2 * IAssemblyName implementation
4 * Copyright 2012 Hans Leidekker for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
34 #include <wine/debug.h>
35 #include <wine/unicode.h>
36 #include "sxs_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(sxs
);
42 IAssemblyName IAssemblyName_iface
;
51 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};
52 static const WCHAR tokenW
[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
53 static const WCHAR typeW
[] = {'t','y','p','e',0};
54 static const WCHAR versionW
[] = {'v','e','r','s','i','o','n',0};
56 static inline struct name
*impl_from_IAssemblyName( IAssemblyName
*iface
)
58 return CONTAINING_RECORD( iface
, struct name
, IAssemblyName_iface
);
61 static HRESULT WINAPI
name_QueryInterface(
66 struct name
*name
= impl_from_IAssemblyName( iface
);
68 TRACE("%p, %s, %p\n", name
, debugstr_guid(riid
), obj
);
72 if (IsEqualIID( riid
, &IID_IUnknown
) ||
73 IsEqualIID( riid
, &IID_IAssemblyName
))
75 IAssemblyName_AddRef( iface
);
83 static ULONG WINAPI
name_AddRef(
84 IAssemblyName
*iface
)
86 struct name
*name
= impl_from_IAssemblyName( iface
);
87 return InterlockedIncrement( &name
->refs
);
90 static ULONG WINAPI
name_Release( IAssemblyName
*iface
)
92 struct name
*name
= impl_from_IAssemblyName( iface
);
93 ULONG refs
= InterlockedDecrement( &name
->refs
);
97 TRACE("destroying %p\n", name
);
98 HeapFree( GetProcessHeap(), 0, name
->name
);
99 HeapFree( GetProcessHeap(), 0, name
->arch
);
100 HeapFree( GetProcessHeap(), 0, name
->token
);
101 HeapFree( GetProcessHeap(), 0, name
->type
);
102 HeapFree( GetProcessHeap(), 0, name
->version
);
103 HeapFree( GetProcessHeap(), 0, name
);
108 static HRESULT WINAPI
name_SetProperty(
109 IAssemblyName
*iface
,
114 FIXME("%p, %d, %p, %d\n", iface
, id
, property
, size
);
118 static HRESULT WINAPI
name_GetProperty(
119 IAssemblyName
*iface
,
124 FIXME("%p, %d, %p, %p\n", iface
, id
, buffer
, buflen
);
128 static HRESULT WINAPI
name_Finalize(
129 IAssemblyName
*iface
)
131 FIXME("%p\n", iface
);
135 static HRESULT WINAPI
name_GetDisplayName(
136 IAssemblyName
*iface
,
141 static const WCHAR fmtW
[] = {',','%','s','=','\"','%','s','\"',0};
142 struct name
*name
= impl_from_IAssemblyName( iface
);
146 TRACE("%p, %p, %p, 0x%08x\n", iface
, buffer
, buflen
, flags
);
148 if (!buflen
|| flags
) return E_INVALIDARG
;
150 len
= strlenW( name
->name
) + 1;
151 if (name
->arch
) len
+= strlenW( archW
) + strlenW( name
->arch
) + 4;
152 if (name
->token
) len
+= strlenW( tokenW
) + strlenW( name
->token
) + 4;
153 if (name
->type
) len
+= strlenW( typeW
) + strlenW( name
->type
) + 4;
154 if (name
->version
) len
+= strlenW( versionW
) + strlenW( version
) + 4;
158 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER
);
160 strcpyW( buffer
, name
->name
);
161 len
= strlenW( buffer
);
162 if (name
->arch
) len
+= sprintfW( buffer
+ len
, fmtW
, archW
, name
->arch
);
163 if (name
->token
) len
+= sprintfW( buffer
+ len
, fmtW
, tokenW
, name
->token
);
164 if (name
->type
) len
+= sprintfW( buffer
+ len
, fmtW
, typeW
, name
->type
);
165 if (name
->version
) len
+= sprintfW( buffer
+ len
, fmtW
, versionW
, name
->version
);
169 static HRESULT WINAPI
name_Reserved(
170 IAssemblyName
*iface
,
172 IUnknown
*pUnkReserved1
,
173 IUnknown
*pUnkReserved2
,
174 LPCOLESTR szReserved
,
180 FIXME("%p, %s, %p, %p, %s, %x%08x, %p, %d, %p\n", iface
,
181 debugstr_guid(riid
), pUnkReserved1
, pUnkReserved2
,
182 debugstr_w(szReserved
), (DWORD
)(llReserved
>> 32), (DWORD
)llReserved
,
183 pvReserved
, cbReserved
, ppReserved
);
187 const WCHAR
*get_name_attribute( IAssemblyName
*iface
, enum name_attr_id id
)
189 struct name
*name
= impl_from_IAssemblyName( iface
);
193 case NAME_ATTR_ID_NAME
: return name
->name
;
194 case NAME_ATTR_ID_ARCH
: return name
->arch
;
195 case NAME_ATTR_ID_TOKEN
: return name
->token
;
196 case NAME_ATTR_ID_TYPE
: return name
->type
;
197 case NAME_ATTR_ID_VERSION
: return name
->version
;
199 ERR("unhandled name attribute %u\n", id
);
205 static HRESULT WINAPI
name_GetName(
206 IAssemblyName
*iface
,
213 TRACE("%p, %p, %p\n", iface
, buflen
, buffer
);
215 if (!buflen
|| !buffer
) return E_INVALIDARG
;
217 name
= get_name_attribute( iface
, NAME_ATTR_ID_NAME
);
218 len
= strlenW( name
) + 1;
222 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER
);
224 strcpyW( buffer
, name
);
229 static HRESULT
parse_version( WCHAR
*version
, DWORD
*high
, DWORD
*low
)
235 memset( ver
, 0, sizeof(ver
) );
236 for (i
= 0, p
= version
; i
< 4; i
++)
239 q
= strchrW( p
, '.' );
242 if (!q
&& i
< 3) break;
245 *high
= (ver
[0] << 16) + ver
[1];
246 *low
= (ver
[2] << 16) + ver
[3];
250 static HRESULT WINAPI
name_GetVersion(
251 IAssemblyName
*iface
,
255 struct name
*name
= impl_from_IAssemblyName( iface
);
259 TRACE("%p, %p, %p\n", iface
, high
, low
);
261 if (!name
->version
) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND
);
262 if (!(version
= strdupW( name
->version
))) return E_OUTOFMEMORY
;
263 hr
= parse_version( version
, high
, low
);
264 HeapFree( GetProcessHeap(), 0, version
);
268 static HRESULT WINAPI
name_IsEqual(
269 IAssemblyName
*name1
,
270 IAssemblyName
*name2
,
273 FIXME("%p, %p, 0x%08x\n", name1
, name2
, flags
);
277 static HRESULT WINAPI
name_Clone(
278 IAssemblyName
*iface
,
279 IAssemblyName
**name
)
281 FIXME("%p, %p\n", iface
, name
);
285 static const IAssemblyNameVtbl name_vtbl
=
301 static WCHAR
*parse_value( const WCHAR
*str
, unsigned int *len
)
304 const WCHAR
*p
= str
;
306 if (*p
++ != '\"') return NULL
;
307 while (*p
&& *p
!= '\"') p
++;
308 if (!*p
) return NULL
;
311 if (!(ret
= HeapAlloc( GetProcessHeap(), 0, *len
* sizeof(WCHAR
) ))) return NULL
;
312 memcpy( ret
, str
+ 1, (*len
- 1) * sizeof(WCHAR
) );
317 static HRESULT
parse_displayname( struct name
*name
, const WCHAR
*displayname
)
323 while (*q
&& *q
!= ',') q
++;
325 if (!(name
->name
= HeapAlloc( GetProcessHeap(), 0, (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
326 memcpy( name
->name
, p
, len
* sizeof(WCHAR
) );
328 if (!*q
) return S_OK
;
333 while (*q
&& *q
!= '=') q
++;
334 if (!*q
) return E_INVALIDARG
;
336 if (len
== sizeof(archW
)/sizeof(archW
[0]) - 1 && !memcmp( p
, archW
, len
* sizeof(WCHAR
) ))
339 if (!(name
->arch
= parse_value( p
, &len
))) return E_INVALIDARG
;
342 else if (len
== sizeof(tokenW
)/sizeof(tokenW
[0]) - 1 && !memcmp( p
, tokenW
, len
* sizeof(WCHAR
) ))
345 if (!(name
->token
= parse_value( p
, &len
))) return E_INVALIDARG
;
348 else if (len
== sizeof(typeW
)/sizeof(typeW
[0]) - 1 && !memcmp( p
, typeW
, len
* sizeof(WCHAR
) ))
351 if (!(name
->type
= parse_value( p
, &len
))) return E_INVALIDARG
;
354 else if (len
== sizeof(versionW
)/sizeof(versionW
[0]) - 1 && !memcmp( p
, versionW
, len
* sizeof(WCHAR
) ))
357 if (!(name
->version
= parse_value( p
, &len
))) return E_INVALIDARG
;
360 else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME
);
361 while (*q
&& *q
!= ',') q
++;
367 /******************************************************************
368 * CreateAssemblyNameObject (SXS.@)
370 HRESULT WINAPI
CreateAssemblyNameObject(
379 TRACE("%p, %s, 0x%08x, %p\n", obj
, debugstr_w(assembly
), flags
, reserved
);
381 if (!obj
) return E_INVALIDARG
;
384 if (!assembly
|| !assembly
[0] || flags
!= CANOF_PARSE_DISPLAY_NAME
)
387 if (!(name
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*name
) )))
388 return E_OUTOFMEMORY
;
390 name
->IAssemblyName_iface
.lpVtbl
= &name_vtbl
;
393 hr
= parse_displayname( name
, assembly
);
396 HeapFree( GetProcessHeap(), 0, name
->name
);
397 HeapFree( GetProcessHeap(), 0, name
->arch
);
398 HeapFree( GetProcessHeap(), 0, name
->token
);
399 HeapFree( GetProcessHeap(), 0, name
->type
);
400 HeapFree( GetProcessHeap(), 0, name
->version
);
401 HeapFree( GetProcessHeap(), 0, name
);
404 *obj
= &name
->IAssemblyName_iface
;