sxs: Add support for installing policy files.
Hans Leidekker
hans at codeweavers.com
Fri Dec 10 05:53:50 CST 2010
Fixes http://bugs.winehq.org/show_bug.cgi?id=25468
---
dlls/sxs/cache.c | 150 ++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 112 insertions(+), 38 deletions(-)
diff --git a/dlls/sxs/cache.c b/dlls/sxs/cache.c
index cd5f26c..46ca785 100644
--- a/dlls/sxs/cache.c
+++ b/dlls/sxs/cache.c
@@ -308,26 +308,20 @@ static HRESULT parse_assembly( IXMLDOMDocument *doc, struct assembly **assembly
hr = IXMLDOMNode_get_attributes( node, &attrs );
if (hr != S_OK) goto done;
- a->type = get_attribute_value( attrs, typeW );
- if (a->type && !strcmpW( a->type, policyW ))
- {
- FIXME("ignoring policy assembly\n");
- hr = ERROR_SXS_MANIFEST_FORMAT_ERROR;
- goto done;
- }
+ a->type = get_attribute_value( attrs, typeW );
a->name = get_attribute_value( attrs, nameW );
a->version = get_attribute_value( attrs, versionW );
a->arch = get_attribute_value( attrs, architectureW );
a->token = get_attribute_value( attrs, tokenW );
- if (!a->type || strcmpW( a->type, win32W ) || !a->name || !a->version || !a->arch || !a->token)
+ if (!a->type || (strcmpW( a->type, win32W ) && strcmpW( a->type, policyW )) ||
+ !a->name || !a->version || !a->arch || !a->token)
{
WARN("invalid win32 assembly\n");
hr = ERROR_SXS_MANIFEST_FORMAT_ERROR;
goto done;
}
-
- hr = parse_files( doc, a );
+ if (!strcmpW( a->type, win32W )) hr = parse_files( doc, a );
done:
if (attrs) IXMLDOMNamedNodeMap_Release( attrs );
@@ -338,6 +332,99 @@ done:
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 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;
+ 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 );
+
+ ret = CopyFileW( manifest, dst, FALSE );
+ HeapFree( GetProcessHeap(), 0, dst );
+ if (!ret)
+ {
+ 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;
+}
+
static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file )
{
WCHAR *src;
@@ -359,42 +446,23 @@ static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file )
static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembly )
{
- static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
static const WCHAR manifestsW[] = {'m','a','n','i','f','e','s','t','s','\\',0};
- static const WCHAR deadbeefW[] = {'n','o','n','e','_','d','e','a','d','b','e','e','f',0};
static const WCHAR suffixW[] = {'.','m','a','n','i','f','e','s','t',0};
static const WCHAR backslashW[] = {'\\',0};
- static const WCHAR fmtW[] = {'%','s','_','%','s','_','%','s','_','%','s','_','%','s',0};
- WCHAR sxsdir[MAX_PATH], *p, *name, *dst, *src;
- int len;
+ WCHAR *sxsdir, *p, *name, *dst, *src;
struct file *file;
- HRESULT hr = S_OK;
+ HRESULT hr = E_OUTOFMEMORY;
BOOL ret;
+ int len;
- GetWindowsDirectoryW( sxsdir, MAX_PATH );
- strcatW( sxsdir, winsxsW );
-
- len = strlenW( fmtW );
- len += strlenW( assembly->arch );
- len += strlenW( assembly->name );
- len += strlenW( assembly->token );
- len += strlenW( assembly->version );
- len += strlenW( deadbeefW );
-
- if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
- return E_OUTOFMEMORY;
-
- len = sprintfW( name, fmtW, assembly->arch, assembly->name, assembly->token, assembly->version, deadbeefW );
- for (p = name; *p; p++) *p = tolowerW( *p );
+ if (!(sxsdir = build_sxs_path())) return E_OUTOFMEMORY;
+ if (!(name = build_assembly_name( assembly ))) goto done;
- len += strlenW( sxsdir );
+ len = strlenW( sxsdir );
len += strlenW( manifestsW );
+ len += strlenW( name );
len += strlenW( suffixW );
- if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
- {
- HeapFree( GetProcessHeap(), 0, name );
- return E_OUTOFMEMORY;
- }
+ if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) goto done;
strcpyW( dst, sxsdir );
strcatW( dst, manifestsW );
strcatW( dst, name );
@@ -442,8 +510,10 @@ static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembl
goto done;
}
}
+ hr = S_OK;
done:
+ HeapFree( GetProcessHeap(), 0, sxsdir );
HeapFree( GetProcessHeap(), 0, name );
return hr;
}
@@ -454,6 +524,7 @@ 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};
HRESULT hr, init;
IXMLDOMDocument *doc = NULL;
struct assembly *assembly = NULL;
@@ -489,7 +560,10 @@ static HRESULT WINAPI cache_InstallAssembly(
/* FIXME: verify name attributes */
- hr = install_assembly( path, assembly );
+ if (!strcmpW( assembly->type, policyW ))
+ hr = install_policy( path, assembly );
+ else
+ hr = install_assembly( path, assembly );
done:
free_assembly( assembly );
--
1.7.1
More information about the wine-patches
mailing list