[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