Leaked source code of windows server 2003
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.

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