Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenasmname.c
Go to the documentation of this file.
00001 /* 00002 * IAssemblyName implementation 00003 * 00004 * Copyright 2008 James Hawkins 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <stdarg.h> 00022 #include <assert.h> 00023 00024 #define COBJMACROS 00025 #define INITGUID 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "winuser.h" 00030 #include "ole2.h" 00031 #include "guiddef.h" 00032 #include "fusion.h" 00033 #include "corerror.h" 00034 00035 #include "wine/debug.h" 00036 #include "wine/unicode.h" 00037 #include "fusionpriv.h" 00038 00039 WINE_DEFAULT_DEBUG_CHANNEL(fusion); 00040 00041 typedef struct { 00042 IAssemblyName IAssemblyName_iface; 00043 00044 LPWSTR path; 00045 00046 LPWSTR displayname; 00047 LPWSTR name; 00048 LPWSTR culture; 00049 LPWSTR procarch; 00050 00051 WORD version[4]; 00052 DWORD versize; 00053 00054 BYTE pubkey[8]; 00055 BOOL haspubkey; 00056 00057 LONG ref; 00058 } IAssemblyNameImpl; 00059 00060 static const WCHAR separator[] = {',',' ',0}; 00061 static const WCHAR version[] = {'V','e','r','s','i','o','n',0}; 00062 static const WCHAR culture[] = {'C','u','l','t','u','r','e',0}; 00063 static const WCHAR pubkey[] = 00064 {'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0}; 00065 static const WCHAR procarch[] = {'p','r','o','c','e','s','s','o','r', 00066 'A','r','c','h','i','t','e','c','t','u','r','e',0}; 00067 00068 #define CHARS_PER_PUBKEY 16 00069 00070 static inline IAssemblyNameImpl *impl_from_IAssemblyName(IAssemblyName *iface) 00071 { 00072 return CONTAINING_RECORD(iface, IAssemblyNameImpl, IAssemblyName_iface); 00073 } 00074 00075 static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface, 00076 REFIID riid, LPVOID *ppobj) 00077 { 00078 IAssemblyNameImpl *This = impl_from_IAssemblyName(iface); 00079 00080 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); 00081 00082 *ppobj = NULL; 00083 00084 if (IsEqualIID(riid, &IID_IUnknown) || 00085 IsEqualIID(riid, &IID_IAssemblyName)) 00086 { 00087 IUnknown_AddRef(iface); 00088 *ppobj = This; 00089 return S_OK; 00090 } 00091 00092 WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj); 00093 return E_NOINTERFACE; 00094 } 00095 00096 static ULONG WINAPI IAssemblyNameImpl_AddRef(IAssemblyName *iface) 00097 { 00098 IAssemblyNameImpl *This = impl_from_IAssemblyName(iface); 00099 ULONG refCount = InterlockedIncrement(&This->ref); 00100 00101 TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); 00102 00103 return refCount; 00104 } 00105 00106 static ULONG WINAPI IAssemblyNameImpl_Release(IAssemblyName *iface) 00107 { 00108 IAssemblyNameImpl *This = impl_from_IAssemblyName(iface); 00109 ULONG refCount = InterlockedDecrement(&This->ref); 00110 00111 TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); 00112 00113 if (!refCount) 00114 { 00115 HeapFree(GetProcessHeap(), 0, This->path); 00116 HeapFree(GetProcessHeap(), 0, This->displayname); 00117 HeapFree(GetProcessHeap(), 0, This->name); 00118 HeapFree(GetProcessHeap(), 0, This->culture); 00119 HeapFree(GetProcessHeap(), 0, This->procarch); 00120 HeapFree(GetProcessHeap(), 0, This); 00121 } 00122 00123 return refCount; 00124 } 00125 00126 static HRESULT WINAPI IAssemblyNameImpl_SetProperty(IAssemblyName *iface, 00127 DWORD PropertyId, 00128 LPVOID pvProperty, 00129 DWORD cbProperty) 00130 { 00131 FIXME("(%p, %d, %p, %d) stub!\n", iface, PropertyId, pvProperty, cbProperty); 00132 return E_NOTIMPL; 00133 } 00134 00135 static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, 00136 DWORD PropertyId, 00137 LPVOID pvProperty, 00138 LPDWORD pcbProperty) 00139 { 00140 IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); 00141 00142 TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty); 00143 00144 *((LPWSTR)pvProperty) = '\0'; 00145 00146 switch (PropertyId) 00147 { 00148 case ASM_NAME_NULL_PUBLIC_KEY: 00149 case ASM_NAME_NULL_PUBLIC_KEY_TOKEN: 00150 if (name->haspubkey) 00151 return S_OK; 00152 return S_FALSE; 00153 00154 case ASM_NAME_NULL_CUSTOM: 00155 return S_OK; 00156 00157 case ASM_NAME_NAME: 00158 *pcbProperty = 0; 00159 if (name->name) 00160 { 00161 lstrcpyW(pvProperty, name->name); 00162 *pcbProperty = (lstrlenW(name->name) + 1) * 2; 00163 } 00164 break; 00165 00166 case ASM_NAME_MAJOR_VERSION: 00167 *pcbProperty = 0; 00168 *((WORD *)pvProperty) = name->version[0]; 00169 if (name->versize >= 1) 00170 *pcbProperty = sizeof(WORD); 00171 break; 00172 00173 case ASM_NAME_MINOR_VERSION: 00174 *pcbProperty = 0; 00175 *((WORD *)pvProperty) = name->version[1]; 00176 if (name->versize >= 2) 00177 *pcbProperty = sizeof(WORD); 00178 break; 00179 00180 case ASM_NAME_BUILD_NUMBER: 00181 *pcbProperty = 0; 00182 *((WORD *)pvProperty) = name->version[2]; 00183 if (name->versize >= 3) 00184 *pcbProperty = sizeof(WORD); 00185 break; 00186 00187 case ASM_NAME_REVISION_NUMBER: 00188 *pcbProperty = 0; 00189 *((WORD *)pvProperty) = name->version[3]; 00190 if (name->versize >= 4) 00191 *pcbProperty = sizeof(WORD); 00192 break; 00193 00194 case ASM_NAME_CULTURE: 00195 *pcbProperty = 0; 00196 if (name->culture) 00197 { 00198 lstrcpyW(pvProperty, name->culture); 00199 *pcbProperty = (lstrlenW(name->culture) + 1) * 2; 00200 } 00201 break; 00202 00203 case ASM_NAME_PUBLIC_KEY_TOKEN: 00204 *pcbProperty = 0; 00205 if (name->haspubkey) 00206 { 00207 memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2); 00208 *pcbProperty = sizeof(DWORD) * 2; 00209 } 00210 break; 00211 00212 default: 00213 *pcbProperty = 0; 00214 break; 00215 } 00216 00217 return S_OK; 00218 } 00219 00220 static HRESULT WINAPI IAssemblyNameImpl_Finalize(IAssemblyName *iface) 00221 { 00222 FIXME("(%p) stub!\n", iface); 00223 return E_NOTIMPL; 00224 } 00225 00226 static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface, 00227 LPOLESTR szDisplayName, 00228 LPDWORD pccDisplayName, 00229 DWORD dwDisplayFlags) 00230 { 00231 IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); 00232 WCHAR verstr[30]; 00233 DWORD size; 00234 LPWSTR cultureval = 0; 00235 00236 static const WCHAR equals[] = {'=',0}; 00237 00238 TRACE("(%p, %p, %p, %d)\n", iface, szDisplayName, 00239 pccDisplayName, dwDisplayFlags); 00240 00241 if (dwDisplayFlags == 0) 00242 { 00243 if (!name->displayname || !*name->displayname) 00244 return FUSION_E_INVALID_NAME; 00245 00246 size = min(*pccDisplayName, lstrlenW(name->displayname) + 1); 00247 00248 lstrcpynW(szDisplayName, name->displayname, size); 00249 *pccDisplayName = size; 00250 00251 return S_OK; 00252 } 00253 00254 if (!name->name || !*name->name) 00255 return FUSION_E_INVALID_NAME; 00256 00257 /* Verify buffer size is sufficient */ 00258 size = lstrlenW(name->name) + 1; 00259 00260 if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0)) 00261 { 00262 static const WCHAR spec[] = {'%','d',0}; 00263 static const WCHAR period[] = {'.',0}; 00264 int i; 00265 00266 wsprintfW(verstr, spec, name->version[0]); 00267 00268 for (i = 1; i < name->versize; i++) 00269 { 00270 WCHAR value[6]; 00271 wsprintfW(value, spec, name->version[i]); 00272 00273 lstrcatW(verstr, period); 00274 lstrcatW(verstr, value); 00275 } 00276 00277 size += lstrlenW(separator) + lstrlenW(version) + lstrlenW(equals) + lstrlenW(verstr); 00278 } 00279 00280 if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture)) 00281 { 00282 static const WCHAR neutral[] = {'n','e','u','t','r','a','l', 0}; 00283 00284 cultureval = (lstrlenW(name->culture) == 2) ? name->culture : (LPWSTR) neutral; 00285 size += lstrlenW(separator) + lstrlenW(culture) + lstrlenW(equals) + lstrlenW(cultureval); 00286 } 00287 00288 if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey)) 00289 size += lstrlenW(separator) + lstrlenW(pubkey) + lstrlenW(equals) + CHARS_PER_PUBKEY; 00290 00291 if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch)) 00292 size += lstrlenW(separator) + lstrlenW(procarch) + lstrlenW(equals) + lstrlenW(name->procarch); 00293 00294 if (size > *pccDisplayName) 00295 return S_FALSE; 00296 00297 /* Construct the string */ 00298 lstrcpyW(szDisplayName, name->name); 00299 00300 if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0)) 00301 { 00302 lstrcatW(szDisplayName, separator); 00303 00304 lstrcatW(szDisplayName, version); 00305 lstrcatW(szDisplayName, equals); 00306 lstrcatW(szDisplayName, verstr); 00307 } 00308 00309 if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture)) 00310 { 00311 lstrcatW(szDisplayName, separator); 00312 00313 lstrcatW(szDisplayName, culture); 00314 lstrcatW(szDisplayName, equals); 00315 lstrcatW(szDisplayName, cultureval); 00316 } 00317 00318 if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey)) 00319 { 00320 WCHAR pkt[CHARS_PER_PUBKEY + 1]; 00321 static const WCHAR spec[] = {'%','0','x','%','0','x','%','0','x', 00322 '%','0','x','%','0','x','%','0','x','%','0','x','%','0','x',0}; 00323 00324 lstrcatW(szDisplayName, separator); 00325 00326 lstrcatW(szDisplayName, pubkey); 00327 lstrcatW(szDisplayName, equals); 00328 00329 wsprintfW(pkt, spec, name->pubkey[0], name->pubkey[1], name->pubkey[2], 00330 name->pubkey[3], name->pubkey[4], name->pubkey[5], name->pubkey[6], 00331 name->pubkey[7]); 00332 00333 lstrcatW(szDisplayName, pkt); 00334 } 00335 00336 if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch)) 00337 { 00338 lstrcatW(szDisplayName, separator); 00339 00340 lstrcatW(szDisplayName, procarch); 00341 lstrcatW(szDisplayName, equals); 00342 lstrcatW(szDisplayName, name->procarch); 00343 } 00344 00345 *pccDisplayName = size; 00346 return S_OK; 00347 } 00348 00349 static HRESULT WINAPI IAssemblyNameImpl_Reserved(IAssemblyName *iface, 00350 REFIID refIID, 00351 IUnknown *pUnkReserved1, 00352 IUnknown *pUnkReserved2, 00353 LPCOLESTR szReserved, 00354 LONGLONG llReserved, 00355 LPVOID pvReserved, 00356 DWORD cbReserved, 00357 LPVOID *ppReserved) 00358 { 00359 TRACE("(%p, %s, %p, %p, %s, %x%08x, %p, %d, %p)\n", iface, 00360 debugstr_guid(refIID), pUnkReserved1, pUnkReserved2, 00361 debugstr_w(szReserved), (DWORD)(llReserved >> 32), (DWORD)llReserved, 00362 pvReserved, cbReserved, ppReserved); 00363 00364 return E_NOTIMPL; 00365 } 00366 00367 static HRESULT WINAPI IAssemblyNameImpl_GetName(IAssemblyName *iface, 00368 LPDWORD lpcwBuffer, 00369 WCHAR *pwzName) 00370 { 00371 IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); 00372 00373 TRACE("(%p, %p, %p)\n", iface, lpcwBuffer, pwzName); 00374 00375 if (!name->name) 00376 { 00377 *pwzName = '\0'; 00378 *lpcwBuffer = 0; 00379 return S_OK; 00380 } 00381 00382 lstrcpyW(pwzName, name->name); 00383 *lpcwBuffer = lstrlenW(pwzName) + 1; 00384 00385 return S_OK; 00386 } 00387 00388 static HRESULT WINAPI IAssemblyNameImpl_GetVersion(IAssemblyName *iface, 00389 LPDWORD pdwVersionHi, 00390 LPDWORD pdwVersionLow) 00391 { 00392 IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); 00393 00394 TRACE("(%p, %p, %p)\n", iface, pdwVersionHi, pdwVersionLow); 00395 00396 *pdwVersionHi = 0; 00397 *pdwVersionLow = 0; 00398 00399 if (name->versize != 4) 00400 return FUSION_E_INVALID_NAME; 00401 00402 *pdwVersionHi = (name->version[0] << 16) + name->version[1]; 00403 *pdwVersionLow = (name->version[2] << 16) + name->version[3]; 00404 00405 return S_OK; 00406 } 00407 00408 static HRESULT WINAPI IAssemblyNameImpl_IsEqual(IAssemblyName *iface, 00409 IAssemblyName *pName, 00410 DWORD dwCmpFlags) 00411 { 00412 FIXME("(%p, %p, %d) stub!\n", iface, pName, dwCmpFlags); 00413 return E_NOTIMPL; 00414 } 00415 00416 static HRESULT WINAPI IAssemblyNameImpl_Clone(IAssemblyName *iface, 00417 IAssemblyName **pName) 00418 { 00419 FIXME("(%p, %p) stub!\n", iface, pName); 00420 return E_NOTIMPL; 00421 } 00422 00423 static const IAssemblyNameVtbl AssemblyNameVtbl = { 00424 IAssemblyNameImpl_QueryInterface, 00425 IAssemblyNameImpl_AddRef, 00426 IAssemblyNameImpl_Release, 00427 IAssemblyNameImpl_SetProperty, 00428 IAssemblyNameImpl_GetProperty, 00429 IAssemblyNameImpl_Finalize, 00430 IAssemblyNameImpl_GetDisplayName, 00431 IAssemblyNameImpl_Reserved, 00432 IAssemblyNameImpl_GetName, 00433 IAssemblyNameImpl_GetVersion, 00434 IAssemblyNameImpl_IsEqual, 00435 IAssemblyNameImpl_Clone 00436 }; 00437 00438 /* Internal methods */ 00439 static inline IAssemblyNameImpl *unsafe_impl_from_IAssemblyName(IAssemblyName *iface) 00440 { 00441 assert(iface->lpVtbl == &AssemblyNameVtbl); 00442 00443 return impl_from_IAssemblyName(iface); 00444 } 00445 00446 HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path) 00447 { 00448 IAssemblyNameImpl *name = unsafe_impl_from_IAssemblyName(iface); 00449 00450 name->path = strdupW(path); 00451 if (!name->path) 00452 return E_OUTOFMEMORY; 00453 00454 return S_OK; 00455 } 00456 00457 HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len) 00458 { 00459 ULONG buffer_size = *len; 00460 IAssemblyNameImpl *name = unsafe_impl_from_IAssemblyName(iface); 00461 00462 if (!name->path) 00463 return S_OK; 00464 00465 if (!buf) 00466 buffer_size = 0; 00467 00468 *len = lstrlenW(name->path) + 1; 00469 00470 if (*len <= buffer_size) 00471 lstrcpyW(buf, name->path); 00472 else 00473 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00474 00475 return S_OK; 00476 } 00477 00478 static HRESULT parse_version(IAssemblyNameImpl *name, LPWSTR version) 00479 { 00480 LPWSTR beg, end; 00481 int i; 00482 00483 for (i = 0, beg = version; i < 4; i++) 00484 { 00485 if (!*beg) 00486 return S_OK; 00487 00488 end = strchrW(beg, '.'); 00489 00490 if (end) *end = '\0'; 00491 name->version[i] = atolW(beg); 00492 name->versize++; 00493 00494 if (!end && i < 3) 00495 return S_OK; 00496 00497 beg = end + 1; 00498 } 00499 00500 return S_OK; 00501 } 00502 00503 static HRESULT parse_culture(IAssemblyNameImpl *name, LPCWSTR culture) 00504 { 00505 static const WCHAR empty[] = {0}; 00506 00507 if (lstrlenW(culture) == 2) 00508 name->culture = strdupW(culture); 00509 else 00510 name->culture = strdupW(empty); 00511 00512 return S_OK; 00513 } 00514 00515 static BOOL is_hex(WCHAR c) 00516 { 00517 return ((c >= 'a' && c <= 'f') || 00518 (c >= 'A' && c <= 'F') || 00519 (c >= '0' && c <= '9')); 00520 } 00521 00522 static BYTE hextobyte(WCHAR c) 00523 { 00524 if(c >= '0' && c <= '9') 00525 return c - '0'; 00526 if(c >= 'A' && c <= 'F') 00527 return c - 'A' + 10; 00528 if(c >= 'a' && c <= 'f') 00529 return c - 'a' + 10; 00530 return 0; 00531 } 00532 00533 static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPCWSTR pubkey) 00534 { 00535 int i; 00536 BYTE val; 00537 00538 if (lstrlenW(pubkey) < CHARS_PER_PUBKEY) 00539 return FUSION_E_INVALID_NAME; 00540 00541 for (i = 0; i < CHARS_PER_PUBKEY; i++) 00542 if (!is_hex(pubkey[i])) 00543 return FUSION_E_INVALID_NAME; 00544 00545 name->haspubkey = TRUE; 00546 00547 for (i = 0; i < CHARS_PER_PUBKEY; i += 2) 00548 { 00549 val = (hextobyte(pubkey[i]) << 4) + hextobyte(pubkey[i + 1]); 00550 name->pubkey[i / 2] = val; 00551 } 00552 00553 return S_OK; 00554 } 00555 00556 static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyName) 00557 { 00558 LPWSTR str, save; 00559 LPWSTR ptr, ptr2; 00560 HRESULT hr = S_OK; 00561 BOOL done = FALSE; 00562 00563 if (!szAssemblyName) 00564 return S_OK; 00565 00566 name->displayname = strdupW(szAssemblyName); 00567 if (!name->displayname) 00568 return E_OUTOFMEMORY; 00569 00570 str = strdupW(szAssemblyName); 00571 save = str; 00572 if (!str) 00573 { 00574 hr = E_OUTOFMEMORY; 00575 goto done; 00576 } 00577 00578 ptr = strchrW(str, ','); 00579 if (ptr) *ptr = '\0'; 00580 00581 /* no ',' but ' ' only */ 00582 if( !ptr && strchrW(str, ' ') ) 00583 { 00584 hr = FUSION_E_INVALID_NAME; 00585 goto done; 00586 } 00587 00588 name->name = strdupW(str); 00589 if (!name->name) 00590 { 00591 hr = E_OUTOFMEMORY; 00592 goto done; 00593 } 00594 00595 if (!ptr) 00596 goto done; 00597 00598 str = ptr + 2; 00599 while (!done) 00600 { 00601 ptr = strchrW(str, '='); 00602 if (!ptr) 00603 { 00604 hr = FUSION_E_INVALID_NAME; 00605 goto done; 00606 } 00607 00608 *(ptr++) = '\0'; 00609 if (!*ptr) 00610 { 00611 hr = FUSION_E_INVALID_NAME; 00612 goto done; 00613 } 00614 00615 if (!(ptr2 = strstrW(ptr, separator))) 00616 { 00617 if (!(ptr2 = strchrW(ptr, '\0'))) 00618 { 00619 hr = FUSION_E_INVALID_NAME; 00620 goto done; 00621 } 00622 00623 done = TRUE; 00624 } 00625 00626 *ptr2 = '\0'; 00627 00628 while (*str == ' ') str++; 00629 00630 if (!lstrcmpW(str, version)) 00631 hr = parse_version(name, ptr); 00632 else if (!lstrcmpW(str, culture)) 00633 hr = parse_culture(name, ptr); 00634 else if (!lstrcmpW(str, pubkey)) 00635 hr = parse_pubkey(name, ptr); 00636 else if (!lstrcmpW(str, procarch)) 00637 { 00638 name->procarch = strdupW(ptr); 00639 if (!name->procarch) 00640 hr = E_OUTOFMEMORY; 00641 } 00642 00643 if (FAILED(hr)) 00644 goto done; 00645 00646 str = ptr2 + 1; 00647 } 00648 00649 done: 00650 HeapFree(GetProcessHeap(), 0, save); 00651 if (FAILED(hr)) 00652 { 00653 HeapFree(GetProcessHeap(), 0, name->displayname); 00654 HeapFree(GetProcessHeap(), 0, name->name); 00655 } 00656 return hr; 00657 } 00658 00659 /****************************************************************** 00660 * CreateAssemblyNameObject (FUSION.@) 00661 */ 00662 HRESULT WINAPI CreateAssemblyNameObject(LPASSEMBLYNAME *ppAssemblyNameObj, 00663 LPCWSTR szAssemblyName, DWORD dwFlags, 00664 LPVOID pvReserved) 00665 { 00666 IAssemblyNameImpl *name; 00667 HRESULT hr; 00668 00669 TRACE("(%p, %s, %08x, %p)\n", ppAssemblyNameObj, 00670 debugstr_w(szAssemblyName), dwFlags, pvReserved); 00671 00672 if (!ppAssemblyNameObj) 00673 return E_INVALIDARG; 00674 00675 if ((dwFlags & CANOF_PARSE_DISPLAY_NAME) && 00676 (!szAssemblyName || !*szAssemblyName)) 00677 return E_INVALIDARG; 00678 00679 name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAssemblyNameImpl)); 00680 if (!name) 00681 return E_OUTOFMEMORY; 00682 00683 name->IAssemblyName_iface.lpVtbl = &AssemblyNameVtbl; 00684 name->ref = 1; 00685 00686 hr = parse_display_name(name, szAssemblyName); 00687 if (FAILED(hr)) 00688 { 00689 HeapFree(GetProcessHeap(), 0, name); 00690 return hr; 00691 } 00692 00693 *ppAssemblyNameObj = &name->IAssemblyName_iface; 00694 00695 return S_OK; 00696 } Generated on Sun May 27 2012 04:23:33 for ReactOS by
1.7.6.1
|