HRESULT GetDLDirsFromName(IAssemblyName *pName, LPWSTR pszParentDir, LPWSTR pszSubDirName) { HRESULT hr = S_OK; LPWSTR pwzCodebaseURL=NULL; FILETIME ftLastMod; DWORD cb=0; ASSERT(pName && pszParentDir && pszSubDirName); if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CODEBASE_URL, (LPBYTE*) &pwzCodebaseURL, &(cb = 0)))) goto exit; hr = GetDLParentDir(pwzCodebaseURL, pszParentDir); if(FAILED(hr = pName->GetProperty(ASM_NAME_CODEBASE_LASTMOD, &ftLastMod, &(cb = sizeof(FILETIME))))) goto exit; GetDLAsmDir(&ftLastMod, pszSubDirName); exit : SAFEDELETE(pwzCodebaseURL); return hr; }
// --------------------------------------------------------------------------- // CCache::TransCacheEntryFromName // create transport entry from name //--------------------------------------------------------------------------- HRESULT CCache::TransCacheEntryFromName(IAssemblyName *pName, DWORD dwFlags, CTransCache **ppTransCache) { HRESULT hr; DWORD cb, dwCacheId = 0; TRANSCACHEINFO *pTCInfo = 0; CTransCache *pTransCache = NULL; _ASSERTE(pName); // Get the correct cache index. if(FAILED(hr = ResolveCacheIndex(pName, dwFlags, &dwCacheId))) goto exit; // Construct new CTransCache object. if(FAILED(hr = CreateTransCacheEntry(dwCacheId, &pTransCache))) goto exit; // Cast base info ptr to TRANSCACHEINFO ptr pTCInfo = (TRANSCACHEINFO*) pTransCache->_pInfo; // Downcased text name from target hr = NameObjGetWrapper(pName, ASM_NAME_NAME, (LPBYTE*) &pTCInfo->pwzName, &(cb = 0)); if (SUCCEEDED(hr)) { for (DWORD i=0; i<4; i++) { cb = sizeof(WORD); hr = pName->GetProperty(ASM_NAME_MAJOR_VERSION+i, &(pTCInfo->wVers[i]), &cb); if (FAILED(hr)) { goto exit; } } } if (SUCCEEDED(hr)) { hr = NameObjGetWrapper(pName, ASM_NAME_CULTURE, (LPBYTE*) &pTCInfo->pwzCulture, &cb); } if (SUCCEEDED(hr)) { hr = NameObjGetWrapper(pName, ASM_NAME_PUBLIC_KEY_TOKEN, &pTCInfo->blobPKT.pBlobData, &pTCInfo->blobPKT.cbSize); } if (SUCCEEDED(hr)) { hr = NameObjGetWrapper(pName, ASM_NAME_SIGNATURE_BLOB, &pTCInfo->blobSignature.pBlobData, &pTCInfo->blobSignature.cbSize); } if (SUCCEEDED(hr)) { hr = NameObjGetWrapper(pName, ASM_NAME_MVID, &pTCInfo->blobMVID.pBlobData, &pTCInfo->blobMVID.cbSize); } if (SUCCEEDED(hr)) { hr = NameObjGetWrapper(pName, ASM_NAME_CODEBASE_URL, (LPBYTE*) &pTCInfo->pwzCodebaseURL, &(cb = 0)); } if (SUCCEEDED(hr)) { hr = pName->GetProperty(ASM_NAME_CODEBASE_LASTMOD, &pTCInfo->ftLastModified, &(cb = sizeof(FILETIME))); } if(SUCCEEDED(hr)) { CAssemblyName *pCName = static_cast<CAssemblyName*>(pName); // dynamic_cast DWORD dwSize = 0; // Returns S_OK if no modifier exists hr = pCName->GetPathModifier(NULL, &dwSize); if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { pTCInfo->pwzPathModifier = NEW(WCHAR[dwSize]); if(!pTCInfo->pwzPathModifier) { hr = E_OUTOFMEMORY; goto exit; } hr = pCName->GetPathModifier(pTCInfo->pwzPathModifier, &dwSize); } } if (SUCCEEDED(hr)) { if(pTCInfo->pwzName && (lstrlenW(pTCInfo->pwzName) >= MAX_PATH) ) hr = FUSION_E_INVALID_NAME; // name is too long; this is an error. } if (SUCCEEDED(hr)) { CAssemblyName *pCName = static_cast<CAssemblyName*>(pName); // dynamic_cast pTCInfo->fLegacyAssembly = pCName->IsLegacyAssembly(); hr = pName->GetProperty(ASM_NAME_ARCHITECTURE, (LPBYTE) &pTCInfo->dwAsmImageType, &(cb = sizeof(DWORD))); } exit: if (SUCCEEDED(hr)) { *ppTransCache = pTransCache; } else { SAFERELEASE(pTransCache); } return hr; }
HRESULT GetCacheDirsFromName(IAssemblyName *pName, DWORD dwFlags, LPWSTR pszParentDirName, LPWSTR pszSubDirName) { HRESULT hr = S_OK; DWORD dwVerHigh=0; DWORD dwVerLow=0; LPWSTR pszTextName=NULL; DWORD cb=0; PBYTE pPKT=NULL; PBYTE pCustom=NULL; DWORD cbCustom=0; DWORD cbPKT=0; LPWSTR wzCulture=NULL; LPWSTR szProp=NULL; ASSERT(pName && dwFlags && pszParentDirName && pszSubDirName); if( (dwFlags & ASM_CACHE_GAC) || (dwFlags & ASM_CACHE_ZAP) ) { if (FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_NAME, (LPBYTE*) &pszTextName, &(cb = 0)))) goto exit; if(cb > MAX_PATH) { hr = HRESULT_FROM_WIN32(FUSION_E_INVALID_NAME); goto exit; } StrCpy(pszParentDirName, pszTextName); // Version if(FAILED(hr = pName->GetVersion(&dwVerHigh, &dwVerLow))) goto exit; // Culture if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CULTURE, (LPBYTE*) &wzCulture, &cb))) goto exit; // PublicKeyToken if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_PUBLIC_KEY_TOKEN, &pPKT, &cbPKT))) goto exit; if (dwFlags & ASM_CACHE_ZAP) { if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CUSTOM, &pCustom, &(cbCustom = 0)))) goto exit; } hr = GetAsmDir(pszSubDirName, dwFlags, dwVerHigh, dwVerLow, wzCulture, pPKT, cbPKT, pCustom, cbCustom); } else if (dwFlags & ASM_CACHE_DOWNLOAD) { GetDLDirsFromName(pName, pszParentDirName, pszSubDirName); } exit: SAFEDELETE(szProp); SAFEDELETE(wzCulture); SAFEDELETE(pPKT); SAFEDELETE(pCustom); SAFEDELETE(pszTextName); return hr; }
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; }
HRESULT StoreFusionInfo(IAssemblyName *pName, LPWSTR pszDir, DWORD *pdwFileSizeLow) { HRESULT hr = S_OK; WCHAR pszFilePath[MAX_PATH+1]; PBYTE pMVID=NULL; PBYTE pCustom=NULL; LPWSTR pszCustomString=NULL; LPWSTR pszURL=NULL; LPWSTR pszDisplayName=NULL; DWORD cbSize=0; BOOL fRet = FALSE; DWORD dwSize; LPWSTR pszBuf=NULL; HINI hIni=NULL; if(( lstrlenW(pszDir) + lstrlenW(g_FusionInfoFile) + 1) >= MAX_PATH) { hr = HRESULT_FROM_WIN32(FUSION_E_INVALID_NAME); goto exit; } StrCpy(pszFilePath, pszDir); PathAddBackslash(pszFilePath); StrCat(pszFilePath, g_FusionInfoFile); if ((hIni = PAL_IniCreate()) == NULL) { hr = FusionpHresultFromLastError(); goto exit; } #define _WriteString(section, key, value) PAL_IniWriteString(hIni, section, key, value) pszBuf = NEW(WCHAR[MAX_URL_LENGTH+1]); if (!pszBuf) { hr = E_OUTOFMEMORY; goto exit; } cbSize = 0; if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_MVID, &pMVID, &cbSize))) goto exit; if(cbSize && (cbSize == MVID_LENGTH)) { CParseUtils::BinToUnicodeHex(pMVID, cbSize, pszBuf); pszBuf[MVID_LENGTH*2] = L'\0'; fRet = _WriteString(ASSEMBLY_INFO_STRING, MVID_KEY_STRING, pszBuf); if (!fRet) { hr = FusionpHresultFromLastError(); goto exit; } } cbSize = 0; if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CUSTOM, &pCustom, &cbSize))) goto exit; if(cbSize) { pszCustomString = (LPWSTR) pCustom; fRet = _WriteString(ASSEMBLY_INFO_STRING, CUSTOM_BLOB_STRING, pszCustomString); if (!fRet) { hr = FusionpHresultFromLastError(); goto exit; } } else { // if there is no Custom Blob try storing URL. cbSize = 0; if(FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CODEBASE_URL, (LPBYTE*) &pszURL, &cbSize))) goto exit; if(cbSize) { fRet = _WriteString(ASSEMBLY_INFO_STRING, URL_STRING, pszURL); if (!fRet) { hr = FusionpHresultFromLastError(); goto exit; } } dwSize = 0; hr = pName->GetDisplayName(NULL, &dwSize, 0); if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { ASSERT(0); hr = E_UNEXPECTED; goto exit; } pszDisplayName = NEW(WCHAR[dwSize]); if (!pszDisplayName) { hr = E_OUTOFMEMORY; goto exit; } hr = pName->GetDisplayName(pszDisplayName, &dwSize, 0); if (FAILED(hr)) { goto exit; } cbSize = dwSize * sizeof(WCHAR); if(cbSize) { fRet = _WriteString(ASSEMBLY_INFO_STRING, DISPLAY_NAME_STRING, pszDisplayName); if (!fRet) { hr = FusionpHresultFromLastError(); goto exit; } } } if (!PAL_IniSave(hIni, pszFilePath, TRUE)) { hr = FusionpHresultFromLastError(); goto exit; } { DWORD dwSizeHigh=0; *pdwFileSizeLow = 512; // hard-code info file size. hr = GetFileSizeRoundedToCluster(INVALID_HANDLE_VALUE, pdwFileSizeLow, &dwSizeHigh); } exit: if (hIni != NULL) PAL_IniClose(hIni); SAFEDELETEARRAY(pszBuf); SAFEDELETEARRAY(pszDisplayName); SAFEDELETEARRAY(pMVID); SAFEDELETEARRAY(pCustom); SAFEDELETEARRAY(pszURL); return hr; }
// --------------------------------------------------------------------------- // CCache::TransCacheEntryFromName // create transport entry from name //--------------------------------------------------------------------------- HRESULT CCache::TransCacheEntryFromName(IAssemblyName *pName, DWORD dwFlags, CTransCache **ppTransCache) { HRESULT hr; DWORD cb, dwCacheId = 0; TRANSCACHEINFO *pTCInfo = 0; CTransCache *pTransCache = NULL; // Get the correct cache index. if(FAILED(hr = ResolveCacheIndex(pName, dwFlags, &dwCacheId))) goto exit; // Construct new CTransCache object. if(FAILED(hr = CreateTransCacheEntry(dwCacheId, &pTransCache))) goto exit; // Cast base info ptr to TRANSCACHEINFO ptr pTCInfo = (TRANSCACHEINFO*) pTransCache->_pInfo; // Downcased text name from target if (FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_NAME, (LPBYTE*) &pTCInfo->pwzName, &(cb = 0))) // Version || FAILED(hr = pName->GetVersion(&pTCInfo->dwVerHigh, &pTCInfo->dwVerLow)) // Culture || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CULTURE, (LPBYTE*) &pTCInfo->pwzCulture, &cb)) || (pTCInfo->pwzCulture && !_wcslwr(pTCInfo->pwzCulture)) // PublicKeyToken || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_PUBLIC_KEY_TOKEN, &pTCInfo->blobPKT.pBlobData, &pTCInfo->blobPKT.cbSize)) // Custom || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CUSTOM, &pTCInfo->blobCustom.pBlobData, &pTCInfo->blobCustom.cbSize)) // MVID || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_MVID, &pTCInfo->blobMVID.pBlobData, &pTCInfo->blobMVID.cbSize)) // Codebase url if any from target || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CODEBASE_URL, (LPBYTE*) &pTCInfo->pwzCodebaseURL, &(cb = 0))) || FAILED(hr = pName->GetProperty(ASM_NAME_CODEBASE_LASTMOD, &pTCInfo->ftLastModified, &(cb = sizeof(FILETIME))))) { goto exit; } if(pTCInfo->pwzName && (lstrlen(pTCInfo->pwzName) >= MAX_PATH) ) hr = FUSION_E_INVALID_NAME; // name is too long; this is an error. exit: if (SUCCEEDED(hr)) { *ppTransCache = pTransCache; } else { SAFERELEASE(pTransCache); } return hr; }
// --------------------------------------------------------------------------- // CCache::InsertTransCacheEntry //--------------------------------------------------------------------------- HRESULT CCache::InsertTransCacheEntry(IAssemblyName *pName, LPTSTR szPath, DWORD dwKBSize, DWORD dwFlags, DWORD dwCommitFlags, DWORD dwPinBits, CTransCache **ppTransCache) { HRESULT hr; DWORD cb, dwCacheId; TRANSCACHEINFO *pTCInfo = NULL; CTransCache *pTransCache = NULL; LPWSTR pwzCodebaseUrl = NULL; WCHAR pwzCanonicalized[MAX_URL_LENGTH]; // Determine which cache index to insert to. if (FAILED(hr = ResolveCacheIndex(pName, dwFlags, &dwCacheId))) goto exit; // Construct new CTransCache object. if(FAILED(hr = CreateTransCacheEntry(dwCacheId, &pTransCache))) goto exit; // Cast pTransCache base info ptr to TRANSCACHEINFO ptr pTCInfo = (TRANSCACHEINFO*) pTransCache->_pInfo; // Downcased text name from target if (FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_NAME, (LPBYTE*) &pTCInfo->pwzName, &(cb = 0))) // Version || FAILED(hr = pName->GetVersion(&pTCInfo->dwVerHigh, &pTCInfo->dwVerLow)) // Culture (downcased) || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CULTURE, (LPBYTE*) &pTCInfo->pwzCulture, &cb)) || (pTCInfo->pwzCulture && !_wcslwr(pTCInfo->pwzCulture)) // PublicKeyToken || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_PUBLIC_KEY_TOKEN, &pTCInfo->blobPKT.pBlobData, &pTCInfo->blobPKT.cbSize)) // Custom || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CUSTOM, &pTCInfo->blobCustom.pBlobData, &pTCInfo->blobCustom.cbSize)) // MVID || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_MVID, &pTCInfo->blobMVID.pBlobData, &pTCInfo->blobMVID.cbSize)) // Codebase url if any from target || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_CODEBASE_URL, (LPBYTE*)&pwzCodebaseUrl, &(cb = 0))) // Codebase last modified time if any from target. || FAILED(hr = pName->GetProperty(ASM_NAME_CODEBASE_LASTMOD, &pTCInfo->ftLastModified, &(cb = sizeof(FILETIME)))) // PK if any from source. || FAILED(hr = NameObjGetWrapper(pName, ASM_NAME_PUBLIC_KEY, &pTCInfo->blobPK.pBlobData, &pTCInfo->blobPK.cbSize)) ) { goto exit; } if (pwzCodebaseUrl) { cb = MAX_URL_LENGTH; hr = UrlCanonicalizeUnescape(pwzCodebaseUrl, pwzCanonicalized, &cb, 0); if (FAILED(hr)) { goto exit; } pTCInfo->pwzCodebaseURL = WSTRDupDynamic(pwzCanonicalized); if (!pTCInfo->pwzCodebaseURL) { hr = E_OUTOFMEMORY; goto exit; } } else { pTCInfo->pwzCodebaseURL = NULL; } // Copy in path. if (!(pTCInfo->pwzPath = TSTRDupDynamic(szPath))) { hr = E_OUTOFMEMORY; goto exit; } // File size pTCInfo->dwKBSize = dwKBSize; // Set pin Bits pTCInfo->dwPinBits = dwPinBits; exit: SAFEDELETEARRAY(pwzCodebaseUrl); // Base destructor takes care // of everything. if (!ppTransCache || (FAILED(hr) && (hr != DB_E_DUPLICATE))) { SAFERELEASE(pTransCache); } else { *ppTransCache = pTransCache; } return hr; }