|
|
#include "wsdueng.h"
#define IDENT_SECTION_CABPOOL "cabpools"
#define IDENT_SECTION_CONTENT31 "content31"
#define IDENT_KEYNAME_DEFAULT "default"
#define IDENT_KEYNAME_ROOT "root"
CV31Server::CV31Server(CDynamicUpdate *pDu) : m_puidConsumerCatalog(0), m_puidSetupCatalog(0), m_dwPlatformID(0), m_lcidLocaleID(0), m_dwConsumerItemCount(0), m_pConsumerCatalog(NULL), m_dwSetupItemCount(0), m_pSetupCatalog(NULL), m_dwGlobalExclusionItemCount(0), m_pDu(pDu) { // set the initial state
m_dwPlatformID = (DWORD)m_pDu->m_iPlatformID; m_lcidLocaleID = m_pDu->m_lcidLocaleID; if (0 == m_pDu->m_wPlatformSKU) // Professional
{ m_enumPlatformSKU = enWhistlerProfessional; } else if (m_pDu->m_wPlatformSKU & VER_SUITE_DATACENTER) // DataCenter
{ m_enumPlatformSKU = enWhistlerDataCenter; } else if (m_pDu->m_wPlatformSKU & VER_SUITE_PERSONAL) // Personal
{ m_enumPlatformSKU = enWhistlerConsumer; } else if (m_pDu->m_wPlatformSKU & VER_SUITE_ENTERPRISE) // Advanced Server
{ m_enumPlatformSKU = enWhistlerAdvancedServer; } else if (m_pDu->m_wPlatformSKU & VER_SUITE_SMALLBUSINESS) // Server
{ m_enumPlatformSKU = enWhistlerServer; }
// RogerJ October 25th, 2000
m_pValidDependentPUIDArray = NULL; m_nNumOfValidDependentPUID = 0; m_pBitMaskAS = m_pBitMaskCDM = NULL; m_fHasDriver = FALSE; m_pszExcludedDriver = NULL;
}
CV31Server::~CV31Server() { FreeCatalogs(); // clears the m_pConsumerItems and m_pSetupItems Varrays.
SafeGlobalFree(m_pConsumerCatalog); SafeGlobalFree(m_pSetupCatalog);
// RogerJ, October 25th, 2000
SafeGlobalFree(m_pValidDependentPUIDArray); SafeGlobalFree(m_pBitMaskAS); SafeGlobalFree(m_pBitMaskCDM); SafeGlobalFree(m_pszExcludedDriver); }
// ----------------------------------------------------------------------------------
// V3.1 Backend Server Apis
//
//
BOOL CV31Server::ReadIdentInfo() { // ident.cab should already be downloaded at this point. Get the path to it and read the fields we care about
char szIdent[MAX_PATH]; char szValueName[32]; int iServerNumber; char szUrl[INTERNET_MAX_URL_LENGTH + 1];
PathCombine(szIdent, m_pDu->GetDuTempPath(), "ident.txt");
// --------------------
// Get the CABPOOL URL
// --------------------
iServerNumber = GetPrivateProfileInt(IDENT_SECTION_CABPOOL, IDENT_KEYNAME_DEFAULT, 1, szIdent); wsprintf(szValueName, "Server%d", iServerNumber);
GetPrivateProfileString(IDENT_SECTION_CABPOOL, szValueName, "", szUrl, sizeof(szUrl), szIdent); if ('\0' == szUrl[0]) { // No Server Value was found in the ident. Cannot continue;
SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; }
// The cabpool URL is the string in the Ident + 'cabpool'
m_pDu->DuUrlCombine(m_szCabPoolUrl, szUrl, "CabPool");
// --------------------
// Get the CONTENT URL
// --------------------
iServerNumber = GetPrivateProfileInt(IDENT_SECTION_CONTENT31, IDENT_KEYNAME_DEFAULT, 1, szIdent); wsprintf(szValueName, "Server%d", iServerNumber);
GetPrivateProfileString(IDENT_SECTION_CONTENT31, szValueName, "", szUrl, sizeof(szUrl), szIdent); if ('\0' == szUrl[0]) { // No Server Value
SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; }
lstrcpy(m_szV31ContentUrl, szUrl);
// -------------------------
// Get the CONTENT ROOT URL
// -------------------------
iServerNumber = GetPrivateProfileInt(IDENT_SECTION_CONTENT31, IDENT_KEYNAME_ROOT, 2, szIdent); wsprintf(szValueName, "Server%d", iServerNumber);
GetPrivateProfileString(IDENT_SECTION_CONTENT31, szValueName, "", szUrl, sizeof(szUrl), szIdent); if ('\0' == szUrl[0]) { // No Root Server Value
SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; }
lstrcpy(m_szV31RootUrl, szUrl);
return TRUE; }
BOOL CV31Server::ReadCatalogINI() { LOG_block("CV31Server::ReadCatalogINI()"); char szServerFile[INTERNET_MAX_URL_LENGTH + 1]; char szLocalFile[MAX_PATH]; char szValue[1024];
// Now read the Catalog.ini file to find out if any of these items needs to be turned off
m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, CATALOGINIFN); PathCombineA(szLocalFile, m_pDu->GetDuTempPath(), CATALOGINIFN); if (ERROR_SUCCESS != m_pDu->DownloadFile(szServerFile, szLocalFile, FALSE, FALSE)) { LOG_out("No catalog.ini found"); return TRUE; }
if (0 != (GetPrivateProfileStringA("exclude", "puids", "", szValue, sizeof(szValue), szLocalFile))) { LPCSTR pszNext = szValue; char szPuid[128]; while (NULL != pszNext) { pszNext = strcpystr(pszNext, ",", szPuid); if ('\0' != szPuid[0]) { m_GlobalExclusionArray[m_dwGlobalExclusionItemCount] = StrToIntA(szPuid); LOG_out("Excluded puid --- %d", m_GlobalExclusionArray[m_dwGlobalExclusionItemCount]); m_dwGlobalExclusionItemCount++; } } } else LOG_out("No Excluded puid"); return TRUE; }
BOOL CV31Server::GetCatalogPUIDs() { LOG_block("CV31Server::GetCatalogPUIDs()"); // There are two v3 catalogs that we will be looking for the PUID's for..
// One is the Consumer Catalog for the target platform
// The other is the Setup Catalog for the target platform
char szServerFile[INTERNET_MAX_URL_LENGTH]; PBYTE pCatalogList = NULL; PBYTE pInventoryList = NULL; PBYTE pWalkList = NULL; DWORD dwLength; m_puidConsumerCatalog = 0; m_puidSetupCatalog = 0;
// Download the Catalog Inventory List
m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, "inventory.plt"); m_pDu->DownloadFileToMem(szServerFile, &pInventoryList, &dwLength, TRUE, "inventory.plt", NULL);
if (NULL == pInventoryList) { // error out of memory
return FALSE; }
// Download the CatalogList
m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, "inventory.cat"); m_pDu->DownloadFileToMem(szServerFile, &pCatalogList, &dwLength, TRUE, "inventory.cat", NULL);
if (NULL == pCatalogList) { // error out of memory
SafeGlobalFree(pInventoryList); return FALSE; }
// Now Parse the Inventory List to Find out how many catalogs there are.
int i; WU_CATALOG_HEADER hdr;
memcpy(&hdr, pInventoryList, sizeof(hdr));
pWalkList = pCatalogList; CATALOGLIST catListElem; for (i = 0; i < hdr.totalItems; i++) { memcpy(&catListElem, pWalkList, sizeof(catListElem)); if (catListElem.dwPlatform == m_dwPlatformID) { // standard catalog is 0, thus, standard catalog with driver will have same value as driver only
if ((CATLIST_DRIVERSPRESENT == catListElem.dwFlags) || (catListElem.dwFlags == (CATLIST_DRIVERSPRESENT | CATLIST_64BIT))) { // consumer catalog for this platform
m_puidConsumerCatalog = catListElem.dwCatPuid; } else if (catListElem.dwFlags & CATLIST_SETUP) { // setup catalog for this platform
m_puidSetupCatalog = catListElem.dwCatPuid; if (0 == m_puidConsumerCatalog && (catListElem.dwFlags & CATLIST_DRIVERSPRESENT)) m_puidConsumerCatalog = catListElem.dwCatPuid; } } pWalkList += sizeof(catListElem); } if (!m_puidConsumerCatalog && ! m_puidSetupCatalog) { SetLastError(ERROR_INTERNET_NO_CONTEXT); SafeGlobalFree(pInventoryList); SafeGlobalFree(pCatalogList); return FALSE; // this technically is an error.. wrong server was pointed to? Catalogs weren't on the server
} SafeGlobalFree(pInventoryList); SafeGlobalFree(pCatalogList);
LOG_out("Consumer catalog %d, Setup catalog %d", m_puidConsumerCatalog, m_puidSetupCatalog); return TRUE; }
BOOL CV31Server::GetCatalogs() { // This will download the two Catalogs (Setup and Consumer) and the InventoryItem Arrays
LOG_block("CV31Server::GetCatalogs()"); DWORD dwRet; int i; char szServerFile[INTERNET_MAX_URL_LENGTH]; char szLocalFile[MAX_PATH]; char szCatalog[MAX_PATH]; char szInvCRC[64]; char szBmCRC[64]; char szLocale[32]; PBYTE pWalkCatalog = NULL; WU_CATALOG_HEADER hdr; PINVENTORY_ITEM pItem; BOOL fDriversAvailable = FALSE; DWORD dwLength;
wsprintf(szLocale, "0x%8.8x", m_lcidLocaleID);
FreeCatalogs(); // free any previously allocated catalog lists
SafeGlobalFree(m_pValidDependentPUIDArray); // free any previously determined dependency list
m_pValidDependentPUIDArray = NULL; m_nNumOfValidDependentPUID = 0;
// Read the Catalog.INI to get a list of Globally Excluded Items
if (0 != m_puidConsumerCatalog) { // Download the Consumer Catalog for this Platform
// first we need to download the redirect file to get the CRC value of the catalog
wsprintf(szCatalog, "%d/%s.as", m_puidConsumerCatalog, szLocale); m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, szCatalog); wsprintf(szCatalog, "%d_%s.as", m_puidConsumerCatalog, szLocale); PathCombine(szLocalFile, m_pDu->GetDuTempPath(), szCatalog); m_pDu->DownloadFile(szServerFile, szLocalFile, TRUE, FALSE);
if (GetPrivateProfileString("redir", "invCRC", "", szInvCRC, sizeof(szInvCRC), szLocalFile) == 0) { LOG_error("Unable to Read Inventory CRC value from Consumer Catalog"); return FALSE; }
// does not need this for consumer catalog
/*if (GetPrivateProfileString("redir", "bmCRC", "", szBmCRC, sizeof(szBmCRC), szLocalFile) == 0)
{ LOG_error("Unable to Read Bitmask CRC value for Consumer Catalog"); return FALSE; }*/
if (!GetBitMask("bitmask.cdm", m_puidConsumerCatalog, &m_pBitMaskCDM, "bitmask.cdm")) { LOG_error("Unable to get bitmask for CDM"); return FALSE; }
// now download the real catalog
wsprintf(szCatalog, "%d/%s.inv", m_puidConsumerCatalog, szInvCRC); m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, szCatalog); SafeGlobalFree(m_pConsumerCatalog); wsprintf(szCatalog, "%s.inv", szInvCRC); m_pDu->DownloadFileToMem(szServerFile, &m_pConsumerCatalog, &dwLength, TRUE, szCatalog, "inventory.as"); if (NULL == m_pConsumerCatalog) { LOG_error("Failed to download Consumer Catalog, %d", m_puidConsumerCatalog); return FALSE; }
pWalkCatalog = m_pConsumerCatalog;
// Read the Catalog Header
ZeroMemory(&hdr, sizeof(hdr)); memcpy(&hdr, pWalkCatalog, sizeof(hdr));
m_pConsumerItems[hdr.totalItems] = NULL; // just to preinitialize the array.
pWalkCatalog += sizeof(hdr);
// walk the list and read the items.
for (i = 0; i < hdr.totalItems; i++) { pItem = (PINVENTORY_ITEM) GlobalAlloc(GMEM_ZEROINIT, sizeof(INVENTORY_ITEM)); if (NULL == pItem) { dwRet = GetLastError(); LOG_error("Failed to Alloc Memory for Inventory Item, Error %d", dwRet); return FALSE; }
pWalkCatalog = GetNextRecord(pWalkCatalog, i, pItem); if (!pWalkCatalog) { LOG_error("Failed to Alloc Memory for InventoryI Item State, Error %d", GetLastError()); return FALSE; }
m_pConsumerItems[i] = pItem; if ( WU_TYPE_CDM_RECORD_PLACE_HOLDER == pItem->recordType) m_fHasDriver = TRUE; m_dwConsumerItemCount++; } }
if (0 != m_puidSetupCatalog) { // Download the Setup Catalog for this Platform
// first we need to download the redirect file to get the CRC value of the catalog
wsprintf(szCatalog, "%d/%s.as", m_puidSetupCatalog, szLocale); m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, szCatalog); wsprintf(szCatalog, "%d_%s.as", m_puidSetupCatalog, szLocale); PathCombine(szLocalFile, m_pDu->GetDuTempPath(), szCatalog); dwRet = m_pDu->DownloadFile(szServerFile, szLocalFile, TRUE, FALSE);
if (ERROR_SUCCESS != dwRet) { SetLastError(dwRet); return FALSE; } if (GetPrivateProfileString("redir", "invCRC", "", szInvCRC, sizeof(szInvCRC), szLocalFile) == 0) { LOG_error("Unable to Read Inventory CRC value from Setup Catalog"); return FALSE; }
if (GetPrivateProfileString("redir", "bmCRC", "", szBmCRC, sizeof(szBmCRC), szLocalFile) == 0) { LOG_error("Unable to Read Bitmask CRC value for Setup Catalog"); return FALSE; }
char szBMCRCFileName[MAX_PATH]; wsprintf(szBMCRCFileName, "%s.bm", szBmCRC); if (!GetBitMask(szBMCRCFileName, m_puidSetupCatalog, &m_pBitMaskAS, "bitmask.as")) { LOG_error("Unable to Read Bitmask File for AS"); return FALSE; } // now download the real catalog
wsprintf(szCatalog, "%d/%s.inv", m_puidSetupCatalog, szInvCRC); m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, szCatalog); SafeGlobalFree(m_pSetupCatalog); wsprintf(szCatalog, "%s.inv", szInvCRC); m_pDu->DownloadFileToMem(szServerFile, &m_pSetupCatalog, &dwLength, TRUE, szCatalog, "inventory.as"); if (NULL == m_pSetupCatalog) { LOG_error("Failed to download Consumer Catalog, %d", m_puidSetupCatalog); return FALSE; }
pWalkCatalog = m_pSetupCatalog;
// Read the Catalog Header
ZeroMemory(&hdr, sizeof(hdr)); memcpy(&hdr, pWalkCatalog, sizeof(hdr));
m_pSetupItems[hdr.totalItems] = NULL; // just to preinitialize the array.
pWalkCatalog += sizeof(hdr);
// walk the list and read the items.
for (i = 0; i < hdr.totalItems; i++) { pItem = (PINVENTORY_ITEM) GlobalAlloc(GMEM_ZEROINIT, sizeof(INVENTORY_ITEM)); if (NULL == pItem) { dwRet = GetLastError(); LOG_error("Failed to Alloc Memory for Inventory Item, Error %d", dwRet); return FALSE; }
pWalkCatalog = GetNextRecord(pWalkCatalog, i, pItem); if (!pWalkCatalog) { LOG_error("Failed to Alloc Memory for InventoryI Item State, Error %d", GetLastError()); return FALSE; }
if (!pItem->ps->bHidden && !GETBIT(m_pBitMaskAS, i)) { // this item is masked out
LOG_out("Item %d is masked out", i); pItem->ps->bHidden = TRUE; pItem->ps->state = WU_ITEM_STATE_PRUNED; pItem->ps->dwReason = WU_STATE_REASON_BITMASK; } m_pSetupItems[i] = pItem; m_dwSetupItemCount++; } }
return TRUE; }
PBYTE CV31Server::GetNextRecord(PBYTE pRecord, int iBitmaskIndex, PINVENTORY_ITEM pItem) { //first get the fixed length part of the record
pItem->pf = (PWU_INV_FIXED)pRecord;
//process the variable part of the record
pRecord = pRecord + sizeof(WU_INV_FIXED);
pItem->pv = (PWU_VARIABLE_FIELD)pRecord;
//since there is no state information create an empty structure
pItem->ps = (PWU_INV_STATE)GlobalAlloc(GMEM_ZEROINIT, sizeof(WU_INV_STATE));
if (!pItem->ps) return NULL;
//new item is unknown detection, not selected and shown to user.
pItem->ps->state = WU_ITEM_STATE_UNKNOWN; pItem->ps->bChecked = FALSE; // RogerJ, to support versioning, we will use the bHidden flag
pItem->ps->bHidden = pItem->pf->a.flags & WU_HIDDEN_ITEM_FLAG; if (pItem->ps->bHidden) m_nNumOfValidDependentPUID++; pItem->ps->dwReason = WU_STATE_REASON_NONE;
//There is no description yet
pItem->pd = (PWU_DESCRIPTION)NULL;
//we need to store the bitmap index (which is the sequential record index)
//since this information will be lost when we add the driver records.
// YanL: is not being used
// pItem->bitmaskIndex = iBitmaskIndex;
//Get record type
pItem->recordType = (BYTE)GetRecordType(pItem); pItem->ndxLinkInstall = (PUID) pItem->pf->a.installLink; //set record pointer to the beginning of the next record
pRecord += pItem->pv->GetSize();
return pRecord; }
int CV31Server::GetRecordType(PINVENTORY_ITEM pItem) { GUID driverRecordId = WU_GUID_DRIVER_RECORD; int iRecordType = 0;
if ( memcmp((void *)&pItem->pf->d.g, (void *)&driverRecordId, sizeof(WU_GUID_DRIVER_RECORD)) ) { //if the GUID field is not 0 then we have an active setup record.
iRecordType = WU_TYPE_ACTIVE_SETUP_RECORD;//active setup record type
} else { //else this is either a driver record place holder or a section - sub section
//record. So we need to check the type field
if ( pItem->pf->d.type == SECTION_RECORD_TYPE_DEVICE_DRIVER_INSERTION ) { //cdm driver place holder record
iRecordType = WU_TYPE_CDM_RECORD_PLACE_HOLDER; //cdm code download manager place holder record
} else if ( pItem->pf->d.type == SECTION_RECORD_TYPE_PRINTER ) { //Note: We may need to use this to support printers on win 98.
iRecordType = WU_TYPE_RECORD_TYPE_PRINTER; //printer record
} else if ( pItem->pf->d.type == SECTION_RECORD_TYPE_DRIVER_RECORD ) { iRecordType = WU_TYPE_CDM_RECORD; //Corporate catalog device driver
} else if ( pItem->pf->s.type == SECTION_RECORD_TYPE_CATALOG_RECORD ) { iRecordType = WU_TYPE_CATALOG_RECORD; } else { //we have either a section, sub section or sub sub section record
switch ( pItem->pf->s.level ) { case 0: iRecordType = WU_TYPE_SECTION_RECORD; break; case 1: iRecordType = WU_TYPE_SUBSECTION_RECORD; break; case 2: iRecordType = WU_TYPE_SUBSUBSECTION_RECORD; break; } } }
return iRecordType; }
// --------------------------------------------------------------------------
// CV31Server::UpdateDownloadItemList()
//
// Parses the Catalogs and gets a list of Items in the Correct Platform SKU
// section to download.
//
//
// --------------------------------------------------------------------------
BOOL CV31Server::UpdateDownloadItemList(OSVERSIONINFOEX& VersionInfo) { LOG_block("CV31Server::UpdateDownloadItemList()"); ULONG ulItem = 0; int iRecordType = 0; BOOL fFound = FALSE, fRet; char szServerFile[INTERNET_MAX_URL_LENGTH + 1]; char szMapFileName[MAX_PATH]; char szLocale[32]; DWORD dwLength; PBYTE pMapMem = NULL; PWU_VARIABLE_FIELD pvCabs; PWU_VARIABLE_FIELD pvCRCs; int iCabNum = 0; BOOL fRetValue = TRUE; wsprintf(szLocale, "0x%8.8x", m_lcidLocaleID);
wsprintf(szMapFileName, "%d_%s.des", m_dwPlatformID, szLocale); m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, szMapFileName); m_pDu->DownloadFileToMem(szServerFile, &pMapMem, &dwLength, TRUE, szMapFileName, NULL);
if (NULL == pMapMem) { LOG_error("Failed to Download CRC Map File %s", szServerFile); return FALSE; }
CCRCMapFile DescMap(pMapMem, dwLength);
// Before we add any items to the download list we need to clear the download list
// from any previous calls to DoDetection.
m_pDu->EnterDownloadListCriticalSection(); // if we're downloading we don't want to allow the download list to change
m_pDu->ClearDownloadItemList();
if (0 != m_dwSetupItemCount) { // We have a valid Setup Catalog, find the Correct Section based on SKU
// ROGERJ, october 24, 2000
// we need to make a list of valid dependency item first
if (!MakeDependentList(VersionInfo, &DescMap)) { // last error will be set by MakeDependentList() function
fRetValue = FALSE; goto ReturnPoint; } // We want to walk the Catalog Looking for the Section PUID that matches our requested Platform SKU
for (ulItem = 0; ulItem < m_dwSetupItemCount; ulItem++) { if (WU_TYPE_SECTION_RECORD == m_pSetupItems[ulItem]->recordType) { if (m_pSetupItems[ulItem]->pf->s.puid == m_enumPlatformSKU) { // found the correct section
fFound = TRUE; break; } } }
if (fFound) { ulItem++; // advance to the next item
// until we find the next section, or the end of the catalog
while ((ulItem < m_dwSetupItemCount) && (WU_TYPE_SECTION_RECORD != GetRecordType(m_pSetupItems[ulItem]))) { PINVENTORY_ITEM pItem = m_pSetupItems[ulItem];
// ROGERJ, October 24th, 2000 --- determine if the item is applied to this version
// skip hidden item
if (pItem->ps->bHidden) { ulItem++; continue; } // determine if this item valid on this build
if ( 0 != pItem->pf->a.installLink && // has dependency
!IsDependencyApply(pItem->pf->a.installLink)) // dependency not apply to this version
{ // if the dependency item is not valid in this version, skip
ulItem++; continue; } char szServerCab[128]; char szLocalCab[128]; // The next section record marks the end of the items valid for this SKU
fRet = ReadDescription(pItem, &DescMap); if (!fRet) { // failed to read description file for this item, skip it.
ulItem++; continue; }
pvCabs = pItem->pd->pv->Find(WU_DESCRIPTION_CABFILENAME); pvCRCs = pItem->pd->pv->Find(WU_DESC_CRC_ARRAY);
if ((NULL == pvCabs) || (NULL == pvCRCs)) { // no cab list or CRC list in the description file
ulItem++; continue; }
DOWNLOADITEM *pDownloadItem = (DOWNLOADITEM *)GlobalAlloc(GMEM_ZEROINIT, sizeof(DOWNLOADITEM)); if (NULL == pDownloadItem) { LOG_error("Error Allocating Memory for new Download Item"); fRetValue = FALSE; goto ReturnPoint; } pDownloadItem->dwTotalFileSize = pItem->pd->size * 1024; // Estimated Size in Bytes
pDownloadItem->puid = pItem->pf->a.puid;
LPSTR pszCabName = pDownloadItem->mszFileList;
iCabNum = 0; for (;;) { if (FAILED(GetCRCNameFromList(iCabNum, pvCabs->pData, pvCRCs->pData, szServerCab, sizeof(szServerCab), szLocalCab))) { break; // no more cabs
}
pDownloadItem->iNumberOfCabs++;
lstrcpy(pszCabName, szServerCab); pszCabName += lstrlen(pszCabName) + 1; *pszCabName = '\0'; // double null terminate
pszCabName++; // next cab
iCabNum++; }
// don't add the item unless there are cabs for it.
if (pDownloadItem->iNumberOfCabs > 0 && !IsPUIDExcluded(pItem->pf->a.puid)) // before adding this item to the list, check to see if it should be excluded based
// on the Catalog.INI
m_pDu->AddDownloadItemToList(pDownloadItem);
SafeGlobalFree(pItem->pd); ulItem++; } } } ReturnPoint: m_pDu->LeaveDownloadListCriticalSection(); SafeGlobalFree(pMapMem); return fRetValue; }
BOOL CV31Server::ReadDescription(PINVENTORY_ITEM pItem, CCRCMapFile *pMapFile) { if ((NULL == pItem) || (NULL == pMapFile)) { return FALSE; }
LOG_block("CV31Server::ReadDescription()");
char szServerFile[INTERNET_MAX_URL_LENGTH + 1]; char szDownloadFile[MAX_PATH]; PWU_DESCRIPTION pd; DWORD dwLength; char szBase[64]; char szCRCName[64]; HRESULT hr = S_OK;
wsprintf(szBase, "%d.des", pItem->GetPuid()); hr = pMapFile->GetCRCName((DWORD)pItem->GetPuid(), szBase, szCRCName, sizeof(szCRCName)); if (FAILED(hr)) { LOG_error("Failed to get CRC Description Value for Item %d", pItem->GetPuid()); return FALSE; }
wsprintf(szDownloadFile, "CRCDesc/%s", szCRCName); m_pDu->DuUrlCombine(szServerFile, m_szV31RootUrl, szDownloadFile); m_pDu->DownloadFileToMem(szServerFile, (PBYTE *)&pd, &dwLength, TRUE, szCRCName, "desc.as");
if (NULL == pd) { LOG_error("Failed to download Description File %s", szServerFile); return FALSE; }
// for 64 bit, the description is off by size of DWORD
//if (19 == m_pDu->m_iPlatformID)
// 64 bit
// pd->pv = (PWU_VARIABLE_FIELD)(((PBYTE)pd) + sizeof(WU_DESCRIPTION) + sizeof(DWORD));
//else
// 32 bit
pd->pv = (PWU_VARIABLE_FIELD)(((PBYTE)pd) + sizeof(WU_DESCRIPTION)); pItem->pd = pd; return TRUE; }
void CV31Server::FreeCatalogs() { for (DWORD dwcnt = 0; dwcnt < m_dwSetupItemCount; dwcnt++) { if (m_pSetupItems[dwcnt]) { SafeGlobalFree(m_pSetupItems[dwcnt]->ps); SafeGlobalFree(m_pSetupItems[dwcnt]->pd); SafeGlobalFree(m_pSetupItems[dwcnt]); } }
for (dwcnt = 0; dwcnt < m_dwConsumerItemCount; dwcnt++) { if (m_pConsumerItems[dwcnt]) { SafeGlobalFree(m_pConsumerItems[dwcnt]->ps); SafeGlobalFree(m_pConsumerItems[dwcnt]->pd); SafeGlobalFree(m_pConsumerItems[dwcnt]); } }
m_dwSetupItemCount = 0; m_dwConsumerItemCount = 0; }
BOOL CV31Server::MakeDependentList(OSVERSIONINFOEX &VersionInfo, CCRCMapFile *pMapFile) { // Log
LOG_block("CV31Server::MakeDependentList()");
// make sure the array is empty
SafeGlobalFree(m_pValidDependentPUIDArray); // no dependency item
if (!m_nNumOfValidDependentPUID) return TRUE;
int nPUIDIndex = 0; // allocate the memory
m_pValidDependentPUIDArray = (PUID*) GlobalAlloc(GMEM_ZEROINIT, sizeof(PUID)*m_nNumOfValidDependentPUID); if (!m_pValidDependentPUIDArray) { LOG_error("Out of memory"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } ULONG ulItem; for (ulItem = 0; ulItem < m_dwSetupItemCount && nPUIDIndex < m_nNumOfValidDependentPUID; ulItem++) { if (WU_TYPE_ACTIVE_SETUP_RECORD != GetRecordType(m_pSetupItems[ulItem]) || !m_pSetupItems[ulItem]->ps->bHidden || m_pSetupItems[ulItem]->ps->state == WU_ITEM_STATE_PRUNED) continue; PINVENTORY_ITEM pItem = m_pSetupItems[ulItem]; // get a hidden setup dependency item record
BOOL fRet = ReadDescription(pItem, pMapFile); if (!fRet) // failed to read description file for this item, assume this dependency does not apply
// this way, we will not download any item not apply, but may miss some items that apply
continue; // Title is composed as BuildMin.BuildMax.SPMajor.SPMinor
PWU_VARIABLE_FIELD pvField = pItem->pd->pv->Find(WU_DESCRIPTION_TITLE); if (!pvField) { // title is NULL, error, ignore this item
LOG_error("Title is NULL"); continue; } wchar_t * pvTitle = (wchar_t*) pvField->pData; DWORD dwBuild[4]; dwBuild[0]=0; dwBuild[1]=99999; dwBuild[2]=0; dwBuild[3]=0; int nBuildIndex = 0; int nTemp = 0; BOOL fBreak = FALSE; while (nBuildIndex<4 && !fBreak) { if (*pvTitle != L'.' && *pvTitle != NULL ) { if (*pvTitle > L'9' || *pvTitle < '0') { // illegal use of this title
LOG_error("Illegal character '%c' found in the title",(char)*pvTitle); SetLastError(ERROR_INVALID_DATA); return FALSE; } else { nTemp *=10; nTemp += (*pvTitle - L'0'); } } else { if (!*pvTitle) fBreak = TRUE; dwBuild[nBuildIndex++] = nTemp; nTemp = 0; } pvTitle++; }
LOG_out("Title is %d.%d.%d.%d\n", dwBuild[0], dwBuild[1], dwBuild[2], dwBuild[3]); // determine if this item apply
if (dwBuild[0] <= VersionInfo.dwBuildNumber && dwBuild[1] >= VersionInfo.dwBuildNumber && dwBuild[2] == VersionInfo.wServicePackMajor&& dwBuild[3] == VersionInfo.wServicePackMinor) { // applys, add this to the list
LOG_out("This dependency item applied"); m_pValidDependentPUIDArray[nPUIDIndex++] = pItem->GetPuid(); } else LOG_out("This dependency item NOT applied"); } return TRUE; }
BOOL CV31Server::IsDependencyApply(PUID puid) { LOG_block("CV31Server::IsDependencyApply()"); LOG_out("puid(%d)", (long)puid); // handle no link
if (WU_NO_LINK == puid) return TRUE; // no depend item is valid
if (!m_nNumOfValidDependentPUID) { LOG_out("No dependecy item"); return FALSE; } for (int nItem = 0; nItem < m_nNumOfValidDependentPUID; nItem ++) { if (m_pValidDependentPUIDArray[nItem] == puid) { LOG_out ("puid(%d) applies", (long)puid); return TRUE; } if (m_pValidDependentPUIDArray[nItem] == 0) break; // 0 mark the end of valid puid
} LOG_out("puid(%d) does not apply", (long)puid); return FALSE; }
BOOL CV31Server::GetBitMask(LPSTR szBitmapLocalFileName, PUID nDirectoryPuid, PBYTE* pByte, LPSTR szDecompressedName) { LOG_block("CV31Server::GetBitMask()"); LOG_out("Parameters --- %s",szBitmapLocalFileName); SetLastError(0); // Parameter validation
if (!szBitmapLocalFileName) { LOG_error("Invalid Parameter"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
SafeGlobalFree(*pByte);
PBITMASK pBitMask = NULL; DWORD dwLength = 0; DWORD dwError = 0; BOOL fRetVal = FALSE; // log parameter
LOG_out("szBitmapLocalFileName(%s)",szBitmapLocalFileName);
char szBitmapServerFileName[INTERNET_MAX_URL_LENGTH]; ZeroMemory(szBitmapServerFileName, INTERNET_MAX_URL_LENGTH*sizeof(char));
char szBitmapFileWithDir[MAX_PATH]; wsprintf(szBitmapFileWithDir, "%d/%s", nDirectoryPuid, szBitmapLocalFileName);
m_pDu->DuUrlCombine(szBitmapServerFileName, m_szV31ContentUrl, szBitmapFileWithDir);
dwError = m_pDu->DownloadFileToMem(szBitmapServerFileName, (PBYTE*)&pBitMask, &dwLength, TRUE, szBitmapLocalFileName, szDecompressedName); if (ERROR_SUCCESS != dwError) { LOG_error("Failed to download %s --- %d", szBitmapServerFileName, dwError); return FALSE; }
int iMaskByteSize = ((pBitMask->iRecordSize+7)/8); int nIndex = 0; for (int nItem =0; nItem < pBitMask->iLocaleCount; nItem ++) { nIndex = pBitMask->iOemCount + nItem; if (pBitMask->bmID[nIndex] == m_pDu->m_lcidLocaleID) break; }
if (nItem >= pBitMask->iLocaleCount) { // not found
// bad locale ? or missing locale info?
LOG_error("LCID %d is not found in %s", m_pDu->m_lcidLocaleID, szBitmapLocalFileName); SetLastError(ERROR_UNSUPPORTED_TYPE); goto ErrorReturn; }
*pByte =(PBYTE) GlobalAlloc(GMEM_ZEROINIT, iMaskByteSize); if (!pByte) { LOG_error("Out of memory"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto ErrorReturn; }
CopyMemory((PVOID)*pByte, (const PVOID) pBitMask->GetBitMaskPtr(nIndex+2), iMaskByteSize);
fRetVal = TRUE;
/* The next part of the code can be used to print of bitmask.as
if (lstrcmp (szBitmapLocalFileName, "bitmask.cdm") == 0) goto ErrorReturn; for (nIndex = 0; nIndex < pBitMask->iLocaleCount; nIndex ++) { char szTTT [MAX_PATH]; ZeroMemory(szTTT, MAX_PATH); wsprintf(szTTT, "%d --- ", pBitMask->bmID[nIndex +2 + pBitMask->iOemCount]); PBYTE pTep = (PBYTE) pBitMask->GetBitMaskPtr(nIndex +2 + pBitMask->iOemCount); for (nItem = 0; nItem < iMaskByteSize; nItem ++) { char szTTTTT [MAX_PATH]; wsprintf(szTTTTT, "%d, ", pTep[nItem]); lstrcat(szTTT, szTTTTT); } LOG_out("%s", szTTT); }*/ ErrorReturn: SafeGlobalFree(pBitMask); return fRetVal; }
BOOL CV31Server::ReadGuidrvINF() { LOG_block("CV31Server::ReadGuidrvINF()"); char szServerFile[INTERNET_MAX_URL_LENGTH + 1]; char szLocalFile[MAX_PATH]; char szValue[1024]; int nDefaultBufferLength = 512;
SafeGlobalFree(m_pszExcludedDriver); // Now read the Catalog.ini file to find out if any of these items needs to be turned off
m_pDu->DuUrlCombine(szServerFile, m_szV31ContentUrl, GUIDRVINF); PathCombineA(szLocalFile, m_pDu->GetDuDownloadPath(), GUIDRVINF); if (ERROR_SUCCESS!=m_pDu->DownloadFile(szServerFile, szLocalFile, FALSE, FALSE)) { LOG_out("No guidrv.inf found"); return TRUE; } int nReadLength; do { nDefaultBufferLength <<=1; SafeGlobalFree(m_pszExcludedDriver); m_pszExcludedDriver = (LPSTR) GlobalAlloc(GPTR, nDefaultBufferLength * sizeof(char)); if (!m_pszExcludedDriver) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); LOG_error("Out of memory"); return FALSE; } nReadLength = GetPrivateProfileSectionA("ExcludedDrivers", m_pszExcludedDriver, nDefaultBufferLength, szLocalFile); } while ( nDefaultBufferLength-2 == nReadLength);
if (!lstrlenA(m_pszExcludedDriver)) { SafeGlobalFree(m_pszExcludedDriver); m_pszExcludedDriver = NULL; } return TRUE; }
BOOL CV31Server::IsPUIDExcluded(PUID nPuid) { if (m_dwGlobalExclusionItemCount > 0) { for (DWORD dwCnt = 0; dwCnt < m_dwGlobalExclusionItemCount; dwCnt++) { if (nPuid == m_GlobalExclusionArray[dwCnt]) return TRUE; } } return FALSE; }
BOOL CV31Server::IsDriverExcluded(LPCSTR szWHQLId, LPCSTR szHardwareId) { LOG_block("CV31Server::IsDriverExcluded()"); LOG_out("%s %s", szWHQLId, szHardwareId); if(m_pszExcludedDriver) { char* pTemp = m_pszExcludedDriver; while (*pTemp) { // try to find if the driver is excluded
char* pCharEnd = pTemp; char* pCharBegin = pTemp; // first one is the id for the cab
while (*pCharEnd != ',' && *pCharEnd != '\0') pCharEnd++; if (NULL == *pCharEnd) { LOG_error("guidrvs.inf corruption --- %s", pTemp); return TRUE; // guidrvs.inf corrupted, assume excluded
} if (lstrlenA(szWHQLId) == (int)(pCharEnd - pCharBegin) && !StrCmpNI(szWHQLId, pCharBegin, (int)(pCharEnd-pCharBegin))) { // cab name matches, try to match hardware id
// ignore second and third one
for (int i=0; i<2; i++) { pCharBegin = pCharEnd + 1; pCharEnd = pCharBegin; while (*pCharEnd != ',' && *pCharEnd != '\0') pCharEnd++; if (NULL == *pCharEnd) { LOG_error("guidrvs.inf corruption --- %s", pTemp); return TRUE; // guidrv.inf corrupted, assume excluded
} } // the forth one should be the hardware id
pCharBegin = pCharEnd + 1; if (!lstrcmpi(szHardwareId, pCharBegin) || ('*' == *pCharBegin && !*(pCharBegin+1))) { LOG_out("Found match in guidrvs.inf, excluded --- %s", pTemp); return TRUE; } } // move to next string
pTemp += lstrlenA(pTemp) + 1; } } return FALSE; }
BOOL CV31Server::GetAltName(LPCSTR szCabName, LPSTR szAltName, int nSize) { if (!szCabName || !szAltName) return FALSE;
char* pTemp = const_cast<char*>(szCabName); while (*pTemp && *pTemp != '_') pTemp++; int nTempSize = (int)(pTemp-szCabName); if (nTempSize >= nSize) return FALSE; lstrcpynA(szAltName, szCabName, nTempSize+1); return TRUE; }
|