sync fusion.dll with wine 1.1.4

svn path=/trunk/; revision=36114
This commit is contained in:
Christoph von Wittich 2008-09-10 08:47:30 +00:00
parent bac7f47714
commit 01bc267907
12 changed files with 2665 additions and 0 deletions

View file

@ -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" />

View file

@ -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

View 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
};

View 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;
}

View 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;
}

View 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;
}

View 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>

View 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

View 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;
}

View 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;

View 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__ */

View file

@ -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>