|
|
//
// 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; }
|