[1/2] sxs: Parse the display name in CreateAssemblyNameObject. (try 2)

Hans Leidekker hans at codeweavers.com
Fri Mar 16 10:12:56 CDT 2012


---
 dlls/sxs/name.c        |  196 ++++++++++++++++++++++++++++++++++++++++++++++--
 dlls/sxs/sxs_private.h |   38 +++++++++
 2 files changed, 227 insertions(+), 7 deletions(-)
 create mode 100644 dlls/sxs/sxs_private.h

diff --git a/dlls/sxs/name.c b/dlls/sxs/name.c
index 1adeebd..9ca911b 100644
--- a/dlls/sxs/name.c
+++ b/dlls/sxs/name.c
@@ -28,6 +28,8 @@
 #include "winsxs.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
+#include "sxs_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(sxs);
 
@@ -35,8 +37,18 @@ 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 );
@@ -79,6 +91,11 @@ static ULONG WINAPI name_Release( IAssemblyName *iface )
     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;
@@ -117,8 +134,32 @@ static HRESULT WINAPI name_GetDisplayName(
     LPDWORD buflen,
     DWORD flags )
 {
-    FIXME("%p, %p, %p, 0x%08x\n", iface, buffer, buflen, flags);
-    return E_NOTIMPL;
+    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(
@@ -139,22 +180,85 @@ static HRESULT WINAPI name_Reserved(
     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 )
 {
-    FIXME("%p, %p, %p\n", iface, buflen, buffer);
-    return E_NOTIMPL;
+    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 hi,
+    LPDWORD high,
     LPDWORD low )
 {
-    FIXME("%p, %p, %p\n", iface, hi, low);
-    return E_NOTIMPL;
+    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(
@@ -190,6 +294,72 @@ static const IAssemblyNameVtbl name_vtbl =
     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.@)
  */
@@ -200,6 +370,7 @@ HRESULT WINAPI CreateAssemblyNameObject(
     LPVOID reserved )
 {
     struct name *name;
+    HRESULT hr;
 
     TRACE("%p, %s, 0x%08x, %p\n", obj, debugstr_w(assembly), flags, reserved);
 
@@ -215,6 +386,17 @@ HRESULT WINAPI CreateAssemblyNameObject(
     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;
 }
diff --git a/dlls/sxs/sxs_private.h b/dlls/sxs/sxs_private.h
new file mode 100644
index 0000000..8ff9920
--- /dev/null
+++ b/dlls/sxs/sxs_private.h
@@ -0,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;
+}
-- 
1.7.9.1







More information about the wine-patches mailing list