ucrtbase: Fix hexadecimal floats parsing in strtod.
[wine.git] / dlls / sxs / name.c
bloba76510a9fee4274bb1f4c1b43a02445e7c905b8c
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 WCHAR version[30];
139 unsigned int len;
141 TRACE("%p, %p, %p, 0x%08x\n", iface, buffer, buflen, flags);
143 if (!buflen || flags) return E_INVALIDARG;
145 len = lstrlenW( name->name ) + 1;
146 if (name->arch) len += lstrlenW( archW ) + lstrlenW( name->arch ) + 4;
147 if (name->token) len += lstrlenW( tokenW ) + lstrlenW( name->token ) + 4;
148 if (name->type) len += lstrlenW( typeW ) + lstrlenW( name->type ) + 4;
149 if (name->version) len += lstrlenW( versionW ) + lstrlenW( version ) + 4;
150 if (len > *buflen)
152 *buflen = len;
153 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
155 lstrcpyW( buffer, name->name );
156 len = lstrlenW( buffer );
157 if (name->arch) len += swprintf( buffer + len, *buflen - len, fmtW, archW, name->arch );
158 if (name->token) len += swprintf( buffer + len, *buflen - len, fmtW, tokenW, name->token );
159 if (name->type) len += swprintf( buffer + len, *buflen - len, fmtW, typeW, name->type );
160 if (name->version) len += swprintf( buffer + len, *buflen - len, fmtW, versionW, name->version );
161 return S_OK;
164 static HRESULT WINAPI name_Reserved(
165 IAssemblyName *iface,
166 REFIID riid,
167 IUnknown *pUnkReserved1,
168 IUnknown *pUnkReserved2,
169 LPCOLESTR szReserved,
170 LONGLONG llReserved,
171 LPVOID pvReserved,
172 DWORD cbReserved,
173 LPVOID *ppReserved )
175 FIXME("%p, %s, %p, %p, %s, %s, %p, %d, %p\n", iface,
176 debugstr_guid(riid), pUnkReserved1, pUnkReserved2,
177 debugstr_w(szReserved), wine_dbgstr_longlong(llReserved),
178 pvReserved, cbReserved, ppReserved);
179 return E_NOTIMPL;
182 const WCHAR *get_name_attribute( IAssemblyName *iface, enum name_attr_id id )
184 struct name *name = impl_from_IAssemblyName( iface );
186 switch (id)
188 case NAME_ATTR_ID_NAME: return name->name;
189 case NAME_ATTR_ID_ARCH: return name->arch;
190 case NAME_ATTR_ID_TOKEN: return name->token;
191 case NAME_ATTR_ID_TYPE: return name->type;
192 case NAME_ATTR_ID_VERSION: return name->version;
193 default:
194 ERR("unhandled name attribute %u\n", id);
195 break;
197 return NULL;
200 static HRESULT WINAPI name_GetName(
201 IAssemblyName *iface,
202 LPDWORD buflen,
203 WCHAR *buffer )
205 const WCHAR *name;
206 int len;
208 TRACE("%p, %p, %p\n", iface, buflen, buffer);
210 if (!buflen || !buffer) return E_INVALIDARG;
212 name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
213 len = lstrlenW( name ) + 1;
214 if (len > *buflen)
216 *buflen = len;
217 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
219 lstrcpyW( buffer, name );
220 *buflen = len + 3;
221 return S_OK;
224 static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low )
226 WORD ver[4];
227 WCHAR *p, *q;
228 unsigned int i;
230 memset( ver, 0, sizeof(ver) );
231 for (i = 0, p = version; i < 4; i++)
233 if (!*p) break;
234 q = wcschr( p, '.' );
235 if (q) *q = 0;
236 ver[i] = wcstol( p, NULL, 10 );
237 if (!q && i < 3) break;
238 p = q + 1;
240 *high = (ver[0] << 16) + ver[1];
241 *low = (ver[2] << 16) + ver[3];
242 return S_OK;
245 static HRESULT WINAPI name_GetVersion(
246 IAssemblyName *iface,
247 LPDWORD high,
248 LPDWORD low )
250 struct name *name = impl_from_IAssemblyName( iface );
251 WCHAR *version;
252 HRESULT hr;
254 TRACE("%p, %p, %p\n", iface, high, low);
256 if (!name->version) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
257 if (!(version = strdupW( name->version ))) return E_OUTOFMEMORY;
258 hr = parse_version( version, high, low );
259 HeapFree( GetProcessHeap(), 0, version );
260 return hr;
263 static HRESULT WINAPI name_IsEqual(
264 IAssemblyName *name1,
265 IAssemblyName *name2,
266 DWORD flags )
268 FIXME("%p, %p, 0x%08x\n", name1, name2, flags);
269 return E_NOTIMPL;
272 static HRESULT WINAPI name_Clone(
273 IAssemblyName *iface,
274 IAssemblyName **name )
276 FIXME("%p, %p\n", iface, name);
277 return E_NOTIMPL;
280 static const IAssemblyNameVtbl name_vtbl =
282 name_QueryInterface,
283 name_AddRef,
284 name_Release,
285 name_SetProperty,
286 name_GetProperty,
287 name_Finalize,
288 name_GetDisplayName,
289 name_Reserved,
290 name_GetName,
291 name_GetVersion,
292 name_IsEqual,
293 name_Clone
296 static WCHAR *parse_value( const WCHAR *str, unsigned int *len )
298 WCHAR *ret;
299 const WCHAR *p = str;
301 if (*p++ != '\"') return NULL;
302 while (*p && *p != '\"') p++;
303 if (!*p) return NULL;
305 *len = p - str;
306 if (!(ret = HeapAlloc( GetProcessHeap(), 0, *len * sizeof(WCHAR) ))) return NULL;
307 memcpy( ret, str + 1, (*len - 1) * sizeof(WCHAR) );
308 ret[*len - 1] = 0;
309 return ret;
312 static HRESULT parse_displayname( struct name *name, const WCHAR *displayname )
314 const WCHAR *p, *q;
315 unsigned int len;
317 p = q = displayname;
318 while (*q && *q != ',') q++;
319 len = q - p;
320 if (!(name->name = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
321 memcpy( name->name, p, len * sizeof(WCHAR) );
322 name->name[len] = 0;
323 if (!*q) return S_OK;
325 for (;;)
327 p = ++q;
328 while (*q && *q != '=') q++;
329 if (!*q) return E_INVALIDARG;
330 len = q - p;
331 if (len == ARRAY_SIZE(archW) - 1 && !memcmp( p, archW, len * sizeof(WCHAR) ))
333 p = ++q;
334 if (!(name->arch = parse_value( p, &len ))) return E_INVALIDARG;
335 q += len;
337 else if (len == ARRAY_SIZE(tokenW) - 1 && !memcmp( p, tokenW, len * sizeof(WCHAR) ))
339 p = ++q;
340 if (!(name->token = parse_value( p, &len ))) return E_INVALIDARG;
341 q += len;
343 else if (len == ARRAY_SIZE(typeW) - 1 && !memcmp( p, typeW, len * sizeof(WCHAR) ))
345 p = ++q;
346 if (!(name->type = parse_value( p, &len ))) return E_INVALIDARG;
347 q += len;
349 else if (len == ARRAY_SIZE(versionW) - 1 && !memcmp( p, versionW, len * sizeof(WCHAR) ))
351 p = ++q;
352 if (!(name->version = parse_value( p, &len ))) return E_INVALIDARG;
353 q += len;
355 else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME );
356 while (*q && *q != ',') q++;
357 if (!*q) break;
359 return S_OK;
362 /******************************************************************
363 * CreateAssemblyNameObject (SXS.@)
365 HRESULT WINAPI CreateAssemblyNameObject(
366 LPASSEMBLYNAME *obj,
367 LPCWSTR assembly,
368 DWORD flags,
369 LPVOID reserved )
371 struct name *name;
372 HRESULT hr;
374 TRACE("%p, %s, 0x%08x, %p\n", obj, debugstr_w(assembly), flags, reserved);
376 if (!obj) return E_INVALIDARG;
378 *obj = NULL;
379 if (!assembly || !assembly[0] || flags != CANOF_PARSE_DISPLAY_NAME)
380 return E_INVALIDARG;
382 if (!(name = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*name) )))
383 return E_OUTOFMEMORY;
385 name->IAssemblyName_iface.lpVtbl = &name_vtbl;
386 name->refs = 1;
388 hr = parse_displayname( name, assembly );
389 if (hr != S_OK)
391 HeapFree( GetProcessHeap(), 0, name->name );
392 HeapFree( GetProcessHeap(), 0, name->arch );
393 HeapFree( GetProcessHeap(), 0, name->token );
394 HeapFree( GetProcessHeap(), 0, name->type );
395 HeapFree( GetProcessHeap(), 0, name->version );
396 HeapFree( GetProcessHeap(), 0, name );
397 return hr;
399 *obj = &name->IAssemblyName_iface;
400 return S_OK;