488 lines
13 KiB
C++
488 lines
13 KiB
C++
|
|
|
|
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
RegWriter.h
|
|
|
|
Abstract:
|
|
|
|
Contains the registry writer abstraction
|
|
implementation
|
|
|
|
Author:
|
|
|
|
Mike Cirello
|
|
Vijay Jayaseelan (vijayj)
|
|
|
|
Revision History:
|
|
|
|
03 March 2001 :
|
|
Rewamp the whole source to make it more maintainable
|
|
(particularly readable)
|
|
|
|
--*/
|
|
|
|
#include "RegWriter.h"
|
|
#include "buildhive.h"
|
|
#include "Data.h"
|
|
#include <shlwapi.h>
|
|
#include "msginc.h"
|
|
#include <libmsg.h>
|
|
#include "msg.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Macro definitions
|
|
//
|
|
#define AS(x) ( sizeof( (x) ) / sizeof( (x[0]) ) )
|
|
|
|
//
|
|
// static data initilization
|
|
//
|
|
int RegWriter::ctr = 0;
|
|
TCHAR RegWriter::Namespace[64] = {0};
|
|
|
|
//
|
|
// Initializes a new subkey for this regwriter
|
|
//
|
|
// Arguments:
|
|
// LUID is the name of the subkey, all LUID's must be unique
|
|
// target is the name of the hive file to load into the key.
|
|
// If it is null an empty key is created
|
|
//
|
|
DWORD RegWriter::Init(
|
|
IN int LUID,
|
|
PCTSTR target
|
|
)
|
|
{
|
|
DWORD dwRet;
|
|
TCHAR buf[10];
|
|
|
|
//
|
|
// initialize the namespace, if needed
|
|
//
|
|
if (0 == Namespace[0]) {
|
|
GUID guid = {0};
|
|
|
|
if (CoCreateGuid(&guid) != S_OK) {
|
|
return ERROR_FUNCTION_FAILED;
|
|
}
|
|
|
|
swprintf(Namespace,
|
|
L"bldhives.exe{%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X}\\",
|
|
guid.Data1,
|
|
guid.Data2,
|
|
guid.Data3,
|
|
guid.Data4[0],
|
|
guid.Data4[1],
|
|
guid.Data4[2],
|
|
guid.Data4[3],
|
|
guid.Data4[4],
|
|
guid.Data4[5],
|
|
guid.Data4[6],
|
|
guid.Data4[7]);
|
|
}
|
|
|
|
wcscpy(root, Namespace);
|
|
|
|
luid = LUID;
|
|
|
|
//
|
|
// if this is the first time, load the root key
|
|
//
|
|
if (!ctr) {
|
|
dwRet = RegLoadKey(HKEY_USERS, root, L".\\nothing");
|
|
|
|
if (dwRet !=ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_ERROR_LOADING_EMPTY_KEY,
|
|
dwRet) );
|
|
}
|
|
}
|
|
|
|
//
|
|
// create root key for this regwriter (subkey of dummy) if it is for a new file
|
|
//
|
|
if (!target) {
|
|
wcscat(root, _itow(luid,buf,10));
|
|
|
|
dwRet = RegCreateKeyEx(HKEY_USERS, root, 0, 0, 0, KEY_ALL_ACCESS, 0, &key, 0);
|
|
|
|
if (dwRet !=ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_ERROR_LOADING_ROOT_KEY,
|
|
dwRet) );
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
} else {
|
|
//
|
|
// otherwise load existing hive into subkey of dummy
|
|
//
|
|
wcscat(root, _itow(luid,buf,10));
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_LOADING_HIVE,
|
|
target) );
|
|
|
|
dwRet = Load(L"", target);
|
|
|
|
if (dwRet !=ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_ERROR_LOADING_ROOT_KEY,
|
|
dwRet) );
|
|
}
|
|
}
|
|
|
|
ctr++;
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
RegWriter::~RegWriter()
|
|
{
|
|
DWORD dwRet;
|
|
|
|
ctr--;
|
|
|
|
if (!ctr) {
|
|
//
|
|
// unload everything from the registry
|
|
//
|
|
dwRet = RegUnLoadKey(HKEY_USERS, Namespace);
|
|
|
|
if (dwRet !=ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_DECONSTRUCTOR_UNLOAD,
|
|
dwRet) );
|
|
}
|
|
|
|
//
|
|
// delete the files created when we made the empty root key
|
|
//
|
|
HANDLE Handle = CreateFile(L".\\nothing",
|
|
DELETE,
|
|
FILE_SHARE_DELETE,
|
|
0,
|
|
OPEN_EXISTING,
|
|
0,
|
|
0);
|
|
|
|
if (Handle !=INVALID_HANDLE_VALUE) {
|
|
DeleteFile(L".\\nothing");
|
|
CloseHandle(Handle);
|
|
} else {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_EMPTY_HIVE_DELETE_FAILED) );
|
|
}
|
|
|
|
Handle = CreateFile(L".\\nothing.LOG",
|
|
DELETE,
|
|
FILE_SHARE_DELETE,
|
|
0,
|
|
OPEN_EXISTING,
|
|
0,
|
|
0);
|
|
|
|
if (Handle !=INVALID_HANDLE_VALUE) {
|
|
DeleteFile(L".\\nothing.LOG");
|
|
CloseHandle(Handle);
|
|
} else {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_EMPTY_HIVE_LOG_DELETE_FAILED) );
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Writes data to a subkey of this regwriter's root
|
|
//
|
|
// Arguments:
|
|
// Root - ignored
|
|
// Key - the subkey to store the data in
|
|
// Value - the value to store the data in
|
|
// flag - registry flag describing the data - REG_SZ, REG_DWORD, etc..
|
|
// data - a data object containing the information to be written to the subkey
|
|
//
|
|
DWORD RegWriter::Write(
|
|
IN PCTSTR Root,
|
|
IN PCTSTR Key,
|
|
IN PCTSTR Value,
|
|
IN DWORD flag,
|
|
IN Data* data)
|
|
{
|
|
HKEY key;
|
|
DWORD dwRet;
|
|
TCHAR full[1024] = {0};
|
|
|
|
wcsncpy(full, root, AS(full) - 1);
|
|
wcsncpy(full + wcslen(full), Key, AS(full) - wcslen(full) - 1);
|
|
|
|
//
|
|
// open a key and set its value
|
|
//
|
|
dwRet = RegCreateKeyEx(HKEY_USERS, full, 0, 0, 0, KEY_WRITE, 0, &key, 0);
|
|
|
|
if (dwRet !=ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_CREATE_KEY,
|
|
dwRet) );
|
|
return dwRet;
|
|
}
|
|
|
|
if ((data) && (data->GetData())) {
|
|
dwRet = RegSetValueEx(key, Value, 0, flag,data->GetData(), data->Sizeof());
|
|
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_SET_KEY,
|
|
dwRet) );
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
} else if (Value) {
|
|
dwRet = RegSetValueEx(key, Value, 0, flag, 0, 0);
|
|
|
|
if (dwRet !=ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_SET_KEY2,
|
|
dwRet) );
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Saves a subkey to disk
|
|
//
|
|
// Arguments:
|
|
// Key - the subkey to be saved
|
|
// fileName - the file to save the information to.
|
|
//
|
|
DWORD RegWriter::Save(
|
|
PCTSTR Key,
|
|
PCTSTR fileName
|
|
)
|
|
{
|
|
DWORD dwRet = 0;
|
|
HKEY key;
|
|
TCHAR full[1024] = {0};
|
|
|
|
wcsncpy(full, root, AS(full) - 1);
|
|
wcsncpy(full + wcslen(full), Key, AS(full) - wcslen(full) - 1);
|
|
|
|
//
|
|
// save a key to file
|
|
//
|
|
dwRet = RegCreateKeyEx(HKEY_USERS,full,0,0,0,KEY_READ,0,&key,0);
|
|
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_CREATE_KEY,
|
|
dwRet) );
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
dwRet = RegSaveKey(key,fileName,0);
|
|
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_SAVE_KEY,
|
|
dwRet) );
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
//
|
|
// Loads information from a hive file to a subkey.
|
|
//
|
|
// Arguments :
|
|
// Key - subkey to write the information to
|
|
// fileName - full path and file name of the hive file to be loaded.
|
|
//
|
|
DWORD RegWriter::Load(PCTSTR Key, PCTSTR fileName) {
|
|
DWORD dwRet = 0;
|
|
TCHAR full[1024] = {0};
|
|
|
|
wcsncpy(full, root, AS(full) - 1);
|
|
wcsncpy(full + wcslen(full), Key, AS(full) - wcslen(full) - 1);
|
|
|
|
//
|
|
// load data in from a hive
|
|
//
|
|
dwRet = RegCreateKeyEx(HKEY_USERS,full,0,0,0,KEY_ALL_ACCESS,0,&key,0);
|
|
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_ERROR_CREATE_KEY,
|
|
dwRet,
|
|
root,
|
|
full,
|
|
fileName) );
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
dwRet = RegRestoreKey(key,fileName,0);
|
|
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_ERROR_RESTORE_KEY,
|
|
dwRet,
|
|
root,
|
|
full,
|
|
fileName) );
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
dwRet = RegFlushKey(key);
|
|
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
_putws( GetFormattedMessage(ThisModule,
|
|
FALSE,
|
|
Message,
|
|
sizeof(Message)/sizeof(Message[0]),
|
|
MSG_ERROR_FLUSH_KEY,
|
|
dwRet,
|
|
root,
|
|
full,
|
|
fileName) );
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD
|
|
RegWriter::Delete(
|
|
PCTSTR CurrentRoot,
|
|
PCTSTR Key,
|
|
PCTSTR Value OPTIONAL
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Deletes the given key / value underneath the key
|
|
|
|
Arguments:
|
|
|
|
CurrentRoot - The Root key (ignored for the time being)
|
|
|
|
Key - The key to delete or key containing the value to delete
|
|
|
|
Value - The value to delete
|
|
|
|
Return Value:
|
|
|
|
Appropriate WIN32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD Result = ERROR_INVALID_PARAMETER;
|
|
|
|
if (CurrentRoot && Key) {
|
|
DWORD BufferLength = (_tcslen(root) + _tcslen(Key) + _tcslen(root));
|
|
PTSTR Buffer;
|
|
|
|
if (Value) {
|
|
BufferLength += _tcslen(Value);;
|
|
}
|
|
|
|
BufferLength += sizeof(TCHAR); // for null
|
|
BufferLength = sizeof(TCHAR) * BufferLength;
|
|
|
|
Buffer = new TCHAR[BufferLength];
|
|
|
|
if (Buffer) {
|
|
_tcscpy(Buffer, root);
|
|
_tcscat(Buffer, Key);
|
|
|
|
if (Value) {
|
|
Result = SHDeleteValue(HKEY_USERS,
|
|
Buffer,
|
|
Value);
|
|
} else {
|
|
Result = SHDeleteKey(HKEY_USERS,
|
|
Buffer);
|
|
}
|
|
|
|
delete []Buffer;
|
|
} else {
|
|
Result = ERROR_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|