ole32: Use wide-char string literals.
[wine.git] / dlls / sxs / name.c
blob6b3ae5197ac836735573a11021534cd34a6137bc
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 "sxs_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(sxs);
35 struct name
37 IAssemblyName IAssemblyName_iface;
38 LONG refs;
39 WCHAR *name;
40 WCHAR *arch;
41 WCHAR *token;
42 WCHAR *type;
43 WCHAR *version;
46 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};
47 static const WCHAR tokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
48 static const WCHAR typeW[] = {'t','y','p','e',0};
49 static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
51 static inline struct name *impl_from_IAssemblyName( IAssemblyName *iface )
53 return CONTAINING_RECORD( iface, struct name, IAssemblyName_iface );
56 static HRESULT WINAPI name_QueryInterface(
57 IAssemblyName *iface,
58 REFIID riid,
59 void **obj )
61 struct name *name = impl_from_IAssemblyName( iface );
63 TRACE("%p, %s, %p\n", name, debugstr_guid(riid), obj);
65 *obj = NULL;
67 if (IsEqualIID( riid, &IID_IUnknown ) ||
68 IsEqualIID( riid, &IID_IAssemblyName ))
70 IAssemblyName_AddRef( iface );
71 *obj = name;
72 return S_OK;
75 return E_NOINTERFACE;
78 static ULONG WINAPI name_AddRef(
79 IAssemblyName *iface )
81 struct name *name = impl_from_IAssemblyName( iface );
82 return InterlockedIncrement( &name->refs );
85 static ULONG WINAPI name_Release( IAssemblyName *iface )
87 struct name *name = impl_from_IAssemblyName( iface );
88 ULONG refs = InterlockedDecrement( &name->refs );
90 if (!refs)
92 TRACE("destroying %p\n", name);
93 HeapFree( GetProcessHeap(), 0, name->name );
94 HeapFree( GetProcessHeap(), 0, name->arch );
95 HeapFree( GetProcessHeap(), 0, name->token );
96 HeapFree( GetProcessHeap(), 0, name->type );
97 HeapFree( GetProcessHeap(), 0, name->version );
98 HeapFree( GetProcessHeap(), 0, name );
100 return refs;
103 static HRESULT WINAPI name_SetProperty(
104 IAssemblyName *iface,
105 DWORD id,
106 LPVOID property,
107 DWORD size )
109 FIXME("%p, %d, %p, %d\n", iface, id, property, size);
110 return E_NOTIMPL;
113 static HRESULT WINAPI name_GetProperty(
114 IAssemblyName *iface,
115 DWORD id,
116 LPVOID buffer,
117 LPDWORD buflen )
119 FIXME("%p, %d, %p, %p\n", iface, id, buffer, buflen);
120 return E_NOTIMPL;
123 static HRESULT WINAPI name_Finalize(
124 IAssemblyName *iface )
126 FIXME("%p\n", iface);
127 return E_NOTIMPL;
130 static HRESULT WINAPI name_GetDisplayName(
131 IAssemblyName *iface,
132 LPOLESTR buffer,
133 LPDWORD buflen,
134 DWORD flags )
136 static const WCHAR fmtW[] = {',','%','s','=','\"','%','s','\"',0};
137 struct name *name = impl_from_IAssemblyName( iface );
138 unsigned int len;
140 TRACE("%p, %p, %p, 0x%08x\n", iface, buffer, buflen, flags);
142 if (!buflen || flags) return E_INVALIDARG;
144 len = lstrlenW( name->name ) + 1;
145 if (name->arch) len += lstrlenW( archW ) + lstrlenW( name->arch ) + 4;
146 if (name->token) len += lstrlenW( tokenW ) + lstrlenW( name->token ) + 4;
147 if (name->type) len += lstrlenW( typeW ) + lstrlenW( name->type ) + 4;
148 if (name->version) len += lstrlenW( versionW ) + lstrlenW( name->version ) + 4;
149 if (len > *buflen)
151 *buflen = len;
152 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
154 lstrcpyW( buffer, name->name );
155 len = lstrlenW( buffer );
156 if (name->arch) len += swprintf( buffer + len, *buflen - len, fmtW, archW, name->arch );
157 if (name->token) len += swprintf( buffer + len, *buflen - len, fmtW, tokenW, name->token );
158 if (name->type) len += swprintf( buffer + len, *buflen - len, fmtW, typeW, name->type );
159 if (name->version) len += swprintf( buffer + len, *buflen - len, fmtW, versionW, name->version );
160 return S_OK;
163 static HRESULT WINAPI name_Reserved(
164 IAssemblyName *iface,
165 REFIID riid,
166 IUnknown *pUnkReserved1,
167 IUnknown *pUnkReserved2,
168 LPCOLESTR szReserved,
169 LONGLONG llReserved,
170 LPVOID pvReserved,
171 DWORD cbReserved,
172 LPVOID *ppReserved )
174 FIXME("%p, %s, %p, %p, %s, %s, %p, %d, %p\n", iface,
175 debugstr_guid(riid), pUnkReserved1, pUnkReserved2,
176 debugstr_w(szReserved), wine_dbgstr_longlong(llReserved),
177 pvReserved, cbReserved, ppReserved);
178 return E_NOTIMPL;
181 const WCHAR *get_name_attribute( IAssemblyName *iface, enum name_attr_id id )
183 struct name *name = impl_from_IAssemblyName( iface );
185 switch (id)
187 case NAME_ATTR_ID_NAME: return name->name;
188 case NAME_ATTR_ID_ARCH: return name->arch;
189 case NAME_ATTR_ID_TOKEN: return name->token;
190 case NAME_ATTR_ID_TYPE: return name->type;
191 case NAME_ATTR_ID_VERSION: return name->version;
192 default:
193 ERR("unhandled name attribute %u\n", id);
194 break;
196 return NULL;
199 static HRESULT WINAPI name_GetName(
200 IAssemblyName *iface,
201 LPDWORD buflen,
202 WCHAR *buffer )
204 const WCHAR *name;
205 int len;
207 TRACE("%p, %p, %p\n", iface, buflen, buffer);
209 if (!buflen || !buffer) return E_INVALIDARG;
211 name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
212 len = lstrlenW( name ) + 1;
213 if (len > *buflen)
215 *buflen = len;
216 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
218 lstrcpyW( buffer, name );
219 *buflen = len + 3;
220 return S_OK;
223 static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low )
225 WORD ver[4];
226 WCHAR *p, *q;
227 unsigned int i;
229 memset( ver, 0, sizeof(ver) );
230 for (i = 0, p = version; i < 4; i++)
232 if (!*p) break;
233 q = wcschr( p, '.' );
234 if (q) *q = 0;
235 ver[i] = wcstol( p, NULL, 10 );
236 if (!q && i < 3) break;
237 p = q + 1;
239 *high = (ver[0] << 16) + ver[1];
240 *low = (ver[2] << 16) + ver[3];
241 return S_OK;
244 static HRESULT WINAPI name_GetVersion(
245 IAssemblyName *iface,
246 LPDWORD high,
247 LPDWORD low )
249 struct name *name = impl_from_IAssemblyName( iface );
250 WCHAR *version;
251 HRESULT hr;
253 TRACE("%p, %p, %p\n", iface, high, low);
255 if (!name->version) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
256 if (!(version = strdupW( name->version ))) return E_OUTOFMEMORY;
257 hr = parse_version( version, high, low );
258 HeapFree( GetProcessHeap(), 0, version );
259 return hr;
262 static HRESULT WINAPI name_IsEqual(
263 IAssemblyName *name1,
264 IAssemblyName *name2,
265 DWORD flags )
267 FIXME("%p, %p, 0x%08x\n", name1, name2, flags);
268 return E_NOTIMPL;
271 static HRESULT WINAPI name_Clone(
272 IAssemblyName *iface,
273 IAssemblyName **name )
275 FIXME("%p, %p\n", iface, name);
276 return E_NOTIMPL;
279 static const IAssemblyNameVtbl name_vtbl =
281 name_QueryInterface,
282 name_AddRef,
283 name_Release,
284 name_SetProperty,
285 name_GetProperty,
286 name_Finalize,
287 name_GetDisplayName,
288 name_Reserved,
289 name_GetName,
290 name_GetVersion,
291 name_IsEqual,
292 name_Clone
295 static WCHAR *parse_value( const WCHAR *str, unsigned int *len )
297 WCHAR *ret;
298 const WCHAR *p = str;
300 if (*p++ != '\"') return NULL;
301 while (*p && *p != '\"') p++;
302 if (!*p) return NULL;
304 *len = p - str;
305 if (!(ret = HeapAlloc( GetProcessHeap(), 0, *len * sizeof(WCHAR) ))) return NULL;
306 memcpy( ret, str + 1, (*len - 1) * sizeof(WCHAR) );
307 ret[*len - 1] = 0;
308 return ret;
311 static HRESULT parse_displayname( struct name *name, const WCHAR *displayname )
313 const WCHAR *p, *q;
314 unsigned int len;
316 p = q = displayname;
317 while (*q && *q != ',') q++;
318 len = q - p;
319 if (!(name->name = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
320 memcpy( name->name, p, len * sizeof(WCHAR) );
321 name->name[len] = 0;
322 if (!*q) return S_OK;
324 for (;;)
326 p = ++q;
327 while (*q && *q != '=') q++;
328 if (!*q) return E_INVALIDARG;
329 len = q - p;
330 if (len == ARRAY_SIZE(archW) - 1 && !memcmp( p, archW, len * sizeof(WCHAR) ))
332 p = ++q;
333 if (!(name->arch = parse_value( p, &len ))) return E_INVALIDARG;
334 q += len;
336 else if (len == ARRAY_SIZE(tokenW) - 1 && !memcmp( p, tokenW, len * sizeof(WCHAR) ))
338 p = ++q;
339 if (!(name->token = parse_value( p, &len ))) return E_INVALIDARG;
340 q += len;
342 else if (len == ARRAY_SIZE(typeW) - 1 && !memcmp( p, typeW, len * sizeof(WCHAR) ))
344 p = ++q;
345 if (!(name->type = parse_value( p, &len ))) return E_INVALIDARG;
346 q += len;
348 else if (len == ARRAY_SIZE(versionW) - 1 && !memcmp( p, versionW, len * sizeof(WCHAR) ))
350 p = ++q;
351 if (!(name->version = parse_value( p, &len ))) return E_INVALIDARG;
352 q += len;
354 else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME );
355 while (*q && *q != ',') q++;
356 if (!*q) break;
358 return S_OK;
361 /******************************************************************
362 * CreateAssemblyNameObject (SXS.@)
364 HRESULT WINAPI CreateAssemblyNameObject(
365 LPASSEMBLYNAME *obj,
366 LPCWSTR assembly,
367 DWORD flags,
368 LPVOID reserved )
370 struct name *name;
371 HRESULT hr;
373 TRACE("%p, %s, 0x%08x, %p\n", obj, debugstr_w(assembly), flags, reserved);
375 if (!obj) return E_INVALIDARG;
377 *obj = NULL;
378 if (!assembly || !assembly[0] || flags != CANOF_PARSE_DISPLAY_NAME)
379 return E_INVALIDARG;
381 if (!(name = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*name) )))
382 return E_OUTOFMEMORY;
384 name->IAssemblyName_iface.lpVtbl = &name_vtbl;
385 name->refs = 1;
387 hr = parse_displayname( name, assembly );
388 if (hr != S_OK)
390 HeapFree( GetProcessHeap(), 0, name->name );
391 HeapFree( GetProcessHeap(), 0, name->arch );
392 HeapFree( GetProcessHeap(), 0, name->token );
393 HeapFree( GetProcessHeap(), 0, name->type );
394 HeapFree( GetProcessHeap(), 0, name->version );
395 HeapFree( GetProcessHeap(), 0, name );
396 return hr;
398 *obj = &name->IAssemblyName_iface;
399 return S_OK;