msvcrt: Use EnumSystemLocalesEx instead of directly accessing kernel32 resources.
[wine.git] / dlls / sxs / name.c
blob4772c7317c540e8a09a2e1e7a29138697c8490ce
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 **ret_iface )
61 TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), ret_iface);
63 *ret_iface = NULL;
65 if (IsEqualIID( riid, &IID_IUnknown ) ||
66 IsEqualIID( riid, &IID_IAssemblyName ))
68 IAssemblyName_AddRef( iface );
69 *ret_iface = iface;
70 return S_OK;
73 return E_NOINTERFACE;
76 static ULONG WINAPI name_AddRef(
77 IAssemblyName *iface )
79 struct name *name = impl_from_IAssemblyName( iface );
80 return InterlockedIncrement( &name->refs );
83 static ULONG WINAPI name_Release( IAssemblyName *iface )
85 struct name *name = impl_from_IAssemblyName( iface );
86 ULONG refs = InterlockedDecrement( &name->refs );
88 if (!refs)
90 TRACE("destroying %p\n", name);
91 free( name->name );
92 free( name->arch );
93 free( name->token );
94 free( name->type );
95 free( name->version );
96 free( name );
98 return refs;
101 static HRESULT WINAPI name_SetProperty(
102 IAssemblyName *iface,
103 DWORD id,
104 LPVOID property,
105 DWORD size )
107 FIXME("%p, %ld, %p, %ld\n", iface, id, property, size);
108 return E_NOTIMPL;
111 static HRESULT WINAPI name_GetProperty(
112 IAssemblyName *iface,
113 DWORD id,
114 LPVOID buffer,
115 LPDWORD buflen )
117 FIXME("%p, %ld, %p, %p\n", iface, id, buffer, buflen);
118 return E_NOTIMPL;
121 static HRESULT WINAPI name_Finalize(
122 IAssemblyName *iface )
124 FIXME("%p\n", iface);
125 return E_NOTIMPL;
128 static HRESULT WINAPI name_GetDisplayName(
129 IAssemblyName *iface,
130 LPOLESTR buffer,
131 LPDWORD buflen,
132 DWORD flags )
134 static const WCHAR fmtW[] = {',','%','s','=','\"','%','s','\"',0};
135 struct name *name = impl_from_IAssemblyName( iface );
136 unsigned int len;
138 TRACE("%p, %p, %p, 0x%08lx\n", iface, buffer, buflen, flags);
140 if (!buflen || flags) return E_INVALIDARG;
142 len = lstrlenW( name->name ) + 1;
143 if (name->arch) len += lstrlenW( archW ) + lstrlenW( name->arch ) + 4;
144 if (name->token) len += lstrlenW( tokenW ) + lstrlenW( name->token ) + 4;
145 if (name->type) len += lstrlenW( typeW ) + lstrlenW( name->type ) + 4;
146 if (name->version) len += lstrlenW( versionW ) + lstrlenW( name->version ) + 4;
147 if (len > *buflen)
149 *buflen = len;
150 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
152 lstrcpyW( buffer, name->name );
153 len = lstrlenW( buffer );
154 if (name->arch) len += swprintf( buffer + len, *buflen - len, fmtW, archW, name->arch );
155 if (name->token) len += swprintf( buffer + len, *buflen - len, fmtW, tokenW, name->token );
156 if (name->type) len += swprintf( buffer + len, *buflen - len, fmtW, typeW, name->type );
157 if (name->version) len += swprintf( buffer + len, *buflen - len, fmtW, versionW, name->version );
158 return S_OK;
161 static HRESULT WINAPI name_Reserved(
162 IAssemblyName *iface,
163 REFIID riid,
164 IUnknown *pUnkReserved1,
165 IUnknown *pUnkReserved2,
166 LPCOLESTR szReserved,
167 LONGLONG llReserved,
168 LPVOID pvReserved,
169 DWORD cbReserved,
170 LPVOID *ppReserved )
172 FIXME("%p, %s, %p, %p, %s, %s, %p, %ld, %p\n", iface,
173 debugstr_guid(riid), pUnkReserved1, pUnkReserved2,
174 debugstr_w(szReserved), wine_dbgstr_longlong(llReserved),
175 pvReserved, cbReserved, ppReserved);
176 return E_NOTIMPL;
179 const WCHAR *get_name_attribute( IAssemblyName *iface, enum name_attr_id id )
181 struct name *name = impl_from_IAssemblyName( iface );
183 switch (id)
185 case NAME_ATTR_ID_NAME: return name->name;
186 case NAME_ATTR_ID_ARCH: return name->arch;
187 case NAME_ATTR_ID_TOKEN: return name->token;
188 case NAME_ATTR_ID_TYPE: return name->type;
189 case NAME_ATTR_ID_VERSION: return name->version;
190 default:
191 ERR("unhandled name attribute %u\n", id);
192 break;
194 return NULL;
197 static HRESULT WINAPI name_GetName(
198 IAssemblyName *iface,
199 LPDWORD buflen,
200 WCHAR *buffer )
202 const WCHAR *name;
203 int len;
205 TRACE("%p, %p, %p\n", iface, buflen, buffer);
207 if (!buflen || !buffer) return E_INVALIDARG;
209 name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
210 len = lstrlenW( name ) + 1;
211 if (len > *buflen)
213 *buflen = len;
214 return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
216 lstrcpyW( buffer, name );
217 *buflen = len + 3;
218 return S_OK;
221 static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low )
223 WORD ver[4];
224 WCHAR *p, *q;
225 unsigned int i;
227 memset( ver, 0, sizeof(ver) );
228 for (i = 0, p = version; i < 4; i++)
230 if (!*p) break;
231 q = wcschr( p, '.' );
232 if (q) *q = 0;
233 ver[i] = wcstol( p, NULL, 10 );
234 if (!q && i < 3) break;
235 p = q + 1;
237 *high = (ver[0] << 16) + ver[1];
238 *low = (ver[2] << 16) + ver[3];
239 return S_OK;
242 static HRESULT WINAPI name_GetVersion(
243 IAssemblyName *iface,
244 LPDWORD high,
245 LPDWORD low )
247 struct name *name = impl_from_IAssemblyName( iface );
248 WCHAR *version;
249 HRESULT hr;
251 TRACE("%p, %p, %p\n", iface, high, low);
253 if (!name->version) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
254 if (!(version = wcsdup( name->version ))) return E_OUTOFMEMORY;
255 hr = parse_version( version, high, low );
256 free( version );
257 return hr;
260 static HRESULT WINAPI name_IsEqual(
261 IAssemblyName *name1,
262 IAssemblyName *name2,
263 DWORD flags )
265 FIXME("%p, %p, 0x%08lx\n", name1, name2, flags);
266 return E_NOTIMPL;
269 static HRESULT WINAPI name_Clone(
270 IAssemblyName *iface,
271 IAssemblyName **name )
273 FIXME("%p, %p\n", iface, name);
274 return E_NOTIMPL;
277 static const IAssemblyNameVtbl name_vtbl =
279 name_QueryInterface,
280 name_AddRef,
281 name_Release,
282 name_SetProperty,
283 name_GetProperty,
284 name_Finalize,
285 name_GetDisplayName,
286 name_Reserved,
287 name_GetName,
288 name_GetVersion,
289 name_IsEqual,
290 name_Clone
293 static WCHAR *parse_value( const WCHAR *str, unsigned int *len )
295 WCHAR *ret;
296 const WCHAR *p = str;
298 if (*p++ != '\"') return NULL;
299 while (*p && *p != '\"') p++;
300 if (!*p) return NULL;
302 *len = p - str;
303 if (!(ret = malloc( *len * sizeof(WCHAR) ))) return NULL;
304 memcpy( ret, str + 1, (*len - 1) * sizeof(WCHAR) );
305 ret[*len - 1] = 0;
306 return ret;
309 static HRESULT parse_displayname( struct name *name, const WCHAR *displayname )
311 const WCHAR *p, *q;
312 unsigned int len;
314 p = q = displayname;
315 while (*q && *q != ',') q++;
316 len = q - p;
317 if (!(name->name = malloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
318 memcpy( name->name, p, len * sizeof(WCHAR) );
319 name->name[len] = 0;
320 if (!*q) return S_OK;
322 for (;;)
324 p = ++q;
325 while (*q && *q != '=') q++;
326 if (!*q) return E_INVALIDARG;
327 len = q - p;
328 if (len == ARRAY_SIZE(archW) - 1 && !memcmp( p, archW, len * sizeof(WCHAR) ))
330 p = ++q;
331 if (!(name->arch = parse_value( p, &len ))) return E_INVALIDARG;
332 q += len;
334 else if (len == ARRAY_SIZE(tokenW) - 1 && !memcmp( p, tokenW, len * sizeof(WCHAR) ))
336 p = ++q;
337 if (!(name->token = parse_value( p, &len ))) return E_INVALIDARG;
338 q += len;
340 else if (len == ARRAY_SIZE(typeW) - 1 && !memcmp( p, typeW, len * sizeof(WCHAR) ))
342 p = ++q;
343 if (!(name->type = parse_value( p, &len ))) return E_INVALIDARG;
344 q += len;
346 else if (len == ARRAY_SIZE(versionW) - 1 && !memcmp( p, versionW, len * sizeof(WCHAR) ))
348 p = ++q;
349 if (!(name->version = parse_value( p, &len ))) return E_INVALIDARG;
350 q += len;
352 else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME );
353 while (*q && *q != ',') q++;
354 if (!*q) break;
356 return S_OK;
359 /******************************************************************
360 * CreateAssemblyNameObject (SXS.@)
362 HRESULT WINAPI CreateAssemblyNameObject(
363 LPASSEMBLYNAME *obj,
364 LPCWSTR assembly,
365 DWORD flags,
366 LPVOID reserved )
368 struct name *name;
369 HRESULT hr;
371 TRACE("%p, %s, 0x%08lx, %p\n", obj, debugstr_w(assembly), flags, reserved);
373 if (!obj) return E_INVALIDARG;
375 *obj = NULL;
376 if (!assembly || !assembly[0] || flags != CANOF_PARSE_DISPLAY_NAME)
377 return E_INVALIDARG;
379 if (!(name = calloc(1, sizeof(*name) )))
380 return E_OUTOFMEMORY;
382 name->IAssemblyName_iface.lpVtbl = &name_vtbl;
383 name->refs = 1;
385 hr = parse_displayname( name, assembly );
386 if (hr != S_OK)
388 free( name->name );
389 free( name->arch );
390 free( name->token );
391 free( name->type );
392 free( name->version );
393 free( name );
394 return hr;
396 *obj = &name->IAssemblyName_iface;
397 return S_OK;