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.

367 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. buildhive.cpp
  5. Abstract:
  6. Builds the hive from the specified inf files.
  7. The inf files follow the same syntax as used
  8. by setup.
  9. Author:
  10. Mike Cirello
  11. Vijay Jayaseelan (vijayj)
  12. Revision History:
  13. 03 March 2001 :
  14. Rewamp the whole source to make it more maintainable
  15. (particularly readable)
  16. --*/
  17. #include <new.h>
  18. #include "buildhive.h"
  19. #include "File.h"
  20. #include "Data.h"
  21. //
  22. // Global variables used to get formatted message for this program.
  23. //
  24. HMODULE ThisModule = NULL;
  25. WCHAR Message[4096];
  26. //
  27. // Define a function to be called if new fails to allocate memory.
  28. //
  29. int __cdecl MyNewHandler( size_t size )
  30. {
  31. _putws(GetFormattedMessage( ThisModule,
  32. FALSE,
  33. Message,
  34. sizeof(Message)/sizeof(Message[0]),
  35. MSG_MEMORY_ALLOC_FAILED) );
  36. // Exit program
  37. //
  38. ExitProcess(errOUT_OF_MEMORY);
  39. }
  40. //
  41. // main() entry point
  42. //
  43. int
  44. _cdecl
  45. wmain(
  46. int Argc,
  47. wchar_t *Argv[]
  48. )
  49. {
  50. DWORD ErrorCode = 0;
  51. HANDLE hToken;
  52. ThisModule = GetModuleHandle(NULL);
  53. _set_new_handler( MyNewHandler );
  54. try {
  55. if (Argc < 2) {
  56. return ShowProgramUsage();
  57. }
  58. std::wstring InputFile = Argv[1];
  59. if ((InputFile == L"/?") ||
  60. (InputFile == L"?") ||
  61. (InputFile == L"-?") ||
  62. (InputFile == L"-h")) {
  63. return ShowProgramUsage();
  64. }
  65. RegUnLoadKey(HKEY_USERS, L"dummy");
  66. //
  67. // Set privileges needed to load and save registry keys.
  68. //
  69. OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
  70. SetPrivilege(hToken,SE_BACKUP_NAME,TRUE);
  71. SetPrivilege(hToken,SE_RESTORE_NAME,TRUE);
  72. ErrorCode = GetLastError();
  73. if (ErrorCode != ERROR_SUCCESS) {
  74. throw new W32Error(ErrorCode);
  75. }
  76. std::cout << InputFile << std::endl;
  77. //
  78. // load the configuration file
  79. //
  80. File ConfigFile(InputFile.c_str(), false);
  81. //
  82. // look for the sections defining the target files and .inf files
  83. //
  84. //
  85. // get the target directory
  86. //
  87. ConfigFile.AddInfSection(InputFile.c_str(),
  88. L"Directory",
  89. L"SetDirectory");
  90. //
  91. // set the directory
  92. //
  93. ConfigFile.ProcessSections();
  94. //
  95. // NOTE: The sections are processed in the order of addition
  96. //
  97. ConfigFile.AddInfSection(InputFile.c_str(),
  98. L"Add Registry New",
  99. L"AddRegNew");
  100. //
  101. // do the actual conversion from .inf to hive files since
  102. // we may need them for adding existing entries
  103. //
  104. ConfigFile.ProcessSections();
  105. //
  106. // process the localization specific registry sections
  107. //
  108. ConfigFile.ProcessNlsRegistryEntries();
  109. //
  110. // process modify/delete entries
  111. //
  112. ConfigFile.AddInfSection(InputFile.c_str(),
  113. L"Add Registry Existing",
  114. L"AddRegExisting");
  115. ConfigFile.AddInfSection(InputFile.c_str(),
  116. L"Delete Registry Existing",
  117. L"DelRegExisting");
  118. //
  119. // do the actual conversion from .inf to hive file
  120. //
  121. ConfigFile.ProcessSections();
  122. //
  123. // save the hive files and clean out the registry
  124. //
  125. ConfigFile.Cleanup();
  126. } catch (DWORD x) {
  127. ErrorCode = x;
  128. std::cout << GetFormattedMessage( ThisModule,
  129. FALSE,
  130. Message,
  131. sizeof(Message)/sizeof(Message[0]),
  132. MSG_ERROR_ABNORMAL_PGM_TERMINATION);
  133. switch (x) {
  134. case errFILE_LOCKED:
  135. std::cout << GetFormattedMessage(ThisModule,
  136. FALSE,
  137. Message,
  138. sizeof(Message)/sizeof(Message[0]),
  139. MSG_ERROR_FILE_LOCKED);
  140. break;
  141. case errBAD_FLAGS:
  142. std::cout << GetFormattedMessage(ThisModule,
  143. FALSE,
  144. Message,
  145. sizeof(Message)/sizeof(Message[0]),
  146. MSG_ERROR_BAD_FLAGS);
  147. break;
  148. case errFILE_NOT_FOUND:
  149. std::cout << GetFormattedMessage(ThisModule,
  150. FALSE,
  151. Message,
  152. sizeof(Message)/sizeof(Message[0]),
  153. MSG_ERROR_FILE_NOT_FOUND);
  154. break;
  155. case errGENERAL_ERROR:
  156. std::cout << GetFormattedMessage(ThisModule,
  157. FALSE,
  158. Message,
  159. sizeof(Message)/sizeof(Message[0]),
  160. MSG_ERROR_GENERAL_ERROR);
  161. break;
  162. default:
  163. std::cout << GetFormattedMessage(ThisModule,
  164. FALSE,
  165. Message,
  166. sizeof(Message)/sizeof(Message[0]),
  167. MSG_ERROR_ERROR_CODE,
  168. x);
  169. }
  170. }
  171. catch(W32Error *Error) {
  172. if (Error) {
  173. Error->Dump(std::cout);
  174. ErrorCode = Error->ErrorCode;
  175. delete Error;
  176. } else {
  177. ErrorCode = 1;
  178. }
  179. }
  180. catch(...) {
  181. ErrorCode = 1; // unknown error
  182. _putws( GetFormattedMessage(ThisModule,
  183. FALSE,
  184. Message,
  185. sizeof(Message)/sizeof(Message[0]),
  186. MSG_ERROR_ABNORMAL_PGM_TERMINATION) );
  187. }
  188. RegUnLoadKey(HKEY_USERS, L"dummy");
  189. _putws( GetFormattedMessage(ThisModule,
  190. FALSE,
  191. Message,
  192. sizeof(Message)/sizeof(Message[0]),
  193. MSG_COMPLETED) );
  194. return ErrorCode;
  195. }
  196. BOOL SetPrivilege(
  197. IN HANDLE hToken,
  198. IN LPCTSTR lpszPrivilege,
  199. IN BOOL bEnablePrivilege
  200. )
  201. /*++
  202. Routine Description:
  203. Sets privileges for the current process. Used to get permission
  204. to save and loadregistry keys
  205. Arguments :
  206. hToken : Handle to the token whose priviledge has to be modified
  207. lpszPrivilege : Priviledge name
  208. bEnablePrivilege : Enable or disable the priviledge
  209. Return Value :
  210. TRUE if successful, otherwise FALSE.
  211. --*/
  212. {
  213. TOKEN_PRIVILEGES tp;
  214. LUID luid;
  215. if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid)){
  216. return FALSE;
  217. }
  218. tp.PrivilegeCount = 1;
  219. tp.Privileges[0].Luid = luid;
  220. if (bEnablePrivilege) {
  221. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  222. } else {
  223. tp.Privileges[0].Attributes = 0;
  224. }
  225. //
  226. // Enable the privilege or disable all privileges.
  227. //
  228. AdjustTokenPrivileges(hToken,
  229. FALSE,
  230. &tp,
  231. sizeof(TOKEN_PRIVILEGES),
  232. (PTOKEN_PRIVILEGES) NULL,
  233. (PDWORD) NULL);
  234. //
  235. // Call GetLastError to determine whether the function succeeded.
  236. //
  237. return (GetLastError() != ERROR_SUCCESS) ? FALSE : TRUE;
  238. }
  239. INT
  240. ShowProgramUsage(
  241. VOID
  242. )
  243. /*++
  244. Routine Description:
  245. Shows show help message on how to use the program.
  246. Arguments:
  247. None.
  248. Return Value:
  249. 0 if successful other non-zero value
  250. --*/
  251. {
  252. //
  253. // TBD : Need to localize this message in future
  254. // based on the need for localized WinPE build
  255. // tools
  256. //
  257. _putws( GetFormattedMessage(ThisModule,
  258. FALSE,
  259. Message,
  260. sizeof(Message)/sizeof(Message[0]),
  261. MSG_PGM_USAGE) );
  262. return 0;
  263. }
  264. //
  265. // Returns a TCHAR string explaining the last win32 error code
  266. //
  267. PCTSTR
  268. Error(
  269. VOID
  270. )
  271. {
  272. static TCHAR MessageBuffer[4096];
  273. MessageBuffer[0] = UNICODE_NULL;
  274. FormatMessage(
  275. FORMAT_MESSAGE_FROM_SYSTEM |
  276. FORMAT_MESSAGE_IGNORE_INSERTS,
  277. NULL,
  278. GetLastError(),
  279. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  280. MessageBuffer,
  281. sizeof(MessageBuffer)/sizeof(TCHAR),
  282. NULL);
  283. return MessageBuffer;
  284. }