mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
[SXS]
* Sync to Wine 1.5.4. svn path=/trunk/; revision=56633
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
|
||||
add_definitions(-D__WINESRC__)
|
||||
|
||||
spec2def(sxs.dll sxs.spec)
|
||||
spec2def(sxs.dll sxs.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
cache.c
|
||||
name.c
|
||||
sxs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/sxs_stubs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/sxs.def)
|
||||
|
||||
+383
-143
@@ -32,21 +32,22 @@
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "sxs_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(sxs);
|
||||
|
||||
static inline WCHAR *strdupW( const WCHAR *s )
|
||||
{
|
||||
WCHAR *t;
|
||||
if (!s) return NULL;
|
||||
if ((t = HeapAlloc( GetProcessHeap(), 0, (strlenW( s ) + 1) * sizeof(WCHAR) ))) strcpyW( t, s );
|
||||
return t;
|
||||
}
|
||||
static const WCHAR cache_mutex_nameW[] =
|
||||
{'_','_','W','I','N','E','_','S','X','S','_','C','A','C','H','E','_','M','U','T','E','X','_','_',0};
|
||||
|
||||
static const WCHAR win32W[] = {'w','i','n','3','2',0};
|
||||
static const WCHAR win32_policyW[] = {'w','i','n','3','2','-','p','o','l','i','c','y',0};
|
||||
static const WCHAR backslashW[] = {'\\',0};
|
||||
|
||||
struct cache
|
||||
{
|
||||
IAssemblyCache IAssemblyCache_iface;
|
||||
LONG refs;
|
||||
HANDLE lock;
|
||||
};
|
||||
|
||||
static inline struct cache *impl_from_IAssemblyCache(IAssemblyCache *iface)
|
||||
@@ -90,30 +91,185 @@ static ULONG WINAPI cache_Release( IAssemblyCache *iface )
|
||||
if (!refs)
|
||||
{
|
||||
TRACE("destroying %p\n", cache);
|
||||
CloseHandle( cache->lock );
|
||||
HeapFree( GetProcessHeap(), 0, cache );
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI cache_UninstallAssembly(
|
||||
IAssemblyCache *iface,
|
||||
DWORD flags,
|
||||
LPCWSTR name,
|
||||
LPCFUSION_INSTALL_REFERENCE ref,
|
||||
ULONG *disp )
|
||||
static unsigned int build_sxs_path( WCHAR *path )
|
||||
{
|
||||
FIXME("%p, 0x%08x, %s, %p, %p\n", iface, flags, debugstr_w(name), ref, disp);
|
||||
return E_NOTIMPL;
|
||||
static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
|
||||
unsigned int len = GetWindowsDirectoryW( path, MAX_PATH );
|
||||
|
||||
memcpy( path + len, winsxsW, sizeof(winsxsW) );
|
||||
return len + sizeof(winsxsW) / sizeof(winsxsW[0]) - 1;
|
||||
}
|
||||
|
||||
static WCHAR *build_assembly_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
|
||||
const WCHAR *version, unsigned int *len )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','s','_','%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
|
||||
unsigned int buflen = sizeof(fmtW) / sizeof(fmtW[0]);
|
||||
WCHAR *ret, *p;
|
||||
|
||||
buflen += strlenW( arch );
|
||||
buflen += strlenW( name );
|
||||
buflen += strlenW( token );
|
||||
buflen += strlenW( version );
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
|
||||
*len = sprintfW( ret, fmtW, arch, name, token, version );
|
||||
for (p = ret; *p; p++) *p = tolowerW( *p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *build_manifest_path( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
|
||||
const WCHAR *version )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','s','m','a','n','i','f','e','s','t','s','\\','%','s','.','m','a','n','i','f','e','s','t',0};
|
||||
WCHAR *path = NULL, *ret, sxsdir[MAX_PATH];
|
||||
unsigned int len;
|
||||
|
||||
if (!(path = build_assembly_name( arch, name, token, version, &len ))) return NULL;
|
||||
len += sizeof(fmtW) / sizeof(fmtW[0]);
|
||||
len += build_sxs_path( sxsdir );
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
return NULL;
|
||||
}
|
||||
sprintfW( ret, fmtW, sxsdir, path );
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *build_policy_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
|
||||
unsigned int *len )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
|
||||
unsigned int buflen = sizeof(fmtW) / sizeof(fmtW[0]);
|
||||
WCHAR *ret, *p;
|
||||
|
||||
buflen += strlenW( arch );
|
||||
buflen += strlenW( name );
|
||||
buflen += strlenW( token );
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
|
||||
*len = sprintfW( ret, fmtW, arch, name, token );
|
||||
for (p = ret; *p; p++) *p = tolowerW( *p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *build_policy_path( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
|
||||
const WCHAR *version )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','s','p','o','l','i','c','i','e','s','\\','%','s','\\','%','s','.','p','o','l','i','c','y',0};
|
||||
WCHAR *path = NULL, *ret, sxsdir[MAX_PATH];
|
||||
unsigned int len;
|
||||
|
||||
if (!(path = build_policy_name( arch, name, token, &len ))) return NULL;
|
||||
len += sizeof(fmtW) / sizeof(fmtW[0]);
|
||||
len += build_sxs_path( sxsdir );
|
||||
len += strlenW( version );
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
return NULL;
|
||||
}
|
||||
sprintfW( ret, fmtW, sxsdir, path, version );
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cache_lock( struct cache *cache )
|
||||
{
|
||||
WaitForSingleObject( cache->lock, INFINITE );
|
||||
}
|
||||
|
||||
static void cache_unlock( struct cache *cache )
|
||||
{
|
||||
ReleaseMutex( cache->lock );
|
||||
}
|
||||
|
||||
#define ASSEMBLYINFO_FLAG_INSTALLED 1
|
||||
|
||||
static HRESULT WINAPI cache_QueryAssemblyInfo(
|
||||
IAssemblyCache *iface,
|
||||
DWORD flags,
|
||||
LPCWSTR name,
|
||||
LPCWSTR assembly_name,
|
||||
ASSEMBLY_INFO *info )
|
||||
{
|
||||
FIXME("%p, 0x%08x, %s, %p\n", iface, flags, debugstr_w(name), info);
|
||||
return E_NOTIMPL;
|
||||
struct cache *cache = impl_from_IAssemblyCache( iface );
|
||||
IAssemblyName *name_obj;
|
||||
const WCHAR *arch, *name, *token, *type, *version;
|
||||
WCHAR *p, *path = NULL;
|
||||
unsigned int len;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p, 0x%08x, %s, %p\n", iface, flags, debugstr_w(assembly_name), info);
|
||||
|
||||
if (flags || (info && info->cbAssemblyInfo != sizeof(*info)))
|
||||
return E_INVALIDARG;
|
||||
|
||||
hr = CreateAssemblyNameObject( &name_obj, assembly_name, CANOF_PARSE_DISPLAY_NAME, 0 );
|
||||
if (FAILED( hr ))
|
||||
return hr;
|
||||
|
||||
arch = get_name_attribute( name_obj, NAME_ATTR_ID_ARCH );
|
||||
name = get_name_attribute( name_obj, NAME_ATTR_ID_NAME );
|
||||
token = get_name_attribute( name_obj, NAME_ATTR_ID_TOKEN );
|
||||
type = get_name_attribute( name_obj, NAME_ATTR_ID_TYPE );
|
||||
version = get_name_attribute( name_obj, NAME_ATTR_ID_VERSION );
|
||||
if (!arch || !name || !token || !type || !version)
|
||||
{
|
||||
IAssemblyName_Release( name_obj );
|
||||
return HRESULT_FROM_WIN32( ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE );
|
||||
}
|
||||
if (!info)
|
||||
{
|
||||
IAssemblyName_Release( name_obj );
|
||||
return S_OK;
|
||||
}
|
||||
cache_lock( cache );
|
||||
|
||||
if (!strcmpW( type, win32W )) path = build_manifest_path( arch, name, token, version );
|
||||
else if (!strcmpW( type, win32_policyW )) path = build_policy_path( arch, name, token, version );
|
||||
else
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32( ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE );
|
||||
goto done;
|
||||
}
|
||||
if (!path)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
hr = S_OK;
|
||||
if (GetFileAttributesW( path ) != INVALID_FILE_ATTRIBUTES) /* FIXME: better check */
|
||||
{
|
||||
info->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED;
|
||||
TRACE("assembly is installed\n");
|
||||
}
|
||||
if ((p = strrchrW( path, '\\' ))) *p = 0;
|
||||
len = strlenW( path ) + 1;
|
||||
if (info->pszCurrentAssemblyPathBuf)
|
||||
{
|
||||
if (info->cchBuf < len)
|
||||
{
|
||||
info->cchBuf = len;
|
||||
hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
|
||||
}
|
||||
else strcpyW( info->pszCurrentAssemblyPathBuf, path );
|
||||
}
|
||||
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
IAssemblyName_Release( name_obj );
|
||||
cache_unlock( cache );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI cache_CreateAssemblyCacheItem(
|
||||
@@ -274,8 +430,6 @@ static HRESULT parse_assembly( IXMLDOMDocument *doc, struct assembly **assembly
|
||||
static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
|
||||
static const WCHAR architectureW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0};
|
||||
static const WCHAR tokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
|
||||
static const WCHAR win32W[] = {'w','i','n','3','2',0};
|
||||
static const WCHAR policyW[] = {'w','i','n','3','2','-','p','o','l','i','c','y',0};
|
||||
IXMLDOMNodeList *list = NULL;
|
||||
IXMLDOMNode *node = NULL;
|
||||
IXMLDOMNamedNodeMap *attrs = NULL;
|
||||
@@ -319,7 +473,7 @@ static HRESULT parse_assembly( IXMLDOMDocument *doc, struct assembly **assembly
|
||||
a->arch = get_attribute_value( attrs, architectureW );
|
||||
a->token = get_attribute_value( attrs, tokenW );
|
||||
|
||||
if (!a->type || (strcmpW( a->type, win32W ) && strcmpW( a->type, policyW )) ||
|
||||
if (!a->type || (strcmpW( a->type, win32W ) && strcmpW( a->type, win32_policyW )) ||
|
||||
!a->name || !a->version || !a->arch || !a->token)
|
||||
{
|
||||
WARN("invalid win32 assembly\n");
|
||||
@@ -337,97 +491,56 @@ done:
|
||||
return hr;
|
||||
}
|
||||
|
||||
static WCHAR *build_sxs_path( void )
|
||||
static WCHAR *build_policy_filename( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
|
||||
const WCHAR *version )
|
||||
{
|
||||
static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
|
||||
WCHAR sxsdir[MAX_PATH];
|
||||
static const WCHAR policiesW[] = {'p','o','l','i','c','i','e','s','\\',0};
|
||||
static const WCHAR suffixW[] = {'.','p','o','l','i','c','y',0};
|
||||
WCHAR sxsdir[MAX_PATH], *ret, *fullname;
|
||||
unsigned int len;
|
||||
|
||||
GetWindowsDirectoryW( sxsdir, MAX_PATH );
|
||||
strcatW( sxsdir, winsxsW );
|
||||
return strdupW( sxsdir );
|
||||
}
|
||||
if (!(fullname = build_policy_name( arch, name, token, &len ))) return NULL;
|
||||
len += build_sxs_path( sxsdir );
|
||||
len += sizeof(policiesW) / sizeof(policiesW[0]) - 1;
|
||||
len += strlenW( version );
|
||||
len += sizeof(suffixW) / sizeof(suffixW[0]) - 1;
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, fullname );
|
||||
return NULL;
|
||||
}
|
||||
strcpyW( ret, sxsdir );
|
||||
strcatW( ret, policiesW );
|
||||
CreateDirectoryW( ret, NULL );
|
||||
strcatW( ret, name );
|
||||
CreateDirectoryW( ret, NULL );
|
||||
strcatW( ret, backslashW );
|
||||
strcatW( ret, version );
|
||||
strcatW( ret, suffixW );
|
||||
|
||||
static WCHAR *build_assembly_name( struct assembly *assembly )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','s','_','%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
|
||||
WCHAR *ret, *p;
|
||||
int len;
|
||||
|
||||
len = strlenW( fmtW );
|
||||
len += strlenW( assembly->arch );
|
||||
len += strlenW( assembly->name );
|
||||
len += strlenW( assembly->token );
|
||||
len += strlenW( assembly->version );
|
||||
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
|
||||
sprintfW( ret, fmtW, assembly->arch, assembly->name, assembly->token, assembly->version );
|
||||
for (p = ret; *p; p++) *p = tolowerW( *p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *build_policy_name( struct assembly *assembly )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
|
||||
WCHAR *ret, *p;
|
||||
int len;
|
||||
|
||||
len = strlenW( fmtW );
|
||||
len += strlenW( assembly->arch );
|
||||
len += strlenW( assembly->name );
|
||||
len += strlenW( assembly->token );
|
||||
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
|
||||
sprintfW( ret, fmtW, assembly->arch, assembly->name, assembly->token );
|
||||
for (p = ret; *p; p++) *p = tolowerW( *p );
|
||||
HeapFree( GetProcessHeap(), 0, fullname );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT install_policy( const WCHAR *manifest, struct assembly *assembly )
|
||||
{
|
||||
static const WCHAR policiesW[] = {'p','o','l','i','c','i','e','s','\\',0};
|
||||
static const WCHAR suffixW[] = {'.','p','o','l','i','c','y',0};
|
||||
static const WCHAR backslashW[] = {'\\',0};
|
||||
WCHAR *sxsdir, *name, *dst;
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
WCHAR *dst;
|
||||
BOOL ret;
|
||||
int len;
|
||||
|
||||
/* FIXME: handle catalog file */
|
||||
|
||||
if (!(sxsdir = build_sxs_path())) return E_OUTOFMEMORY;
|
||||
if (!(name = build_policy_name( assembly ))) goto done;
|
||||
|
||||
len = strlenW( sxsdir );
|
||||
len += strlenW( policiesW );
|
||||
len += strlenW( name ) + 1;
|
||||
len += strlenW( assembly->version );
|
||||
len += strlenW( suffixW );
|
||||
|
||||
if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) goto done;
|
||||
strcpyW( dst, sxsdir );
|
||||
strcatW( dst, policiesW );
|
||||
CreateDirectoryW( dst, NULL );
|
||||
strcatW( dst, name );
|
||||
CreateDirectoryW( dst, NULL );
|
||||
strcatW( dst, backslashW );
|
||||
strcatW( dst, assembly->version );
|
||||
strcatW( dst, suffixW );
|
||||
dst = build_policy_filename( assembly->arch, assembly->name, assembly->token, assembly->version );
|
||||
if (!dst) return E_OUTOFMEMORY;
|
||||
|
||||
ret = CopyFileW( manifest, dst, FALSE );
|
||||
HeapFree( GetProcessHeap(), 0, dst );
|
||||
if (!ret)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||||
HRESULT hr = HRESULT_FROM_WIN32( GetLastError() );
|
||||
WARN("failed to copy policy manifest file 0x%08x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
hr = S_OK;
|
||||
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, sxsdir );
|
||||
HeapFree( GetProcessHeap(), 0, name );
|
||||
return hr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file )
|
||||
@@ -449,29 +562,64 @@ static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file )
|
||||
return src;
|
||||
}
|
||||
|
||||
static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembly )
|
||||
static WCHAR *build_manifest_filename( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
|
||||
const WCHAR *version )
|
||||
{
|
||||
static const WCHAR manifestsW[] = {'m','a','n','i','f','e','s','t','s','\\',0};
|
||||
static const WCHAR suffixW[] = {'.','m','a','n','i','f','e','s','t',0};
|
||||
static const WCHAR backslashW[] = {'\\',0};
|
||||
WCHAR *sxsdir, *p, *name, *dst, *src;
|
||||
WCHAR sxsdir[MAX_PATH], *ret, *fullname;
|
||||
unsigned int len;
|
||||
|
||||
if (!(fullname = build_assembly_name( arch, name, token, version, &len ))) return NULL;
|
||||
len += build_sxs_path( sxsdir );
|
||||
len += sizeof(manifestsW) / sizeof(manifestsW[0]) - 1;
|
||||
len += sizeof(suffixW) / sizeof(suffixW[0]) - 1;
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, fullname );
|
||||
return NULL;
|
||||
}
|
||||
strcpyW( ret, sxsdir );
|
||||
strcatW( ret, manifestsW );
|
||||
strcatW( ret, fullname );
|
||||
strcatW( ret, suffixW );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, fullname );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT load_manifest( IXMLDOMDocument *doc, const WCHAR *filename )
|
||||
{
|
||||
HRESULT hr;
|
||||
VARIANT var;
|
||||
VARIANT_BOOL b;
|
||||
BSTR str;
|
||||
|
||||
str = SysAllocString( filename );
|
||||
VariantInit( &var );
|
||||
V_VT( &var ) = VT_BSTR;
|
||||
V_BSTR( &var ) = str;
|
||||
hr = IXMLDOMDocument_load( doc, var, &b );
|
||||
SysFreeString( str );
|
||||
if (hr != S_OK) return hr;
|
||||
if (!b)
|
||||
{
|
||||
WARN("failed to load manifest\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembly )
|
||||
{
|
||||
WCHAR sxsdir[MAX_PATH], *p, *name, *dst, *src;
|
||||
unsigned int len, len_name, len_sxsdir = build_sxs_path( sxsdir );
|
||||
struct file *file;
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
BOOL ret;
|
||||
int len;
|
||||
|
||||
if (!(sxsdir = build_sxs_path())) return E_OUTOFMEMORY;
|
||||
if (!(name = build_assembly_name( assembly ))) goto done;
|
||||
|
||||
len = strlenW( sxsdir );
|
||||
len += strlenW( manifestsW );
|
||||
len += strlenW( name );
|
||||
len += strlenW( suffixW );
|
||||
if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) goto done;
|
||||
strcpyW( dst, sxsdir );
|
||||
strcatW( dst, manifestsW );
|
||||
strcatW( dst, name );
|
||||
strcatW( dst, suffixW );
|
||||
dst = build_manifest_filename( assembly->arch, assembly->name, assembly->token, assembly->version );
|
||||
if (!dst) return E_OUTOFMEMORY;
|
||||
|
||||
ret = CopyFileW( manifest, dst, FALSE );
|
||||
HeapFree( GetProcessHeap(), 0, dst );
|
||||
@@ -479,22 +627,22 @@ static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembl
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||||
WARN("failed to copy manifest file 0x%08x\n", hr);
|
||||
goto done;
|
||||
return hr;
|
||||
}
|
||||
|
||||
name = build_assembly_name( assembly->arch, assembly->name, assembly->token, assembly->version,
|
||||
&len_name );
|
||||
if (!name) return E_OUTOFMEMORY;
|
||||
|
||||
/* FIXME: this should be a transaction */
|
||||
LIST_FOR_EACH_ENTRY( file, &assembly->files, struct file, entry )
|
||||
{
|
||||
if (!(src = build_source_filename( manifest, file )))
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
len = strlenW( sxsdir ) + strlenW( name ) + strlenW( file->name );
|
||||
if (!(src = build_source_filename( manifest, file ))) goto done;
|
||||
|
||||
len = len_sxsdir + len_name + strlenW( file->name );
|
||||
if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, src );
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto done;
|
||||
}
|
||||
strcpyW( dst, sxsdir );
|
||||
@@ -518,7 +666,6 @@ static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembl
|
||||
hr = S_OK;
|
||||
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, sxsdir );
|
||||
HeapFree( GetProcessHeap(), 0, name );
|
||||
return hr;
|
||||
}
|
||||
@@ -529,43 +676,26 @@ static HRESULT WINAPI cache_InstallAssembly(
|
||||
LPCWSTR path,
|
||||
LPCFUSION_INSTALL_REFERENCE ref )
|
||||
{
|
||||
static const WCHAR policyW[] = {'w','i','n','3','2','-','p','o','l','i','c','y',0};
|
||||
struct cache *cache = impl_from_IAssemblyCache( iface );
|
||||
HRESULT hr, init;
|
||||
IXMLDOMDocument *doc = NULL;
|
||||
struct assembly *assembly = NULL;
|
||||
BSTR str;
|
||||
VARIANT var;
|
||||
VARIANT_BOOL b;
|
||||
|
||||
TRACE("%p, 0x%08x, %s, %p\n", iface, flags, debugstr_w(path), ref);
|
||||
|
||||
cache_lock( cache );
|
||||
init = CoInitialize( NULL );
|
||||
|
||||
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc );
|
||||
if (hr != S_OK)
|
||||
goto done;
|
||||
|
||||
str = SysAllocString( path );
|
||||
VariantInit( &var );
|
||||
V_VT( &var ) = VT_BSTR;
|
||||
V_BSTR( &var ) = str;
|
||||
hr = IXMLDOMDocument_load( doc, var, &b );
|
||||
SysFreeString( str );
|
||||
if (hr != S_OK) goto done;
|
||||
if (!b)
|
||||
{
|
||||
WARN("failed to load manifest\n");
|
||||
hr = S_FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = parse_assembly( doc, &assembly );
|
||||
if (hr != S_OK)
|
||||
goto done;
|
||||
if ((hr = load_manifest( doc, path )) != S_OK) goto done;
|
||||
if ((hr = parse_assembly( doc, &assembly )) != S_OK) goto done;
|
||||
|
||||
/* FIXME: verify name attributes */
|
||||
|
||||
if (!strcmpW( assembly->type, policyW ))
|
||||
if (!strcmpW( assembly->type, win32_policyW ))
|
||||
hr = install_policy( path, assembly );
|
||||
else
|
||||
hr = install_assembly( path, assembly );
|
||||
@@ -573,10 +703,115 @@ static HRESULT WINAPI cache_InstallAssembly(
|
||||
done:
|
||||
free_assembly( assembly );
|
||||
if (doc) IXMLDOMDocument_Release( doc );
|
||||
if (SUCCEEDED(init)) CoUninitialize();
|
||||
cache_unlock( cache );
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(init))
|
||||
CoUninitialize();
|
||||
static HRESULT uninstall_assembly( struct assembly *assembly )
|
||||
{
|
||||
WCHAR sxsdir[MAX_PATH], *name, *dirname, *filename;
|
||||
unsigned int len, len_name, len_sxsdir = build_sxs_path( sxsdir );
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
struct file *file;
|
||||
|
||||
name = build_assembly_name( assembly->arch, assembly->name, assembly->token, assembly->version,
|
||||
&len_name );
|
||||
if (!name) return E_OUTOFMEMORY;
|
||||
if (!(dirname = HeapAlloc( GetProcessHeap(), 0, (len_sxsdir + len_name + 1) * sizeof(WCHAR) )))
|
||||
goto done;
|
||||
strcpyW( dirname, sxsdir );
|
||||
strcpyW( dirname + len_sxsdir, name );
|
||||
|
||||
LIST_FOR_EACH_ENTRY( file, &assembly->files, struct file, entry )
|
||||
{
|
||||
len = len_sxsdir + len_name + 1 + strlenW( file->name );
|
||||
if (!(filename = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) goto done;
|
||||
strcpyW( filename, dirname );
|
||||
strcatW( filename, backslashW );
|
||||
strcatW( filename, file->name );
|
||||
|
||||
if (!DeleteFileW( filename )) WARN( "failed to delete file %u\n", GetLastError() );
|
||||
HeapFree( GetProcessHeap(), 0, filename );
|
||||
}
|
||||
RemoveDirectoryW( dirname );
|
||||
hr = S_OK;
|
||||
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, dirname );
|
||||
HeapFree( GetProcessHeap(), 0, name );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI cache_UninstallAssembly(
|
||||
IAssemblyCache *iface,
|
||||
DWORD flags,
|
||||
LPCWSTR assembly_name,
|
||||
LPCFUSION_INSTALL_REFERENCE ref,
|
||||
ULONG *disp )
|
||||
{
|
||||
struct cache *cache = impl_from_IAssemblyCache( iface );
|
||||
HRESULT hr, init;
|
||||
IXMLDOMDocument *doc = NULL;
|
||||
struct assembly *assembly = NULL;
|
||||
IAssemblyName *name_obj = NULL;
|
||||
const WCHAR *arch, *name, *token, *type, *version;
|
||||
WCHAR *p, *path = NULL;
|
||||
|
||||
TRACE("%p, 0x%08x, %s, %p, %p\n", iface, flags, debugstr_w(assembly_name), ref, disp);
|
||||
|
||||
if (ref)
|
||||
{
|
||||
FIXME("application reference not supported\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
cache_lock( cache );
|
||||
init = CoInitialize( NULL );
|
||||
|
||||
hr = CreateAssemblyNameObject( &name_obj, assembly_name, CANOF_PARSE_DISPLAY_NAME, NULL );
|
||||
if (FAILED( hr ))
|
||||
goto done;
|
||||
|
||||
arch = get_name_attribute( name_obj, NAME_ATTR_ID_ARCH );
|
||||
name = get_name_attribute( name_obj, NAME_ATTR_ID_NAME );
|
||||
token = get_name_attribute( name_obj, NAME_ATTR_ID_TOKEN );
|
||||
type = get_name_attribute( name_obj, NAME_ATTR_ID_TYPE );
|
||||
version = get_name_attribute( name_obj, NAME_ATTR_ID_VERSION );
|
||||
if (!arch || !name || !token || !type || !version)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto done;
|
||||
}
|
||||
if (!strcmpW( type, win32W )) path = build_manifest_filename( arch, name, token, version );
|
||||
else if (!strcmpW( type, win32_policyW )) path = build_policy_filename( arch, name, token, version );
|
||||
else
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc );
|
||||
if (hr != S_OK)
|
||||
goto done;
|
||||
|
||||
if ((hr = load_manifest( doc, path )) != S_OK) goto done;
|
||||
if ((hr = parse_assembly( doc, &assembly )) != S_OK) goto done;
|
||||
|
||||
if (!DeleteFileW( path )) WARN( "unable to remove manifest file %u\n", GetLastError() );
|
||||
else if ((p = strrchrW( path, '\\' )))
|
||||
{
|
||||
*p = 0;
|
||||
RemoveDirectoryW( path );
|
||||
}
|
||||
if (!strcmpW( assembly->type, win32W )) hr = uninstall_assembly( assembly );
|
||||
|
||||
done:
|
||||
if (name_obj) IAssemblyName_Release( name_obj );
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
free_assembly( assembly );
|
||||
if (doc) IXMLDOMDocument_Release( doc );
|
||||
if (SUCCEEDED(init)) CoUninitialize();
|
||||
cache_unlock( cache );
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -612,7 +847,12 @@ HRESULT WINAPI CreateAssemblyCache( IAssemblyCache **obj, DWORD reserved )
|
||||
|
||||
cache->IAssemblyCache_iface.lpVtbl = &cache_vtbl;
|
||||
cache->refs = 1;
|
||||
|
||||
cache->lock = CreateMutexW( NULL, FALSE, cache_mutex_nameW );
|
||||
if (!cache->lock)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, cache );
|
||||
return HRESULT_FROM_WIN32( GetLastError() );
|
||||
}
|
||||
*obj = &cache->IAssemblyCache_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* IAssemblyName implementation
|
||||
*
|
||||
* Copyright 2012 Hans Leidekker for CodeWeavers
|
||||
*
|
||||
* 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 "ole2.h"
|
||||
#include "winsxs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "sxs_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(sxs);
|
||||
|
||||
struct name
|
||||
{
|
||||
IAssemblyName IAssemblyName_iface;
|
||||
LONG refs;
|
||||
WCHAR *name;
|
||||
WCHAR *arch;
|
||||
WCHAR *token;
|
||||
WCHAR *type;
|
||||
WCHAR *version;
|
||||
};
|
||||
|
||||
static const WCHAR archW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0};
|
||||
static const WCHAR tokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
|
||||
static const WCHAR typeW[] = {'t','y','p','e',0};
|
||||
static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
|
||||
|
||||
static inline struct name *impl_from_IAssemblyName( IAssemblyName *iface )
|
||||
{
|
||||
return CONTAINING_RECORD( iface, struct name, IAssemblyName_iface );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_QueryInterface(
|
||||
IAssemblyName *iface,
|
||||
REFIID riid,
|
||||
void **obj )
|
||||
{
|
||||
struct name *name = impl_from_IAssemblyName( iface );
|
||||
|
||||
TRACE("%p, %s, %p\n", name, debugstr_guid(riid), obj);
|
||||
|
||||
*obj = NULL;
|
||||
|
||||
if (IsEqualIID( riid, &IID_IUnknown ) ||
|
||||
IsEqualIID( riid, &IID_IAssemblyName ))
|
||||
{
|
||||
IUnknown_AddRef( iface );
|
||||
*obj = name;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI name_AddRef(
|
||||
IAssemblyName *iface )
|
||||
{
|
||||
struct name *name = impl_from_IAssemblyName( iface );
|
||||
return InterlockedIncrement( &name->refs );
|
||||
}
|
||||
|
||||
static ULONG WINAPI name_Release( IAssemblyName *iface )
|
||||
{
|
||||
struct name *name = impl_from_IAssemblyName( iface );
|
||||
ULONG refs = InterlockedDecrement( &name->refs );
|
||||
|
||||
if (!refs)
|
||||
{
|
||||
TRACE("destroying %p\n", name);
|
||||
HeapFree( GetProcessHeap(), 0, name->name );
|
||||
HeapFree( GetProcessHeap(), 0, name->arch );
|
||||
HeapFree( GetProcessHeap(), 0, name->token );
|
||||
HeapFree( GetProcessHeap(), 0, name->type );
|
||||
HeapFree( GetProcessHeap(), 0, name->version );
|
||||
HeapFree( GetProcessHeap(), 0, name );
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_SetProperty(
|
||||
IAssemblyName *iface,
|
||||
DWORD id,
|
||||
LPVOID property,
|
||||
DWORD size )
|
||||
{
|
||||
FIXME("%p, %d, %p, %d\n", iface, id, property, size);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_GetProperty(
|
||||
IAssemblyName *iface,
|
||||
DWORD id,
|
||||
LPVOID buffer,
|
||||
LPDWORD buflen )
|
||||
{
|
||||
FIXME("%p, %d, %p, %p\n", iface, id, buffer, buflen);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_Finalize(
|
||||
IAssemblyName *iface )
|
||||
{
|
||||
FIXME("%p\n", iface);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_GetDisplayName(
|
||||
IAssemblyName *iface,
|
||||
LPOLESTR buffer,
|
||||
LPDWORD buflen,
|
||||
DWORD flags )
|
||||
{
|
||||
static const WCHAR fmtW[] = {',','%','s','=','\"','%','s','\"',0};
|
||||
struct name *name = impl_from_IAssemblyName( iface );
|
||||
WCHAR version[30];
|
||||
unsigned int len;
|
||||
|
||||
TRACE("%p, %p, %p, 0x%08x\n", iface, buffer, buflen, flags);
|
||||
|
||||
if (!buflen || flags) return E_INVALIDARG;
|
||||
|
||||
len = strlenW( name->name ) + 1;
|
||||
if (name->arch) len += strlenW( archW ) + strlenW( name->arch ) + 4;
|
||||
if (name->token) len += strlenW( tokenW ) + strlenW( name->token ) + 4;
|
||||
if (name->type) len += strlenW( typeW ) + strlenW( name->type ) + 4;
|
||||
if (name->version) len += strlenW( versionW ) + strlenW( version ) + 4;
|
||||
if (len > *buflen)
|
||||
{
|
||||
*buflen = len;
|
||||
return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
|
||||
}
|
||||
strcpyW( buffer, name->name );
|
||||
len = strlenW( buffer );
|
||||
if (name->arch) len += sprintfW( buffer + len, fmtW, archW, name->arch );
|
||||
if (name->token) len += sprintfW( buffer + len, fmtW, tokenW, name->token );
|
||||
if (name->type) len += sprintfW( buffer + len, fmtW, typeW, name->type );
|
||||
if (name->version) len += sprintfW( buffer + len, fmtW, versionW, name->version );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_Reserved(
|
||||
IAssemblyName *iface,
|
||||
REFIID riid,
|
||||
IUnknown *pUnkReserved1,
|
||||
IUnknown *pUnkReserved2,
|
||||
LPCOLESTR szReserved,
|
||||
LONGLONG llReserved,
|
||||
LPVOID pvReserved,
|
||||
DWORD cbReserved,
|
||||
LPVOID *ppReserved )
|
||||
{
|
||||
FIXME("%p, %s, %p, %p, %s, %x%08x, %p, %d, %p\n", iface,
|
||||
debugstr_guid(riid), pUnkReserved1, pUnkReserved2,
|
||||
debugstr_w(szReserved), (DWORD)(llReserved >> 32), (DWORD)llReserved,
|
||||
pvReserved, cbReserved, ppReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
const WCHAR *get_name_attribute( IAssemblyName *iface, enum name_attr_id id )
|
||||
{
|
||||
struct name *name = impl_from_IAssemblyName( iface );
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case NAME_ATTR_ID_NAME: return name->name;
|
||||
case NAME_ATTR_ID_ARCH: return name->arch;
|
||||
case NAME_ATTR_ID_TOKEN: return name->token;
|
||||
case NAME_ATTR_ID_TYPE: return name->type;
|
||||
case NAME_ATTR_ID_VERSION: return name->version;
|
||||
default:
|
||||
ERR("unhandled name attribute %u\n", id);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_GetName(
|
||||
IAssemblyName *iface,
|
||||
LPDWORD buflen,
|
||||
WCHAR *buffer )
|
||||
{
|
||||
const WCHAR *name;
|
||||
int len;
|
||||
|
||||
TRACE("%p, %p, %p\n", iface, buflen, buffer);
|
||||
|
||||
if (!buflen || !buffer) return E_INVALIDARG;
|
||||
|
||||
name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
|
||||
len = strlenW( name ) + 1;
|
||||
if (len > *buflen)
|
||||
{
|
||||
*buflen = len;
|
||||
return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
|
||||
}
|
||||
strcpyW( buffer, name );
|
||||
*buflen = len + 3;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low )
|
||||
{
|
||||
WORD ver[4];
|
||||
WCHAR *p, *q;
|
||||
unsigned int i;
|
||||
|
||||
memset( ver, 0, sizeof(ver) );
|
||||
for (i = 0, p = version; i < 4; i++)
|
||||
{
|
||||
if (!*p) break;
|
||||
q = strchrW( p, '.' );
|
||||
if (q) *q = 0;
|
||||
ver[i] = atolW( p );
|
||||
if (!q && i < 3) break;
|
||||
p = q + 1;
|
||||
}
|
||||
*high = (ver[0] << 16) + ver[1];
|
||||
*low = (ver[2] << 16) + ver[3];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_GetVersion(
|
||||
IAssemblyName *iface,
|
||||
LPDWORD high,
|
||||
LPDWORD low )
|
||||
{
|
||||
struct name *name = impl_from_IAssemblyName( iface );
|
||||
WCHAR *version;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p, %p, %p\n", iface, high, low);
|
||||
|
||||
if (!name->version) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
|
||||
if (!(version = strdupW( name->version ))) return E_OUTOFMEMORY;
|
||||
hr = parse_version( version, high, low );
|
||||
HeapFree( GetProcessHeap(), 0, version );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_IsEqual(
|
||||
IAssemblyName *name1,
|
||||
IAssemblyName *name2,
|
||||
DWORD flags )
|
||||
{
|
||||
FIXME("%p, %p, 0x%08x\n", name1, name2, flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI name_Clone(
|
||||
IAssemblyName *iface,
|
||||
IAssemblyName **name )
|
||||
{
|
||||
FIXME("%p, %p\n", iface, name);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IAssemblyNameVtbl name_vtbl =
|
||||
{
|
||||
name_QueryInterface,
|
||||
name_AddRef,
|
||||
name_Release,
|
||||
name_SetProperty,
|
||||
name_GetProperty,
|
||||
name_Finalize,
|
||||
name_GetDisplayName,
|
||||
name_Reserved,
|
||||
name_GetName,
|
||||
name_GetVersion,
|
||||
name_IsEqual,
|
||||
name_Clone
|
||||
};
|
||||
|
||||
static WCHAR *parse_value( const WCHAR *str, unsigned int *len )
|
||||
{
|
||||
WCHAR *ret;
|
||||
const WCHAR *p = str;
|
||||
|
||||
if (*p++ != '\"') return NULL;
|
||||
while (*p && *p != '\"') p++;
|
||||
if (!*p) return NULL;
|
||||
|
||||
*len = p - str;
|
||||
if (!(ret = HeapAlloc( GetProcessHeap(), 0, *len * sizeof(WCHAR) ))) return NULL;
|
||||
memcpy( ret, str + 1, (*len - 1) * sizeof(WCHAR) );
|
||||
ret[*len - 1] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT parse_displayname( struct name *name, const WCHAR *displayname )
|
||||
{
|
||||
const WCHAR *p, *q;
|
||||
unsigned int len;
|
||||
|
||||
p = q = displayname;
|
||||
while (*q && *q != ',') q++;
|
||||
len = q - p;
|
||||
if (!(name->name = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
|
||||
memcpy( name->name, p, len * sizeof(WCHAR) );
|
||||
name->name[len] = 0;
|
||||
if (!*q) return S_OK;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
p = ++q;
|
||||
while (*q && *q != '=') q++;
|
||||
if (!*q) return E_INVALIDARG;
|
||||
len = q - p;
|
||||
if (len == sizeof(archW)/sizeof(archW[0]) - 1 && !memcmp( p, archW, len * sizeof(WCHAR) ))
|
||||
{
|
||||
p = ++q;
|
||||
if (!(name->arch = parse_value( p, &len ))) return E_INVALIDARG;
|
||||
q += len;
|
||||
}
|
||||
else if (len == sizeof(tokenW)/sizeof(tokenW[0]) - 1 && !memcmp( p, tokenW, len * sizeof(WCHAR) ))
|
||||
{
|
||||
p = ++q;
|
||||
if (!(name->token = parse_value( p, &len ))) return E_INVALIDARG;
|
||||
q += len;
|
||||
}
|
||||
else if (len == sizeof(typeW)/sizeof(typeW[0]) - 1 && !memcmp( p, typeW, len * sizeof(WCHAR) ))
|
||||
{
|
||||
p = ++q;
|
||||
if (!(name->type = parse_value( p, &len ))) return E_INVALIDARG;
|
||||
q += len;
|
||||
}
|
||||
else if (len == sizeof(versionW)/sizeof(versionW[0]) - 1 && !memcmp( p, versionW, len * sizeof(WCHAR) ))
|
||||
{
|
||||
p = ++q;
|
||||
if (!(name->version = parse_value( p, &len ))) return E_INVALIDARG;
|
||||
q += len;
|
||||
}
|
||||
else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME );
|
||||
while (*q && *q != ',') q++;
|
||||
if (!*q) break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CreateAssemblyNameObject (SXS.@)
|
||||
*/
|
||||
HRESULT WINAPI CreateAssemblyNameObject(
|
||||
LPASSEMBLYNAME *obj,
|
||||
LPCWSTR assembly,
|
||||
DWORD flags,
|
||||
LPVOID reserved )
|
||||
{
|
||||
struct name *name;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p, %s, 0x%08x, %p\n", obj, debugstr_w(assembly), flags, reserved);
|
||||
|
||||
if (!obj) return E_INVALIDARG;
|
||||
|
||||
*obj = NULL;
|
||||
if (!assembly || !assembly[0] || flags != CANOF_PARSE_DISPLAY_NAME)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!(name = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*name) )))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
name->IAssemblyName_iface.lpVtbl = &name_vtbl;
|
||||
name->refs = 1;
|
||||
|
||||
hr = parse_displayname( name, assembly );
|
||||
if (hr != S_OK)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, name->name );
|
||||
HeapFree( GetProcessHeap(), 0, name->arch );
|
||||
HeapFree( GetProcessHeap(), 0, name->token );
|
||||
HeapFree( GetProcessHeap(), 0, name->type );
|
||||
HeapFree( GetProcessHeap(), 0, name->version );
|
||||
HeapFree( GetProcessHeap(), 0, name );
|
||||
return hr;
|
||||
}
|
||||
*obj = &name->IAssemblyName_iface;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
@ stdcall CreateAssemblyCache(ptr long)
|
||||
@ stub CreateAssemblyNameObject
|
||||
@ stdcall CreateAssemblyNameObject(ptr wstr long ptr)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012 Hans Leidekker for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
enum name_attr_id
|
||||
{
|
||||
NAME_ATTR_ID_NAME,
|
||||
NAME_ATTR_ID_ARCH,
|
||||
NAME_ATTR_ID_TOKEN,
|
||||
NAME_ATTR_ID_TYPE,
|
||||
NAME_ATTR_ID_VERSION
|
||||
};
|
||||
|
||||
const WCHAR *get_name_attribute( IAssemblyName *, enum name_attr_id );
|
||||
|
||||
static inline WCHAR *strdupW( const WCHAR *src )
|
||||
{
|
||||
WCHAR *dst;
|
||||
|
||||
if (!src) return NULL;
|
||||
dst = HeapAlloc( GetProcessHeap(), 0, (strlenW( src ) + 1) * sizeof(WCHAR) );
|
||||
if (dst) strcpyW( dst, src );
|
||||
return dst;
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import "oleidl.idl";
|
||||
|
||||
interface IAssemblyCache;
|
||||
interface IAssemblyCacheItem;
|
||||
interface IAssemblyName;
|
||||
|
||||
typedef struct _FUSION_INSTALL_REFERENCE_
|
||||
{
|
||||
@@ -99,4 +100,99 @@ interface IAssemblyCacheItem : IUnknown
|
||||
HRESULT AbortItem();
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(cd193bc0-b4bc-11D2-9833-00c04fc31d2e),
|
||||
pointer_default(unique),
|
||||
local
|
||||
]
|
||||
interface IAssemblyName : IUnknown
|
||||
{
|
||||
typedef [public] enum
|
||||
{
|
||||
ASM_NAME_PUBLIC_KEY,
|
||||
ASM_NAME_PUBLIC_KEY_TOKEN,
|
||||
ASM_NAME_HASH_VALUE,
|
||||
ASM_NAME_NAME,
|
||||
ASM_NAME_MAJOR_VERSION,
|
||||
ASM_NAME_MINOR_VERSION,
|
||||
ASM_NAME_BUILD_NUMBER,
|
||||
ASM_NAME_REVISION_NUMBER,
|
||||
ASM_NAME_CULTURE,
|
||||
ASM_NAME_PROCESSOR_ID_ARRAY,
|
||||
ASM_NAME_OSINFO_ARRAY,
|
||||
ASM_NAME_HASH_ALGID,
|
||||
ASM_NAME_ALIAS,
|
||||
ASM_NAME_CODEBASE_URL,
|
||||
ASM_NAME_CODEBASE_LASTMOD,
|
||||
ASM_NAME_NULL_PUBLIC_KEY,
|
||||
ASM_NAME_NULL_PUBLIC_KEY_TOKEN,
|
||||
ASM_NAME_CUSTOM,
|
||||
ASM_NAME_NULL_CUSTOM,
|
||||
ASM_NAME_MVID,
|
||||
ASM_NAME_MAX_PARAMS
|
||||
} ASM_NAME;
|
||||
|
||||
typedef [public] enum
|
||||
{
|
||||
ASM_DISPLAYF_VERSION = 0x1,
|
||||
ASM_DISPLAYF_CULTURE = 0x2,
|
||||
ASM_DISPLAYF_PUBLIC_KEY_TOKEN = 0x4,
|
||||
ASM_DISPLAYF_PUBLIC_KEY = 0x8,
|
||||
ASM_DISPLAYF_CUSTOM = 0x10,
|
||||
ASM_DISPLAYF_PROCESSORARCHITECTURE = 0x20,
|
||||
ASM_DISPLAYF_LANGUAGEID = 0x40
|
||||
} ASM_DISPLAY_FLAGS;
|
||||
|
||||
HRESULT SetProperty(
|
||||
[in] DWORD id,
|
||||
[in] LPVOID property,
|
||||
[in] DWORD size);
|
||||
|
||||
HRESULT GetProperty(
|
||||
[in] DWORD id,
|
||||
[out] LPVOID buffer,
|
||||
[in][out] LPDWORD buflen);
|
||||
|
||||
HRESULT Finalize();
|
||||
|
||||
HRESULT GetDisplayName(
|
||||
[out] LPWSTR buffer,
|
||||
[in][out] LPDWORD buflen,
|
||||
[in] DWORD flags);
|
||||
|
||||
HRESULT Reserved(
|
||||
[in] REFIID riid,
|
||||
[in] IUnknown *pUnkReserved1,
|
||||
[in] IUnknown *pUnkReserved2,
|
||||
[in] LPCOLESTR szReserved,
|
||||
[in] LONGLONG llReserved,
|
||||
[in] LPVOID pvReserved,
|
||||
[in] DWORD cbReserved,
|
||||
[out] LPVOID *ppReserved);
|
||||
|
||||
HRESULT GetName(
|
||||
[in][out] LPDWORD buflen,
|
||||
[out] LPWSTR buffer);
|
||||
|
||||
HRESULT GetVersion(
|
||||
[out] LPDWORD hi,
|
||||
[out] LPDWORD low);
|
||||
|
||||
HRESULT IsEqual(
|
||||
[in] IAssemblyName *name,
|
||||
[in] DWORD flags);
|
||||
|
||||
HRESULT Clone(
|
||||
[out] IAssemblyName **name);
|
||||
}
|
||||
|
||||
typedef [unique] IAssemblyName *LPASSEMBLYNAME;
|
||||
typedef [public] enum
|
||||
{
|
||||
CANOF_PARSE_DISPLAY_NAME = 0x1,
|
||||
CANOF_SET_DEFAULT_VALUES = 0x2
|
||||
} CREATE_ASM_NAME_OBJ_FLAGS;
|
||||
|
||||
cpp_quote("HRESULT WINAPI CreateAssemblyCache(IAssemblyCache**,DWORD);")
|
||||
cpp_quote("HRESULT WINAPI CreateAssemblyNameObject(LPASSEMBLYNAME *,LPCWSTR,DWORD,LPVOID);")
|
||||
|
||||
@@ -161,7 +161,7 @@ reactos/dll/win32/spoolss # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/stdole2.tlb # Synced to Wine-1.3.37
|
||||
reactos/dll/win32/stdole32.tlb # Synced to Wine-1.3.37
|
||||
reactos/dll/win32/sti # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/sxs # Synced to Wine-1.3.37
|
||||
reactos/dll/win32/sxs # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/tapi32 # Autosync
|
||||
reactos/dll/win32/traffic # Autosync
|
||||
reactos/dll/win32/twain_32 # Out of sync
|
||||
|
||||
Reference in New Issue
Block a user