Author: akhaldi Date: Sat May 19 14:52:48 2012 New Revision: 56633
URL: http://svn.reactos.org/svn/reactos?rev=56633&view=rev Log: [SXS] * Sync to Wine 1.5.4.
Added: trunk/reactos/dll/win32/sxs/name.c (with props) trunk/reactos/dll/win32/sxs/sxs_private.h (with props) Modified: trunk/reactos/dll/win32/sxs/CMakeLists.txt trunk/reactos/dll/win32/sxs/cache.c trunk/reactos/dll/win32/sxs/sxs.spec trunk/reactos/include/psdk/winsxs.idl trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/sxs/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/sxs/CMakeLists.tx... ============================================================================== --- trunk/reactos/dll/win32/sxs/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/win32/sxs/CMakeLists.txt [iso-8859-1] Sat May 19 14:52:48 2012 @@ -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)
Modified: trunk/reactos/dll/win32/sxs/cache.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/sxs/cache.c?rev=5... ============================================================================== --- trunk/reactos/dll/win32/sxs/cache.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/sxs/cache.c [iso-8859-1] Sat May 19 14:52:48 2012 @@ -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 @@ 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 ) -{ - FIXME("%p, 0x%08x, %s, %p, %p\n", iface, flags, debugstr_w(name), ref, disp); - return E_NOTIMPL; -} +static unsigned int build_sxs_path( WCHAR *path ) +{ + 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 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 @@ 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 @@ return hr; }
-static WCHAR *build_sxs_path( void ) -{ - static const WCHAR winsxsW[] = {'\','w','i','n','s','x','s','\',0}; - WCHAR sxsdir[MAX_PATH]; - - GetWindowsDirectoryW( sxsdir, MAX_PATH ); - strcatW( sxsdir, winsxsW ); - return strdupW( sxsdir ); -} - -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 ); - return ret; -} - -static HRESULT install_policy( const WCHAR *manifest, struct assembly *assembly ) +static WCHAR *build_policy_filename( const WCHAR *arch, const WCHAR *name, const WCHAR *token, + const WCHAR *version ) { 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 sxsdir[MAX_PATH], *ret, *fullname; + unsigned int len; + + 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 ); + + HeapFree( GetProcessHeap(), 0, fullname ); + return ret; +} + +static HRESULT install_policy( const WCHAR *manifest, struct assembly *assembly ) +{ + 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); - } - hr = S_OK; - -done: - HeapFree( GetProcessHeap(), 0, sxsdir ); - HeapFree( GetProcessHeap(), 0, name ); - return hr; + return hr; + } + return S_OK; }
static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file ) @@ -449,29 +562,64 @@ 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 @@ { 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 @@ hr = S_OK;
done: - HeapFree( GetProcessHeap(), 0, sxsdir ); HeapFree( GetProcessHeap(), 0, name ); return hr; } @@ -529,43 +676,26 @@ 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 @@ done: free_assembly( assembly ); if (doc) IXMLDOMDocument_Release( doc ); - - if (SUCCEEDED(init)) - CoUninitialize(); - + if (SUCCEEDED(init)) CoUninitialize(); + cache_unlock( cache ); + return hr; +} + +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 @@
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; }
Added: trunk/reactos/dll/win32/sxs/name.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/sxs/name.c?rev=56... ============================================================================== --- trunk/reactos/dll/win32/sxs/name.c (added) +++ trunk/reactos/dll/win32/sxs/name.c [iso-8859-1] Sat May 19 14:52:48 2012 @@ -1,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; +}
Propchange: trunk/reactos/dll/win32/sxs/name.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/sxs/sxs.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/sxs/sxs.spec?rev=... ============================================================================== --- trunk/reactos/dll/win32/sxs/sxs.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/sxs/sxs.spec [iso-8859-1] Sat May 19 14:52:48 2012 @@ -1,2 +1,2 @@ @ stdcall CreateAssemblyCache(ptr long) -@ stub CreateAssemblyNameObject +@ stdcall CreateAssemblyNameObject(ptr wstr long ptr)
Added: trunk/reactos/dll/win32/sxs/sxs_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/sxs/sxs_private.h... ============================================================================== --- trunk/reactos/dll/win32/sxs/sxs_private.h (added) +++ trunk/reactos/dll/win32/sxs/sxs_private.h [iso-8859-1] Sat May 19 14:52:48 2012 @@ -1,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; +}
Propchange: trunk/reactos/dll/win32/sxs/sxs_private.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/include/psdk/winsxs.idl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winsxs.idl?rev... ============================================================================== --- trunk/reactos/include/psdk/winsxs.idl [iso-8859-1] (original) +++ trunk/reactos/include/psdk/winsxs.idl [iso-8859-1] Sat May 19 14:52:48 2012 @@ -21,6 +21,7 @@
interface IAssemblyCache; interface IAssemblyCacheItem; +interface IAssemblyName;
typedef struct _FUSION_INSTALL_REFERENCE_ { @@ -99,4 +100,99 @@ 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);")
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=5... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sat May 19 14:52:48 2012 @@ -161,7 +161,7 @@ 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