[ros-diffs] [cwittich] 41022: sync fusion with wine 1.1.21

cwittich at svn.reactos.org cwittich at svn.reactos.org
Wed May 20 16:43:25 CEST 2009


Author: cwittich
Date: Wed May 20 18:43:24 2009
New Revision: 41022

URL: http://svn.reactos.org/svn/reactos?rev=41022&view=rev
Log:
sync fusion with wine 1.1.21

Added:
    trunk/reactos/dll/win32/fusion/asmenum.c   (with props)
Modified:
    trunk/reactos/dll/win32/fusion/asmcache.c
    trunk/reactos/dll/win32/fusion/asmname.c
    trunk/reactos/dll/win32/fusion/assembly.c
    trunk/reactos/dll/win32/fusion/fusion.c
    trunk/reactos/dll/win32/fusion/fusion.rbuild
    trunk/reactos/dll/win32/fusion/fusionpriv.h

Modified: trunk/reactos/dll/win32/fusion/asmcache.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/asmcache.c?rev=41022&r1=41021&r2=41022&view=diff
==============================================================================
--- trunk/reactos/dll/win32/fusion/asmcache.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/fusion/asmcache.c [iso-8859-1] Wed May 20 18:43:24 2009
@@ -41,24 +41,24 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(fusion);
 
-static BOOL create_full_path(LPCSTR path)
-{
-    LPSTR new_path;
+static BOOL create_full_path(LPCWSTR path)
+{
+    LPWSTR new_path;
     BOOL ret = TRUE;
     int len;
 
-    new_path = HeapAlloc(GetProcessHeap(), 0, lstrlenA(path) + 1);
+    new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) * sizeof(WCHAR));
     if (!new_path)
         return FALSE;
 
-    lstrcpyA(new_path, path);
-
-    while ((len = lstrlenA(new_path)) && new_path[len - 1] == '\\')
+    strcpyW(new_path, path);
+
+    while ((len = strlenW(new_path)) && new_path[len - 1] == '\\')
         new_path[len - 1] = 0;
 
-    while (!CreateDirectoryA(new_path, NULL))
-    {
-        LPSTR slash;
+    while (!CreateDirectoryW(new_path, NULL))
+    {
+        LPWSTR slash;
         DWORD last_error = GetLastError();
 
         if(last_error == ERROR_ALREADY_EXISTS)
@@ -70,7 +70,7 @@
             break;
         }
 
-        if(!(slash = strrchr(new_path, '\\')))
+        if(!(slash = strrchrW(new_path, '\\')))
         {
             ret = FALSE;
             break;
@@ -91,6 +91,18 @@
     return ret;
 }
 
+static BOOL get_assembly_directory(LPWSTR dir, DWORD size)
+{
+    static const WCHAR gac[] =
+        {'\\','a','s','s','e','m','b','l','y','\\','G','A','C','_','M','S','I','L',0};
+
+    FIXME("Ignoring assembly architecture\n");
+
+    GetWindowsDirectoryW(dir, size);
+    strcatW(dir, gac);
+    return TRUE;
+}
+
 /* IAssemblyCache */
 
 typedef struct {
@@ -160,10 +172,48 @@
                                                            LPCWSTR pszAssemblyName,
                                                            ASSEMBLY_INFO *pAsmInfo)
 {
-    FIXME("(%p, %d, %s, %p) stub!\n", iface, dwFlags,
+    IAssemblyName *asmname, *next = NULL;
+    IAssemblyEnum *asmenum = NULL;
+    HRESULT hr;
+
+    TRACE("(%p, %d, %s, %p)\n", iface, dwFlags,
           debugstr_w(pszAssemblyName), pAsmInfo);
 
-    return E_NOTIMPL;
+    if (pAsmInfo)
+    {
+        if (pAsmInfo->cbAssemblyInfo == 0)
+            pAsmInfo->cbAssemblyInfo = sizeof(ASSEMBLY_INFO);
+        else if (pAsmInfo->cbAssemblyInfo != sizeof(ASSEMBLY_INFO))
+            return E_INVALIDARG;
+    }
+
+    hr = CreateAssemblyNameObject(&asmname, pszAssemblyName,
+                                  CANOF_PARSE_DISPLAY_NAME, NULL);
+    if (FAILED(hr))
+        return hr;
+
+    hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
+    if (FAILED(hr))
+        goto done;
+
+    hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0);
+    if (hr == S_FALSE)
+    {
+        hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+        goto done;
+    }
+
+    if (!pAsmInfo)
+        goto done;
+
+    pAsmInfo->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED;
+
+done:
+    IAssemblyName_Release(asmname);
+    if (next) IAssemblyName_Release(next);
+    if (asmenum) IAssemblyEnum_Release(asmenum);
+
+    return hr;
 }
 
 static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyCacheItem(IAssemblyCache *iface,
@@ -190,14 +240,17 @@
                                                          LPCWSTR pszManifestFilePath,
                                                          LPCFUSION_INSTALL_REFERENCE pRefData)
 {
+    static const WCHAR format[] =
+        {'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0};
+
     ASSEMBLY *assembly;
-    LPSTR filename;
-    LPSTR name = NULL;
-    LPSTR token = NULL;
-    LPSTR version = NULL;
-    LPSTR asmpath = NULL;
-    CHAR path[MAX_PATH];
-    CHAR windir[MAX_PATH];
+    LPWSTR filename;
+    LPWSTR name = NULL;
+    LPWSTR token = NULL;
+    LPWSTR version = NULL;
+    LPWSTR asmpath = NULL;
+    WCHAR path[MAX_PATH];
+    WCHAR asmdir[MAX_PATH];
     LPWSTR ext;
     HRESULT hr;
 
@@ -238,12 +291,9 @@
     if (FAILED(hr))
         goto done;
 
-    GetWindowsDirectoryA(windir, MAX_PATH);
-
-    FIXME("Ignoring assembly architecture!\n");
-
-    sprintf(path, "%s\\assembly\\GAC_MSIL\\%s\\%s__%s\\", windir, name,
-            version, token);
+    get_assembly_directory(asmdir, MAX_PATH);
+
+    sprintfW(path, format, asmdir, name, version, token);
 
     create_full_path(path);
 
@@ -251,10 +301,10 @@
     if (FAILED(hr))
         goto done;
 
-    filename = PathFindFileNameA(asmpath);
-
-    lstrcatA(path, filename);
-    if (!CopyFileA(asmpath, path, FALSE))
+    filename = PathFindFileNameW(asmpath);
+
+    strcatW(path, filename);
+    if (!CopyFileW(asmpath, path, FALSE))
         hr = HRESULT_FROM_WIN32(GetLastError());
 
 done:
@@ -391,86 +441,3 @@
     IAssemblyCacheItemImpl_Commit,
     IAssemblyCacheItemImpl_AbortItem
 };
-
-/* IAssemblyEnum */
-
-typedef struct {
-    const IAssemblyEnumVtbl *lpIAssemblyEnumVtbl;
-
-    LONG ref;
-} IAssemblyEnumImpl;
-
-static HRESULT WINAPI IAssemblyEnumImpl_QueryInterface(IAssemblyEnum *iface,
-                                                       REFIID riid, LPVOID *ppobj)
-{
-    IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface;
-
-    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
-
-    *ppobj = NULL;
-
-    if (IsEqualIID(riid, &IID_IUnknown) ||
-        IsEqualIID(riid, &IID_IAssemblyEnum))
-    {
-        IUnknown_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-
-    WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj);
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IAssemblyEnumImpl_AddRef(IAssemblyEnum *iface)
-{
-    IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface;
-    ULONG refCount = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->(ref before = %u)\n", This, refCount - 1);
-
-    return refCount;
-}
-
-static ULONG WINAPI IAssemblyEnumImpl_Release(IAssemblyEnum *iface)
-{
-    IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface;
-    ULONG refCount = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->(ref before = %u)\n", This, refCount + 1);
-
-    if (!refCount)
-        HeapFree(GetProcessHeap(), 0, This);
-
-    return refCount;
-}
-
-static HRESULT WINAPI IAssemblyEnumImpl_GetNextAssembly(IAssemblyEnum *iface,
-                                                        LPVOID pvReserved,
-                                                        IAssemblyName **ppName,
-                                                        DWORD dwFlags)
-{
-    FIXME("(%p, %p, %p, %d) stub!\n", iface, pvReserved, ppName, dwFlags);
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI IAssemblyEnumImpl_Reset(IAssemblyEnum *iface)
-{
-    FIXME("(%p) stub!\n", iface);
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI IAssemblyEnumImpl_Clone(IAssemblyEnum *iface,
-                                               IAssemblyEnum **ppEnum)
-{
-    FIXME("(%p, %p) stub!\n", iface, ppEnum);
-    return E_NOTIMPL;
-}
-
-static const IAssemblyEnumVtbl AssemblyEnumVtbl = {
-    IAssemblyEnumImpl_QueryInterface,
-    IAssemblyEnumImpl_AddRef,
-    IAssemblyEnumImpl_Release,
-    IAssemblyEnumImpl_GetNextAssembly,
-    IAssemblyEnumImpl_Reset,
-    IAssemblyEnumImpl_Clone
-};

Added: trunk/reactos/dll/win32/fusion/asmenum.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/asmenum.c?rev=41022&view=auto
==============================================================================
--- trunk/reactos/dll/win32/fusion/asmenum.c (added)
+++ trunk/reactos/dll/win32/fusion/asmenum.c [iso-8859-1] Wed May 20 18:43:24 2009
@@ -1,0 +1,443 @@
+/*
+ * IAssemblyEnum implementation
+ *
+ * Copyright 2008 James Hawkins
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ole2.h"
+#include "guiddef.h"
+#include "fusion.h"
+#include "corerror.h"
+#include "fusionpriv.h"
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "wine/list.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(fusion);
+
+typedef struct _tagASMNAME
+{
+    struct list entry;
+    IAssemblyName *name;
+} ASMNAME;
+
+typedef struct
+{
+    const IAssemblyEnumVtbl *lpIAssemblyEnumVtbl;
+
+    struct list assemblies;
+    struct list *iter;
+    LONG ref;
+} IAssemblyEnumImpl;
+
+static HRESULT WINAPI IAssemblyEnumImpl_QueryInterface(IAssemblyEnum *iface,
+                                                       REFIID riid, LPVOID *ppobj)
+{
+    IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface;
+
+    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
+
+    *ppobj = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IAssemblyEnum))
+    {
+        IUnknown_AddRef(iface);
+        *ppobj = This;
+        return S_OK;
+    }
+
+    WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IAssemblyEnumImpl_AddRef(IAssemblyEnum *iface)
+{
+    IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->(ref before = %u)\n", This, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI IAssemblyEnumImpl_Release(IAssemblyEnum *iface)
+{
+    IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface;
+    ULONG refCount = InterlockedDecrement(&This->ref);
+    struct list *item, *cursor;
+
+    TRACE("(%p)->(ref before = %u)\n", This, refCount + 1);
+
+    if (!refCount)
+    {
+        LIST_FOR_EACH_SAFE(item, cursor, &This->assemblies)
+        {
+            ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);
+
+            list_remove(&asmname->entry);
+            IAssemblyName_Release(asmname->name);
+            HeapFree(GetProcessHeap(), 0, asmname);
+        }
+
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return refCount;
+}
+
+static HRESULT WINAPI IAssemblyEnumImpl_GetNextAssembly(IAssemblyEnum *iface,
+                                                        LPVOID pvReserved,
+                                                        IAssemblyName **ppName,
+                                                        DWORD dwFlags)
+{
+    IAssemblyEnumImpl *asmenum = (IAssemblyEnumImpl *)iface;
+    ASMNAME *asmname;
+
+    TRACE("(%p, %p, %p, %d)\n", iface, pvReserved, ppName, dwFlags);
+
+    if (!ppName)
+        return E_INVALIDARG;
+
+    asmname = LIST_ENTRY(asmenum->iter, ASMNAME, entry);
+    if (!asmname)
+        return S_FALSE;
+
+    *ppName = asmname->name;
+    IAssemblyName_AddRef(*ppName);
+
+    asmenum->iter = list_next(&asmenum->assemblies, asmenum->iter);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IAssemblyEnumImpl_Reset(IAssemblyEnum *iface)
+{
+    IAssemblyEnumImpl *asmenum = (IAssemblyEnumImpl *)iface;
+
+    TRACE("(%p)\n", iface);
+
+    asmenum->iter = list_head(&asmenum->assemblies);
+    return S_OK;
+}
+
+static HRESULT WINAPI IAssemblyEnumImpl_Clone(IAssemblyEnum *iface,
+                                               IAssemblyEnum **ppEnum)
+{
+    FIXME("(%p, %p) stub!\n", iface, ppEnum);
+    return E_NOTIMPL;
+}
+
+static const IAssemblyEnumVtbl AssemblyEnumVtbl = {
+    IAssemblyEnumImpl_QueryInterface,
+    IAssemblyEnumImpl_AddRef,
+    IAssemblyEnumImpl_Release,
+    IAssemblyEnumImpl_GetNextAssembly,
+    IAssemblyEnumImpl_Reset,
+    IAssemblyEnumImpl_Clone
+};
+
+static void parse_name(IAssemblyName *name, int depth, LPWSTR path, LPWSTR buf)
+{
+    WCHAR disp[MAX_PATH];
+    LPCWSTR verptr, pubkeyptr;
+    HRESULT hr;
+    DWORD size, major_size, minor_size, build_size, revision_size;
+    WORD major, minor, build, revision;
+
+    static const WCHAR star[] = {'*',0};
+    static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0};
+    static const WCHAR verpubkey[] = {'%','s','\\','%','s','_','_','%','s',0};
+    static const WCHAR ver_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
+
+    WCHAR version[24]; /* strlen("65535") * 4 + 3 + 1 */
+    WCHAR token_str[TOKEN_LENGTH + 1];
+    BYTE token[BYTES_PER_TOKEN];
+
+    if (depth == 0)
+    {
+        size = MAX_PATH;
+        *disp = '\0';
+        hr = IAssemblyName_GetName(name, &size, disp);
+        if (SUCCEEDED(hr))
+            sprintfW(buf, ss_fmt, path, disp);
+        else
+            sprintfW(buf, ss_fmt, path, star);
+    }
+    else if (depth == 1)
+    {
+        major_size = sizeof(major);
+        IAssemblyName_GetProperty(name, ASM_NAME_MAJOR_VERSION, &major, &major_size);
+
+        minor_size = sizeof(minor);
+        IAssemblyName_GetProperty(name, ASM_NAME_MINOR_VERSION, &minor, &minor_size);
+
+        build_size = sizeof(build);
+        IAssemblyName_GetProperty(name, ASM_NAME_BUILD_NUMBER, &build, &build_size);
+
+        revision_size = sizeof(revision);
+        IAssemblyName_GetProperty(name, ASM_NAME_REVISION_NUMBER, &revision, &revision_size);
+
+        if (!major_size || !minor_size || !build_size || !revision_size) verptr = star;
+        else
+        {
+            sprintfW(version, ver_fmt, major, minor, build, revision);
+            verptr = version;
+        }
+
+        size = sizeof(token);
+        IAssemblyName_GetProperty(name, ASM_NAME_PUBLIC_KEY_TOKEN, token, &size);
+
+        if (!size) pubkeyptr = star;
+        else
+        {
+            token_to_str(token, token_str);
+            pubkeyptr = token_str;
+        }
+
+        sprintfW(buf, verpubkey, path, verptr, pubkeyptr);
+    }
+}
+
+static int compare_assembly_names(ASMNAME *asmname1, ASMNAME *asmname2)
+{
+    int ret;
+    WORD version1, version2;
+    WCHAR name1[MAX_PATH], name2[MAX_PATH];
+    WCHAR token_str1[TOKEN_LENGTH + 1], token_str2[TOKEN_LENGTH + 1];
+    BYTE token1[BYTES_PER_TOKEN], token2[BYTES_PER_TOKEN];
+    DWORD size, i;
+
+    size = sizeof(name1);
+    IAssemblyName_GetProperty(asmname1->name, ASM_NAME_NAME, &name1, &size);
+    size = sizeof(name2);
+    IAssemblyName_GetProperty(asmname2->name, ASM_NAME_NAME, &name2, &size);
+
+    if ((ret = strcmpiW(name1, name2))) return ret;
+
+    for (i = ASM_NAME_MAJOR_VERSION; i < ASM_NAME_CULTURE; i++)
+    {
+        size = sizeof(version1);
+        IAssemblyName_GetProperty(asmname1->name, i, &version1, &size);
+        size = sizeof(version2);
+        IAssemblyName_GetProperty(asmname2->name, i, &version2, &size);
+
+        if (version1 < version2) return -1;
+        if (version1 > version2) return 1;
+    }
+
+    /* FIXME: compare cultures */
+
+    size = sizeof(token1);
+    IAssemblyName_GetProperty(asmname1->name, ASM_NAME_PUBLIC_KEY_TOKEN, token1, &size);
+    size = sizeof(token2);
+    IAssemblyName_GetProperty(asmname2->name, ASM_NAME_PUBLIC_KEY_TOKEN, token2, &size);
+
+    token_to_str(token1, token_str1);
+    token_to_str(token2, token_str2);
+
+    if ((ret = strcmpiW(token_str1, token_str2))) return ret;
+
+    return 0;
+}
+
+/* insert assembly in list preserving sort order */
+static void insert_assembly(struct list *assemblies, ASMNAME *to_insert)
+{
+    struct list *item;
+
+    LIST_FOR_EACH(item, assemblies)
+    {
+        ASMNAME *name = LIST_ENTRY(item, ASMNAME, entry);
+
+        if (compare_assembly_names(name, to_insert) > 0)
+        {
+            list_add_before(&name->entry, &to_insert->entry);
+            return;
+        }
+    }
+    list_add_tail(assemblies, &to_insert->entry);
+}
+
+static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name,
+                                   int depth, LPWSTR path)
+{
+    WIN32_FIND_DATAW ffd;
+    WCHAR buf[MAX_PATH];
+    WCHAR disp[MAX_PATH];
+    ASMNAME *asmname;
+    HANDLE hfind;
+    LPWSTR ptr;
+    HRESULT hr = S_OK;
+
+    static WCHAR parent[MAX_PATH];
+
+    static const WCHAR dot[] = {'.',0};
+    static const WCHAR dotdot[] = {'.','.',0};
+    static const WCHAR search_fmt[] = {'%','s','\\','*',0};
+    static const WCHAR parent_fmt[] = {'%','s',',',' ',0};
+    static const WCHAR dblunder[] = {'_','_',0};
+    static const WCHAR fmt[] = {'V','e','r','s','i','o','n','=','%','s',',',' ',
+        'C','u','l','t','u','r','e','=','n','e','u','t','r','a','l',',',' ',
+        'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=','%','s',0};
+    static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0};
+
+    if (name)
+        parse_name(name, depth, path, buf);
+    else
+        sprintfW(buf, search_fmt, path);
+
+    hfind = FindFirstFileW(buf, &ffd);
+    if (hfind == INVALID_HANDLE_VALUE)
+        return S_OK;
+
+    do
+    {
+        if (!lstrcmpW(ffd.cFileName, dot) || !lstrcmpW(ffd.cFileName, dotdot))
+            continue;
+
+        if (depth == 0)
+        {
+            if (name)
+                ptr = strrchrW(buf, '\\') + 1;
+            else
+                ptr = ffd.cFileName;
+
+            sprintfW(parent, parent_fmt, ptr);
+        }
+        else if (depth == 1)
+        {
+            ptr = strstrW(ffd.cFileName, dblunder);
+            *ptr = '\0';
+            ptr += 2;
+            sprintfW(buf, fmt, ffd.cFileName, ptr);
+
+            lstrcpyW(disp, parent);
+            lstrcatW(disp, buf);
+
+            asmname = HeapAlloc(GetProcessHeap(), 0, sizeof(ASMNAME));
+            if (!asmname)
+            {
+                hr = E_OUTOFMEMORY;
+                break;
+            }
+
+            hr = CreateAssemblyNameObject(&asmname->name, disp,
+                                          CANOF_PARSE_DISPLAY_NAME, NULL);
+            if (FAILED(hr))
+            {
+                HeapFree(GetProcessHeap(), 0, asmname);
+                break;
+            }
+
+            insert_assembly(assemblies, asmname);
+            continue;
+        }
+
+        sprintfW(buf, ss_fmt, path, ffd.cFileName);
+        hr = enum_gac_assemblies(assemblies, name, depth + 1, buf);
+        if (FAILED(hr))
+            break;
+    } while (FindNextFileW(hfind, &ffd) != 0);
+
+    FindClose(hfind);
+    return hr;
+}
+
+static HRESULT enumerate_gac(IAssemblyEnumImpl *asmenum, IAssemblyName *pName)
+{
+    WCHAR path[MAX_PATH];
+    WCHAR buf[MAX_PATH];
+    HRESULT hr;
+    DWORD size;
+
+    static WCHAR under32[] = {'_','3','2',0};
+    static WCHAR msil[] = {'_','M','S','I','L',0};
+
+    size = MAX_PATH;
+    hr = GetCachePath(ASM_CACHE_GAC, buf, &size);
+    if (FAILED(hr))
+        return hr;
+
+    lstrcpyW(path, buf);
+    lstrcatW(path, under32);
+    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, path);
+    if (FAILED(hr))
+        return hr;
+
+    lstrcpyW(path, buf);
+    lstrcatW(path, msil);
+    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, path);
+    if (FAILED(hr))
+        return hr;
+
+    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, buf);
+    if (FAILED(hr))
+        return hr;
+
+    return S_OK;
+}
+
+/******************************************************************
+ *  CreateAssemblyEnum   (FUSION.@)
+ */
+HRESULT WINAPI CreateAssemblyEnum(IAssemblyEnum **pEnum, IUnknown *pUnkReserved,
+                                  IAssemblyName *pName, DWORD dwFlags, LPVOID pvReserved)
+{
+    IAssemblyEnumImpl *asmenum;
+    HRESULT hr;
+
+    TRACE("(%p, %p, %p, %08x, %p)\n", pEnum, pUnkReserved,
+          pName, dwFlags, pvReserved);
+
+    if (!pEnum)
+        return E_INVALIDARG;
+
+    if (dwFlags == 0 || dwFlags == ASM_CACHE_ROOT)
+        return E_INVALIDARG;
+
+    asmenum = HeapAlloc(GetProcessHeap(), 0, sizeof(IAssemblyEnumImpl));
+    if (!asmenum)
+        return E_OUTOFMEMORY;
+
+    asmenum->lpIAssemblyEnumVtbl = &AssemblyEnumVtbl;
+    asmenum->ref = 1;
+    list_init(&asmenum->assemblies);
+
+    if (dwFlags & ASM_CACHE_GAC)
+    {
+        hr = enumerate_gac(asmenum, pName);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, asmenum);
+            return hr;
+        }
+    }
+
+    asmenum->iter = list_head(&asmenum->assemblies);
+    *pEnum = (IAssemblyEnum *)asmenum;
+
+    return S_OK;
+}

Propchange: trunk/reactos/dll/win32/fusion/asmenum.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/dll/win32/fusion/asmname.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/asmname.c?rev=41022&r1=41021&r2=41022&view=diff
==============================================================================
--- trunk/reactos/dll/win32/fusion/asmname.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/fusion/asmname.c [iso-8859-1] Wed May 20 18:43:24 2009
@@ -33,22 +33,9 @@
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
+#include "fusionpriv.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(fusion);
-
-static inline LPWSTR strdupW(LPCWSTR src)
-{
-    LPWSTR dest;
-
-    if (!src)
-        return NULL;
-
-    dest = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src) + 1) * sizeof(WCHAR));
-    if (dest)
-        lstrcpyW(dest, src);
-
-    return dest;
-}
 
 typedef struct {
     const IAssemblyNameVtbl *lpIAssemblyNameVtbl;
@@ -57,7 +44,7 @@
     LPWSTR name;
     LPWSTR culture;
 
-    BYTE version[4];
+    WORD version[4];
     DWORD versize;
 
     BYTE pubkey[8];
@@ -157,28 +144,28 @@
 
         case ASM_NAME_MAJOR_VERSION:
             *pcbProperty = 0;
-            *((LPDWORD)pvProperty) = name->version[0];
+            *((WORD *)pvProperty) = name->version[0];
             if (name->versize >= 1)
                 *pcbProperty = sizeof(WORD);
             break;
 
         case ASM_NAME_MINOR_VERSION:
             *pcbProperty = 0;
-            *((LPDWORD)pvProperty) = name->version[1];
+            *((WORD *)pvProperty) = name->version[1];
             if (name->versize >= 2)
                 *pcbProperty = sizeof(WORD);
             break;
 
         case ASM_NAME_BUILD_NUMBER:
             *pcbProperty = 0;
-            *((LPDWORD)pvProperty) = name->version[2];
+            *((WORD *)pvProperty) = name->version[2];
             if (name->versize >= 3)
                 *pcbProperty = sizeof(WORD);
             break;
 
         case ASM_NAME_REVISION_NUMBER:
             *pcbProperty = 0;
-            *((LPDWORD)pvProperty) = name->version[3];
+            *((WORD *)pvProperty) = name->version[3];
             if (name->versize >= 4)
                 *pcbProperty = sizeof(WORD);
             break;
@@ -222,7 +209,7 @@
 {
     IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface;
 
-    TRACE("(%p, %s, %p, %d)\n", iface, debugstr_w(szDisplayName),
+    TRACE("(%p, %p, %p, %d)\n", iface, szDisplayName,
           pccDisplayName, dwDisplayFlags);
 
     if (!name->displayname || !*name->displayname)
@@ -467,6 +454,8 @@
 
         *ptr2 = '\0';
 
+        while (*str == ' ') str++;
+
         if (!lstrcmpW(str, version))
             hr = parse_version(name, ptr);
         else if (!lstrcmpW(str, culture))

Modified: trunk/reactos/dll/win32/fusion/assembly.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/assembly.c?rev=41022&r1=41021&r2=41022&view=diff
==============================================================================
--- trunk/reactos/dll/win32/fusion/assembly.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/fusion/assembly.c [iso-8859-1] Wed May 20 18:43:24 2009
@@ -52,7 +52,7 @@
 
 struct tagASSEMBLY
 {
-    LPSTR path;
+    LPWSTR path;
 
     HANDLE hfile;
     HANDLE hmap;
@@ -75,22 +75,6 @@
     BYTE *strings;
     BYTE *blobs;
 };
-
-static LPSTR strdupWtoA(LPCWSTR str)
-{
-    LPSTR ret = NULL;
-    DWORD len;
-
-    if (!str)
-        return ret;
-
-    len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
-    ret = HeapAlloc(GetProcessHeap(), 0, len);
-    if (ret)
-        WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, NULL, NULL);
-
-    return ret;
-}
 
 static DWORD rva_to_offset(IMAGE_NT_HEADERS *nthdrs, DWORD rva)
 {
@@ -647,14 +631,18 @@
     if (!assembly->nthdr)
         return E_FAIL;
 
-    if (assembly->nthdr->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
+    if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
     {
         IMAGE_OPTIONAL_HEADER64 *opthdr =
                 (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
         datadirs = opthdr->DataDirectory;
     }
     else
-        datadirs = assembly->nthdr->OptionalHeader.DataDirectory;
+    {
+        IMAGE_OPTIONAL_HEADER32 *opthdr =
+                (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
+        datadirs = opthdr->DataDirectory;
+    }
 
     if (!datadirs)
         return E_FAIL;
@@ -684,7 +672,7 @@
     if (!assembly)
         return E_OUTOFMEMORY;
 
-    assembly->path = strdupWtoA(file);
+    assembly->path = strdupW(file);
     if (!assembly->path)
     {
         hr = E_OUTOFMEMORY;
@@ -743,16 +731,21 @@
     return S_OK;
 }
 
-static LPSTR assembly_dup_str(ASSEMBLY *assembly, DWORD index)
-{
+static LPWSTR assembly_dup_str(ASSEMBLY *assembly, DWORD index)
+{
+    int len;
+    LPWSTR cpy;
     LPSTR str = (LPSTR)&assembly->strings[index];
-    LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1);
-    if (cpy)
-       strcpy(cpy, str);
+
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+
+    if ((cpy = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
+       MultiByteToWideChar(CP_ACP, 0, str, -1, cpy, len);
+
     return cpy;
 }
 
-HRESULT assembly_get_name(ASSEMBLY *assembly, LPSTR *name)
+HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name)
 {
     BYTE *ptr;
     LONG offset;
@@ -779,59 +772,43 @@
     return S_OK;
 }
 
-HRESULT assembly_get_path(ASSEMBLY *assembly, LPSTR *path)
-{
-    LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(assembly->path)+1);
+HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path)
+{
+    LPWSTR cpy = HeapAlloc(GetProcessHeap(), 0, (strlenW(assembly->path) + 1) * sizeof(WCHAR));
     *path = cpy;
     if (cpy)
-        strcpy(cpy, assembly->path);
+        strcpyW(cpy, assembly->path);
     else
         return E_OUTOFMEMORY;
 
     return S_OK;
 }
 
-HRESULT assembly_get_version(ASSEMBLY *assembly, LPSTR *version)
-{
-    LPSTR verdata;
-    VS_FIXEDFILEINFO *ffi;
-    HRESULT hr = S_OK;
-    DWORD size;
-
-    size = GetFileVersionInfoSizeA(assembly->path, NULL);
-    if (!size)
-        return HRESULT_FROM_WIN32(GetLastError());
-
-    verdata = HeapAlloc(GetProcessHeap(), 0, size);
-    if (!verdata)
+HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version)
+{
+    static const WCHAR format[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
+
+    ASSEMBLYTABLE *asmtbl;
+    LONG offset;
+
+    *version = NULL;
+
+    offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
+    if (offset == -1)
+        return E_FAIL;
+
+    asmtbl = assembly_data_offset(assembly, offset);
+    if (!asmtbl)
+        return E_FAIL;
+
+    *version = HeapAlloc(GetProcessHeap(), 0, sizeof(format) + 4 * strlen("65535") * sizeof(WCHAR));
+    if (!*version)
         return E_OUTOFMEMORY;
 
-    if (!GetFileVersionInfoA(assembly->path, 0, size, verdata))
-    {
-        hr = HRESULT_FROM_WIN32(GetLastError());
-        goto done;
-    }
-
-    if (!VerQueryValueA(verdata, "\\", (LPVOID *)&ffi, &size))
-    {
-        hr = HRESULT_FROM_WIN32(GetLastError());
-        goto done;
-    }
-
-    *version = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
-    if (!*version)
-    {
-        hr = E_OUTOFMEMORY;
-        goto done;
-    }
-
-    sprintf(*version, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
-            LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
-            LOWORD(ffi->dwFileVersionLS));
-
-done:
-    HeapFree(GetProcessHeap(), 0, verdata);
-    return hr;
+    sprintfW(*version, format, asmtbl->MajorVersion, asmtbl->MinorVersion,
+             asmtbl->BuildNumber, asmtbl->RevisionNumber);
+
+    return S_OK;
 }
 
 HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme)
@@ -845,26 +822,7 @@
     return GetData(&assembly->blobs[index], size);
 }
 
-static void bytes_to_str(BYTE *bytes, DWORD len, LPSTR str)
-{
-    DWORD i;
-
-    static const char 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, LPSTR *token)
+HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token)
 {
     ASSEMBLYTABLE *asmtbl;
     ULONG i, size;
@@ -875,7 +833,7 @@
     BYTE *pubkey;
     BYTE tokbytes[BYTES_PER_TOKEN];
     HRESULT hr = E_FAIL;
-    LPSTR tok;
+    LPWSTR tok;
 
     *token = NULL;
 
@@ -916,15 +874,14 @@
     for (i = size - 1; i >= size - 8; i--)
         tokbytes[size - i - 1] = hashdata[i];
 
-    tok = HeapAlloc(GetProcessHeap(), 0, TOKEN_LENGTH);
+    tok = HeapAlloc(GetProcessHeap(), 0, (TOKEN_LENGTH + 1) * sizeof(WCHAR));
     if (!tok)
     {
         hr = E_OUTOFMEMORY;
         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;

Modified: trunk/reactos/dll/win32/fusion/fusion.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/fusion.c?rev=41022&r1=41021&r2=41022&view=diff
==============================================================================
--- trunk/reactos/dll/win32/fusion/fusion.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/fusion/fusion.c [iso-8859-1] Wed May 20 18:43:24 2009
@@ -50,18 +50,6 @@
 {
     FIXME("(%s, %d, %s, %d, %p, %p) stub!\n", debugstr_w(pwzAssemblyIdentity1),
           fUnified1, debugstr_w(pwzAssemblyIdentity2), fUnified2, pfEquivalent, pResult);
-
-    return E_NOTIMPL;
-}
-
-/******************************************************************
- *  CreateAssemblyEnum   (FUSION.@)
- */
-HRESULT WINAPI CreateAssemblyEnum(IAssemblyEnum **pEnum, IUnknown *pUnkReserved,
-                                  IAssemblyName *pName, DWORD dwFlags, LPVOID pvReserved)
-{
-    FIXME("(%p, %p, %p, %08x, %p) stub!\n", pEnum, pUnkReserved,
-          pName, dwFlags, pvReserved);
 
     return E_NOTIMPL;
 }
@@ -129,8 +117,11 @@
     static const WCHAR gac[] = {'G','A','C',0};
     static const WCHAR nativeimg[] = {
         'N','a','t','i','v','e','I','m','a','g','e','s','_',0};
-    static const WCHAR zapfmt[] = {
-        '%','s','\\','%','s','\\','%','s','%','s','_','3','2',0};
+#ifdef _WIN64
+    static const WCHAR zapfmt[] = {'%','s','\\','%','s','\\','%','s','%','s','_','6','4',0};
+#else
+    static const WCHAR zapfmt[] = {'%','s','\\','%','s','\\','%','s','%','s','_','3','2',0};
+#endif
 
     TRACE("(%08x, %p, %p)\n", dwCacheFlags, pwzCachePath, pcchPath);
 

Modified: trunk/reactos/dll/win32/fusion/fusion.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/fusion.rbuild?rev=41022&r1=41021&r2=41022&view=diff
==============================================================================
--- trunk/reactos/dll/win32/fusion/fusion.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/fusion/fusion.rbuild [iso-8859-1] Wed May 20 18:43:24 2009
@@ -10,6 +10,7 @@
 	<library>advapi32</library>
 	<library>dbghelp</library>
 	<file>asmcache.c</file>
+	<file>asmenum.c</file>
 	<file>asmname.c</file>
 	<file>assembly.c</file>
 	<file>fusion.c</file>

Modified: trunk/reactos/dll/win32/fusion/fusionpriv.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/fusion/fusionpriv.h?rev=41022&r1=41021&r2=41022&view=diff
==============================================================================
--- trunk/reactos/dll/win32/fusion/fusionpriv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/fusion/fusionpriv.h [iso-8859-1] Wed May 20 18:43:24 2009
@@ -26,6 +26,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
+#include "winver.h"
 
 #include <pshpack1.h>
 
@@ -429,10 +430,44 @@
 
 HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file);
 HRESULT assembly_release(ASSEMBLY *assembly);
-HRESULT assembly_get_name(ASSEMBLY *assembly, LPSTR *name);
-HRESULT assembly_get_path(ASSEMBLY *assembly, LPSTR *path);
-HRESULT assembly_get_version(ASSEMBLY *assembly, LPSTR *version);
+HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name);
+HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path);
+HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version);
 HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme);
-HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token);
+HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token);
+
+static inline LPWSTR strdupW(LPCWSTR src)
+{
+    LPWSTR dest;
+
+    if (!src)
+        return NULL;
+
+    dest = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src) + 1) * sizeof(WCHAR));
+    if (dest)
+        lstrcpyW(dest, src);
+
+    return dest;
+}
+
+#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__ */



More information about the Ros-diffs mailing list