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

  1. //
  2. // File: Database.cpp
  3. // BY: Anthony V. Demarco
  4. // Date: 12/28/1999
  5. // Description: Contains routines for reading system update registry entries into an
  6. // internal database. See Database.h for database structure.
  7. // Copyright (c) Microsoft Corporation 1999-2000
  8. //
  9. #include "stdafx.h"
  10. #include "Database.h"
  11. #define BUFFER_SIZE 255
  12. PPRODUCT BuildDatabase(_TCHAR * lpszComputerName)
  13. {
  14. HKEY hPrimaryKey; // Handle of the target system HKLM
  15. // _TCHAR szPrimaryPath; // Path to the update key;
  16. HKEY hUpdatesKey; // Handle to the updates key.
  17. _TCHAR szUpdatesPath[BUFFER_SIZE]; // Path to the udates key
  18. DWORD dwUpdatesIndex; // index of current updates subkey
  19. DWORD dwBufferSize; // Size of the product name buffer.
  20. _TCHAR szProductPath[BUFFER_SIZE]; // Path of the current product key
  21. _TCHAR szProductName[BUFFER_SIZE]; // Name of product; also path to product key
  22. PPRODUCT pProductList = NULL; // Pointer to the head of the product list.
  23. PPRODUCT pNewProdNode; // Pointer used to allocate new nodes in the product list.
  24. PPRODUCT pCurrProdNode; // Used to walk the Products List;
  25. // Connect to the target registry
  26. RegConnectRegistry(lpszComputerName,HKEY_LOCAL_MACHINE, &hPrimaryKey);
  27. // insert error handling here......
  28. if (hPrimaryKey != NULL)
  29. {
  30. // Initialize the primary path not localized since registry keys are not localized.
  31. _tcscpy (szUpdatesPath, _T("SOFTWARE\\Microsoft\\Updates"));
  32. // open the udates key
  33. RegOpenKeyEx(hPrimaryKey,szUpdatesPath, 0, KEY_READ ,&hUpdatesKey);
  34. // Enumerate the Updates key.
  35. dwUpdatesIndex = 0;
  36. while ( RegEnumKeyEx(hUpdatesKey,dwUpdatesIndex,szProductName, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
  37. {
  38. // Create a node for the current product
  39. pNewProdNode = (PPRODUCT) malloc(sizeof(PPRODUCT));
  40. _tcscpy(pNewProdNode->ProductName,szProductName);
  41. _tcscpy (szProductPath, szProductName);
  42. // now get the hotfix for the current product.
  43. pNewProdNode->HotfixList = GetHotfixInfo(szProductName, &hUpdatesKey);
  44. // Insert the new node into the list.
  45. pCurrProdNode=pProductList;
  46. if (pCurrProdNode == NULL) // Head of the list
  47. {
  48. pProductList = pNewProdNode;
  49. pProductList->pPrev = NULL;
  50. pProductList->pNext = NULL;
  51. }
  52. else
  53. {
  54. //Find the end of the list.
  55. while (pCurrProdNode->pNext != NULL)
  56. pCurrProdNode = pCurrProdNode->pNext;
  57. // Now insert the new node at the end of the list.
  58. pCurrProdNode->pNext = pNewProdNode;
  59. pNewProdNode->pPrev = pCurrProdNode;
  60. pNewProdNode->pNext = NULL;
  61. }
  62. // increment index and clear the szProducts name string for the next pass.
  63. dwUpdatesIndex++;
  64. _tcscpy (szProductName,_T("\0"));
  65. _tcscpy(szProductPath, _T("\0"));
  66. dwBufferSize = 255;
  67. }
  68. }
  69. // close the open keys
  70. RegCloseKey(hUpdatesKey);
  71. RegCloseKey(hPrimaryKey);
  72. // return a pointer to the head of our database.
  73. return pProductList;
  74. }
  75. PHOTFIXLIST GetHotfixInfo( _TCHAR * pszProductName, HKEY* hUpdateKey )
  76. {
  77. HKEY hHotfix; // Handle of the hotfix key being processed.
  78. HKEY hProduct; // Handle to the current product key
  79. _TCHAR szHotfixName[BUFFER_SIZE]; // Name of the current hotfix.
  80. // _TCHAR szHotfixPath[BUFFER_SIZE]; // Path of the current hotfix key
  81. _TCHAR szValueName[BUFFER_SIZE];
  82. PHOTFIXLIST pHotfixList = NULL; // Pointer to the head of the hotfix list.
  83. PHOTFIXLIST pCurrNode; // Used to walk the list of hotfixes
  84. PHOTFIXLIST pNewNode; // Used to create nodes to be added to the list.
  85. DWORD dwBufferSize; // Size of the product name buffer.
  86. DWORD dwValIndex; // index of current value.
  87. DWORD dwHotfixIndex = 0;
  88. BYTE *Data;
  89. DWORD dwDataSize = BUFFER_SIZE;
  90. DWORD dwValType;
  91. Data = (BYTE *) malloc(BUFFER_SIZE);
  92. // Open the current product key
  93. RegOpenKeyEx(*hUpdateKey,pszProductName,0 , KEY_READ, &hProduct);
  94. dwHotfixIndex = 0;
  95. dwBufferSize = BUFFER_SIZE;
  96. while (RegEnumKeyEx(hProduct,dwHotfixIndex, szHotfixName,&dwBufferSize, 0, NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
  97. {
  98. // now create a new node
  99. pNewNode = (PHOTFIXLIST) malloc (sizeof(PHOTFIXLIST));
  100. pNewNode->pNext = NULL;
  101. pNewNode->FileList = NULL;
  102. _tcscpy(pNewNode->HotfixName,szHotfixName);
  103. // open the hotfix key
  104. RegOpenKeyEx(hProduct,szHotfixName,0,KEY_READ,&hHotfix);
  105. // Now enumerate the values of the current hotfix.
  106. dwValIndex = 0;
  107. dwBufferSize =BUFFER_SIZE;
  108. dwDataSize = BUFFER_SIZE;
  109. while (RegEnumValue(hHotfix,dwValIndex, szValueName,&dwBufferSize, 0,&dwValType, Data, &dwDataSize) != ERROR_NO_MORE_ITEMS)
  110. {
  111. // Fill in the hotfix data members.
  112. ++ dwValIndex;
  113. _tcscpy (szValueName, _T("\0"));
  114. ZeroMemory(Data,BUFFER_SIZE);
  115. dwValType = 0;
  116. dwBufferSize =BUFFER_SIZE;
  117. dwDataSize = BUFFER_SIZE;
  118. }
  119. // Get the file list for the current hotfix.
  120. pNewNode->FileList = GetFileInfo(&hHotfix);
  121. //insert the new node at the end of the hotfix list.
  122. if (pHotfixList = NULL)
  123. {
  124. pHotfixList = pNewNode;
  125. pHotfixList->pPrev = NULL;
  126. pHotfixList->pNext = NULL;
  127. }
  128. else
  129. {
  130. pCurrNode = pHotfixList;
  131. while (pCurrNode->pNext != NULL)
  132. pCurrNode = pCurrNode->pNext;
  133. pCurrNode->pNext = pNewNode;
  134. pNewNode->pPrev = pCurrNode;
  135. pNewNode->pNext = NULL;
  136. }
  137. // Close the current Hotfix Key
  138. RegCloseKey(hHotfix);
  139. // Clear the strings.
  140. _tcscpy(szHotfixName,_T("\0"));
  141. // increment the current index
  142. ++dwHotfixIndex;
  143. dwBufferSize = BUFFER_SIZE;
  144. }
  145. // Close all open keys
  146. RegCloseKey(hProduct);
  147. if (Data != NULL)
  148. free (Data);
  149. return pHotfixList;
  150. }
  151. PFILELIST GetFileInfo(HKEY* hHotfixKey)
  152. {
  153. PFILELIST pFileList = NULL; // Pointer to the head of the file list.
  154. // _TCHAR szFilePath; // Path to the files subkey.
  155. PFILELIST pNewNode = NULL;
  156. PFILELIST pCurrNode = NULL;;
  157. BYTE * Data;
  158. DWORD dwBufferSize = BUFFER_SIZE;
  159. DWORD dwDataSize = BUFFER_SIZE;
  160. DWORD dwFileIndex = 0;
  161. DWORD dwPrimeIndex = 0;
  162. DWORD dwValType = 0;
  163. HKEY hPrimaryFile;
  164. HKEY hFileKey;
  165. _TCHAR szFileSubKey[BUFFER_SIZE];
  166. _TCHAR szValueName[BUFFER_SIZE];
  167. Data = (BYTE *) malloc(BUFFER_SIZE);
  168. ZeroMemory(Data,BUFFER_SIZE);
  169. // Open the files subkey of the current hotfix
  170. RegOpenKeyEx(*hHotfixKey, _T("Files"),0,KEY_READ,&hPrimaryFile);
  171. while (RegEnumKeyEx(hPrimaryFile,dwPrimeIndex,szFileSubKey, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
  172. {
  173. // open the subfile key
  174. RegOpenKeyEx(hPrimaryFile,szFileSubKey,0,KEY_READ,&hFileKey);
  175. // Enumerate the file(x) subkeys of the file subkey
  176. while (RegEnumValue(hFileKey,dwFileIndex,szValueName,&dwBufferSize,0,&dwValType,Data,&dwDataSize) != ERROR_NO_MORE_ITEMS)
  177. {
  178. pNewNode = (PFILELIST) malloc (sizeof(PFILELIST));
  179. pNewNode->pNext = NULL;
  180. pNewNode->pPrev = NULL;
  181. dwFileIndex ++;
  182. _tcscpy(szValueName,_T("\0"));
  183. ZeroMemory(Data,BUFFER_SIZE);
  184. dwValType = 0;
  185. dwBufferSize = BUFFER_SIZE;
  186. dwDataSize = BUFFER_SIZE;
  187. }
  188. RegCloseKey(hFileKey);
  189. // add the current node to the list
  190. if (pFileList == NULL)
  191. {
  192. pFileList = pNewNode;
  193. }
  194. else
  195. {
  196. pCurrNode = pFileList;
  197. while (pCurrNode->pNext != NULL)
  198. pCurrNode = pCurrNode->pNext;
  199. pCurrNode->pNext = pNewNode;
  200. }
  201. } // end enum of primary file key
  202. RegCloseKey(hPrimaryFile);
  203. if (Data != NUL)
  204. free (Data);
  205. return pFileList;
  206. }