/*++ 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 #include "msginc.h" #include #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; }