diff --git a/reactos/dll/win32/fusion/asmcache.c b/reactos/dll/win32/fusion/asmcache.c index 7334e5d793e..fe4e12a49a9 100644 --- a/reactos/dll/win32/fusion/asmcache.c +++ b/reactos/dll/win32/fusion/asmcache.c @@ -123,15 +123,20 @@ static BOOL get_assembly_directory(LPWSTR dir, DWORD size, BYTE architecture) /* IAssemblyCache */ typedef struct { - const IAssemblyCacheVtbl *lpIAssemblyCacheVtbl; + IAssemblyCache IAssemblyCache_iface; LONG ref; } IAssemblyCacheImpl; +static inline IAssemblyCacheImpl *impl_from_IAssemblyCache(IAssemblyCache *iface) +{ + return CONTAINING_RECORD(iface, IAssemblyCacheImpl, IAssemblyCache_iface); +} + static HRESULT WINAPI IAssemblyCacheImpl_QueryInterface(IAssemblyCache *iface, REFIID riid, LPVOID *ppobj) { - IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + IAssemblyCacheImpl *This = impl_from_IAssemblyCache(iface); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); @@ -151,7 +156,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryInterface(IAssemblyCache *iface, static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface) { - IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + IAssemblyCacheImpl *This = impl_from_IAssemblyCache(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); @@ -161,7 +166,7 @@ static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface) static ULONG WINAPI IAssemblyCacheImpl_Release(IAssemblyCache *iface) { - IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + IAssemblyCacheImpl *This = impl_from_IAssemblyCache(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); @@ -223,6 +228,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface if (!pAsmInfo) goto done; + hr = IAssemblyName_GetPath(next, pAsmInfo->pszCurrentAssemblyPathBuf, &pAsmInfo->cchBuf); + pAsmInfo->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED; done: @@ -362,10 +369,10 @@ HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved if (!cache) return E_OUTOFMEMORY; - cache->lpIAssemblyCacheVtbl = &AssemblyCacheVtbl; + cache->IAssemblyCache_iface.lpVtbl = &AssemblyCacheVtbl; cache->ref = 1; - *ppAsmCache = (IAssemblyCache *)cache; + *ppAsmCache = &cache->IAssemblyCache_iface; return S_OK; } @@ -373,15 +380,20 @@ HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved /* IAssemblyCacheItem */ typedef struct { - const IAssemblyCacheItemVtbl *lpIAssemblyCacheItemVtbl; + IAssemblyCacheItem IAssemblyCacheItem_iface; LONG ref; } IAssemblyCacheItemImpl; +static inline IAssemblyCacheItemImpl *impl_from_IAssemblyCacheItem(IAssemblyCacheItem *iface) +{ + return CONTAINING_RECORD(iface, IAssemblyCacheItemImpl, IAssemblyCacheItem_iface); +} + static HRESULT WINAPI IAssemblyCacheItemImpl_QueryInterface(IAssemblyCacheItem *iface, REFIID riid, LPVOID *ppobj) { - IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + IAssemblyCacheItemImpl *This = impl_from_IAssemblyCacheItem(iface); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); @@ -401,7 +413,7 @@ static HRESULT WINAPI IAssemblyCacheItemImpl_QueryInterface(IAssemblyCacheItem * static ULONG WINAPI IAssemblyCacheItemImpl_AddRef(IAssemblyCacheItem *iface) { - IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + IAssemblyCacheItemImpl *This = impl_from_IAssemblyCacheItem(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); @@ -411,7 +423,7 @@ static ULONG WINAPI IAssemblyCacheItemImpl_AddRef(IAssemblyCacheItem *iface) static ULONG WINAPI IAssemblyCacheItemImpl_Release(IAssemblyCacheItem *iface) { - IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + IAssemblyCacheItemImpl *This = impl_from_IAssemblyCacheItem(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); diff --git a/reactos/dll/win32/fusion/asmenum.c b/reactos/dll/win32/fusion/asmenum.c index 3706f07f511..99462ed2c5d 100644 --- a/reactos/dll/win32/fusion/asmenum.c +++ b/reactos/dll/win32/fusion/asmenum.c @@ -45,17 +45,22 @@ typedef struct _tagASMNAME typedef struct { - const IAssemblyEnumVtbl *lpIAssemblyEnumVtbl; + IAssemblyEnum IAssemblyEnum_iface; struct list assemblies; struct list *iter; LONG ref; } IAssemblyEnumImpl; +static inline IAssemblyEnumImpl *impl_from_IAssemblyEnum(IAssemblyEnum *iface) +{ + return CONTAINING_RECORD(iface, IAssemblyEnumImpl, IAssemblyEnum_iface); +} + static HRESULT WINAPI IAssemblyEnumImpl_QueryInterface(IAssemblyEnum *iface, REFIID riid, LPVOID *ppobj) { - IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface; + IAssemblyEnumImpl *This = impl_from_IAssemblyEnum(iface); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); @@ -75,7 +80,7 @@ static HRESULT WINAPI IAssemblyEnumImpl_QueryInterface(IAssemblyEnum *iface, static ULONG WINAPI IAssemblyEnumImpl_AddRef(IAssemblyEnum *iface) { - IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface; + IAssemblyEnumImpl *This = impl_from_IAssemblyEnum(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); @@ -85,7 +90,7 @@ static ULONG WINAPI IAssemblyEnumImpl_AddRef(IAssemblyEnum *iface) static ULONG WINAPI IAssemblyEnumImpl_Release(IAssemblyEnum *iface) { - IAssemblyEnumImpl *This = (IAssemblyEnumImpl *)iface; + IAssemblyEnumImpl *This = impl_from_IAssemblyEnum(iface); ULONG refCount = InterlockedDecrement(&This->ref); struct list *item, *cursor; @@ -113,7 +118,7 @@ static HRESULT WINAPI IAssemblyEnumImpl_GetNextAssembly(IAssemblyEnum *iface, IAssemblyName **ppName, DWORD dwFlags) { - IAssemblyEnumImpl *asmenum = (IAssemblyEnumImpl *)iface; + IAssemblyEnumImpl *asmenum = impl_from_IAssemblyEnum(iface); ASMNAME *asmname; TRACE("(%p, %p, %p, %d)\n", iface, pvReserved, ppName, dwFlags); @@ -135,7 +140,7 @@ static HRESULT WINAPI IAssemblyEnumImpl_GetNextAssembly(IAssemblyEnum *iface, static HRESULT WINAPI IAssemblyEnumImpl_Reset(IAssemblyEnum *iface) { - IAssemblyEnumImpl *asmenum = (IAssemblyEnumImpl *)iface; + IAssemblyEnumImpl *asmenum = impl_from_IAssemblyEnum(iface); TRACE("(%p)\n", iface); @@ -287,6 +292,7 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, WIN32_FIND_DATAW ffd; WCHAR buf[MAX_PATH]; WCHAR disp[MAX_PATH]; + WCHAR asmpath[MAX_PATH]; ASMNAME *asmname; HANDLE hfind; LPWSTR ptr; @@ -297,9 +303,9 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, 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',',',' ', + static const WCHAR path_fmt[] = {'%','s','\\','%','s','\\','%','s','.','d','l','l',0}; + static const WCHAR fmt[] = {'%','s',',',' ','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}; @@ -325,17 +331,17 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, else ptr = ffd.cFileName; - sprintfW(parent, parent_fmt, ptr); + lstrcpyW(parent, ptr); } else if (depth == 1) { + sprintfW(asmpath, path_fmt, path, ffd.cFileName, parent); + ptr = strstrW(ffd.cFileName, dblunder); *ptr = '\0'; ptr += 2; - sprintfW(buf, fmt, ffd.cFileName, ptr); - lstrcpyW(disp, parent); - lstrcatW(disp, buf); + sprintfW(disp, fmt, parent, ffd.cFileName, ptr); asmname = HeapAlloc(GetProcessHeap(), 0, sizeof(ASMNAME)); if (!asmname) @@ -352,6 +358,14 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, break; } + hr = IAssemblyName_SetPath(asmname->name, asmpath); + if (FAILED(hr)) + { + IAssemblyName_Release(asmname->name); + HeapFree(GetProcessHeap(), 0, asmname); + break; + } + insert_assembly(assemblies, asmname); continue; } @@ -422,7 +436,7 @@ HRESULT WINAPI CreateAssemblyEnum(IAssemblyEnum **pEnum, IUnknown *pUnkReserved, if (!asmenum) return E_OUTOFMEMORY; - asmenum->lpIAssemblyEnumVtbl = &AssemblyEnumVtbl; + asmenum->IAssemblyEnum_iface.lpVtbl = &AssemblyEnumVtbl; asmenum->ref = 1; list_init(&asmenum->assemblies); @@ -437,7 +451,7 @@ HRESULT WINAPI CreateAssemblyEnum(IAssemblyEnum **pEnum, IUnknown *pUnkReserved, } asmenum->iter = list_head(&asmenum->assemblies); - *pEnum = (IAssemblyEnum *)asmenum; + *pEnum = &asmenum->IAssemblyEnum_iface; return S_OK; } diff --git a/reactos/dll/win32/fusion/asmname.c b/reactos/dll/win32/fusion/asmname.c index bcf49a7f214..34f05559ae4 100644 --- a/reactos/dll/win32/fusion/asmname.c +++ b/reactos/dll/win32/fusion/asmname.c @@ -19,6 +19,7 @@ */ #include +#include #define COBJMACROS #define INITGUID @@ -40,6 +41,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(fusion); typedef struct { const IAssemblyNameVtbl *lpIAssemblyNameVtbl; + LPWSTR path; + LPWSTR displayname; LPWSTR name; LPWSTR culture; @@ -104,6 +107,7 @@ static ULONG WINAPI IAssemblyNameImpl_Release(IAssemblyName *iface) if (!refCount) { + HeapFree(GetProcessHeap(), 0, This->path); HeapFree(GetProcessHeap(), 0, This->displayname); HeapFree(GetProcessHeap(), 0, This->name); HeapFree(GetProcessHeap(), 0, This->culture); @@ -425,6 +429,43 @@ static const IAssemblyNameVtbl AssemblyNameVtbl = { IAssemblyNameImpl_Clone }; +/* Internal methods */ +HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path) +{ + IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface; + + assert(name->lpIAssemblyNameVtbl == &AssemblyNameVtbl); + + name->path = strdupW(path); + if (!name->path) + return E_OUTOFMEMORY; + + return S_OK; +} + +HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len) +{ + ULONG buffer_size = *len; + IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface; + + assert(name->lpIAssemblyNameVtbl == &AssemblyNameVtbl); + + if (!name->path) + return S_OK; + + if (!buf) + buffer_size = 0; + + *len = lstrlenW(name->path) + 1; + + if (*len <= buffer_size) + lstrcpyW(buf, name->path); + else + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + + return S_OK; +} + static HRESULT parse_version(IAssemblyNameImpl *name, LPWSTR version) { LPWSTR beg, end; @@ -450,7 +491,7 @@ static HRESULT parse_version(IAssemblyNameImpl *name, LPWSTR version) return S_OK; } -static HRESULT parse_culture(IAssemblyNameImpl *name, LPWSTR culture) +static HRESULT parse_culture(IAssemblyNameImpl *name, LPCWSTR culture) { static const WCHAR empty[] = {0}; @@ -480,7 +521,7 @@ static BYTE hextobyte(WCHAR c) return 0; } -static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPWSTR pubkey) +static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPCWSTR pubkey) { int i; BYTE val; @@ -522,8 +563,16 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam if (!str) return E_OUTOFMEMORY; - ptr = strstrW(str, separator); + ptr = strchrW(str, ','); if (ptr) *ptr = '\0'; + + /* no ',' but ' ' only */ + if( !ptr && strchrW(str, ' ') ) + { + hr = FUSION_E_INVALID_NAME; + goto done; + } + name->name = strdupW(str); if (!name->name) return E_OUTOFMEMORY; diff --git a/reactos/dll/win32/fusion/assembly.c b/reactos/dll/win32/fusion/assembly.c index 328b2792c9c..a3abc4e98d8 100644 --- a/reactos/dll/win32/fusion/assembly.c +++ b/reactos/dll/win32/fusion/assembly.c @@ -146,7 +146,7 @@ static VOID *assembly_data_offset(ASSEMBLY *assembly, ULONG offset) #define MAX_TABLES_3BIT_ENCODE 8191 #define MAX_TABLES_5BIT_ENCODE 2047 -static inline ULONG get_table_size(ASSEMBLY *assembly, DWORD index) +static inline ULONG get_table_size(const ASSEMBLY *assembly, DWORD index) { DWORD size; INT tables; @@ -731,11 +731,11 @@ HRESULT assembly_release(ASSEMBLY *assembly) return S_OK; } -static LPWSTR assembly_dup_str(ASSEMBLY *assembly, DWORD index) +static LPWSTR assembly_dup_str(const ASSEMBLY *assembly, DWORD index) { int len; LPWSTR cpy; - LPSTR str = (LPSTR)&assembly->strings[index]; + LPCSTR str = (LPCSTR)&assembly->strings[index]; len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); @@ -772,7 +772,7 @@ HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name) return S_OK; } -HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path) +HRESULT assembly_get_path(const ASSEMBLY *assembly, LPWSTR *path) { LPWSTR cpy = HeapAlloc(GetProcessHeap(), 0, (strlenW(assembly->path) + 1) * sizeof(WCHAR)); *path = cpy; diff --git a/reactos/dll/win32/fusion/fusion.rbuild b/reactos/dll/win32/fusion/fusion.rbuild index f95cee92880..b1732dac348 100644 --- a/reactos/dll/win32/fusion/fusion.rbuild +++ b/reactos/dll/win32/fusion/fusion.rbuild @@ -8,6 +8,7 @@ shlwapi advapi32 dbghelp + msvcrt user32 asmcache.c asmenum.c diff --git a/reactos/dll/win32/fusion/fusionpriv.h b/reactos/dll/win32/fusion/fusionpriv.h index 6f4b28dc793..c114cd4b6bc 100644 --- a/reactos/dll/win32/fusion/fusionpriv.h +++ b/reactos/dll/win32/fusion/fusionpriv.h @@ -431,11 +431,14 @@ typedef struct tagASSEMBLY ASSEMBLY; HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file); HRESULT assembly_release(ASSEMBLY *assembly); HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name); -HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path); +HRESULT assembly_get_path(const ASSEMBLY *assembly, LPWSTR *path); HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version); BYTE assembly_get_architecture(ASSEMBLY *assembly); HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token); +extern HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path); +extern HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len); + static inline LPWSTR strdupW(LPCWSTR src) { LPWSTR dest;