HRESULT FusionBind::ParseName() { HRESULT hr = S_OK; if (m_fParsed || !m_pAssemblyName) return S_OK; TIMELINE_START(FUSIONBIND, ("ParseName %s", m_pAssemblyName)); IAssemblyName *pName; CQuickBytes qb; long pwNameLen = WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, 0, 0); LPWSTR pwName = (LPWSTR) qb.Alloc(pwNameLen*sizeof(WCHAR)); WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, pwName, pwNameLen); IfFailRet(CreateAssemblyNameObject(&pName, pwName, CANOF_PARSE_DISPLAY_NAME, NULL)); if (m_ownedFlags & NAME_OWNED) delete [] m_pAssemblyName; m_pAssemblyName = NULL; hr = Init(pName); pName->Release(); TIMELINE_END(FUSIONBIND, ("ParseName %s", m_pAssemblyName)); return hr; }
HRESULT FusionBind::CreateFusionContext(LPCWSTR pzName, IApplicationContext** ppFusionContext) { TIMELINE_START(FUSIONBIND, ("CreateFusionContext %S", pzName)); _ASSERTE(ppFusionContext); // This is a file name not a namespace LPCWSTR contextName = NULL; if(pzName) { contextName = wcsrchr( pzName, L'\\' ); if(contextName) contextName++; else contextName = pzName; } // We go off and create a fusion context for this application domain. // Note, once it is made it can not be modified. IAssemblyName *pFusionAssemblyName = NULL; HRESULT hr = CreateAssemblyNameObject(&pFusionAssemblyName, contextName, 0, NULL); if(SUCCEEDED(hr)) { hr = CreateApplicationContext(pFusionAssemblyName, ppFusionContext); pFusionAssemblyName->Release(); } if(pzName) TIMELINE_END(FUSIONBIND, ("CreateFusionContext %S", pzName)); else TIMELINE_END(FUSIONBIND, ("CreateFusionContext <unknown>")); return hr; }
static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszAssemblyName, ASSEMBLY_INFO *pAsmInfo) { IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); IAssemblyName *asmname, *next = NULL; IAssemblyEnum *asmenum = NULL; HRESULT hr; TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, debugstr_w(pszAssemblyName), pAsmInfo); if (pAsmInfo) { if (pAsmInfo->cbAssemblyInfo == 0) pAsmInfo->cbAssemblyInfo = sizeof(ASSEMBLY_INFO); else if (pAsmInfo->cbAssemblyInfo != sizeof(ASSEMBLY_INFO)) return E_INVALIDARG; } hr = CreateAssemblyNameObject(&asmname, pszAssemblyName, CANOF_PARSE_DISPLAY_NAME, NULL); if (FAILED(hr)) return hr; cache_lock( cache ); hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL); if (FAILED(hr)) goto done; for (;;) { hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0); if (hr != S_OK) { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); goto done; } hr = IAssemblyName_IsEqual(asmname, next, ASM_CMPF_IL_ALL); if (hr == S_OK) break; } if (!pAsmInfo) goto done; hr = IAssemblyName_GetPath(next, pAsmInfo->pszCurrentAssemblyPathBuf, &pAsmInfo->cchBuf); pAsmInfo->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED; done: IAssemblyName_Release(asmname); if (next) IAssemblyName_Release(next); if (asmenum) IAssemblyEnum_Release(asmenum); cache_unlock( cache ); return hr; }
HRESULT FusionBind::CreateFusionName(IAssemblyName **ppName, BOOL fIncludeHash) { TIMELINE_START(FUSIONBIND, ("CreateFusionName %s", m_pAssemblyName)); HRESULT hr; IAssemblyName *pFusionAssemblyName = NULL; LPWSTR pwAssemblyName = NULL; CQuickBytes qb; if (m_pAssemblyName) { long pwNameLen = WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, 0, 0); pwAssemblyName = (LPWSTR) qb.Alloc(pwNameLen*sizeof(WCHAR)); WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, pwAssemblyName, pwNameLen); } IfFailGo(CreateAssemblyNameObject(&pFusionAssemblyName, pwAssemblyName, m_fParsed || (!pwAssemblyName) ? 0 : CANOF_PARSE_DISPLAY_NAME, NULL)); if (m_fParsed) { if (m_context.usMajorVersion != (USHORT) -1) { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_MAJOR_VERSION, &m_context.usMajorVersion, sizeof(USHORT))); if (m_context.usMinorVersion != (USHORT) -1) { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_MINOR_VERSION, &m_context.usMinorVersion, sizeof(USHORT))); if (m_context.usBuildNumber != (USHORT) -1) { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_BUILD_NUMBER, &m_context.usBuildNumber, sizeof(USHORT))); if (m_context.usRevisionNumber != (USHORT) -1) IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_REVISION_NUMBER, &m_context.usRevisionNumber, sizeof(USHORT))); } } } if (m_context.szLocale) { MAKE_WIDEPTR_FROMUTF8(pwLocale,m_context.szLocale); IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_CULTURE, pwLocale, (DWORD)(wcslen(pwLocale) + 1) * sizeof (WCHAR))); } if (m_pbPublicKeyOrToken) { if (m_cbPublicKeyOrToken) { if(m_dwFlags & afPublicKey) { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY, m_pbPublicKeyOrToken, m_cbPublicKeyOrToken)); } else { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_pbPublicKeyOrToken, m_cbPublicKeyOrToken)); } } else { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN, NULL, 0)); } } } if (m_CodeInfo.m_dwCodeBase > 0) { IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_CODEBASE_URL, (void*)m_CodeInfo.m_pszCodeBase, m_CodeInfo.m_dwCodeBase*sizeof(WCHAR))); } *ppName = pFusionAssemblyName; TIMELINE_END(FUSIONBIND, ("CreateFusionName %s", m_pAssemblyName)); return S_OK; ErrExit: if (pFusionAssemblyName) pFusionAssemblyName->Release(); TIMELINE_END(FUSIONBIND, ("CreateFusionName %s", m_pAssemblyName)); return hr; }
void AsmMan::EndAssembly() { if(m_pCurAsmRef) { if(m_pCurAsmRef->isRef) { // list the assembly ref if(GetAsmRefByName(m_pCurAsmRef->szAlias)) { //report->warn("Multiple declarations of Assembly Ref '%s', ignored except the 1st one\n",m_pCurAsmRef->szName); delete m_pCurAsmRef; m_pCurAsmRef = NULL; return; } if(m_pCurAsmRef->isAutodetect) { IAssemblyName* pIAsmName; HRESULT hr; // Convert name to Unicode WszMultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf); hr = CreateAssemblyNameObject(&pIAsmName,wzUniBuf,CANOF_PARSE_DISPLAY_NAME,NULL); if(SUCCEEDED(hr)) { // set enumeration criteria: what is known about AsmRef (besides name) if(m_pCurAsmRef->usVerMajor != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,&(m_pCurAsmRef->usVerMajor),2); if(m_pCurAsmRef->usVerMinor != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_MINOR_VERSION,&(m_pCurAsmRef->usVerMinor),2); if(m_pCurAsmRef->usBuild != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,&(m_pCurAsmRef->usBuild),2); if(m_pCurAsmRef->usRevision != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,&(m_pCurAsmRef->usRevision),2); if(m_pCurAsmRef->pPublicKeyToken) pIAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_pCurAsmRef->pPublicKeyToken->ptr(), m_pCurAsmRef->pPublicKeyToken->length()); if(m_pCurAsmRef->pLocale) pIAsmName->SetProperty(ASM_NAME_CULTURE, m_pCurAsmRef->pLocale->ptr(), m_pCurAsmRef->pLocale->length()); // enumerate assemblies IAssemblyEnum* pIAsmEnum = NULL; hr = CreateAssemblyEnum(&pIAsmEnum, NULL, pIAsmName, ASM_CACHE_GAC, NULL); if(SUCCEEDED(hr)) { IAssemblyName* pIAsmNameFound; IAssemblyName* pIAsmNameLatestVer = NULL; ULONGLONG ullVer=0, ullVerLatest=0; DWORD dwVerHi, dwVerLo; // find the latest and greatest, if any for(;;) { pIAsmNameFound = NULL; hr = pIAsmEnum->GetNextAssembly(NULL,&pIAsmNameFound,0); if(SUCCEEDED(hr) && pIAsmNameFound) { pIAsmNameFound->GetVersion(&dwVerHi,&dwVerLo); ullVer = (ULONGLONG)dwVerHi; ullVer <<= sizeof(DWORD); ullVer |= dwVerLo; if(ullVer > ullVerLatest) { if(pIAsmNameLatestVer) pIAsmNameLatestVer->Release(); ullVerLatest = ullVer; pIAsmNameLatestVer = pIAsmNameFound; } else pIAsmNameFound->Release(); } else break; } // if found, fill the gaps if(pIAsmNameLatestVer) { DWORD cbSize=0; USHORT usDummy=0; if(m_pCurAsmRef->pPublicKeyToken == NULL) { cbSize = 1024; pIAsmNameLatestVer->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, wzUniBuf, &cbSize); if(cbSize) { if((m_pCurAsmRef->pPublicKeyToken = new BinStr())) memcpy(m_pCurAsmRef->pPublicKeyToken->getBuff(cbSize), wzUniBuf, cbSize); } } if(m_pCurAsmRef->usVerMajor == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_MAJOR_VERSION, &usDummy, &cbSize); m_pCurAsmRef->usVerMajor = usDummy; } if(m_pCurAsmRef->usVerMinor == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_MINOR_VERSION, &usDummy, &cbSize); m_pCurAsmRef->usVerMinor = usDummy; } if(m_pCurAsmRef->usBuild == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_BUILD_NUMBER, &usDummy, &cbSize); m_pCurAsmRef->usBuild = usDummy; } if(m_pCurAsmRef->usRevision == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_REVISION_NUMBER, &usDummy, &cbSize); m_pCurAsmRef->usRevision = usDummy; } if(m_pCurAsmRef->pLocale == NULL) { cbSize = 1024; pIAsmNameLatestVer->GetProperty(ASM_NAME_CULTURE, wzUniBuf, &cbSize); if(cbSize > (DWORD)sizeof(WCHAR)) { if((m_pCurAsmRef->pLocale = new BinStr())) memcpy(m_pCurAsmRef->pLocale->getBuff(cbSize), wzUniBuf, cbSize); } } pIAsmNameLatestVer->Release(); } else report->warn("Failed to autodetect assembly '%s'\n",m_pCurAsmRef->szName); // if no assembly found, leave it as is, it might be not a GAC assembly pIAsmEnum->Release(); } else report->error("Failed to enum assemblies %S, hr=0x%08X\n",wzUniBuf,hr); pIAsmName->Release(); } else report->error("Failed to create assembly name object for %S, hr=0x%08X\n",wzUniBuf,hr); } // end if isAutodetect m_AsmRefLst.PUSH(m_pCurAsmRef); m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef); } else { HRESULT hr = S_OK; m_pCurAsmRef->tkTok = TokenFromRid(1,mdtAssembly); // Determine the strong name public key. This may have been set // via a directive in the source or from the command line (which // overrides the directive). From the command line we may have // been provided with a file or the name of a CAPI key // container. Either may contain a public key or a full key // pair. if (((Assembler*)m_pAssembler)->m_wzKeySourceName) { { // Read public key or key pair from file. HANDLE hFile = WszCreateFile(((Assembler*)m_pAssembler)->m_wzKeySourceName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFile == INVALID_HANDLE_VALUE) { hr = GetLastError(); report->error("Failed to open key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr); m_pCurAsmRef = NULL; return; } // Determine file size and allocate an appropriate buffer. m_sStrongName.m_cbPublicKey = SafeGetFileSize(hFile, NULL); if (m_sStrongName.m_cbPublicKey == 0xffffffff) { report->error("File size too large\n"); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } m_sStrongName.m_pbPublicKey = new BYTE[m_sStrongName.m_cbPublicKey]; if (m_sStrongName.m_pbPublicKey == NULL) { report->error("Failed to allocate key buffer\n"); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } m_sStrongName.m_dwPublicKeyAllocated = 2; // Read the file into the buffer. DWORD dwBytesRead; if (!ReadFile(hFile, m_sStrongName.m_pbPublicKey, m_sStrongName.m_cbPublicKey, &dwBytesRead, NULL)) { hr = GetLastError(); report->error("Failed to read key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } CloseHandle(hFile); // Guess whether we're full or delay signing based on // whether the blob passed to us looks like a public // key. (I.e. we may just have copied a full key pair // into the public key buffer). if (m_sStrongName.m_cbPublicKey >= sizeof(PublicKeyBlob) && (offsetof(PublicKeyBlob, PublicKey) + ((PublicKeyBlob*)m_sStrongName.m_pbPublicKey)->cbPublicKey) == m_sStrongName.m_cbPublicKey) m_sStrongName.m_fFullSign = FALSE; else m_sStrongName.m_fFullSign = TRUE; // If we really have a key pair, we'll move it into a // key container so the signing code gets the key pair // from a consistent place. if (m_sStrongName.m_fFullSign) { m_sStrongName.m_pbPrivateKey = m_sStrongName.m_pbPublicKey; m_sStrongName.m_cbPrivateKey = m_sStrongName.m_cbPublicKey; m_sStrongName.m_pbPublicKey = NULL; m_sStrongName.m_cbPublicKey = NULL; m_sStrongName.m_dwPublicKeyAllocated = 0; // Retrieve the public key portion as a byte blob. if (!StrongNameGetPublicKey(NULL, m_sStrongName.m_pbPrivateKey, m_sStrongName.m_cbPrivateKey, &m_sStrongName.m_pbPublicKey, &m_sStrongName.m_cbPublicKey)) { hr = StrongNameErrorInfo(); report->error("Failed to extract public key: 0x%08X\n",hr); m_pCurAsmRef = NULL; return; } m_sStrongName.m_dwPublicKeyAllocated = 2; } } } else if (m_pAssembly->pPublicKey) { m_sStrongName.m_pbPublicKey = m_pAssembly->pPublicKey->ptr(); m_sStrongName.m_cbPublicKey = m_pAssembly->pPublicKey->length(); m_sStrongName.m_wzKeyContainer = NULL; m_sStrongName.m_fFullSign = FALSE; m_sStrongName.m_dwPublicKeyAllocated = 0; } else { m_sStrongName.m_pbPublicKey = NULL; m_sStrongName.m_cbPublicKey = 0; m_sStrongName.m_wzKeyContainer = NULL; m_sStrongName.m_fFullSign = FALSE; m_sStrongName.m_dwPublicKeyAllocated = 0; } } m_pCurAsmRef = NULL; } ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP(); }
static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszAssemblyName, LPCFUSION_INSTALL_REFERENCE pRefData, ULONG *pulDisposition) { HRESULT hr; IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); IAssemblyName *asmname, *next = NULL; IAssemblyEnum *asmenum = NULL; WCHAR *p, *path = NULL; ULONG disp; DWORD len; TRACE("(%p, 0%08x, %s, %p, %p)\n", iface, dwFlags, debugstr_w(pszAssemblyName), pRefData, pulDisposition); if (pRefData) { FIXME("application reference not supported\n"); return E_NOTIMPL; } hr = CreateAssemblyNameObject( &asmname, pszAssemblyName, CANOF_PARSE_DISPLAY_NAME, NULL ); if (FAILED( hr )) return hr; cache_lock( cache ); hr = CreateAssemblyEnum( &asmenum, NULL, asmname, ASM_CACHE_GAC, NULL ); if (FAILED( hr )) goto done; hr = IAssemblyEnum_GetNextAssembly( asmenum, NULL, &next, 0 ); if (hr == S_FALSE) { if (pulDisposition) *pulDisposition = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED; goto done; } hr = IAssemblyName_GetPath( next, NULL, &len ); if (hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER )) goto done; if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) { hr = E_OUTOFMEMORY; goto done; } hr = IAssemblyName_GetPath( next, path, &len ); if (FAILED( hr )) goto done; if (DeleteFileW( path )) { if ((p = strrchrW( path, '\\' ))) { *p = 0; RemoveDirectoryW( path ); if ((p = strrchrW( path, '\\' ))) { *p = 0; RemoveDirectoryW( path ); } } disp = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED; hr = S_OK; } else { disp = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED; hr = S_FALSE; } if (pulDisposition) *pulDisposition = disp; done: IAssemblyName_Release( asmname ); if (next) IAssemblyName_Release( next ); if (asmenum) IAssemblyEnum_Release( asmenum ); HeapFree( GetProcessHeap(), 0, path ); cache_unlock( cache ); return hr; }
// --------------------------------------------------------------------------- // CCache::NameFromTransCacheEntry // convert target assembly name from name res entry //--------------------------------------------------------------------------- HRESULT CCache::NameFromTransCacheEntry( CTransCache *pTransCache, IAssemblyName **ppName ) { HRESULT hr; TRANSCACHEINFO *pTCInfo = NULL; LPBYTE pbPublicKeyToken, pbSignature, pbMVID; DWORD cbPublicKeyToken, cbSignature, cbMVID; // IAssemblyName target to be returned. IAssemblyName *pNameFinal = NULL; pTCInfo = (TRANSCACHEINFO*) pTransCache->_pInfo; // Currently this function is only called during enuming // the global cache so we expect an PublicKeyToken to be present. // BUT THIS IS NO LONGER TRUE - THE TRANSPORT CACHE CAN BE // INDEPENDENTLY ENUMERATED BUT AM LEAVING IN _ASSERTE AS COMMENT. // _ASSERTE(pTCInfo->blobPKT.cbSize); pbPublicKeyToken = pTCInfo->blobPKT.pBlobData; cbPublicKeyToken = pTCInfo->blobPKT.cbSize; pbSignature = pTCInfo->blobSignature.pBlobData; cbSignature = pTCInfo->blobSignature.cbSize; pbMVID = pTCInfo->blobMVID.pBlobData; cbMVID = pTCInfo->blobMVID.cbSize; // Create final name on text name and set properties. if (FAILED(hr = CreateAssemblyNameObject(&pNameFinal, pTCInfo->pwzName, NULL, 0))) goto exit; if(FAILED(hr = pNameFinal->SetProperty(cbPublicKeyToken ? ASM_NAME_PUBLIC_KEY_TOKEN : ASM_NAME_NULL_PUBLIC_KEY_TOKEN, pbPublicKeyToken, cbPublicKeyToken))) goto exit; for (DWORD i=0; i<4; i++) { if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_MAJOR_VERSION + i, &(pTCInfo->wVers[i]), sizeof(WORD)))) goto exit; } // Culture if(pTCInfo->pwzCulture) { if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_CULTURE, pTCInfo->pwzCulture, (lstrlenW(pTCInfo->pwzCulture) +1) * sizeof(TCHAR)))) goto exit; } if(pbSignature) { // Signature blob if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_SIGNATURE_BLOB, pbSignature, cbSignature))) goto exit; } if(pbMVID) { // MVID if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_MVID, pbMVID, cbMVID))) goto exit; } // For GAC's, we must have both runtime version // and architecture if(IsGacType(pTransCache->GetCacheType())) { if(!pTCInfo->fLegacyAssembly) { if(pTCInfo->dwAsmImageType) { // Assembly Image Type hr = pNameFinal->SetProperty(ASM_NAME_ARCHITECTURE, (LPBYTE) &pTCInfo->dwAsmImageType, sizeof(pTCInfo->dwAsmImageType)); if(FAILED(hr)) { goto exit; } } else { _ASSERTE(!"Non Legacy Assembly must have processor architecture."); } } } if(pTCInfo->pwzCodebaseURL) { // Codebase url if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_CODEBASE_URL, pTCInfo->pwzCodebaseURL, pTCInfo->pwzCodebaseURL ? (DWORD)((lstrlenW(pTCInfo->pwzCodebaseURL) +1) * sizeof(TCHAR)) : 0))) goto exit; } // Codebase url last modified filetime if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_CODEBASE_LASTMOD, &pTCInfo->ftLastModified, sizeof(FILETIME)))) goto exit; // Path modifier for ASP.NET installations if(pTCInfo->pwzPathModifier) { CAssemblyName *pCName = static_cast<CAssemblyName*>(pNameFinal); // dynamic_cast hr = pCName->SetPathModifier(pTCInfo->pwzPathModifier); if(FAILED(hr)) { goto exit; } } // We're done and can hand out the target name. hr = S_OK; exit: if (SUCCEEDED(hr)) { *ppName = pNameFinal; } else { SAFERELEASE(pNameFinal); } return hr; }
static void test_CreateAssemblyNameObject( void ) { static const WCHAR emptyW[] = {0}; IAssemblyName *name; HRESULT hr; hr = CreateAssemblyNameObject( NULL, wine1W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = NULL; hr = CreateAssemblyNameObject( &name, wine1W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == S_OK, "expected S_OK got %08x\n", hr ); ok( name != NULL, "expected non-NULL name\n" ); IAssemblyName_Release( name ); hr = CreateAssemblyNameObject( NULL, wine1W, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine1W, CANOF_SET_DEFAULT_VALUES, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); hr = CreateAssemblyNameObject( NULL, wine1W, 0, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, 0, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, 0, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, 0, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, 0, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine1W, 0, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); hr = CreateAssemblyNameObject( NULL, wine1W, CANOF_SET_DEFAULT_VALUES|CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, CANOF_SET_DEFAULT_VALUES|CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, CANOF_SET_DEFAULT_VALUES|CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, NULL, CANOF_SET_DEFAULT_VALUES|CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, emptyW, CANOF_SET_DEFAULT_VALUES|CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine1W, CANOF_SET_DEFAULT_VALUES|CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = NULL; hr = CreateAssemblyNameObject( &name, wine3W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == S_OK, "expected S_OK got %08x\n", hr ); ok( name != NULL, "expected non-NULL name\n" ); IAssemblyName_Release( name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine4W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine5W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME ), "expected ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine6W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME ), "expected ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine7W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = NULL; hr = CreateAssemblyNameObject( &name, wine8W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == S_OK, "expected S_OK got %08x\n", hr ); ok( name != NULL, "expected non-NULL name\n" ); IAssemblyName_Release( name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine9W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); name = NULL; hr = CreateAssemblyNameObject( &name, wine10W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == S_OK, "expected S_OK got %08x\n", hr ); ok( name != NULL, "expected non-NULL name\n" ); IAssemblyName_Release( name ); name = (IAssemblyName *)0xdeadbeef; hr = CreateAssemblyNameObject( &name, wine11W, CANOF_PARSE_DISPLAY_NAME, NULL ); ok( hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr ); ok( !name, "expected NULL got %p\n", name ); }
HRESULT GetFusionInfo(CTransCache *pTC, LPWSTR pszAsmDir) { HRESULT hr = S_OK; WCHAR wzFilePath[MAX_PATH+1]; DWORD cbSize=0; PBYTE pMVID=NULL; DWORD dwAttrib; DWORD cb; IAssemblyName *pName=NULL; LPWSTR pszBuf=NULL; BOOL bMVIDFailed=FALSE; BOOL bCustomFailed=FALSE; BOOL bURLFailed=FALSE; BOOL bDispNameFailed=FALSE; HINI hIni=NULL; TRANSCACHEINFO *pTCInfo = NULL; ASSERT(pszAsmDir || (pTC && pTC->_pInfo->pwzPath)); pszBuf = NEW(WCHAR[MAX_URL_LENGTH+1]); if (!pszBuf) { hr = E_OUTOFMEMORY; goto exit; } if(pTC && pTC->_pInfo->pwzPath) { // if there is path is transprtCache obj use it. else use second param pszAsmDir wnsprintf(wzFilePath, MAX_PATH, L"%s", pTC->_pInfo->pwzPath); } else { wnsprintf(wzFilePath, MAX_PATH, L"%s", pszAsmDir); } if((dwAttrib = GetFileAttributes(wzFilePath)) == (DWORD) -1) { hr = E_FAIL; goto exit; } if(!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { // looks manifestFilePath is passed in. knock-off the filename. LPWSTR pszTemp = PathFindFileName(wzFilePath); if(pszTemp > wzFilePath) { *(pszTemp-1) = L'\0'; } } // else we have assembly dir; wnsprintf(wzFilePath, MAX_PATH, L"%s\\%s", wzFilePath, g_FusionInfoFile); if ((hIni = PAL_IniCreate()) == NULL) { hr = FusionpHresultFromLastError(); goto exit; } if (!PAL_IniLoad(hIni, wzFilePath)) { hr = FusionpHresultFromLastError(); goto exit; } #define _ReadString(section, key, buf, size) PAL_IniReadString(hIni, section, key, buf, size) pTCInfo = (TRANSCACHEINFO*) pTC->_pInfo; cbSize = _ReadString(ASSEMBLY_INFO_STRING, MVID_KEY_STRING, pszBuf, MAX_URL_LENGTH); if(cbSize == MVID_LENGTH*2) { pMVID = NEW(BYTE[MVID_LENGTH]); if (!pMVID) { hr = E_OUTOFMEMORY; goto exit; } CParseUtils::UnicodeHexToBin(pszBuf, MVID_LENGTH*2, (LPBYTE) pMVID); SAFEDELETEARRAY(pTCInfo->blobMVID.pBlobData); pTCInfo->blobMVID.pBlobData = pMVID; pTCInfo->blobMVID.cbSize = MVID_LENGTH; pMVID = NULL; } else bMVIDFailed = TRUE; if(pTC->GetCacheType() & ASM_CACHE_ZAP) { cbSize = _ReadString(ASSEMBLY_INFO_STRING, CUSTOM_BLOB_STRING, pszBuf, MAX_URL_LENGTH); if(cbSize) { SAFEDELETEARRAY(pTCInfo->blobCustom.pBlobData); pTCInfo->blobCustom.pBlobData = (PBYTE) WSTRDupDynamic(pszBuf); if (!pTCInfo->blobCustom.pBlobData) { hr = E_OUTOFMEMORY; goto exit; } pTCInfo->blobCustom.cbSize = (cbSize + 1) * sizeof(WCHAR) ; } else bCustomFailed = TRUE; } else { cbSize = _ReadString(ASSEMBLY_INFO_STRING, URL_STRING, pszBuf, MAX_URL_LENGTH); if(cbSize) { SAFEDELETEARRAY(pTCInfo->pwzCodebaseURL); pTCInfo->pwzCodebaseURL = WSTRDupDynamic(pszBuf); if (!pTCInfo->pwzCodebaseURL) { hr = E_OUTOFMEMORY; goto exit; } } else bURLFailed = TRUE; if(pTC->GetCacheType() & ASM_CACHE_DOWNLOAD) { cbSize = _ReadString(ASSEMBLY_INFO_STRING, DISPLAY_NAME_STRING, pszBuf, MAX_URL_LENGTH); if(cbSize) { if (FAILED(hr = CreateAssemblyNameObject(&pName, pszBuf, CANOF_PARSE_DISPLAY_NAME, 0))) goto exit; SAFEDELETEARRAY(pTCInfo->pwzName); if (FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_NAME, (LPBYTE*) &pTCInfo->pwzName, &(cb = 0)))) goto exit; // Version if(FAILED(hr = pName->GetVersion(&pTCInfo->dwVerHigh, &pTCInfo->dwVerLow))) goto exit; SAFEDELETEARRAY(pTCInfo->pwzCulture); // Culture if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CULTURE, (LPBYTE*) &pTCInfo->pwzCulture, &cb)) || (pTCInfo->pwzCulture && !_wcslwr(pTCInfo->pwzCulture))) goto exit; SAFEDELETEARRAY(pTCInfo->blobPKT.pBlobData); // PublicKeyToken if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_PUBLIC_KEY_TOKEN, &pTCInfo->blobPKT.pBlobData, &pTCInfo->blobPKT.cbSize))) goto exit; } else bDispNameFailed = TRUE; } } exit: SAFEDELETEARRAY(pszBuf); SAFEDELETEARRAY(pMVID); SAFERELEASE(pName); if(SUCCEEDED(hr)) { if(bMVIDFailed || bCustomFailed) hr = E_FAIL; else if(bDispNameFailed || bURLFailed) hr = S_FALSE; } return hr; }
// --------------------------------------------------------------------------- // CCache::NameFromTransCacheEntry // convert target assembly name from name res entry //--------------------------------------------------------------------------- HRESULT CCache::NameFromTransCacheEntry( CTransCache *pTransCache, IAssemblyName **ppName ) { HRESULT hr; WORD wVerMajor, wVerMinor, wRevNo, wBldNo; TRANSCACHEINFO *pTCInfo = NULL; LPBYTE pbPublicKeyToken, pbCustom, pbMVID; DWORD cbPublicKeyToken, cbCustom, cbMVID; // IAssemblyName target to be returned. IAssemblyName *pNameFinal = NULL; pTCInfo = (TRANSCACHEINFO*) pTransCache->_pInfo; // Mask target major, minor versions and rev#, build# wVerMajor = HIWORD(pTCInfo->dwVerHigh); wVerMinor = LOWORD(pTCInfo->dwVerHigh); wBldNo = HIWORD(pTCInfo->dwVerLow); wRevNo = LOWORD(pTCInfo->dwVerLow); // Currently this function is only called during enuming // the global cache so we expect an PublicKeyToken to be present. // BUT THIS IS NO LONGER TRUE - THE TRANSPORT CACHE CAN BE // INDEPENDENTLY ENUMERATED BUT AM LEAVING IN ASSERT AS COMMENT. // ASSERT(pTCInfo->blobPKT.cbSize); pbPublicKeyToken = pTCInfo->blobPKT.pBlobData; cbPublicKeyToken = pTCInfo->blobPKT.cbSize; pbCustom = pTCInfo->blobCustom.pBlobData; cbCustom = pTCInfo->blobCustom.cbSize; pbMVID = pTCInfo->blobMVID.pBlobData; cbMVID = pTCInfo->blobMVID.cbSize; // Create final name on text name and set properties. if (FAILED(hr = CreateAssemblyNameObject(&pNameFinal, pTCInfo->pwzName, NULL, 0))) goto exit; if(FAILED(hr = pNameFinal->SetProperty(cbPublicKeyToken ? ASM_NAME_PUBLIC_KEY_TOKEN : ASM_NAME_NULL_PUBLIC_KEY_TOKEN, pbPublicKeyToken, cbPublicKeyToken))) goto exit; if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_MAJOR_VERSION, &wVerMajor, sizeof(WORD)))) goto exit; if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_MINOR_VERSION, &wVerMinor, sizeof(WORD)))) goto exit; // Build no. if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_BUILD_NUMBER, &wBldNo, sizeof(WORD)))) goto exit; // Revision no. if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_REVISION_NUMBER, &wRevNo, sizeof(WORD)))) goto exit; // Culture if(pTCInfo->pwzCulture) { if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_CULTURE, pTCInfo->pwzCulture, (lstrlen(pTCInfo->pwzCulture) +1) * sizeof(TCHAR)))) goto exit; } // Custom if(pbCustom) { if(FAILED(hr = pNameFinal->SetProperty(cbCustom ? ASM_NAME_CUSTOM : ASM_NAME_NULL_CUSTOM, pbCustom, cbCustom))) goto exit; } if(pbMVID) { // MVID if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_MVID, pbMVID, cbMVID))) goto exit; } if(pTCInfo->pwzCodebaseURL) { // Codebase url if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_CODEBASE_URL, pTCInfo->pwzCodebaseURL, pTCInfo->pwzCodebaseURL ? (DWORD)((lstrlen(pTCInfo->pwzCodebaseURL) +1) * sizeof(TCHAR)) : 0))) goto exit; } // Codebase url last modified filetime if(FAILED(hr = pNameFinal->SetProperty(ASM_NAME_CODEBASE_LASTMOD, &pTCInfo->ftLastModified, sizeof(FILETIME)))) goto exit; // We're done and can hand out the target name. hr = S_OK; exit: if (SUCCEEDED(hr)) { *ppName = pNameFinal; } else { SAFERELEASE(pNameFinal); } return hr; }
HRESULT CNodeFactory::ProcessQualifyAssemblyTag(XML_NODE_INFO **aNodeInfo, USHORT cNumRecs) { HRESULT hr = S_OK; USHORT idx = 1; LPWSTR pwzAttributeNS = NULL; LPWSTR pwzPartialName = NULL; LPWSTR pwzFullName = NULL; CQualifyAssembly *pqa = NULL; IAssemblyName *pNameFull = NULL; IAssemblyName *pNamePartial = NULL; IAssemblyName *pNameQualified = NULL; LPWSTR wzCanonicalDisplayName=NULL; ASSERT(aNodeInfo && cNumRecs); while (idx < cNumRecs) { if (aNodeInfo[idx]->dwType == XML_ATTRIBUTE) { // Found an attribute. Find out which one, and extract the data. // Node: ::ExtractXMLAttribute increments idx. hr = ApplyNamespace(aNodeInfo[idx], &pwzAttributeNS, 0); if (FAILED(hr)) { goto Exit; } if (!lstrcmpW(pwzAttributeNS, XML_ATTRIBUTE_PARTIALNAME)) { SAFEDELETEARRAY(pwzAttributeNS); if (pwzPartialName) { // Ignore duplicate attribute idx++; } else { hr = ::ExtractXMLAttribute(&pwzPartialName, aNodeInfo, &idx, cNumRecs); if (FAILED(hr)) { goto Exit; } } } else if (!lstrcmpW(pwzAttributeNS, XML_ATTRIBUTE_FULLNAME)) { SAFEDELETEARRAY(pwzAttributeNS); if (pwzFullName) { // Ignore duplicate attribute idx++; } else { hr = ::ExtractXMLAttribute(&pwzFullName, aNodeInfo, &idx, cNumRecs); if (FAILED(hr)) { goto Exit; } } } else { SAFEDELETEARRAY(pwzAttributeNS); idx++; } } else { idx++; } } if (pwzPartialName && pwzFullName) { DWORD dwSize; DWORD adwProperties[] = { ASM_NAME_NAME, ASM_NAME_MAJOR_VERSION, ASM_NAME_MINOR_VERSION, ASM_NAME_BUILD_NUMBER, ASM_NAME_REVISION_NUMBER, ASM_NAME_CULTURE, ASM_NAME_PUBLIC_KEY_TOKEN }; DWORD adwCmpFlags[] = { ASM_CMPF_NAME, ASM_CMPF_MAJOR_VERSION, ASM_CMPF_MINOR_VERSION, ASM_CMPF_BUILD_NUMBER, ASM_CMPF_REVISION_NUMBER, ASM_CMPF_CULTURE, ASM_CMPF_PUBLIC_KEY_TOKEN }; DWORD dwNumProps = sizeof(adwProperties) / sizeof(adwProperties[0]); if (FAILED(CreateAssemblyNameObject(&pNameFull, pwzFullName, CANOF_PARSE_DISPLAY_NAME, 0))) { goto Exit; } if (FAILED(CreateAssemblyNameObject(&pNamePartial, pwzPartialName, CANOF_PARSE_DISPLAY_NAME, 0))) { goto Exit; } // Check validity of qualification if (CAssemblyName::IsPartial(pNameFull) || !CAssemblyName::IsPartial(pNamePartial)) { goto Exit; } if (FAILED(pNamePartial->Clone(&pNameQualified))) { goto Exit; } for (DWORD i = 0; i < dwNumProps; i++) { dwSize = 0; if (pNamePartial->GetProperty(adwProperties[i], NULL, &dwSize) != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { // Partial on this field. Set pNameQualified's corresponding // property to whatever is in pNameFull. dwSize = 0; pNameFull->GetProperty(adwProperties[i], NULL, &dwSize); if (!dwSize) { goto Exit; } else { BYTE *pBuf; pBuf = NEW(BYTE[dwSize]); if (!pBuf) { hr = E_OUTOFMEMORY; goto Exit; } if (FAILED(pNameFull->GetProperty(adwProperties[i], pBuf, &dwSize))) { SAFEDELETEARRAY(pBuf); goto Exit; } if (FAILED(pNameQualified->SetProperty(adwProperties[i], pBuf, dwSize))) { SAFEDELETEARRAY(pBuf); goto Exit; } SAFEDELETEARRAY(pBuf); } } else { // Full-specified on this field. Make sure it matches the full ref specified. if (pNamePartial->IsEqual(pNameFull, adwCmpFlags[i]) != S_OK) { goto Exit; } } } if (CAssemblyName::IsPartial(pNameQualified)) { goto Exit; } // Get canonical display name format wzCanonicalDisplayName = NEW(WCHAR[MAX_URL_LENGTH+1]); if (!wzCanonicalDisplayName) { hr = E_OUTOFMEMORY; goto Exit; } dwSize = MAX_URL_LENGTH; if (FAILED(pNamePartial->GetDisplayName(wzCanonicalDisplayName, &dwSize, 0))) { goto Exit; } // Add qualified assembly entry to list pqa = new CQualifyAssembly; if (!pqa) { hr = E_OUTOFMEMORY; goto Exit; } pqa->_pwzPartialName = WSTRDupDynamic(wzCanonicalDisplayName); if (!pqa->_pwzPartialName) { hr = E_OUTOFMEMORY; goto Exit; } pqa->_pNameFull = pNameQualified; pNameQualified->AddRef(); _listQualifyAssembly.AddTail(pqa); } Exit: SAFEDELETEARRAY(pwzPartialName); SAFEDELETEARRAY(pwzFullName); SAFERELEASE(pNameFull); SAFERELEASE(pNamePartial); SAFERELEASE(pNameQualified); SAFEDELETEARRAY(wzCanonicalDisplayName); return hr; }