From 01bc267907e6c0c2ccf335c838a3d212eb9cd60a Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 10 Sep 2008 08:47:30 +0000 Subject: [PATCH] sync fusion.dll with wine 1.1.4 svn path=/trunk/; revision=36114 --- reactos/baseaddress.rbuild | 1 + reactos/boot/bootdata/packages/reactos.dff | 1 + reactos/dll/win32/fusion/asmcache.c | 476 +++++++++++ reactos/dll/win32/fusion/asmname.c | 525 ++++++++++++ reactos/dll/win32/fusion/assembly.c | 938 +++++++++++++++++++++ reactos/dll/win32/fusion/fusion.c | 186 ++++ reactos/dll/win32/fusion/fusion.rbuild | 22 + reactos/dll/win32/fusion/fusion.spec | 17 + reactos/dll/win32/fusion/fusion_main.c | 47 ++ reactos/dll/win32/fusion/fusion_ros.diff | 11 + reactos/dll/win32/fusion/fusionpriv.h | 438 ++++++++++ reactos/dll/win32/win32.rbuild | 3 + 12 files changed, 2665 insertions(+) create mode 100644 reactos/dll/win32/fusion/asmcache.c create mode 100644 reactos/dll/win32/fusion/asmname.c create mode 100644 reactos/dll/win32/fusion/assembly.c create mode 100644 reactos/dll/win32/fusion/fusion.c create mode 100644 reactos/dll/win32/fusion/fusion.rbuild create mode 100644 reactos/dll/win32/fusion/fusion.spec create mode 100644 reactos/dll/win32/fusion/fusion_main.c create mode 100644 reactos/dll/win32/fusion/fusion_ros.diff create mode 100644 reactos/dll/win32/fusion/fusionpriv.h diff --git a/reactos/baseaddress.rbuild b/reactos/baseaddress.rbuild index 34037555c1e..76886828f62 100644 --- a/reactos/baseaddress.rbuild +++ b/reactos/baseaddress.rbuild @@ -187,6 +187,7 @@ + diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 9d94f51efe8..a2eda74d94b 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -252,6 +252,7 @@ dll\win32\devmgr\devmgr.dll 1 dll\win32\dhcpcsvc\dhcpcsvc.dll 1 dll\win32\dnsapi\dnsapi.dll 1 dll\win32\fmifs\fmifs.dll 1 +dll\win32\fusion\fusion.dll 1 dll\win32\gdi32\gdi32.dll 1 dll\win32\gdiplus\gdiplus.dll 1 dll\win32\glu32\glu32.dll 1 diff --git a/reactos/dll/win32/fusion/asmcache.c b/reactos/dll/win32/fusion/asmcache.c new file mode 100644 index 00000000000..57c7aeded7d --- /dev/null +++ b/reactos/dll/win32/fusion/asmcache.c @@ -0,0 +1,476 @@ +/* + * IAssemblyCache 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 +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winver.h" +#include "wincrypt.h" +#include "winreg.h" +#include "shlwapi.h" +#include "dbghelp.h" +#include "ole2.h" +#include "fusion.h" +#include "corerror.h" + +#include "fusionpriv.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(fusion); + +static BOOL create_full_path(LPCSTR path) +{ + LPSTR new_path; + BOOL ret = TRUE; + int len; + + new_path = HeapAlloc(GetProcessHeap(), 0, lstrlenA(path) + 1); + if (!new_path) + return FALSE; + + lstrcpyA(new_path, path); + + while ((len = lstrlenA(new_path)) && new_path[len - 1] == '\\') + new_path[len - 1] = 0; + + while (!CreateDirectoryA(new_path, NULL)) + { + LPSTR slash; + DWORD last_error = GetLastError(); + + if(last_error == ERROR_ALREADY_EXISTS) + break; + + if(last_error != ERROR_PATH_NOT_FOUND) + { + ret = FALSE; + break; + } + + if(!(slash = strrchr(new_path, '\\'))) + { + ret = FALSE; + break; + } + + len = slash - new_path; + new_path[len] = 0; + if(!create_full_path(new_path)) + { + ret = FALSE; + break; + } + + new_path[len] = '\\'; + } + + HeapFree(GetProcessHeap(), 0, new_path); + return ret; +} + +/* IAssemblyCache */ + +typedef struct { + const IAssemblyCacheVtbl *lpIAssemblyCacheVtbl; + + LONG ref; +} IAssemblyCacheImpl; + +static HRESULT WINAPI IAssemblyCacheImpl_QueryInterface(IAssemblyCache *iface, + REFIID riid, LPVOID *ppobj) +{ + IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAssemblyCache)) + { + 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 IAssemblyCacheImpl_AddRef(IAssemblyCache *iface) +{ + IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); + + return refCount; +} + +static ULONG WINAPI IAssemblyCacheImpl_Release(IAssemblyCache *iface) +{ + IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)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 IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface, + DWORD dwFlags, + LPCWSTR pszAssemblyName, + LPCFUSION_INSTALL_REFERENCE pRefData, + ULONG *pulDisposition) +{ + FIXME("(%p, %d, %s, %p, %p) stub!\n", iface, dwFlags, + debugstr_w(pszAssemblyName), pRefData, pulDisposition); + + return E_NOTIMPL; +} + +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); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyCacheItem(IAssemblyCache *iface, + DWORD dwFlags, + PVOID pvReserved, + IAssemblyCacheItem **ppAsmItem, + LPCWSTR pszAssemblyName) +{ + FIXME("(%p, %d, %p, %p, %s) stub!\n", iface, dwFlags, pvReserved, + ppAsmItem, debugstr_w(pszAssemblyName)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyScavenger(IAssemblyCache *iface, + IUnknown **ppUnkReserved) +{ + FIXME("(%p, %p) stub!\n", iface, ppUnkReserved); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, + DWORD dwFlags, + LPCWSTR pszManifestFilePath, + LPCFUSION_INSTALL_REFERENCE pRefData) +{ + 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 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); + + if (!pszManifestFilePath || !*pszManifestFilePath) + return E_INVALIDARG; + + if (!(ext = strrchrW(pszManifestFilePath, '.'))) + return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); + + if (lstrcmpiW(ext, ext_exe) && lstrcmpiW(ext, ext_dll)) + return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); + + if (GetFileAttributesW(pszManifestFilePath) == INVALID_FILE_ATTRIBUTES) + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + + hr = assembly_create(&assembly, pszManifestFilePath); + if (FAILED(hr)) + { + hr = COR_E_ASSEMBLYEXPECTED; + goto done; + } + + hr = assembly_get_name(assembly, &name); + if (FAILED(hr)) + goto done; + + hr = assembly_get_pubkey_token(assembly, &token); + if (FAILED(hr)) + goto done; + + hr = assembly_get_version(assembly, &version); + 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); + + create_full_path(path); + + hr = assembly_get_path(assembly, &asmpath); + if (FAILED(hr)) + goto done; + + filename = PathFindFileNameA(asmpath); + + lstrcatA(path, filename); + if (!CopyFileA(asmpath, path, FALSE)) + hr = HRESULT_FROM_WIN32(GetLastError()); + +done: + HeapFree(GetProcessHeap(), 0, name); + HeapFree(GetProcessHeap(), 0, token); + HeapFree(GetProcessHeap(), 0, version); + HeapFree(GetProcessHeap(), 0, asmpath); + assembly_release(assembly); + return hr; +} + +static const IAssemblyCacheVtbl AssemblyCacheVtbl = { + IAssemblyCacheImpl_QueryInterface, + IAssemblyCacheImpl_AddRef, + IAssemblyCacheImpl_Release, + IAssemblyCacheImpl_UninstallAssembly, + IAssemblyCacheImpl_QueryAssemblyInfo, + IAssemblyCacheImpl_CreateAssemblyCacheItem, + IAssemblyCacheImpl_CreateAssemblyScavenger, + IAssemblyCacheImpl_InstallAssembly +}; + +/****************************************************************** + * CreateAssemblyCache (FUSION.@) + */ +HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved) +{ + IAssemblyCacheImpl *cache; + + TRACE("(%p, %d)\n", ppAsmCache, dwReserved); + + if (!ppAsmCache) + return E_INVALIDARG; + + *ppAsmCache = NULL; + + cache = HeapAlloc(GetProcessHeap(), 0, sizeof(IAssemblyCacheImpl)); + if (!cache) + return E_OUTOFMEMORY; + + cache->lpIAssemblyCacheVtbl = &AssemblyCacheVtbl; + cache->ref = 1; + + *ppAsmCache = (IAssemblyCache *)cache; + + return S_OK; +} + +/* IAssemblyCacheItem */ + +typedef struct { + const IAssemblyCacheItemVtbl *lpIAssemblyCacheItemVtbl; + + LONG ref; +} IAssemblyCacheItemImpl; + +static HRESULT WINAPI IAssemblyCacheItemImpl_QueryInterface(IAssemblyCacheItem *iface, + REFIID riid, LPVOID *ppobj) +{ + IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAssemblyCacheItem)) + { + 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 IAssemblyCacheItemImpl_AddRef(IAssemblyCacheItem *iface) +{ + IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); + + return refCount; +} + +static ULONG WINAPI IAssemblyCacheItemImpl_Release(IAssemblyCacheItem *iface) +{ + IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)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 IAssemblyCacheItemImpl_CreateStream(IAssemblyCacheItem *iface, + DWORD dwFlags, + LPCWSTR pszStreamName, + DWORD dwFormat, + DWORD dwFormatFlags, + IStream **ppIStream, + ULARGE_INTEGER *puliMaxSize) +{ + FIXME("(%p, %d, %s, %d, %d, %p, %p) stub!\n", iface, dwFlags, + debugstr_w(pszStreamName), dwFormat, dwFormatFlags, ppIStream, puliMaxSize); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheItemImpl_Commit(IAssemblyCacheItem *iface, + DWORD dwFlags, + ULONG *pulDisposition) +{ + FIXME("(%p, %d, %p) stub!\n", iface, dwFlags, pulDisposition); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheItemImpl_AbortItem(IAssemblyCacheItem *iface) +{ + FIXME("(%p) stub!\n", iface); + return E_NOTIMPL; +} + +static const IAssemblyCacheItemVtbl AssemblyCacheItemVtbl = { + IAssemblyCacheItemImpl_QueryInterface, + IAssemblyCacheItemImpl_AddRef, + IAssemblyCacheItemImpl_Release, + IAssemblyCacheItemImpl_CreateStream, + 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 +}; diff --git a/reactos/dll/win32/fusion/asmname.c b/reactos/dll/win32/fusion/asmname.c new file mode 100644 index 00000000000..81a5b82ebbf --- /dev/null +++ b/reactos/dll/win32/fusion/asmname.c @@ -0,0 +1,525 @@ +/* + * IAssemblyName 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 + +#define COBJMACROS +#define INITGUID + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "guiddef.h" +#include "fusion.h" +#include "corerror.h" + +#include "wine/debug.h" +#include "wine/unicode.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; + + LPWSTR displayname; + LPWSTR name; + LPWSTR culture; + + BYTE version[4]; + DWORD versize; + + BYTE pubkey[8]; + BOOL haspubkey; + + LONG ref; +} IAssemblyNameImpl; + +static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface, + REFIID riid, LPVOID *ppobj) +{ + IAssemblyNameImpl *This = (IAssemblyNameImpl *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAssemblyName)) + { + 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 IAssemblyNameImpl_AddRef(IAssemblyName *iface) +{ + IAssemblyNameImpl *This = (IAssemblyNameImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); + + return refCount; +} + +static ULONG WINAPI IAssemblyNameImpl_Release(IAssemblyName *iface) +{ + IAssemblyNameImpl *This = (IAssemblyNameImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); + + if (!refCount) + { + HeapFree(GetProcessHeap(), 0, This->displayname); + HeapFree(GetProcessHeap(), 0, This->name); + HeapFree(GetProcessHeap(), 0, This->culture); + HeapFree(GetProcessHeap(), 0, This); + } + + return refCount; +} + +static HRESULT WINAPI IAssemblyNameImpl_SetProperty(IAssemblyName *iface, + DWORD PropertyId, + LPVOID pvProperty, + DWORD cbProperty) +{ + FIXME("(%p, %d, %p, %d) stub!\n", iface, PropertyId, pvProperty, cbProperty); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, + DWORD PropertyId, + LPVOID pvProperty, + LPDWORD pcbProperty) +{ + IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface; + + TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty); + + *((LPWSTR)pvProperty) = '\0'; + + switch (PropertyId) + { + case ASM_NAME_NULL_PUBLIC_KEY: + case ASM_NAME_NULL_PUBLIC_KEY_TOKEN: + if (name->haspubkey) + return S_OK; + return S_FALSE; + + case ASM_NAME_NULL_CUSTOM: + return S_OK; + + case ASM_NAME_NAME: + *pcbProperty = 0; + if (name->name) + { + lstrcpyW((LPWSTR)pvProperty, name->name); + *pcbProperty = (lstrlenW(name->name) + 1) * 2; + } + break; + + case ASM_NAME_MAJOR_VERSION: + *pcbProperty = 0; + *((LPDWORD)pvProperty) = name->version[0]; + if (name->versize >= 1) + *pcbProperty = sizeof(WORD); + break; + + case ASM_NAME_MINOR_VERSION: + *pcbProperty = 0; + *((LPDWORD)pvProperty) = name->version[1]; + if (name->versize >= 2) + *pcbProperty = sizeof(WORD); + break; + + case ASM_NAME_BUILD_NUMBER: + *pcbProperty = 0; + *((LPDWORD)pvProperty) = name->version[2]; + if (name->versize >= 3) + *pcbProperty = sizeof(WORD); + break; + + case ASM_NAME_REVISION_NUMBER: + *pcbProperty = 0; + *((LPDWORD)pvProperty) = name->version[3]; + if (name->versize >= 4) + *pcbProperty = sizeof(WORD); + break; + + case ASM_NAME_CULTURE: + *pcbProperty = 0; + if (name->culture) + { + lstrcpyW((LPWSTR)pvProperty, name->culture); + *pcbProperty = (lstrlenW(name->culture) + 1) * 2; + } + break; + + case ASM_NAME_PUBLIC_KEY_TOKEN: + *pcbProperty = 0; + if (name->haspubkey) + { + memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2); + *pcbProperty = sizeof(DWORD) * 2; + } + break; + + default: + *pcbProperty = 0; + break; + } + + return S_OK; +} + +static HRESULT WINAPI IAssemblyNameImpl_Finalize(IAssemblyName *iface) +{ + FIXME("(%p) stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface, + LPOLESTR szDisplayName, + LPDWORD pccDisplayName, + DWORD dwDisplayFlags) +{ + IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface; + + TRACE("(%p, %s, %p, %d)\n", iface, debugstr_w(szDisplayName), + pccDisplayName, dwDisplayFlags); + + if (!name->displayname || !*name->displayname) + return FUSION_E_INVALID_NAME; + + lstrcpyW(szDisplayName, name->displayname); + *pccDisplayName = lstrlenW(szDisplayName) + 1; + + return S_OK; +} + +static HRESULT WINAPI IAssemblyNameImpl_Reserved(IAssemblyName *iface, + REFIID refIID, + IUnknown *pUnkReserved1, + IUnknown *pUnkReserved2, + LPCOLESTR szReserved, + LONGLONG llReserved, + LPVOID pvReserved, + DWORD cbReserved, + LPVOID *ppReserved) +{ + TRACE("(%p, %s, %p, %p, %s, %x%08x, %p, %d, %p)\n", iface, + debugstr_guid(refIID), pUnkReserved1, pUnkReserved2, + debugstr_w(szReserved), (DWORD)(llReserved >> 32), (DWORD)llReserved, + pvReserved, cbReserved, ppReserved); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyNameImpl_GetName(IAssemblyName *iface, + LPDWORD lpcwBuffer, + WCHAR *pwzName) +{ + IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface; + + TRACE("(%p, %p, %p)\n", iface, lpcwBuffer, pwzName); + + if (!name->name) + { + *pwzName = '\0'; + *lpcwBuffer = 0; + return S_OK; + } + + lstrcpyW(pwzName, name->name); + *lpcwBuffer = lstrlenW(pwzName) + 1; + + return S_OK; +} + +static HRESULT WINAPI IAssemblyNameImpl_GetVersion(IAssemblyName *iface, + LPDWORD pdwVersionHi, + LPDWORD pdwVersionLow) +{ + IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface; + + TRACE("(%p, %p, %p)\n", iface, pdwVersionHi, pdwVersionLow); + + *pdwVersionHi = 0; + *pdwVersionLow = 0; + + if (name->versize != 4) + return FUSION_E_INVALID_NAME; + + *pdwVersionHi = (name->version[0] << 16) + name->version[1]; + *pdwVersionLow = (name->version[2] << 16) + name->version[3]; + + return S_OK; +} + +static HRESULT WINAPI IAssemblyNameImpl_IsEqual(IAssemblyName *iface, + IAssemblyName *pName, + DWORD dwCmpFlags) +{ + FIXME("(%p, %p, %d) stub!\n", iface, pName, dwCmpFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyNameImpl_Clone(IAssemblyName *iface, + IAssemblyName **pName) +{ + FIXME("(%p, %p) stub!\n", iface, pName); + return E_NOTIMPL; +} + +static const IAssemblyNameVtbl AssemblyNameVtbl = { + IAssemblyNameImpl_QueryInterface, + IAssemblyNameImpl_AddRef, + IAssemblyNameImpl_Release, + IAssemblyNameImpl_SetProperty, + IAssemblyNameImpl_GetProperty, + IAssemblyNameImpl_Finalize, + IAssemblyNameImpl_GetDisplayName, + IAssemblyNameImpl_Reserved, + IAssemblyNameImpl_GetName, + IAssemblyNameImpl_GetVersion, + IAssemblyNameImpl_IsEqual, + IAssemblyNameImpl_Clone +}; + +static HRESULT parse_version(IAssemblyNameImpl *name, LPWSTR version) +{ + LPWSTR beg, end; + int i; + + for (i = 0, beg = version; i < 4; i++) + { + if (!*beg) + return S_OK; + + end = strchrW(beg, '.'); + + if (end) *end = '\0'; + name->version[i] = atolW(beg); + name->versize++; + + if (!end && i < 3) + return S_OK; + + beg = end + 1; + } + + return S_OK; +} + +static HRESULT parse_culture(IAssemblyNameImpl *name, LPWSTR culture) +{ + static const WCHAR empty[] = {0}; + + if (lstrlenW(culture) == 2) + name->culture = strdupW(culture); + else + name->culture = strdupW(empty); + + return S_OK; +} + +#define CHARS_PER_PUBKEY 16 + +static BOOL is_hex(WCHAR c) +{ + return ((c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F') || + (c >= '0' && c <= '9')); +} + +static BYTE hextobyte(WCHAR c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; +} + +static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPWSTR pubkey) +{ + int i; + BYTE val; + + if (lstrlenW(pubkey) < CHARS_PER_PUBKEY) + return FUSION_E_INVALID_NAME; + + for (i = 0; i < CHARS_PER_PUBKEY; i++) + if (!is_hex(pubkey[i])) + return FUSION_E_INVALID_NAME; + + name->haspubkey = TRUE; + + for (i = 0; i < CHARS_PER_PUBKEY; i += 2) + { + val = (hextobyte(pubkey[i]) << 4) + hextobyte(pubkey[i + 1]); + name->pubkey[i / 2] = val; + } + + return S_OK; +} + +static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyName) +{ + LPWSTR str, save; + LPWSTR ptr, ptr2; + HRESULT hr = S_OK; + BOOL done = FALSE; + + static const WCHAR separator[] = {',',' ',0}; + static const WCHAR version[] = {'V','e','r','s','i','o','n',0}; + static const WCHAR culture[] = {'C','u','l','t','u','r','e',0}; + static const WCHAR pubkey[] = + {'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0}; + + if (!szAssemblyName) + return S_OK; + + name->displayname = strdupW(szAssemblyName); + if (!name->displayname) + return E_OUTOFMEMORY; + + str = strdupW(szAssemblyName); + save = str; + if (!str) + return E_OUTOFMEMORY; + + ptr = strstrW(str, separator); + if (ptr) *ptr = '\0'; + name->name = strdupW(str); + if (!name->name) + return E_OUTOFMEMORY; + + if (!ptr) + goto done; + + str = ptr + 2; + while (!done) + { + ptr = strchrW(str, '='); + if (!ptr) + { + hr = FUSION_E_INVALID_NAME; + goto done; + } + + *(ptr++) = '\0'; + if (!*ptr) + { + hr = FUSION_E_INVALID_NAME; + goto done; + } + + if (!(ptr2 = strstrW(ptr, separator))) + { + if (!(ptr2 = strchrW(ptr, '\0'))) + { + hr = FUSION_E_INVALID_NAME; + goto done; + } + + done = TRUE; + } + + *ptr2 = '\0'; + + if (!lstrcmpW(str, version)) + hr = parse_version(name, ptr); + else if (!lstrcmpW(str, culture)) + hr = parse_culture(name, ptr); + else if (!lstrcmpW(str, pubkey)) + hr = parse_pubkey(name, ptr); + + if (FAILED(hr)) + goto done; + + str = ptr2 + 1; + } + +done: + HeapFree(GetProcessHeap(), 0, save); + return hr; +} + +/****************************************************************** + * CreateAssemblyNameObject (FUSION.@) + */ +HRESULT WINAPI CreateAssemblyNameObject(LPASSEMBLYNAME *ppAssemblyNameObj, + LPCWSTR szAssemblyName, DWORD dwFlags, + LPVOID pvReserved) +{ + IAssemblyNameImpl *name; + HRESULT hr; + + TRACE("(%p, %s, %08x, %p) stub!\n", ppAssemblyNameObj, + debugstr_w(szAssemblyName), dwFlags, pvReserved); + + if (!ppAssemblyNameObj) + return E_INVALIDARG; + + if ((dwFlags & CANOF_PARSE_DISPLAY_NAME) && + (!szAssemblyName || !*szAssemblyName)) + return E_INVALIDARG; + + name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAssemblyNameImpl)); + if (!name) + return E_OUTOFMEMORY; + + name->lpIAssemblyNameVtbl = &AssemblyNameVtbl; + name->ref = 1; + + hr = parse_display_name(name, szAssemblyName); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, name); + return hr; + } + + *ppAssemblyNameObj = (IAssemblyName *)name; + + return S_OK; +} diff --git a/reactos/dll/win32/fusion/assembly.c b/reactos/dll/win32/fusion/assembly.c new file mode 100644 index 00000000000..75ca048053c --- /dev/null +++ b/reactos/dll/win32/fusion/assembly.c @@ -0,0 +1,938 @@ +/* + * assembly parser + * + * 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 +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winver.h" +#include "wincrypt.h" +#include "dbghelp.h" +#include "ole2.h" +#include "fusion.h" +#include "corhdr.h" + +#include "fusionpriv.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +#define TableFromToken(tk) (TypeFromToken(tk) >> 24) +#define TokenFromTable(idx) (idx << 24) + +#define MAX_CLR_TABLES 64 + +#define MD_STRINGS_BIT 0x1 +#define MD_GUIDS_BIT 0x2 +#define MD_BLOBS_BIT 0x4 + +typedef struct tagCLRTABLE +{ + INT rows; + DWORD offset; +} CLRTABLE; + +struct tagASSEMBLY +{ + LPSTR path; + + HANDLE hfile; + HANDLE hmap; + BYTE *data; + + IMAGE_NT_HEADERS *nthdr; + IMAGE_COR20_HEADER *corhdr; + + METADATAHDR *metadatahdr; + + METADATATABLESHDR *tableshdr; + DWORD numtables; + DWORD *numrows; + CLRTABLE tables[MAX_CLR_TABLES]; + + DWORD stringsz; + DWORD guidsz; + DWORD blobsz; + + 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) +{ + DWORD offset = rva, limit; + IMAGE_SECTION_HEADER *img; + WORD i; + + img = IMAGE_FIRST_SECTION(nthdrs); + + if (rva < img->PointerToRawData) + return rva; + + for (i = 0; i < nthdrs->FileHeader.NumberOfSections; i++) + { + if (img[i].SizeOfRawData) + limit = img[i].SizeOfRawData; + else + limit = img[i].Misc.VirtualSize; + + if (rva >= img[i].VirtualAddress && + rva < (img[i].VirtualAddress + limit)) + { + if (img[i].PointerToRawData != 0) + { + offset -= img[i].VirtualAddress; + offset += img[i].PointerToRawData; + } + + return offset; + } + } + + return 0; +} + +static BYTE *GetData(BYTE *pData, ULONG *pLength) +{ + if ((*pData & 0x80) == 0x00) + { + *pLength = (*pData & 0x7f); + return pData + 1; + } + + if ((*pData & 0xC0) == 0x80) + { + *pLength = ((*pData & 0x3f) << 8 | *(pData + 1)); + return pData + 2; + } + + if ((*pData & 0xE0) == 0xC0) + { + *pLength = ((*pData & 0x1f) << 24 | *(pData + 1) << 16 | + *(pData + 2) << 8 | *(pData + 3)); + return pData + 4; + } + + *pLength = (ULONG)-1; + return 0; +} + +static VOID *assembly_data_offset(ASSEMBLY *assembly, ULONG offset) +{ + return (VOID *)&assembly->data[offset]; +} + +#define MAX_TABLES_WORD 0xFFFF +#define MAX_TABLES_1BIT_ENCODE 32767 +#define MAX_TABLES_2BIT_ENCODE 16383 +#define MAX_TABLES_3BIT_ENCODE 8191 +#define MAX_TABLES_5BIT_ENCODE 2047 + +static inline ULONG get_table_size(ASSEMBLY *assembly, DWORD index) +{ + DWORD size; + INT tables; + + switch (TokenFromTable(index)) + { + case mdtModule: + { + size = sizeof(MODULETABLE) + (assembly->stringsz - sizeof(WORD)) + + 2 * (assembly->guidsz - sizeof(WORD)); + break; + } + case mdtTypeRef: + { + size = sizeof(TYPEREFTABLE) + 2 * (assembly->stringsz - sizeof(WORD)); + + /* ResolutionScope:ResolutionScope */ + tables = max(assembly->tables[TableFromToken(mdtModule)].rows, + assembly->tables[TableFromToken(mdtModuleRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtAssemblyRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeRef)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case mdtTypeDef: + { + size = sizeof(TYPEDEFTABLE) + 2 * (assembly->stringsz - sizeof(WORD)); + + /* Extends:TypeDefOrRef */ + tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows, + assembly->tables[TableFromToken(mdtTypeRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + + size += (assembly->tables[TableFromToken(mdtFieldDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + size += (assembly->tables[TableFromToken(mdtMethodDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtFieldDef: + { + size = sizeof(FIELDTABLE) + (assembly->stringsz - sizeof(WORD)) + + (assembly->blobsz - sizeof(WORD)); + break; + } + case mdtMethodDef: + { + size = sizeof(METHODDEFTABLE) + (assembly->stringsz - sizeof(WORD)) + + (assembly->blobsz - sizeof(WORD)); + + size += (assembly->tables[TableFromToken(mdtParamDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtParamDef: + { + size = sizeof(PARAMTABLE) + (assembly->stringsz - sizeof(WORD)); + break; + } + case mdtInterfaceImpl: + { + size = sizeof(INTERFACEIMPLTABLE); + + /* Interface:TypeDefOrRef */ + tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows, + assembly->tables[TableFromToken(mdtTypeRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case mdtMemberRef: + { + size = sizeof(MEMBERREFTABLE) + (assembly->stringsz - sizeof(WORD)) + + (assembly->blobsz - sizeof(WORD)); + + /* Class:MemberRefParent */ + tables = max(assembly->tables[TableFromToken(mdtTypeRef)].rows, + assembly->tables[TableFromToken(mdtModuleRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtMethodDef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeDef)].rows); + size += (tables > MAX_TABLES_3BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case 0x0B000000: /* FIXME */ + { + size = sizeof(CONSTANTTABLE) + (assembly->blobsz - sizeof(WORD)); + + /* Parent:HasConstant */ + tables = max(assembly->tables[TableFromToken(mdtParamDef)].rows, + assembly->tables[TableFromToken(mdtFieldDef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtProperty)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case mdtCustomAttribute: + { + size = sizeof(CUSTOMATTRIBUTETABLE) + (assembly->blobsz - sizeof(WORD)); + + /* Parent:HasCustomAttribute */ + tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows, + assembly->tables[TableFromToken(mdtFieldDef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeDef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtParamDef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtInterfaceImpl)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtMemberRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtPermission)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtProperty)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtEvent)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtSignature)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtModuleRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtAssembly)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtFile)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtExportedType)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtManifestResource)].rows); + size += (tables > MAX_TABLES_5BIT_ENCODE) ? sizeof(WORD) : 0; + + /* Type:CustomAttributeType */ + tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows, + assembly->tables[TableFromToken(mdtMemberRef)].rows); + size += (tables > MAX_TABLES_3BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case 0x0D000000: /* FIXME */ + { + size = sizeof(FIELDMARSHALTABLE) + (assembly->blobsz - sizeof(WORD)); + + /* Parent:HasFieldMarshal */ + tables = max(assembly->tables[TableFromToken(mdtFieldDef)].rows, + assembly->tables[TableFromToken(mdtParamDef)].rows); + size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case mdtPermission: + { + size = sizeof(DECLSECURITYTABLE) + (assembly->blobsz - sizeof(WORD)); + + /* Parent:HasDeclSecurity */ + tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows, + assembly->tables[TableFromToken(mdtMethodDef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtAssembly)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case 0x0F000000: /* FIXME */ + { + size = sizeof(CLASSLAYOUTTABLE); + size += (assembly->tables[TableFromToken(mdtTypeDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case 0x10000000: /* FIXME */ + { + size = sizeof(FIELDLAYOUTTABLE); + size += (assembly->tables[TableFromToken(mdtFieldDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtSignature: + { + size = sizeof(STANDALONESIGTABLE) + (assembly->blobsz - sizeof(WORD)); + break; + } + case 0x12000000: /* FIXME */ + { + size = sizeof(EVENTMAPTABLE); + size += (assembly->tables[TableFromToken(mdtTypeDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + size += (assembly->tables[TableFromToken(mdtEvent)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtEvent: + { + size = sizeof(EVENTTABLE) + (assembly->stringsz - sizeof(WORD)); + + /* EventType:TypeDefOrRef */ + tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows, + assembly->tables[TableFromToken(mdtTypeRef)].rows); + tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case 0x15000000:/* FIXME */ + { + size = sizeof(PROPERTYMAPTABLE); + size += (assembly->tables[TableFromToken(mdtTypeDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + size += (assembly->tables[TableFromToken(mdtProperty)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtProperty: + { + size = sizeof(PROPERTYTABLE) + (assembly->stringsz - sizeof(WORD)) + + (assembly->blobsz - sizeof(WORD)); + break; + } + case 0x18000000: /* FIXME */ + { + size = sizeof(METHODSEMANTICSTABLE); + + /* Association:HasSemantics */ + tables = max(assembly->tables[TableFromToken(mdtEvent)].rows, + assembly->tables[TableFromToken(mdtProperty)].rows); + size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0; + + size += (assembly->tables[TableFromToken(mdtMethodDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case 0x19000000: /* FIXME */ + { + size = sizeof(METHODIMPLTABLE); + + /* MethodBody:MethodDefOrRef, MethodDeclaration:MethodDefOrRef */ + tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows, + assembly->tables[TableFromToken(mdtMemberRef)].rows); + size += (tables > MAX_TABLES_1BIT_ENCODE) ? 2 * sizeof(WORD) : 0; + + size += (assembly->tables[TableFromToken(mdtTypeDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtModuleRef: + { + size = sizeof(MODULEREFTABLE) + (assembly->stringsz - sizeof(WORD)); + break; + } + case mdtTypeSpec: + { + size = sizeof(TYPESPECTABLE) + (assembly->blobsz - sizeof(WORD)); + break; + } + case 0x1C000000: /* FIXME */ + { + size = sizeof(IMPLMAPTABLE) + (assembly->stringsz - sizeof(WORD)); + + /* MemberForwarded:MemberForwarded */ + tables = max(assembly->tables[TableFromToken(mdtFieldDef)].rows, + assembly->tables[TableFromToken(mdtMethodDef)].rows); + size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0; + + size += (assembly->tables[TableFromToken(mdtModuleRef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case 0x1D000000: /* FIXME */ + { + size = sizeof(FIELDRVATABLE); + size += (assembly->tables[TableFromToken(mdtFieldDef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtAssembly: + { + size = sizeof(ASSEMBLYTABLE) + 2 * (assembly->stringsz - sizeof(WORD)) + + (assembly->blobsz - sizeof(WORD)); + break; + } + case 0x20000001: /* FIXME */ + { + size = sizeof(ASSEMBLYPROCESSORTABLE); + break; + } + case 0x22000000: /* FIXME */ + { + size = sizeof(ASSEMBLYOSTABLE); + break; + } + case mdtAssemblyRef: + { + size = sizeof(ASSEMBLYREFTABLE) + 2 * (assembly->stringsz - sizeof(WORD)) + + 2 * (assembly->blobsz - sizeof(WORD)); + break; + } + case 0x24000000: /* FIXME */ + { + size = sizeof(ASSEMBLYREFPROCESSORTABLE); + size += (assembly->tables[TableFromToken(mdtAssemblyRef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case 0x25000000: /* FIXME */ + { + size = sizeof(ASSEMBLYREFOSTABLE); + size += (assembly->tables[TableFromToken(mdtAssemblyRef)].rows > + MAX_TABLES_WORD) ? sizeof(WORD) : 0; + break; + } + case mdtFile: + { + size = sizeof(FILETABLE) + (assembly->stringsz - sizeof(WORD)) + + (assembly->blobsz - sizeof(WORD)); + break; + } + case mdtExportedType: + { + size = sizeof(EXPORTEDTYPETABLE) + 2 * (assembly->stringsz - sizeof(WORD)); + + /* Implementation:Implementation */ + tables = max(assembly->tables[TableFromToken(mdtFile)].rows, + assembly->tables[TableFromToken(mdtMethodDef)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case mdtManifestResource: + { + size = sizeof(MANIFESTRESTABLE) + (assembly->stringsz - sizeof(WORD)); + + /* Implementation:Implementation */ + tables = max(assembly->tables[TableFromToken(mdtFile)].rows, + assembly->tables[TableFromToken(mdtAssemblyRef)].rows); + size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0; + break; + } + case 0x29000000: /* FIXME */ + { + size = sizeof(NESTEDCLASSTABLE); + size += (assembly->tables[TableFromToken(mdtTypeDef)].rows > + MAX_TABLES_WORD) ? 2 * sizeof(WORD) : 0; + break; + } + default: + return 0; + } + + return size; +} + +static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset) +{ + DWORD i, previ, offidx; + ULONG currofs; + + currofs = offset; + assembly->tableshdr = (METADATATABLESHDR *)assembly_data_offset(assembly, currofs); + if (!assembly->tableshdr) + return E_FAIL; + + assembly->stringsz = (assembly->tableshdr->HeapOffsetSizes & MD_STRINGS_BIT) ? + sizeof(DWORD) : sizeof(WORD); + assembly->guidsz = (assembly->tableshdr->HeapOffsetSizes & MD_GUIDS_BIT) ? + sizeof(DWORD) : sizeof(WORD); + assembly->blobsz = (assembly->tableshdr->HeapOffsetSizes & MD_BLOBS_BIT) ? + sizeof(DWORD) : sizeof(WORD); + + currofs += sizeof(METADATATABLESHDR); + assembly->numrows = (DWORD *)assembly_data_offset(assembly, currofs); + if (!assembly->numrows) + return E_FAIL; + + assembly->numtables = 0; + for (i = 0; i < MAX_CLR_TABLES; i++) + { + if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) || + (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1)) + { + assembly->numtables++; + } + } + + currofs += assembly->numtables * sizeof(DWORD); + memset(assembly->tables, -1, MAX_CLR_TABLES * sizeof(CLRTABLE)); + + if (assembly->tableshdr->MaskValid.u.LowPart & 1) + assembly->tables[0].offset = currofs; + + offidx = 0; + for (i = 0; i < MAX_CLR_TABLES; i++) + { + if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) || + (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1)) + { + assembly->tables[i].rows = assembly->numrows[offidx]; + offidx++; + } + } + + previ = 0; + offidx = 1; + for (i = 1; i < MAX_CLR_TABLES; i++) + { + if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) || + (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1)) + { + currofs += get_table_size(assembly, previ) * assembly->numrows[offidx - 1]; + assembly->tables[i].offset = currofs; + offidx++; + previ = i; + } + } + + return S_OK; +} + +static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz) +{ + METADATAHDR *metadatahdr; + BYTE *ptr, *dest; + DWORD size, ofs; + ULONG rva; + + rva = assembly->corhdr->MetaData.VirtualAddress; + ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL); + if (!ptr) + return E_FAIL; + + metadatahdr = (METADATAHDR *)ptr; + + assembly->metadatahdr = HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR)); + if (!assembly->metadatahdr) + return E_OUTOFMEMORY; + + size = FIELD_OFFSET(METADATAHDR, Version); + memcpy(assembly->metadatahdr, metadatahdr, size); + + /* we don't care about the version string */ + + ofs = FIELD_OFFSET(METADATAHDR, Flags); + ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1; + dest = (BYTE *)assembly->metadatahdr + ofs; + memcpy(dest, ptr, sizeof(METADATAHDR) - ofs); + + *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1; + + return S_OK; +} + +static HRESULT parse_clr_metadata(ASSEMBLY *assembly) +{ + METADATASTREAMHDR *streamhdr; + ULONG rva, i, ofs; + LPSTR stream; + HRESULT hr; + DWORD hdrsz; + BYTE *ptr; + + hr = parse_metadata_header(assembly, &hdrsz); + if (FAILED(hr)) + return hr; + + rva = assembly->corhdr->MetaData.VirtualAddress; + ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL); + if (!ptr) + return E_FAIL; + + for (i = 0; i < assembly->metadatahdr->Streams; i++) + { + streamhdr = (METADATASTREAMHDR *)ptr; + ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset); + + ptr += sizeof(METADATASTREAMHDR); + stream = (LPSTR)ptr; + + if (!lstrcmpA(stream, "#~")) + { + hr = parse_clr_tables(assembly, ofs); + if (FAILED(hr)) + return hr; + } + else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings")) + assembly->strings = (BYTE *)assembly_data_offset(assembly, ofs); + else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob")) + assembly->blobs = (BYTE *)assembly_data_offset(assembly, ofs); + + ptr += lstrlenA(stream) + 1; + ptr = (BYTE *)(((UINT_PTR)ptr + 3) & ~3); /* align on DWORD boundary */ + } + + return S_OK; +} + +static HRESULT parse_pe_header(ASSEMBLY *assembly) +{ + IMAGE_DATA_DIRECTORY *datadirs; + + assembly->nthdr = ImageNtHeader(assembly->data); + if (!assembly->nthdr) + return E_FAIL; + + if (assembly->nthdr->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) + { + IMAGE_OPTIONAL_HEADER64 *opthdr = + (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader; + datadirs = opthdr->DataDirectory; + } + else + datadirs = assembly->nthdr->OptionalHeader.DataDirectory; + + if (!datadirs) + return E_FAIL; + + if (!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress || + !datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size) + { + return E_FAIL; + } + + assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data, + datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress, NULL); + if (!assembly->corhdr) + return E_FAIL; + + return S_OK; +} + +HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file) +{ + ASSEMBLY *assembly; + HRESULT hr; + + *out = NULL; + + assembly = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ASSEMBLY)); + if (!assembly) + return E_OUTOFMEMORY; + + assembly->path = strdupWtoA(file); + if (!assembly->path) + { + hr = E_OUTOFMEMORY; + goto failed; + } + + assembly->hfile = CreateFileW(file, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (assembly->hfile == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto failed; + } + + assembly->hmap = CreateFileMappingW(assembly->hfile, NULL, PAGE_READONLY, + 0, 0, NULL); + if (!assembly->hmap) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto failed; + } + + assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0); + if (!assembly->data) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto failed; + } + + hr = parse_pe_header(assembly); + if (FAILED(hr)) goto failed; + + hr = parse_clr_metadata(assembly); + if (FAILED(hr)) goto failed; + + *out = assembly; + return S_OK; + +failed: + assembly_release(assembly); + return hr; +} + +HRESULT assembly_release(ASSEMBLY *assembly) +{ + if (!assembly) + return S_OK; + + HeapFree(GetProcessHeap(), 0, assembly->metadatahdr); + HeapFree(GetProcessHeap(), 0, assembly->path); + UnmapViewOfFile(assembly->data); + CloseHandle(assembly->hmap); + CloseHandle(assembly->hfile); + HeapFree(GetProcessHeap(), 0, assembly); + + return S_OK; +} + +static LPSTR assembly_dup_str(ASSEMBLY *assembly, DWORD index) +{ + LPSTR str = (LPSTR)&assembly->strings[index]; + LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1); + if (cpy) + strcpy(cpy, str); + return cpy; +} + +HRESULT assembly_get_name(ASSEMBLY *assembly, LPSTR *name) +{ + BYTE *ptr; + LONG offset; + DWORD stridx; + + offset = assembly->tables[TableFromToken(mdtAssembly)].offset; + if (offset == -1) + return E_FAIL; + + ptr = assembly_data_offset(assembly, offset); + if (!ptr) + return E_FAIL; + + ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz; + if (assembly->stringsz == sizeof(DWORD)) + stridx = *((DWORD *)ptr); + else + stridx = *((WORD *)ptr); + + *name = assembly_dup_str(assembly, stridx); + if (!*name) + return E_OUTOFMEMORY; + + return S_OK; +} + +HRESULT assembly_get_path(ASSEMBLY *assembly, LPSTR *path) +{ + LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(assembly->path)+1); + *path = cpy; + if (cpy) + strcpy(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) + 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; +} + +HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme) +{ + /* FIXME */ + return S_OK; +} + +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, 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) +{ + ASSEMBLYTABLE *asmtbl; + ULONG i, size; + LONG offset; + BYTE *hashdata; + HCRYPTPROV crypt; + HCRYPTHASH hash; + BYTE *pubkey; + BYTE tokbytes[BYTES_PER_TOKEN]; + HRESULT hr = E_FAIL; + LPSTR tok; + + *token = NULL; + + offset = assembly->tables[TableFromToken(mdtAssembly)].offset; + if (offset == -1) + return E_FAIL; + + asmtbl = (ASSEMBLYTABLE *)assembly_data_offset(assembly, offset); + if (!asmtbl) + return E_FAIL; + + pubkey = assembly_get_blob(assembly, asmtbl->PublicKey, &size); + + if (!CryptAcquireContextA(&crypt, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + return E_FAIL; + + if (!CryptCreateHash(crypt, CALG_SHA1, 0, 0, &hash)) + return E_FAIL; + + if (!CryptHashData(hash, pubkey, size, 0)) + return E_FAIL; + + size = 0; + if (!CryptGetHashParam(hash, HP_HASHVAL, NULL, &size, 0)) + return E_FAIL; + + hashdata = HeapAlloc(GetProcessHeap(), 0, size); + if (!hashdata) + { + hr = E_OUTOFMEMORY; + goto done; + } + + if (!CryptGetHashParam(hash, HP_HASHVAL, hashdata, &size, 0)) + goto done; + + for (i = size - 1; i >= size - 8; i--) + tokbytes[size - i - 1] = hashdata[i]; + + tok = HeapAlloc(GetProcessHeap(), 0, TOKEN_LENGTH); + if (!tok) + { + hr = E_OUTOFMEMORY; + goto done; + } + + bytes_to_str(tokbytes, BYTES_PER_TOKEN, tok); + tok[TOKEN_LENGTH - 1] = '\0'; + + *token = tok; + hr = S_OK; + +done: + HeapFree(GetProcessHeap(), 0, hashdata); + CryptDestroyHash(hash); + CryptReleaseContext(crypt, 0); + + return hr; +} diff --git a/reactos/dll/win32/fusion/fusion.c b/reactos/dll/win32/fusion/fusion.c new file mode 100644 index 00000000000..ac01cf415ee --- /dev/null +++ b/reactos/dll/win32/fusion/fusion.c @@ -0,0 +1,186 @@ +/* + * Implementation of the Fusion API + * + * 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 + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "fusion.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(fusion); + +/****************************************************************** + * ClearDownloadCache (FUSION.@) + */ +HRESULT WINAPI ClearDownloadCache(void) +{ + FIXME("stub!\n"); + return E_NOTIMPL; +} + +/****************************************************************** + * CompareAssemblyIdentity (FUSION.@) + */ +HRESULT WINAPI CompareAssemblyIdentity(LPCWSTR pwzAssemblyIdentity1, BOOL fUnified1, + LPCWSTR pwzAssemblyIdentity2, BOOL fUnified2, + BOOL *pfEquivalent, AssemblyComparisonResult *pResult) +{ + 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; +} + +/****************************************************************** + * CreateInstallReferenceEnum (FUSION.@) + */ +HRESULT WINAPI CreateInstallReferenceEnum(IInstallReferenceEnum **ppRefEnum, + IAssemblyName *pName, DWORD dwFlags, + LPVOID pvReserved) +{ + FIXME("(%p, %p, %08x, %p) stub!\n", ppRefEnum, pName, dwFlags, pvReserved); + return E_NOTIMPL; +} + +/****************************************************************** + * GetAssemblyIdentityFromFile (FUSION.@) + */ +HRESULT WINAPI GetAssemblyIdentityFromFile(LPCWSTR pwzFilePath, REFIID riid, + IUnknown **ppIdentity) +{ + FIXME("(%s, %s, %p) stub!\n", debugstr_w(pwzFilePath), debugstr_guid(riid), + ppIdentity); + + return E_NOTIMPL; +} + +static HRESULT (WINAPI *pGetCORVersion)(LPWSTR pbuffer, DWORD cchBuffer, + DWORD *dwLength); + +static HRESULT get_corversion(LPWSTR version, DWORD size) +{ + HMODULE hmscoree; + HRESULT hr; + DWORD len; + + hmscoree = LoadLibraryA("mscoree.dll"); + if (!hmscoree) + return E_FAIL; + + pGetCORVersion = (void *)GetProcAddress(hmscoree, "GetCORVersion"); + if (!pGetCORVersion) + return E_FAIL; + + hr = pGetCORVersion(version, size, &len); + + FreeLibrary(hmscoree); + return hr; +} + +/****************************************************************** + * GetCachePath (FUSION.@) + */ +HRESULT WINAPI GetCachePath(ASM_CACHE_FLAGS dwCacheFlags, LPWSTR pwzCachePath, + PDWORD pcchPath) +{ + WCHAR path[MAX_PATH]; + WCHAR windir[MAX_PATH]; + WCHAR version[MAX_PATH]; + DWORD len; + HRESULT hr = S_OK; + + static const WCHAR backslash[] = {'\\',0}; + static const WCHAR assembly[] = {'a','s','s','e','m','b','l','y',0}; + 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}; + + TRACE("(%08x, %p, %p)\n", dwCacheFlags, pwzCachePath, pcchPath); + + if (!pcchPath) + return E_INVALIDARG; + + GetWindowsDirectoryW(windir, MAX_PATH); + lstrcpyW(path, windir); + lstrcatW(path, backslash); + lstrcatW(path, assembly); + + switch (dwCacheFlags) + { + case ASM_CACHE_ZAP: + { + hr = get_corversion(version, MAX_PATH); + if (FAILED(hr)) + return hr; + + sprintfW(path, zapfmt, windir, assembly, nativeimg, version); + break; + } + + case ASM_CACHE_GAC: + { + lstrcatW(path, backslash); + lstrcatW(path, gac); + break; + } + + case ASM_CACHE_DOWNLOAD: + { + FIXME("Download cache not implemented\n"); + return E_FAIL; + } + + case ASM_CACHE_ROOT: + break; /* already set */ + + default: + return E_INVALIDARG; + } + + len = lstrlenW(path) + 1; + if (*pcchPath <= len || !pwzCachePath) + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + else if (pwzCachePath) + lstrcpyW(pwzCachePath, path); + + *pcchPath = len; + + return hr; +} diff --git a/reactos/dll/win32/fusion/fusion.rbuild b/reactos/dll/win32/fusion/fusion.rbuild new file mode 100644 index 00000000000..90cabde35b4 --- /dev/null +++ b/reactos/dll/win32/fusion/fusion.rbuild @@ -0,0 +1,22 @@ + + + . + include/reactos/wine + + + 0x600 + 0x601 + 0x501 + wine + kernel32 + version + shlwapi + advapi32 + dbghelp + asmcache.c + asmname.c + assembly.c + fusion.c + fusion_main.c + fusion.spec + diff --git a/reactos/dll/win32/fusion/fusion.spec b/reactos/dll/win32/fusion/fusion.spec new file mode 100644 index 00000000000..e589ad17e08 --- /dev/null +++ b/reactos/dll/win32/fusion/fusion.spec @@ -0,0 +1,17 @@ +@ stub CopyPDBs +@ stdcall ClearDownloadCache() +@ stub CreateApplicationContext +@ stdcall CreateAssemblyCache(ptr long) +@ stdcall CreateAssemblyEnum(ptr ptr ptr long ptr) +@ stdcall CreateAssemblyNameObject(ptr wstr long ptr) +@ stub CreateHistoryReader +@ stdcall CreateInstallReferenceEnum(ptr ptr long ptr) +@ stdcall GetCachePath(long wstr ptr) +@ stub GetHistoryFileDirectory +@ stub InitializeFusion +@ stub InstallCustomAssembly +@ stub InstallCustomModule +@ stub LookupHistoryAssembly +@ stub NukeDownloadedCache +@ stub PreBindAssembly +@ stub PreBindAssemblyEx diff --git a/reactos/dll/win32/fusion/fusion_main.c b/reactos/dll/win32/fusion/fusion_main.c new file mode 100644 index 00000000000..8bc4b1e3349 --- /dev/null +++ b/reactos/dll/win32/fusion/fusion_main.c @@ -0,0 +1,47 @@ +/* + * fusion main + * + * 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 "config.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(fusion); + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + case DLL_PROCESS_DETACH: + break; + default: + break; + } + + return TRUE; +} diff --git a/reactos/dll/win32/fusion/fusion_ros.diff b/reactos/dll/win32/fusion/fusion_ros.diff new file mode 100644 index 00000000000..25677a0da2c --- /dev/null +++ b/reactos/dll/win32/fusion/fusion_ros.diff @@ -0,0 +1,11 @@ +--- dll\win32\fusion\fusion_main - Kopie.c Fr Sep 5 17:28:27 2008 ++++ dll\win32\fusion\fusion_main.c Mi Sep 10 10:38:55 2008 +@@ -34,8 +34,6 @@ + + switch (fdwReason) + { +- case DLL_WINE_PREATTACH: +- return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; diff --git a/reactos/dll/win32/fusion/fusionpriv.h b/reactos/dll/win32/fusion/fusionpriv.h new file mode 100644 index 00000000000..a4e6193b054 --- /dev/null +++ b/reactos/dll/win32/fusion/fusionpriv.h @@ -0,0 +1,438 @@ +/* + * fusion private definitions + * + * 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 + */ + +#ifndef __WINE_FUSION_PRIVATE__ +#define __WINE_FUSION_PRIVATE__ + +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" + +#include + +typedef struct +{ + ULONG Signature; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG Reserved; + ULONG VersionLength; + LPSTR Version; + BYTE Flags; + WORD Streams; +} METADATAHDR; + +typedef struct +{ + DWORD Offset; + DWORD Size; +} METADATASTREAMHDR; + +typedef struct +{ + DWORD Reserved1; + BYTE MajorVersion; + BYTE MinorVersion; + BYTE HeapOffsetSizes; + BYTE Reserved2; + LARGE_INTEGER MaskValid; + LARGE_INTEGER MaskSorted; +} METADATATABLESHDR; + +typedef struct +{ + WORD Generation; + WORD Name; + WORD Mvid; + WORD EncId; + WORD EncBaseId; +} MODULETABLE; + +typedef struct +{ + DWORD Flags; + WORD Name; + WORD Namespace; + WORD Extends; + WORD FieldList; + WORD MethodList; +} TYPEDEFTABLE; + +typedef struct +{ + WORD ResolutionScope; + WORD Name; + WORD Namespace; +} TYPEREFTABLE; + +typedef struct +{ + WORD Flags; + WORD Name; + WORD Signature; +} FIELDTABLE; + +typedef struct +{ + DWORD HashAlgId; + WORD MajorVersion; + WORD MinorVersion; + WORD BuildNumber; + WORD RevisionNumber; + DWORD Flags; + WORD PublicKey; + WORD Name; + WORD Culture; +} ASSEMBLYTABLE; + +typedef struct +{ + DWORD Offset; + DWORD Flags; + WORD Name; + WORD Implementation; +} MANIFESTRESTABLE; + +typedef struct +{ + DWORD RVA; + WORD ImplFlags; + WORD Flags; + WORD Name; + WORD Signature; + WORD ParamList; +} METHODDEFTABLE; + +typedef struct +{ + WORD Flags; + WORD Sequence; + WORD Name; +} PARAMTABLE; + +typedef struct +{ + WORD Class; + WORD Interface; +} INTERFACEIMPLTABLE; + +typedef struct +{ + WORD Class; + WORD Name; + WORD Signature; +} MEMBERREFTABLE; + +typedef struct +{ + BYTE Type; + BYTE Reserved; + WORD Parent; + WORD Value; +} CONSTANTTABLE; + +typedef struct +{ + WORD Parent; + WORD Type; + WORD Value; +} CUSTOMATTRIBUTETABLE; + +typedef struct +{ + WORD Parent; + WORD NativeType; +} FIELDMARSHALTABLE; + +typedef struct +{ + WORD Action; + WORD Parent; + WORD PermissionSet; +} DECLSECURITYTABLE; + +typedef struct +{ + WORD PackingSize; + DWORD ClassSize; + WORD Parent; +} CLASSLAYOUTTABLE; + +typedef struct +{ + DWORD Offset; + WORD Field; +} FIELDLAYOUTTABLE; + +typedef struct +{ + WORD Signature; +} STANDALONESIGTABLE; + +typedef struct +{ + WORD Parent; + WORD EventList; +} EVENTMAPTABLE; + +typedef struct +{ + WORD EventFlags; + WORD Name; + WORD EventType; +} EVENTTABLE; + +typedef struct +{ + WORD Parent; + WORD PropertyList; +} PROPERTYMAPTABLE; + +typedef struct +{ + WORD Flags; + WORD Name; + WORD Type; +} PROPERTYTABLE; + +typedef struct +{ + WORD Semantics; + WORD Method; + WORD Association; +} METHODSEMANTICSTABLE; + +typedef struct +{ + WORD Class; + WORD MethodBody; + WORD MethodDeclaration; +} METHODIMPLTABLE; + +typedef struct +{ + WORD Name; +} MODULEREFTABLE; + +typedef struct +{ + WORD Signature; +} TYPESPECTABLE; + +typedef struct +{ + WORD MappingFlags; + WORD MemberForwarded; + WORD ImportName; + WORD ImportScope; +} IMPLMAPTABLE; + +typedef struct +{ + DWORD RVA; + WORD Field; +} FIELDRVATABLE; + +typedef struct +{ + DWORD Processor; +} ASSEMBLYPROCESSORTABLE; + +typedef struct +{ + DWORD OSPlatformID; + DWORD OSMajorVersion; + DWORD OSMinorVersion; +} ASSEMBLYOSTABLE; + +typedef struct +{ + WORD MajorVersion; + WORD MinorVersion; + WORD BuildNumber; + WORD RevisionNumber; + DWORD Flags; + WORD PublickKeyOrToken; + WORD Name; + WORD Culture; + WORD HashValue; +} ASSEMBLYREFTABLE; + +typedef struct +{ + DWORD Processor; + WORD AssemblyRef; +} ASSEMBLYREFPROCESSORTABLE; + +typedef struct +{ + DWORD OSPlatformId; + DWORD OSMajorVersion; + DWORD OSMinorVersion; + WORD AssemblyRef; +} ASSEMBLYREFOSTABLE; + +typedef struct +{ + DWORD Flags; + WORD Name; + WORD HashValue; +} FILETABLE; + +typedef struct +{ + DWORD Flags; + DWORD TypeDefId; + WORD TypeName; + WORD TypeNameSpace; + WORD Implementation; +} EXPORTEDTYPETABLE; + +typedef struct +{ + WORD NestedClass; + WORD EnclosingClass; +} NESTEDCLASSTABLE; + +typedef struct +{ + WORD Number; + WORD Flags; +} GENERICPARAMTABLE; + +typedef struct +{ + WORD MethodDef; + WORD Instantiation; +} METHODSPECTABLE; + +typedef struct +{ + WORD Owner; + WORD Constraint; +} GENERICPARAMCONSTRAINTTABLE; + +typedef struct +{ + DWORD ImportLookupTable; + DWORD DateTimeStamp; + DWORD ForwarderChain; + DWORD Name; + DWORD ImportAddressTable; + BYTE pad[20]; +} IMPORTTABLE; + +typedef struct +{ + DWORD HintNameTableRVA; + BYTE pad[8]; +} IMPORTLOOKUPTABLE; + +typedef struct +{ + WORD Hint; + BYTE Name[12]; + BYTE Module[12]; + DWORD Reserved; + WORD EntryPoint; + DWORD RVA; +} HINTNAMETABLE; + +typedef struct +{ + DWORD PageRVA; + DWORD Size; + DWORD Relocation; +} RELOCATION; + +typedef struct +{ + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[17]; + VS_FIXEDFILEINFO Value; +} VS_VERSIONINFO; + +typedef struct +{ + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[13]; +} VARFILEINFO; + +typedef struct +{ + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[13]; + DWORD Value; +} VAR; + +typedef struct +{ + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[15]; +} STRINGFILEINFO; + +typedef struct +{ + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[9]; +} STRINGTABLE; + +typedef struct +{ + WORD wLength; + WORD wValueLength; + WORD wType; +} STRINGHDR; + +typedef struct +{ + DWORD Size; + DWORD Signature; + DWORD HeaderVersion; + DWORD SkipData; + BYTE Data[168]; +} RESOURCE; + +#include + +struct tagASSEMBLY; +typedef struct tagASSEMBLY ASSEMBLY; + +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_architecture(ASSEMBLY *assembly, DWORD fixme); +HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token); + +#endif /* __WINE_FUSION_PRIVATE__ */ diff --git a/reactos/dll/win32/win32.rbuild b/reactos/dll/win32/win32.rbuild index b89fb73cf2e..2c4beff3286 100644 --- a/reactos/dll/win32/win32.rbuild +++ b/reactos/dll/win32/win32.rbuild @@ -85,6 +85,9 @@ + + +