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
30 #include "wine/debug.h"
31 #include "sxs_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(sxs
);
37 IAssemblyName IAssemblyName_iface
;
46 static inline struct name
*impl_from_IAssemblyName( IAssemblyName
*iface
)
48 return CONTAINING_RECORD( iface
, struct name
, IAssemblyName_iface
);
51 static HRESULT WINAPI
name_QueryInterface(
56 TRACE("%p, %s, %p\n", iface
, debugstr_guid(riid
), ret_iface
);
60 if (IsEqualIID( riid
, &IID_IUnknown
) ||
61 IsEqualIID( riid
, &IID_IAssemblyName
))
63 IAssemblyName_AddRef( iface
);
71 static ULONG WINAPI
name_AddRef(
72 IAssemblyName
*iface
)
74 struct name
*name
= impl_from_IAssemblyName( iface
);
75 return InterlockedIncrement( &name
->refs
);
78 static ULONG WINAPI
name_Release( IAssemblyName
*iface
)
80 struct name
*name
= impl_from_IAssemblyName( iface
);
81 ULONG refs
= InterlockedDecrement( &name
->refs
);
85 TRACE("destroying %p\n", name
);
90 free( name
->version
);
96 static HRESULT WINAPI
name_SetProperty(
102 FIXME("%p, %ld, %p, %ld\n", iface
, id
, property
, size
);
106 static HRESULT WINAPI
name_GetProperty(
107 IAssemblyName
*iface
,
112 FIXME("%p, %ld, %p, %p\n", iface
, id
, buffer
, buflen
);
116 static HRESULT WINAPI
name_Finalize(
117 IAssemblyName
*iface
)
119 FIXME("%p\n", iface
);
123 static HRESULT WINAPI
name_GetDisplayName(
124 IAssemblyName
*iface
,
129 static const WCHAR fmtW
[] = {',','%','s','=','\"','%','s','\"',0};
130 struct name
*name
= impl_from_IAssemblyName( iface
);
133 TRACE("%p, %p, %p, 0x%08lx\n", iface
, buffer
, buflen
, flags
);
135 if (!buflen
|| flags
) return E_INVALIDARG
;
137 len
= lstrlenW( name
->name
) + 1;
138 if (name
->arch
) len
+= lstrlenW( L
"processorArchitecture" ) + lstrlenW( name
->arch
) + 4;
139 if (name
->token
) len
+= lstrlenW( L
"publicKeyToken" ) + lstrlenW( name
->token
) + 4;
140 if (name
->type
) len
+= lstrlenW( L
"type" ) + lstrlenW( name
->type
) + 4;
141 if (name
->version
) len
+= lstrlenW( L
"version" ) + lstrlenW( name
->version
) + 4;
145 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER
);
147 lstrcpyW( buffer
, name
->name
);
148 len
= lstrlenW( buffer
);
149 if (name
->arch
) len
+= swprintf( buffer
+ len
, *buflen
- len
, fmtW
, L
"processorArchitecture", name
->arch
);
150 if (name
->token
) len
+= swprintf( buffer
+ len
, *buflen
- len
, fmtW
, L
"publicKeyToken", name
->token
);
151 if (name
->type
) len
+= swprintf( buffer
+ len
, *buflen
- len
, fmtW
, L
"type", name
->type
);
152 if (name
->version
) len
+= swprintf( buffer
+ len
, *buflen
- len
, fmtW
, L
"version", name
->version
);
156 static HRESULT WINAPI
name_Reserved(
157 IAssemblyName
*iface
,
159 IUnknown
*pUnkReserved1
,
160 IUnknown
*pUnkReserved2
,
161 LPCOLESTR szReserved
,
167 FIXME("%p, %s, %p, %p, %s, %s, %p, %ld, %p\n", iface
,
168 debugstr_guid(riid
), pUnkReserved1
, pUnkReserved2
,
169 debugstr_w(szReserved
), wine_dbgstr_longlong(llReserved
),
170 pvReserved
, cbReserved
, ppReserved
);
174 const WCHAR
*get_name_attribute( IAssemblyName
*iface
, enum name_attr_id id
)
176 struct name
*name
= impl_from_IAssemblyName( iface
);
180 case NAME_ATTR_ID_NAME
: return name
->name
;
181 case NAME_ATTR_ID_ARCH
: return name
->arch
;
182 case NAME_ATTR_ID_TOKEN
: return name
->token
;
183 case NAME_ATTR_ID_TYPE
: return name
->type
;
184 case NAME_ATTR_ID_VERSION
: return name
->version
;
186 ERR("unhandled name attribute %u\n", id
);
192 static HRESULT WINAPI
name_GetName(
193 IAssemblyName
*iface
,
200 TRACE("%p, %p, %p\n", iface
, buflen
, buffer
);
202 if (!buflen
|| !buffer
) return E_INVALIDARG
;
204 name
= get_name_attribute( iface
, NAME_ATTR_ID_NAME
);
205 len
= lstrlenW( name
) + 1;
209 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER
);
211 lstrcpyW( buffer
, name
);
216 static HRESULT
parse_version( WCHAR
*version
, DWORD
*high
, DWORD
*low
)
222 memset( ver
, 0, sizeof(ver
) );
223 for (i
= 0, p
= version
; i
< 4; i
++)
226 q
= wcschr( p
, '.' );
228 ver
[i
] = wcstol( p
, NULL
, 10 );
229 if (!q
&& i
< 3) break;
232 *high
= (ver
[0] << 16) + ver
[1];
233 *low
= (ver
[2] << 16) + ver
[3];
237 static HRESULT WINAPI
name_GetVersion(
238 IAssemblyName
*iface
,
242 struct name
*name
= impl_from_IAssemblyName( iface
);
246 TRACE("%p, %p, %p\n", iface
, high
, low
);
248 if (!name
->version
) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND
);
249 if (!(version
= wcsdup( name
->version
))) return E_OUTOFMEMORY
;
250 hr
= parse_version( version
, high
, low
);
255 static HRESULT WINAPI
name_IsEqual(
256 IAssemblyName
*name1
,
257 IAssemblyName
*name2
,
260 FIXME("%p, %p, 0x%08lx\n", name1
, name2
, flags
);
264 static HRESULT WINAPI
name_Clone(
265 IAssemblyName
*iface
,
266 IAssemblyName
**name
)
268 FIXME("%p, %p\n", iface
, name
);
272 static const IAssemblyNameVtbl name_vtbl
=
288 static WCHAR
*parse_value( const WCHAR
*str
, unsigned int *len
)
291 const WCHAR
*p
= str
;
293 if (*p
++ != '\"') return NULL
;
294 while (*p
&& *p
!= '\"') p
++;
295 if (!*p
) return NULL
;
298 if (!(ret
= malloc( *len
* sizeof(WCHAR
) ))) return NULL
;
299 memcpy( ret
, str
+ 1, (*len
- 1) * sizeof(WCHAR
) );
304 static HRESULT
parse_displayname( struct name
*name
, const WCHAR
*displayname
)
310 while (*q
&& *q
!= ',') q
++;
312 if (!(name
->name
= malloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
313 memcpy( name
->name
, p
, len
* sizeof(WCHAR
) );
315 if (!*q
) return S_OK
;
320 while (*q
&& *q
!= '=') q
++;
321 if (!*q
) return E_INVALIDARG
;
323 if (len
== ARRAY_SIZE(L
"processorArchitecture") - 1 && !memcmp( p
, L
"processorArchitecture", len
* sizeof(WCHAR
) ))
326 if (!(name
->arch
= parse_value( p
, &len
))) return E_INVALIDARG
;
329 else if (len
== ARRAY_SIZE(L
"publicKeyToken") - 1 && !memcmp( p
, L
"publicKeyToken", len
* sizeof(WCHAR
) ))
332 if (!(name
->token
= parse_value( p
, &len
))) return E_INVALIDARG
;
335 else if (len
== ARRAY_SIZE(L
"type") - 1 && !memcmp( p
, L
"type", len
* sizeof(WCHAR
) ))
338 if (!(name
->type
= parse_value( p
, &len
))) return E_INVALIDARG
;
341 else if (len
== ARRAY_SIZE(L
"version") - 1 && !memcmp( p
, L
"version", len
* sizeof(WCHAR
) ))
344 if (!(name
->version
= parse_value( p
, &len
))) return E_INVALIDARG
;
347 else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME
);
348 while (*q
&& *q
!= ',') q
++;
354 /******************************************************************
355 * CreateAssemblyNameObject (SXS.@)
357 HRESULT WINAPI
CreateAssemblyNameObject(
366 TRACE("%p, %s, 0x%08lx, %p\n", obj
, debugstr_w(assembly
), flags
, reserved
);
368 if (!obj
) return E_INVALIDARG
;
371 if (!assembly
|| !assembly
[0] || flags
!= CANOF_PARSE_DISPLAY_NAME
)
374 if (!(name
= calloc(1, sizeof(*name
) )))
375 return E_OUTOFMEMORY
;
377 name
->IAssemblyName_iface
.lpVtbl
= &name_vtbl
;
380 hr
= parse_displayname( name
, assembly
);
387 free( name
->version
);
391 *obj
= &name
->IAssemblyName_iface
;