|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1996 * * TITLE: REGHELP.C * * VERSION: 2.0 * * AUTHOR: ReedB * * DATE: 17 Oct, 1996 * * DESCRIPTION: * *******************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <string.h>
#include <regstr.h>
#include <commctrl.h>
#include <ntpoapi.h>
#include "powrprofp.h"
#include "reghelp.h"
/*******************************************************************************
* * G L O B A L D A T A * *******************************************************************************/
extern HINSTANCE g_hInstance; // Global instance handle of this DLL.
extern HANDLE g_hSemRegistry; // Registry semaphore.
extern UINT g_uiLastID; // The last ID value used, per machine.
extern TCHAR c_szREGSTR_PATH_MACHINE_POWERCFG[]; extern TCHAR c_szREGSTR_VAL_LASTID[];
// Global semaphore name.
const TCHAR c_szSemRegistry[] = TEXT("PowerProfileRegistrySemaphore");
/*******************************************************************************
* * OpenCurrentUser * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
DWORD OpenCurrentUser2(PHKEY phKey) { #ifdef WINNT
// Since powerprof can be called in the Winlogon context when
// a user is being impersonated, use RegOpenCurrentUser to get HKCU.
LONG lRet = RegOpenCurrentUser(KEY_ALL_ACCESS, phKey); if (lRet != ERROR_SUCCESS) { DebugPrint("RegOpenCurrentUser, failed, LastError: 0x%08X", lRet); }
return lRet;
#else
*phKey = HKEY_CURRENT_USER; return ERROR_SUCCESS; #endif
}
BOOLEAN OpenCurrentUser(PHKEY phKey) { DWORD dwError = OpenCurrentUser2(phKey); BOOLEAN fSucceeded = TRUE; if (ERROR_SUCCESS != dwError) { fSucceeded = FALSE; SetLastError(dwError); }
return fSucceeded; }
/*******************************************************************************
* * CloseCurrentUser * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN CloseCurrentUser(HKEY hKey) { #ifdef WINNT
RegCloseKey(hKey); #endif
return TRUE; }
/*******************************************************************************
* * OpenMachineUserKeys * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
DWORD OpenMachineUserKeys2( LPTSTR lpszUserKeyName, LPTSTR lpszMachineKeyName, PHKEY phKeyUser, PHKEY phKeyMachine ) { HKEY hKeyCurrentUser; DWORD dwError = OpenCurrentUser2(&hKeyCurrentUser);
if (ERROR_SUCCESS == dwError) // Sets Last Error
{ dwError = RegOpenKey(hKeyCurrentUser, lpszUserKeyName, phKeyUser); if (dwError == ERROR_SUCCESS) { dwError = RegOpenKey(HKEY_LOCAL_MACHINE, lpszMachineKeyName, phKeyMachine); if (dwError == ERROR_SUCCESS) { CloseCurrentUser(hKeyCurrentUser); return dwError; } else { DebugPrint("OpenMachineUserKeys, failure opening HKEY_LOCAL_MACHINE\\%s", lpszMachineKeyName); }
RegCloseKey(*phKeyUser); } else { DebugPrint("OpenMachineUserKeys, failure opening HKEY_CURRENT_USER\\%s", lpszUserKeyName); }
CloseCurrentUser(hKeyCurrentUser); } else { dwError = ERROR_FILE_NOT_FOUND; }
DebugPrint("OpenMachineUserKeys, failed, LastError: 0x%08X", dwError); return dwError; }
BOOLEAN OpenMachineUserKeys( LPTSTR lpszUserKeyName, LPTSTR lpszMachineKeyName, PHKEY phKeyUser, PHKEY phKeyMachine) { DWORD dwError = OpenMachineUserKeys2(lpszUserKeyName, lpszMachineKeyName, phKeyUser, phKeyMachine); BOOLEAN fSucceeded = TRUE; if (ERROR_SUCCESS != dwError) { fSucceeded = FALSE; SetLastError(dwError); }
return fSucceeded; }
/*******************************************************************************
* * OpenPathKeys * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
DWORD OpenPathKeys( LPTSTR lpszUserKeyName, LPTSTR lpszMachineKeyName, LPTSTR lpszSchemeName, PHKEY phKeyUser, PHKEY phKeyMachine, BOOLEAN bMustExist, REGSAM sam ) { HKEY hKeyUser, hKeyMachine;
DWORD dwError = OpenMachineUserKeys2(lpszUserKeyName, lpszMachineKeyName, &hKeyUser, &hKeyMachine); if (ERROR_SUCCESS == dwError) { DWORD dwDisposition;
dwError = RegCreateKeyEx(hKeyUser, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, sam, NULL, phKeyUser, &dwDisposition); if (dwError == ERROR_SUCCESS) { if (!bMustExist || (dwDisposition == REG_OPENED_EXISTING_KEY)) { dwError = RegCreateKeyEx(hKeyMachine, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, sam, NULL, phKeyMachine, &dwDisposition); if (dwError == ERROR_SUCCESS) { if (!bMustExist || (dwDisposition == REG_OPENED_EXISTING_KEY)) { // This is the success case.
} else { dwError = ERROR_ACCESS_DENIED; } } else { RegCloseKey(*phKeyUser); DebugPrint("OpenPathKeys, unable to create machine key %s\\%s", lpszMachineKeyName, lpszSchemeName); } } else { dwError = ERROR_ACCESS_DENIED; } } else { DebugPrint("OpenPathKeys, unable to create user key %s\\%s", lpszUserKeyName, lpszSchemeName); }
RegCloseKey(hKeyUser); RegCloseKey(hKeyMachine);
if (ERROR_SUCCESS != dwError) { DebugPrint("OpenPathKeys, failed, LastError: 0x%08X", dwError); } }
return dwError; }
PACL BuildSemaphoreACL (void)
// 2000-06-22 vtan:
//
// This function builds an ACL which allows everybody access to the named
// semaphore for SYNCHRONIZE | READ_CONTROL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE.
// It gives full access for the local SYSTEM or members of the local administrators
// group. If something goes wrong the return result is NULL and no security descriptor
// is built then.
{ static SID_IDENTIFIER_AUTHORITY worldSIDAuthority = SECURITY_WORLD_SID_AUTHORITY; static SID_IDENTIFIER_AUTHORITY securityNTAuthority = SECURITY_NT_AUTHORITY;
PSID pSIDWorld; PACL pACL;
pACL = NULL; if (AllocateAndInitializeSid(&worldSIDAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSIDWorld) != FALSE) { PSID pSIDLocalSystem;
if (AllocateAndInitializeSid(&securityNTAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSIDLocalSystem) != FALSE) { PSID pSIDLocalAdministrators;
if (AllocateAndInitializeSid(&securityNTAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSIDLocalAdministrators) != FALSE) { DWORD dwACLSize;
dwACLSize = sizeof(ACL) + ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG)) * 3) + GetLengthSid(pSIDWorld) + GetLengthSid(pSIDLocalSystem) + GetLengthSid(pSIDLocalAdministrators); pACL = (PACL)LocalAlloc(LMEM_FIXED, dwACLSize); if (pACL != NULL) { if ((InitializeAcl(pACL, dwACLSize, ACL_REVISION) == FALSE) || (AddAccessAllowedAce(pACL, ACL_REVISION, SYNCHRONIZE | READ_CONTROL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE, pSIDWorld) == FALSE) || (AddAccessAllowedAce(pACL, ACL_REVISION, SEMAPHORE_ALL_ACCESS, pSIDLocalSystem) == FALSE) || (AddAccessAllowedAce(pACL, ACL_REVISION, SEMAPHORE_ALL_ACCESS, pSIDLocalAdministrators) == FALSE)) { (HLOCAL)LocalFree(pACL); pACL = NULL; } } (PVOID)FreeSid(pSIDLocalAdministrators); } (PVOID)FreeSid(pSIDLocalSystem); } (PVOID)FreeSid(pSIDWorld); } return(pACL); }
/*******************************************************************************
* * CreateRegSemaphore * * DESCRIPTION: Attempts to open/create the registry semaphore. g_hSemRegistry * is initialized on success. * * PARAMETERS: None * *******************************************************************************/
BOOLEAN CreateRegSemaphore(VOID) { HANDLE Semaphore=NULL;
// First try to open the named semaphore with only required access.
// NOTE: the named object is per terminal server session. Therefore
// this semaphore is really bogus because it protects HKEY_LOCAL_MACHINE
// as well as HKEY_CURRENT_USER. Making it "Global\" is very dangerous
// and you don't know the side effects without complete retesting.
// Not worth it.
Semaphore = OpenSemaphore(SYNCHRONIZE | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE, FALSE, c_szSemRegistry); if ((Semaphore == NULL) && (GetLastError() != ERROR_ACCESS_DENIED)) { SECURITY_ATTRIBUTES securityAttributes, *pSA; SECURITY_DESCRIPTOR securityDescriptor; PACL pACL;
// If this fails then create the semaphore and ACL it so that everybody
// can get SYNCHRONIZE | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE
// access. This allows a service (such as UPS) running in the SYSTEM context
// to grant limited access to anybody who needs it to synchronize against
// this semaphore. It also prevents C2 violation by NOT putting a NULL
// DACL on the named semaphore. If an ACL for the semaphore cannot be
// built then no security descriptor is given and the default ACL is used.
pSA = NULL; pACL = BuildSemaphoreACL(); if (pACL != NULL) { if ((InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION) != FALSE) && (SetSecurityDescriptorDacl(&securityDescriptor, TRUE, pACL, FALSE) != FALSE)) { securityAttributes.nLength = sizeof(securityAttributes); securityAttributes.bInheritHandle = FALSE; securityAttributes.lpSecurityDescriptor = &securityDescriptor; pSA = &securityAttributes; } }
// Create the registry semaphore.
Semaphore = CreateSemaphore(pSA, 1, 1, c_szSemRegistry);
if (pACL != NULL) { (HLOCAL)LocalFree(pACL); } }
//
// If we successfully opened a handle, update the global g_hSemRegistry now
//
if (Semaphore) { if (InterlockedCompareExchangePointer(&g_hSemRegistry, Semaphore, NULL) != NULL) { CloseHandle(Semaphore); } return(TRUE); } else { return(FALSE); }
}
/*******************************************************************************
* * TakeRegSemaphore * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN TakeRegSemaphore(VOID) { if (g_hSemRegistry == NULL) { if (!CreateRegSemaphore()) { return FALSE; } } if (WaitForSingleObject(g_hSemRegistry, SEMAPHORE_TIMEOUT) != WAIT_OBJECT_0) { ReleaseSemaphore(g_hSemRegistry, 1, NULL); DebugPrint("WaitForSingleObject, failed"); SetLastError(ERROR_INVALID_ACCESS); return FALSE; } return TRUE; }
/*******************************************************************************
* * ReadPowerValueOptional * * DESCRIPTION: * Value may not exist. * * PARAMETERS: * *******************************************************************************/
BOOLEAN ReadPowerValueOptional( HKEY hKey, LPTSTR lpszPath, LPTSTR lpszValueName, LPTSTR lpszValue, LPDWORD lpdwSize ) { HKEY hKeyPath; BOOLEAN bRet = FALSE; DWORD dwSize; LONG lRet;
if ((lRet = RegOpenKey(hKey, lpszPath, &hKeyPath)) != ERROR_SUCCESS) { goto RPVO_exit; }
if ((lRet = RegQueryValueEx(hKeyPath, lpszValueName, NULL, NULL, (PBYTE) lpszValue, lpdwSize)) == ERROR_SUCCESS) { bRet = TRUE; }
RegCloseKey(hKeyPath);
RPVO_exit: return bRet; }
/*******************************************************************************
* * ReadPowerIntOptional * * DESCRIPTION: * Integer value may not exist. * * PARAMETERS: * *******************************************************************************/
BOOLEAN ReadPowerIntOptional( HKEY hKey, LPTSTR lpszPath, LPTSTR lpszValueName, PINT piVal ) { HKEY hKeyPath; BOOLEAN bRet = FALSE; DWORD dwSize; TCHAR szNum[NUM_DEC_DIGITS]; LONG lRet;
if ((lRet = RegOpenKey(hKey, lpszPath, &hKeyPath)) != ERROR_SUCCESS) { goto RPVO_exit; }
dwSize = sizeof(szNum); if ((lRet = RegQueryValueEx(hKeyPath, lpszValueName, NULL, NULL, (PBYTE) szNum, &dwSize)) == ERROR_SUCCESS) { if (MyStrToInt(szNum, piVal)) { bRet = TRUE; } }
RegCloseKey(hKeyPath);
RPVO_exit: return bRet; }
/*******************************************************************************
* * CreatePowerValue * * DESCRIPTION: * Value may not exist. * * PARAMETERS: * *******************************************************************************/
BOOLEAN CreatePowerValue( HKEY hKey, LPCTSTR lpszPath, LPCTSTR lpszValueName, LPCTSTR lpszValue ) { DWORD dwDisposition, dwDescSize; HKEY hKeyPath; BOOLEAN bRet = FALSE; DWORD dwSize; LONG lRet; // Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) // Will SetLastError
{ return FALSE; }
if ((lRet = RegCreateKeyEx(hKey, lpszPath, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyPath, &dwDisposition)) == ERROR_SUCCESS) { if (lpszValue) { dwSize = (lstrlen(lpszValue) + 1) * sizeof(TCHAR); if ((lRet = RegSetValueEx(hKeyPath, lpszValueName, 0, REG_SZ, (PBYTE) lpszValue, dwSize)) == ERROR_SUCCESS) { bRet = TRUE; } } else { lRet = ERROR_INVALID_PARAMETER; }
RegCloseKey(hKeyPath); } if (!bRet) { SetLastError(lRet); }
ReleaseSemaphore(g_hSemRegistry, 1, NULL); return bRet; }
/*******************************************************************************
* * ReadWritePowerValue * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN ReadWritePowerValue( HKEY hKey, LPTSTR lpszPath, LPTSTR lpszValueName, LPTSTR lpszValue, LPDWORD lpdwSize, BOOLEAN bWrite, BOOLEAN bTakeSemaphore ) { // This function will set the Last Error correctly on failure
HKEY hKeyPath; BOOLEAN bRet = FALSE; DWORD dwSize; LONG lRet;
if ((lRet = RegOpenKey(hKey, lpszPath, &hKeyPath)) != ERROR_SUCCESS) { goto RWPV_exit; }
// Wait on/take the registry semaphore.
if (bTakeSemaphore) { if (!TakeRegSemaphore()) // Will Set last error
{ return FALSE; } }
if (bWrite) { // Write current case.
if (lpszValue) { dwSize = (lstrlen(lpszValue) + 1) * sizeof(TCHAR); if ((lRet = RegSetValueEx(hKeyPath, lpszValueName, 0, REG_SZ, (PBYTE) lpszValue, dwSize)) == ERROR_SUCCESS) { bRet = TRUE; } } else { lRet = ERROR_INVALID_PARAMETER; } } else { // Read current case.
if ((lRet = RegQueryValueEx(hKeyPath, lpszValueName, NULL, NULL, (PBYTE) lpszValue, lpdwSize)) == ERROR_SUCCESS) { bRet = TRUE; } }
if (bTakeSemaphore) { ReleaseSemaphore(g_hSemRegistry, 1, NULL); } RegCloseKey(hKeyPath);
RWPV_exit: if (!bRet) { if (lRet == ERROR_SUCCESS) { lRet = GetLastError(); }
SetLastError(lRet);
// Access denied is a valid result.
if (lRet != ERROR_ACCESS_DENIED) { DebugPrint("ReadWritePowerValue, failed, lpszValueName: %s, LastError: 0x%08X", lpszValueName, lRet); } } return bRet; }
/*******************************************************************************
* * ReadPwrPolicyEx * * DESCRIPTION: * Supports ReadPwrScheme and ReadGlobalPwrPolicy * * PARAMETERS: * lpdwDescSize - Pointer to size of optional description buffer. * lpszDesc - Optional description buffer. * *******************************************************************************/
DWORD ReadPwrPolicyEx2( LPTSTR lpszUserKeyName, LPTSTR lpszMachineKeyName, LPTSTR lpszSchemeName, LPTSTR lpszDesc, LPDWORD lpdwDescSize, LPVOID lpvUser, DWORD dwcbUserSize, LPVOID lpvMachine, DWORD dwcbMachineSize ) { HKEY hKeyUser, hKeyMachine; DWORD dwType, dwSize; DWORD dwError = ERROR_SUCCESS; BOOLEAN bRet = FALSE;
if ((!lpszUserKeyName || !lpszMachineKeyName) || (!lpszSchemeName || !lpvUser || !lpvMachine) || (!lpdwDescSize && lpszDesc) || (lpdwDescSize && !lpszDesc)) { dwError = ERROR_INVALID_PARAMETER; } else { // Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) // Will Set Last Error
{ return GetLastError(); }
dwError = OpenPathKeys(lpszUserKeyName, lpszMachineKeyName, lpszSchemeName, &hKeyUser, &hKeyMachine, TRUE, KEY_READ); if (ERROR_SUCCESS != dwError) { ReleaseSemaphore(g_hSemRegistry, 1, NULL); return dwError; }
dwSize = dwcbUserSize; dwError = RegQueryValueEx(hKeyUser, TEXT("Policies"), NULL, &dwType, (PBYTE) lpvUser, &dwSize);
if (dwError == ERROR_SUCCESS) { if (dwType == REG_BINARY) { dwSize = dwcbMachineSize; dwError = RegQueryValueEx(hKeyMachine, TEXT("Policies"), NULL, &dwType, (PBYTE) lpvMachine, &dwSize); } else { dwError = ERROR_INVALID_DATATYPE; } }
if (dwError == ERROR_SUCCESS) { if (dwType == REG_BINARY) { if (lpdwDescSize) { dwError = RegQueryValueEx(hKeyUser, TEXT("Description"), NULL, &dwType, (PBYTE) lpszDesc, lpdwDescSize); } } else { dwError = ERROR_INVALID_DATATYPE; } }
RegCloseKey(hKeyUser); RegCloseKey(hKeyMachine); ReleaseSemaphore(g_hSemRegistry, 1, NULL); }
if (ERROR_SUCCESS != dwError) { DebugPrint("ReadPwrPolicyEx, failed, LastError: 0x%08X", dwError); DebugPrint(" lpszUserKeyName: %s, lpszSchemeName: %s", lpszUserKeyName, lpszSchemeName); SetLastError(dwError); }
return dwError; }
DWORD ReadProcessorPwrPolicy( LPTSTR lpszMachineKeyName, LPTSTR lpszSchemeName, LPVOID lpvMachineProcessor, DWORD dwcbMachineProcessorSize ) { HKEY hKeyMachine = NULL; HKEY hKeyPolicy = NULL; DWORD dwError = ERROR_SUCCESS; DWORD dwDisposition, dwSize, dwType;
if (!lpszMachineKeyName || !lpvMachineProcessor) { dwError = ERROR_INVALID_PARAMETER; goto ReadProcessorPwrPolicyEnd; }
// Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) // Will Set Last Error
{ return GetLastError(); }
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszMachineKeyName, 0, KEY_READ, &hKeyMachine); if (ERROR_SUCCESS != dwError) goto ReadProcessorPwrPolicyExit;
dwError = RegCreateKeyEx(hKeyMachine, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKeyPolicy, &dwDisposition); if (ERROR_SUCCESS != dwError) goto ReadProcessorPwrPolicyExit;
dwSize = dwcbMachineProcessorSize; dwError = RegQueryValueEx(hKeyPolicy, TEXT("Policies"), NULL, &dwType, (PBYTE) lpvMachineProcessor, &dwSize);
if (REG_BINARY != dwType) { dwError = ERROR_INVALID_DATATYPE; } ReadProcessorPwrPolicyExit:
if (hKeyPolicy) RegCloseKey(hKeyPolicy); if (hKeyMachine) RegCloseKey(hKeyMachine); ReleaseSemaphore(g_hSemRegistry, 1, NULL);
ReadProcessorPwrPolicyEnd:
if (ERROR_SUCCESS != dwError) { DebugPrint("ReadProcessorPwrPolicy, failed, LastError: 0x%08X", dwError); DebugPrint(" lpszMachineKeyName: %s, lpszSchemeName: %s", lpszMachineKeyName, lpszSchemeName); SetLastError(dwError); }
return dwError; }
DWORD WriteProcessorPwrPolicy( LPTSTR lpszMachineKeyName, LPTSTR lpszSchemeName, LPVOID lpvMachineProcessor, DWORD dwcbMachineProcessorSize ) { HKEY hKeyMachine = NULL; HKEY hKeyPolicy = NULL; DWORD dwError = ERROR_SUCCESS; DWORD dwDisposition;
if (!lpszMachineKeyName || !lpvMachineProcessor) { dwError = ERROR_INVALID_PARAMETER; goto WriteProcessorPwrPolicyEnd; }
// Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) // Will Set Last Error
{ return GetLastError(); }
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszMachineKeyName, 0, KEY_WRITE, &hKeyMachine); if (ERROR_SUCCESS != dwError) goto WriteProcessorPwrPolicyExit;
dwError = RegCreateKeyEx(hKeyMachine, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyPolicy, &dwDisposition); if (ERROR_SUCCESS != dwError) goto WriteProcessorPwrPolicyExit;
dwError = RegSetValueEx(hKeyPolicy, TEXT("Policies"), 0, REG_BINARY, (PBYTE) lpvMachineProcessor, dwcbMachineProcessorSize);
WriteProcessorPwrPolicyExit:
if (hKeyPolicy) RegCloseKey(hKeyPolicy); if (hKeyMachine) RegCloseKey(hKeyMachine); ReleaseSemaphore(g_hSemRegistry, 1, NULL);
WriteProcessorPwrPolicyEnd:
if (ERROR_SUCCESS != dwError) { DebugPrint("WriteProcessorPwrPolicy, failed, LastError: 0x%08X", dwError); DebugPrint(" lpszMachineKeyName: %s, lpszSchemeName: %s", lpszMachineKeyName, lpszSchemeName); SetLastError(dwError); }
return dwError; }
/*******************************************************************************
* * WritePwrPolicyEx * * DESCRIPTION: * Supports WritePwrScheme and * WriteGlobalPwrPolicy * * PARAMETERS: * *******************************************************************************/
BOOLEAN WritePwrPolicyEx( LPTSTR lpszUserKeyName, LPTSTR lpszMachineKeyName, PUINT puiID, LPTSTR lpszName, LPTSTR lpszDescription, LPVOID lpvUser, DWORD dwcbUserSize, LPVOID lpvMachine, DWORD dwcbMachineSize ) { // The function will set the last error if it fails.
HKEY hKeyUser, hKeyMachine; LONG lRet = ERROR_SUCCESS; DWORD dwDisposition, dwSize; TCHAR szNum[NUM_DEC_DIGITS]; LPTSTR lpszKeyName;
if ((!lpszUserKeyName || !lpszMachineKeyName || !lpvUser || !lpvMachine) || (!puiID && !lpszName)) { SetLastError(ERROR_INVALID_PARAMETER); lRet = ERROR_INVALID_PARAMETER; } else { // If a scheme ID was passed
if (puiID) { if (*puiID == NEWSCHEME) { *puiID = ++g_uiLastID; wsprintf(szNum, TEXT("%d"), *puiID);
// This ReadWritePowerValue will SetLastError
if (!ReadWritePowerValue(HKEY_LOCAL_MACHINE, c_szREGSTR_PATH_MACHINE_POWERCFG, c_szREGSTR_VAL_LASTID, szNum, &dwSize, TRUE, TRUE)) { return FALSE; } } else { wsprintf(szNum, TEXT("%d"), *puiID); } lpszKeyName = szNum; } else { lpszKeyName = lpszName; }
// Wait on/take the registry semaphore.
if (!TakeRegSemaphore()) // Will set last error
{ return FALSE; }
lRet = OpenPathKeys(lpszUserKeyName, lpszMachineKeyName, lpszKeyName, &hKeyUser, &hKeyMachine, FALSE, KEY_WRITE); if (ERROR_SUCCESS != lRet) { ReleaseSemaphore(g_hSemRegistry, 1, FALSE); SetLastError(lRet); return FALSE; }
// Write the binary policies data
if ((lRet = RegSetValueEx(hKeyUser, TEXT("Policies"), 0, REG_BINARY, (PBYTE) lpvUser, dwcbUserSize)) == ERROR_SUCCESS) { // Write the binary policies data
if ((lRet = RegSetValueEx(hKeyMachine, TEXT("Policies"), 0, REG_BINARY, (PBYTE) lpvMachine, dwcbMachineSize)) == ERROR_SUCCESS) { // Write the name text if an ID was provided.
if (lpszName && puiID) { dwSize = (lstrlen(lpszName) + 1) * sizeof(TCHAR); lRet = RegSetValueEx(hKeyUser, TEXT("Name"), 0, REG_SZ, (PBYTE) lpszName, dwSize); }
// Write the description text.
if (lpszDescription && (lRet == ERROR_SUCCESS)) { dwSize = (lstrlen(lpszDescription) + 1) * sizeof(TCHAR); lRet = RegSetValueEx(hKeyUser, TEXT("Description"), 0, REG_SZ, (PBYTE) lpszDescription, dwSize); } } } RegCloseKey(hKeyUser); RegCloseKey(hKeyMachine); ReleaseSemaphore(g_hSemRegistry, 1, NULL); }
if (lRet != ERROR_SUCCESS) { DebugPrint("WritePwrPolicyEx, failed, LastError: 0x%08X", lRet); DebugPrint(" lpszUserKeyName: %s, lpszKeyName: %s", lpszUserKeyName, lpszKeyName);
SetLastError(lRet); return FALSE; } return TRUE; }
|