[5/5] fusion: Implement IAssemblyCache::QueryAssemblyInfo.

James Hawkins truiken at gmail.com
Fri Feb 13 02:31:54 CST 2009


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 <hans at 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);
>
>
>



More information about the wine-devel mailing list