It would be a lot easier if you just took over my patches that implement this properly:
[PATCH 1/3] fusion: Implement the IAssemblyEnum interface. [try4] http://winehq.org/pipermail/wine-patches/2009-January/066994.html [PATCH 2/3] fusion: Add tests for the IAssemblyEnum interface. [try4] http://winehq.org/pipermail/wine-patches/2009-January/066995.html [PATCH 3/3] fusion: Add initial implementation of IAssemblyCache::QueryAssemblyInfo. [try4] http://winehq.org/pipermail/wine-patches/2009-January/066996.html The tests need to be fixed in a couple places to take directory ordering (or lack-thereof) into account. http://winehq.org/pipermail/wine-devel/2009-January/071727.html -- James Hawkins On Fri, Feb 13, 2009 at 12:14 AM, Hans Leidekker <h...@meelstraat.net> wrote: > > diff --git a/dlls/fusion/asmcache.c b/dlls/fusion/asmcache.c > index 73756b3..2ce1995 100644 > --- a/dlls/fusion/asmcache.c > +++ b/dlls/fusion/asmcache.c > @@ -41,6 +41,9 @@ > > WINE_DEFAULT_DEBUG_CHANNEL(fusion); > > +static const WCHAR ext_exe[] = {'.','e','x','e',0}; > +static const WCHAR ext_dll[] = {'.','d','l','l',0}; > + > static BOOL create_full_path(LPCWSTR path) > { > LPWSTR new_path; > @@ -167,15 +170,102 @@ static HRESULT WINAPI > IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface > return E_NOTIMPL; > } > > +static BOOL get_file_size(const WCHAR *filename, LARGE_INTEGER *size) > +{ > + HANDLE file; > + > + size->QuadPart = 0; > + file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, > + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); > + if (file == INVALID_HANDLE_VALUE) return FALSE; > + GetFileSizeEx(file, size); > + CloseHandle(file); > + return TRUE; > +} > + > +#define TOKEN_LEN 16 > +#define CULTURE_LEN 17 > +#define NAME_LEN 100 > + > static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache > *iface, > DWORD dwFlags, > LPCWSTR > pszAssemblyName, > ASSEMBLY_INFO > *pAsmInfo) > { > - FIXME("(%p, %d, %s, %p) stub!\n", iface, dwFlags, > - debugstr_w(pszAssemblyName), pAsmInfo); > + static const WCHAR fmt[] = > + {'%','s','\\','%','s','\\','%','u','.','%','u','.','%','u', > + '.','%','u','_','%','s','_','%','s','\\','%','s','%','s',0}; > > - return E_NOTIMPL; > + HRESULT hr; > + IAssemblyName *asmname; > + WCHAR asmdir[MAX_PATH], path[MAX_PATH]; > + WCHAR name[NAME_LEN + 1], culture[CULTURE_LEN + 1], token[TOKEN_LEN + 1]; > + WORD major, minor, build, revision; > + BYTE buf[8]; > + DWORD size; > + LARGE_INTEGER filesize; > + BOOL installed; > + > + TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, debugstr_w(pszAssemblyName), > pAsmInfo); > + > + hr = CreateAssemblyNameObject(&asmname, pszAssemblyName, > CANOF_PARSE_DISPLAY_NAME, NULL); > + if (FAILED(hr)) > + return hr; > + > + size = sizeof(name); > + IAssemblyName_GetProperty(asmname, ASM_NAME_NAME, name, &size); > + > + size = sizeof(buf); > + memset(buf, 0, sizeof(buf)); > + IAssemblyName_GetProperty(asmname, ASM_NAME_PUBLIC_KEY_TOKEN, buf, > &size); > + > + token_to_str(buf, token); > + > + size = sizeof(major); > + IAssemblyName_GetProperty(asmname, ASM_NAME_MAJOR_VERSION, &major, > &size); > + > + size = sizeof(minor); > + IAssemblyName_GetProperty(asmname, ASM_NAME_MINOR_VERSION, &minor, > &size); > + > + size = sizeof(build); > + IAssemblyName_GetProperty(asmname, ASM_NAME_BUILD_NUMBER, &build, &size); > + > + size = sizeof(revision); > + IAssemblyName_GetProperty(asmname, ASM_NAME_REVISION_NUMBER, &revision, > &size); > + > + size = sizeof(culture); > + IAssemblyName_GetProperty(asmname, ASM_NAME_CULTURE, &culture, &size); > + > + get_assembly_directory(asmdir, MAX_PATH); > + > + sprintfW(path, fmt, asmdir, > + name, major, minor, build, revision, culture, token, name, > ext_dll); > + > + /* FIXME: there can be more than one file */ > + if (!(installed = get_file_size(path, &filesize))) > + { > + strcpyW(strrchrW(path, '.'), ext_exe); > + if (!(installed = get_file_size(path, &filesize))) > + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); > + } > + > + if (pAsmInfo) > + { > + pAsmInfo->uliAssemblySizeInKB.QuadPart = filesize.QuadPart; > + pAsmInfo->dwAssemblyFlags = 0; > + if (installed) > + { > + pAsmInfo->cbAssemblyInfo = sizeof(ASSEMBLY_INFO); > + pAsmInfo->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED; > + pAsmInfo->pszCurrentAssemblyPathBuf = strdupW(path); > + pAsmInfo->cchBuf = strlenW(pAsmInfo->pszCurrentAssemblyPathBuf) > + 1; > + } > + } > + > + if (dwFlags & QUERYASMINFO_FLAG_VALIDATE) FIXME("not validating > assembly\n"); > + > + IAssemblyName_Release(asmname); > + return hr; > } > > static HRESULT WINAPI > IAssemblyCacheImpl_CreateAssemblyCacheItem(IAssemblyCache *iface, > @@ -216,9 +306,6 @@ static HRESULT WINAPI > IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, > LPWSTR ext; > HRESULT hr; > > - static const WCHAR ext_exe[] = {'.','e','x','e',0}; > - static const WCHAR ext_dll[] = {'.','d','l','l',0}; > - > TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, > debugstr_w(pszManifestFilePath), pRefData); > > diff --git a/dlls/fusion/assembly.c b/dlls/fusion/assembly.c > index 049bf15..a7b09c8 100644 > --- a/dlls/fusion/assembly.c > +++ b/dlls/fusion/assembly.c > @@ -818,25 +818,6 @@ static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD > index, ULONG *size) > return GetData(&assembly->blobs[index], size); > } > > -static void bytes_to_str(BYTE *bytes, DWORD len, LPWSTR str) > -{ > - DWORD i; > - > - static const WCHAR hexval[16] = { > - '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' > - }; > - > - for(i = 0; i < len; i++) > - { > - str[i * 2] = hexval[((bytes[i] >> 4) & 0xF)]; > - str[i * 2 + 1] = hexval[(bytes[i]) & 0x0F]; > - } > -} > - > -#define BYTES_PER_TOKEN 8 > -#define CHARS_PER_BYTE 2 > -#define TOKEN_LENGTH (BYTES_PER_TOKEN * CHARS_PER_BYTE + 1) > - > HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) > { > ASSEMBLYTABLE *asmtbl; > @@ -896,8 +877,7 @@ HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, > LPWSTR *token) > goto done; > } > > - bytes_to_str(tokbytes, BYTES_PER_TOKEN, tok); > - tok[TOKEN_LENGTH - 1] = '\0'; > + token_to_str(tokbytes, tok); > > *token = tok; > hr = S_OK; > diff --git a/dlls/fusion/fusionpriv.h b/dlls/fusion/fusionpriv.h > index 405133b..6dec11b 100644 > --- a/dlls/fusion/fusionpriv.h > +++ b/dlls/fusion/fusionpriv.h > @@ -445,4 +445,24 @@ static inline WCHAR *strdupW(const WCHAR *src) > return dst; > } > > +#define BYTES_PER_TOKEN 8 > +#define CHARS_PER_BYTE 2 > +#define TOKEN_LENGTH (BYTES_PER_TOKEN * CHARS_PER_BYTE + 1) > + > +static inline void token_to_str(BYTE *bytes, LPWSTR str) > +{ > + DWORD i; > + > + static const WCHAR hexval[16] = { > + '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' > + }; > + > + for(i = 0; i < BYTES_PER_TOKEN; i++) > + { > + str[i * 2] = hexval[((bytes[i] >> 4) & 0xF)]; > + str[i * 2 + 1] = hexval[(bytes[i]) & 0x0F]; > + } > + str[i * 2] = 0; > +} > + > #endif /* __WINE_FUSION_PRIVATE__ */ > diff --git a/dlls/fusion/tests/asmcache.c b/dlls/fusion/tests/asmcache.c > index fe2b466..42d8cba 100644 > --- a/dlls/fusion/tests/asmcache.c > +++ b/dlls/fusion/tests/asmcache.c > @@ -1020,11 +1020,8 @@ static void test_QueryAssemblyInfo(void) > /* assembly not installed yet */ > INIT_ASM_INFO(); > hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, wine, &info); > - todo_wine > - { > - ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > - "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", > hr); > - } > + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1043,10 +1040,7 @@ static void test_QueryAssemblyInfo(void) > INIT_ASM_INFO(); > hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE, > NULL, &info); > - todo_wine > - { > - ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); > - } > + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1062,10 +1056,7 @@ static void test_QueryAssemblyInfo(void) > INIT_ASM_INFO(); > hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_VALIDATE, > empty, &info); > - todo_wine > - { > - ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); > - } > + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1100,11 +1091,8 @@ static void test_QueryAssemblyInfo(void) > /* pwzCachePath is full filename */ > INIT_ASM_INFO(); > hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, winedll, &info); > - todo_wine > - { > - ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > - "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", > hr); > - } > + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1332,11 +1320,8 @@ static void test_QueryAssemblyInfo(void) > lstrcatW(name, badver); > hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE, > name, &info); > - todo_wine > - { > - ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > - "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", > hr); > - } > + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1379,11 +1364,8 @@ static void test_QueryAssemblyInfo(void) > lstrcatW(name, badculture); > hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE, > name, &info); > - todo_wine > - { > - ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > - "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", > hr); > - } > + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1426,11 +1408,8 @@ static void test_QueryAssemblyInfo(void) > lstrcatW(name, badpubkey); > hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE, > name, &info); > - todo_wine > - { > - ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > - "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", > hr); > - } > + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), > + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); > ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", > info.dwAssemblyFlags); > @@ -1466,6 +1445,31 @@ static void test_QueryAssemblyInfo(void) > "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf); > } > > + /* fully qualified display name */ > + INIT_ASM_INFO(); > + lstrcpyW(name, wine); > + lstrcatW(name, commasep); > + lstrcatW(name, ver); > + lstrcatW(name, commasep); > + lstrcatW(name, culture); > + lstrcatW(name, commasep); > + lstrcatW(name, pubkey); > + hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE, > + name, &info); > + ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), > + "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); > + ok(info.uliAssemblySizeInKB.u.HighPart == 0, > + "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart); > + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); > + ok(info.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED, > + "Expected ASSEMBLYINFO_FLAG_INSTALLED, got %08x\n", > info.dwAssemblyFlags); > + ok(info.uliAssemblySizeInKB.u.LowPart == sizeof(ASSEMBLY), > + "Expected 4, got %d\n", info.uliAssemblySizeInKB.u.LowPart); > + ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, asmpath), > + "Wrong assembly path returned\n"); > + ok(info.cchBuf == lstrlenW(asmpath) + 1, > + "Expected %d, got %d\n", lstrlenW(asmpath) + 1, info.cchBuf); > + > /* uninstall the assembly from the GAC */ > disp = 0xf00dbad; > hr = IAssemblyCache_UninstallAssembly(cache, 0, wine, NULL, &disp); > > >