[1/4] sxs: Implement IAssemblyCache::QueryAssemblyInfo.

Hans Leidekker hans at codeweavers.com
Fri Mar 30 03:21:11 CDT 2012


---
 dlls/sxs/cache.c |  211 ++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 141 insertions(+), 70 deletions(-)

diff --git a/dlls/sxs/cache.c b/dlls/sxs/cache.c
index af19e60..02cf455 100644
--- a/dlls/sxs/cache.c
+++ b/dlls/sxs/cache.c
@@ -32,16 +32,12 @@
 #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 win32W[] = {'w','i','n','3','2',0};
+static const WCHAR win32_policyW[] = {'w','i','n','3','2','-','p','o','l','i','c','y',0};
 
 struct cache
 {
@@ -106,14 +102,139 @@ static HRESULT WINAPI cache_UninstallAssembly(
     return E_NOTIMPL;
 }
 
+static void build_sxs_path( WCHAR *path )
+{
+    static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0};
+    GetWindowsDirectoryW( path, MAX_PATH );
+    strcatW( path, winsxsW );
+}
+
+static WCHAR *build_assembly_name( const WCHAR *arch, const WCHAR *name, const WCHAR *token,
+                                   const WCHAR *version )
+{
+    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( 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 );
+    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 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( arch );
+    len += strlenW( name );
+    len += strlenW( token );
+
+    if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
+    sprintfW( ret, fmtW, arch, name, token );
+    for (p = ret; *p; p++) *p = tolowerW( *p );
+    return ret;
+}
+
+#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;
+    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;
+    const WCHAR *arch, *name, *token, *type, *version;
+    WCHAR *p, *path = NULL, *full_path = NULL, sxsdir[MAX_PATH];
+    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)
+    {
+        return HRESULT_FROM_WIN32( ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE );
+    }
+    if (!info)
+    {
+        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 );
+    }
+    else
+    {
+        hr = HRESULT_FROM_WIN32( ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE );
+        goto done;
+    }
+    hr = S_OK;
+    if (GetFileAttributesW( full_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 (info->pszCurrentAssemblyPathBuf)
+    {
+        if (info->cchBuf < len)
+        {
+            info->cchBuf = len;
+            hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
+        }
+        else strcpyW( info->pszCurrentAssemblyPathBuf, full_path );
+    }
+
+done:
+    HeapFree( GetProcessHeap(), 0, full_path );
+    HeapFree( GetProcessHeap(), 0, path );
+    IAssemblyName_Release( name_obj );
+    return hr;
 }
 
 static HRESULT WINAPI cache_CreateAssemblyCacheItem(
@@ -274,8 +395,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 +438,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,67 +456,21 @@ 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;
+    WCHAR sxsdir[MAX_PATH], *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;
+    build_sxs_path( sxsdir );
+    name = build_policy_name( assembly->arch, assembly->name, assembly->token );
+    if (!name) goto done;
 
     len = strlenW( sxsdir );
     len += strlenW( policiesW );
@@ -425,7 +498,6 @@ static HRESULT install_policy( const WCHAR *manifest, struct assembly *assembly
     hr = S_OK;
 
 done:
-    HeapFree( GetProcessHeap(), 0, sxsdir );
     HeapFree( GetProcessHeap(), 0, name );
     return hr;
 }
@@ -454,14 +526,15 @@ static HRESULT install_assembly( const WCHAR *manifest, struct assembly *assembl
     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], *p, *name, *dst, *src;
     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;
+    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 );
@@ -518,7 +591,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,7 +601,6 @@ 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;
@@ -565,7 +636,7 @@ static HRESULT WINAPI cache_InstallAssembly(
 
     /* 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 );
-- 
1.7.5.4







More information about the wine-patches mailing list