Module: wine Branch: master Commit: 3647c337a9483096ef9af5d36658805819b50dd7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3647c337a9483096ef9af5d366...
Author: Piotr Caban piotr@codeweavers.com Date: Mon Feb 22 23:14:40 2010 +0100
oleaut32: Improved ICreateTypeInfo2_AddRefTypeInfo implementation.
---
dlls/oleaut32/tests/typelib.c | 23 ++++++++++- dlls/oleaut32/typelib2.c | 94 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 109 insertions(+), 8 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index bcf959c..c821fac 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -969,6 +969,7 @@ if(use_midl_tlb) { }
static void test_CreateTypeLib(void) { + static const WCHAR stdoleW[] = {'s','t','d','o','l','e','2','.','t','l','b',0}; static OLECHAR interface1W[] = {'i','n','t','e','r','f','a','c','e','1',0}; static WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0}; static OLECHAR func1W[] = {'f','u','n','c','1',0}; @@ -982,15 +983,23 @@ static void test_CreateTypeLib(void) { WCHAR filenameW[MAX_PATH]; ICreateTypeLib2 *createtl; ICreateTypeInfo *createti; - ITypeLib *tl; + ITypeLib *tl, *stdole; + ITypeInfo *unknown; FUNCDESC funcdesc; ELEMDESC elemdesc[5]; PARAMDESCEX paramdescex; TYPEDESC typedesc1, typedesc2; + HREFTYPE hreftype; HRESULT hres;
trace("CreateTypeLib tests\n");
+ hres = LoadTypeLib(stdoleW, &stdole); + ok(hres == S_OK, "got %08x\n", hres); + + hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IUnknown, &unknown); + ok(hres == S_OK, "got %08x\n", hres); + GetTempFileNameA(".", "tlb", 0, filename); MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, MAX_PATH);
@@ -1003,6 +1012,15 @@ static void test_CreateTypeLib(void) { hres = ICreateTypeInfo_LayOut(createti); ok(hres == S_OK, "got %08x\n", hres);
+ hres = ICreateTypeInfo_AddRefTypeInfo(createti, NULL, &hreftype); + ok(hres == E_INVALIDARG, "got %08x\n", hres); + + hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, NULL); + ok(hres == E_INVALIDARG, "got %08x\n", hres); + + hres = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, &hreftype); + ok(hres == S_OK, "got %08x\n", hres); + memset(&funcdesc, 0, sizeof(FUNCDESC)); funcdesc.funckind = FUNC_PUREVIRTUAL; funcdesc.invkind = INVOKE_PROPERTYGET; @@ -1135,7 +1153,10 @@ static void test_CreateTypeLib(void) { hres = LoadTypeLib(filenameW, &tl); ok(hres == S_OK, "got %08x\n", hres);
+ ITypeInfo_Release(unknown); + ITypeLib_Release(tl); + ITypeLib_Release(stdole);
DeleteFileA(filename); } diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c index 907eae1..38e15ea 100644 --- a/dlls/oleaut32/typelib2.c +++ b/dlls/oleaut32/typelib2.c @@ -43,6 +43,7 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" +#include "winreg.h" #include "winuser.h"
#include "wine/unicode.h" @@ -707,6 +708,7 @@ static int ctl2_alloc_importinfo( static int ctl2_alloc_importfile( ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ int guidoffset, /* [I] The offset to the GUID for the imported library. */ + LCID lcid, /* [I] The LCID of imported library. */ int major_version, /* [I] The major version number of the imported library. */ int minor_version, /* [I] The minor version number of the imported library. */ const WCHAR *filename) /* [I] The filename of the imported library. */ @@ -732,7 +734,7 @@ static int ctl2_alloc_importfile(
importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; importfile->guid = guidoffset; - importfile->lcid = This->typelib_header.lcid2; + importfile->lcid = lcid; importfile->version = major_version | (minor_version << 16); memcpy(importfile->filename, encoded_string, length);
@@ -1370,7 +1372,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U guidoffset = ctl2_alloc_guid(This->typelib, &foo); if (guidoffset == -1) return E_OUTOFMEMORY;
- fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, 2, 0, stdole2tlb); + fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, + This->typelib->typelib_header.lcid2, 2, 0, stdole2tlb); if (fileoffset == -1) return E_OUTOFMEMORY;
foo.guid = IID_IDispatch; @@ -1471,10 +1474,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);
+ if(!pTInfo || !phRefType) + return E_INVALIDARG; + /* - * If this is one of ours, we set *phRefType to the TYPEINFO offset of - * the referred TypeInfo. Otherwise, we presumably have more magic to do. - * * Unfortunately, we can't rely on the passed-in TypeInfo even having the * same internal structure as one of ours. It could be from another * implementation of ITypeInfo. So we need to do the following... @@ -1486,9 +1489,86 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( }
if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) { + /* Process locally defined TypeInfo */ *phRefType = This->typelib->typelib_typeinfo_offsets[index]; } else { - FIXME("(%p,%p,%p), pTInfo from different typelib.\n", iface, pTInfo, phRefType); + static const WCHAR regkey[] = {'T','y','p','e','L','i','b','\','{', + '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%', + '0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x', + '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x', + '}','\','%','d','.','%','d','\','0','\','w','i','n','3','2',0}; + + WCHAR name[MAX_PATH], *p; + TLIBATTR *tlibattr; + TYPEATTR *typeattr; + MSFT_GuidEntry guid; + MSFT_ImpInfo impinfo; + int guid_offset, import_offset; + DWORD len; + HRESULT hres; + + /* Allocate container GUID */ + hres = ITypeLib_GetLibAttr(container, &tlibattr); + if(FAILED(hres)) + return hres; + + guid.guid = tlibattr->guid; + guid.hreftype = 2; + guid.next_hash = -1; + + guid_offset = ctl2_alloc_guid(This->typelib, &guid); + if(guid_offset == -1) { + ITypeLib_ReleaseTLibAttr(container, tlibattr); + return E_OUTOFMEMORY; + } + + /* Get import file name */ + /* Check HKEY_CLASSES_ROOT\TypeLib{GUID}{Ver}\0\win32 */ + len = MAX_PATH; + sprintfW(name, regkey, guid.guid.Data1, guid.guid.Data2, + guid.guid.Data3, guid.guid.Data4[0], guid.guid.Data4[1], + guid.guid.Data4[2], guid.guid.Data4[3], guid.guid.Data4[4], + guid.guid.Data4[5], guid.guid.Data4[6], guid.guid.Data4[7], + tlibattr->wMajorVerNum, tlibattr->wMinorVerNum); + + if(RegGetValueW(HKEY_CLASSES_ROOT, name, NULL, RRF_RT_REG_SZ, NULL, name, &len)!=ERROR_SUCCESS + || (p=strrchrW(name, '\'))==NULL) { + ERR("Error guessing typelib filename\n"); + ITypeLib_ReleaseTLibAttr(container, tlibattr); + return E_NOTIMPL; + } + memmove(name, p+1, strlenW(p)*sizeof(WCHAR)); + + /* Import file */ + import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, + tlibattr->lcid, tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, name); + ITypeLib_ReleaseTLibAttr(container, tlibattr); + + if(import_offset == -1) + return E_OUTOFMEMORY; + + /* Allocate referenced guid */ + hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr); + if(FAILED(hres)) + return hres; + + guid.guid = typeattr->guid; + guid.hreftype = 1; + guid.next_hash = -1; + ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr); + + guid_offset = ctl2_alloc_guid(This->typelib, &guid); + if(guid_offset == -1) + return E_OUTOFMEMORY; + + /* Allocate importinfo */ + impinfo.flags = ((This->typeinfo->typekind&0xf)<<24) | MSFT_IMPINFO_OFFSET_IS_GUID; + impinfo.oImpFile = import_offset; + impinfo.oGuid = guid_offset; + *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1; + + if(!memcmp(&guid.guid, &IID_IDispatch, sizeof(GUID))) + This->typelib->typelib_header.dispatchpos = *phRefType; }
ITypeLib_Release(container); @@ -1613,7 +1693,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( }
/* update the index data */ - insert->indice = (This->typeinfo->cImplTypes << 16) | pFuncDesc->memid; + insert->indice = pFuncDesc->memid; insert->name = -1;
/* insert type data to list */