|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
buildhive.cpp
Abstract:
Builds the hive from the specified inf files. The inf files follow the same syntax as used by setup. Author:
Mike Cirello Vijay Jayaseelan (vijayj)
Revision History:
03 March 2001 : Rewamp the whole source to make it more maintainable (particularly readable) --*/
#include <new.h>
#include "buildhive.h"
#include "File.h"
#include "Data.h"
//
// Global variables used to get formatted message for this program.
//
HMODULE ThisModule = NULL; WCHAR Message[4096];
//
// Define a function to be called if new fails to allocate memory.
//
int __cdecl MyNewHandler( size_t size ) { _putws(GetFormattedMessage( ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_MEMORY_ALLOC_FAILED) ); // Exit program
//
ExitProcess(errOUT_OF_MEMORY); }
//
// main() entry point
//
int _cdecl wmain( int Argc, wchar_t *Argv[] ) { DWORD ErrorCode = 0; HANDLE hToken;
ThisModule = GetModuleHandle(NULL);
_set_new_handler( MyNewHandler );
try { if (Argc < 2) { return ShowProgramUsage(); }
std::wstring InputFile = Argv[1];
if ((InputFile == L"/?") || (InputFile == L"?") || (InputFile == L"-?") || (InputFile == L"-h")) { return ShowProgramUsage(); }
RegUnLoadKey(HKEY_USERS, L"dummy");
//
// Set privileges needed to load and save registry keys.
//
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); SetPrivilege(hToken,SE_BACKUP_NAME,TRUE); SetPrivilege(hToken,SE_RESTORE_NAME,TRUE);
ErrorCode = GetLastError();
if (ErrorCode != ERROR_SUCCESS) { throw new W32Error(ErrorCode); }
std::cout << InputFile << std::endl;
//
// load the configuration file
//
File ConfigFile(InputFile.c_str(), false);
//
// look for the sections defining the target files and .inf files
//
//
// get the target directory
//
ConfigFile.AddInfSection(InputFile.c_str(), L"Directory", L"SetDirectory");
//
// set the directory
//
ConfigFile.ProcessSections();
//
// NOTE: The sections are processed in the order of addition
//
ConfigFile.AddInfSection(InputFile.c_str(), L"Add Registry New", L"AddRegNew");
//
// do the actual conversion from .inf to hive files since
// we may need them for adding existing entries
//
ConfigFile.ProcessSections(); //
// process the localization specific registry sections
//
ConfigFile.ProcessNlsRegistryEntries();
//
// process modify/delete entries
//
ConfigFile.AddInfSection(InputFile.c_str(), L"Add Registry Existing", L"AddRegExisting"); ConfigFile.AddInfSection(InputFile.c_str(), L"Delete Registry Existing", L"DelRegExisting"); //
// do the actual conversion from .inf to hive file
//
ConfigFile.ProcessSections(); //
// save the hive files and clean out the registry
//
ConfigFile.Cleanup(); } catch (DWORD x) { ErrorCode = x; std::cout << GetFormattedMessage( ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_ABNORMAL_PGM_TERMINATION); switch (x) { case errFILE_LOCKED: std::cout << GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_FILE_LOCKED); break; case errBAD_FLAGS: std::cout << GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_BAD_FLAGS); break; case errFILE_NOT_FOUND: std::cout << GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_FILE_NOT_FOUND); break; case errGENERAL_ERROR: std::cout << GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_GENERAL_ERROR); break; default: std::cout << GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_ERROR_CODE, x); } } catch(W32Error *Error) { if (Error) { Error->Dump(std::cout); ErrorCode = Error->ErrorCode; delete Error; } else { ErrorCode = 1; } } catch(...) { ErrorCode = 1; // unknown error
_putws( GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_ERROR_ABNORMAL_PGM_TERMINATION) ); }
RegUnLoadKey(HKEY_USERS, L"dummy"); _putws( GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_COMPLETED) );
return ErrorCode; }
BOOL SetPrivilege( IN HANDLE hToken, IN LPCTSTR lpszPrivilege, IN BOOL bEnablePrivilege ) /*++
Routine Description:
Sets privileges for the current process. Used to get permission to save and loadregistry keys
Arguments :
hToken : Handle to the token whose priviledge has to be modified lpszPrivilege : Priviledge name bEnablePrivilege : Enable or disable the priviledge
Return Value :
TRUE if successful, otherwise FALSE. --*/ { TOKEN_PRIVILEGES tp; LUID luid;
if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid)){ return FALSE; }
tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid;
if (bEnablePrivilege) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { tp.Privileges[0].Attributes = 0; }
//
// Enable the privilege or disable all privileges.
//
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL);
//
// Call GetLastError to determine whether the function succeeded.
//
return (GetLastError() != ERROR_SUCCESS) ? FALSE : TRUE; }
INT ShowProgramUsage( VOID ) /*++
Routine Description:
Shows show help message on how to use the program.
Arguments:
None.
Return Value:
0 if successful other non-zero value --*/ { //
// TBD : Need to localize this message in future
// based on the need for localized WinPE build
// tools
//
_putws( GetFormattedMessage(ThisModule, FALSE, Message, sizeof(Message)/sizeof(Message[0]), MSG_PGM_USAGE) ); return 0; }
//
// Returns a TCHAR string explaining the last win32 error code
//
PCTSTR Error( VOID ) { static TCHAR MessageBuffer[4096];
MessageBuffer[0] = UNICODE_NULL; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
MessageBuffer, sizeof(MessageBuffer)/sizeof(TCHAR), NULL); return MessageBuffer; }
|