wined3d: Directly pass the texture to texture_activate_dimensions().
[wine.git] / dlls / fusion / asmname.c
blob54be4e8e9cf72fb014882c5848808da8324e2a52
1 /*
2 * IAssemblyName implementation
4 * Copyright 2008 James Hawkins
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
24 #define INITGUID
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "guiddef.h"
31 #include "fusion.h"
32 #include "corerror.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36 #include "fusionpriv.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(fusion);
40 typedef struct {
41 const IAssemblyNameVtbl *lpIAssemblyNameVtbl;
43 LPWSTR displayname;
44 LPWSTR name;
45 LPWSTR culture;
46 LPWSTR procarch;
48 WORD version[4];
49 DWORD versize;
51 BYTE pubkey[8];
52 BOOL haspubkey;
54 LONG ref;
55 } IAssemblyNameImpl;
57 static const WCHAR separator[] = {',',' ',0};
58 static const WCHAR version[] = {'V','e','r','s','i','o','n',0};
59 static const WCHAR culture[] = {'C','u','l','t','u','r','e',0};
60 static const WCHAR pubkey[] =
61 {'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
62 static const WCHAR procarch[] = {'p','r','o','c','e','s','s','o','r',
63 'A','r','c','h','i','t','e','c','t','u','r','e',0};
65 #define CHARS_PER_PUBKEY 16
67 static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface,
68 REFIID riid, LPVOID *ppobj)
70 IAssemblyNameImpl *This = (IAssemblyNameImpl *)iface;
72 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
74 *ppobj = NULL;
76 if (IsEqualIID(riid, &IID_IUnknown) ||
77 IsEqualIID(riid, &IID_IAssemblyName))
79 IUnknown_AddRef(iface);
80 *ppobj = This;
81 return S_OK;
84 WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj);
85 return E_NOINTERFACE;
88 static ULONG WINAPI IAssemblyNameImpl_AddRef(IAssemblyName *iface)
90 IAssemblyNameImpl *This = (IAssemblyNameImpl *)iface;
91 ULONG refCount = InterlockedIncrement(&This->ref);
93 TRACE("(%p)->(ref before = %u)\n", This, refCount - 1);
95 return refCount;
98 static ULONG WINAPI IAssemblyNameImpl_Release(IAssemblyName *iface)
100 IAssemblyNameImpl *This = (IAssemblyNameImpl *)iface;
101 ULONG refCount = InterlockedDecrement(&This->ref);
103 TRACE("(%p)->(ref before = %u)\n", This, refCount + 1);
105 if (!refCount)
107 HeapFree(GetProcessHeap(), 0, This->displayname);
108 HeapFree(GetProcessHeap(), 0, This->name);
109 HeapFree(GetProcessHeap(), 0, This->culture);
110 HeapFree(GetProcessHeap(), 0, This);
113 return refCount;
116 static HRESULT WINAPI IAssemblyNameImpl_SetProperty(IAssemblyName *iface,
117 DWORD PropertyId,
118 LPVOID pvProperty,
119 DWORD cbProperty)
121 FIXME("(%p, %d, %p, %d) stub!\n", iface, PropertyId, pvProperty, cbProperty);
122 return E_NOTIMPL;
125 static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface,
126 DWORD PropertyId,
127 LPVOID pvProperty,
128 LPDWORD pcbProperty)
130 IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface;
132 TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty);
134 *((LPWSTR)pvProperty) = '\0';
136 switch (PropertyId)
138 case ASM_NAME_NULL_PUBLIC_KEY:
139 case ASM_NAME_NULL_PUBLIC_KEY_TOKEN:
140 if (name->haspubkey)
141 return S_OK;
142 return S_FALSE;
144 case ASM_NAME_NULL_CUSTOM:
145 return S_OK;
147 case ASM_NAME_NAME:
148 *pcbProperty = 0;
149 if (name->name)
151 lstrcpyW(pvProperty, name->name);
152 *pcbProperty = (lstrlenW(name->name) + 1) * 2;
154 break;
156 case ASM_NAME_MAJOR_VERSION:
157 *pcbProperty = 0;
158 *((WORD *)pvProperty) = name->version[0];
159 if (name->versize >= 1)
160 *pcbProperty = sizeof(WORD);
161 break;
163 case ASM_NAME_MINOR_VERSION:
164 *pcbProperty = 0;
165 *((WORD *)pvProperty) = name->version[1];
166 if (name->versize >= 2)
167 *pcbProperty = sizeof(WORD);
168 break;
170 case ASM_NAME_BUILD_NUMBER:
171 *pcbProperty = 0;
172 *((WORD *)pvProperty) = name->version[2];
173 if (name->versize >= 3)
174 *pcbProperty = sizeof(WORD);
175 break;
177 case ASM_NAME_REVISION_NUMBER:
178 *pcbProperty = 0;
179 *((WORD *)pvProperty) = name->version[3];
180 if (name->versize >= 4)
181 *pcbProperty = sizeof(WORD);
182 break;
184 case ASM_NAME_CULTURE:
185 *pcbProperty = 0;
186 if (name->culture)
188 lstrcpyW(pvProperty, name->culture);
189 *pcbProperty = (lstrlenW(name->culture) + 1) * 2;
191 break;
193 case ASM_NAME_PUBLIC_KEY_TOKEN:
194 *pcbProperty = 0;
195 if (name->haspubkey)
197 memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2);
198 *pcbProperty = sizeof(DWORD) * 2;
200 break;
202 default:
203 *pcbProperty = 0;
204 break;
207 return S_OK;
210 static HRESULT WINAPI IAssemblyNameImpl_Finalize(IAssemblyName *iface)
212 FIXME("(%p) stub!\n", iface);
213 return E_NOTIMPL;
216 static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface,
217 LPOLESTR szDisplayName,
218 LPDWORD pccDisplayName,
219 DWORD dwDisplayFlags)
221 IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface;
222 WCHAR verstr[30];
223 DWORD size;
224 LPWSTR cultureval = 0;
226 static const WCHAR equals[] = {'=',0};
228 TRACE("(%p, %p, %p, %d)\n", iface, szDisplayName,
229 pccDisplayName, dwDisplayFlags);
231 if (dwDisplayFlags == 0)
233 if (!name->displayname || !*name->displayname)
234 return FUSION_E_INVALID_NAME;
236 size = min(*pccDisplayName, lstrlenW(name->displayname) + 1);
238 lstrcpynW(szDisplayName, name->displayname, size);
239 *pccDisplayName = size;
241 return S_OK;
244 if (!name->name || !*name->name)
245 return FUSION_E_INVALID_NAME;
247 /* Verify buffer size is sufficient */
248 size = lstrlenW(name->name) + 1;
250 if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0))
252 static const WCHAR spec[] = {'%','d',0};
253 static const WCHAR period[] = {'.',0};
254 int i;
256 wsprintfW(verstr, spec, name->version[0]);
258 for (i = 1; i < name->versize; i++)
260 WCHAR value[6];
261 wsprintfW(value, spec, name->version[i]);
263 lstrcatW(verstr, period);
264 lstrcatW(verstr, value);
267 size += lstrlenW(separator) + lstrlenW(version) + lstrlenW(equals) + lstrlenW(verstr);
270 if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture))
272 static const WCHAR neutral[] = {'n','e','u','t','r','a','l', 0};
274 cultureval = (lstrlenW(name->culture) == 2) ? name->culture : (LPWSTR) neutral;
275 size += lstrlenW(separator) + lstrlenW(culture) + lstrlenW(equals) + lstrlenW(cultureval);
278 if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey))
279 size += lstrlenW(separator) + lstrlenW(pubkey) + lstrlenW(equals) + CHARS_PER_PUBKEY;
281 if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch))
282 size += lstrlenW(separator) + lstrlenW(procarch) + lstrlenW(equals) + lstrlenW(name->procarch);
284 if (size > *pccDisplayName)
285 return S_FALSE;
287 /* Construct the string */
288 lstrcpyW(szDisplayName, name->name);
290 if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0))
292 lstrcatW(szDisplayName, separator);
294 lstrcatW(szDisplayName, version);
295 lstrcatW(szDisplayName, equals);
296 lstrcatW(szDisplayName, verstr);
299 if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture))
301 lstrcatW(szDisplayName, separator);
303 lstrcatW(szDisplayName, culture);
304 lstrcatW(szDisplayName, equals);
305 lstrcatW(szDisplayName, cultureval);
308 if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey))
310 WCHAR pkt[CHARS_PER_PUBKEY + 1];
311 static const WCHAR spec[] = {'%','0','x','%','0','x','%','0','x',
312 '%','0','x','%','0','x','%','0','x','%','0','x','%','0','x',0};
314 lstrcatW(szDisplayName, separator);
316 lstrcatW(szDisplayName, pubkey);
317 lstrcatW(szDisplayName, equals);
319 wsprintfW(pkt, spec, name->pubkey[0], name->pubkey[1], name->pubkey[2],
320 name->pubkey[3], name->pubkey[4], name->pubkey[5], name->pubkey[6],
321 name->pubkey[7]);
323 lstrcatW(szDisplayName, pkt);
326 if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch))
328 lstrcatW(szDisplayName, separator);
330 lstrcatW(szDisplayName, procarch);
331 lstrcatW(szDisplayName, equals);
332 lstrcatW(szDisplayName, name->procarch);
335 *pccDisplayName = size;
336 return S_OK;
339 static HRESULT WINAPI IAssemblyNameImpl_Reserved(IAssemblyName *iface,
340 REFIID refIID,
341 IUnknown *pUnkReserved1,
342 IUnknown *pUnkReserved2,
343 LPCOLESTR szReserved,
344 LONGLONG llReserved,
345 LPVOID pvReserved,
346 DWORD cbReserved,
347 LPVOID *ppReserved)
349 TRACE("(%p, %s, %p, %p, %s, %x%08x, %p, %d, %p)\n", iface,
350 debugstr_guid(refIID), pUnkReserved1, pUnkReserved2,
351 debugstr_w(szReserved), (DWORD)(llReserved >> 32), (DWORD)llReserved,
352 pvReserved, cbReserved, ppReserved);
354 return E_NOTIMPL;
357 static HRESULT WINAPI IAssemblyNameImpl_GetName(IAssemblyName *iface,
358 LPDWORD lpcwBuffer,
359 WCHAR *pwzName)
361 IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface;
363 TRACE("(%p, %p, %p)\n", iface, lpcwBuffer, pwzName);
365 if (!name->name)
367 *pwzName = '\0';
368 *lpcwBuffer = 0;
369 return S_OK;
372 lstrcpyW(pwzName, name->name);
373 *lpcwBuffer = lstrlenW(pwzName) + 1;
375 return S_OK;
378 static HRESULT WINAPI IAssemblyNameImpl_GetVersion(IAssemblyName *iface,
379 LPDWORD pdwVersionHi,
380 LPDWORD pdwVersionLow)
382 IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface;
384 TRACE("(%p, %p, %p)\n", iface, pdwVersionHi, pdwVersionLow);
386 *pdwVersionHi = 0;
387 *pdwVersionLow = 0;
389 if (name->versize != 4)
390 return FUSION_E_INVALID_NAME;
392 *pdwVersionHi = (name->version[0] << 16) + name->version[1];
393 *pdwVersionLow = (name->version[2] << 16) + name->version[3];
395 return S_OK;
398 static HRESULT WINAPI IAssemblyNameImpl_IsEqual(IAssemblyName *iface,
399 IAssemblyName *pName,
400 DWORD dwCmpFlags)
402 FIXME("(%p, %p, %d) stub!\n", iface, pName, dwCmpFlags);
403 return E_NOTIMPL;
406 static HRESULT WINAPI IAssemblyNameImpl_Clone(IAssemblyName *iface,
407 IAssemblyName **pName)
409 FIXME("(%p, %p) stub!\n", iface, pName);
410 return E_NOTIMPL;
413 static const IAssemblyNameVtbl AssemblyNameVtbl = {
414 IAssemblyNameImpl_QueryInterface,
415 IAssemblyNameImpl_AddRef,
416 IAssemblyNameImpl_Release,
417 IAssemblyNameImpl_SetProperty,
418 IAssemblyNameImpl_GetProperty,
419 IAssemblyNameImpl_Finalize,
420 IAssemblyNameImpl_GetDisplayName,
421 IAssemblyNameImpl_Reserved,
422 IAssemblyNameImpl_GetName,
423 IAssemblyNameImpl_GetVersion,
424 IAssemblyNameImpl_IsEqual,
425 IAssemblyNameImpl_Clone
428 static HRESULT parse_version(IAssemblyNameImpl *name, LPWSTR version)
430 LPWSTR beg, end;
431 int i;
433 for (i = 0, beg = version; i < 4; i++)
435 if (!*beg)
436 return S_OK;
438 end = strchrW(beg, '.');
440 if (end) *end = '\0';
441 name->version[i] = atolW(beg);
442 name->versize++;
444 if (!end && i < 3)
445 return S_OK;
447 beg = end + 1;
450 return S_OK;
453 static HRESULT parse_culture(IAssemblyNameImpl *name, LPWSTR culture)
455 static const WCHAR empty[] = {0};
457 if (lstrlenW(culture) == 2)
458 name->culture = strdupW(culture);
459 else
460 name->culture = strdupW(empty);
462 return S_OK;
465 static BOOL is_hex(WCHAR c)
467 return ((c >= 'a' && c <= 'f') ||
468 (c >= 'A' && c <= 'F') ||
469 (c >= '0' && c <= '9'));
472 static BYTE hextobyte(WCHAR c)
474 if(c >= '0' && c <= '9')
475 return c - '0';
476 if(c >= 'A' && c <= 'F')
477 return c - 'A' + 10;
478 if(c >= 'a' && c <= 'f')
479 return c - 'a' + 10;
480 return 0;
483 static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPWSTR pubkey)
485 int i;
486 BYTE val;
488 if (lstrlenW(pubkey) < CHARS_PER_PUBKEY)
489 return FUSION_E_INVALID_NAME;
491 for (i = 0; i < CHARS_PER_PUBKEY; i++)
492 if (!is_hex(pubkey[i]))
493 return FUSION_E_INVALID_NAME;
495 name->haspubkey = TRUE;
497 for (i = 0; i < CHARS_PER_PUBKEY; i += 2)
499 val = (hextobyte(pubkey[i]) << 4) + hextobyte(pubkey[i + 1]);
500 name->pubkey[i / 2] = val;
503 return S_OK;
506 static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyName)
508 LPWSTR str, save;
509 LPWSTR ptr, ptr2;
510 HRESULT hr = S_OK;
511 BOOL done = FALSE;
513 if (!szAssemblyName)
514 return S_OK;
516 name->displayname = strdupW(szAssemblyName);
517 if (!name->displayname)
518 return E_OUTOFMEMORY;
520 str = strdupW(szAssemblyName);
521 save = str;
522 if (!str)
523 return E_OUTOFMEMORY;
525 ptr = strchrW(str, ',');
526 if (ptr) *ptr = '\0';
528 /* no ',' but ' ' only */
529 if( !ptr && strchrW(str, ' ') )
531 hr = FUSION_E_INVALID_NAME;
532 goto done;
535 name->name = strdupW(str);
536 if (!name->name)
537 return E_OUTOFMEMORY;
539 if (!ptr)
540 goto done;
542 str = ptr + 2;
543 while (!done)
545 ptr = strchrW(str, '=');
546 if (!ptr)
548 hr = FUSION_E_INVALID_NAME;
549 goto done;
552 *(ptr++) = '\0';
553 if (!*ptr)
555 hr = FUSION_E_INVALID_NAME;
556 goto done;
559 if (!(ptr2 = strstrW(ptr, separator)))
561 if (!(ptr2 = strchrW(ptr, '\0')))
563 hr = FUSION_E_INVALID_NAME;
564 goto done;
567 done = TRUE;
570 *ptr2 = '\0';
572 while (*str == ' ') str++;
574 if (!lstrcmpW(str, version))
575 hr = parse_version(name, ptr);
576 else if (!lstrcmpW(str, culture))
577 hr = parse_culture(name, ptr);
578 else if (!lstrcmpW(str, pubkey))
579 hr = parse_pubkey(name, ptr);
580 else if (!lstrcmpW(str, procarch))
582 name->procarch = strdupW(ptr);
583 hr = S_OK;
586 if (FAILED(hr))
587 goto done;
589 str = ptr2 + 1;
592 done:
593 HeapFree(GetProcessHeap(), 0, save);
594 if (FAILED(hr))
596 HeapFree(GetProcessHeap(), 0, name->displayname);
597 HeapFree(GetProcessHeap(), 0, name->name);
599 return hr;
602 /******************************************************************
603 * CreateAssemblyNameObject (FUSION.@)
605 HRESULT WINAPI CreateAssemblyNameObject(LPASSEMBLYNAME *ppAssemblyNameObj,
606 LPCWSTR szAssemblyName, DWORD dwFlags,
607 LPVOID pvReserved)
609 IAssemblyNameImpl *name;
610 HRESULT hr;
612 TRACE("(%p, %s, %08x, %p) stub!\n", ppAssemblyNameObj,
613 debugstr_w(szAssemblyName), dwFlags, pvReserved);
615 if (!ppAssemblyNameObj)
616 return E_INVALIDARG;
618 if ((dwFlags & CANOF_PARSE_DISPLAY_NAME) &&
619 (!szAssemblyName || !*szAssemblyName))
620 return E_INVALIDARG;
622 name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAssemblyNameImpl));
623 if (!name)
624 return E_OUTOFMEMORY;
626 name->lpIAssemblyNameVtbl = &AssemblyNameVtbl;
627 name->ref = 1;
629 hr = parse_display_name(name, szAssemblyName);
630 if (FAILED(hr))
632 HeapFree(GetProcessHeap(), 0, name);
633 return hr;
636 *ppAssemblyNameObj = (IAssemblyName *)name;
638 return S_OK;