Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

246 lines
7.5 KiB

//
// File: Database.cpp
// BY: Anthony V. Demarco
// Date: 12/28/1999
// Description: Contains routines for reading system update registry entries into an
// internal database. See Database.h for database structure.
// Copyright (c) Microsoft Corporation 1999-2000
//
#include "stdafx.h"
#include "Database.h"
#define BUFFER_SIZE 255
PPRODUCT BuildDatabase(_TCHAR * lpszComputerName)
{
HKEY hPrimaryKey; // Handle of the target system HKLM
// _TCHAR szPrimaryPath; // Path to the update key;
HKEY hUpdatesKey; // Handle to the updates key.
_TCHAR szUpdatesPath[BUFFER_SIZE]; // Path to the udates key
DWORD dwUpdatesIndex; // index of current updates subkey
DWORD dwBufferSize; // Size of the product name buffer.
_TCHAR szProductPath[BUFFER_SIZE]; // Path of the current product key
_TCHAR szProductName[BUFFER_SIZE]; // Name of product; also path to product key
PPRODUCT pProductList = NULL; // Pointer to the head of the product list.
PPRODUCT pNewProdNode; // Pointer used to allocate new nodes in the product list.
PPRODUCT pCurrProdNode; // Used to walk the Products List;
// Connect to the target registry
RegConnectRegistry(lpszComputerName,HKEY_LOCAL_MACHINE, &hPrimaryKey);
// insert error handling here......
if (hPrimaryKey != NULL)
{
// Initialize the primary path not localized since registry keys are not localized.
_tcscpy (szUpdatesPath, _T("SOFTWARE\\Microsoft\\Updates"));
// open the udates key
RegOpenKeyEx(hPrimaryKey,szUpdatesPath, 0, KEY_READ ,&hUpdatesKey);
// Enumerate the Updates key.
dwUpdatesIndex = 0;
while ( RegEnumKeyEx(hUpdatesKey,dwUpdatesIndex,szProductName, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
{
// Create a node for the current product
pNewProdNode = (PPRODUCT) malloc(sizeof(PPRODUCT));
_tcscpy(pNewProdNode->ProductName,szProductName);
_tcscpy (szProductPath, szProductName);
// now get the hotfix for the current product.
pNewProdNode->HotfixList = GetHotfixInfo(szProductName, &hUpdatesKey);
// Insert the new node into the list.
pCurrProdNode=pProductList;
if (pCurrProdNode == NULL) // Head of the list
{
pProductList = pNewProdNode;
pProductList->pPrev = NULL;
pProductList->pNext = NULL;
}
else
{
//Find the end of the list.
while (pCurrProdNode->pNext != NULL)
pCurrProdNode = pCurrProdNode->pNext;
// Now insert the new node at the end of the list.
pCurrProdNode->pNext = pNewProdNode;
pNewProdNode->pPrev = pCurrProdNode;
pNewProdNode->pNext = NULL;
}
// increment index and clear the szProducts name string for the next pass.
dwUpdatesIndex++;
_tcscpy (szProductName,_T("\0"));
_tcscpy(szProductPath, _T("\0"));
dwBufferSize = 255;
}
}
// close the open keys
RegCloseKey(hUpdatesKey);
RegCloseKey(hPrimaryKey);
// return a pointer to the head of our database.
return pProductList;
}
PHOTFIXLIST GetHotfixInfo( _TCHAR * pszProductName, HKEY* hUpdateKey )
{
HKEY hHotfix; // Handle of the hotfix key being processed.
HKEY hProduct; // Handle to the current product key
_TCHAR szHotfixName[BUFFER_SIZE]; // Name of the current hotfix.
// _TCHAR szHotfixPath[BUFFER_SIZE]; // Path of the current hotfix key
_TCHAR szValueName[BUFFER_SIZE];
PHOTFIXLIST pHotfixList = NULL; // Pointer to the head of the hotfix list.
PHOTFIXLIST pCurrNode; // Used to walk the list of hotfixes
PHOTFIXLIST pNewNode; // Used to create nodes to be added to the list.
DWORD dwBufferSize; // Size of the product name buffer.
DWORD dwValIndex; // index of current value.
DWORD dwHotfixIndex = 0;
BYTE *Data;
DWORD dwDataSize = BUFFER_SIZE;
DWORD dwValType;
Data = (BYTE *) malloc(BUFFER_SIZE);
// Open the current product key
RegOpenKeyEx(*hUpdateKey,pszProductName,0 , KEY_READ, &hProduct);
dwHotfixIndex = 0;
dwBufferSize = BUFFER_SIZE;
while (RegEnumKeyEx(hProduct,dwHotfixIndex, szHotfixName,&dwBufferSize, 0, NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
{
// now create a new node
pNewNode = (PHOTFIXLIST) malloc (sizeof(PHOTFIXLIST));
pNewNode->pNext = NULL;
pNewNode->FileList = NULL;
_tcscpy(pNewNode->HotfixName,szHotfixName);
// open the hotfix key
RegOpenKeyEx(hProduct,szHotfixName,0,KEY_READ,&hHotfix);
// Now enumerate the values of the current hotfix.
dwValIndex = 0;
dwBufferSize =BUFFER_SIZE;
dwDataSize = BUFFER_SIZE;
while (RegEnumValue(hHotfix,dwValIndex, szValueName,&dwBufferSize, 0,&dwValType, Data, &dwDataSize) != ERROR_NO_MORE_ITEMS)
{
// Fill in the hotfix data members.
++ dwValIndex;
_tcscpy (szValueName, _T("\0"));
ZeroMemory(Data,BUFFER_SIZE);
dwValType = 0;
dwBufferSize =BUFFER_SIZE;
dwDataSize = BUFFER_SIZE;
}
// Get the file list for the current hotfix.
pNewNode->FileList = GetFileInfo(&hHotfix);
//insert the new node at the end of the hotfix list.
if (pHotfixList = NULL)
{
pHotfixList = pNewNode;
pHotfixList->pPrev = NULL;
pHotfixList->pNext = NULL;
}
else
{
pCurrNode = pHotfixList;
while (pCurrNode->pNext != NULL)
pCurrNode = pCurrNode->pNext;
pCurrNode->pNext = pNewNode;
pNewNode->pPrev = pCurrNode;
pNewNode->pNext = NULL;
}
// Close the current Hotfix Key
RegCloseKey(hHotfix);
// Clear the strings.
_tcscpy(szHotfixName,_T("\0"));
// increment the current index
++dwHotfixIndex;
dwBufferSize = BUFFER_SIZE;
}
// Close all open keys
RegCloseKey(hProduct);
if (Data != NULL)
free (Data);
return pHotfixList;
}
PFILELIST GetFileInfo(HKEY* hHotfixKey)
{
PFILELIST pFileList = NULL; // Pointer to the head of the file list.
// _TCHAR szFilePath; // Path to the files subkey.
PFILELIST pNewNode = NULL;
PFILELIST pCurrNode = NULL;;
BYTE * Data;
DWORD dwBufferSize = BUFFER_SIZE;
DWORD dwDataSize = BUFFER_SIZE;
DWORD dwFileIndex = 0;
DWORD dwPrimeIndex = 0;
DWORD dwValType = 0;
HKEY hPrimaryFile;
HKEY hFileKey;
_TCHAR szFileSubKey[BUFFER_SIZE];
_TCHAR szValueName[BUFFER_SIZE];
Data = (BYTE *) malloc(BUFFER_SIZE);
ZeroMemory(Data,BUFFER_SIZE);
// Open the files subkey of the current hotfix
RegOpenKeyEx(*hHotfixKey, _T("Files"),0,KEY_READ,&hPrimaryFile);
while (RegEnumKeyEx(hPrimaryFile,dwPrimeIndex,szFileSubKey, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
{
// open the subfile key
RegOpenKeyEx(hPrimaryFile,szFileSubKey,0,KEY_READ,&hFileKey);
// Enumerate the file(x) subkeys of the file subkey
while (RegEnumValue(hFileKey,dwFileIndex,szValueName,&dwBufferSize,0,&dwValType,Data,&dwDataSize) != ERROR_NO_MORE_ITEMS)
{
pNewNode = (PFILELIST) malloc (sizeof(PFILELIST));
pNewNode->pNext = NULL;
pNewNode->pPrev = NULL;
dwFileIndex ++;
_tcscpy(szValueName,_T("\0"));
ZeroMemory(Data,BUFFER_SIZE);
dwValType = 0;
dwBufferSize = BUFFER_SIZE;
dwDataSize = BUFFER_SIZE;
}
RegCloseKey(hFileKey);
// add the current node to the list
if (pFileList == NULL)
{
pFileList = pNewNode;
}
else
{
pCurrNode = pFileList;
while (pCurrNode->pNext != NULL)
pCurrNode = pCurrNode->pNext;
pCurrNode->pNext = pNewNode;
}
} // end enum of primary file key
RegCloseKey(hPrimaryFile);
if (Data != NUL)
free (Data);
return pFileList;
}