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

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