xref: /reactos/dll/win32/fusion/asmname.c (revision 88179a5d)
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