[4/6] sxs: Implement IAssemblyCache::UninstallAssembly.
Hans Leidekker
hans at codeweavers.com
Mon Apr 30 02:34:52 CDT 2012
---
dlls/sxs/cache.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 104 insertions(+), 11 deletions(-)
diff --git a/dlls/sxs/cache.c b/dlls/sxs/cache.c
index f39c2fd..e0ec0d0 100644
--- a/dlls/sxs/cache.c
+++ b/dlls/sxs/cache.c
@@ -92,17 +92,6 @@ static ULONG WINAPI cache_Release( IAssemblyCache *iface )
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};
@@ -697,6 +686,110 @@ done:
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 )
+{
+ 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;
+ }
+ 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();
+ return hr;
+}
+
static const IAssemblyCacheVtbl cache_vtbl =
{
cache_QueryInterface,
--
1.7.10
More information about the wine-patches
mailing list