mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 04:26:32 +00:00
sync fusion.dll with wine 1.1.4
svn path=/trunk/; revision=36114
This commit is contained in:
parent
bac7f47714
commit
01bc267907
12 changed files with 2665 additions and 0 deletions
|
@ -187,6 +187,7 @@
|
|||
<property name="BASEADDRESS_MSVCRT20" value="0x78500000" />
|
||||
<property name="BASEADDRESS_MSVCRT40" value="0x78700000" />
|
||||
<property name="BASEADDRESS_MSCOREE" value="0x79000000" />
|
||||
<property name="BASEADDRESS_FUSION" value="0x79040000" />
|
||||
<property name="BASEADDRESS_KERNEL32" value="0x7c800000" />
|
||||
<property name="BASEADDRESS_NTDLL" value="0x7c900000" />
|
||||
<property name="BASEADDRESS_HHCTRL" value="0x7e410000" />
|
||||
|
|
|
@ -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
|
||||
|
|
476
reactos/dll/win32/fusion/asmcache.c
Normal file
476
reactos/dll/win32/fusion/asmcache.c
Normal file
|
@ -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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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
|
||||
};
|
525
reactos/dll/win32/fusion/asmname.c
Normal file
525
reactos/dll/win32/fusion/asmname.c
Normal file
|
@ -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 <stdarg.h>
|
||||
|
||||
#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;
|
||||
}
|
938
reactos/dll/win32/fusion/assembly.c
Normal file
938
reactos/dll/win32/fusion/assembly.c
Normal file
|
@ -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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
186
reactos/dll/win32/fusion/fusion.c
Normal file
186
reactos/dll/win32/fusion/fusion.c
Normal file
|
@ -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 <stdarg.h>
|
||||
|
||||
#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;
|
||||
}
|
22
reactos/dll/win32/fusion/fusion.rbuild
Normal file
22
reactos/dll/win32/fusion/fusion.rbuild
Normal file
|
@ -0,0 +1,22 @@
|
|||
<module name="fusion" type="win32dll" baseaddress="${BASEADDRESS_FUSION}" installbase="system32" installname="fusion.dll" allowwarnings="true">
|
||||
<importlibrary definition="fusion.spec.def" />
|
||||
<include base="fusion">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__WINESRC__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x601</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<library>wine</library>
|
||||
<library>kernel32</library>
|
||||
<library>version</library>
|
||||
<library>shlwapi</library>
|
||||
<library>advapi32</library>
|
||||
<library>dbghelp</library>
|
||||
<file>asmcache.c</file>
|
||||
<file>asmname.c</file>
|
||||
<file>assembly.c</file>
|
||||
<file>fusion.c</file>
|
||||
<file>fusion_main.c</file>
|
||||
<file>fusion.spec</file>
|
||||
</module>
|
17
reactos/dll/win32/fusion/fusion.spec
Normal file
17
reactos/dll/win32/fusion/fusion.spec
Normal file
|
@ -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
|
47
reactos/dll/win32/fusion/fusion_main.c
Normal file
47
reactos/dll/win32/fusion/fusion_main.c
Normal file
|
@ -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 <stdarg.h>
|
||||
|
||||
#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;
|
||||
}
|
11
reactos/dll/win32/fusion/fusion_ros.diff
Normal file
11
reactos/dll/win32/fusion/fusion_ros.diff
Normal file
|
@ -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;
|
438
reactos/dll/win32/fusion/fusionpriv.h
Normal file
438
reactos/dll/win32/fusion/fusionpriv.h
Normal file
|
@ -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 <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
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 <poppack.h>
|
||||
|
||||
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__ */
|
|
@ -85,6 +85,9 @@
|
|||
<directory name="fmifs">
|
||||
<xi:include href="fmifs/fmifs.rbuild" />
|
||||
</directory>
|
||||
<directory name="fusion">
|
||||
<xi:include href="fusion/fusion.rbuild" />
|
||||
</directory>
|
||||
<directory name="gdi32">
|
||||
<xi:include href="gdi32/gdi32.rbuild" />
|
||||
</directory>
|
||||
|
|
Loading…
Reference in a new issue