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.

1064 lines
30 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1996
  4. *
  5. * TITLE: REGHELP.C
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 17 Oct, 1996
  12. *
  13. * DESCRIPTION:
  14. *
  15. *******************************************************************************/
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <windows.h>
  20. #include <string.h>
  21. #include <regstr.h>
  22. #include <commctrl.h>
  23. #include <ntpoapi.h>
  24. #include "powrprofp.h"
  25. #include "reghelp.h"
  26. /*******************************************************************************
  27. *
  28. * G L O B A L D A T A
  29. *
  30. *******************************************************************************/
  31. extern HINSTANCE g_hInstance; // Global instance handle of this DLL.
  32. extern HANDLE g_hSemRegistry; // Registry semaphore.
  33. extern UINT g_uiLastID; // The last ID value used, per machine.
  34. extern TCHAR c_szREGSTR_PATH_MACHINE_POWERCFG[];
  35. extern TCHAR c_szREGSTR_VAL_LASTID[];
  36. // Global semaphore name.
  37. const TCHAR c_szSemRegistry[] = TEXT("PowerProfileRegistrySemaphore");
  38. /*******************************************************************************
  39. *
  40. * OpenCurrentUser
  41. *
  42. * DESCRIPTION:
  43. *
  44. * PARAMETERS:
  45. *
  46. *******************************************************************************/
  47. DWORD OpenCurrentUser2(PHKEY phKey)
  48. {
  49. #ifdef WINNT
  50. // Since powerprof can be called in the Winlogon context when
  51. // a user is being impersonated, use RegOpenCurrentUser to get HKCU.
  52. LONG lRet = RegOpenCurrentUser(KEY_ALL_ACCESS, phKey);
  53. if (lRet != ERROR_SUCCESS)
  54. {
  55. DebugPrint("RegOpenCurrentUser, failed, LastError: 0x%08X", lRet);
  56. }
  57. return lRet;
  58. #else
  59. *phKey = HKEY_CURRENT_USER;
  60. return ERROR_SUCCESS;
  61. #endif
  62. }
  63. BOOLEAN OpenCurrentUser(PHKEY phKey)
  64. {
  65. DWORD dwError = OpenCurrentUser2(phKey);
  66. BOOLEAN fSucceeded = TRUE;
  67. if (ERROR_SUCCESS != dwError)
  68. {
  69. fSucceeded = FALSE;
  70. SetLastError(dwError);
  71. }
  72. return fSucceeded;
  73. }
  74. /*******************************************************************************
  75. *
  76. * CloseCurrentUser
  77. *
  78. * DESCRIPTION:
  79. *
  80. * PARAMETERS:
  81. *
  82. *******************************************************************************/
  83. BOOLEAN CloseCurrentUser(HKEY hKey)
  84. {
  85. #ifdef WINNT
  86. RegCloseKey(hKey);
  87. #endif
  88. return TRUE;
  89. }
  90. /*******************************************************************************
  91. *
  92. * OpenMachineUserKeys
  93. *
  94. * DESCRIPTION:
  95. *
  96. * PARAMETERS:
  97. *
  98. *******************************************************************************/
  99. DWORD OpenMachineUserKeys2(
  100. LPTSTR lpszUserKeyName,
  101. LPTSTR lpszMachineKeyName,
  102. PHKEY phKeyUser,
  103. PHKEY phKeyMachine
  104. )
  105. {
  106. HKEY hKeyCurrentUser;
  107. DWORD dwError = OpenCurrentUser2(&hKeyCurrentUser);
  108. if (ERROR_SUCCESS == dwError) // Sets Last Error
  109. {
  110. dwError = RegOpenKey(hKeyCurrentUser, lpszUserKeyName, phKeyUser);
  111. if (dwError == ERROR_SUCCESS)
  112. {
  113. dwError = RegOpenKey(HKEY_LOCAL_MACHINE, lpszMachineKeyName, phKeyMachine);
  114. if (dwError == ERROR_SUCCESS)
  115. {
  116. CloseCurrentUser(hKeyCurrentUser);
  117. return dwError;
  118. }
  119. else
  120. {
  121. DebugPrint("OpenMachineUserKeys, failure opening HKEY_LOCAL_MACHINE\\%s", lpszMachineKeyName);
  122. }
  123. RegCloseKey(*phKeyUser);
  124. }
  125. else
  126. {
  127. DebugPrint("OpenMachineUserKeys, failure opening HKEY_CURRENT_USER\\%s", lpszUserKeyName);
  128. }
  129. CloseCurrentUser(hKeyCurrentUser);
  130. }
  131. else
  132. {
  133. dwError = ERROR_FILE_NOT_FOUND;
  134. }
  135. DebugPrint("OpenMachineUserKeys, failed, LastError: 0x%08X", dwError);
  136. return dwError;
  137. }
  138. BOOLEAN OpenMachineUserKeys(
  139. LPTSTR lpszUserKeyName,
  140. LPTSTR lpszMachineKeyName,
  141. PHKEY phKeyUser,
  142. PHKEY phKeyMachine)
  143. {
  144. DWORD dwError = OpenMachineUserKeys2(lpszUserKeyName, lpszMachineKeyName, phKeyUser, phKeyMachine);
  145. BOOLEAN fSucceeded = TRUE;
  146. if (ERROR_SUCCESS != dwError)
  147. {
  148. fSucceeded = FALSE;
  149. SetLastError(dwError);
  150. }
  151. return fSucceeded;
  152. }
  153. /*******************************************************************************
  154. *
  155. * OpenPathKeys
  156. *
  157. * DESCRIPTION:
  158. *
  159. * PARAMETERS:
  160. *
  161. *******************************************************************************/
  162. DWORD OpenPathKeys(
  163. LPTSTR lpszUserKeyName,
  164. LPTSTR lpszMachineKeyName,
  165. LPTSTR lpszSchemeName,
  166. PHKEY phKeyUser,
  167. PHKEY phKeyMachine,
  168. BOOLEAN bMustExist,
  169. REGSAM sam
  170. )
  171. {
  172. HKEY hKeyUser, hKeyMachine;
  173. DWORD dwError = OpenMachineUserKeys2(lpszUserKeyName, lpszMachineKeyName, &hKeyUser, &hKeyMachine);
  174. if (ERROR_SUCCESS == dwError)
  175. {
  176. DWORD dwDisposition;
  177. dwError = RegCreateKeyEx(hKeyUser, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, sam, NULL, phKeyUser, &dwDisposition);
  178. if (dwError == ERROR_SUCCESS)
  179. {
  180. if (!bMustExist || (dwDisposition == REG_OPENED_EXISTING_KEY))
  181. {
  182. dwError = RegCreateKeyEx(hKeyMachine,
  183. lpszSchemeName,
  184. 0,
  185. TEXT(""),
  186. REG_OPTION_NON_VOLATILE,
  187. sam,
  188. NULL,
  189. phKeyMachine,
  190. &dwDisposition);
  191. if (dwError == ERROR_SUCCESS)
  192. {
  193. if (!bMustExist ||
  194. (dwDisposition == REG_OPENED_EXISTING_KEY))
  195. {
  196. // This is the success case.
  197. }
  198. else
  199. {
  200. dwError = ERROR_ACCESS_DENIED;
  201. }
  202. }
  203. else
  204. {
  205. RegCloseKey(*phKeyUser);
  206. DebugPrint("OpenPathKeys, unable to create machine key %s\\%s", lpszMachineKeyName, lpszSchemeName);
  207. }
  208. }
  209. else
  210. {
  211. dwError = ERROR_ACCESS_DENIED;
  212. }
  213. }
  214. else
  215. {
  216. DebugPrint("OpenPathKeys, unable to create user key %s\\%s", lpszUserKeyName, lpszSchemeName);
  217. }
  218. RegCloseKey(hKeyUser);
  219. RegCloseKey(hKeyMachine);
  220. if (ERROR_SUCCESS != dwError)
  221. {
  222. DebugPrint("OpenPathKeys, failed, LastError: 0x%08X", dwError);
  223. }
  224. }
  225. return dwError;
  226. }
  227. PACL BuildSemaphoreACL (void)
  228. // 2000-06-22 vtan:
  229. //
  230. // This function builds an ACL which allows everybody access to the named
  231. // semaphore for SYNCHRONIZE | READ_CONTROL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE.
  232. // It gives full access for the local SYSTEM or members of the local administrators
  233. // group. If something goes wrong the return result is NULL and no security descriptor
  234. // is built then.
  235. {
  236. static SID_IDENTIFIER_AUTHORITY worldSIDAuthority = SECURITY_WORLD_SID_AUTHORITY;
  237. static SID_IDENTIFIER_AUTHORITY securityNTAuthority = SECURITY_NT_AUTHORITY;
  238. PSID pSIDWorld;
  239. PACL pACL;
  240. pACL = NULL;
  241. if (AllocateAndInitializeSid(&worldSIDAuthority,
  242. 1,
  243. SECURITY_WORLD_RID,
  244. 0, 0, 0, 0, 0, 0, 0,
  245. &pSIDWorld) != FALSE)
  246. {
  247. PSID pSIDLocalSystem;
  248. if (AllocateAndInitializeSid(&securityNTAuthority,
  249. 1,
  250. SECURITY_LOCAL_SYSTEM_RID,
  251. 0, 0, 0, 0, 0, 0, 0,
  252. &pSIDLocalSystem) != FALSE)
  253. {
  254. PSID pSIDLocalAdministrators;
  255. if (AllocateAndInitializeSid(&securityNTAuthority,
  256. 2,
  257. SECURITY_BUILTIN_DOMAIN_RID,
  258. DOMAIN_ALIAS_RID_ADMINS,
  259. 0, 0, 0, 0, 0, 0,
  260. &pSIDLocalAdministrators) != FALSE)
  261. {
  262. DWORD dwACLSize;
  263. dwACLSize = sizeof(ACL) +
  264. ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG)) * 3) +
  265. GetLengthSid(pSIDWorld) +
  266. GetLengthSid(pSIDLocalSystem) +
  267. GetLengthSid(pSIDLocalAdministrators);
  268. pACL = (PACL)LocalAlloc(LMEM_FIXED, dwACLSize);
  269. if (pACL != NULL)
  270. {
  271. if ((InitializeAcl(pACL, dwACLSize, ACL_REVISION) == FALSE) ||
  272. (AddAccessAllowedAce(pACL,
  273. ACL_REVISION,
  274. SYNCHRONIZE | READ_CONTROL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE,
  275. pSIDWorld) == FALSE) ||
  276. (AddAccessAllowedAce(pACL,
  277. ACL_REVISION,
  278. SEMAPHORE_ALL_ACCESS,
  279. pSIDLocalSystem) == FALSE) ||
  280. (AddAccessAllowedAce(pACL,
  281. ACL_REVISION,
  282. SEMAPHORE_ALL_ACCESS,
  283. pSIDLocalAdministrators) == FALSE))
  284. {
  285. (HLOCAL)LocalFree(pACL);
  286. pACL = NULL;
  287. }
  288. }
  289. (PVOID)FreeSid(pSIDLocalAdministrators);
  290. }
  291. (PVOID)FreeSid(pSIDLocalSystem);
  292. }
  293. (PVOID)FreeSid(pSIDWorld);
  294. }
  295. return(pACL);
  296. }
  297. /*******************************************************************************
  298. *
  299. * CreateRegSemaphore
  300. *
  301. * DESCRIPTION: Attempts to open/create the registry semaphore. g_hSemRegistry
  302. * is initialized on success.
  303. *
  304. * PARAMETERS: None
  305. *
  306. *******************************************************************************/
  307. BOOLEAN CreateRegSemaphore(VOID)
  308. {
  309. HANDLE Semaphore=NULL;
  310. // First try to open the named semaphore with only required access.
  311. // NOTE: the named object is per terminal server session. Therefore
  312. // this semaphore is really bogus because it protects HKEY_LOCAL_MACHINE
  313. // as well as HKEY_CURRENT_USER. Making it "Global\" is very dangerous
  314. // and you don't know the side effects without complete retesting.
  315. // Not worth it.
  316. Semaphore = OpenSemaphore(SYNCHRONIZE | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE,
  317. FALSE,
  318. c_szSemRegistry);
  319. if ((Semaphore == NULL) && (GetLastError() != ERROR_ACCESS_DENIED))
  320. {
  321. SECURITY_ATTRIBUTES securityAttributes, *pSA;
  322. SECURITY_DESCRIPTOR securityDescriptor;
  323. PACL pACL;
  324. // If this fails then create the semaphore and ACL it so that everybody
  325. // can get SYNCHRONIZE | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE
  326. // access. This allows a service (such as UPS) running in the SYSTEM context
  327. // to grant limited access to anybody who needs it to synchronize against
  328. // this semaphore. It also prevents C2 violation by NOT putting a NULL
  329. // DACL on the named semaphore. If an ACL for the semaphore cannot be
  330. // built then no security descriptor is given and the default ACL is used.
  331. pSA = NULL;
  332. pACL = BuildSemaphoreACL();
  333. if (pACL != NULL)
  334. {
  335. if ((InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION) != FALSE) &&
  336. (SetSecurityDescriptorDacl(&securityDescriptor, TRUE, pACL, FALSE) != FALSE))
  337. {
  338. securityAttributes.nLength = sizeof(securityAttributes);
  339. securityAttributes.bInheritHandle = FALSE;
  340. securityAttributes.lpSecurityDescriptor = &securityDescriptor;
  341. pSA = &securityAttributes;
  342. }
  343. }
  344. // Create the registry semaphore.
  345. Semaphore = CreateSemaphore(pSA, 1, 1, c_szSemRegistry);
  346. if (pACL != NULL)
  347. {
  348. (HLOCAL)LocalFree(pACL);
  349. }
  350. }
  351. //
  352. // If we successfully opened a handle, update the global g_hSemRegistry now
  353. //
  354. if (Semaphore) {
  355. if (InterlockedCompareExchangePointer(&g_hSemRegistry, Semaphore, NULL) != NULL) {
  356. CloseHandle(Semaphore);
  357. }
  358. return(TRUE);
  359. } else {
  360. return(FALSE);
  361. }
  362. }
  363. /*******************************************************************************
  364. *
  365. * TakeRegSemaphore
  366. *
  367. * DESCRIPTION:
  368. *
  369. * PARAMETERS:
  370. *
  371. *******************************************************************************/
  372. BOOLEAN TakeRegSemaphore(VOID)
  373. {
  374. if (g_hSemRegistry == NULL) {
  375. if (!CreateRegSemaphore()) {
  376. return FALSE;
  377. }
  378. }
  379. if (WaitForSingleObject(g_hSemRegistry, SEMAPHORE_TIMEOUT) != WAIT_OBJECT_0) {
  380. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  381. DebugPrint("WaitForSingleObject, failed");
  382. SetLastError(ERROR_INVALID_ACCESS);
  383. return FALSE;
  384. }
  385. return TRUE;
  386. }
  387. /*******************************************************************************
  388. *
  389. * ReadPowerValueOptional
  390. *
  391. * DESCRIPTION:
  392. * Value may not exist.
  393. *
  394. * PARAMETERS:
  395. *
  396. *******************************************************************************/
  397. BOOLEAN ReadPowerValueOptional(
  398. HKEY hKey,
  399. LPTSTR lpszPath,
  400. LPTSTR lpszValueName,
  401. LPTSTR lpszValue,
  402. LPDWORD lpdwSize
  403. )
  404. {
  405. HKEY hKeyPath;
  406. BOOLEAN bRet = FALSE;
  407. DWORD dwSize;
  408. LONG lRet;
  409. if ((lRet = RegOpenKey(hKey,
  410. lpszPath,
  411. &hKeyPath)) != ERROR_SUCCESS) {
  412. goto RPVO_exit;
  413. }
  414. if ((lRet = RegQueryValueEx(hKeyPath,
  415. lpszValueName,
  416. NULL,
  417. NULL,
  418. (PBYTE) lpszValue,
  419. lpdwSize)) == ERROR_SUCCESS) {
  420. bRet = TRUE;
  421. }
  422. RegCloseKey(hKeyPath);
  423. RPVO_exit:
  424. return bRet;
  425. }
  426. /*******************************************************************************
  427. *
  428. * ReadPowerIntOptional
  429. *
  430. * DESCRIPTION:
  431. * Integer value may not exist.
  432. *
  433. * PARAMETERS:
  434. *
  435. *******************************************************************************/
  436. BOOLEAN ReadPowerIntOptional(
  437. HKEY hKey,
  438. LPTSTR lpszPath,
  439. LPTSTR lpszValueName,
  440. PINT piVal
  441. )
  442. {
  443. HKEY hKeyPath;
  444. BOOLEAN bRet = FALSE;
  445. DWORD dwSize;
  446. TCHAR szNum[NUM_DEC_DIGITS];
  447. LONG lRet;
  448. if ((lRet = RegOpenKey(hKey,
  449. lpszPath,
  450. &hKeyPath)) != ERROR_SUCCESS) {
  451. goto RPVO_exit;
  452. }
  453. dwSize = sizeof(szNum);
  454. if ((lRet = RegQueryValueEx(hKeyPath,
  455. lpszValueName,
  456. NULL,
  457. NULL,
  458. (PBYTE) szNum,
  459. &dwSize)) == ERROR_SUCCESS) {
  460. if (MyStrToInt(szNum, piVal)) {
  461. bRet = TRUE;
  462. }
  463. }
  464. RegCloseKey(hKeyPath);
  465. RPVO_exit:
  466. return bRet;
  467. }
  468. /*******************************************************************************
  469. *
  470. * CreatePowerValue
  471. *
  472. * DESCRIPTION:
  473. * Value may not exist.
  474. *
  475. * PARAMETERS:
  476. *
  477. *******************************************************************************/
  478. BOOLEAN CreatePowerValue(
  479. HKEY hKey,
  480. LPCTSTR lpszPath,
  481. LPCTSTR lpszValueName,
  482. LPCTSTR lpszValue
  483. )
  484. {
  485. DWORD dwDisposition, dwDescSize;
  486. HKEY hKeyPath;
  487. BOOLEAN bRet = FALSE;
  488. DWORD dwSize;
  489. LONG lRet;
  490. // Wait on/take the registry semaphore.
  491. if (!TakeRegSemaphore()) // Will SetLastError
  492. {
  493. return FALSE;
  494. }
  495. if ((lRet = RegCreateKeyEx(hKey,
  496. lpszPath,
  497. 0,
  498. TEXT(""),
  499. REG_OPTION_NON_VOLATILE,
  500. KEY_WRITE,
  501. NULL,
  502. &hKeyPath,
  503. &dwDisposition)) == ERROR_SUCCESS)
  504. {
  505. if (lpszValue)
  506. {
  507. dwSize = (lstrlen(lpszValue) + 1) * sizeof(TCHAR);
  508. if ((lRet = RegSetValueEx(hKeyPath,
  509. lpszValueName,
  510. 0,
  511. REG_SZ,
  512. (PBYTE) lpszValue,
  513. dwSize)) == ERROR_SUCCESS)
  514. {
  515. bRet = TRUE;
  516. }
  517. }
  518. else
  519. {
  520. lRet = ERROR_INVALID_PARAMETER;
  521. }
  522. RegCloseKey(hKeyPath);
  523. }
  524. if (!bRet)
  525. {
  526. SetLastError(lRet);
  527. }
  528. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  529. return bRet;
  530. }
  531. /*******************************************************************************
  532. *
  533. * ReadWritePowerValue
  534. *
  535. * DESCRIPTION:
  536. *
  537. * PARAMETERS:
  538. *
  539. *******************************************************************************/
  540. BOOLEAN ReadWritePowerValue(
  541. HKEY hKey,
  542. LPTSTR lpszPath,
  543. LPTSTR lpszValueName,
  544. LPTSTR lpszValue,
  545. LPDWORD lpdwSize,
  546. BOOLEAN bWrite,
  547. BOOLEAN bTakeSemaphore
  548. )
  549. {
  550. // This function will set the Last Error correctly on failure
  551. HKEY hKeyPath;
  552. BOOLEAN bRet = FALSE;
  553. DWORD dwSize;
  554. LONG lRet;
  555. if ((lRet = RegOpenKey(hKey,
  556. lpszPath,
  557. &hKeyPath)) != ERROR_SUCCESS)
  558. {
  559. goto RWPV_exit;
  560. }
  561. // Wait on/take the registry semaphore.
  562. if (bTakeSemaphore)
  563. {
  564. if (!TakeRegSemaphore()) // Will Set last error
  565. {
  566. return FALSE;
  567. }
  568. }
  569. if (bWrite)
  570. {
  571. // Write current case.
  572. if (lpszValue)
  573. {
  574. dwSize = (lstrlen(lpszValue) + 1) * sizeof(TCHAR);
  575. if ((lRet = RegSetValueEx(hKeyPath,
  576. lpszValueName,
  577. 0,
  578. REG_SZ,
  579. (PBYTE) lpszValue,
  580. dwSize)) == ERROR_SUCCESS)
  581. {
  582. bRet = TRUE;
  583. }
  584. }
  585. else
  586. {
  587. lRet = ERROR_INVALID_PARAMETER;
  588. }
  589. }
  590. else
  591. {
  592. // Read current case.
  593. if ((lRet = RegQueryValueEx(hKeyPath,
  594. lpszValueName,
  595. NULL,
  596. NULL,
  597. (PBYTE) lpszValue,
  598. lpdwSize)) == ERROR_SUCCESS)
  599. {
  600. bRet = TRUE;
  601. }
  602. }
  603. if (bTakeSemaphore)
  604. {
  605. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  606. }
  607. RegCloseKey(hKeyPath);
  608. RWPV_exit:
  609. if (!bRet)
  610. {
  611. if (lRet == ERROR_SUCCESS)
  612. {
  613. lRet = GetLastError();
  614. }
  615. SetLastError(lRet);
  616. // Access denied is a valid result.
  617. if (lRet != ERROR_ACCESS_DENIED)
  618. {
  619. DebugPrint("ReadWritePowerValue, failed, lpszValueName: %s, LastError: 0x%08X", lpszValueName, lRet);
  620. }
  621. }
  622. return bRet;
  623. }
  624. /*******************************************************************************
  625. *
  626. * ReadPwrPolicyEx
  627. *
  628. * DESCRIPTION:
  629. * Supports ReadPwrScheme and ReadGlobalPwrPolicy
  630. *
  631. * PARAMETERS:
  632. * lpdwDescSize - Pointer to size of optional description buffer.
  633. * lpszDesc - Optional description buffer.
  634. *
  635. *******************************************************************************/
  636. DWORD ReadPwrPolicyEx2(
  637. LPTSTR lpszUserKeyName,
  638. LPTSTR lpszMachineKeyName,
  639. LPTSTR lpszSchemeName,
  640. LPTSTR lpszDesc,
  641. LPDWORD lpdwDescSize,
  642. LPVOID lpvUser,
  643. DWORD dwcbUserSize,
  644. LPVOID lpvMachine,
  645. DWORD dwcbMachineSize
  646. )
  647. {
  648. HKEY hKeyUser, hKeyMachine;
  649. DWORD dwType, dwSize;
  650. DWORD dwError = ERROR_SUCCESS;
  651. BOOLEAN bRet = FALSE;
  652. if ((!lpszUserKeyName || !lpszMachineKeyName) ||
  653. (!lpszSchemeName || !lpvUser || !lpvMachine) ||
  654. (!lpdwDescSize && lpszDesc) ||
  655. (lpdwDescSize && !lpszDesc))
  656. {
  657. dwError = ERROR_INVALID_PARAMETER;
  658. }
  659. else
  660. {
  661. // Wait on/take the registry semaphore.
  662. if (!TakeRegSemaphore()) // Will Set Last Error
  663. {
  664. return GetLastError();
  665. }
  666. dwError = OpenPathKeys(lpszUserKeyName, lpszMachineKeyName, lpszSchemeName, &hKeyUser, &hKeyMachine, TRUE, KEY_READ);
  667. if (ERROR_SUCCESS != dwError)
  668. {
  669. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  670. return dwError;
  671. }
  672. dwSize = dwcbUserSize;
  673. dwError = RegQueryValueEx(hKeyUser,
  674. TEXT("Policies"),
  675. NULL,
  676. &dwType,
  677. (PBYTE) lpvUser,
  678. &dwSize);
  679. if (dwError == ERROR_SUCCESS)
  680. {
  681. if (dwType == REG_BINARY)
  682. {
  683. dwSize = dwcbMachineSize;
  684. dwError = RegQueryValueEx(hKeyMachine,
  685. TEXT("Policies"),
  686. NULL,
  687. &dwType,
  688. (PBYTE) lpvMachine,
  689. &dwSize);
  690. }
  691. else
  692. {
  693. dwError = ERROR_INVALID_DATATYPE;
  694. }
  695. }
  696. if (dwError == ERROR_SUCCESS)
  697. {
  698. if (dwType == REG_BINARY)
  699. {
  700. if (lpdwDescSize)
  701. {
  702. dwError = RegQueryValueEx(hKeyUser, TEXT("Description"), NULL, &dwType, (PBYTE) lpszDesc, lpdwDescSize);
  703. }
  704. }
  705. else
  706. {
  707. dwError = ERROR_INVALID_DATATYPE;
  708. }
  709. }
  710. RegCloseKey(hKeyUser);
  711. RegCloseKey(hKeyMachine);
  712. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  713. }
  714. if (ERROR_SUCCESS != dwError)
  715. {
  716. DebugPrint("ReadPwrPolicyEx, failed, LastError: 0x%08X", dwError);
  717. DebugPrint(" lpszUserKeyName: %s, lpszSchemeName: %s", lpszUserKeyName, lpszSchemeName);
  718. SetLastError(dwError);
  719. }
  720. return dwError;
  721. }
  722. DWORD
  723. ReadProcessorPwrPolicy(
  724. LPTSTR lpszMachineKeyName,
  725. LPTSTR lpszSchemeName,
  726. LPVOID lpvMachineProcessor,
  727. DWORD dwcbMachineProcessorSize
  728. )
  729. {
  730. HKEY hKeyMachine = NULL;
  731. HKEY hKeyPolicy = NULL;
  732. DWORD dwError = ERROR_SUCCESS;
  733. DWORD dwDisposition, dwSize, dwType;
  734. if (!lpszMachineKeyName || !lpvMachineProcessor) {
  735. dwError = ERROR_INVALID_PARAMETER;
  736. goto ReadProcessorPwrPolicyEnd;
  737. }
  738. // Wait on/take the registry semaphore.
  739. if (!TakeRegSemaphore()) // Will Set Last Error
  740. {
  741. return GetLastError();
  742. }
  743. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszMachineKeyName, 0, KEY_READ, &hKeyMachine);
  744. if (ERROR_SUCCESS != dwError) goto ReadProcessorPwrPolicyExit;
  745. dwError = RegCreateKeyEx(hKeyMachine, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKeyPolicy, &dwDisposition);
  746. if (ERROR_SUCCESS != dwError) goto ReadProcessorPwrPolicyExit;
  747. dwSize = dwcbMachineProcessorSize;
  748. dwError = RegQueryValueEx(hKeyPolicy,
  749. TEXT("Policies"),
  750. NULL,
  751. &dwType,
  752. (PBYTE) lpvMachineProcessor,
  753. &dwSize);
  754. if (REG_BINARY != dwType) {
  755. dwError = ERROR_INVALID_DATATYPE;
  756. }
  757. ReadProcessorPwrPolicyExit:
  758. if (hKeyPolicy) RegCloseKey(hKeyPolicy);
  759. if (hKeyMachine) RegCloseKey(hKeyMachine);
  760. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  761. ReadProcessorPwrPolicyEnd:
  762. if (ERROR_SUCCESS != dwError)
  763. {
  764. DebugPrint("ReadProcessorPwrPolicy, failed, LastError: 0x%08X", dwError);
  765. DebugPrint(" lpszMachineKeyName: %s, lpszSchemeName: %s", lpszMachineKeyName, lpszSchemeName);
  766. SetLastError(dwError);
  767. }
  768. return dwError;
  769. }
  770. DWORD
  771. WriteProcessorPwrPolicy(
  772. LPTSTR lpszMachineKeyName,
  773. LPTSTR lpszSchemeName,
  774. LPVOID lpvMachineProcessor,
  775. DWORD dwcbMachineProcessorSize
  776. )
  777. {
  778. HKEY hKeyMachine = NULL;
  779. HKEY hKeyPolicy = NULL;
  780. DWORD dwError = ERROR_SUCCESS;
  781. DWORD dwDisposition;
  782. if (!lpszMachineKeyName || !lpvMachineProcessor) {
  783. dwError = ERROR_INVALID_PARAMETER;
  784. goto WriteProcessorPwrPolicyEnd;
  785. }
  786. // Wait on/take the registry semaphore.
  787. if (!TakeRegSemaphore()) // Will Set Last Error
  788. {
  789. return GetLastError();
  790. }
  791. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszMachineKeyName, 0, KEY_WRITE, &hKeyMachine);
  792. if (ERROR_SUCCESS != dwError) goto WriteProcessorPwrPolicyExit;
  793. dwError = RegCreateKeyEx(hKeyMachine, lpszSchemeName, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyPolicy, &dwDisposition);
  794. if (ERROR_SUCCESS != dwError) goto WriteProcessorPwrPolicyExit;
  795. dwError = RegSetValueEx(hKeyPolicy,
  796. TEXT("Policies"),
  797. 0,
  798. REG_BINARY,
  799. (PBYTE) lpvMachineProcessor,
  800. dwcbMachineProcessorSize);
  801. WriteProcessorPwrPolicyExit:
  802. if (hKeyPolicy) RegCloseKey(hKeyPolicy);
  803. if (hKeyMachine) RegCloseKey(hKeyMachine);
  804. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  805. WriteProcessorPwrPolicyEnd:
  806. if (ERROR_SUCCESS != dwError)
  807. {
  808. DebugPrint("WriteProcessorPwrPolicy, failed, LastError: 0x%08X", dwError);
  809. DebugPrint(" lpszMachineKeyName: %s, lpszSchemeName: %s", lpszMachineKeyName, lpszSchemeName);
  810. SetLastError(dwError);
  811. }
  812. return dwError;
  813. }
  814. /*******************************************************************************
  815. *
  816. * WritePwrPolicyEx
  817. *
  818. * DESCRIPTION:
  819. * Supports WritePwrScheme and
  820. * WriteGlobalPwrPolicy
  821. *
  822. * PARAMETERS:
  823. *
  824. *******************************************************************************/
  825. BOOLEAN WritePwrPolicyEx(
  826. LPTSTR lpszUserKeyName,
  827. LPTSTR lpszMachineKeyName,
  828. PUINT puiID,
  829. LPTSTR lpszName,
  830. LPTSTR lpszDescription,
  831. LPVOID lpvUser,
  832. DWORD dwcbUserSize,
  833. LPVOID lpvMachine,
  834. DWORD dwcbMachineSize
  835. )
  836. {
  837. // The function will set the last error if it fails.
  838. HKEY hKeyUser, hKeyMachine;
  839. LONG lRet = ERROR_SUCCESS;
  840. DWORD dwDisposition, dwSize;
  841. TCHAR szNum[NUM_DEC_DIGITS];
  842. LPTSTR lpszKeyName;
  843. if ((!lpszUserKeyName || !lpszMachineKeyName || !lpvUser || !lpvMachine) || (!puiID && !lpszName))
  844. {
  845. SetLastError(ERROR_INVALID_PARAMETER);
  846. lRet = ERROR_INVALID_PARAMETER;
  847. }
  848. else
  849. {
  850. // If a scheme ID was passed
  851. if (puiID)
  852. {
  853. if (*puiID == NEWSCHEME)
  854. {
  855. *puiID = ++g_uiLastID;
  856. wsprintf(szNum, TEXT("%d"), *puiID);
  857. // This ReadWritePowerValue will SetLastError
  858. if (!ReadWritePowerValue(HKEY_LOCAL_MACHINE,
  859. c_szREGSTR_PATH_MACHINE_POWERCFG,
  860. c_szREGSTR_VAL_LASTID,
  861. szNum, &dwSize, TRUE, TRUE))
  862. {
  863. return FALSE;
  864. }
  865. }
  866. else
  867. {
  868. wsprintf(szNum, TEXT("%d"), *puiID);
  869. }
  870. lpszKeyName = szNum;
  871. }
  872. else
  873. {
  874. lpszKeyName = lpszName;
  875. }
  876. // Wait on/take the registry semaphore.
  877. if (!TakeRegSemaphore()) // Will set last error
  878. {
  879. return FALSE;
  880. }
  881. lRet = OpenPathKeys(lpszUserKeyName, lpszMachineKeyName, lpszKeyName, &hKeyUser, &hKeyMachine, FALSE, KEY_WRITE);
  882. if (ERROR_SUCCESS != lRet)
  883. {
  884. ReleaseSemaphore(g_hSemRegistry, 1, FALSE);
  885. SetLastError(lRet);
  886. return FALSE;
  887. }
  888. // Write the binary policies data
  889. if ((lRet = RegSetValueEx(hKeyUser,
  890. TEXT("Policies"),
  891. 0,
  892. REG_BINARY,
  893. (PBYTE) lpvUser,
  894. dwcbUserSize)) == ERROR_SUCCESS)
  895. {
  896. // Write the binary policies data
  897. if ((lRet = RegSetValueEx(hKeyMachine,
  898. TEXT("Policies"),
  899. 0,
  900. REG_BINARY,
  901. (PBYTE) lpvMachine,
  902. dwcbMachineSize)) == ERROR_SUCCESS)
  903. {
  904. // Write the name text if an ID was provided.
  905. if (lpszName && puiID)
  906. {
  907. dwSize = (lstrlen(lpszName) + 1) * sizeof(TCHAR);
  908. lRet = RegSetValueEx(hKeyUser, TEXT("Name"), 0, REG_SZ, (PBYTE) lpszName, dwSize);
  909. }
  910. // Write the description text.
  911. if (lpszDescription && (lRet == ERROR_SUCCESS))
  912. {
  913. dwSize = (lstrlen(lpszDescription) + 1) * sizeof(TCHAR);
  914. lRet = RegSetValueEx(hKeyUser, TEXT("Description"), 0, REG_SZ, (PBYTE) lpszDescription, dwSize);
  915. }
  916. }
  917. }
  918. RegCloseKey(hKeyUser);
  919. RegCloseKey(hKeyMachine);
  920. ReleaseSemaphore(g_hSemRegistry, 1, NULL);
  921. }
  922. if (lRet != ERROR_SUCCESS)
  923. {
  924. DebugPrint("WritePwrPolicyEx, failed, LastError: 0x%08X", lRet);
  925. DebugPrint(" lpszUserKeyName: %s, lpszKeyName: %s", lpszUserKeyName, lpszKeyName);
  926. SetLastError(lRet);
  927. return FALSE;
  928. }
  929. return TRUE;
  930. }