reg: Do not allow duplicate /d or /t switches.
[wine.git] / dlls / sxs / name.c
blobbb7f094169f436bcd4ed207d1506614efb8617b0
1 /*
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 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "winsxs.h"
30 #include "wine/debug.h"
31 #include "wine/unicode.h"
32 #include "sxs_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(sxs);
36 struct name
38 IAssemblyName IAssemblyName_iface;
39 LONG refs;
40 WCHAR *name;
41 WCHAR *arch;
42 WCHAR *token;
43 WCHAR *type;
44 WCHAR *version;
47 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};
48 static const WCHAR tokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
49 static const WCHAR typeW[] = {'t','y','p','e',0};
50 static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
52 static inline struct name *impl_from_IAssemblyName( IAssemblyName *iface )
54 return CONTAINING_RECORD( iface, struct name, IAssemblyName_iface );
57 static HRESULT WINAPI name_QueryInterface(
58 IAssemblyName *iface,
59 REFIID riid,
60 void **obj )
62 struct name *name = impl_from_IAssemblyName( iface );
64 TRACE("%p, %s, %p\n", name, debugstr_guid(riid), obj);
66 *obj = NULL;
68 if (IsEqualIID( riid, &IID_IUnknown ) ||
69 IsEqualIID( riid, &IID_IAssemblyName ))
71 IAssemblyName_AddRef( iface );
72 *obj = name;
73 return S_OK;
76 return E_NOINTERFACE;
79 static ULONG WINAPI name_AddRef(
80 IAssemblyName *iface )
82 struct name *name = impl_from_IAssemblyName( iface );
83 return InterlockedIncrement( &name->refs );
86 static ULONG WINAPI name_Release( IAssemblyName *iface )
88 struct name *name = impl_from_IAssemblyName( iface );
89 ULONG refs = InterlockedDecrement( &name->refs );
91 if (!refs)
93 TRACE("destroying %p\n", name);
94 HeapFree( GetProcessHeap(), 0, name->name );
95 HeapFree( GetProcessHeap(), 0, name->arch );
96 HeapFree( GetProcessHeap(), 0, name->token );
97 HeapFree( GetProcessHeap(), 0, name->type );
98 HeapFree( GetProcessHeap(), 0, name->version );
99 HeapFree( GetProcessHeap(), 0, name );
101 return refs;
104 static HRESULT WINAPI name_SetProperty(
105 IAssemblyName *iface,
106 DWORD id,
107 LPVOID property,
108 DWORD size )
110 FIXME("%p, %d, %p, %d\n", iface, id, property, size);
111 return E_NOTIMPL;
114 static HRESULT WINAPI name_GetProperty(
115 IAssemblyName *iface,
116 DWORD id,
117 LPVOID buffer,
118 LPDWORD buflen )
120 FIXME("%p, %d, %p, %p\n", iface, id, buffer, buflen);
121 return E_NOTIMPL;
124 static HRESULT WINAPI name_Finalize(
125 IAssemblyName *iface )
127 FIXME("%p\n", iface);
128 return E_NOTIMPL;
131 static HRESULT WINAPI name_GetDisplayName(
132 IAssemblyName *iface,
133 LPOLESTR buffer,
134 LPDWORD buflen,
135 DWORD flags )
137 static const WCHAR fmtW[] = {',','%','s','=','\"','%','s','\"',0};
138 struct name *name = impl_from_IAssemblyName( iface );
139 WCHAR version[30];
140 unsigned int len;
142 TRACE("%p, %p, %p, 0x%08x\n", iface, buffer, buflen, flags);
144 if (!buflen || flags) return E_INVALIDARG;
146 len = strlenW( name->name ) + 1;
147 if (name->arch) len += strlenW( archW ) + strlenW( name->arch ) + 4;
148 if (name->token) len += strlenW( tokenW ) + strlenW( name->token ) + 4;
149 if (name->type) len += strlenW( typeW ) + strlenW( name->type ) + 4;
150 if (name->version) len += strlenW( versionW ) + strlenW( version ) + 4;
151 if (len > *buflen)
153 *buflen = len;
154 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
156 strcpyW( buffer, name->name );
157 len = strlenW( buffer );
158 if (name->arch) len += sprintfW( buffer + len, fmtW, archW, name->arch );
159 if (name->token) len += sprintfW( buffer + len, fmtW, tokenW, name->token );
160 if (name->type) len += sprintfW( buffer + len, fmtW, typeW, name->type );
161 if (name->version) len += sprintfW( buffer + len, fmtW, versionW, name->version );
162 return S_OK;
165 static HRESULT WINAPI name_Reserved(
166 IAssemblyName *iface,
167 REFIID riid,
168 IUnknown *pUnkReserved1,
169 IUnknown *pUnkReserved2,
170 LPCOLESTR szReserved,
171 LONGLONG llReserved,
172 LPVOID pvReserved,
173 DWORD cbReserved,
174 LPVOID *ppReserved )
176 FIXME("%p, %s, %p, %p, %s, %x%08x, %p, %d, %p\n", iface,
177 debugstr_guid(riid), pUnkReserved1, pUnkReserved2,
178 debugstr_w(szReserved), (DWORD)(llReserved >> 32), (DWORD)llReserved,
179 pvReserved, cbReserved, ppReserved);
180 return E_NOTIMPL;
183 const WCHAR *get_name_attribute( IAssemblyName *iface, enum name_attr_id id )
185 struct name *name = impl_from_IAssemblyName( iface );
187 switch (id)
189 case NAME_ATTR_ID_NAME: return name->name;
190 case NAME_ATTR_ID_ARCH: return name->arch;
191 case NAME_ATTR_ID_TOKEN: return name->token;
192 case NAME_ATTR_ID_TYPE: return name->type;
193 case NAME_ATTR_ID_VERSION: return name->version;
194 default:
195 ERR("unhandled name attribute %u\n", id);
196 break;
198 return NULL;
201 static HRESULT WINAPI name_GetName(
202 IAssemblyName *iface,
203 LPDWORD buflen,
204 WCHAR *buffer )
206 const WCHAR *name;
207 int len;
209 TRACE("%p, %p, %p\n", iface, buflen, buffer);
211 if (!buflen || !buffer) return E_INVALIDARG;
213 name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
214 len = strlenW( name ) + 1;
215 if (len > *buflen)
217 *buflen = len;
218 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
220 strcpyW( buffer, name );
221 *buflen = len + 3;
222 return S_OK;
225 static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low )
227 WORD ver[4];
228 WCHAR *p, *q;
229 unsigned int i;
231 memset( ver, 0, sizeof(ver) );
232 for (i = 0, p = version; i < 4; i++)
234 if (!*p) break;
235 q = strchrW( p, '.' );
236 if (q) *q = 0;
237 ver[i] = atolW( p );
238 if (!q && i < 3) break;
239 p = q + 1;
241 *high = (ver[0] << 16) + ver[1];
242 *low = (ver[2] << 16) + ver[3];
243 return S_OK;
246 static HRESULT WINAPI name_GetVersion(
247 IAssemblyName *iface,
248 LPDWORD high,
249 LPDWORD low )
251 struct name *name = impl_from_IAssemblyName( iface );
252 WCHAR *version;
253 HRESULT hr;
255 TRACE("%p, %p, %p\n", iface, high, low);
257 if (!name->version) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
258 if (!(version = strdupW( name->version ))) return E_OUTOFMEMORY;
259 hr = parse_version( version, high, low );
260 HeapFree( GetProcessHeap(), 0, version );
261 return hr;
264 static HRESULT WINAPI name_IsEqual(
265 IAssemblyName *name1,
266 IAssemblyName *name2,
267 DWORD flags )
269 FIXME("%p, %p, 0x%08x\n", name1, name2, flags);
270 return E_NOTIMPL;
273 static HRESULT WINAPI name_Clone(
274 IAssemblyName *iface,
275 IAssemblyName **name )
277 FIXME("%p, %p\n", iface, name);
278 return E_NOTIMPL;
281 static const IAssemblyNameVtbl name_vtbl =
283 name_QueryInterface,
284 name_AddRef,
285 name_Release,
286 name_SetProperty,
287 name_GetProperty,
288 name_Finalize,
289 name_GetDisplayName,
290 name_Reserved,
291 name_GetName,
292 name_GetVersion,
293 name_IsEqual,
294 name_Clone
297 static WCHAR *parse_value( const WCHAR *str, unsigned int *len )
299 WCHAR *ret;
300 const WCHAR *p = str;
302 if (*p++ != '\"') return NULL;
303 while (*p && *p != '\"') p++;
304 if (!*p) return NULL;
306 *len = p - str;
307 if (!(ret = HeapAlloc( GetProcessHeap(), 0, *len * sizeof(WCHAR) ))) return NULL;
308 memcpy( ret, str + 1, (*len - 1) * sizeof(WCHAR) );
309 ret[*len - 1] = 0;
310 return ret;
313 static HRESULT parse_displayname( struct name *name, const WCHAR *displayname )
315 const WCHAR *p, *q;
316 unsigned int len;
318 p = q = displayname;
319 while (*q && *q != ',') q++;
320 len = q - p;
321 if (!(name->name = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
322 memcpy( name->name, p, len * sizeof(WCHAR) );
323 name->name[len] = 0;
324 if (!*q) return S_OK;
326 for (;;)
328 p = ++q;
329 while (*q && *q != '=') q++;
330 if (!*q) return E_INVALIDARG;
331 len = q - p;
332 if (len == sizeof(archW)/sizeof(archW[0]) - 1 && !memcmp( p, archW, len * sizeof(WCHAR) ))
334 p = ++q;
335 if (!(name->arch = parse_value( p, &len ))) return E_INVALIDARG;
336 q += len;
338 else if (len == sizeof(tokenW)/sizeof(tokenW[0]) - 1 && !memcmp( p, tokenW, len * sizeof(WCHAR) ))
340 p = ++q;
341 if (!(name->token = parse_value( p, &len ))) return E_INVALIDARG;
342 q += len;
344 else if (len == sizeof(typeW)/sizeof(typeW[0]) - 1 && !memcmp( p, typeW, len * sizeof(WCHAR) ))
346 p = ++q;
347 if (!(name->type = parse_value( p, &len ))) return E_INVALIDARG;
348 q += len;
350 else if (len == sizeof(versionW)/sizeof(versionW[0]) - 1 && !memcmp( p, versionW, len * sizeof(WCHAR) ))
352 p = ++q;
353 if (!(name->version = parse_value( p, &len ))) return E_INVALIDARG;
354 q += len;
356 else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME );
357 while (*q && *q != ',') q++;
358 if (!*q) break;
360 return S_OK;
363 /******************************************************************
364 * CreateAssemblyNameObject (SXS.@)
366 HRESULT WINAPI CreateAssemblyNameObject(
367 LPASSEMBLYNAME *obj,
368 LPCWSTR assembly,
369 DWORD flags,
370 LPVOID reserved )
372 struct name *name;
373 HRESULT hr;
375 TRACE("%p, %s, 0x%08x, %p\n", obj, debugstr_w(assembly), flags, reserved);
377 if (!obj) return E_INVALIDARG;
379 *obj = NULL;
380 if (!assembly || !assembly[0] || flags != CANOF_PARSE_DISPLAY_NAME)
381 return E_INVALIDARG;
383 if (!(name = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*name) )))
384 return E_OUTOFMEMORY;
386 name->IAssemblyName_iface.lpVtbl = &name_vtbl;
387 name->refs = 1;
389 hr = parse_displayname( name, assembly );
390 if (hr != S_OK)
392 HeapFree( GetProcessHeap(), 0, name->name );
393 HeapFree( GetProcessHeap(), 0, name->arch );
394 HeapFree( GetProcessHeap(), 0, name->token );
395 HeapFree( GetProcessHeap(), 0, name->type );
396 HeapFree( GetProcessHeap(), 0, name->version );
397 HeapFree( GetProcessHeap(), 0, name );
398 return hr;
400 *obj = &name->IAssemblyName_iface;
401 return S_OK;