1c2c66affSColin Finck /*
2c2c66affSColin Finck * IAssemblyName implementation
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2008 James Hawkins
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
21b980bb98SAmine Khaldi #include <stdarg.h>
22b980bb98SAmine Khaldi #include <assert.h>
23b980bb98SAmine Khaldi
24b980bb98SAmine Khaldi #define COBJMACROS
25b980bb98SAmine Khaldi #define INITGUID
26*88179a5dSAmine Khaldi #ifdef __REACTOS__
27*88179a5dSAmine Khaldi #define WIN32_NO_STATUS
28*88179a5dSAmine Khaldi #endif
29b980bb98SAmine Khaldi
30b980bb98SAmine Khaldi #include "windef.h"
31b980bb98SAmine Khaldi #include "winbase.h"
32b980bb98SAmine Khaldi #include "winuser.h"
33b980bb98SAmine Khaldi #include "ole2.h"
34b980bb98SAmine Khaldi #include "guiddef.h"
35b980bb98SAmine Khaldi #include "fusion.h"
36b980bb98SAmine Khaldi #include "corerror.h"
37b980bb98SAmine Khaldi #include "strsafe.h"
38b980bb98SAmine Khaldi
39b980bb98SAmine Khaldi #include "wine/debug.h"
40c2c66affSColin Finck #include "fusionpriv.h"
41c2c66affSColin Finck
42b980bb98SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(fusion);
43c2c66affSColin Finck
44c2c66affSColin Finck typedef struct {
45c2c66affSColin Finck IAssemblyName IAssemblyName_iface;
46c2c66affSColin Finck
47c2c66affSColin Finck LPWSTR path;
48c2c66affSColin Finck
49c2c66affSColin Finck LPWSTR displayname;
50c2c66affSColin Finck LPWSTR name;
51c2c66affSColin Finck LPWSTR culture;
52c2c66affSColin Finck LPWSTR procarch;
53c2c66affSColin Finck
54c2c66affSColin Finck WORD version[4];
55c2c66affSColin Finck DWORD versize;
56c2c66affSColin Finck
57c2c66affSColin Finck BYTE pubkey[8];
58c2c66affSColin Finck BOOL haspubkey;
59c2c66affSColin Finck
60975d9d4dSAmine Khaldi PEKIND pekind;
61975d9d4dSAmine Khaldi
62c2c66affSColin Finck LONG ref;
63c2c66affSColin Finck } IAssemblyNameImpl;
64c2c66affSColin Finck
65c2c66affSColin Finck static const WCHAR separator[] = {',',' ',0};
66c2c66affSColin Finck static const WCHAR version[] = {'V','e','r','s','i','o','n',0};
67c2c66affSColin Finck static const WCHAR culture[] = {'C','u','l','t','u','r','e',0};
68c2c66affSColin Finck static const WCHAR pubkey[] =
69c2c66affSColin Finck {'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
70c2c66affSColin Finck static const WCHAR procarch[] = {'p','r','o','c','e','s','s','o','r',
71c2c66affSColin Finck 'A','r','c','h','i','t','e','c','t','u','r','e',0};
72c2c66affSColin Finck
73c2c66affSColin Finck #define CHARS_PER_PUBKEY 16
74c2c66affSColin Finck
impl_from_IAssemblyName(IAssemblyName * iface)75c2c66affSColin Finck static inline IAssemblyNameImpl *impl_from_IAssemblyName(IAssemblyName *iface)
76c2c66affSColin Finck {
77c2c66affSColin Finck return CONTAINING_RECORD(iface, IAssemblyNameImpl, IAssemblyName_iface);
78c2c66affSColin Finck }
79c2c66affSColin Finck
IAssemblyNameImpl_QueryInterface(IAssemblyName * iface,REFIID riid,LPVOID * ppobj)80c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface,
81c2c66affSColin Finck REFIID riid, LPVOID *ppobj)
82c2c66affSColin Finck {
83c2c66affSColin Finck IAssemblyNameImpl *This = impl_from_IAssemblyName(iface);
84c2c66affSColin Finck
85c2c66affSColin Finck TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
86c2c66affSColin Finck
87c2c66affSColin Finck *ppobj = NULL;
88c2c66affSColin Finck
89c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown) ||
90c2c66affSColin Finck IsEqualIID(riid, &IID_IAssemblyName))
91c2c66affSColin Finck {
92c2c66affSColin Finck IAssemblyName_AddRef(iface);
93c2c66affSColin Finck *ppobj = &This->IAssemblyName_iface;
94c2c66affSColin Finck return S_OK;
95c2c66affSColin Finck }
96c2c66affSColin Finck
97c2c66affSColin Finck WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj);
98c2c66affSColin Finck return E_NOINTERFACE;
99c2c66affSColin Finck }
100c2c66affSColin Finck
IAssemblyNameImpl_AddRef(IAssemblyName * iface)101c2c66affSColin Finck static ULONG WINAPI IAssemblyNameImpl_AddRef(IAssemblyName *iface)
102c2c66affSColin Finck {
103c2c66affSColin Finck IAssemblyNameImpl *This = impl_from_IAssemblyName(iface);
104c2c66affSColin Finck ULONG refCount = InterlockedIncrement(&This->ref);
105c2c66affSColin Finck
106c2c66affSColin Finck TRACE("(%p)->(ref before = %u)\n", This, refCount - 1);
107c2c66affSColin Finck
108c2c66affSColin Finck return refCount;
109c2c66affSColin Finck }
110c2c66affSColin Finck
IAssemblyNameImpl_Release(IAssemblyName * iface)111c2c66affSColin Finck static ULONG WINAPI IAssemblyNameImpl_Release(IAssemblyName *iface)
112c2c66affSColin Finck {
113c2c66affSColin Finck IAssemblyNameImpl *This = impl_from_IAssemblyName(iface);
114c2c66affSColin Finck ULONG refCount = InterlockedDecrement(&This->ref);
115c2c66affSColin Finck
116c2c66affSColin Finck TRACE("(%p)->(ref before = %u)\n", This, refCount + 1);
117c2c66affSColin Finck
118c2c66affSColin Finck if (!refCount)
119c2c66affSColin Finck {
120b980bb98SAmine Khaldi heap_free(This->path);
121b980bb98SAmine Khaldi heap_free(This->displayname);
122b980bb98SAmine Khaldi heap_free(This->name);
123b980bb98SAmine Khaldi heap_free(This->culture);
124b980bb98SAmine Khaldi heap_free(This->procarch);
125b980bb98SAmine Khaldi heap_free(This);
126c2c66affSColin Finck }
127c2c66affSColin Finck
128c2c66affSColin Finck return refCount;
129c2c66affSColin Finck }
130c2c66affSColin Finck
IAssemblyNameImpl_SetProperty(IAssemblyName * iface,DWORD PropertyId,LPVOID pvProperty,DWORD cbProperty)131c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_SetProperty(IAssemblyName *iface,
132c2c66affSColin Finck DWORD PropertyId,
133c2c66affSColin Finck LPVOID pvProperty,
134c2c66affSColin Finck DWORD cbProperty)
135c2c66affSColin Finck {
136c2c66affSColin Finck FIXME("(%p, %d, %p, %d) stub!\n", iface, PropertyId, pvProperty, cbProperty);
137c2c66affSColin Finck return E_NOTIMPL;
138c2c66affSColin Finck }
139c2c66affSColin Finck
IAssemblyNameImpl_GetProperty(IAssemblyName * iface,DWORD PropertyId,LPVOID pvProperty,LPDWORD pcbProperty)140c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface,
141c2c66affSColin Finck DWORD PropertyId,
142c2c66affSColin Finck LPVOID pvProperty,
143c2c66affSColin Finck LPDWORD pcbProperty)
144c2c66affSColin Finck {
145c2c66affSColin Finck IAssemblyNameImpl *name = impl_from_IAssemblyName(iface);
146975d9d4dSAmine Khaldi DWORD size;
147c2c66affSColin Finck
148c2c66affSColin Finck TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty);
149c2c66affSColin Finck
150975d9d4dSAmine Khaldi size = *pcbProperty;
151c2c66affSColin Finck switch (PropertyId)
152c2c66affSColin Finck {
153c2c66affSColin Finck case ASM_NAME_NULL_PUBLIC_KEY:
154c2c66affSColin Finck case ASM_NAME_NULL_PUBLIC_KEY_TOKEN:
155c2c66affSColin Finck if (name->haspubkey)
156c2c66affSColin Finck return S_OK;
157c2c66affSColin Finck return S_FALSE;
158c2c66affSColin Finck
159c2c66affSColin Finck case ASM_NAME_NULL_CUSTOM:
160c2c66affSColin Finck return S_OK;
161c2c66affSColin Finck
162c2c66affSColin Finck case ASM_NAME_NAME:
163c2c66affSColin Finck *pcbProperty = 0;
164c2c66affSColin Finck if (name->name)
165c2c66affSColin Finck {
166c2c66affSColin Finck *pcbProperty = (lstrlenW(name->name) + 1) * 2;
167975d9d4dSAmine Khaldi if (size < *pcbProperty)
168975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
169975d9d4dSAmine Khaldi lstrcpyW(pvProperty, name->name);
170c2c66affSColin Finck }
171c2c66affSColin Finck break;
172c2c66affSColin Finck
173c2c66affSColin Finck case ASM_NAME_MAJOR_VERSION:
174c2c66affSColin Finck *pcbProperty = 0;
175c2c66affSColin Finck if (name->versize >= 1)
176975d9d4dSAmine Khaldi {
177c2c66affSColin Finck *pcbProperty = sizeof(WORD);
178975d9d4dSAmine Khaldi if (size < *pcbProperty)
179975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
180975d9d4dSAmine Khaldi *((WORD *)pvProperty) = name->version[0];
181975d9d4dSAmine Khaldi }
182c2c66affSColin Finck break;
183c2c66affSColin Finck
184c2c66affSColin Finck case ASM_NAME_MINOR_VERSION:
185c2c66affSColin Finck *pcbProperty = 0;
186c2c66affSColin Finck if (name->versize >= 2)
187975d9d4dSAmine Khaldi {
188c2c66affSColin Finck *pcbProperty = sizeof(WORD);
189975d9d4dSAmine Khaldi if (size < *pcbProperty)
190975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
191975d9d4dSAmine Khaldi *((WORD *)pvProperty) = name->version[1];
192975d9d4dSAmine Khaldi }
193c2c66affSColin Finck break;
194c2c66affSColin Finck
195c2c66affSColin Finck case ASM_NAME_BUILD_NUMBER:
196c2c66affSColin Finck *pcbProperty = 0;
197c2c66affSColin Finck if (name->versize >= 3)
198975d9d4dSAmine Khaldi {
199c2c66affSColin Finck *pcbProperty = sizeof(WORD);
200975d9d4dSAmine Khaldi if (size < *pcbProperty)
201975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
202975d9d4dSAmine Khaldi *((WORD *)pvProperty) = name->version[2];
203975d9d4dSAmine Khaldi }
204c2c66affSColin Finck break;
205c2c66affSColin Finck
206c2c66affSColin Finck case ASM_NAME_REVISION_NUMBER:
207c2c66affSColin Finck *pcbProperty = 0;
208c2c66affSColin Finck if (name->versize >= 4)
209975d9d4dSAmine Khaldi {
210c2c66affSColin Finck *pcbProperty = sizeof(WORD);
211975d9d4dSAmine Khaldi if (size < *pcbProperty)
212975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
213975d9d4dSAmine Khaldi *((WORD *)pvProperty) = name->version[3];
214975d9d4dSAmine Khaldi }
215c2c66affSColin Finck break;
216c2c66affSColin Finck
217c2c66affSColin Finck case ASM_NAME_CULTURE:
218c2c66affSColin Finck *pcbProperty = 0;
219c2c66affSColin Finck if (name->culture)
220c2c66affSColin Finck {
221c2c66affSColin Finck *pcbProperty = (lstrlenW(name->culture) + 1) * 2;
222975d9d4dSAmine Khaldi if (size < *pcbProperty)
223975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
224975d9d4dSAmine Khaldi lstrcpyW(pvProperty, name->culture);
225c2c66affSColin Finck }
226c2c66affSColin Finck break;
227c2c66affSColin Finck
228c2c66affSColin Finck case ASM_NAME_PUBLIC_KEY_TOKEN:
229c2c66affSColin Finck *pcbProperty = 0;
230c2c66affSColin Finck if (name->haspubkey)
231c2c66affSColin Finck {
232c2c66affSColin Finck *pcbProperty = sizeof(DWORD) * 2;
233975d9d4dSAmine Khaldi if (size < *pcbProperty)
234975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
235975d9d4dSAmine Khaldi memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2);
236975d9d4dSAmine Khaldi }
237975d9d4dSAmine Khaldi break;
238975d9d4dSAmine Khaldi
239975d9d4dSAmine Khaldi case ASM_NAME_ARCHITECTURE:
240975d9d4dSAmine Khaldi *pcbProperty = 0;
241975d9d4dSAmine Khaldi if (name->pekind != peNone)
242975d9d4dSAmine Khaldi {
243975d9d4dSAmine Khaldi *pcbProperty = sizeof(PEKIND);
244975d9d4dSAmine Khaldi if (size < *pcbProperty)
245975d9d4dSAmine Khaldi return STRSAFE_E_INSUFFICIENT_BUFFER;
246975d9d4dSAmine Khaldi *((PEKIND *)pvProperty) = name->pekind;
247c2c66affSColin Finck }
248c2c66affSColin Finck break;
249c2c66affSColin Finck
250c2c66affSColin Finck default:
251c2c66affSColin Finck *pcbProperty = 0;
252c2c66affSColin Finck break;
253c2c66affSColin Finck }
254c2c66affSColin Finck
255c2c66affSColin Finck return S_OK;
256c2c66affSColin Finck }
257c2c66affSColin Finck
IAssemblyNameImpl_Finalize(IAssemblyName * iface)258c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_Finalize(IAssemblyName *iface)
259c2c66affSColin Finck {
260c2c66affSColin Finck FIXME("(%p) stub!\n", iface);
261c2c66affSColin Finck return E_NOTIMPL;
262c2c66affSColin Finck }
263c2c66affSColin Finck
IAssemblyNameImpl_GetDisplayName(IAssemblyName * iface,LPOLESTR szDisplayName,LPDWORD pccDisplayName,DWORD dwDisplayFlags)264c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface,
265c2c66affSColin Finck LPOLESTR szDisplayName,
266c2c66affSColin Finck LPDWORD pccDisplayName,
267c2c66affSColin Finck DWORD dwDisplayFlags)
268c2c66affSColin Finck {
269c2c66affSColin Finck static const WCHAR equals[] = {'=',0};
270c2c66affSColin Finck IAssemblyNameImpl *name = impl_from_IAssemblyName(iface);
271c2c66affSColin Finck WCHAR verstr[30], *cultureval = NULL;
272c2c66affSColin Finck DWORD size;
273c2c66affSColin Finck
274c2c66affSColin Finck TRACE("(%p, %p, %p, %d)\n", iface, szDisplayName,
275c2c66affSColin Finck pccDisplayName, dwDisplayFlags);
276c2c66affSColin Finck
277c2c66affSColin Finck if (dwDisplayFlags == 0)
278c2c66affSColin Finck {
279c2c66affSColin Finck if (!name->displayname || !*name->displayname)
280c2c66affSColin Finck return FUSION_E_INVALID_NAME;
281c2c66affSColin Finck
282*88179a5dSAmine Khaldi size = lstrlenW(name->displayname) + 1;
283c2c66affSColin Finck
284c2c66affSColin Finck if (*pccDisplayName < size)
285c2c66affSColin Finck {
286c2c66affSColin Finck *pccDisplayName = size;
287c2c66affSColin Finck return E_NOT_SUFFICIENT_BUFFER;
288c2c66affSColin Finck }
289c2c66affSColin Finck
290*88179a5dSAmine Khaldi if (szDisplayName) lstrcpyW(szDisplayName, name->displayname);
291c2c66affSColin Finck *pccDisplayName = size;
292c2c66affSColin Finck
293c2c66affSColin Finck return S_OK;
294c2c66affSColin Finck }
295c2c66affSColin Finck
296c2c66affSColin Finck if (!name->name || !*name->name)
297c2c66affSColin Finck return FUSION_E_INVALID_NAME;
298c2c66affSColin Finck
299c2c66affSColin Finck /* Verify buffer size is sufficient */
300c2c66affSColin Finck size = lstrlenW(name->name) + 1;
301c2c66affSColin Finck
302c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0))
303c2c66affSColin Finck {
304c2c66affSColin Finck static const WCHAR spec[] = {'%','d',0};
305c2c66affSColin Finck static const WCHAR period[] = {'.',0};
306c2c66affSColin Finck DWORD i;
307c2c66affSColin Finck
308c2c66affSColin Finck wsprintfW(verstr, spec, name->version[0]);
309c2c66affSColin Finck
310c2c66affSColin Finck for (i = 1; i < name->versize; i++)
311c2c66affSColin Finck {
312c2c66affSColin Finck WCHAR value[6];
313c2c66affSColin Finck wsprintfW(value, spec, name->version[i]);
314c2c66affSColin Finck
315c2c66affSColin Finck lstrcatW(verstr, period);
316c2c66affSColin Finck lstrcatW(verstr, value);
317c2c66affSColin Finck }
318c2c66affSColin Finck
319c2c66affSColin Finck size += lstrlenW(separator) + lstrlenW(version) + lstrlenW(equals) + lstrlenW(verstr);
320c2c66affSColin Finck }
321c2c66affSColin Finck
322c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture))
323c2c66affSColin Finck {
324c2c66affSColin Finck static const WCHAR neutral[] = {'n','e','u','t','r','a','l', 0};
325c2c66affSColin Finck
326c2c66affSColin Finck cultureval = (lstrlenW(name->culture) == 2) ? name->culture : (LPWSTR) neutral;
327c2c66affSColin Finck size += lstrlenW(separator) + lstrlenW(culture) + lstrlenW(equals) + lstrlenW(cultureval);
328c2c66affSColin Finck }
329c2c66affSColin Finck
330c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey))
331c2c66affSColin Finck size += lstrlenW(separator) + lstrlenW(pubkey) + lstrlenW(equals) + CHARS_PER_PUBKEY;
332c2c66affSColin Finck
333c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch))
334c2c66affSColin Finck size += lstrlenW(separator) + lstrlenW(procarch) + lstrlenW(equals) + lstrlenW(name->procarch);
335c2c66affSColin Finck
336c2c66affSColin Finck if (size > *pccDisplayName)
337975d9d4dSAmine Khaldi {
338975d9d4dSAmine Khaldi *pccDisplayName = size;
339975d9d4dSAmine Khaldi return E_NOT_SUFFICIENT_BUFFER;
340975d9d4dSAmine Khaldi }
341c2c66affSColin Finck
342c2c66affSColin Finck /* Construct the string */
343c2c66affSColin Finck lstrcpyW(szDisplayName, name->name);
344c2c66affSColin Finck
345c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0))
346c2c66affSColin Finck {
347c2c66affSColin Finck lstrcatW(szDisplayName, separator);
348c2c66affSColin Finck
349c2c66affSColin Finck lstrcatW(szDisplayName, version);
350c2c66affSColin Finck lstrcatW(szDisplayName, equals);
351c2c66affSColin Finck lstrcatW(szDisplayName, verstr);
352c2c66affSColin Finck }
353c2c66affSColin Finck
354c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture))
355c2c66affSColin Finck {
356c2c66affSColin Finck lstrcatW(szDisplayName, separator);
357c2c66affSColin Finck
358c2c66affSColin Finck lstrcatW(szDisplayName, culture);
359c2c66affSColin Finck lstrcatW(szDisplayName, equals);
360c2c66affSColin Finck lstrcatW(szDisplayName, cultureval);
361c2c66affSColin Finck }
362c2c66affSColin Finck
363c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey))
364c2c66affSColin Finck {
365c2c66affSColin Finck WCHAR pkt[CHARS_PER_PUBKEY + 1];
366975d9d4dSAmine Khaldi static const WCHAR spec[] = {'%','0','2','x','%','0','2','x','%','0','2','x',
367975d9d4dSAmine Khaldi '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',0};
368c2c66affSColin Finck
369c2c66affSColin Finck lstrcatW(szDisplayName, separator);
370c2c66affSColin Finck
371c2c66affSColin Finck lstrcatW(szDisplayName, pubkey);
372c2c66affSColin Finck lstrcatW(szDisplayName, equals);
373c2c66affSColin Finck
374c2c66affSColin Finck wsprintfW(pkt, spec, name->pubkey[0], name->pubkey[1], name->pubkey[2],
375c2c66affSColin Finck name->pubkey[3], name->pubkey[4], name->pubkey[5], name->pubkey[6],
376c2c66affSColin Finck name->pubkey[7]);
377c2c66affSColin Finck
378c2c66affSColin Finck lstrcatW(szDisplayName, pkt);
379c2c66affSColin Finck }
380c2c66affSColin Finck
381c2c66affSColin Finck if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch))
382c2c66affSColin Finck {
383c2c66affSColin Finck lstrcatW(szDisplayName, separator);
384c2c66affSColin Finck
385c2c66affSColin Finck lstrcatW(szDisplayName, procarch);
386c2c66affSColin Finck lstrcatW(szDisplayName, equals);
387c2c66affSColin Finck lstrcatW(szDisplayName, name->procarch);
388c2c66affSColin Finck }
389c2c66affSColin Finck
390c2c66affSColin Finck *pccDisplayName = size;
391c2c66affSColin Finck return S_OK;
392c2c66affSColin Finck }
393c2c66affSColin Finck
IAssemblyNameImpl_Reserved(IAssemblyName * iface,REFIID refIID,IUnknown * pUnkReserved1,IUnknown * pUnkReserved2,LPCOLESTR szReserved,LONGLONG llReserved,LPVOID pvReserved,DWORD cbReserved,LPVOID * ppReserved)394c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_Reserved(IAssemblyName *iface,
395c2c66affSColin Finck REFIID refIID,
396c2c66affSColin Finck IUnknown *pUnkReserved1,
397c2c66affSColin Finck IUnknown *pUnkReserved2,
398c2c66affSColin Finck LPCOLESTR szReserved,
399c2c66affSColin Finck LONGLONG llReserved,
400c2c66affSColin Finck LPVOID pvReserved,
401c2c66affSColin Finck DWORD cbReserved,
402c2c66affSColin Finck LPVOID *ppReserved)
403c2c66affSColin Finck {
404c2c66affSColin Finck TRACE("(%p, %s, %p, %p, %s, %s, %p, %d, %p)\n", iface,
405c2c66affSColin Finck debugstr_guid(refIID), pUnkReserved1, pUnkReserved2,
406c2c66affSColin Finck debugstr_w(szReserved), wine_dbgstr_longlong(llReserved),
407c2c66affSColin Finck pvReserved, cbReserved, ppReserved);
408c2c66affSColin Finck
409c2c66affSColin Finck return E_NOTIMPL;
410c2c66affSColin Finck }
411c2c66affSColin Finck
IAssemblyNameImpl_GetName(IAssemblyName * iface,LPDWORD lpcwBuffer,WCHAR * pwzName)412c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_GetName(IAssemblyName *iface,
413c2c66affSColin Finck LPDWORD lpcwBuffer,
414c2c66affSColin Finck WCHAR *pwzName)
415c2c66affSColin Finck {
416c2c66affSColin Finck IAssemblyNameImpl *name = impl_from_IAssemblyName(iface);
417c2c66affSColin Finck DWORD len;
418c2c66affSColin Finck
419c2c66affSColin Finck TRACE("(%p, %p, %p)\n", iface, lpcwBuffer, pwzName);
420c2c66affSColin Finck
421c2c66affSColin Finck if (name->name)
422*88179a5dSAmine Khaldi len = lstrlenW(name->name) + 1;
423c2c66affSColin Finck else
424c2c66affSColin Finck len = 0;
425c2c66affSColin Finck
426c2c66affSColin Finck if (*lpcwBuffer < len)
427c2c66affSColin Finck {
428c2c66affSColin Finck *lpcwBuffer = len;
429c2c66affSColin Finck return E_NOT_SUFFICIENT_BUFFER;
430c2c66affSColin Finck }
431c2c66affSColin Finck if (!name->name) lpcwBuffer[0] = 0;
432*88179a5dSAmine Khaldi else lstrcpyW(pwzName, name->name);
433c2c66affSColin Finck
434c2c66affSColin Finck *lpcwBuffer = len;
435c2c66affSColin Finck return S_OK;
436c2c66affSColin Finck }
437c2c66affSColin Finck
IAssemblyNameImpl_GetVersion(IAssemblyName * iface,LPDWORD pdwVersionHi,LPDWORD pdwVersionLow)438c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_GetVersion(IAssemblyName *iface,
439c2c66affSColin Finck LPDWORD pdwVersionHi,
440c2c66affSColin Finck LPDWORD pdwVersionLow)
441c2c66affSColin Finck {
442c2c66affSColin Finck IAssemblyNameImpl *name = impl_from_IAssemblyName(iface);
443c2c66affSColin Finck
444c2c66affSColin Finck TRACE("(%p, %p, %p)\n", iface, pdwVersionHi, pdwVersionLow);
445c2c66affSColin Finck
446c2c66affSColin Finck *pdwVersionHi = 0;
447c2c66affSColin Finck *pdwVersionLow = 0;
448c2c66affSColin Finck
449c2c66affSColin Finck if (name->versize != 4)
450c2c66affSColin Finck return FUSION_E_INVALID_NAME;
451c2c66affSColin Finck
452c2c66affSColin Finck *pdwVersionHi = (name->version[0] << 16) + name->version[1];
453c2c66affSColin Finck *pdwVersionLow = (name->version[2] << 16) + name->version[3];
454c2c66affSColin Finck
455c2c66affSColin Finck return S_OK;
456c2c66affSColin Finck }
457c2c66affSColin Finck
IAssemblyNameImpl_IsEqual(IAssemblyName * iface,IAssemblyName * pName,DWORD flags)458c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_IsEqual(IAssemblyName *iface,
459c2c66affSColin Finck IAssemblyName *pName,
460c2c66affSColin Finck DWORD flags)
461c2c66affSColin Finck {
462c2c66affSColin Finck IAssemblyNameImpl *name1 = impl_from_IAssemblyName(iface);
463c2c66affSColin Finck IAssemblyNameImpl *name2 = impl_from_IAssemblyName(pName);
464c2c66affSColin Finck
465c2c66affSColin Finck TRACE("(%p, %p, 0x%08x)\n", iface, pName, flags);
466c2c66affSColin Finck
467c2c66affSColin Finck if (!pName) return S_FALSE;
468c2c66affSColin Finck if (flags & ~ASM_CMPF_IL_ALL) FIXME("unsupported flags\n");
469c2c66affSColin Finck
470*88179a5dSAmine Khaldi if ((flags & ASM_CMPF_NAME) && lstrcmpW(name1->name, name2->name)) return S_FALSE;
471c2c66affSColin Finck if (name1->versize && name2->versize)
472c2c66affSColin Finck {
473c2c66affSColin Finck if ((flags & ASM_CMPF_MAJOR_VERSION) &&
474c2c66affSColin Finck name1->version[0] != name2->version[0]) return S_FALSE;
475c2c66affSColin Finck if ((flags & ASM_CMPF_MINOR_VERSION) &&
476c2c66affSColin Finck name1->version[1] != name2->version[1]) return S_FALSE;
477c2c66affSColin Finck if ((flags & ASM_CMPF_BUILD_NUMBER) &&
478c2c66affSColin Finck name1->version[2] != name2->version[2]) return S_FALSE;
479c2c66affSColin Finck if ((flags & ASM_CMPF_REVISION_NUMBER) &&
480c2c66affSColin Finck name1->version[3] != name2->version[3]) return S_FALSE;
481c2c66affSColin Finck }
482c2c66affSColin Finck if ((flags & ASM_CMPF_PUBLIC_KEY_TOKEN) &&
483c2c66affSColin Finck name1->haspubkey && name2->haspubkey &&
484c2c66affSColin Finck memcmp(name1->pubkey, name2->pubkey, sizeof(name1->pubkey))) return S_FALSE;
485c2c66affSColin Finck
486c2c66affSColin Finck if ((flags & ASM_CMPF_CULTURE) &&
487c2c66affSColin Finck name1->culture && name2->culture &&
488*88179a5dSAmine Khaldi lstrcmpW(name1->culture, name2->culture)) return S_FALSE;
489c2c66affSColin Finck
490c2c66affSColin Finck return S_OK;
491c2c66affSColin Finck }
492c2c66affSColin Finck
IAssemblyNameImpl_Clone(IAssemblyName * iface,IAssemblyName ** pName)493c2c66affSColin Finck static HRESULT WINAPI IAssemblyNameImpl_Clone(IAssemblyName *iface,
494c2c66affSColin Finck IAssemblyName **pName)
495c2c66affSColin Finck {
496c2c66affSColin Finck FIXME("(%p, %p) stub!\n", iface, pName);
497c2c66affSColin Finck return E_NOTIMPL;
498c2c66affSColin Finck }
499c2c66affSColin Finck
500c2c66affSColin Finck static const IAssemblyNameVtbl AssemblyNameVtbl = {
501c2c66affSColin Finck IAssemblyNameImpl_QueryInterface,
502c2c66affSColin Finck IAssemblyNameImpl_AddRef,
503c2c66affSColin Finck IAssemblyNameImpl_Release,
504c2c66affSColin Finck IAssemblyNameImpl_SetProperty,
505c2c66affSColin Finck IAssemblyNameImpl_GetProperty,
506c2c66affSColin Finck IAssemblyNameImpl_Finalize,
507c2c66affSColin Finck IAssemblyNameImpl_GetDisplayName,
508c2c66affSColin Finck IAssemblyNameImpl_Reserved,
509c2c66affSColin Finck IAssemblyNameImpl_GetName,
510c2c66affSColin Finck IAssemblyNameImpl_GetVersion,
511c2c66affSColin Finck IAssemblyNameImpl_IsEqual,
512c2c66affSColin Finck IAssemblyNameImpl_Clone
513c2c66affSColin Finck };
514c2c66affSColin Finck
515c2c66affSColin Finck /* Internal methods */
unsafe_impl_from_IAssemblyName(IAssemblyName * iface)516c2c66affSColin Finck static inline IAssemblyNameImpl *unsafe_impl_from_IAssemblyName(IAssemblyName *iface)
517c2c66affSColin Finck {
518c2c66affSColin Finck assert(iface->lpVtbl == &AssemblyNameVtbl);
519c2c66affSColin Finck
520c2c66affSColin Finck return impl_from_IAssemblyName(iface);
521c2c66affSColin Finck }
522c2c66affSColin Finck
IAssemblyName_SetPath(IAssemblyName * iface,LPCWSTR path)523c2c66affSColin Finck HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path)
524c2c66affSColin Finck {
525c2c66affSColin Finck IAssemblyNameImpl *name = unsafe_impl_from_IAssemblyName(iface);
526c2c66affSColin Finck
527c2c66affSColin Finck name->path = strdupW(path);
528c2c66affSColin Finck if (!name->path)
529c2c66affSColin Finck return E_OUTOFMEMORY;
530c2c66affSColin Finck
531c2c66affSColin Finck return S_OK;
532c2c66affSColin Finck }
533c2c66affSColin Finck
IAssemblyName_GetPath(IAssemblyName * iface,LPWSTR buf,ULONG * len)534c2c66affSColin Finck HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len)
535c2c66affSColin Finck {
536c2c66affSColin Finck ULONG buffer_size = *len;
537c2c66affSColin Finck IAssemblyNameImpl *name = unsafe_impl_from_IAssemblyName(iface);
538c2c66affSColin Finck
539c2c66affSColin Finck if (!name->path)
540c2c66affSColin Finck return S_OK;
541c2c66affSColin Finck
542c2c66affSColin Finck if (!buf)
543c2c66affSColin Finck buffer_size = 0;
544c2c66affSColin Finck
545c2c66affSColin Finck *len = lstrlenW(name->path) + 1;
546c2c66affSColin Finck
547c2c66affSColin Finck if (*len <= buffer_size)
548c2c66affSColin Finck lstrcpyW(buf, name->path);
549c2c66affSColin Finck else
550c2c66affSColin Finck return E_NOT_SUFFICIENT_BUFFER;
551c2c66affSColin Finck
552c2c66affSColin Finck return S_OK;
553c2c66affSColin Finck }
554c2c66affSColin Finck
parse_version(IAssemblyNameImpl * name,LPWSTR version)555c2c66affSColin Finck static HRESULT parse_version(IAssemblyNameImpl *name, LPWSTR version)
556c2c66affSColin Finck {
557c2c66affSColin Finck LPWSTR beg, end;
558c2c66affSColin Finck int i;
559c2c66affSColin Finck
560c2c66affSColin Finck for (i = 0, beg = version; i < 4; i++)
561c2c66affSColin Finck {
562c2c66affSColin Finck if (!*beg)
563c2c66affSColin Finck return S_OK;
564c2c66affSColin Finck
565*88179a5dSAmine Khaldi end = wcschr(beg, '.');
566c2c66affSColin Finck
567c2c66affSColin Finck if (end) *end = '\0';
568*88179a5dSAmine Khaldi name->version[i] = wcstol(beg, NULL, 10);
569c2c66affSColin Finck name->versize++;
570c2c66affSColin Finck
571c2c66affSColin Finck if (!end && i < 3)
572c2c66affSColin Finck return S_OK;
573c2c66affSColin Finck
574c2c66affSColin Finck beg = end + 1;
575c2c66affSColin Finck }
576c2c66affSColin Finck
577c2c66affSColin Finck return S_OK;
578c2c66affSColin Finck }
579c2c66affSColin Finck
parse_culture(IAssemblyNameImpl * name,LPCWSTR culture)580c2c66affSColin Finck static HRESULT parse_culture(IAssemblyNameImpl *name, LPCWSTR culture)
581c2c66affSColin Finck {
582c2c66affSColin Finck static const WCHAR empty[] = {0};
583c2c66affSColin Finck
584c2c66affSColin Finck if (lstrlenW(culture) == 2)
585c2c66affSColin Finck name->culture = strdupW(culture);
586c2c66affSColin Finck else
587c2c66affSColin Finck name->culture = strdupW(empty);
588c2c66affSColin Finck
589c2c66affSColin Finck return S_OK;
590c2c66affSColin Finck }
591c2c66affSColin Finck
is_hex(WCHAR c)592c2c66affSColin Finck static BOOL is_hex(WCHAR c)
593c2c66affSColin Finck {
594c2c66affSColin Finck return ((c >= 'a' && c <= 'f') ||
595c2c66affSColin Finck (c >= 'A' && c <= 'F') ||
596c2c66affSColin Finck (c >= '0' && c <= '9'));
597c2c66affSColin Finck }
598c2c66affSColin Finck
hextobyte(WCHAR c)599c2c66affSColin Finck static BYTE hextobyte(WCHAR c)
600c2c66affSColin Finck {
601c2c66affSColin Finck if(c >= '0' && c <= '9')
602c2c66affSColin Finck return c - '0';
603c2c66affSColin Finck if(c >= 'A' && c <= 'F')
604c2c66affSColin Finck return c - 'A' + 10;
605c2c66affSColin Finck if(c >= 'a' && c <= 'f')
606c2c66affSColin Finck return c - 'a' + 10;
607c2c66affSColin Finck return 0;
608c2c66affSColin Finck }
609c2c66affSColin Finck
parse_pubkey(IAssemblyNameImpl * name,LPCWSTR pubkey)610c2c66affSColin Finck static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPCWSTR pubkey)
611c2c66affSColin Finck {
612c2c66affSColin Finck int i;
613c2c66affSColin Finck BYTE val;
614c2c66affSColin Finck static const WCHAR nullstr[] = {'n','u','l','l',0};
615c2c66affSColin Finck
616c2c66affSColin Finck if(lstrcmpiW(pubkey, nullstr) == 0)
617c2c66affSColin Finck return FUSION_E_PRIVATE_ASM_DISALLOWED;
618c2c66affSColin Finck
619c2c66affSColin Finck if (lstrlenW(pubkey) < CHARS_PER_PUBKEY)
620c2c66affSColin Finck return FUSION_E_INVALID_NAME;
621c2c66affSColin Finck
622c2c66affSColin Finck for (i = 0; i < CHARS_PER_PUBKEY; i++)
623c2c66affSColin Finck if (!is_hex(pubkey[i]))
624c2c66affSColin Finck return FUSION_E_INVALID_NAME;
625c2c66affSColin Finck
626c2c66affSColin Finck name->haspubkey = TRUE;
627c2c66affSColin Finck
628c2c66affSColin Finck for (i = 0; i < CHARS_PER_PUBKEY; i += 2)
629c2c66affSColin Finck {
630c2c66affSColin Finck val = (hextobyte(pubkey[i]) << 4) + hextobyte(pubkey[i + 1]);
631c2c66affSColin Finck name->pubkey[i / 2] = val;
632c2c66affSColin Finck }
633c2c66affSColin Finck
634c2c66affSColin Finck return S_OK;
635c2c66affSColin Finck }
636c2c66affSColin Finck
parse_procarch(IAssemblyNameImpl * name,LPCWSTR procarch)637975d9d4dSAmine Khaldi static HRESULT parse_procarch(IAssemblyNameImpl *name, LPCWSTR procarch)
638975d9d4dSAmine Khaldi {
639975d9d4dSAmine Khaldi static const WCHAR msilW[] = {'m','s','i','l',0};
640975d9d4dSAmine Khaldi static const WCHAR x86W[] = {'x','8','6',0};
641975d9d4dSAmine Khaldi static const WCHAR ia64W[] = {'i','a','6','4',0};
642975d9d4dSAmine Khaldi static const WCHAR amd64W[] = {'a','m','d','6','4',0};
643975d9d4dSAmine Khaldi
644975d9d4dSAmine Khaldi if (!lstrcmpiW(procarch, msilW))
645975d9d4dSAmine Khaldi name->pekind = peMSIL;
646975d9d4dSAmine Khaldi else if (!lstrcmpiW(procarch, x86W))
647975d9d4dSAmine Khaldi name->pekind = peI386;
648975d9d4dSAmine Khaldi else if (!lstrcmpiW(procarch, ia64W))
649975d9d4dSAmine Khaldi name->pekind = peIA64;
650975d9d4dSAmine Khaldi else if (!lstrcmpiW(procarch, amd64W))
651975d9d4dSAmine Khaldi name->pekind = peAMD64;
652975d9d4dSAmine Khaldi else
653975d9d4dSAmine Khaldi {
654975d9d4dSAmine Khaldi ERR("unrecognized architecture: %s\n", wine_dbgstr_w(procarch));
655975d9d4dSAmine Khaldi return FUSION_E_INVALID_NAME;
656975d9d4dSAmine Khaldi }
657975d9d4dSAmine Khaldi
658975d9d4dSAmine Khaldi return S_OK;
659975d9d4dSAmine Khaldi }
660975d9d4dSAmine Khaldi
parse_value(const WCHAR * str,unsigned int len)661c2c66affSColin Finck static WCHAR *parse_value( const WCHAR *str, unsigned int len )
662c2c66affSColin Finck {
663c2c66affSColin Finck WCHAR *ret;
664c2c66affSColin Finck const WCHAR *p = str;
665c2c66affSColin Finck BOOL quoted = FALSE;
666c2c66affSColin Finck unsigned int i = 0;
667c2c66affSColin Finck
668b980bb98SAmine Khaldi if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
669c2c66affSColin Finck if (*p == '\"')
670c2c66affSColin Finck {
671c2c66affSColin Finck quoted = TRUE;
672c2c66affSColin Finck p++;
673c2c66affSColin Finck }
674c2c66affSColin Finck while (*p && *p != '\"') ret[i++] = *p++;
675c2c66affSColin Finck if ((quoted && *p != '\"') || (!quoted && *p == '\"'))
676c2c66affSColin Finck {
677b980bb98SAmine Khaldi heap_free( ret );
678c2c66affSColin Finck return NULL;
679c2c66affSColin Finck }
680c2c66affSColin Finck ret[i] = 0;
681c2c66affSColin Finck return ret;
682c2c66affSColin Finck }
683c2c66affSColin Finck
parse_display_name(IAssemblyNameImpl * name,LPCWSTR szAssemblyName)684c2c66affSColin Finck static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyName)
685c2c66affSColin Finck {
686c2c66affSColin Finck LPWSTR str, save, ptr, ptr2, value;
687c2c66affSColin Finck HRESULT hr = S_OK;
688c2c66affSColin Finck BOOL done = FALSE;
689c2c66affSColin Finck
690c2c66affSColin Finck if (!szAssemblyName)
691c2c66affSColin Finck return S_OK;
692c2c66affSColin Finck
693c2c66affSColin Finck name->displayname = strdupW(szAssemblyName);
694c2c66affSColin Finck if (!name->displayname)
695c2c66affSColin Finck return E_OUTOFMEMORY;
696c2c66affSColin Finck
697c2c66affSColin Finck str = strdupW(szAssemblyName);
698c2c66affSColin Finck save = str;
699c2c66affSColin Finck if (!str)
700c2c66affSColin Finck {
701c2c66affSColin Finck hr = E_OUTOFMEMORY;
702c2c66affSColin Finck goto done;
703c2c66affSColin Finck }
704c2c66affSColin Finck
705*88179a5dSAmine Khaldi ptr = wcschr(str, ',');
706c2c66affSColin Finck if (ptr) *ptr = '\0';
707c2c66affSColin Finck
708c2c66affSColin Finck /* no ',' but ' ' only */
709*88179a5dSAmine Khaldi if( !ptr && wcschr(str, ' ') )
710c2c66affSColin Finck {
711c2c66affSColin Finck hr = FUSION_E_INVALID_NAME;
712c2c66affSColin Finck goto done;
713c2c66affSColin Finck }
714c2c66affSColin Finck
715c2c66affSColin Finck name->name = strdupW(str);
716c2c66affSColin Finck if (!name->name)
717c2c66affSColin Finck {
718c2c66affSColin Finck hr = E_OUTOFMEMORY;
719c2c66affSColin Finck goto done;
720c2c66affSColin Finck }
721c2c66affSColin Finck
722c2c66affSColin Finck if (!ptr)
723c2c66affSColin Finck goto done;
724c2c66affSColin Finck
725c2c66affSColin Finck str = ptr + 1;
726c2c66affSColin Finck while (!done)
727c2c66affSColin Finck {
728*88179a5dSAmine Khaldi ptr = wcschr(str, '=');
729c2c66affSColin Finck if (!ptr)
730c2c66affSColin Finck {
731c2c66affSColin Finck hr = FUSION_E_INVALID_NAME;
732c2c66affSColin Finck goto done;
733c2c66affSColin Finck }
734c2c66affSColin Finck
735c2c66affSColin Finck *(ptr++) = '\0';
736c2c66affSColin Finck if (!*ptr)
737c2c66affSColin Finck {
738c2c66affSColin Finck hr = FUSION_E_INVALID_NAME;
739c2c66affSColin Finck goto done;
740c2c66affSColin Finck }
741c2c66affSColin Finck
742*88179a5dSAmine Khaldi if (!(ptr2 = wcschr(ptr, ',')))
743c2c66affSColin Finck {
744*88179a5dSAmine Khaldi if (!(ptr2 = wcschr(ptr, '\0')))
745c2c66affSColin Finck {
746c2c66affSColin Finck hr = FUSION_E_INVALID_NAME;
747c2c66affSColin Finck goto done;
748c2c66affSColin Finck }
749c2c66affSColin Finck
750c2c66affSColin Finck done = TRUE;
751c2c66affSColin Finck }
752c2c66affSColin Finck
753c2c66affSColin Finck *ptr2 = '\0';
754c2c66affSColin Finck if (!(value = parse_value( ptr, ptr2 - ptr )))
755c2c66affSColin Finck {
756c2c66affSColin Finck hr = FUSION_E_INVALID_NAME;
757c2c66affSColin Finck goto done;
758c2c66affSColin Finck }
759c2c66affSColin Finck while (*str == ' ') str++;
760c2c66affSColin Finck
761c2c66affSColin Finck if (!lstrcmpiW(str, version))
762c2c66affSColin Finck hr = parse_version( name, value );
763c2c66affSColin Finck else if (!lstrcmpiW(str, culture))
764c2c66affSColin Finck hr = parse_culture( name, value );
765c2c66affSColin Finck else if (!lstrcmpiW(str, pubkey))
766c2c66affSColin Finck hr = parse_pubkey( name, value );
767c2c66affSColin Finck else if (!lstrcmpiW(str, procarch))
768c2c66affSColin Finck {
769c2c66affSColin Finck name->procarch = value;
770c2c66affSColin Finck value = NULL;
771975d9d4dSAmine Khaldi
772975d9d4dSAmine Khaldi hr = parse_procarch( name, name->procarch );
773c2c66affSColin Finck }
774b980bb98SAmine Khaldi heap_free( value );
775c2c66affSColin Finck
776c2c66affSColin Finck if (FAILED(hr))
777c2c66affSColin Finck goto done;
778c2c66affSColin Finck
779c2c66affSColin Finck str = ptr2 + 1;
780c2c66affSColin Finck }
781c2c66affSColin Finck
782c2c66affSColin Finck done:
783b980bb98SAmine Khaldi heap_free(save);
784c2c66affSColin Finck if (FAILED(hr))
785c2c66affSColin Finck {
786b980bb98SAmine Khaldi heap_free(name->displayname);
787b980bb98SAmine Khaldi heap_free(name->name);
788b980bb98SAmine Khaldi heap_free(name->culture);
789b980bb98SAmine Khaldi heap_free(name->procarch);
790c2c66affSColin Finck }
791c2c66affSColin Finck return hr;
792c2c66affSColin Finck }
793c2c66affSColin Finck
794c2c66affSColin Finck /******************************************************************
795c2c66affSColin Finck * CreateAssemblyNameObject (FUSION.@)
796c2c66affSColin Finck */
CreateAssemblyNameObject(IAssemblyName ** ppAssemblyNameObj,LPCWSTR szAssemblyName,DWORD dwFlags,LPVOID pvReserved)797c2c66affSColin Finck HRESULT WINAPI CreateAssemblyNameObject(IAssemblyName **ppAssemblyNameObj,
798c2c66affSColin Finck LPCWSTR szAssemblyName, DWORD dwFlags,
799c2c66affSColin Finck LPVOID pvReserved)
800c2c66affSColin Finck {
801c2c66affSColin Finck IAssemblyNameImpl *name;
802c2c66affSColin Finck HRESULT hr;
803c2c66affSColin Finck
804c2c66affSColin Finck TRACE("(%p, %s, %08x, %p)\n", ppAssemblyNameObj,
805c2c66affSColin Finck debugstr_w(szAssemblyName), dwFlags, pvReserved);
806c2c66affSColin Finck
807c2c66affSColin Finck if (!ppAssemblyNameObj)
808c2c66affSColin Finck return E_INVALIDARG;
809c2c66affSColin Finck
810c2c66affSColin Finck if ((dwFlags & CANOF_PARSE_DISPLAY_NAME) &&
811c2c66affSColin Finck (!szAssemblyName || !*szAssemblyName))
812c2c66affSColin Finck return E_INVALIDARG;
813c2c66affSColin Finck
814b980bb98SAmine Khaldi if (!(name = heap_alloc_zero(sizeof(*name)))) return E_OUTOFMEMORY;
815c2c66affSColin Finck
816c2c66affSColin Finck name->IAssemblyName_iface.lpVtbl = &AssemblyNameVtbl;
817c2c66affSColin Finck name->ref = 1;
818c2c66affSColin Finck
819c2c66affSColin Finck hr = parse_display_name(name, szAssemblyName);
820c2c66affSColin Finck if (FAILED(hr))
821c2c66affSColin Finck {
822b980bb98SAmine Khaldi heap_free(name);
823c2c66affSColin Finck return hr;
824c2c66affSColin Finck }
825c2c66affSColin Finck
826c2c66affSColin Finck *ppAssemblyNameObj = &name->IAssemblyName_iface;
827c2c66affSColin Finck
828c2c66affSColin Finck return S_OK;
829c2c66affSColin Finck }
830