It would be a lot easier if you just took over my patches that
implement this properly:
The tests need to be fixed in a couple places to take directory
ordering (or lack-thereof) into account.
--
James Hawkins
On Fri, Feb 13, 2009 at 12:14 AM, Hans Leidekker
hans@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);
>
>
>