[5/5] fusion: Implement IAssemblyCache::QueryAssemblyInfo.
Hans Leidekker
hans at meelstraat.net
Fri Feb 13 02:14:51 CST 2009
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);
More information about the wine-patches
mailing list