//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: N C R E G . C P P // // Contents: Common routines for dealing with the registry. // // Notes: // // Author: danielwe 24 Mar 1997 // //---------------------------------------------------------------------------- #include #pragma hdrstop #include "ncdebug.h" #include "ncreg.h" #include "ncstring.h" #include "ncperms.h" extern const WCHAR c_szAdapters[]; extern const WCHAR c_szBackslash[]; extern const WCHAR c_szParameters[]; extern const WCHAR c_szRegKeyServices[]; //+--------------------------------------------------------------------------- // // Function: HrRegAddStringToMultiSz // // Purpose: Add a string into a REG_MULTI_SZ registry value // // Arguments: // pszAddString [in] The string to add to the multi-sz // hkeyRoot [in] An open registry key, or one of the // predefined hkey values (HKEY_LOCAL_MACHINE, // for instance) // pszKeySubPath [in] Name of the subkey to open. // pszValueName [in] Name of the registry value that we're going to // modify. // dwFlags [in] Can contain one or more of the following // values: // // STRING_FLAG_ALLOW_DUPLICATES // Don't remove duplicate values when adding // the string to the list. Default is to // remove all other instance of this string. // STRING_FLAG_ENSURE_AT_FRONT // Ensure the string is the first element of // the list. If the string is present and // duplicates aren't allowed, move the // string to the end. // STRING_FLAG_ENSURE_AT_END // Ensure the string is the last // element of the list. This can not be used // with STRING_FLAG_ENSURE_AT_FRONT. If the // string is present and duplicates aren't // allowed, move the string to the end. // STRING_FLAG_ENSURE_AT_INDEX // Ensure that the string is at dwStringIndex // in the multi-sz. If the index specified // is greater than the number of strings // in the multi-sz, the string will be // placed at the end. // STRING_FLAG_DONT_MODIFY_IF_PRESENT // If the string already exists in the // multi-sz then no modication will take // place. Note: This takes precedent // over the presence/non-presence of the // STRING_FLAG_ALLOW_DUPLICATES flag. // i.e nothing will be added or removed // if this flag is set and the string was // present in the multi-sz // dwIndex [in] If STRING_FLAG_ENSURE_AT_INDEX is specified, // this is the index for the string position. // Otherwise, this value is ignored. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: jeffspr 27 Mar 1997 // HRESULT HrRegAddStringToMultiSz ( IN PCWSTR pszAddString, IN HKEY hkeyRoot, IN PCWSTR pszKeySubPath, IN PCWSTR pszValueName, IN DWORD dwFlags, IN DWORD dwIndex) { HRESULT hr = S_OK; DWORD dwRegType = 0; // Should be REG_MULTI_SZ HKEY hkeyOpen = NULL; // Return value from RegCreateKeyEx HKEY hkeyUse = NULL; // The key value that we'll actually use LPBYTE pbOrderOld = NULL; // Return buffer for order reg value LPBYTE pbOrderNew = NULL; // Build buffer for order swap // Check for valid parameters if (!pszAddString || !hkeyRoot || !pszValueName) { Assert(pszAddString); Assert(hkeyRoot); Assert(pszValueName); hr = E_INVALIDARG; goto Exit; } // Check to make sure that no "remove" flags are being used, and that // mutually exclusive flags aren't being used together // if ((dwFlags & STRING_FLAG_REMOVE_SINGLE) || (dwFlags & STRING_FLAG_REMOVE_ALL) || ((dwFlags & STRING_FLAG_ENSURE_AT_FRONT) && (dwFlags & STRING_FLAG_ENSURE_AT_END))) { AssertSz(FALSE, "Invalid flags in HrRegAddStringToMultiSz"); hr = E_INVALIDARG; goto Exit; } // If the user passed in a subkey string, then we should attempt to open // the subkey of the passed in root, else we'll just use the // pre-opened hkeyRoot // if (pszKeySubPath) { // Open the key, creating if necessary // hr = HrRegCreateKeyEx ( hkeyRoot, // Base hive pszKeySubPath, // Our reg path 0, // dwOptions KEY_QUERY_VALUE | KEY_SET_VALUE, // samDesired NULL, // lpSecurityAttributes &hkeyOpen, // Our return hkey. NULL); if (FAILED(hr)) { goto Exit; } hkeyUse = hkeyOpen; } else { // Use the passed in key for the Query. // hkeyUse = hkeyRoot; } // Retrieve the existing REG_MULTI_SZ // hr = HrRegQueryValueWithAlloc ( hkeyUse, pszValueName, &dwRegType, &pbOrderOld, NULL); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { // This is OK. It just means that the value was missing, and we // should continue on, and create the value ourselves. hr = S_OK; } else { // Since there's an error that we didn't expect, drop out, // returning this error to the caller. // goto Exit; } } else { // If we did retrieve a value, then check to make sure that we're // dealing with a MULTI_SZ // if (dwRegType != REG_MULTI_SZ) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); goto Exit; } } BOOL fChanged; hr = HrAddSzToMultiSz (pszAddString, (PCWSTR)pbOrderOld, dwFlags, dwIndex, (PWSTR*)&pbOrderNew, &fChanged); if ((S_OK == hr) && fChanged) { DWORD cbNew = CbOfMultiSzAndTermSafe ((PWSTR)pbOrderNew); // Save our string back into the registry // hr = HrRegSetValueEx ( hkeyUse, pszValueName, REG_MULTI_SZ, (const BYTE *)pbOrderNew, cbNew); } Exit: // Close the key, if opened // RegSafeCloseKey (hkeyOpen); // Clean up the registry buffers // MemFree (pbOrderOld); MemFree (pbOrderNew); TraceError ("HrRegAddStringToMultiSz", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegAddStringToSz // // Purpose: Add a string into a REG_MULTI_SZ registry value // // Arguments: // pszAddString [in] The string to add to the multi-sz // hkeyRoot [in] An open registry key, or one of the // predefined hkey values (HKEY_LOCAL_MACHINE, // for instance) // pszKeySubPath [in] Name of the subkey to open. // pszValueName [in] Name of the registry value that we're going to // modify. // chDelimiter [in] The character to be used to delimit the // values. Most multi-valued REG_SZ strings are // delimited with either ',' or ' '. This will // be used to delimit the value that we add, // as well. // dwFlags [in] Can contain one or more of the following // values: // // STRING_FLAG_ALLOW_DUPLICATES // Don't remove duplicate values when adding // the string to the list. Default is to // remove all other instance of this string. // STRING_FLAG_ENSURE_AT_FRONT // Insert the string as the first element of // the list. // STRING_FLAG_ENSURE_AT_END // Insert the string as the last // element of the list. This can not be used // with STRING_FLAG_ENSURE_AT_FRONT. // STRING_FLAG_ENSURE_AT_INDEX // Ensure that the string is at dwStringIndex // in the sz. If the index specified // is greater than the number of strings // in the sz, the string will be // placed at the end. // dwStringIndex [in] If STRING_FLAG_ENSURE_AT_INDEX is specified, // this is the index for the string position. // Otherwise, this value is ignored. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: jeffspr 27 Mar 1997 // // // Note: // Might want to allow for the removal of leading/trailing spaces // HRESULT HrRegAddStringToSz ( IN PCWSTR pszAddString, IN HKEY hkeyRoot, IN PCWSTR pszKeySubPath, IN PCWSTR pszValueName, IN WCHAR chDelimiter, IN DWORD dwFlags, IN DWORD dwStringIndex) { HRESULT hr = S_OK; DWORD dwRegType = 0; // Should be REG_MULTI_SZ HKEY hkeyOpen = NULL; // Open key to open PWSTR pszOrderOld = NULL; // Return buffer for order reg value PWSTR pszOrderNew = NULL; // Build buffer for order swap // Check for all of the required args // if (!pszAddString || !hkeyRoot || !pszValueName) { Assert(pszAddString); Assert(hkeyRoot); Assert(pszValueName); hr = E_INVALIDARG; goto Exit; } // Check to make sure that no "remove" flags are being used, and that // mutually exclusive flags aren't being used together // if ((dwFlags & STRING_FLAG_REMOVE_SINGLE) || (dwFlags & STRING_FLAG_REMOVE_ALL)) { AssertSz(FALSE, "Invalid flags in HrRegAddStringToSz"); hr = E_INVALIDARG; goto Exit; } // Open the key, creating if necessary // hr = HrRegCreateKeyEx( hkeyRoot, // Base hive pszKeySubPath, // Our reg path 0, // dwOptions KEY_QUERY_VALUE | KEY_SET_VALUE, // samDesired NULL, // lpSecurityAttributes &hkeyOpen, // Our return hkey. NULL); if (FAILED(hr)) { goto Exit; } // Retrieve the existing REG_SZ // hr = HrRegQueryValueWithAlloc( hkeyOpen, pszValueName, &dwRegType, (LPBYTE *) &pszOrderOld, NULL); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND)) { // This is OK. It just means that the value is missing. We // can handle this. hr = S_OK; } else { goto Exit; } } else { // If we did retrieve a value, then check to make sure that we're // dealing with a MULTI_SZ // if (dwRegType != REG_SZ) { hr = HRESULT_FROM_WIN32 (ERROR_INVALID_DATATYPE); goto Exit; } } hr = HrAddStringToDelimitedSz(pszAddString, pszOrderOld, chDelimiter, dwFlags, dwStringIndex, &pszOrderNew); if (S_OK == hr) { // Save our string back into the registry // hr = HrRegSetSz(hkeyOpen, pszValueName, pszOrderNew); if (FAILED(hr)) { goto Exit; } } Exit: // Close the key, if open // RegSafeCloseKey (hkeyOpen); // Clean up the registry buffers // MemFree (pszOrderOld); MemFree (pszOrderNew); TraceError ("HrRegAddStringToSz", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegRemoveStringFromSz // // Purpose: Removes a string from a REG_SZ registry value // // Arguments: // pszRemoveString [in] The string to be removed from the multi-sz // hkeyRoot [in] An open registry key, or one of the // predefined hkey values (HKEY_LOCAL_MACHINE, // for instance) // pszKeySubPath [in] Name of the subkey to open. // pszValueName [in] Name of the registry value that we're going to // modify. // chDelimiter [in] The character to be used to delimit the // values. Most multi-valued REG_SZ strings are // delimited with either ',' or ' '. // dwFlags [in] Can contain one or more of the following // values: // // STRING_FLAG_REMOVE_SINGLE // Don't remove more than one value, if // multiple are present. // STRING_FLAG_REMOVE_ALL // If multiple matching values are present, // remove them all. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: jeffspr 27 Mar 1997 // // // Note: // Might want to allow for the removal of leading/trailing spaces // HRESULT HrRegRemoveStringFromSz ( IN PCWSTR pszRemoveString, IN HKEY hkeyRoot, IN PCWSTR pszKeySubPath, IN PCWSTR pszValueName, IN WCHAR chDelimiter, IN DWORD dwFlags ) { HRESULT hr = S_OK; DWORD dwRegType = 0; // Should be REG_MULTI_SZ HKEY hkeyOpen = NULL; // Open key to open PWSTR pszOrderOld = NULL; // Return buffer for order reg value PWSTR pszOrderNew = NULL; // Build buffer for order swap DWORD dwDataSize = 0; // Check for all of the required args // if (!pszRemoveString || !hkeyRoot || !pszValueName) { Assert(pszRemoveString); Assert(hkeyRoot); Assert(pszValueName); hr = E_INVALIDARG; goto Exit; } // Check to make sure that no "remove" flags are being used, and that // mutually exclusive flags aren't being used together // if ((dwFlags & STRING_FLAG_ENSURE_AT_FRONT) || (dwFlags & STRING_FLAG_ENSURE_AT_END) || ((dwFlags & STRING_FLAG_REMOVE_SINGLE) && (dwFlags & STRING_FLAG_REMOVE_ALL))) { AssertSz(FALSE, "Invalid flags in HrRegAddStringToSz"); hr = E_INVALIDARG; goto Exit; } // Open the key, creating if necessary // hr = HrRegOpenKeyEx ( hkeyRoot, // Base hive pszKeySubPath, // Our reg path KEY_QUERY_VALUE | KEY_SET_VALUE, // samDesired &hkeyOpen); // Our return hkey if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { hr = S_OK; } goto Exit; } // Retrieve the existing REG_SZ // hr = HrRegQueryValueWithAlloc ( hkeyOpen, pszValueName, &dwRegType, (LPBYTE *) &pszOrderOld, &dwDataSize); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { // This is OK. It just means that the value is missing. We // can handle this. hr = S_OK; } goto Exit; } else { // If we did retrieve a value, then check to make sure that we're // dealing with a REG_SZ // if (dwRegType != REG_SZ) { hr = HRESULT_FROM_WIN32 (ERROR_INVALID_DATATYPE); goto Exit; } if (dwDataSize == 0) { // This is OK, but we're going to assert here anyway, because this is not // a case that I know about // AssertSz(dwDataSize > 0, "How did we retrieve something from the " "registry with 0 size?"); hr = S_OK; goto Exit; } } hr = HrRemoveStringFromDelimitedSz (pszRemoveString, pszOrderOld, chDelimiter, dwFlags, &pszOrderNew); if (S_OK == hr) { // Save our string back into the registry // hr = HrRegSetSz (hkeyOpen, pszValueName, pszOrderNew); } Exit: // Close the key, if open // RegSafeCloseKey (hkeyOpen); // Clean up the registry buffers // MemFree (pszOrderOld); MemFree (pszOrderNew); TraceError("HrRegRemoveStringFromSz", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegRemoveStringFromMultiSz // // Purpose: Removes the specified string from a multi-sz, if it is present. // // Arguments: // pszRemoveString [in] // hkeyRoot [in] // pszKeySubPath [in] // pszValueName [in] // dwFlags [in] Can contain one or more of the following // values: // // STRING_FLAG_REMOVE_SINGLE // Don't remove more than one value, if // multiple are present. // [default] STRING_FLAG_REMOVE_ALL // If multiple matching values are present, // remove them all. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: ScottBri 11-Apr-1997 // // Notes: // HRESULT HrRegRemoveStringFromMultiSz ( IN PCWSTR pszRemoveString, IN HKEY hkeyRoot, IN PCWSTR pszKeySubPath, IN PCWSTR pszValueName, IN DWORD dwFlags) { DWORD dwDataSize; DWORD dwRegType; HKEY hkey = NULL; HKEY hkeyUse = hkeyRoot; HRESULT hr; PWSTR psz = NULL; // Valid the input parameters if ((NULL == pszRemoveString) || (NULL == pszValueName) || (NULL == hkeyRoot)) { Assert(NULL != pszRemoveString); Assert(NULL != pszValueName); Assert(NULL != hkeyRoot); return E_INVALIDARG; } if ((STRING_FLAG_REMOVE_SINGLE & dwFlags) && (STRING_FLAG_REMOVE_ALL & dwFlags)) { AssertSz(FALSE, "Can't specify both 'remove all' and 'remove single'"); return E_INVALIDARG; } if (NULL != pszKeySubPath) { hr = HrRegOpenKeyEx (hkeyRoot, pszKeySubPath, KEY_READ_WRITE, &hkey); if (S_OK != hr) { return hr; } hkeyUse = hkey; } // Retrieve the existing REG_SZ // hr = HrRegQueryValueWithAlloc (hkeyUse, pszValueName, &dwRegType, (LPBYTE *)&psz, &dwDataSize); if (FAILED(hr)) { if (HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND) == hr) { // This is OK. It just means that the value is missing. We // can handle this. hr = S_OK; } goto Done; } else { // If we did retrieve a value, then check to make sure that we're // dealing with a MULTI_SZ // if (dwRegType != REG_MULTI_SZ) { hr = HRESULT_FROM_WIN32 (ERROR_INVALID_DATATYPE); goto Done; } } // Search for and extract the specified string if present Assert(psz); BOOL fRemoved; RemoveSzFromMultiSz (pszRemoveString, psz, dwFlags, &fRemoved); // Rewrite the registry value if it was changed if (fRemoved) { dwDataSize = CbOfMultiSzAndTermSafe (psz); hr = HrRegSetValueEx (hkeyUse, pszValueName, REG_MULTI_SZ, (const LPBYTE)psz, dwDataSize); } Done: RegSafeCloseKey (hkey); MemFree (psz); TraceError ("HrRegRemoveStringFromMultiSz", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegCopyHive // // Purpose: Copies the contents of one hive to another. It does this // by using RegSaveKey and RegRestoreKey to a temporary file. // // Arguments: // hkeySrc [in] The source key to copy from. // hkeyDst [in] The destination key to copy to. // // Returns: S_OK or an error // // Author: shaunco 12 Jan 1998 // // Notes: // HRESULT HrRegCopyHive ( IN HKEY hkeySrc, IN HKEY hkeyDst) { HRESULT hr; // Enable the needed privileges. // if ((S_OK == (hr = HrEnablePrivilege(SE_BACKUP_NAME))) && (S_OK == (hr = HrEnablePrivilege(SE_RESTORE_NAME)))) { // Create a temporary file name to save the source hive to. // static const WCHAR c_szPrefix [] = L"~ch"; WCHAR szTempPath [MAX_PATH]; WCHAR szTempFile [MAX_PATH]; // If GetTempPath fails, we'd like to know about it (via the trace) // but it's not fatal as we'll just use the current directory // as the path. // if (!GetTempPath (celems(szTempPath), szTempPath)) { TraceError ("HrRegCopyHive: GetTempPath failed (benign)", HrFromLastWin32Error ()); *szTempFile = 0; } // Create the temporary filename and delete it because RegSaveKey // won't write to an existing file. // if (GetTempFileName (szTempPath, c_szPrefix, 0, szTempFile)) { DeleteFile (szTempFile); // Save the source key to the temp file. // hr = HrRegSaveKey (hkeySrc, szTempFile, NULL); if (S_OK == hr) { // Restore the temp file to the destination key. // hr = HrRegRestoreKey (hkeyDst, szTempFile, NULL); } // We're done with the temp file so we delete it. We shoudln't // have any error doing this, but it will be nice to see it // should it occur. // if (!DeleteFile (szTempFile)) { TraceError ("HrRegCopyHive: DeleteFile failed on the " "temporary file (benign)", HrFromLastWin32Error ()); } } else { hr = HrFromLastWin32Error (); } } TraceError ("HrRegCopyHive", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegCreateKeyEx // // Purpose: Creates a registry key by calling RegCreateKeyEx. // // Arguments: // hkey [in] // pszSubkey [in] // dwOptions [in] See the Win32 documentation for the // samDesired [in] RegCreateKeyEx function. // lpSecurityAttributes [in] // phkResult [out] // pdwDisposition [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: danielwe 25 Feb 1997 // // Notes: // HRESULT HrRegCreateKeyEx ( IN HKEY hkey, IN PCWSTR pszSubkey, IN DWORD dwOptions, IN REGSAM samDesired, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes, OUT PHKEY phkResult, OUT LPDWORD pdwDisposition) { Assert (hkey); Assert (pszSubkey); Assert (phkResult); LONG lr = RegCreateKeyExW (hkey, pszSubkey, 0, NULL, dwOptions, samDesired, lpSecurityAttributes, phkResult, pdwDisposition); HRESULT hr = HRESULT_FROM_WIN32 (lr); if (FAILED(hr)) { *phkResult = NULL; } TraceError("HrRegCreateKeyEx", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegDeleteKey // // Purpose: Delete the specified registry key. // // Arguments: // hkey [in] See the Win32 documentation for the RegDeleteKey. // pszSubkey [in] function. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: shaunco 1 Apr 1997 // // Notes: // HRESULT HrRegDeleteKey ( IN HKEY hkey, IN PCWSTR pszSubkey) { Assert (hkey); Assert (pszSubkey); LONG lr = RegDeleteKeyW (hkey, pszSubkey); HRESULT hr = HRESULT_FROM_WIN32 (lr); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); TraceHr (ttidError, FAL, hr, ERROR_FILE_NOT_FOUND == lr, "HrRegDeleteKey"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegDeleteKeyTree // // Purpose: Deletes an entire registry hive. // // Arguments: // hkeyParent [in] Handle to open key where the desired key resides. // pszRemoveKey [in] Name of key to delete. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: danielwe 25 Feb 1997 // // Notes: ckotze Changed to use KEY_READ_WRITE_DELETE as opposed to // KEY_ALL_ACCESS, which is far too much access for what is // required. // HRESULT HrRegDeleteKeyTree ( IN HKEY hkeyParent, IN PCWSTR pszRemoveKey) { Assert (hkeyParent); Assert (pszRemoveKey); // Open the key we want to remove HKEY hkeyRemove; HRESULT hr = HrRegOpenKeyEx(hkeyParent, pszRemoveKey, KEY_READ_WRITE_DELETE, &hkeyRemove); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); if (S_OK == hr) { WCHAR szValueName [MAX_PATH]; DWORD cchBuffSize = MAX_PATH; FILETIME ft; LONG lr; // Enum the keys children, and remove those sub-trees while (ERROR_SUCCESS == (lr = RegEnumKeyExW (hkeyRemove, 0, szValueName, &cchBuffSize, NULL, NULL, NULL, &ft))) { HrRegDeleteKeyTree (hkeyRemove, szValueName); cchBuffSize = MAX_PATH; } RegCloseKey (hkeyRemove); if ((ERROR_SUCCESS == lr) || (ERROR_NO_MORE_ITEMS == lr)) { lr = RegDeleteKeyW (hkeyParent, pszRemoveKey); } hr = HRESULT_FROM_WIN32 (lr); } TraceHr (ttidError, FAL, hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr, "HrRegDeleteKeyTree"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegDeleteValue // // Purpose: Deletes the given registry value. // // Arguments: // hkey [in] See the Win32 documentation for the RegDeleteValue // pszValueName [in] function. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: danielwe 25 Feb 1997 // // Notes: // HRESULT HrRegDeleteValue ( IN HKEY hkey, IN PCWSTR pszValueName) { Assert (hkey); Assert (pszValueName); LONG lr = RegDeleteValueW (hkey, pszValueName); HRESULT hr = HRESULT_FROM_WIN32(lr); TraceErrorOptional("HrRegDeleteValue", hr, (ERROR_FILE_NOT_FOUND == lr)); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegEnumKey // // Purpose: Enumerates subkeys of the specified open registry key. // // Arguments: // hkey [in] // dwIndex [in] See the Win32 documentation for the // pszSubkeyName [out] RegEnumKeyEx function. // pcchSubkeyName [inout] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: shaunco 30 Mar 1997 // // Notes: // HRESULT HrRegEnumKey ( IN HKEY hkey, IN DWORD dwIndex, OUT PWSTR pszSubkeyName, IN DWORD cchSubkeyName) { Assert (hkey); Assert (pszSubkeyName); Assert (cchSubkeyName); LONG lr = RegEnumKeyW (hkey, dwIndex, pszSubkeyName, cchSubkeyName); HRESULT hr = HRESULT_FROM_WIN32(lr); TraceHr (ttidError, FAL, hr, ERROR_NO_MORE_ITEMS == lr, "HrRegEnumKey"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegEnumKeyEx // // Purpose: Enumerates subkeys of the specified open registry key. // // Arguments: // hkey [in] // dwIndex [in] See the Win32 documentation for the // pszSubkeyName [out] RegEnumKeyEx function. // pcchSubkeyName [inout] // pszClass [out] // pcchClass [inout] // pftLastWriteTime [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: shaunco 30 Mar 1997 // // Notes: // HRESULT HrRegEnumKeyEx ( IN HKEY hkey, IN DWORD dwIndex, OUT PWSTR pszSubkeyName, IN OUT LPDWORD pcchSubkeyName, OUT PWSTR pszClass, IN OUT LPDWORD pcchClass, OUT FILETIME* pftLastWriteTime) { Assert (hkey); Assert (pszSubkeyName); Assert (pcchSubkeyName); Assert (pftLastWriteTime); LONG lr = RegEnumKeyExW (hkey, dwIndex, pszSubkeyName, pcchSubkeyName, NULL, pszClass, pcchClass, pftLastWriteTime); HRESULT hr = HRESULT_FROM_WIN32(lr); TraceHr (ttidError, FAL, hr, ERROR_NO_MORE_ITEMS == lr, "HrRegEnumKeyEx"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegEnumValue // // Purpose: Enumerates the values for the specified open registry key. // // Arguments: // hkey [in] // dwIndex [in] See the Win32 documentation for the // pszValueName [out] RegEnumValue function. // pcbValueName [inout] // pdwType [out] // pbData [out] // pcbData [inout] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: shaunco 30 Mar 1997 // // Notes: // HRESULT HrRegEnumValue ( IN HKEY hkey, IN DWORD dwIndex, OUT PWSTR pszValueName, IN OUT LPDWORD pcbValueName, OUT LPDWORD pdwType, OUT LPBYTE pbData, IN OUT LPDWORD pcbData) { Assert (hkey); Assert (pszValueName); Assert (pcbValueName); Assert (FImplies(pbData, pcbData)); LONG lr = RegEnumValueW (hkey, dwIndex, pszValueName, pcbValueName, NULL, pdwType, pbData, pcbData); HRESULT hr = HRESULT_FROM_WIN32 (lr); TraceErrorOptional("HrRegEnumValue", hr, (ERROR_NO_MORE_ITEMS == lr)); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegOpenKeyEx // // Purpose: Opens a registry key by calling RegOpenKeyEx. // // Arguments: // hkey [in] // pszSubkey [in] See the Win32 documentation for the // samDesired [in] RegOpenKeyEx function. // phkResult [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: danielwe 25 Feb 1997 // // Notes: // HRESULT HrRegOpenKeyEx ( IN HKEY hkey, IN PCWSTR pszSubkey, IN REGSAM samDesired, OUT PHKEY phkResult) { Assert (hkey); Assert (pszSubkey); Assert (phkResult); LONG lr = RegOpenKeyExW (hkey, pszSubkey, 0, samDesired, phkResult); HRESULT hr = HRESULT_FROM_WIN32(lr); if (FAILED(hr)) { *phkResult = NULL; TraceTag(ttidDefault, "Error Opening Key:%s hr: 0x%x", pszSubkey, hr); } TraceErrorOptional("HrRegOpenKeyEx", hr, (ERROR_FILE_NOT_FOUND == lr)); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegOpenKeyBestAccess // // Purpose: Opens a registry key by calling RegOpenKeyEx with the highest // access possible. // // Arguments: // hkey [in] // pszSubkey [in] See the Win32 documentation for the // phkResult [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: scottbri 31-Oct-1997 // // Notes: // HRESULT HrRegOpenKeyBestAccess ( IN HKEY hkey, IN PCWSTR pszSubkey, OUT PHKEY phkResult) { Assert (hkey); Assert (pszSubkey); Assert (phkResult); TraceTag(ttidDefault, "Why do you call this function? Either you can write or you can't."); LONG lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_ALL_ACCESS, phkResult); HRESULT hr = HRESULT_FROM_WIN32 (lr); if (E_ACCESSDENIED == hr) { lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_READ_WRITE_DELETE, phkResult); hr = HRESULT_FROM_WIN32 (lr); if (E_ACCESSDENIED == hr) { lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_READ_WRITE, phkResult); hr = HRESULT_FROM_WIN32 (lr); if (E_ACCESSDENIED == hr) { lr = RegOpenKeyExW (hkey, pszSubkey, 0, KEY_READ, phkResult); hr = HRESULT_FROM_WIN32 (lr); if (E_ACCESSDENIED == hr) { lr = RegOpenKeyExW (hkey, pszSubkey, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, phkResult); hr = HRESULT_FROM_WIN32 (lr); } } } } if (FAILED(hr)) { *phkResult = NULL; } TraceErrorOptional("HrRegOpenKeyEx", hr, (ERROR_FILE_NOT_FOUND == lr)); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegDuplicateKeyEx // // Purpose: Duplicates a registry key by calling RegOpenKeyEx. // // Arguments: // hkey [in] // samDesired [in] RegOpenKeyEx function. // phkResult [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: mikemi 09 Apr 1997 // // Notes: // HRESULT HrRegDuplicateKeyEx ( IN HKEY hkey, IN REGSAM samDesired, OUT PHKEY phkResult) { Assert (hkey); Assert (phkResult); LONG lr = RegOpenKeyExW (hkey, NULL, 0, samDesired, phkResult); HRESULT hr = HRESULT_FROM_WIN32 (lr); if (FAILED(hr)) { *phkResult = NULL; } TraceError("HrRegDuplicateKeyEx", hr); return hr; } HRESULT HrRegSetBool ( IN HKEY hkey, IN PCWSTR pszValueName, IN BOOL fValue) { DWORD dwValue = !!fValue; return HrRegSetValueEx (hkey, pszValueName, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD)); } HRESULT HrRegSetDword ( IN HKEY hkey, IN PCWSTR pszValueName, IN DWORD dwValue) { return HrRegSetValueEx (hkey, pszValueName, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD)); } //+--------------------------------------------------------------------------- // // Function: HrRegSetGuidAsSz // // Purpose: Converts a given guid to a string and sets the given registry // value. // // Arguments: // hkey [in] // pszValueName [in] // guid [in] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: BillBe 21 Feb 1999 // // Notes: // HRESULT HrRegSetGuidAsSz ( IN HKEY hkey, IN PCWSTR pszValueName, IN const GUID& guid) { HRESULT hr; INT cch; WCHAR szGuid[c_cchGuidWithTerm]; Assert (hkey); Assert (pszValueName && *pszValueName); cch = StringFromGUID2 (guid, szGuid, c_cchGuidWithTerm); Assert (c_cchGuidWithTerm == cch); hr = HrRegSetSz (hkey, pszValueName, szGuid); TraceHr (ttidError, FAL, hr, FALSE, "HrRegSetGuidAsSz"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegSetValueEx // // Purpose: Sets the data for the given registry value by calling the // RegSetValueEx function. // // Arguments: // hkey [in] // pszValueName [in] // dwType [in] See the Win32 documentation for the RegSetValueEx // pbData [in] function. // cbData [in] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: danielwe 25 Feb 1997 // // Notes: // HRESULT HrRegSetValueEx ( IN HKEY hkey, IN PCWSTR pszValueName, IN DWORD dwType, IN const BYTE *pbData, IN DWORD cbData) { Assert (hkey); Assert (FImplies (cbData > 0, pbData)); LONG lr = RegSetValueExW(hkey, pszValueName, 0, dwType, pbData, cbData); HRESULT hr = HRESULT_FROM_WIN32 (lr); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); TraceError("HrRegSetValue", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: RegSafeCloseKey // // Purpose: Closes the given registry key if it is non-NULL. // // Arguments: // hkey [in] Key to be closed. Can be NULL. // // Returns: Nothing. // // Author: danielwe 25 Feb 1997 // // Notes: If hkey is NULL this function does nothing. // VOID RegSafeCloseKey ( IN HKEY hkey) { if (hkey) { RegCloseKey(hkey); } } //+--------------------------------------------------------------------------- // // Function: HrRegRestoreKey // // Purpose: Wrapper for RegRestoreKey // // Arguments: // hkey [in] Parent key to restore into // pszFileName [in] Name of file containing registry info // dwFlags [in] Flags for restore // // Returns: Win32 HRESULT if failure, otherwise S_OK // // Author: danielwe 8 Aug 1997 // // Notes: See docs for RegRestoreKey for more info // HRESULT HrRegRestoreKey ( IN HKEY hkey, IN PCWSTR pszFileName, IN DWORD dwFlags) { HRESULT hr = S_OK; LONG lres; Assert(hkey); Assert(pszFileName); lres = RegRestoreKeyW(hkey, pszFileName, dwFlags); hr = HRESULT_FROM_WIN32(lres); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); TraceError("HrRegRestoreKey", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegSaveKey // // Purpose: Wrapper for RegSaveKey // // Arguments: // hkey [in] Parent key to restore into // pszFileName [in] Name of file containing registry info // psa [in] Security attributes for the file // // Returns: Win32 HRESULT if failure, otherwise S_OK // // Author: BillBe 2 Jan 1998 // // Notes: See docs for RegSaveKey for more info // HRESULT HrRegSaveKey ( IN HKEY hkey, IN PCWSTR pszFileName, IN LPSECURITY_ATTRIBUTES psa) { HRESULT hr; LONG lres; Assert(hkey); Assert(pszFileName); lres = RegSaveKeyW (hkey, pszFileName, psa); hr = HRESULT_FROM_WIN32(lres); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); TraceError("HrRegSaveKey", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegGetKeySecurity // // Purpose: Retrieves the Security of a Key using RegGetKeySecurity // // Arguments: // hkey [in] // pszSubkey [in] See the Win32 documentation for the // samDesired [in] RegOpenKeyEx function. // phkResult [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: ckotze 06 July 2000 // // Notes: // HRESULT HrRegGetKeySecurity( HKEY hKey, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor) { Assert (hKey); Assert (SecurityInformation); Assert (pSecurityDescriptor); LONG lr = RegGetKeySecurity(hKey, SecurityInformation, pSecurityDescriptor, lpcbSecurityDescriptor); HRESULT hr = HRESULT_FROM_WIN32(lr); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); if (FAILED(hr)) { pSecurityDescriptor = NULL; } TraceErrorOptional("HrRegGetKeySecurity", hr, (lr != ERROR_INSUFFICIENT_BUFFER)); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegOpenKeyEx // // Purpose: Opens a registry key by calling RegOpenKeyEx. // // Arguments: // hkey [in] // pszSubkey [in] See the Win32 documentation for the // samDesired [in] RegOpenKeyEx function. // phkResult [out] // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: danielwe 25 Feb 1997 // // Notes: // HRESULT HrRegSetKeySecurity ( HKEY hKey, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor) { Assert (hKey); Assert (SecurityInformation); Assert (pSecurityDescriptor); LONG lr = RegSetKeySecurity(hKey, SecurityInformation, pSecurityDescriptor); HRESULT hr = HRESULT_FROM_WIN32(lr); // Did we open the key with incorrect access? Assert(E_ACCESSDENIED != hr); TraceError("HrRegSetKeySecurity", hr); return hr; } //+--------------------------------------------------------------------------- // // Member: HrRegOpenAdapterKey // // Purpose: This creates or opens the Adapters subkey to a component // // Arguments: // pszComponentName [in] The name of the component being // fCreate [in] TRUE if the directory is to be created // phkey [out] The handle to the Adapters subkey // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: CWill 06/11/97 // // Notes: The handle has to be release by the calling app on SUCCESS // HRESULT HrRegOpenAdapterKey ( IN PCWSTR pszComponentName, IN BOOL fCreate, OUT HKEY* phkey) { HRESULT hr = S_OK; DWORD dwDisposition = 0x0; tstring strKey; // Build the registry path strKey = c_szRegKeyServices; strKey.append(c_szBackslash); strKey.append(pszComponentName); strKey.append(c_szBackslash); strKey.append(c_szParameters); strKey.append(c_szBackslash); strKey.append(c_szAdapters); // Create the key if we are asked if (fCreate) { hr = HrRegCreateKeyEx( HKEY_LOCAL_MACHINE, strKey.c_str(), REG_OPTION_NON_VOLATILE, KEY_READ_WRITE_DELETE, NULL, phkey, &dwDisposition); } else { hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strKey.c_str(), KEY_READ, phkey); } TraceError("HrRegOpenAdapterKey", hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegQueryColString // // Purpose: Allocates strings and appends to collects as read from the registry. // // Arguments: // hkey [in] The registry key. // pszValueName [in] The name of the value to get. // pcolstr [out] The returned collection of tstrings*. empty collection otherwise. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: mikemi 30 Apr 1997 // // Notes: If the function succeeds, you must call DeleteColString on the // return parameter. // This will empty and delete the collection passed in // //--------------------------------------------------------------------------- HRESULT HrRegQueryColString ( IN HKEY hkey, IN PCWSTR pszValueName, OUT list* pcolstr ) { WCHAR* pmsz; HRESULT hr; DeleteColString (pcolstr); hr = HrRegQueryMultiSzWithAlloc (hkey, pszValueName, &pmsz); if (S_OK == hr) { MultiSzToColString (pmsz, pcolstr); MemFree (pmsz); } TraceHr (ttidError, FAL, hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr, "HrRegQueryColString"); return hr; } HRESULT HrRegQueryColString ( IN HKEY hkey, IN PCWSTR pszValueName, OUT vector* pcolstr ) { WCHAR* pmsz; HRESULT hr; DeleteColString (pcolstr); hr = HrRegQueryMultiSzWithAlloc (hkey, pszValueName, &pmsz); if (S_OK == hr) { MultiSzToColString (pmsz, pcolstr); MemFree (pmsz); } TraceHr (ttidError, FAL, hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr, "HrRegQueryColString"); return hr; } //+--------------------------------------------------------------------------- // // Function: HrRegSetColString // // Purpose: Sets a multi-sz in the registry using the collection of strings // // Arguments: // hkey [in] The registry key. // pszValueName [in] The name of the value to set. // colstr [in] The collection of tstrings to set. // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: mikemi 30 Apr 1997 // // Notes: // //--------------------------------------------------------------------------- HRESULT HrRegSetColString ( IN HKEY hkey, IN PCWSTR pszValueName, IN const list& colstr) { WCHAR* pmsz; HRESULT hr; ColStringToMultiSz (colstr, &pmsz); hr = HrRegSetMultiSz (hkey, pszValueName, (pmsz ? pmsz : c_szEmpty)); MemFree (pmsz); TraceError ("HrRegSetColString", hr); return hr; } HRESULT HrRegSetColString ( IN HKEY hkey, IN PCWSTR pszValueName, IN const vector& colstr) { WCHAR* pmsz; HRESULT hr; ColStringToMultiSz (colstr, &pmsz); hr = HrRegSetMultiSz (hkey, pszValueName, (pmsz ? pmsz : c_szEmpty)); MemFree (pmsz); TraceError ("HrRegSetColString", hr); return hr; }