[3/6] sxs: Add some helper functions.

Hans Leidekker hans at codeweavers.com
Mon Apr 30 02:34:30 CDT 2012


---
 dlls/sxs/cache.c |  308 +++++++++++++++++++++++++++++++-----------------------
 1 file changed, 177 insertions(+), 131 deletions(-)

diff --git a/dlls/sxs/cache.c b/dlls/sxs/cache.c
index 02cf455..f39c2fd 100644
--- a/dlls/sxs/cache.c
+++ b/dlls/sxs/cache.c
@@ -38,6 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(sxs);
 
 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
 {
@@ -102,51 +103,93 @@ static HRESULT WINAPI cache_UninstallAssembly(
     return E_NOTIMPL;
 }
 
-static void build_sxs_path( WCHAR *path )
+static unsigned int build_sxs_path( WCHAR *path )
 {
     static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
-    GetWindowsDirectoryW( path, MAX_PATH );
-    strcatW( path, winsxsW );
+    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 )
+                                   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;
-    int len;
-
-    len = strlenW( fmtW );
-    len += strlenW( arch );
-    len += strlenW( name );
-    len += strlenW( token );
-    len += strlenW( version );
 
-    if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
-    sprintfW( ret, fmtW, arch, name, token, version );
+    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_policy_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token )
+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;
-    int len;
 
-    len = strlenW( fmtW );
-    len += strlenW( arch );
-    len += strlenW( name );
-    len += strlenW( token );
-
-    if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
-    sprintfW( ret, fmtW, arch, name, token );
+    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;
+}
+
 #define ASSEMBLYINFO_FLAG_INSTALLED 1
 
 static HRESULT WINAPI cache_QueryAssemblyInfo(
@@ -155,14 +198,10 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
     LPCWSTR assembly_name,
     ASSEMBLY_INFO *info )
 {
-    static const WCHAR fmt_assemblyW[] =
-        {'%','s','m','a','n','i','f','e','s','t','s','\\','%','s','.','m','a','n','i','f','e','s','t',0};
-    static const WCHAR fmt_policyW[] =
-        {'%','s','p','o','l','i','c','i','e','s','\\','%','s','\\','%','s','.','p','o','l','i','c','y',0};
-    LPASSEMBLYNAME name_obj;
-    unsigned int len;
+    IAssemblyName *name_obj;
     const WCHAR *arch, *name, *token, *type, *version;
-    WCHAR *p, *path = NULL, *full_path = NULL, sxsdir[MAX_PATH];
+    WCHAR *p, *path = NULL;
+    unsigned int len;
     HRESULT hr;
 
     TRACE("%p, 0x%08x, %s, %p\n", iface, flags, debugstr_w(assembly_name), info);
@@ -181,6 +220,7 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
     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)
@@ -188,38 +228,26 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
         IAssemblyName_Release( name_obj );
         return S_OK;
     }
-    hr = E_OUTOFMEMORY;
-    build_sxs_path( sxsdir );
-    len = strlenW( sxsdir );
-    if (!strcmpW( type, win32W ))
-    {
-        len += strlenW( fmt_assemblyW );
-        if (!(path = build_assembly_name( arch, name, token, version ))) goto done;
-        len += strlenW( path );
-        if (!(full_path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done;
-        sprintfW( full_path, fmt_assemblyW, sxsdir, path );
-    }
-    else if (!strcmpW( type, win32_policyW ))
-    {
-        len += strlenW( fmt_policyW );
-        if (!(path = build_policy_name( arch, name, token ))) goto done;
-        len += strlenW( path ) + strlenW( version );
-        if (!(full_path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done;
-        sprintfW( full_path, fmt_policyW, sxsdir, path, version );
-    }
+    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( full_path ) != INVALID_FILE_ATTRIBUTES) /* FIXME: better check */
+    if (GetFileAttributesW( path ) != INVALID_FILE_ATTRIBUTES) /* FIXME: better check */
     {
         info->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED;
         TRACE("assembly is installed\n");
     }
-    if ((p = strrchrW( full_path, '\\' ))) *p = 0;
-    len = strlenW( full_path ) + 1;
+    if ((p = strrchrW( path, '\\' ))) *p = 0;
+    len = strlenW( path ) + 1;
     if (info->pszCurrentAssemblyPathBuf)
     {
         if (info->cchBuf < len)
@@ -227,11 +255,10 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
             info->cchBuf = len;
             hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
         }
-        else strcpyW( info->pszCurrentAssemblyPathBuf, full_path );
+        else strcpyW( info->pszCurrentAssemblyPathBuf, path );
     }
 
 done:
-    HeapFree( GetProcessHeap(), 0, full_path );
     HeapFree( GetProcessHeap(), 0, path );
     IAssemblyName_Release( name_obj );
     return hr;
@@ -456,50 +483,56 @@ done:
     return hr;
 }
 
-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[MAX_PATH], *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 */
 
-    build_sxs_path( sxsdir );
-    name = build_policy_name( assembly->arch, assembly->name, assembly->token );
-    if (!name) 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, name );
-    return hr;
+    return S_OK;
 }
 
 static WCHAR *build_source_filename( const WCHAR *manifest, struct file *file )
@@ -521,30 +554,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[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;
-
-    build_sxs_path( sxsdir );
-    name = build_assembly_name( assembly->arch, assembly->name, assembly->token, assembly->version );
-    if (!name) 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 );
@@ -552,22 +619,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 );
@@ -604,9 +671,6 @@ static HRESULT WINAPI cache_InstallAssembly(
     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);
 
@@ -616,23 +680,8 @@ static HRESULT WINAPI cache_InstallAssembly(
     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 */
 
@@ -644,10 +693,7 @@ static HRESULT WINAPI cache_InstallAssembly(
 done:
     free_assembly( assembly );
     if (doc) IXMLDOMDocument_Release( doc );
-
-    if (SUCCEEDED(init))
-        CoUninitialize();
-
+    if (SUCCEEDED(init)) CoUninitialize();
     return hr;
 }
 
-- 
1.7.10







More information about the wine-patches mailing list