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.

4975 lines
157 KiB

  1. //*************************************************************
  2. //
  3. // Group Policy Support - State functions
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1997-1998
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "gphdr.h"
  11. #include <strsafe.h>
  12. //*************************************************************
  13. //
  14. // GetDeletedGPOList()
  15. //
  16. // Purpose: Get the list of deleted GPOs
  17. //
  18. // Parameters: lpGPOList - List of old GPOs
  19. // ppDeletedGPOList - Deleted list returned here
  20. //
  21. //
  22. // Return: TRUE if successful
  23. // FALSE if an error occurs
  24. //
  25. //*************************************************************
  26. BOOL GetDeletedGPOList (PGROUP_POLICY_OBJECT lpGPOList,
  27. PGROUP_POLICY_OBJECT *ppDeletedGPOList)
  28. {
  29. //
  30. // It's possible that lpGPOList could be NULL. This is ok.
  31. //
  32. if (!lpGPOList) {
  33. DebugMsg((DM_VERBOSE, TEXT("GetDeletedList: No old GPOs. Leaving.")));
  34. return TRUE;
  35. }
  36. //
  37. // We need to do any delete operations in reverse order
  38. // of the way there were applied. Also, check that duplicates
  39. // of same GPO are not being added.
  40. //
  41. while ( lpGPOList ) {
  42. PGROUP_POLICY_OBJECT pCurGPO = lpGPOList;
  43. lpGPOList = lpGPOList->pNext;
  44. if ( pCurGPO->lParam & GPO_LPARAM_FLAG_DELETE ) {
  45. PGROUP_POLICY_OBJECT lpGPODest = *ppDeletedGPOList;
  46. BOOL bDup = FALSE;
  47. while (lpGPODest) {
  48. if (!lstrcmpi (pCurGPO->szGPOName, lpGPODest->szGPOName)) {
  49. bDup = TRUE;
  50. break;
  51. }
  52. lpGPODest = lpGPODest->pNext;
  53. }
  54. if (!bDup) {
  55. //
  56. // Not a duplicate, so prepend to deleted list
  57. //
  58. pCurGPO->pNext = *ppDeletedGPOList;
  59. pCurGPO->pPrev = NULL;
  60. if ( *ppDeletedGPOList )
  61. (*ppDeletedGPOList)->pPrev = pCurGPO;
  62. *ppDeletedGPOList = pCurGPO;
  63. } else
  64. LocalFree( pCurGPO );
  65. } else
  66. LocalFree( pCurGPO );
  67. }
  68. DebugMsg((DM_VERBOSE, TEXT("GetDeletedGPOList: Finished.")));
  69. return TRUE;
  70. }
  71. //*************************************************************
  72. //
  73. // ReadGPOList()
  74. //
  75. // Purpose: Reads the list of Group Policy Objects from
  76. // the registry
  77. //
  78. // Parameters: pszExtName - GP extension
  79. // hKeyRoot - Registry handle
  80. // hKeyRootMach - Registry handle to hklm
  81. // lpwszSidUser - Sid of user, if non-null then it means
  82. // per user local setting
  83. // bShadow - Read from shadow or from history list
  84. // lpGPOList - pointer to the array of GPOs
  85. //
  86. //
  87. // Return: TRUE if successful
  88. // FALSE if an error occurs
  89. //
  90. //*************************************************************
  91. BOOL ReadGPOList ( TCHAR * pszExtName, HKEY hKeyRoot,
  92. HKEY hKeyRootMach, LPTSTR lpwszSidUser, BOOL bShadow,
  93. PGROUP_POLICY_OBJECT * lpGPOList)
  94. {
  95. INT iIndex = 0;
  96. LONG lResult;
  97. HKEY hKey, hSubKey = NULL;
  98. BOOL bResult = FALSE;
  99. TCHAR szSubKey[CCH_MAX_DEC];
  100. DWORD dwOptions, dwVersion;
  101. GPO_LINK GPOLink;
  102. LPARAM lParam;
  103. TCHAR szGPOName[50];
  104. LPTSTR lpDSPath = NULL, lpFileSysPath = NULL, lpDisplayName = NULL, lpExtensions = NULL, lpLink = NULL;
  105. DWORD dwDisp, dwSize, dwType, dwTemp, dwMaxSize;
  106. PGROUP_POLICY_OBJECT lpGPO, lpGPOTemp;
  107. TCHAR szKey[400];
  108. XLastError xe;
  109. HRESULT hr = S_OK;
  110. //
  111. // Set default
  112. //
  113. *lpGPOList = NULL;
  114. //
  115. // Open the key that holds the GPO list
  116. //
  117. if ( lpwszSidUser == 0 ) {
  118. hr = StringCchPrintf (szKey, ARRAYSIZE(szKey),
  119. bShadow ? GP_SHADOW_KEY
  120. : GP_HISTORY_KEY,
  121. pszExtName );
  122. } else {
  123. hr = StringCchPrintf (szKey, ARRAYSIZE(szKey),
  124. bShadow ? GP_SHADOW_SID_KEY
  125. : GP_HISTORY_SID_KEY,
  126. lpwszSidUser, pszExtName );
  127. }
  128. if ( FAILED(hr) ) {
  129. xe = HRESULT_CODE(hr);
  130. return FALSE;
  131. }
  132. lResult = RegOpenKeyEx ( lpwszSidUser ? hKeyRootMach : hKeyRoot,
  133. szKey,
  134. 0, KEY_READ, &hKey);
  135. if (lResult != ERROR_SUCCESS) {
  136. if (lResult == ERROR_FILE_NOT_FOUND) {
  137. return TRUE;
  138. } else {
  139. xe = lResult;
  140. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to open reg key with %d."), lResult));
  141. return FALSE;
  142. }
  143. }
  144. while (TRUE) {
  145. //
  146. // Enumerate through the subkeys. The keys are named by index number
  147. // eg: 0, 1, 2, 3, etc...
  148. //
  149. IntToString (iIndex, szSubKey);
  150. lResult = RegOpenKeyEx (hKey, szSubKey, 0, KEY_READ, &hSubKey);
  151. if (lResult != ERROR_SUCCESS) {
  152. if (lResult == ERROR_FILE_NOT_FOUND) {
  153. bResult = TRUE;
  154. goto Exit;
  155. } else {
  156. xe = lResult;
  157. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to open reg key <%s> with %d."), szSubKey, lResult));
  158. goto Exit;
  159. }
  160. }
  161. //
  162. // Read the size of the largest value in this key
  163. //
  164. lResult = RegQueryInfoKey (hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  165. &dwMaxSize, NULL, NULL);
  166. if (lResult != ERROR_SUCCESS) {
  167. xe = lResult;
  168. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query max size with %d."), lResult));
  169. goto Exit;
  170. }
  171. //
  172. // RegQueryInfoKey does not account for trailing 0 in strings
  173. //
  174. dwMaxSize += sizeof( WCHAR );
  175. //
  176. // Allocate buffers based upon the value above
  177. //
  178. lpDSPath = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  179. if (!lpDSPath) {
  180. xe = GetLastError();
  181. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
  182. goto Exit;
  183. }
  184. lpFileSysPath = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  185. if (!lpFileSysPath) {
  186. xe = GetLastError();
  187. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
  188. goto Exit;
  189. }
  190. lpDisplayName = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  191. if (!lpDisplayName) {
  192. xe = GetLastError();
  193. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
  194. goto Exit;
  195. }
  196. lpExtensions = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  197. if (!lpExtensions) {
  198. xe = GetLastError();
  199. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
  200. goto Exit;
  201. }
  202. lpLink = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  203. if (!lpLink) {
  204. xe = GetLastError();
  205. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to allocate memory with %d."), GetLastError()));
  206. goto Exit;
  207. }
  208. //
  209. // Read in the GPO
  210. //
  211. dwOptions = 0;
  212. dwSize = sizeof(dwOptions);
  213. lResult = RegQueryValueEx (hSubKey, TEXT("Options"), NULL, &dwType,
  214. (LPBYTE) &dwOptions, &dwSize);
  215. if (lResult != ERROR_SUCCESS) {
  216. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query options reg value with %d."), lResult));
  217. }
  218. dwVersion = 0;
  219. dwSize = sizeof(dwVersion);
  220. lResult = RegQueryValueEx (hSubKey, TEXT("Version"), NULL, &dwType,
  221. (LPBYTE) &dwVersion, &dwSize);
  222. if (lResult != ERROR_SUCCESS) {
  223. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query Version reg value with %d."), lResult));
  224. }
  225. dwSize = dwMaxSize;
  226. lResult = RegQueryValueEx (hSubKey, TEXT("DSPath"), NULL, &dwType,
  227. (LPBYTE) lpDSPath, &dwSize);
  228. if (lResult != ERROR_SUCCESS) {
  229. if (lResult != ERROR_FILE_NOT_FOUND) {
  230. xe = lResult;
  231. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query DS reg value with %d."), lResult));
  232. goto Exit;
  233. }
  234. LocalFree (lpDSPath);
  235. lpDSPath = NULL;
  236. }
  237. dwSize = dwMaxSize;
  238. lResult = RegQueryValueEx (hSubKey, TEXT("FileSysPath"), NULL, &dwType,
  239. (LPBYTE) lpFileSysPath, &dwSize);
  240. if (lResult != ERROR_SUCCESS) {
  241. xe = lResult;
  242. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query file sys path reg value with %d."), lResult));
  243. goto Exit;
  244. }
  245. dwSize = dwMaxSize;
  246. lResult = RegQueryValueEx (hSubKey, TEXT("DisplayName"), NULL, &dwType,
  247. (LPBYTE) lpDisplayName, &dwSize);
  248. if (lResult != ERROR_SUCCESS) {
  249. xe = lResult;
  250. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query display name reg value with %d."), lResult));
  251. goto Exit;
  252. }
  253. dwSize = dwMaxSize;
  254. lResult = RegQueryValueEx (hSubKey, TEXT("Extensions"), NULL, &dwType,
  255. (LPBYTE) lpExtensions, &dwSize);
  256. if (lResult != ERROR_SUCCESS) {
  257. xe = lResult;
  258. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query extension names reg value with %d."), lResult));
  259. LocalFree(lpExtensions);
  260. lpExtensions = NULL;
  261. }
  262. dwSize = dwMaxSize;
  263. lResult = RegQueryValueEx (hSubKey, TEXT("Link"), NULL, &dwType,
  264. (LPBYTE) lpLink, &dwSize);
  265. if (lResult != ERROR_SUCCESS) {
  266. if (lResult != ERROR_FILE_NOT_FOUND) {
  267. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query DS Object reg value with %d."), lResult));
  268. }
  269. LocalFree(lpLink);
  270. lpLink = NULL;
  271. }
  272. dwSize = sizeof(szGPOName);
  273. lResult = RegQueryValueEx (hSubKey, TEXT("GPOName"), NULL, &dwType,
  274. (LPBYTE) szGPOName, &dwSize);
  275. if (lResult != ERROR_SUCCESS) {
  276. xe = lResult;
  277. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query GPO name reg value with %d."), lResult));
  278. goto Exit;
  279. }
  280. GPOLink = GPLinkUnknown;
  281. dwSize = sizeof(GPOLink);
  282. lResult = RegQueryValueEx (hSubKey, TEXT("GPOLink"), NULL, &dwType,
  283. (LPBYTE) &GPOLink, &dwSize);
  284. if (lResult != ERROR_SUCCESS) {
  285. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query reserved reg value with %d."), lResult));
  286. }
  287. lParam = 0;
  288. dwSize = sizeof(lParam);
  289. lResult = RegQueryValueEx (hSubKey, TEXT("lParam"), NULL, &dwType,
  290. (LPBYTE) &lParam, &dwSize);
  291. if (lResult != ERROR_SUCCESS) {
  292. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to query lParam reg value with %d."), lResult));
  293. }
  294. //
  295. // Add the GPO to the list
  296. //
  297. if (!AddGPO (lpGPOList, 0, TRUE, TRUE, FALSE, dwOptions, dwVersion, lpDSPath, lpFileSysPath,
  298. lpDisplayName, szGPOName, lpExtensions, 0, 0, GPOLink, lpLink, lParam, FALSE,
  299. FALSE, FALSE, TRUE)) {
  300. xe = GetLastError();
  301. DebugMsg((DM_WARNING, TEXT("ReadGPOList: Failed to add GPO to list.")));
  302. goto Exit;
  303. }
  304. //
  305. // Free the buffers allocated above
  306. //
  307. if (lpDSPath) {
  308. LocalFree (lpDSPath);
  309. lpDSPath = NULL;
  310. }
  311. LocalFree (lpFileSysPath);
  312. lpFileSysPath = NULL;
  313. LocalFree (lpDisplayName);
  314. lpDisplayName = NULL;
  315. if (lpExtensions) {
  316. LocalFree(lpExtensions);
  317. lpExtensions = NULL;
  318. }
  319. if (lpLink) {
  320. LocalFree(lpLink);
  321. lpLink = NULL;
  322. }
  323. //
  324. // Close the subkey handle
  325. //
  326. RegCloseKey (hSubKey);
  327. hSubKey = NULL;
  328. iIndex++;
  329. }
  330. Exit:
  331. if (lpDSPath) {
  332. LocalFree (lpDSPath);
  333. }
  334. if (lpFileSysPath) {
  335. LocalFree (lpFileSysPath);
  336. }
  337. if (lpDisplayName) {
  338. LocalFree (lpDisplayName);
  339. }
  340. if (lpExtensions) {
  341. LocalFree(lpExtensions);
  342. }
  343. if (lpLink) {
  344. LocalFree(lpLink);
  345. }
  346. if (hSubKey) {
  347. RegCloseKey (hSubKey);
  348. }
  349. RegCloseKey (hKey);
  350. if (!bResult) {
  351. //
  352. // Free any entries in the list
  353. //
  354. lpGPO = *lpGPOList;
  355. while (lpGPO) {
  356. lpGPOTemp = lpGPO->pNext;
  357. LocalFree (lpGPO);
  358. lpGPO = lpGPOTemp;
  359. }
  360. *lpGPOList = NULL;
  361. }
  362. return bResult;
  363. }
  364. //*************************************************************
  365. //
  366. // SaveGPOList()
  367. //
  368. // Purpose: Saves the list of Group Policy Objects in
  369. // the registry
  370. //
  371. // Parameters: pszExtName - GP extension
  372. // lpGPOInfo - Group policy info
  373. // hKeyRootMach - Registry handle to hklm
  374. // lpwszSidUser - Sid of user, if non-null then it means
  375. // per user local setting
  376. // bShadow - Save to shadow or to history list
  377. // lpGPOList - Array of GPOs
  378. //
  379. //
  380. // Return: TRUE if successful
  381. // FALSE if an error occurs
  382. //
  383. //*************************************************************
  384. BOOL SaveGPOList (TCHAR *pszExtName, LPGPOINFO lpGPOInfo,
  385. HKEY hKeyRootMach, LPTSTR lpwszSidUser, BOOL bShadow,
  386. PGROUP_POLICY_OBJECT lpGPOList)
  387. {
  388. INT iIndex = 0;
  389. LONG lResult;
  390. HKEY hKey = NULL;
  391. BOOL bResult = FALSE;
  392. TCHAR szSubKey[400];
  393. DWORD dwDisp, dwSize;
  394. XLastError xe;
  395. HRESULT hr = S_OK;
  396. //
  397. // Start off with an empty key
  398. //
  399. if ( lpwszSidUser == 0 ) {
  400. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey),
  401. bShadow ? GP_SHADOW_KEY
  402. : GP_HISTORY_KEY,
  403. pszExtName);
  404. } else {
  405. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey),
  406. bShadow ? GP_SHADOW_SID_KEY
  407. : GP_HISTORY_SID_KEY,
  408. lpwszSidUser, pszExtName);
  409. }
  410. if ( FAILED(hr) ) {
  411. xe = HRESULT_CODE(hr);
  412. return FALSE; // no need to go to exit as hkey is not got yet.
  413. }
  414. if (RegDelnode (lpwszSidUser ? hKeyRootMach : lpGPOInfo->hKeyRoot, szSubKey) != ERROR_SUCCESS) {
  415. DebugMsg((DM_VERBOSE, TEXT("SaveGPOList: RegDelnode failed.")));
  416. }
  417. //
  418. // Check if we have any GPOs to store. It's ok for this to be NULL.
  419. //
  420. if (!lpGPOList) {
  421. return TRUE;
  422. }
  423. //
  424. // Set the proper security on the registry key
  425. //
  426. if ( !MakeRegKeySecure( (lpGPOInfo->dwFlags & GP_MACHINE) ? NULL : lpGPOInfo->hToken,
  427. lpwszSidUser ? hKeyRootMach : lpGPOInfo->hKeyRoot,
  428. szSubKey ) ) {
  429. DebugMsg((DM_WARNING, TEXT("SaveGpoList: Failed to secure reg key.")));
  430. CEvents ev(TRUE, EVENT_FAILED_CREATE);
  431. ev.AddArg(szSubKey);
  432. ev.AddArgWin32Error(ERROR_ACCESS_DENIED);
  433. ev.Report();
  434. return FALSE;
  435. }
  436. //
  437. // Loop through the GPOs saving them in the registry
  438. //
  439. while (lpGPOList) {
  440. if ( lpwszSidUser == 0 ) {
  441. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey),
  442. bShadow ? TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\Shadow\\%ws\\%d")
  443. : TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History\\%ws\\%d"),
  444. pszExtName,
  445. iIndex);
  446. } else {
  447. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey),
  448. bShadow ? TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\%ws\\Shadow\\%ws\\%d")
  449. : TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\%ws\\History\\%ws\\%d"),
  450. lpwszSidUser, pszExtName, iIndex);
  451. }
  452. if ( FAILED(hr) ) {
  453. xe = HRESULT_CODE(hr);
  454. goto Exit;
  455. }
  456. lResult = RegCreateKeyEx (lpwszSidUser ? hKeyRootMach : lpGPOInfo->hKeyRoot,
  457. szSubKey, 0, NULL,
  458. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
  459. if (lResult != ERROR_SUCCESS) {
  460. xe = lResult;
  461. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to create reg key with %d."), lResult));
  462. goto Exit;
  463. }
  464. //
  465. // Save the GPO
  466. //
  467. dwSize = sizeof(lpGPOList->dwOptions);
  468. lResult = RegSetValueEx (hKey, TEXT("Options"), 0, REG_DWORD,
  469. (LPBYTE) &lpGPOList->dwOptions, dwSize);
  470. if (lResult != ERROR_SUCCESS) {
  471. xe = lResult;
  472. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set options reg value with %d."), lResult));
  473. goto Exit;
  474. }
  475. dwSize = sizeof(lpGPOList->dwVersion);
  476. lResult = RegSetValueEx (hKey, TEXT("Version"), 0, REG_DWORD,
  477. (LPBYTE) &lpGPOList->dwVersion, dwSize);
  478. if (lResult != ERROR_SUCCESS) {
  479. xe = lResult;
  480. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set Version reg value with %d."), lResult));
  481. goto Exit;
  482. }
  483. if (lpGPOList->lpDSPath) {
  484. dwSize = (lstrlen (lpGPOList->lpDSPath) + 1) * sizeof(TCHAR);
  485. lResult = RegSetValueEx (hKey, TEXT("DSPath"), 0, REG_SZ,
  486. (LPBYTE) lpGPOList->lpDSPath, dwSize);
  487. if (lResult != ERROR_SUCCESS) {
  488. xe = lResult;
  489. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set DS reg value with %d."), lResult));
  490. goto Exit;
  491. }
  492. }
  493. dwSize = (lstrlen (lpGPOList->lpFileSysPath) + 1) * sizeof(TCHAR);
  494. lResult = RegSetValueEx (hKey, TEXT("FileSysPath"), 0, REG_SZ,
  495. (LPBYTE) lpGPOList->lpFileSysPath, dwSize);
  496. if (lResult != ERROR_SUCCESS) {
  497. xe = lResult;
  498. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set file sys path reg value with %d."), lResult));
  499. goto Exit;
  500. }
  501. dwSize = (lstrlen (lpGPOList->lpDisplayName) + 1) * sizeof(TCHAR);
  502. lResult = RegSetValueEx (hKey, TEXT("DisplayName"), 0, REG_SZ,
  503. (LPBYTE) lpGPOList->lpDisplayName, dwSize);
  504. if (lResult != ERROR_SUCCESS) {
  505. xe = lResult;
  506. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set display name reg value with %d."), lResult));
  507. goto Exit;
  508. }
  509. if (lpGPOList->lpExtensions) {
  510. dwSize = (lstrlen (lpGPOList->lpExtensions) + 1) * sizeof(TCHAR);
  511. lResult = RegSetValueEx (hKey, TEXT("Extensions"), 0, REG_SZ,
  512. (LPBYTE) lpGPOList->lpExtensions, dwSize);
  513. if (lResult != ERROR_SUCCESS) {
  514. xe = lResult;
  515. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set extension names reg value with %d."), lResult));
  516. goto Exit;
  517. }
  518. }
  519. if (lpGPOList->lpLink) {
  520. dwSize = (lstrlen (lpGPOList->lpLink) + 1) * sizeof(TCHAR);
  521. lResult = RegSetValueEx (hKey, TEXT("Link"), 0, REG_SZ,
  522. (LPBYTE) lpGPOList->lpLink, dwSize);
  523. if (lResult != ERROR_SUCCESS) {
  524. xe = lResult;
  525. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set DSObject reg value with %d."), lResult));
  526. goto Exit;
  527. }
  528. }
  529. dwSize = (lstrlen (lpGPOList->szGPOName) + 1) * sizeof(TCHAR);
  530. lResult = RegSetValueEx (hKey, TEXT("GPOName"), 0, REG_SZ,
  531. (LPBYTE) lpGPOList->szGPOName, dwSize);
  532. if (lResult != ERROR_SUCCESS) {
  533. xe = lResult;
  534. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set GPO name reg value with %d."), lResult));
  535. goto Exit;
  536. }
  537. dwSize = sizeof(lpGPOList->GPOLink);
  538. lResult = RegSetValueEx (hKey, TEXT("GPOLink"), 0, REG_DWORD,
  539. (LPBYTE) &lpGPOList->GPOLink, dwSize);
  540. if (lResult != ERROR_SUCCESS) {
  541. xe = lResult;
  542. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set GPOLink reg value with %d."), lResult));
  543. goto Exit;
  544. }
  545. dwSize = sizeof(lpGPOList->lParam);
  546. lResult = RegSetValueEx (hKey, TEXT("lParam"), 0, REG_DWORD,
  547. (LPBYTE) &lpGPOList->lParam, dwSize);
  548. if (lResult != ERROR_SUCCESS) {
  549. xe = lResult;
  550. DebugMsg((DM_WARNING, TEXT("SaveGPOList: Failed to set lParam reg value with %d."), lResult));
  551. goto Exit;
  552. }
  553. //
  554. // Close the handle
  555. //
  556. RegCloseKey (hKey);
  557. hKey = NULL;
  558. //
  559. // Prep for the next loop
  560. //
  561. iIndex++;
  562. lpGPOList = lpGPOList->pNext;
  563. }
  564. //
  565. // Success
  566. //
  567. bResult = TRUE;
  568. Exit:
  569. if (hKey) {
  570. RegCloseKey (hKey);
  571. }
  572. return bResult;
  573. }
  574. //*************************************************************
  575. //
  576. // WriteStatus()
  577. //
  578. // Purpose: Saves status in the registry
  579. //
  580. // Parameters: lpGPOInfo - GPO info
  581. // lpExtName - GP extension name
  582. // dwStatus - Status to write
  583. // dwTime - Policy time to write
  584. // dwSlowLink - Link speed to write
  585. // dwRsopLogging - Rsop Logging to Write
  586. //
  587. //
  588. // Return: TRUE if successful
  589. // FALSE if an error occurs
  590. //
  591. //*************************************************************
  592. BOOL WriteStatus( TCHAR *lpExtName, LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, LPGPEXTSTATUS lpExtStatus )
  593. {
  594. HKEY hKey = NULL, hKeyExt = NULL;
  595. DWORD dwDisp, dwSize;
  596. LONG lResult;
  597. BOOL bResult = FALSE;
  598. TCHAR szKey[400];
  599. XLastError xe;
  600. HRESULT hr = S_OK;
  601. if ( lpwszSidUser == 0 ) {
  602. hr = StringCchPrintf (szKey, ARRAYSIZE(szKey),
  603. GP_EXTENSIONS_KEY,
  604. lpExtName);
  605. } else {
  606. hr = StringCchPrintf (szKey, ARRAYSIZE(szKey),
  607. GP_EXTENSIONS_SID_KEY,
  608. lpwszSidUser, lpExtName);
  609. }
  610. if ( FAILED(hr) ) {
  611. xe = HRESULT_CODE(hr);
  612. return FALSE; // no need to go to exit here
  613. }
  614. lResult = RegCreateKeyEx (lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
  615. szKey, 0, NULL,
  616. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
  617. if (lResult != ERROR_SUCCESS) {
  618. xe = lResult;
  619. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to create reg key with %d."), lResult));
  620. goto Exit;
  621. }
  622. dwSize = sizeof(lpExtStatus->dwStatus);
  623. lResult = RegSetValueEx (hKey, TEXT("Status"), 0, REG_DWORD,
  624. (LPBYTE) &(lpExtStatus->dwStatus), dwSize);
  625. if (lResult != ERROR_SUCCESS) {
  626. xe = lResult;
  627. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set status reg value with %d."), lResult));
  628. goto Exit;
  629. }
  630. dwSize = sizeof(lpExtStatus->dwRsopStatus);
  631. lResult = RegSetValueEx (hKey, TEXT("RsopStatus"), 0, REG_DWORD,
  632. (LPBYTE) &(lpExtStatus->dwRsopStatus), dwSize);
  633. if (lResult != ERROR_SUCCESS) {
  634. xe = lResult;
  635. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set rsop status reg value with %d."), lResult));
  636. goto Exit;
  637. }
  638. dwSize = sizeof(lpExtStatus->dwTime);
  639. lResult = RegSetValueEx (hKey, TEXT("LastPolicyTime"), 0, REG_DWORD,
  640. (LPBYTE) &(lpExtStatus->dwTime), dwSize);
  641. if (lResult != ERROR_SUCCESS) {
  642. xe = lResult;
  643. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set time reg value with %d."), lResult));
  644. goto Exit;
  645. }
  646. dwSize = sizeof(lpExtStatus->dwSlowLink);
  647. lResult = RegSetValueEx (hKey, TEXT("PrevSlowLink"), 0, REG_DWORD,
  648. (LPBYTE) &(lpExtStatus->dwSlowLink), dwSize);
  649. if (lResult != ERROR_SUCCESS) {
  650. xe = lResult;
  651. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set slowlink reg value with %d."), lResult));
  652. goto Exit;
  653. }
  654. dwSize = sizeof(lpExtStatus->dwRsopLogging);
  655. lResult = RegSetValueEx (hKey, TEXT("PrevRsopLogging"), 0, REG_DWORD,
  656. (LPBYTE) &(lpExtStatus->dwRsopLogging), dwSize);
  657. if (lResult != ERROR_SUCCESS) {
  658. xe = lResult;
  659. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set RsopLogging reg value with %d."), lResult));
  660. goto Exit;
  661. }
  662. dwSize = sizeof(lpExtStatus->bForceRefresh);
  663. lResult = RegSetValueEx (hKey, TEXT("ForceRefreshFG"), 0, REG_DWORD,
  664. (LPBYTE) &(lpExtStatus->bForceRefresh), dwSize);
  665. if (lResult != ERROR_SUCCESS) {
  666. xe = lResult;
  667. DebugMsg((DM_WARNING, TEXT("WriteStatus: Failed to set ForceRefresh reg value with %d."), lResult));
  668. goto Exit;
  669. }
  670. bResult = TRUE;
  671. Exit:
  672. if ( hKey != NULL )
  673. RegCloseKey( hKey );
  674. if ( hKeyExt != NULL )
  675. RegCloseKey( hKeyExt );
  676. return bResult;
  677. }
  678. //*************************************************************
  679. //
  680. // ReadStatus()
  681. //
  682. // Purpose: Reads status from the registry
  683. //
  684. // Parameters: lpKeyName - Extension name
  685. // lpGPOInfo - GPO info
  686. // lpwszSidUser - Sid of user, if non-null then it means
  687. // per user local setting
  688. // (out) lpExtStatus - The extension status returned.
  689. //
  690. // Return: TRUE if successful
  691. // FALSE if an error occurs
  692. //
  693. //*************************************************************
  694. void ReadStatus ( TCHAR *lpKeyName, LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, LPGPEXTSTATUS lpExtStatus )
  695. {
  696. HKEY hKey = NULL, hKeyExt = NULL;
  697. DWORD dwType, dwSize;
  698. LONG lResult;
  699. BOOL bResult = FALSE;
  700. TCHAR szKey[400];
  701. XLastError xe;
  702. HRESULT hr = S_OK;
  703. memset(lpExtStatus, 0, sizeof(GPEXTSTATUS));
  704. if ( lpwszSidUser == 0 ) {
  705. hr = StringCchPrintf (szKey, ARRAYSIZE(szKey),
  706. GP_EXTENSIONS_KEY,
  707. lpKeyName);
  708. } else {
  709. hr = StringCchPrintf (szKey, ARRAYSIZE(szKey),
  710. GP_EXTENSIONS_SID_KEY,
  711. lpwszSidUser, lpKeyName);
  712. }
  713. if ( FAILED(hr) ) {
  714. xe = ERROR_INSUFFICIENT_BUFFER;
  715. return; // no need to go to exit here.
  716. }
  717. lResult = RegOpenKeyEx (lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
  718. szKey,
  719. 0, KEY_READ, &hKey);
  720. if (lResult != ERROR_SUCCESS) {
  721. if (lResult != ERROR_FILE_NOT_FOUND) {
  722. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to open reg key with %d."), lResult));
  723. }
  724. xe = lResult;
  725. goto Exit;
  726. }
  727. dwSize = sizeof(DWORD);
  728. lResult = RegQueryValueEx( hKey, TEXT("Status"), NULL,
  729. &dwType, (LPBYTE) &(lpExtStatus->dwStatus),
  730. &dwSize );
  731. if (lResult != ERROR_SUCCESS) {
  732. if (lResult != ERROR_FILE_NOT_FOUND) {
  733. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read status reg value with %d."), lResult));
  734. }
  735. xe = lResult;
  736. goto Exit;
  737. }
  738. dwSize = sizeof(DWORD);
  739. lResult = RegQueryValueEx( hKey, TEXT("RsopStatus"), NULL,
  740. &dwType, (LPBYTE) &(lpExtStatus->dwRsopStatus),
  741. &dwSize );
  742. if (lResult != ERROR_SUCCESS) {
  743. if (lResult != ERROR_FILE_NOT_FOUND) {
  744. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read rsop status reg value with %d."), lResult));
  745. }
  746. // rsop status was not found. treat it as a legacy cse not supporting rsop
  747. lpExtStatus->dwRsopStatus = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
  748. xe = lResult;
  749. }
  750. dwSize = sizeof(DWORD);
  751. lResult = RegQueryValueEx( hKey, TEXT("LastPolicyTime"), NULL,
  752. &dwType, (LPBYTE) &(lpExtStatus->dwTime),
  753. &dwSize );
  754. if (lResult != ERROR_SUCCESS) {
  755. xe = lResult;
  756. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read time reg value with %d."), lResult));
  757. goto Exit;
  758. }
  759. dwSize = sizeof(DWORD);
  760. lResult = RegQueryValueEx( hKey, TEXT("PrevSlowLink"), NULL,
  761. &dwType, (LPBYTE) &(lpExtStatus->dwSlowLink),
  762. &dwSize );
  763. if (lResult != ERROR_SUCCESS) {
  764. xe = lResult;
  765. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read slowlink reg value with %d."), lResult));
  766. goto Exit;
  767. }
  768. dwSize = sizeof(DWORD);
  769. lResult = RegQueryValueEx( hKey, TEXT("PrevRsopLogging"), NULL,
  770. &dwType, (LPBYTE) &(lpExtStatus->dwRsopLogging),
  771. &dwSize );
  772. if (lResult != ERROR_SUCCESS) {
  773. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read rsop logging reg value with %d."), lResult));
  774. //
  775. // This can fail currently (first time or run first time after upgrade) with File not found.
  776. // we will treat it as if logging was not turned on.
  777. }
  778. lpExtStatus->bForceRefresh = FALSE;
  779. dwSize = sizeof(lpExtStatus->bForceRefresh);
  780. lResult = RegQueryValueEx( hKey, TEXT("ForceRefreshFG"), NULL,
  781. &dwType, (LPBYTE) &(lpExtStatus->bForceRefresh),
  782. &dwSize );
  783. if (lResult != ERROR_SUCCESS) {
  784. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Failed to read ForceRefreshFG value with %d."), lResult));
  785. }
  786. DebugMsg((DM_VERBOSE, TEXT("ReadStatus: Read Extension's Previous status successfully.")));
  787. bResult = TRUE;
  788. Exit:
  789. if ( hKey != NULL )
  790. RegCloseKey( hKey );
  791. if ( hKeyExt != NULL )
  792. RegCloseKey( hKeyExt );
  793. lpExtStatus->bStatus = bResult;
  794. }
  795. //*************************************************************
  796. //
  797. // ReadExtStatus()
  798. //
  799. // Purpose: Reads all the extensions status
  800. //
  801. // Parameters: lpGPOInfo - GPOInfo structure
  802. //
  803. // Return: TRUE if successful
  804. // FALSE otherwise
  805. //
  806. //*************************************************************
  807. BOOL ReadExtStatus(LPGPOINFO lpGPOInfo)
  808. {
  809. LPGPEXT lpExt = lpGPOInfo->lpExtensions;
  810. while ( lpExt ) {
  811. BOOL bUsePerUserLocalSetting = lpExt->dwUserLocalSetting && !(lpGPOInfo->dwFlags & GP_MACHINE);
  812. lpExt->lpPrevStatus = (LPGPEXTSTATUS) LocalAlloc(LPTR, sizeof(GPEXTSTATUS));
  813. if (!(lpExt->lpPrevStatus)) {
  814. DebugMsg((DM_WARNING, TEXT("ReadExtStatus: Couldn't allocate memory")));
  815. CEvents ev(TRUE, EVENT_OUT_OF_MEMORY);
  816. ev.AddArgWin32Error(GetLastError()); ev.Report();
  817. return FALSE;
  818. // Things that are already allocated will be freed by the caller
  819. }
  820. DmAssert( !bUsePerUserLocalSetting || lpGPOInfo->lpwszSidUser != 0 );
  821. DebugMsg((DM_VERBOSE, TEXT("ReadExtStatus: Reading Previous Status for extension %s"), lpExt->lpKeyName));
  822. ReadStatus( lpExt->lpKeyName, lpGPOInfo,
  823. bUsePerUserLocalSetting ? lpGPOInfo->lpwszSidUser : NULL,
  824. lpExt->lpPrevStatus );
  825. lpExt = lpExt->pNext;
  826. }
  827. return TRUE;
  828. }
  829. //*************************************************************
  830. //
  831. // HistoryPresent()
  832. //
  833. // Purpose: Checks if the current extension has any cached
  834. // GPOs
  835. //
  836. // Parameters: lpGPOInfo - GPOInfo
  837. // lpExt - Extension
  838. // pbPresent - (out) returns true if history is present
  839. //
  840. //
  841. // Return: TRUE on success
  842. // FALSE otherwise
  843. //
  844. //*************************************************************
  845. BOOL HistoryPresent( LPGPOINFO lpGPOInfo, LPGPEXT lpExt, BOOL *pbPresent )
  846. {
  847. TCHAR szKey[400];
  848. LONG lResult;
  849. HKEY hKey;
  850. HRESULT hr = S_OK;
  851. XLastError xe;
  852. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_HISTORY_KEY, lpExt->lpKeyName );
  853. if ( FAILED(hr) ) {
  854. xe = HRESULT_CODE(hr);
  855. return FALSE;
  856. }
  857. lResult = RegOpenKeyEx ( lpGPOInfo->hKeyRoot,
  858. szKey,
  859. 0, KEY_READ, &hKey);
  860. if (lResult == ERROR_SUCCESS) {
  861. RegCloseKey( hKey );
  862. *pbPresent = TRUE;
  863. return TRUE;
  864. }
  865. //
  866. // Check if history is cached on per user per machine basis
  867. //
  868. BOOL bUsePerUserLocalSetting = lpExt->dwUserLocalSetting && !(lpGPOInfo->dwFlags & GP_MACHINE);
  869. DmAssert( !bUsePerUserLocalSetting || lpGPOInfo->lpwszSidUser != 0 );
  870. if ( bUsePerUserLocalSetting ) {
  871. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_HISTORY_SID_KEY, lpGPOInfo->lpwszSidUser, lpExt->lpKeyName );
  872. if ( FAILED(hr) ) {
  873. xe = HRESULT_CODE(hr);
  874. return FALSE;
  875. }
  876. lResult = RegOpenKeyEx ( HKEY_LOCAL_MACHINE,
  877. szKey,
  878. 0, KEY_READ, &hKey);
  879. if (lResult == ERROR_SUCCESS) {
  880. RegCloseKey( hKey );
  881. *pbPresent = TRUE;
  882. return TRUE;
  883. } else {
  884. *pbPresent = FALSE;
  885. return TRUE;
  886. }
  887. }
  888. *pbPresent = FALSE;
  889. return TRUE;
  890. }
  891. //*************************************************************
  892. //
  893. // MigrateMembershipData()
  894. //
  895. // Purpose: Moves group membership data from old sid to new
  896. // sid.
  897. //
  898. // Parameters: lpwszSidUserNew - New sid
  899. // lpwszSidUserOld - Old sid
  900. //
  901. // Return: TRUE if success
  902. // FALSE otherwise
  903. //
  904. //*************************************************************
  905. BOOL MigrateMembershipData( LPTSTR lpwszSidUserNew, LPTSTR lpwszSidUserOld )
  906. {
  907. DWORD dwCount = 0;
  908. DWORD dwSize, dwType, dwMaxSize, dwDisp;
  909. DWORD i= 0;
  910. LONG lResult;
  911. HKEY hKeyRead = NULL, hKeyWrite = NULL;
  912. BOOL bResult = TRUE;
  913. LPTSTR lpSid = NULL;
  914. TCHAR szKeyRead[250];
  915. TCHAR szKeyWrite[250];
  916. const DWORD dwGrpLength = 30;
  917. TCHAR szGroup[dwGrpLength];
  918. XLastError xe;
  919. HRESULT hr = S_OK;
  920. hr = StringCchPrintf( szKeyRead, ARRAYSIZE(szKeyRead), GP_MEMBERSHIP_KEY, lpwszSidUserOld );
  921. if (FAILED(hr)) {
  922. xe = HRESULT_CODE(hr);
  923. return FALSE;
  924. }
  925. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyRead, 0, KEY_READ, &hKeyRead);
  926. if (lResult != ERROR_SUCCESS)
  927. return TRUE;
  928. hr = StringCchPrintf( szKeyWrite, ARRAYSIZE(szKeyWrite), GP_MEMBERSHIP_KEY, lpwszSidUserNew );
  929. if (FAILED(hr)) {
  930. xe = HRESULT_CODE(hr);
  931. return FALSE;
  932. }
  933. lResult = RegDelnode( HKEY_LOCAL_MACHINE, szKeyWrite );
  934. if (lResult != ERROR_SUCCESS) {
  935. xe = lResult;
  936. DebugMsg((DM_VERBOSE, TEXT("MigrateMembershipData: RegDelnode failed.")));
  937. bResult = FALSE;
  938. goto Exit;
  939. }
  940. lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKeyWrite, 0, NULL,
  941. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyWrite, &dwDisp);
  942. if (lResult != ERROR_SUCCESS) {
  943. xe = lResult;
  944. DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to create key with %d."), lResult));
  945. bResult = FALSE;
  946. goto Exit;
  947. }
  948. dwSize = sizeof(dwCount);
  949. lResult = RegQueryValueEx (hKeyRead, TEXT("Count"), NULL, &dwType,
  950. (LPBYTE) &dwCount, &dwSize);
  951. if ( lResult != ERROR_SUCCESS ) {
  952. xe = lResult;
  953. DebugMsg((DM_VERBOSE, TEXT("MigrateMembershipData: Failed to read membership count")));
  954. goto Exit;
  955. }
  956. lResult = RegQueryInfoKey (hKeyRead, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  957. &dwMaxSize, NULL, NULL);
  958. if (lResult != ERROR_SUCCESS) {
  959. xe = lResult;
  960. DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to query max size with %d."), lResult));
  961. goto Exit;
  962. }
  963. //
  964. // RegQueryInfoKey does not account for trailing 0 in strings
  965. //
  966. dwMaxSize += sizeof( WCHAR );
  967. //
  968. // Allocate buffer based upon the largest value
  969. //
  970. lpSid = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  971. if (!lpSid) {
  972. xe = GetLastError();
  973. DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to allocate memory with %d."), lResult));
  974. bResult = FALSE;
  975. goto Exit;
  976. }
  977. for ( i=0; i<dwCount; i++ ) {
  978. hr = StringCchPrintf( szGroup, dwGrpLength, TEXT("Group%d"), i );
  979. if ( FAILED(hr) ) {
  980. xe = HRESULT_CODE(hr);
  981. bResult = FALSE;
  982. goto Exit;
  983. }
  984. dwSize = dwMaxSize;
  985. lResult = RegQueryValueEx (hKeyRead, szGroup, NULL, &dwType, (LPBYTE) lpSid, &dwSize);
  986. if (lResult != ERROR_SUCCESS) {
  987. xe = lResult;
  988. DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to read value %ws"), szGroup ));
  989. goto Exit;
  990. }
  991. dwSize = (lstrlen(lpSid) + 1) * sizeof(TCHAR);
  992. lResult = RegSetValueEx (hKeyWrite, szGroup, 0, REG_SZ, (LPBYTE) lpSid, dwSize);
  993. if (lResult != ERROR_SUCCESS) {
  994. xe = lResult;
  995. bResult = FALSE;
  996. DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to write value %ws"), szGroup ));
  997. goto Exit;
  998. }
  999. }
  1000. dwSize = sizeof(dwCount);
  1001. lResult = RegSetValueEx (hKeyWrite, TEXT("Count"), 0, REG_DWORD, (LPBYTE) &dwCount, dwSize);
  1002. if (lResult != ERROR_SUCCESS) {
  1003. xe = lResult;
  1004. bResult = FALSE;
  1005. DebugMsg((DM_WARNING, TEXT("MigrateMembershipData: Failed to write count value") ));
  1006. goto Exit;
  1007. }
  1008. Exit:
  1009. if ( lpSid )
  1010. LocalFree( lpSid );
  1011. if ( hKeyRead )
  1012. RegCloseKey (hKeyRead);
  1013. if ( hKeyWrite )
  1014. RegCloseKey (hKeyWrite);
  1015. return bResult;
  1016. }
  1017. //*************************************************************
  1018. //
  1019. // MigrateGPOData()
  1020. //
  1021. // Purpose: Moves cached GPOs from old sid to new
  1022. // sid.
  1023. //
  1024. // Parameters: lpGPOInfo - GPOInfo
  1025. // lpwszSidUserNew - New sid
  1026. // lpwszSidUserOld - Old sid
  1027. //
  1028. // Return: TRUE if success
  1029. // FALSE otherwise
  1030. //
  1031. //*************************************************************
  1032. BOOL MigrateGPOData( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUserNew, LPTSTR lpwszSidUserOld )
  1033. {
  1034. TCHAR szKey[250];
  1035. LONG lResult;
  1036. HKEY hKey = NULL;
  1037. DWORD dwIndex = 0;
  1038. TCHAR szExtension[50];
  1039. DWORD dwSize = 50;
  1040. PGROUP_POLICY_OBJECT pGPOList, lpGPO, lpGPOTemp;
  1041. BOOL bResult;
  1042. XLastError xe;
  1043. HRESULT hr = S_OK;
  1044. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_HISTORY_SID_ROOT_KEY, lpwszSidUserOld );
  1045. if (FAILED(hr)) {
  1046. xe = HRESULT_CODE(hr);
  1047. return FALSE;
  1048. }
  1049. lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
  1050. if ( lResult != ERROR_SUCCESS )
  1051. return TRUE;
  1052. while (RegEnumKeyEx (hKey, dwIndex, szExtension, &dwSize,
  1053. NULL, NULL, NULL, NULL) == ERROR_SUCCESS ) {
  1054. if ( ReadGPOList( szExtension, NULL, HKEY_LOCAL_MACHINE,
  1055. lpwszSidUserOld, FALSE, &pGPOList) ) {
  1056. bResult = SaveGPOList( szExtension, lpGPOInfo, HKEY_LOCAL_MACHINE,
  1057. lpwszSidUserNew, FALSE, pGPOList );
  1058. lpGPO = pGPOList;
  1059. while (lpGPO) {
  1060. lpGPOTemp = lpGPO->pNext;
  1061. LocalFree (lpGPO);
  1062. lpGPO = lpGPOTemp;
  1063. }
  1064. if ( !bResult ) {
  1065. xe = GetLastError();
  1066. DebugMsg((DM_WARNING, TEXT("MigrateGPOData: Failed to save GPO list") ));
  1067. RegCloseKey( hKey );
  1068. return FALSE;
  1069. }
  1070. }
  1071. else {
  1072. CEvents ev(TRUE, EVENT_READ_EXT_FAILED); // Fixing bug 569320
  1073. ev.AddArgWin32Error(GetLastError()); ev.Report();
  1074. }
  1075. dwSize = ARRAYSIZE(szExtension);
  1076. dwIndex++;
  1077. }
  1078. RegCloseKey( hKey );
  1079. return TRUE;
  1080. }
  1081. //*************************************************************
  1082. //
  1083. // MigrateStatusData()
  1084. //
  1085. // Purpose: Moves extension status data from old sid to new
  1086. // sid.
  1087. //
  1088. // Parameters: lpGPOInfo - GPOInfo
  1089. // lpwszSidUserNew - New sid
  1090. // lpwszSidUserOld - Old sid
  1091. //
  1092. // Return: TRUE if success
  1093. // FALSE otherwise
  1094. //
  1095. //*************************************************************
  1096. BOOL MigrateStatusData( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUserNew, LPTSTR lpwszSidUserOld )
  1097. {
  1098. TCHAR szKey[250];
  1099. LONG lResult;
  1100. HKEY hKey = NULL;
  1101. DWORD dwIndex = 0;
  1102. TCHAR szExtension[50];
  1103. DWORD dwSize = 50;
  1104. BOOL bTemp;
  1105. XLastError xe;
  1106. HRESULT hr = S_OK;
  1107. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_EXTENSIONS_SID_ROOT_KEY, lpwszSidUserOld );
  1108. if (FAILED(hr)) {
  1109. xe = HRESULT_CODE(hr);
  1110. return FALSE;
  1111. }
  1112. lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
  1113. if ( lResult != ERROR_SUCCESS )
  1114. return TRUE;
  1115. while (RegEnumKeyEx (hKey, dwIndex, szExtension, &dwSize,
  1116. NULL, NULL, NULL, NULL) == ERROR_SUCCESS ) {
  1117. GPEXTSTATUS gpExtStatus;
  1118. ReadStatus( szExtension, lpGPOInfo, lpwszSidUserOld, &gpExtStatus);
  1119. if (gpExtStatus.bStatus) {
  1120. bTemp = WriteStatus( szExtension, lpGPOInfo, lpwszSidUserNew, &gpExtStatus );
  1121. if ( !bTemp ) {
  1122. xe = GetLastError();
  1123. DebugMsg((DM_WARNING, TEXT("MigrateStatusData: Failed to save status") ));
  1124. RegCloseKey( hKey );
  1125. return FALSE;
  1126. }
  1127. }
  1128. dwSize = ARRAYSIZE(szExtension);
  1129. dwIndex++;
  1130. }
  1131. RegCloseKey( hKey );
  1132. return TRUE;
  1133. }
  1134. //*************************************************************
  1135. //
  1136. // CheckForChangedSid()
  1137. //
  1138. // Purpose: Checks if the user's sid has changed and if so,
  1139. // moves history data from old sid to new sid.
  1140. //
  1141. // Parameters: lpGPOInfo - GPOInfo
  1142. //
  1143. // Return: TRUE if success
  1144. // FALSE otherwise
  1145. //
  1146. //*************************************************************
  1147. BOOL CheckForChangedSid (LPGPOINFO lpGPOInfo, CLocator *locator)
  1148. {
  1149. TCHAR szKey[400];
  1150. LONG lResult;
  1151. HKEY hKey = NULL;
  1152. LPTSTR lpwszSidUserOld = NULL;
  1153. DWORD dwDisp;
  1154. BOOL bCommit = FALSE; // True, if move of history data should be committed
  1155. XLastError xe;
  1156. HRESULT hr = S_OK;
  1157. //
  1158. // initialize it to FALSE at the beginning and if the Sid has
  1159. // changed we will set it to true later on..
  1160. //
  1161. lpGPOInfo->bSidChanged = FALSE;
  1162. if ( lpGPOInfo->dwFlags & GP_MACHINE )
  1163. return TRUE;
  1164. if ( lpGPOInfo->lpwszSidUser == 0 ) {
  1165. lpGPOInfo->lpwszSidUser = GetSidString( lpGPOInfo->hToken );
  1166. if ( lpGPOInfo->lpwszSidUser == 0 ) {
  1167. xe = GetLastError();
  1168. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: GetSidString failed.")));
  1169. CEvents ev(TRUE, EVENT_FAILED_GET_SID); ev.Report();
  1170. return FALSE;
  1171. }
  1172. }
  1173. if (!(lpGPOInfo->dwFlags & GP_APPLY_DS_POLICY))
  1174. return TRUE;
  1175. //
  1176. // Check if the key where history is cached exists
  1177. //
  1178. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_POLICY_SID_KEY, lpGPOInfo->lpwszSidUser );
  1179. if (FAILED(hr)) {
  1180. xe = HRESULT_CODE(hr);
  1181. return FALSE;
  1182. }
  1183. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey);
  1184. if ( lResult == ERROR_SUCCESS ) {
  1185. RegCloseKey( hKey );
  1186. return TRUE;
  1187. }
  1188. if ( lResult != ERROR_FILE_NOT_FOUND ) {
  1189. xe = lResult;
  1190. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: Failed to open registry key with %d."),
  1191. lResult ));
  1192. return FALSE;
  1193. }
  1194. //
  1195. // This is the first time that we are seeing this sid, it can either be a brand new sid or
  1196. // an old sid that has been renamed.
  1197. //
  1198. lpwszSidUserOld = GetOldSidString( lpGPOInfo->hToken, POLICY_GUID_PATH );
  1199. if ( !lpwszSidUserOld )
  1200. {
  1201. //
  1202. // Brand new sid
  1203. //
  1204. if ( !SetOldSidString(lpGPOInfo->hToken, lpGPOInfo->lpwszSidUser, POLICY_GUID_PATH) ) {
  1205. xe = GetLastError();
  1206. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: WriteSidMapping failed.") ));
  1207. CEvents ev(TRUE, EVENT_FAILED_WRITE_SID_MAPPING); ev.Report();
  1208. return FALSE;
  1209. }
  1210. lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, NULL,
  1211. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
  1212. if (lResult != ERROR_SUCCESS) {
  1213. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: RegCreateKey failed.") ));
  1214. return TRUE;
  1215. }
  1216. RegCloseKey( hKey );
  1217. return TRUE;
  1218. }
  1219. else
  1220. {
  1221. DeletePolicyState( lpwszSidUserOld );
  1222. }
  1223. //
  1224. // Need to migrate history data from old sid to new sid
  1225. //
  1226. if ( !MigrateMembershipData( lpGPOInfo->lpwszSidUser, lpwszSidUserOld ) ) {
  1227. xe = GetLastError();
  1228. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: MigrateMembershipData failed.") ));
  1229. CEvents ev(TRUE, EVENT_FAILED_MIGRATION); ev.Report();
  1230. goto Exit;
  1231. }
  1232. if ( !MigrateGPOData( lpGPOInfo, lpGPOInfo->lpwszSidUser, lpwszSidUserOld ) ) {
  1233. xe = GetLastError();
  1234. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: MigrateGPOData failed.") ));
  1235. CEvents ev(TRUE, EVENT_FAILED_MIGRATION); ev.Report();
  1236. goto Exit;
  1237. }
  1238. if ( !MigrateStatusData( lpGPOInfo, lpGPOInfo->lpwszSidUser, lpwszSidUserOld ) ) {
  1239. xe = GetLastError();
  1240. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: MigrateStatusData failed.") ));
  1241. CEvents ev(TRUE, EVENT_FAILED_MIGRATION); ev.Report();
  1242. goto Exit;
  1243. }
  1244. //
  1245. // Migrate Rsop Data, ignore failures
  1246. //
  1247. if (locator->GetWbemLocator()) {
  1248. DWORD dwRSOPNSLength = lstrlen(RSOP_NS_DIAG_USER_FMT) + lstrlen(lpwszSidUserOld) + 10;
  1249. XPtrLF<WCHAR> xszRsopNameSpace = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*
  1250. (dwRSOPNSLength));
  1251. // convert the Sids to WMI Names
  1252. XPtrLF<WCHAR> xszWmiNameOld = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpwszSidUserOld)+1));
  1253. XPtrLF<WCHAR> xszWmiName = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpGPOInfo->lpwszSidUser)+1));
  1254. if ((xszRsopNameSpace) && (xszWmiNameOld) && (xszWmiName)) {
  1255. ConvertSidToWMIName(lpwszSidUserOld, xszWmiNameOld);
  1256. ConvertSidToWMIName(lpGPOInfo->lpwszSidUser, xszWmiName);
  1257. hr = StringCchPrintf(xszRsopNameSpace, dwRSOPNSLength, RSOP_NS_DIAG_USER_FMT, xszWmiNameOld);
  1258. ASSERT(SUCCEEDED(hr));
  1259. CreateAndCopyNameSpace(locator->GetWbemLocator(), xszRsopNameSpace, RSOP_NS_DIAG_USERROOT,
  1260. xszWmiName, NEW_NS_FLAGS_COPY_CLASSES | NEW_NS_FLAGS_COPY_INSTS,
  1261. NULL, NULL);
  1262. } else {
  1263. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: couldn't allocate memory.") ));
  1264. }
  1265. } else {
  1266. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: couldn't get WMI locator.") ));
  1267. }
  1268. bCommit = TRUE;
  1269. Exit:
  1270. if ( bCommit ) {
  1271. if ( !SetOldSidString(lpGPOInfo->hToken, lpGPOInfo->lpwszSidUser, POLICY_GUID_PATH) )
  1272. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: SetOldString failed.") ));
  1273. lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szKey, 0, NULL,
  1274. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
  1275. if (lResult == ERROR_SUCCESS)
  1276. RegCloseKey( hKey );
  1277. else
  1278. DebugMsg((DM_WARNING, TEXT("CheckForChangedSid: RegCreateKey failed.") ));
  1279. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_POLICY_SID_KEY, lpwszSidUserOld );
  1280. ASSERT(SUCCEEDED(hr));
  1281. RegDelnode( HKEY_LOCAL_MACHINE, szKey );
  1282. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_LOGON_SID_KEY, lpwszSidUserOld );
  1283. ASSERT(SUCCEEDED(hr));
  1284. RegDelnode( HKEY_LOCAL_MACHINE, szKey );
  1285. //
  1286. // if we managed to successfully migrate everything
  1287. //
  1288. lpGPOInfo->bSidChanged = TRUE;
  1289. } else {
  1290. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_POLICY_SID_KEY, lpGPOInfo->lpwszSidUser );
  1291. ASSERT(SUCCEEDED(hr));
  1292. RegDelnode( HKEY_LOCAL_MACHINE, szKey );
  1293. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), GP_LOGON_SID_KEY, lpGPOInfo->lpwszSidUser );
  1294. ASSERT(SUCCEEDED(hr));
  1295. RegDelnode( HKEY_LOCAL_MACHINE, szKey );
  1296. }
  1297. if ( lpwszSidUserOld )
  1298. LocalFree( lpwszSidUserOld );
  1299. return bCommit;
  1300. }
  1301. //*************************************************************
  1302. //
  1303. // ReadGPExtensions()
  1304. //
  1305. // Purpose: Reads the group policy extenions from registry.
  1306. // The actual loading of extension is deferred.
  1307. //
  1308. // Parameters: lpGPOInfo - GP Information
  1309. //
  1310. // Return: TRUE if successful
  1311. // FALSE if an error occurs
  1312. //
  1313. //*************************************************************
  1314. BOOL ReadGPExtensions (LPGPOINFO lpGPOInfo)
  1315. {
  1316. TCHAR szSubKey[MAX_PATH];
  1317. DWORD dwType;
  1318. HKEY hKey, hKeyOverride;
  1319. DWORD dwIndex = 0;
  1320. DWORD dwSize = 50;
  1321. TCHAR szDisplayName[50];
  1322. TCHAR szKeyName[50];
  1323. TCHAR szDllName[MAX_PATH+1];
  1324. TCHAR szExpDllName[MAX_PATH+1];
  1325. CHAR szFunctionName[100];
  1326. CHAR szRsopFunctionName[100];
  1327. HKEY hKeyExt;
  1328. HINSTANCE hInstDLL;
  1329. LPGPEXT lpExt, lpTemp;
  1330. HRESULT hr = S_OK;
  1331. XLastError xe;
  1332. //
  1333. // Check if any extensions are registered
  1334. //
  1335. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  1336. GP_EXTENSIONS,
  1337. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  1338. //
  1339. // Enumerate the keys (each extension has its own key)
  1340. //
  1341. while (RegEnumKeyEx (hKey, dwIndex, szKeyName, &dwSize,
  1342. NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
  1343. //
  1344. // Open the extension's key.
  1345. //
  1346. if (RegOpenKeyEx (hKey, szKeyName,
  1347. 0, KEY_READ, &hKeyExt) == ERROR_SUCCESS) {
  1348. if ( ValidateGuid( szKeyName ) ) {
  1349. if ( lstrcmpi(szKeyName, c_szRegistryExtName) != 0 ) {
  1350. //
  1351. // Every extension, other than RegistryExtension is required to have a value called
  1352. // DllName. This value can be REG_SZ or REG_EXPAND_SZ type.
  1353. //
  1354. dwSize = sizeof(szDllName);
  1355. if (RegQueryValueEx (hKeyExt, TEXT("DllName"), NULL,
  1356. &dwType, (LPBYTE) szDllName,
  1357. &dwSize) == ERROR_SUCCESS) {
  1358. BOOL bFuncFound = FALSE;
  1359. BOOL bNewInterface = FALSE;
  1360. DWORD dwNoMachPolicy = FALSE;
  1361. DWORD dwNoUserPolicy = FALSE;
  1362. DWORD dwNoSlowLink = FALSE;
  1363. DWORD dwNoBackgroundPolicy = FALSE;
  1364. DWORD dwNoGPOChanges = FALSE;
  1365. DWORD dwUserLocalSetting = FALSE;
  1366. DWORD dwRequireRegistry = FALSE;
  1367. DWORD dwEnableAsynch = FALSE;
  1368. DWORD dwMaxChangesInterval = 0;
  1369. DWORD dwLinkTransition = FALSE;
  1370. WCHAR szEventLogSources[MAX_PATH+1];
  1371. DWORD dwSizeEventLogSources = MAX_PATH+1;
  1372. DWORD cchDllName = 0;
  1373. cchDllName = ExpandEnvironmentStrings (szDllName, szExpDllName, MAX_PATH);
  1374. //
  1375. // Read new interface name, if failed read old interface name
  1376. //
  1377. dwSize = sizeof(szFunctionName);
  1378. if ( cchDllName > 0 )
  1379. {
  1380. if ( RegQueryValueExA (hKeyExt, "ProcessGroupPolicyEx", NULL,
  1381. &dwType, (LPBYTE) szFunctionName,
  1382. &dwSize) == ERROR_SUCCESS ) {
  1383. bFuncFound = TRUE;
  1384. bNewInterface = TRUE;
  1385. } else if ( RegQueryValueExA (hKeyExt, "ProcessGroupPolicy", NULL,
  1386. &dwType, (LPBYTE) szFunctionName,
  1387. &dwSize) == ERROR_SUCCESS ) {
  1388. bFuncFound = TRUE;
  1389. }
  1390. }
  1391. if ( bFuncFound) {
  1392. //
  1393. // Read preferences
  1394. //
  1395. dwSize = sizeof(szDisplayName);
  1396. if (RegQueryValueEx (hKeyExt, NULL, NULL,
  1397. &dwType, (LPBYTE) szDisplayName,
  1398. &dwSize) != ERROR_SUCCESS) {
  1399. lstrcpyn (szDisplayName, szKeyName, ARRAYSIZE(szDisplayName));
  1400. }
  1401. dwSize = sizeof(szRsopFunctionName);
  1402. if (RegQueryValueExA (hKeyExt, "GenerateGroupPolicy", NULL,
  1403. &dwType, (LPBYTE) szRsopFunctionName,
  1404. &dwSize) != ERROR_SUCCESS) {
  1405. szRsopFunctionName[0] = 0;
  1406. DebugMsg((DM_VERBOSE, TEXT("ReadGPExtensions: Rsop entry point not found for %s."),
  1407. szExpDllName));
  1408. }
  1409. dwSize = sizeof(DWORD);
  1410. RegQueryValueEx( hKeyExt, TEXT("NoMachinePolicy"), NULL,
  1411. &dwType, (LPBYTE) &dwNoMachPolicy,
  1412. &dwSize );
  1413. dwSize = sizeof(DWORD);
  1414. RegQueryValueEx( hKeyExt, TEXT("NoUserPolicy"), NULL,
  1415. &dwType, (LPBYTE) &dwNoUserPolicy,
  1416. &dwSize );
  1417. dwSize = sizeof(DWORD);
  1418. RegQueryValueEx( hKeyExt, TEXT("NoSlowLink"), NULL,
  1419. &dwType, (LPBYTE) &dwNoSlowLink,
  1420. &dwSize );
  1421. dwSize = sizeof(DWORD);
  1422. RegQueryValueEx( hKeyExt, TEXT("NoGPOListChanges"), NULL,
  1423. &dwType, (LPBYTE) &dwNoGPOChanges,
  1424. &dwSize );
  1425. dwSize = sizeof(DWORD);
  1426. RegQueryValueEx( hKeyExt, TEXT("NoBackgroundPolicy"), NULL,
  1427. &dwType, (LPBYTE) &dwNoBackgroundPolicy,
  1428. &dwSize );
  1429. dwSize = sizeof(DWORD);
  1430. RegQueryValueEx( hKeyExt, TEXT("PerUserLocalSettings"), NULL,
  1431. &dwType, (LPBYTE) &dwUserLocalSetting,
  1432. &dwSize );
  1433. dwSize = sizeof(DWORD);
  1434. RegQueryValueEx( hKeyExt, TEXT("RequiresSuccessfulRegistry"), NULL,
  1435. &dwType, (LPBYTE) &dwRequireRegistry,
  1436. &dwSize );
  1437. dwSize = sizeof(DWORD);
  1438. RegQueryValueEx( hKeyExt, TEXT("EnableAsynchronousProcessing"), NULL,
  1439. &dwType, (LPBYTE) &dwEnableAsynch,
  1440. &dwSize );
  1441. dwSize = sizeof(DWORD);
  1442. RegQueryValueEx( hKeyExt, TEXT("MaxNoGPOListChangesInterval"), NULL,
  1443. &dwType, (LPBYTE) &dwMaxChangesInterval,
  1444. &dwSize );
  1445. dwSize = sizeof(DWORD);
  1446. RegQueryValueEx( hKeyExt, TEXT("NotifyLinkTransition"), NULL,
  1447. &dwType, (LPBYTE) &dwLinkTransition,
  1448. &dwSize );
  1449. dwSize = sizeof(DWORD);
  1450. if (RegQueryValueEx( hKeyExt, TEXT("EventSources"), 0,
  1451. &dwType, (LPBYTE) &(szEventLogSources[0]),
  1452. &dwSizeEventLogSources ) != ERROR_SUCCESS) {
  1453. dwSizeEventLogSources = 0;
  1454. szEventLogSources[0] = TEXT('\0');
  1455. }
  1456. //
  1457. // Read override policy values, if any
  1458. //
  1459. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), GP_EXTENSIONS_POLICIES, szKeyName );
  1460. ASSERT(SUCCEEDED(hr));
  1461. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  1462. szSubKey,
  1463. 0, KEY_READ, &hKeyOverride ) == ERROR_SUCCESS) {
  1464. dwSize = sizeof(DWORD);
  1465. RegQueryValueEx( hKeyOverride, TEXT("NoSlowLink"), NULL,
  1466. &dwType, (LPBYTE) &dwNoSlowLink,
  1467. &dwSize );
  1468. dwSize = sizeof(DWORD);
  1469. RegQueryValueEx( hKeyOverride, TEXT("NoGPOListChanges"), NULL,
  1470. &dwType, (LPBYTE) &dwNoGPOChanges,
  1471. &dwSize );
  1472. dwSize = sizeof(DWORD);
  1473. RegQueryValueEx( hKeyOverride, TEXT("NoBackgroundPolicy"), NULL,
  1474. &dwType, (LPBYTE) &dwNoBackgroundPolicy,
  1475. &dwSize );
  1476. RegCloseKey( hKeyOverride );
  1477. }
  1478. }
  1479. if ( bFuncFound ) {
  1480. DWORD dwExtSize = sizeof(GPEXT)
  1481. + ((lstrlen(szDisplayName) + 1) * sizeof(TCHAR))
  1482. + ((lstrlen(szKeyName) + 1) * sizeof(TCHAR))
  1483. + ((lstrlen(szExpDllName) + 1) * sizeof(TCHAR))
  1484. + lstrlenA(szFunctionName) + 1
  1485. + lstrlenA(szRsopFunctionName) + 1;
  1486. lpExt = (LPGPEXT) LocalAlloc (LPTR, dwExtSize);
  1487. if (lpExt) {
  1488. //
  1489. // Set up all fields
  1490. //
  1491. lpExt->lpDisplayName = (LPTSTR)((LPBYTE)lpExt + sizeof(GPEXT));
  1492. hr = StringCchCopy( lpExt->lpDisplayName, lstrlen(szDisplayName) + 1, szDisplayName );
  1493. ASSERT(SUCCEEDED(hr));
  1494. lpExt->lpKeyName = lpExt->lpDisplayName + lstrlen(lpExt->lpDisplayName) + 1;
  1495. hr = StringCchCopy( lpExt->lpKeyName, lstrlen(szKeyName) + 1, szKeyName );
  1496. ASSERT(SUCCEEDED(hr));
  1497. StringToGuid( szKeyName, &lpExt->guid );
  1498. lpExt->lpDllName = lpExt->lpKeyName + lstrlen(lpExt->lpKeyName) + 1;
  1499. hr = StringCchCopy (lpExt->lpDllName, lstrlen(szExpDllName) + 1, szExpDllName);
  1500. ASSERT(SUCCEEDED(hr));
  1501. lpExt->lpFunctionName = (LPSTR)( (LPBYTE)lpExt->lpDllName + (lstrlen(lpExt->lpDllName) + 1) * sizeof(TCHAR) );
  1502. hr = StringCchCopyA( lpExt->lpFunctionName, lstrlenA(szFunctionName) + 1, szFunctionName );
  1503. ASSERT(SUCCEEDED(hr));
  1504. if ( szRsopFunctionName[0] == 0 ) {
  1505. lpExt->lpRsopFunctionName = 0;
  1506. } else {
  1507. lpExt->lpRsopFunctionName = (LPSTR)( (LPBYTE)lpExt->lpDllName + (lstrlen(lpExt->lpDllName) + 1) * sizeof(TCHAR)
  1508. + lstrlenA(szFunctionName) + 1);
  1509. hr = StringCchCopyA( lpExt->lpRsopFunctionName, lstrlenA(szRsopFunctionName) + 1, szRsopFunctionName );
  1510. ASSERT(SUCCEEDED(hr));
  1511. }
  1512. lpExt->hInstance = NULL;
  1513. lpExt->pEntryPoint = NULL;
  1514. lpExt->pEntryPointEx = NULL;
  1515. lpExt->bNewInterface = bNewInterface;
  1516. lpExt->dwNoMachPolicy = dwNoMachPolicy;
  1517. lpExt->dwNoUserPolicy = dwNoUserPolicy;
  1518. lpExt->dwNoSlowLink = dwNoSlowLink;
  1519. lpExt->dwNoBackgroundPolicy = dwNoBackgroundPolicy;
  1520. lpExt->dwNoGPOChanges = dwNoGPOChanges;
  1521. lpExt->dwUserLocalSetting = dwUserLocalSetting;
  1522. lpExt->dwRequireRegistry = dwRequireRegistry;
  1523. lpExt->dwEnableAsynch = dwEnableAsynch;
  1524. lpExt->dwMaxChangesInterval = dwMaxChangesInterval;
  1525. lpExt->dwLinkTransition = dwLinkTransition;
  1526. if ( dwSizeEventLogSources )
  1527. {
  1528. lpExt->szEventLogSources = (LPTSTR) LocalAlloc( LPTR, dwSizeEventLogSources+ sizeof(TCHAR) );
  1529. if ( lpExt->szEventLogSources )
  1530. {
  1531. memcpy( lpExt->szEventLogSources, szEventLogSources, dwSizeEventLogSources );
  1532. }
  1533. }
  1534. lpExt->bRegistryExt = FALSE;
  1535. lpExt->bSkipped = FALSE;
  1536. lpExt->pNext = NULL;
  1537. //
  1538. // Append to end of extension list
  1539. //
  1540. if (lpGPOInfo->lpExtensions) {
  1541. lpTemp = lpGPOInfo->lpExtensions;
  1542. while (TRUE) {
  1543. if (lpTemp->pNext) {
  1544. lpTemp = lpTemp->pNext;
  1545. } else {
  1546. break;
  1547. }
  1548. }
  1549. lpTemp->pNext = lpExt;
  1550. } else {
  1551. lpGPOInfo->lpExtensions = lpExt;
  1552. }
  1553. } else { // if lpExt
  1554. DebugMsg((DM_WARNING, TEXT("ReadGPExtensions: Failed to allocate memory with %d"),
  1555. GetLastError()));
  1556. }
  1557. } else { // if bFuncFound
  1558. DebugMsg((DM_WARNING, TEXT("ReadGPExtensions: Failed to query for the function name.")));
  1559. CEvents ev(TRUE, EVENT_EXT_MISSING_FUNC);
  1560. ev.AddArg(szExpDllName); ev.Report();
  1561. }
  1562. } else { // if RegQueryValueEx DllName
  1563. DebugMsg((DM_WARNING, TEXT("ReadGPExtensions: Failed to query DllName value.")));
  1564. CEvents ev(TRUE, EVENT_EXT_MISSING_DLLNAME);
  1565. ev.AddArg(szKeyName); ev.Report();
  1566. }
  1567. } // if lstrcmpi(szKeyName, c_szRegistryExtName)
  1568. } // if validateguid
  1569. RegCloseKey (hKeyExt);
  1570. } // if RegOpenKey hKeyExt
  1571. dwSize = ARRAYSIZE(szKeyName);
  1572. dwIndex++;
  1573. } // while RegEnumKeyEx
  1574. RegCloseKey (hKey);
  1575. } // if RegOpenKey gpext
  1576. //
  1577. // Add the registry psuedo extension at the beginning
  1578. //
  1579. DWORD dwExtSize = 0;
  1580. if ( LoadString (g_hDllInstance, IDS_REGISTRYNAME, szDisplayName, ARRAYSIZE(szDisplayName)) ) {
  1581. dwExtSize = sizeof(GPEXT)
  1582. + ((lstrlen(szDisplayName) + 1) * sizeof(TCHAR))
  1583. + ((lstrlen(c_szRegistryExtName) + 1) * sizeof(TCHAR)) ;
  1584. lpExt = (LPGPEXT) LocalAlloc (LPTR, dwExtSize);
  1585. } else {
  1586. lpExt = 0;
  1587. }
  1588. if (lpExt) {
  1589. DWORD dwNoSlowLink = FALSE;
  1590. DWORD dwNoGPOChanges = TRUE;
  1591. DWORD dwNoBackgroundPolicy = FALSE;
  1592. lpExt->lpDisplayName = (LPTSTR)((LPBYTE)lpExt + sizeof(GPEXT));
  1593. hr = StringCchCopy( lpExt->lpDisplayName, lstrlen(szDisplayName) + 1, szDisplayName );
  1594. ASSERT(SUCCEEDED(hr));
  1595. lpExt->lpKeyName = lpExt->lpDisplayName + lstrlen(lpExt->lpDisplayName) + 1;
  1596. hr = StringCchCopy( lpExt->lpKeyName, lstrlen(c_szRegistryExtName) + 1, c_szRegistryExtName );
  1597. ASSERT(SUCCEEDED(hr));
  1598. StringToGuid( lpExt->lpKeyName, &lpExt->guid );
  1599. lpExt->lpDllName = L"userenv.dll";
  1600. lpExt->lpFunctionName = NULL;
  1601. lpExt->hInstance = NULL;
  1602. lpExt->pEntryPoint = NULL;
  1603. //
  1604. // Read override policy values, if any
  1605. //
  1606. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), GP_EXTENSIONS_POLICIES, lpExt->lpKeyName );
  1607. if (FAILED(hr)) {
  1608. LocalFree(lpExt);
  1609. xe = HRESULT_CODE(hr);
  1610. return FALSE;
  1611. }
  1612. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  1613. szSubKey,
  1614. 0, KEY_READ, &hKeyOverride ) == ERROR_SUCCESS) {
  1615. dwSize = sizeof( dwNoGPOChanges );
  1616. RegQueryValueEx( hKeyOverride, TEXT("NoGPOListChanges"), NULL,
  1617. &dwType, (LPBYTE) &dwNoGPOChanges,
  1618. &dwSize );
  1619. dwSize = sizeof( dwNoBackgroundPolicy );
  1620. RegQueryValueEx( hKeyOverride, TEXT("NoBackgroundPolicy"), NULL,
  1621. &dwType, (LPBYTE) &dwNoBackgroundPolicy,
  1622. &dwSize );
  1623. RegCloseKey( hKeyOverride );
  1624. }
  1625. lpExt->dwNoMachPolicy = FALSE;
  1626. lpExt->dwNoUserPolicy = FALSE;
  1627. lpExt->dwNoSlowLink = dwNoSlowLink;
  1628. lpExt->dwNoBackgroundPolicy = dwNoBackgroundPolicy;
  1629. lpExt->dwNoGPOChanges = dwNoGPOChanges;
  1630. lpExt->dwUserLocalSetting = FALSE;
  1631. lpExt->dwRequireRegistry = FALSE;
  1632. lpExt->dwEnableAsynch = FALSE;
  1633. lpExt->dwLinkTransition = FALSE;
  1634. lpExt->bRegistryExt = TRUE;
  1635. lpExt->bSkipped = FALSE;
  1636. lpExt->bNewInterface = TRUE;
  1637. lpExt->pNext = lpGPOInfo->lpExtensions;
  1638. lpGPOInfo->lpExtensions = lpExt;
  1639. } else {
  1640. DebugMsg((DM_WARNING, TEXT("ReadGPExtensions: Failed to allocate memory with %d"),
  1641. GetLastError()));
  1642. return FALSE;
  1643. }
  1644. return TRUE;
  1645. }
  1646. //*************************************************************
  1647. //
  1648. // ReadMembershipList()
  1649. //
  1650. // Purpose: Reads cached memberhip list and checks if the
  1651. // security groups has changed.
  1652. //
  1653. // Parameters: lpGPOInfo - LPGPOINFO struct
  1654. // lpwszSidUser - Sid of user, if non-null then it means
  1655. // per user local setting
  1656. // pGroups - List of token groups
  1657. //
  1658. // Return: TRUE if changed
  1659. // FALSE otherwise
  1660. //
  1661. //*************************************************************
  1662. BOOL ReadMembershipList( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, PTOKEN_GROUPS pGroupsCur )
  1663. {
  1664. DWORD i= 0;
  1665. LONG lResult;
  1666. TCHAR szGroup[30];
  1667. TCHAR szKey[250];
  1668. HKEY hKey = NULL;
  1669. BOOL bDiff = TRUE;
  1670. DWORD dwCountOld = 0;
  1671. DWORD dwSize, dwType, dwMaxSize;
  1672. LPTSTR lpSid = NULL;
  1673. HRESULT hr = S_OK;
  1674. DWORD dwCountCur = 0;
  1675. XLastError xe;
  1676. //
  1677. // Get current count of groups ignoring groups that have
  1678. // the SE_GROUP_LOGON_ID attribute set as this sid will be different
  1679. // for each logon session.
  1680. //
  1681. for ( i=0; i < pGroupsCur->GroupCount; i++) {
  1682. if ( (SE_GROUP_LOGON_ID & pGroupsCur->Groups[i].Attributes) == 0 )
  1683. dwCountCur++;
  1684. }
  1685. //
  1686. // Read from cached group membership list
  1687. //
  1688. if ( lpwszSidUser == 0 )
  1689. hr = StringCchCopy( szKey, ARRAYSIZE(szKey), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\GroupMembership") );
  1690. else
  1691. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\%ws\\GroupMembership"),
  1692. lpwszSidUser );
  1693. if (FAILED(hr)) {
  1694. xe = HRESULT_CODE(hr);
  1695. goto Exit;
  1696. }
  1697. lResult = RegOpenKeyEx ( lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
  1698. szKey,
  1699. 0, KEY_READ, &hKey);
  1700. if (lResult != ERROR_SUCCESS)
  1701. return TRUE;
  1702. dwSize = sizeof(dwCountOld);
  1703. lResult = RegQueryValueEx (hKey, TEXT("Count"), NULL, &dwType,
  1704. (LPBYTE) &dwCountOld, &dwSize);
  1705. if ( lResult != ERROR_SUCCESS ) {
  1706. DebugMsg((DM_VERBOSE, TEXT("ReadMembershipList: Failed to read old group count") ));
  1707. goto Exit;
  1708. }
  1709. //
  1710. // Now compare the old and new number of security groups
  1711. //
  1712. if ( dwCountOld != dwCountCur ) {
  1713. DebugMsg((DM_VERBOSE, TEXT("ReadMembershipList: Old count %d is different from current count %d"),
  1714. dwCountOld, dwCountCur ));
  1715. goto Exit;
  1716. }
  1717. //
  1718. // Total group count is the same, now check that each individual group is the same.
  1719. // First read the size of the largest value in this key.
  1720. //
  1721. lResult = RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  1722. &dwMaxSize, NULL, NULL);
  1723. if (lResult != ERROR_SUCCESS) {
  1724. DebugMsg((DM_WARNING, TEXT("ReadMembershipList: Failed to query max size with %d."), lResult));
  1725. goto Exit;
  1726. }
  1727. //
  1728. // RegQueryInfoKey does not account for trailing 0 in strings
  1729. //
  1730. dwMaxSize += sizeof( WCHAR );
  1731. //
  1732. // Allocate buffer based upon the largest value
  1733. //
  1734. lpSid = (LPTSTR) LocalAlloc (LPTR, dwMaxSize);
  1735. if (!lpSid) {
  1736. DebugMsg((DM_WARNING, TEXT("ReadMembershipList: Failed to allocate memory with %d."), lResult));
  1737. goto Exit;
  1738. }
  1739. for ( i=0; i<dwCountOld; i++ ) {
  1740. hr = StringCchPrintf( szGroup, ARRAYSIZE(szGroup), TEXT("Group%d"), i );
  1741. if (FAILED(hr)) {
  1742. xe = HRESULT_CODE(hr);
  1743. goto Exit;
  1744. }
  1745. dwSize = dwMaxSize;
  1746. lResult = RegQueryValueEx (hKey, szGroup, NULL, &dwType,
  1747. (LPBYTE) lpSid, &dwSize);
  1748. if (lResult != ERROR_SUCCESS) {
  1749. DebugMsg((DM_WARNING, TEXT("ReadMembershipList: Failed to read value %ws"), szGroup ));
  1750. goto Exit;
  1751. }
  1752. if ( !GroupInList( lpSid, pGroupsCur ) ) {
  1753. DebugMsg((DM_WARNING, TEXT("ReadMembershipList: Group %ws not in current list of token groups"), lpSid ));
  1754. goto Exit;
  1755. }
  1756. }
  1757. bDiff = FALSE;
  1758. Exit:
  1759. if ( lpSid )
  1760. LocalFree( lpSid );
  1761. if ( hKey )
  1762. RegCloseKey (hKey);
  1763. return bDiff;
  1764. }
  1765. //*************************************************************
  1766. //
  1767. // SavesMembershipList()
  1768. //
  1769. // Purpose: Caches memberhip list
  1770. //
  1771. // Parameters: lpGPOInfo - LPGPOINFO struct
  1772. // lpwszSidUser - Sid of user, if non-null then it means
  1773. // per user local setting
  1774. // pGroups - List of token groups to cache
  1775. //
  1776. // Notes: The count is saved last because it serves
  1777. // as a commit point for the entire save operation.
  1778. //
  1779. //*************************************************************
  1780. void SaveMembershipList( LPGPOINFO lpGPOInfo, LPTSTR lpwszSidUser, PTOKEN_GROUPS pGroups )
  1781. {
  1782. TCHAR szKey[250];
  1783. TCHAR szGroup[30];
  1784. DWORD i;
  1785. LONG lResult;
  1786. DWORD dwCount = 0, dwSize, dwDisp;
  1787. NTSTATUS ntStatus;
  1788. UNICODE_STRING unicodeStr;
  1789. HKEY hKey = NULL;
  1790. HRESULT hr = S_OK;
  1791. XLastError xe;
  1792. //
  1793. // Start with clean key
  1794. //
  1795. if ( lpwszSidUser == 0 )
  1796. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\GroupMembership") );
  1797. else
  1798. hr = StringCchPrintf( szKey, ARRAYSIZE(szKey), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\%ws\\GroupMembership"),
  1799. lpwszSidUser );
  1800. if (FAILED(hr)) {
  1801. xe = HRESULT_CODE(hr);
  1802. return;
  1803. }
  1804. if (RegDelnode ( lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot, szKey) != ERROR_SUCCESS) {
  1805. DebugMsg((DM_VERBOSE, TEXT("SaveMembershipList: RegDelnode failed.")));
  1806. return;
  1807. }
  1808. lResult = RegCreateKeyEx ( lpwszSidUser ? HKEY_LOCAL_MACHINE : lpGPOInfo->hKeyRoot,
  1809. szKey, 0, NULL,
  1810. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp);
  1811. if (lResult != ERROR_SUCCESS) {
  1812. DebugMsg((DM_WARNING, TEXT("SaveMemberList: Failed to create key with %d."), lResult));
  1813. goto Exit;
  1814. }
  1815. for ( i=0; i < pGroups->GroupCount; i++) {
  1816. if (SE_GROUP_LOGON_ID & pGroups->Groups[i].Attributes )
  1817. continue;
  1818. dwCount++;
  1819. //
  1820. // Convert user SID to a string.
  1821. //
  1822. ntStatus = RtlConvertSidToUnicodeString( &unicodeStr,
  1823. pGroups->Groups[i].Sid,
  1824. (BOOLEAN)TRUE ); // Allocate
  1825. if ( !NT_SUCCESS(ntStatus) ) {
  1826. DebugMsg((DM_WARNING, TEXT("SaveMembershipList: RtlConvertSidToUnicodeString failed, status = 0x%x"),
  1827. ntStatus));
  1828. goto Exit;
  1829. }
  1830. hr = StringCchPrintf( szGroup, ARRAYSIZE(szGroup), TEXT("Group%d"), dwCount-1 );
  1831. ASSERT(SUCCEEDED(hr));
  1832. dwSize = (lstrlen (unicodeStr.Buffer) + 1) * sizeof(TCHAR);
  1833. lResult = RegSetValueEx (hKey, szGroup, 0, REG_SZ,
  1834. (LPBYTE) unicodeStr.Buffer, dwSize);
  1835. RtlFreeUnicodeString( &unicodeStr );
  1836. if (lResult != ERROR_SUCCESS) {
  1837. DebugMsg((DM_WARNING, TEXT("SaveMemberList: Failed to set value %ws with %d."),
  1838. szGroup, lResult));
  1839. goto Exit;
  1840. }
  1841. } // for
  1842. //
  1843. // Commit by writing count
  1844. //
  1845. dwSize = sizeof(dwCount);
  1846. lResult = RegSetValueEx (hKey, TEXT("Count"), 0, REG_DWORD,
  1847. (LPBYTE) &dwCount, dwSize);
  1848. Exit:
  1849. if (hKey)
  1850. RegCloseKey (hKey);
  1851. }
  1852. //*************************************************************
  1853. //
  1854. // ExtensionHasPerUserLocalSetting()
  1855. //
  1856. // Purpose: Checks registry if extension has per user local setting
  1857. //
  1858. // Parameters: pwszExtension - Extension guid
  1859. // hKeyRoot - Registry root
  1860. //
  1861. // Returns: True if extension has per user local setting
  1862. // False otherwise
  1863. //
  1864. //*************************************************************
  1865. BOOL ExtensionHasPerUserLocalSetting( LPTSTR pszExtension, HKEY hKeyRoot )
  1866. {
  1867. TCHAR szKey[200];
  1868. DWORD dwType, dwSetting = 0, dwSize = sizeof(DWORD);
  1869. LONG lResult;
  1870. HKEY hKey;
  1871. HRESULT hr = S_OK;
  1872. hr = StringCchPrintf ( szKey, ARRAYSIZE(szKey), GP_EXTENSIONS_KEY, pszExtension );
  1873. ASSERT(SUCCEEDED(hr));
  1874. lResult = RegOpenKeyEx ( hKeyRoot, szKey, 0, KEY_READ, &hKey);
  1875. if ( lResult != ERROR_SUCCESS )
  1876. return FALSE;
  1877. lResult = RegQueryValueEx( hKey, TEXT("PerUserLocalSettings"), NULL,
  1878. &dwType, (LPBYTE) &dwSetting,
  1879. &dwSize );
  1880. RegCloseKey( hKey );
  1881. if (lResult == ERROR_SUCCESS)
  1882. return dwSetting;
  1883. else
  1884. return FALSE;
  1885. }
  1886. //*************************************************************
  1887. //
  1888. // GetAppliedGPOList()
  1889. //
  1890. // Purpose: Queries for the list of applied Group Policy
  1891. // Objects for the specified user or machine
  1892. // and specified client side extension.
  1893. //
  1894. // Parameters: dwFlags - User or machine policy, if it is GPO_LIST_FLAG_MACHINE
  1895. // then machine policy
  1896. // pMachineName - Name of remote computer in the form \\computername. If null
  1897. // then local computer is used.
  1898. // pSidUser - Security id of user (relevant for user policy). If pMachineName is
  1899. // null and pSidUser is null then it means current logged on user.
  1900. // If pMachine is null and pSidUser is non-null then it means user
  1901. // represented by pSidUser on local machine. If pMachineName is non-null
  1902. // then and if dwFlags specifies user policy, then pSidUser must be
  1903. // non-null.
  1904. // pGuid - Guid of the specified extension
  1905. // ppGPOList - Address of a pointer which receives the link list of GPOs
  1906. //
  1907. // Returns: Win32 error code
  1908. //
  1909. //*************************************************************
  1910. DWORD GetAppliedGPOList( DWORD dwFlags,
  1911. LPCTSTR pMachineName,
  1912. PSID pSidUser,
  1913. GUID *pGuidExtension,
  1914. PGROUP_POLICY_OBJECT *ppGPOList)
  1915. {
  1916. DWORD dwRet = E_FAIL;
  1917. TCHAR szExtension[64];
  1918. BOOL bOk;
  1919. BOOL bMachine = dwFlags & GPO_LIST_FLAG_MACHINE;
  1920. NTSTATUS ntStatus;
  1921. UNICODE_STRING unicodeStr;
  1922. *ppGPOList = 0;
  1923. if ( pGuidExtension == 0 )
  1924. return ERROR_INVALID_PARAMETER;
  1925. GuidToString( pGuidExtension, szExtension );
  1926. DebugMsg((DM_VERBOSE, TEXT("GetAppliedGPOList: Entering. Extension = %s"),
  1927. szExtension));
  1928. if ( pMachineName == NULL ) {
  1929. //
  1930. // Local case
  1931. //
  1932. if ( bMachine ) {
  1933. bOk = ReadGPOList( szExtension,
  1934. HKEY_LOCAL_MACHINE,
  1935. HKEY_LOCAL_MACHINE,
  1936. 0,
  1937. FALSE, ppGPOList );
  1938. return bOk ? ERROR_SUCCESS : E_FAIL;
  1939. } else {
  1940. BOOL bUsePerUserLocalSetting = ExtensionHasPerUserLocalSetting( szExtension, HKEY_LOCAL_MACHINE );
  1941. LPTSTR lpwszSidUser = NULL;
  1942. if ( pSidUser == NULL ) {
  1943. //
  1944. // Current logged on user
  1945. //
  1946. if ( bUsePerUserLocalSetting ) {
  1947. HANDLE hToken = NULL;
  1948. if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken)) {
  1949. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
  1950. DebugMsg((DM_WARNING, TEXT("GetAppliedGPOList: Failed to get user token with %d"),
  1951. GetLastError()));
  1952. return GetLastError();
  1953. }
  1954. }
  1955. lpwszSidUser = GetSidString( hToken );
  1956. CloseHandle( hToken );
  1957. if ( lpwszSidUser == NULL ) {
  1958. DebugMsg((DM_WARNING, TEXT("GetAppliedGPOList: GetSidString failed.")));
  1959. return E_FAIL;
  1960. }
  1961. }
  1962. bOk = ReadGPOList( szExtension,
  1963. HKEY_CURRENT_USER,
  1964. HKEY_LOCAL_MACHINE,
  1965. lpwszSidUser,
  1966. FALSE, ppGPOList );
  1967. if ( lpwszSidUser )
  1968. DeleteSidString( lpwszSidUser );
  1969. return bOk ? ERROR_SUCCESS : E_FAIL;
  1970. } else {
  1971. //
  1972. // User represented by pSidUser
  1973. //
  1974. HKEY hSubKey;
  1975. ntStatus = RtlConvertSidToUnicodeString( &unicodeStr,
  1976. pSidUser,
  1977. (BOOLEAN)TRUE ); // Allocate
  1978. if ( !NT_SUCCESS(ntStatus) )
  1979. return E_FAIL;
  1980. dwRet = RegOpenKeyEx ( HKEY_USERS, unicodeStr.Buffer, 0, KEY_READ, &hSubKey);
  1981. if (dwRet != ERROR_SUCCESS) {
  1982. RtlFreeUnicodeString(&unicodeStr);
  1983. if (dwRet == ERROR_FILE_NOT_FOUND)
  1984. return ERROR_SUCCESS;
  1985. else
  1986. return dwRet;
  1987. }
  1988. bOk = ReadGPOList( szExtension,
  1989. hSubKey,
  1990. HKEY_LOCAL_MACHINE,
  1991. bUsePerUserLocalSetting ? unicodeStr.Buffer : NULL,
  1992. FALSE, ppGPOList );
  1993. RtlFreeUnicodeString(&unicodeStr);
  1994. RegCloseKey(hSubKey);
  1995. return bOk ? ERROR_SUCCESS : E_FAIL;
  1996. } // else if psiduser == null
  1997. } // else if bmachine
  1998. } else { // if pmachine == null
  1999. //
  2000. // Remote case
  2001. //
  2002. if ( bMachine ) {
  2003. HKEY hKeyRemote;
  2004. dwRet = RegConnectRegistry( pMachineName,
  2005. HKEY_LOCAL_MACHINE,
  2006. &hKeyRemote );
  2007. if ( dwRet != ERROR_SUCCESS )
  2008. return dwRet;
  2009. bOk = ReadGPOList( szExtension,
  2010. hKeyRemote,
  2011. hKeyRemote,
  2012. 0,
  2013. FALSE, ppGPOList );
  2014. RegCloseKey( hKeyRemote );
  2015. dwRet = bOk ? ERROR_SUCCESS : E_FAIL;
  2016. return dwRet;
  2017. } else {
  2018. //
  2019. // Remote user
  2020. //
  2021. HKEY hKeyRemoteMach;
  2022. BOOL bUsePerUserLocalSetting;
  2023. if ( pSidUser == NULL )
  2024. return ERROR_INVALID_PARAMETER;
  2025. ntStatus = RtlConvertSidToUnicodeString( &unicodeStr,
  2026. pSidUser,
  2027. (BOOLEAN)TRUE ); // Allocate
  2028. if ( !NT_SUCCESS(ntStatus) )
  2029. return E_FAIL;
  2030. dwRet = RegConnectRegistry( pMachineName,
  2031. HKEY_LOCAL_MACHINE,
  2032. &hKeyRemoteMach );
  2033. if ( dwRet != ERROR_SUCCESS ) {
  2034. RtlFreeUnicodeString(&unicodeStr);
  2035. return dwRet;
  2036. }
  2037. bUsePerUserLocalSetting = ExtensionHasPerUserLocalSetting( szExtension, hKeyRemoteMach );
  2038. if ( bUsePerUserLocalSetting ) {
  2039. //
  2040. // Account for per user local settings
  2041. //
  2042. bOk = ReadGPOList( szExtension,
  2043. hKeyRemoteMach,
  2044. hKeyRemoteMach,
  2045. unicodeStr.Buffer,
  2046. FALSE, ppGPOList );
  2047. RtlFreeUnicodeString(&unicodeStr);
  2048. RegCloseKey(hKeyRemoteMach);
  2049. return bOk ? ERROR_SUCCESS : E_FAIL;
  2050. } else {
  2051. HKEY hKeyRemote, hSubKeyRemote;
  2052. RegCloseKey( hKeyRemoteMach );
  2053. dwRet = RegConnectRegistry( pMachineName,
  2054. HKEY_USERS,
  2055. &hKeyRemote );
  2056. if ( dwRet != ERROR_SUCCESS ) {
  2057. RtlFreeUnicodeString(&unicodeStr);
  2058. return dwRet;
  2059. }
  2060. dwRet = RegOpenKeyEx (hKeyRemote, unicodeStr.Buffer, 0, KEY_READ, &hSubKeyRemote);
  2061. RtlFreeUnicodeString(&unicodeStr);
  2062. if (dwRet != ERROR_SUCCESS) {
  2063. RegCloseKey(hKeyRemote);
  2064. if (dwRet == ERROR_FILE_NOT_FOUND)
  2065. return ERROR_SUCCESS;
  2066. else
  2067. return dwRet;
  2068. }
  2069. bOk = ReadGPOList( szExtension,
  2070. hSubKeyRemote,
  2071. hSubKeyRemote,
  2072. 0,
  2073. FALSE, ppGPOList );
  2074. RegCloseKey(hSubKeyRemote);
  2075. RegCloseKey(hKeyRemote);
  2076. return bOk ? ERROR_SUCCESS : E_FAIL;
  2077. } // else if bUsePerUserLocalSettings
  2078. } // else if bMachine
  2079. } // else if pMachName == null
  2080. return dwRet;
  2081. }
  2082. #define FORCE_FOREGROUND_LOGGING L"ForceForegroundLogging"
  2083. #define SITENAME L"Site-Name"
  2084. // dn defined in gpt.h
  2085. #define LOOPBACKDN L"Loopback-Distinguished-Name"
  2086. #define SLOWLINK L"SlowLink"
  2087. #define GPO L"GPO-List"
  2088. #define LOOPBACK L"Loopback-GPO-List"
  2089. #define EXTENSION L"Extension-List"
  2090. #define GPLINKLIST L"GPLink-List"
  2091. #define LOOPBACKGPL L"Loopback-GPLink-List"
  2092. #define GPOID L"GPOID"
  2093. #define VERSION L"Version"
  2094. #define SOM L"SOM"
  2095. #define WQL L"WQLFilterPass"
  2096. #define ACCESS L"AccessDenied"
  2097. #define DISPLAYNAME L"DisplayName"
  2098. #define DISABLED L"GPO-Disabled"
  2099. #define WQLID L"WQL-Id"
  2100. #define OPTIONS L"Options"
  2101. #define STARTTIME1 L"StartTimeLo"
  2102. #define ENDTIME1 L"EndTimeLo"
  2103. #define STARTTIME2 L"StartTimeHi"
  2104. #define ENDTIME2 L"EndTimeHi"
  2105. #define STATUS L"Status"
  2106. #define LOGSTATUS L"LoggingStatus"
  2107. #define ENABLED L"Enabled"
  2108. #define NOOVERRIDE L"NoOverride"
  2109. #define DSPATH L"DsPath"
  2110. DWORD RegSaveGPL( HKEY hKeyState,
  2111. LPSCOPEOFMGMT pSOM,
  2112. LPWSTR szGPLKey )
  2113. {
  2114. DWORD dwError = ERROR_SUCCESS;
  2115. //
  2116. // delete the existing list of GPLs
  2117. //
  2118. dwError = RegDelnode( hKeyState, szGPLKey );
  2119. if ( dwError == ERROR_SUCCESS )
  2120. {
  2121. HKEY hKeyGPL;
  2122. //
  2123. // recreate the GPL key
  2124. //
  2125. dwError = RegCreateKeyEx( hKeyState,
  2126. szGPLKey,
  2127. 0,
  2128. 0,
  2129. 0,
  2130. KEY_ALL_ACCESS,
  2131. 0,
  2132. &hKeyGPL,
  2133. 0 );
  2134. if ( dwError == ERROR_SUCCESS )
  2135. {
  2136. DWORD dwGPLs = 0;
  2137. while ( pSOM )
  2138. {
  2139. LPGPLINK pGPLink = pSOM->pGpLinkList;
  2140. while ( pGPLink )
  2141. {
  2142. HKEY hKeyNumber = 0;
  2143. WCHAR szNumber[32];
  2144. //
  2145. // create the number key of GPLs
  2146. //
  2147. dwError = RegCreateKeyEx( hKeyGPL,
  2148. _itow( dwGPLs, szNumber, 16 ),
  2149. 0,
  2150. 0,
  2151. 0,
  2152. KEY_ALL_ACCESS,
  2153. 0,
  2154. &hKeyNumber,
  2155. 0 );
  2156. if ( dwError != ERROR_SUCCESS )
  2157. {
  2158. break;
  2159. }
  2160. //
  2161. // Enabled
  2162. //
  2163. dwError = RegSetValueEx(hKeyNumber,
  2164. ENABLED,
  2165. 0,
  2166. REG_DWORD,
  2167. (BYTE*) &( pGPLink->bEnabled ),
  2168. sizeof( pGPLink->bEnabled ) );
  2169. if ( dwError != ERROR_SUCCESS )
  2170. {
  2171. RegCloseKey( hKeyNumber );
  2172. break;
  2173. }
  2174. //
  2175. // NoOverride
  2176. //
  2177. dwError = RegSetValueEx(hKeyNumber,
  2178. NOOVERRIDE,
  2179. 0,
  2180. REG_DWORD,
  2181. (BYTE*) &( pGPLink->bNoOverride ),
  2182. sizeof( pGPLink->bNoOverride ) );
  2183. if ( dwError != ERROR_SUCCESS )
  2184. {
  2185. RegCloseKey( hKeyNumber );
  2186. break;
  2187. }
  2188. //
  2189. // DS PATH
  2190. //
  2191. LPWSTR szTemp = pGPLink->pwszGPO ? pGPLink->pwszGPO : L"";
  2192. dwError = RegSetValueEx(hKeyNumber,
  2193. DSPATH,
  2194. 0,
  2195. REG_SZ,
  2196. (BYTE*) szTemp,
  2197. ( wcslen( szTemp ) + 1 ) * sizeof( WCHAR ) );
  2198. if ( dwError != ERROR_SUCCESS )
  2199. {
  2200. RegCloseKey( hKeyNumber );
  2201. break;
  2202. }
  2203. //
  2204. // SOM
  2205. //
  2206. szTemp = pSOM->pwszSOMId ? pSOM->pwszSOMId : L"";
  2207. dwError = RegSetValueEx(hKeyNumber,
  2208. SOM,
  2209. 0,
  2210. REG_SZ,
  2211. (BYTE*) szTemp,
  2212. ( wcslen( szTemp ) + 1 ) * sizeof( WCHAR ) );
  2213. if ( dwError != ERROR_SUCCESS )
  2214. {
  2215. RegCloseKey( hKeyNumber );
  2216. break;
  2217. }
  2218. RegCloseKey( hKeyNumber );
  2219. pGPLink = pGPLink->pNext;
  2220. dwGPLs++;
  2221. }
  2222. pSOM = pSOM->pNext;
  2223. }
  2224. RegCloseKey( hKeyGPL );
  2225. }
  2226. }
  2227. return dwError;
  2228. }
  2229. DWORD RegCompareGPLs( HKEY hKeyState,
  2230. LPSCOPEOFMGMT pSOM,
  2231. LPWSTR szGPLKey,
  2232. BOOL* pbChanged )
  2233. {
  2234. DWORD dwError = ERROR_SUCCESS;
  2235. HKEY hKeyGPL;
  2236. *pbChanged = FALSE;
  2237. //
  2238. // open the GPL key
  2239. //
  2240. dwError = RegOpenKeyEx( hKeyState,
  2241. szGPLKey,
  2242. 0,
  2243. KEY_ALL_ACCESS,
  2244. &hKeyGPL );
  2245. if ( dwError != ERROR_SUCCESS )
  2246. {
  2247. *pbChanged = TRUE;
  2248. return dwError;
  2249. }
  2250. WCHAR szNumber[32];
  2251. HKEY hKeyNumber = 0;
  2252. //
  2253. // compare each GPL and its corr. key for changes
  2254. //
  2255. DWORD dwGPLs = 0;
  2256. while ( pSOM )
  2257. {
  2258. LPGPLINK pGPLink = pSOM->pGpLinkList;
  2259. WCHAR* szBuffer;
  2260. szBuffer = NULL;
  2261. while ( pGPLink && dwError == ERROR_SUCCESS && !*pbChanged )
  2262. {
  2263. DWORD dwType;
  2264. DWORD dwSize;
  2265. DWORD dwBuffer;
  2266. DWORD dwBufferSize;
  2267. DWORD cbMaxValueLength;
  2268. if ( szBuffer )
  2269. {
  2270. LocalFree( szBuffer );
  2271. szBuffer = NULL;
  2272. }
  2273. //
  2274. // open the key corr. to the GPL
  2275. //
  2276. dwError = RegOpenKeyEx( hKeyGPL,
  2277. _itow( dwGPLs, szNumber, 16 ),
  2278. 0,
  2279. KEY_ALL_ACCESS,
  2280. &hKeyNumber );
  2281. if ( dwError != ERROR_SUCCESS )
  2282. {
  2283. *pbChanged = TRUE;
  2284. continue;
  2285. }
  2286. //
  2287. // Determine the maximum length of data in this key
  2288. // so we can use this to query for values
  2289. //
  2290. dwError = RegQueryInfoKey(
  2291. hKeyNumber,
  2292. 0,
  2293. 0,
  2294. 0,
  2295. 0,
  2296. 0,
  2297. 0,
  2298. 0,
  2299. 0,
  2300. &cbMaxValueLength,
  2301. 0,
  2302. 0 );
  2303. if ( dwError != ERROR_SUCCESS )
  2304. {
  2305. *pbChanged = TRUE;
  2306. continue;
  2307. }
  2308. //
  2309. // The string data type of the registry does not include the null terminator
  2310. //
  2311. dwBufferSize = ( cbMaxValueLength + sizeof( WCHAR ) );
  2312. szBuffer = (WCHAR*) LocalAlloc(LPTR, dwBufferSize);
  2313. if ( ! szBuffer )
  2314. {
  2315. *pbChanged = TRUE;
  2316. continue;
  2317. }
  2318. //
  2319. // Enabled
  2320. //
  2321. dwType = 0;
  2322. dwBuffer = 0;
  2323. dwSize = sizeof( dwBuffer );
  2324. dwError = RegQueryValueEx( hKeyNumber,
  2325. ENABLED,
  2326. 0,
  2327. &dwType,
  2328. (BYTE*) &dwBuffer,
  2329. &dwSize );
  2330. if ( dwError != ERROR_SUCCESS || dwBuffer != pGPLink->bEnabled )
  2331. {
  2332. *pbChanged = TRUE;
  2333. continue;
  2334. }
  2335. //
  2336. // NoOverride
  2337. //
  2338. dwType = 0;
  2339. dwBuffer = 0;
  2340. dwSize = sizeof( dwBuffer );
  2341. dwError = RegQueryValueEx( hKeyNumber,
  2342. NOOVERRIDE,
  2343. 0,
  2344. &dwType,
  2345. (BYTE*) &dwBuffer,
  2346. &dwSize );
  2347. if ( dwError != ERROR_SUCCESS || dwBuffer != pGPLink->bNoOverride )
  2348. {
  2349. *pbChanged = TRUE;
  2350. continue;
  2351. }
  2352. //
  2353. // DS PATH
  2354. //
  2355. LPWSTR szTemp = pGPLink->pwszGPO ? pGPLink->pwszGPO : L"";
  2356. dwType = 0;
  2357. szBuffer[0] = 0;
  2358. dwSize = dwBufferSize;
  2359. dwError = RegQueryValueEx( hKeyNumber,
  2360. DSPATH,
  2361. 0,
  2362. &dwType,
  2363. (BYTE*) szBuffer,
  2364. &dwSize );
  2365. if ( dwError != ERROR_SUCCESS || _wcsicmp( szBuffer, szTemp ) )
  2366. {
  2367. *pbChanged = TRUE;
  2368. continue;
  2369. }
  2370. //
  2371. // SOM
  2372. //
  2373. szTemp = pSOM->pwszSOMId ? pSOM->pwszSOMId : L"";
  2374. dwType = 0;
  2375. szBuffer[0] = 0;
  2376. dwSize = dwBufferSize;
  2377. dwError = RegQueryValueEx( hKeyNumber,
  2378. SOM,
  2379. 0,
  2380. &dwType,
  2381. (BYTE*) szBuffer,
  2382. &dwSize );
  2383. if ( dwError != ERROR_SUCCESS || _wcsicmp( szBuffer, szTemp ) )
  2384. {
  2385. *pbChanged = TRUE;
  2386. continue;
  2387. }
  2388. RegCloseKey( hKeyNumber );
  2389. hKeyNumber = 0;
  2390. pGPLink = pGPLink->pNext;
  2391. dwGPLs++;
  2392. }
  2393. pSOM = pSOM->pNext;
  2394. if ( szBuffer )
  2395. {
  2396. LocalFree( szBuffer );
  2397. }
  2398. }
  2399. if ( hKeyNumber )
  2400. {
  2401. RegCloseKey( hKeyNumber );
  2402. }
  2403. RegCloseKey( hKeyGPL );
  2404. return dwError;
  2405. }
  2406. DWORD RegSaveGPOs( HKEY hKeyState,
  2407. LPGPCONTAINER pGPOs,
  2408. BOOL bMachine,
  2409. LPWSTR szGPOKey )
  2410. {
  2411. DWORD dwError = ERROR_SUCCESS;
  2412. //
  2413. // delete the existing list of GPOs
  2414. //
  2415. dwError = RegDelnode( hKeyState, szGPOKey );
  2416. if ( dwError == ERROR_SUCCESS )
  2417. {
  2418. HKEY hKeyGPO;
  2419. //
  2420. // recreate the GPO key
  2421. //
  2422. dwError = RegCreateKeyEx( hKeyState,
  2423. szGPOKey,
  2424. 0,
  2425. 0,
  2426. 0,
  2427. KEY_ALL_ACCESS,
  2428. 0,
  2429. &hKeyGPO,
  2430. 0 );
  2431. if ( dwError == ERROR_SUCCESS )
  2432. {
  2433. DWORD dwGPOs = 0;
  2434. while ( pGPOs )
  2435. {
  2436. HKEY hKeyNumber = 0;
  2437. WCHAR szNumber[32];
  2438. //
  2439. // create the number key of GPOs
  2440. //
  2441. dwError = RegCreateKeyEx( hKeyGPO,
  2442. _itow( dwGPOs, szNumber, 16 ),
  2443. 0,
  2444. 0,
  2445. 0,
  2446. KEY_ALL_ACCESS,
  2447. 0,
  2448. &hKeyNumber,
  2449. 0 );
  2450. if ( dwError != ERROR_SUCCESS )
  2451. {
  2452. break;
  2453. }
  2454. //
  2455. // version
  2456. //
  2457. dwError = RegSetValueEx(hKeyNumber,
  2458. VERSION,
  2459. 0,
  2460. REG_DWORD,
  2461. (BYTE*) ( bMachine ? &pGPOs->dwMachVersion : &pGPOs->dwUserVersion ),
  2462. sizeof( DWORD ) );
  2463. if ( dwError != ERROR_SUCCESS )
  2464. {
  2465. RegCloseKey( hKeyNumber );
  2466. break;
  2467. }
  2468. //
  2469. // WQL
  2470. //
  2471. dwError = RegSetValueEx(hKeyNumber,
  2472. WQL,
  2473. 0,
  2474. REG_DWORD,
  2475. (BYTE*) &pGPOs->bFilterAllowed,
  2476. sizeof( DWORD ) );
  2477. if ( dwError != ERROR_SUCCESS )
  2478. {
  2479. RegCloseKey( hKeyNumber );
  2480. break;
  2481. }
  2482. //
  2483. // Access
  2484. //
  2485. dwError = RegSetValueEx(hKeyNumber,
  2486. ACCESS,
  2487. 0,
  2488. REG_DWORD,
  2489. (BYTE*) &pGPOs->bAccessDenied,
  2490. sizeof( DWORD ) );
  2491. if ( dwError != ERROR_SUCCESS )
  2492. {
  2493. RegCloseKey( hKeyNumber );
  2494. break;
  2495. }
  2496. //
  2497. // disabled
  2498. //
  2499. dwError = RegSetValueEx(hKeyNumber,
  2500. DISABLED,
  2501. 0,
  2502. REG_DWORD,
  2503. (BYTE*) ( bMachine ? &pGPOs->bMachDisabled : &pGPOs->bUserDisabled ),
  2504. sizeof( DWORD ) );
  2505. if ( dwError != ERROR_SUCCESS )
  2506. {
  2507. RegCloseKey( hKeyNumber );
  2508. break;
  2509. }
  2510. //
  2511. // Options
  2512. //
  2513. dwError = RegSetValueEx(hKeyNumber,
  2514. OPTIONS,
  2515. 0,
  2516. REG_DWORD,
  2517. (BYTE*) &( pGPOs->dwOptions ),
  2518. sizeof( DWORD ) );
  2519. if ( dwError != ERROR_SUCCESS )
  2520. {
  2521. RegCloseKey( hKeyNumber );
  2522. break;
  2523. }
  2524. //
  2525. // GPO GUID
  2526. //
  2527. dwError = RegSetValueEx(hKeyNumber,
  2528. GPOID,
  2529. 0,
  2530. REG_SZ,
  2531. (BYTE*) pGPOs->pwszGPOName,
  2532. ( wcslen( pGPOs->pwszGPOName ) + 1 ) * sizeof( WCHAR ) );
  2533. if ( dwError != ERROR_SUCCESS )
  2534. {
  2535. RegCloseKey( hKeyNumber );
  2536. break;
  2537. }
  2538. //
  2539. // SOM
  2540. //
  2541. dwError = RegSetValueEx(hKeyNumber,
  2542. SOM,
  2543. 0,
  2544. REG_SZ,
  2545. (BYTE*) pGPOs->szSOM,
  2546. ( wcslen( pGPOs->szSOM ) + 1 ) * sizeof( WCHAR ) );
  2547. if ( dwError != ERROR_SUCCESS )
  2548. {
  2549. RegCloseKey( hKeyNumber );
  2550. break;
  2551. }
  2552. LPWSTR szTemp;
  2553. //
  2554. // display name
  2555. //
  2556. szTemp = pGPOs->pwszDisplayName ? pGPOs->pwszDisplayName : L"";
  2557. dwError = RegSetValueEx(hKeyNumber,
  2558. DISPLAYNAME,
  2559. 0,
  2560. REG_SZ,
  2561. (BYTE*) szTemp,
  2562. ( wcslen( szTemp ) + 1 ) * sizeof( WCHAR ) );
  2563. if ( dwError != ERROR_SUCCESS )
  2564. {
  2565. RegCloseKey( hKeyNumber );
  2566. break;
  2567. }
  2568. //
  2569. // WQL filter
  2570. //
  2571. szTemp = pGPOs->pwszFilterId ? pGPOs->pwszFilterId : L"";
  2572. dwError = RegSetValueEx(hKeyNumber,
  2573. WQLID,
  2574. 0,
  2575. REG_SZ,
  2576. (BYTE*) szTemp,
  2577. ( wcslen( szTemp ) + 1 ) * sizeof( WCHAR ) );
  2578. if ( dwError != ERROR_SUCCESS )
  2579. {
  2580. RegCloseKey( hKeyNumber );
  2581. break;
  2582. }
  2583. RegCloseKey( hKeyNumber );
  2584. pGPOs = pGPOs->pNext;
  2585. dwGPOs++;
  2586. }
  2587. RegCloseKey( hKeyGPO );
  2588. }
  2589. }
  2590. return dwError;
  2591. }
  2592. DWORD RegCompareGPOs( HKEY hKeyState,
  2593. LPGPCONTAINER pGPOs,
  2594. BOOL bMachine,
  2595. LPWSTR szGPOKey,
  2596. BOOL* pbChanged,
  2597. BOOL* pbListChanged )
  2598. {
  2599. DWORD dwError = ERROR_SUCCESS;
  2600. HKEY hKeyGPO;
  2601. *pbChanged = FALSE;
  2602. *pbListChanged = FALSE;
  2603. //
  2604. // open the GPO key
  2605. //
  2606. dwError = RegOpenKeyEx( hKeyState,
  2607. szGPOKey,
  2608. 0,
  2609. KEY_ALL_ACCESS,
  2610. &hKeyGPO );
  2611. if ( dwError != ERROR_SUCCESS )
  2612. {
  2613. *pbChanged = TRUE;
  2614. return dwError;
  2615. }
  2616. DWORD dwSubKeys = 0;
  2617. //
  2618. // get the number of sub keys
  2619. //
  2620. dwError = RegQueryInfoKey( hKeyGPO,
  2621. 0,
  2622. 0,
  2623. 0,
  2624. &dwSubKeys,
  2625. 0,
  2626. 0,
  2627. 0,
  2628. 0,
  2629. 0,
  2630. 0,
  2631. 0 );
  2632. if ( dwError != ERROR_SUCCESS )
  2633. {
  2634. *pbChanged = TRUE;
  2635. *pbListChanged = TRUE;
  2636. RegCloseKey( hKeyGPO );
  2637. return dwError;
  2638. }
  2639. LPGPCONTAINER pTemp = pGPOs;
  2640. DWORD dwGPOs = 0;
  2641. //
  2642. // count the number of GPOs
  2643. //
  2644. while ( pTemp )
  2645. {
  2646. dwGPOs++;
  2647. pTemp = pTemp->pNext;
  2648. }
  2649. //
  2650. // the number of GPOs and the keys should match
  2651. //
  2652. if ( dwGPOs != dwSubKeys )
  2653. {
  2654. *pbChanged = TRUE;
  2655. *pbListChanged = TRUE;
  2656. RegCloseKey( hKeyGPO );
  2657. return dwError;
  2658. }
  2659. WCHAR szNumber[32];
  2660. HKEY hKeyNumber = 0;
  2661. WCHAR* szBuffer = NULL;
  2662. //
  2663. // compare each GPO and its corr. key for changes
  2664. //
  2665. dwGPOs = 0;
  2666. while ( pGPOs && dwError == ERROR_SUCCESS && !*pbChanged )
  2667. {
  2668. DWORD dwType;
  2669. DWORD dwSize;
  2670. DWORD dwBuffer;
  2671. DWORD dwBufferSize;
  2672. DWORD cbMaxValueLength;
  2673. if ( szBuffer )
  2674. {
  2675. LocalFree( szBuffer );
  2676. szBuffer = NULL;
  2677. }
  2678. //
  2679. // open the key corr. to the GPO
  2680. //
  2681. dwError = RegOpenKeyEx( hKeyGPO,
  2682. _itow( dwGPOs, szNumber, 16 ),
  2683. 0,
  2684. KEY_ALL_ACCESS,
  2685. &hKeyNumber );
  2686. if ( dwError != ERROR_SUCCESS )
  2687. {
  2688. *pbChanged = TRUE;
  2689. continue;
  2690. }
  2691. //
  2692. // Determine the maximum length of data in this key
  2693. // so we can use this to query for values
  2694. //
  2695. dwError = RegQueryInfoKey(
  2696. hKeyNumber,
  2697. 0,
  2698. 0,
  2699. 0,
  2700. 0,
  2701. 0,
  2702. 0,
  2703. 0,
  2704. 0,
  2705. &cbMaxValueLength,
  2706. 0,
  2707. 0 );
  2708. if ( dwError != ERROR_SUCCESS )
  2709. {
  2710. *pbChanged = TRUE;
  2711. continue;
  2712. }
  2713. //
  2714. // The string data type of the registry does not include the null terminator
  2715. //
  2716. dwBufferSize = ( cbMaxValueLength + sizeof( WCHAR ) );
  2717. szBuffer = (WCHAR*) LocalAlloc(LPTR, dwBufferSize);
  2718. if ( ! szBuffer )
  2719. {
  2720. *pbChanged = TRUE;
  2721. continue;
  2722. }
  2723. //
  2724. // version
  2725. //
  2726. dwType = 0;
  2727. dwBuffer = 0;
  2728. dwSize = sizeof( dwBuffer );
  2729. dwError = RegQueryValueEx( hKeyNumber,
  2730. VERSION,
  2731. 0,
  2732. &dwType,
  2733. (BYTE*) &dwBuffer,
  2734. &dwSize );
  2735. if ( dwError != ERROR_SUCCESS || dwBuffer != ( bMachine ? pGPOs->dwMachVersion : pGPOs->dwUserVersion ) )
  2736. {
  2737. *pbChanged = TRUE;
  2738. continue;
  2739. }
  2740. //
  2741. // WQL
  2742. //
  2743. dwType = 0;
  2744. dwBuffer = 0;
  2745. dwSize = sizeof( dwBuffer );
  2746. dwError = RegQueryValueEx( hKeyNumber,
  2747. WQL,
  2748. 0,
  2749. &dwType,
  2750. (BYTE*) &dwBuffer,
  2751. &dwSize );
  2752. if ( dwError != ERROR_SUCCESS || (BOOL) dwBuffer != pGPOs->bFilterAllowed )
  2753. {
  2754. *pbChanged = TRUE;
  2755. continue;
  2756. }
  2757. //
  2758. // Access
  2759. //
  2760. dwType = 0;
  2761. dwBuffer = 0;
  2762. dwSize = sizeof( dwBuffer );
  2763. dwError = RegQueryValueEx( hKeyNumber,
  2764. ACCESS,
  2765. 0,
  2766. &dwType,
  2767. (BYTE*) &dwBuffer,
  2768. &dwSize );
  2769. if ( dwError != ERROR_SUCCESS || (BOOL) dwBuffer != pGPOs->bAccessDenied )
  2770. {
  2771. *pbChanged = TRUE;
  2772. continue;
  2773. }
  2774. //
  2775. // disabled
  2776. //
  2777. dwType = 0;
  2778. dwBuffer = 0;
  2779. dwSize = sizeof( dwBuffer );
  2780. dwError = RegQueryValueEx( hKeyNumber,
  2781. DISABLED,
  2782. 0,
  2783. &dwType,
  2784. (BYTE*) &dwBuffer,
  2785. &dwSize );
  2786. if ( dwError != ERROR_SUCCESS || (BOOL) dwBuffer != ( bMachine ? pGPOs->bMachDisabled : pGPOs->bUserDisabled ) )
  2787. {
  2788. *pbChanged = TRUE;
  2789. continue;
  2790. }
  2791. //
  2792. // Options
  2793. //
  2794. dwType = 0;
  2795. dwBuffer = 0;
  2796. dwSize = sizeof( dwBuffer );
  2797. dwError = RegQueryValueEx( hKeyNumber,
  2798. OPTIONS,
  2799. 0,
  2800. &dwType,
  2801. (BYTE*) &dwBuffer,
  2802. &dwSize );
  2803. if ( dwError != ERROR_SUCCESS || dwBuffer != pGPOs->dwOptions )
  2804. {
  2805. *pbChanged = TRUE;
  2806. continue;
  2807. }
  2808. //
  2809. // GPO GUID
  2810. //
  2811. dwType = 0;
  2812. szBuffer[0] = 0;
  2813. dwSize = dwBufferSize;
  2814. dwError = RegQueryValueEx( hKeyNumber,
  2815. GPOID,
  2816. 0,
  2817. &dwType,
  2818. (BYTE*) szBuffer,
  2819. &dwSize );
  2820. if ( dwError != ERROR_SUCCESS || _wcsicmp( szBuffer, pGPOs->pwszGPOName ) )
  2821. {
  2822. *pbChanged = TRUE;
  2823. continue;
  2824. }
  2825. //
  2826. // SOM
  2827. //
  2828. dwType = 0;
  2829. szBuffer[0] = 0;
  2830. dwSize = dwBufferSize;
  2831. dwError = RegQueryValueEx( hKeyNumber,
  2832. SOM,
  2833. 0,
  2834. &dwType,
  2835. (BYTE*) szBuffer,
  2836. &dwSize );
  2837. if ( dwError != ERROR_SUCCESS || _wcsicmp( szBuffer, pGPOs->szSOM ) )
  2838. {
  2839. *pbChanged = TRUE;
  2840. continue;
  2841. }
  2842. LPWSTR szTemp;
  2843. //
  2844. // display name
  2845. //
  2846. szTemp = pGPOs->pwszDisplayName ? pGPOs->pwszDisplayName : L"";
  2847. dwType = 0;
  2848. szBuffer[0] = 0;
  2849. dwSize = dwBufferSize;
  2850. dwError = RegQueryValueEx( hKeyNumber,
  2851. DISPLAYNAME,
  2852. 0,
  2853. &dwType,
  2854. (BYTE*) szBuffer,
  2855. &dwSize );
  2856. if ( dwError != ERROR_SUCCESS || _wcsicmp( szBuffer, szTemp ) )
  2857. {
  2858. *pbChanged = TRUE;
  2859. continue;
  2860. }
  2861. //
  2862. // WQL filter
  2863. //
  2864. szTemp = pGPOs->pwszFilterId ? pGPOs->pwszFilterId : L"";
  2865. dwType = 0;
  2866. szBuffer[0] = 0;
  2867. dwSize = dwBufferSize;
  2868. dwError = RegQueryValueEx( hKeyNumber,
  2869. WQLID,
  2870. 0,
  2871. &dwType,
  2872. (BYTE*) szBuffer,
  2873. &dwSize );
  2874. if ( dwError != ERROR_SUCCESS || _wcsicmp( szBuffer, szTemp ) )
  2875. {
  2876. *pbChanged = TRUE;
  2877. continue;
  2878. }
  2879. RegCloseKey( hKeyNumber );
  2880. hKeyNumber = 0;
  2881. LocalFree( szBuffer );
  2882. szBuffer = NULL;
  2883. pGPOs = pGPOs->pNext;
  2884. dwGPOs++;
  2885. }
  2886. if ( szBuffer )
  2887. {
  2888. LocalFree( szBuffer );
  2889. }
  2890. if ( hKeyNumber )
  2891. {
  2892. RegCloseKey( hKeyNumber );
  2893. }
  2894. RegCloseKey( hKeyGPO );
  2895. return dwError;
  2896. }
  2897. //*************************************************************
  2898. //
  2899. // SavePolicyState()
  2900. //
  2901. // Purpose: Saves enough information about the policy application
  2902. // to determine if RSoP data needs to be re-logged
  2903. //
  2904. // HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State
  2905. // |- Machine
  2906. // | |-SiteName
  2907. // | |-DN
  2908. // | |-GPO
  2909. // | |-0
  2910. // | |-GPOID
  2911. // | |-SOM
  2912. // | |-Version
  2913. // | |-WQL
  2914. // | |-Access
  2915. // | |-1
  2916. // | |-GPOID
  2917. // | |-SOM
  2918. // | |-Version
  2919. // | |-WQL
  2920. // | |-Access
  2921. // | ...
  2922. // | |-N
  2923. // | |-GPOID
  2924. // | |-SOM
  2925. // | |-Version
  2926. // | |-WQL
  2927. // | |-Access
  2928. // |-{UserSID}
  2929. // |-SiteName
  2930. // |-DN
  2931. // |-GPO
  2932. // |-0
  2933. // |-GPOID
  2934. // |-SOM
  2935. // |-Version
  2936. // |-WQL
  2937. // |-Access
  2938. // |-1
  2939. // |-GPOID
  2940. // |-SOM
  2941. // |-Version
  2942. // |-WQL
  2943. // |-Access
  2944. // ...
  2945. // |-N
  2946. // |-GPOID
  2947. // |-SOM
  2948. // |-Version
  2949. // |-WQL
  2950. // |-Access
  2951. // Parameters:
  2952. // pInfo - current state of affairs
  2953. //
  2954. // Returns: Win32 error code
  2955. //
  2956. //*************************************************************
  2957. DWORD
  2958. SavePolicyState( LPGPOINFO pInfo )
  2959. {
  2960. DWORD dwError = ERROR_SUCCESS;
  2961. BOOL bMachine = (pInfo->dwFlags & GP_MACHINE) != 0;
  2962. HKEY hKeyState = 0;
  2963. WCHAR szKeyState[MAX_PATH+1];
  2964. LPWSTR szSite = pInfo->szSiteName ? pInfo->szSiteName : L"";
  2965. LPWSTR szDN = pInfo->lpDNName ? pInfo->lpDNName : L"";
  2966. BOOL bSlowLink = (pInfo->dwFlags & GP_SLOW_LINK) != 0;
  2967. HRESULT hr = S_OK;
  2968. XLastError xe;
  2969. //
  2970. // determine the subkey to create
  2971. //
  2972. if ( bMachine )
  2973. {
  2974. hr = StringCchPrintf( szKeyState, sizeof(szKeyState)/sizeof(WCHAR), GP_STATE_KEY, L"Machine" );
  2975. }
  2976. else
  2977. {
  2978. hr = StringCchPrintf( szKeyState, sizeof(szKeyState)/sizeof(WCHAR), GP_STATE_KEY, pInfo->lpwszSidUser );
  2979. }
  2980. if (FAILED(hr)) {
  2981. xe = dwError = HRESULT_CODE(hr);
  2982. goto Exit;
  2983. }
  2984. dwError = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  2985. szKeyState,
  2986. 0,
  2987. 0,
  2988. 0,
  2989. KEY_ALL_ACCESS,
  2990. 0,
  2991. &hKeyState,
  2992. 0 );
  2993. if ( dwError != ERROR_SUCCESS )
  2994. {
  2995. goto Exit;
  2996. }
  2997. //
  2998. // reset forced logging in foreground
  2999. //
  3000. if ( !(pInfo->dwFlags & GP_BACKGROUND_THREAD) )
  3001. {
  3002. //
  3003. // set the FORCE_FOREGROUND_LOGGING value
  3004. //
  3005. DWORD dwFalse = 0;
  3006. dwError = RegSetValueEx(hKeyState,
  3007. FORCE_FOREGROUND_LOGGING,
  3008. 0,
  3009. REG_DWORD,
  3010. (BYTE*) &dwFalse,
  3011. sizeof( DWORD ) );
  3012. if ( dwError != ERROR_SUCCESS )
  3013. {
  3014. goto Exit;
  3015. }
  3016. }
  3017. //
  3018. // set the SITENAME value
  3019. //
  3020. dwError = RegSetValueEx(hKeyState,
  3021. SITENAME,
  3022. 0,
  3023. REG_SZ,
  3024. (BYTE*) szSite,
  3025. ( wcslen( szSite ) + 1 ) * sizeof( WCHAR ) );
  3026. if ( dwError != ERROR_SUCCESS )
  3027. {
  3028. goto Exit;
  3029. }
  3030. //
  3031. // set the DN value
  3032. //
  3033. dwError = RegSetValueEx(hKeyState,
  3034. DN,
  3035. 0,
  3036. REG_SZ,
  3037. (BYTE*) szDN,
  3038. ( wcslen( szDN ) + 1 ) * sizeof( WCHAR ) );
  3039. if ( dwError != ERROR_SUCCESS )
  3040. {
  3041. goto Exit;
  3042. }
  3043. //
  3044. // slow link
  3045. //
  3046. dwError = RegSetValueEx(hKeyState,
  3047. SLOWLINK,
  3048. 0,
  3049. REG_DWORD,
  3050. (BYTE*) ( &bSlowLink ),
  3051. sizeof( DWORD ) );
  3052. if ( dwError != ERROR_SUCCESS )
  3053. {
  3054. goto Exit;
  3055. }
  3056. //
  3057. // save the list of GPOs
  3058. //
  3059. dwError = RegSaveGPOs( hKeyState, pInfo->lpGpContainerList, bMachine, GPO );
  3060. if ( dwError != ERROR_SUCCESS )
  3061. {
  3062. goto Exit;
  3063. }
  3064. if ( !bMachine )
  3065. {
  3066. //
  3067. // save the list of Loopback GPOs
  3068. //
  3069. dwError = RegSaveGPOs( hKeyState, pInfo->lpLoopbackGpContainerList, bMachine, LOOPBACK );
  3070. if ( dwError != ERROR_SUCCESS )
  3071. {
  3072. goto Exit;
  3073. }
  3074. }
  3075. //
  3076. // save the list of GPLinks
  3077. //
  3078. dwError = RegSaveGPL( hKeyState, pInfo->lpSOMList, GPLINKLIST );
  3079. if ( dwError != ERROR_SUCCESS )
  3080. {
  3081. goto Exit;
  3082. }
  3083. if ( !bMachine )
  3084. {
  3085. //
  3086. // save the list of Loopback GPLinks
  3087. //
  3088. dwError = RegSaveGPL( hKeyState, pInfo->lpLoopbackSOMList, LOOPBACKGPL );
  3089. }
  3090. Exit:
  3091. if ( hKeyState )
  3092. {
  3093. RegCloseKey( hKeyState );
  3094. }
  3095. if ( dwError != ERROR_SUCCESS )
  3096. {
  3097. DebugMsg( ( DM_WARNING, L"SavePolicyState: Failed Registry operation with %d", dwError ) );
  3098. }
  3099. return dwError;
  3100. }
  3101. //*************************************************************
  3102. //
  3103. // SaveLinkState()
  3104. //
  3105. // Purpose: Saves link speed information for the policy application
  3106. //
  3107. // Parameters:
  3108. // pInfo - current state of affairs
  3109. //
  3110. // Returns: Win32 error code
  3111. //
  3112. //*************************************************************
  3113. DWORD
  3114. SaveLinkState( LPGPOINFO pInfo )
  3115. {
  3116. DWORD dwError = ERROR_SUCCESS;
  3117. BOOL bMachine = (pInfo->dwFlags & GP_MACHINE) != 0;
  3118. HKEY hKeyState = 0;
  3119. WCHAR szKeyState[MAX_PATH+1];
  3120. BOOL bSlowLink = (pInfo->dwFlags & GP_SLOW_LINK) != 0;
  3121. HRESULT hr = S_OK;
  3122. XLastError xe;
  3123. //
  3124. // determine the subkey to create
  3125. //
  3126. if ( bMachine )
  3127. {
  3128. hr = StringCchPrintf( szKeyState, ARRAYSIZE(szKeyState), GP_STATE_KEY, L"Machine" );
  3129. }
  3130. else
  3131. {
  3132. hr = StringCchPrintf( szKeyState, ARRAYSIZE(szKeyState), GP_STATE_KEY, pInfo->lpwszSidUser );
  3133. }
  3134. if (FAILED(hr))
  3135. {
  3136. xe = dwError = HRESULT_CODE(hr);
  3137. return dwError;
  3138. }
  3139. dwError = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  3140. szKeyState,
  3141. 0,
  3142. 0,
  3143. 0,
  3144. KEY_ALL_ACCESS,
  3145. 0,
  3146. &hKeyState,
  3147. 0 );
  3148. if ( dwError == ERROR_SUCCESS )
  3149. {
  3150. //
  3151. // slow link
  3152. //
  3153. dwError = RegSetValueEx(hKeyState,
  3154. SLOWLINK,
  3155. 0,
  3156. REG_DWORD,
  3157. (BYTE*) ( &bSlowLink ),
  3158. sizeof( DWORD ) );
  3159. RegCloseKey( hKeyState );
  3160. }
  3161. if ( dwError != ERROR_SUCCESS )
  3162. {
  3163. DebugMsg( ( DM_WARNING, L"SaveLinkState: Failed Registry operation with %d", dwError ) );
  3164. }
  3165. return dwError;
  3166. }
  3167. //*************************************************************
  3168. //
  3169. // ComparePolicyState()
  3170. //
  3171. // Purpose: Compares the policy state saved in the registry
  3172. // with the state in LPGPOINFO
  3173. //
  3174. // Parameters:
  3175. // pInfo - current state of affairs
  3176. // pbLinkChanged - has the link speed changed?
  3177. // pbStateChanged - has the state changed?
  3178. //
  3179. // Returns: Win32 error code
  3180. //
  3181. //*************************************************************
  3182. DWORD
  3183. ComparePolicyState( LPGPOINFO pInfo, BOOL* pbLinkChanged, BOOL* pbStateChanged, BOOL *pbNoState )
  3184. {
  3185. DWORD dwError = ERROR_SUCCESS;
  3186. BOOL bMachine = (pInfo->dwFlags & GP_MACHINE) != 0;
  3187. HKEY hKeyState = 0;
  3188. WCHAR szKeyState[MAX_PATH+1];
  3189. DWORD dwBuffer;
  3190. BOOL bSlowLink = (pInfo->dwFlags & GP_SLOW_LINK) != 0;
  3191. BOOL bListChanged = FALSE;
  3192. WCHAR* wszBuffer;
  3193. HRESULT hr = S_OK;
  3194. XLastError xe;
  3195. *pbStateChanged = FALSE;
  3196. *pbLinkChanged = FALSE;
  3197. *pbNoState = FALSE;
  3198. wszBuffer = NULL;
  3199. //
  3200. // determine the subkey to open
  3201. //
  3202. if ( bMachine )
  3203. {
  3204. hr = StringCchPrintf( szKeyState, ARRAYSIZE(szKeyState), GP_STATE_KEY, L"Machine" );
  3205. }
  3206. else
  3207. {
  3208. hr = StringCchPrintf( szKeyState, ARRAYSIZE(szKeyState), GP_STATE_KEY, pInfo->lpwszSidUser );
  3209. }
  3210. if (FAILED(hr))
  3211. {
  3212. xe = dwError = HRESULT_CODE(hr);
  3213. return dwError;
  3214. }
  3215. dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  3216. szKeyState,
  3217. 0,
  3218. KEY_ALL_ACCESS,
  3219. &hKeyState );
  3220. if ( dwError != ERROR_SUCCESS )
  3221. {
  3222. *pbStateChanged = TRUE;
  3223. *pbNoState = TRUE;
  3224. if (dwError == ERROR_FILE_NOT_FOUND) {
  3225. return ERROR_SUCCESS;
  3226. }
  3227. else {
  3228. goto Exit;
  3229. }
  3230. }
  3231. DWORD dwBufferSize;
  3232. DWORD dwType;
  3233. DWORD dwSize;
  3234. //
  3235. // Determine the maximum length of data in this key
  3236. // so we can use this to query for values
  3237. //
  3238. dwError = RegQueryInfoKey(
  3239. hKeyState,
  3240. 0,
  3241. 0,
  3242. 0,
  3243. 0,
  3244. 0,
  3245. 0,
  3246. 0,
  3247. 0,
  3248. &dwBufferSize,
  3249. 0,
  3250. 0 );
  3251. if ( dwError != ERROR_SUCCESS )
  3252. {
  3253. *pbStateChanged = TRUE;
  3254. goto Exit;
  3255. }
  3256. //
  3257. // The string data type of the registry does not include the null terminator
  3258. //
  3259. dwBufferSize += sizeof( WCHAR );
  3260. wszBuffer = (WCHAR*) LocalAlloc(LPTR, dwBufferSize);
  3261. if ( ! wszBuffer )
  3262. {
  3263. *pbStateChanged = TRUE;
  3264. goto Exit;
  3265. }
  3266. //
  3267. // check for forced logging in foreground
  3268. //
  3269. if ( !(pInfo->dwFlags & GP_BACKGROUND_THREAD) )
  3270. {
  3271. //
  3272. // get the FORCE_FOREGROUND_LOGGING value
  3273. //
  3274. dwType = 0;
  3275. dwBuffer = 0;
  3276. dwSize = sizeof( dwBuffer );
  3277. dwError = RegQueryValueEx( hKeyState,
  3278. FORCE_FOREGROUND_LOGGING,
  3279. 0,
  3280. &dwType,
  3281. (BYTE*) &dwBuffer,
  3282. &dwSize );
  3283. if ( dwError != ERROR_SUCCESS || dwBuffer != FALSE )
  3284. {
  3285. *pbStateChanged = TRUE;
  3286. goto Exit;
  3287. }
  3288. }
  3289. //
  3290. // get the SITENAME value
  3291. //
  3292. dwSize = dwBufferSize;
  3293. dwType = 0;
  3294. dwError = RegQueryValueEx( hKeyState,
  3295. SITENAME,
  3296. 0,
  3297. &dwType,
  3298. (BYTE*) wszBuffer,
  3299. &dwSize );
  3300. if ( dwError == ERROR_SUCCESS )
  3301. {
  3302. LPWSTR szSite = pInfo->szSiteName ? pInfo->szSiteName : L"";
  3303. if ( _wcsicmp( wszBuffer, szSite ) )
  3304. {
  3305. *pbStateChanged = TRUE;
  3306. goto Exit;
  3307. }
  3308. }
  3309. else
  3310. {
  3311. goto Exit;
  3312. }
  3313. //
  3314. // get the DN value
  3315. //
  3316. dwSize = dwBufferSize;
  3317. dwType = 0;
  3318. dwError = RegQueryValueEx( hKeyState,
  3319. DN,
  3320. 0,
  3321. &dwType,
  3322. (BYTE*) wszBuffer,
  3323. &dwSize );
  3324. if ( dwError == ERROR_SUCCESS )
  3325. {
  3326. LPWSTR szDN = pInfo->lpDNName ? pInfo->lpDNName : L"";
  3327. if ( _wcsicmp( wszBuffer, szDN ) )
  3328. {
  3329. *pbStateChanged = TRUE;
  3330. //
  3331. // set forced logging in foreground
  3332. //
  3333. if ( (pInfo->dwFlags & GP_BACKGROUND_THREAD) )
  3334. {
  3335. //
  3336. // set the FORCE_FOREGROUND_LOGGING value
  3337. //
  3338. DWORD dwTrue = TRUE;
  3339. dwError = RegSetValueEx(hKeyState,
  3340. FORCE_FOREGROUND_LOGGING,
  3341. 0,
  3342. REG_DWORD,
  3343. (BYTE*) &dwTrue,
  3344. sizeof( DWORD ) );
  3345. if ( dwError != ERROR_SUCCESS )
  3346. {
  3347. goto Exit;
  3348. }
  3349. }
  3350. goto Exit;
  3351. }
  3352. }
  3353. else
  3354. {
  3355. goto Exit;
  3356. }
  3357. //
  3358. // slow link
  3359. //
  3360. dwType = 0;
  3361. dwBuffer = 0;
  3362. dwSize = sizeof( dwBuffer );
  3363. dwError = RegQueryValueEx( hKeyState,
  3364. SLOWLINK,
  3365. 0,
  3366. &dwType,
  3367. (BYTE*) &dwBuffer,
  3368. &dwSize );
  3369. if ( dwError != ERROR_SUCCESS || dwBuffer != (DWORD)bSlowLink )
  3370. {
  3371. *pbLinkChanged = TRUE;
  3372. }
  3373. //
  3374. // has the list of GPOs or the GPOs changed
  3375. //
  3376. dwError = RegCompareGPOs( hKeyState,
  3377. pInfo->lpGpContainerList,
  3378. bMachine,
  3379. GPO,
  3380. pbStateChanged,
  3381. &bListChanged );
  3382. //
  3383. // set forced logging in foreground
  3384. //
  3385. if ( (pInfo->dwFlags & GP_BACKGROUND_THREAD) && bListChanged )
  3386. {
  3387. //
  3388. // set the FORCE_FOREGROUND_LOGGING value
  3389. //
  3390. DWORD dwTrue = TRUE;
  3391. dwError = RegSetValueEx(hKeyState,
  3392. FORCE_FOREGROUND_LOGGING,
  3393. 0,
  3394. REG_DWORD,
  3395. (BYTE*) &dwTrue,
  3396. sizeof( DWORD ) );
  3397. if ( dwError != ERROR_SUCCESS )
  3398. {
  3399. goto Exit;
  3400. }
  3401. }
  3402. if ( dwError == ERROR_SUCCESS && !*pbStateChanged && !bMachine )
  3403. {
  3404. //
  3405. // has the list of loopback GPOs or the GPOs changed
  3406. //
  3407. dwError = RegCompareGPOs( hKeyState,
  3408. pInfo->lpLoopbackGpContainerList,
  3409. bMachine,
  3410. LOOPBACK,
  3411. pbStateChanged,
  3412. &bListChanged );
  3413. //
  3414. // set forced logging in foreground
  3415. //
  3416. if ( (pInfo->dwFlags & GP_BACKGROUND_THREAD) && bListChanged )
  3417. {
  3418. //
  3419. // set the FORCE_FOREGROUND_LOGGING value
  3420. //
  3421. DWORD dwTrue = TRUE;
  3422. dwError = RegSetValueEx(hKeyState,
  3423. FORCE_FOREGROUND_LOGGING,
  3424. 0,
  3425. REG_DWORD,
  3426. (BYTE*) &dwTrue,
  3427. sizeof( DWORD ) );
  3428. if ( dwError != ERROR_SUCCESS )
  3429. {
  3430. goto Exit;
  3431. }
  3432. }
  3433. }
  3434. if ( dwError == ERROR_SUCCESS && !*pbStateChanged )
  3435. {
  3436. dwError = RegCompareGPLs( hKeyState,
  3437. pInfo->lpSOMList,
  3438. GPLINKLIST,
  3439. pbStateChanged );
  3440. if ( dwError == ERROR_SUCCESS && !*pbStateChanged && !bMachine)
  3441. {
  3442. dwError = RegCompareGPLs( hKeyState,
  3443. pInfo->lpLoopbackSOMList,
  3444. LOOPBACKGPL,
  3445. pbStateChanged );
  3446. }
  3447. if (*pbStateChanged)
  3448. {
  3449. DebugMsg( ( DM_VERBOSE, L"ComparePolicyState: Links have changed") );
  3450. }
  3451. }
  3452. Exit:
  3453. if ( wszBuffer )
  3454. {
  3455. LocalFree( wszBuffer );
  3456. }
  3457. if ( hKeyState )
  3458. {
  3459. RegCloseKey( hKeyState );
  3460. }
  3461. if ( dwError != ERROR_SUCCESS )
  3462. {
  3463. *pbStateChanged = TRUE;
  3464. DebugMsg( ( DM_WARNING, L"ComparePolicyState: Failed Registry operation with %d", dwError ) );
  3465. }
  3466. return dwError;
  3467. }
  3468. //*************************************************************
  3469. //
  3470. // DeletePolicyState()
  3471. //
  3472. // Purpose: deletes the policy state saved in the registry
  3473. //
  3474. // Parameters:
  3475. // szSID - user SID or 0 for machine
  3476. //
  3477. // Returns: Win32 error code
  3478. //
  3479. //*************************************************************
  3480. DWORD
  3481. DeletePolicyState( LPCWSTR szSid )
  3482. {
  3483. DWORD dwError = ERROR_SUCCESS;
  3484. HKEY hKeyState = 0;
  3485. LPWSTR szState = L"Machine";
  3486. if ( szSid && *szSid )
  3487. {
  3488. szState = (LPWSTR) szSid;
  3489. }
  3490. dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  3491. GP_STATE_ROOT_KEY,
  3492. 0,
  3493. KEY_ALL_ACCESS,
  3494. &hKeyState );
  3495. if ( dwError == ERROR_SUCCESS )
  3496. {
  3497. dwError = RegDelnode( hKeyState, (LPWSTR) szState );
  3498. RegCloseKey( hKeyState );
  3499. }
  3500. return dwError;
  3501. }
  3502. //*************************************************************
  3503. //
  3504. // SaveLoggingStatus()
  3505. //
  3506. // Purpose: Saving the extension status into the registry
  3507. //
  3508. // Parameters:
  3509. // szSid - Null for machine, otherwise the user sid
  3510. // lpExt - Extension info (null for GP Engine itself)
  3511. // lpRsopExtStatus - A pointer to the RsopExtStatus corresponding
  3512. // to this extension
  3513. //
  3514. // Returns: Win32 error code
  3515. //
  3516. //*************************************************************
  3517. DWORD SaveLoggingStatus(LPWSTR szSid, LPGPEXT lpExt, RSOPEXTSTATUS *lpRsopExtStatus)
  3518. {
  3519. DWORD dwError = ERROR_SUCCESS;
  3520. BOOL bMachine = (szSid == 0);
  3521. HKEY hKeyState = 0, hKeyExtState = 0, hKeyExt = 0;
  3522. WCHAR szKeyState[MAX_PATH+1];
  3523. LPWSTR lpExtId;
  3524. HRESULT hr = S_OK;
  3525. XLastError xe;
  3526. if ( bMachine )
  3527. {
  3528. hr = StringCchPrintf( szKeyState, ARRAYSIZE(szKeyState), GP_STATE_KEY, L"Machine" );
  3529. }
  3530. else
  3531. {
  3532. hr = StringCchPrintf( szKeyState, ARRAYSIZE(szKeyState), GP_STATE_KEY, szSid );
  3533. }
  3534. if (FAILED(hr))
  3535. {
  3536. xe = dwError = HRESULT_CODE(hr);
  3537. return dwError;
  3538. }
  3539. dwError = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  3540. szKeyState,
  3541. 0,
  3542. 0,
  3543. 0,
  3544. KEY_ALL_ACCESS,
  3545. 0,
  3546. &hKeyState,
  3547. 0 );
  3548. if ( dwError != ERROR_SUCCESS )
  3549. {
  3550. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to create state key with %d", dwError ) );
  3551. goto Exit;
  3552. }
  3553. dwError = RegCreateKeyEx( hKeyState,
  3554. EXTENSION,
  3555. 0,
  3556. 0,
  3557. 0,
  3558. KEY_ALL_ACCESS,
  3559. 0,
  3560. &hKeyExtState,
  3561. 0 );
  3562. if ( dwError != ERROR_SUCCESS )
  3563. {
  3564. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to create extension key with %d", dwError ) );
  3565. goto Exit;
  3566. }
  3567. lpExtId = lpExt ? lpExt->lpKeyName : GPCORE_GUID;
  3568. dwError = RegCreateKeyEx( hKeyExtState,
  3569. lpExtId,
  3570. 0,
  3571. 0,
  3572. 0,
  3573. KEY_ALL_ACCESS,
  3574. 0,
  3575. &hKeyExt,
  3576. 0 );
  3577. if ( dwError != ERROR_SUCCESS )
  3578. {
  3579. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to create CSE key with %d", dwError ) );
  3580. goto Exit;
  3581. }
  3582. dwError = RegSetValueEx(hKeyExt, STARTTIME1, 0, REG_DWORD,
  3583. (BYTE *)(&((lpRsopExtStatus->ftStartTime).dwLowDateTime)),
  3584. sizeof(DWORD));
  3585. if ( dwError != ERROR_SUCCESS )
  3586. {
  3587. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to set STARTTIME1 with %d", dwError ) );
  3588. goto Exit;
  3589. }
  3590. dwError = RegSetValueEx(hKeyExt, STARTTIME2, 0, REG_DWORD,
  3591. (BYTE *)(&((lpRsopExtStatus->ftStartTime).dwHighDateTime)),
  3592. sizeof(DWORD));
  3593. if ( dwError != ERROR_SUCCESS )
  3594. {
  3595. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to set STARTTIME2 with %d", dwError ) );
  3596. goto Exit;
  3597. }
  3598. dwError = RegSetValueEx(hKeyExt, ENDTIME1, 0, REG_DWORD,
  3599. (BYTE *)(&((lpRsopExtStatus->ftEndTime).dwLowDateTime)),
  3600. sizeof(DWORD));
  3601. if ( dwError != ERROR_SUCCESS )
  3602. {
  3603. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to set ENDTIME1 with %d", dwError ) );
  3604. goto Exit;
  3605. }
  3606. dwError = RegSetValueEx(hKeyExt, ENDTIME2, 0, REG_DWORD,
  3607. (BYTE *)(&((lpRsopExtStatus->ftEndTime).dwHighDateTime)),
  3608. sizeof(DWORD));
  3609. if ( dwError != ERROR_SUCCESS )
  3610. {
  3611. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to set ENDTIME2 with %d", dwError ) );
  3612. goto Exit;
  3613. }
  3614. dwError = RegSetValueEx(hKeyExt, STATUS, 0, REG_DWORD,
  3615. (BYTE *)(&(lpRsopExtStatus->dwStatus)),
  3616. sizeof(DWORD));
  3617. if ( dwError != ERROR_SUCCESS )
  3618. {
  3619. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to set STATUS with %d", dwError ) );
  3620. goto Exit;
  3621. }
  3622. dwError = RegSetValueEx(hKeyExt, LOGSTATUS, 0, REG_DWORD,
  3623. (BYTE *)(&(lpRsopExtStatus->dwLoggingStatus)),
  3624. sizeof(DWORD));
  3625. if ( dwError != ERROR_SUCCESS )
  3626. {
  3627. DebugMsg( ( DM_WARNING, L"SaveLoggingStatus: Failed to set LOGSTATUS with %d", dwError ) );
  3628. goto Exit;
  3629. }
  3630. Exit:
  3631. if (hKeyExt)
  3632. RegCloseKey(hKeyExt);
  3633. if (hKeyExtState)
  3634. RegCloseKey(hKeyExtState);
  3635. if (hKeyState)
  3636. RegCloseKey(hKeyState);
  3637. return dwError;
  3638. }
  3639. //*************************************************************
  3640. //
  3641. // ReadLoggingStatus()
  3642. //
  3643. // Purpose: Read the extension status into the registry
  3644. //
  3645. // Parameters:
  3646. // szSid - Null for machine, otherwise the user sid
  3647. // szExtId - Extension info (null for GP Engine itself)
  3648. // lpRsopExtStatus - A pointer to the RsopExtStatus (that will be filled up)
  3649. //
  3650. // Returns: Win32 error code
  3651. //
  3652. //
  3653. //*************************************************************
  3654. DWORD ReadLoggingStatus(LPWSTR szSid, LPWSTR szExtId, RSOPEXTSTATUS *lpRsopExtStatus)
  3655. {
  3656. DWORD dwError = ERROR_SUCCESS;
  3657. BOOL bMachine = (szSid == 0);
  3658. HKEY hKeyExt = 0;
  3659. WCHAR szKeyStateExt[MAX_PATH+1];
  3660. LPWSTR lpExtId;
  3661. DWORD dwType, dwSize;
  3662. HRESULT hr = S_OK;
  3663. XLastError xe;
  3664. if ( bMachine )
  3665. {
  3666. hr = StringCchPrintf( szKeyStateExt, ARRAYSIZE(szKeyStateExt), GP_STATE_KEY, L"Machine" );
  3667. }
  3668. else
  3669. {
  3670. hr = StringCchPrintf( szKeyStateExt, ARRAYSIZE(szKeyStateExt), GP_STATE_KEY, szSid );
  3671. }
  3672. if (FAILED(hr))
  3673. {
  3674. xe = dwError = HRESULT_CODE(hr);
  3675. return dwError;
  3676. }
  3677. CheckSlash(szKeyStateExt);
  3678. hr = StringCchCat(szKeyStateExt, ARRAYSIZE(szKeyStateExt), EXTENSION);
  3679. if (FAILED(hr))
  3680. {
  3681. xe = dwError = HRESULT_CODE(hr);
  3682. return dwError;
  3683. }
  3684. CheckSlash(szKeyStateExt);
  3685. lpExtId = szExtId ? szExtId : GPCORE_GUID;
  3686. hr = StringCchCat(szKeyStateExt, ARRAYSIZE(szKeyStateExt), lpExtId);
  3687. if (FAILED(hr))
  3688. {
  3689. xe = dwError = HRESULT_CODE(hr);
  3690. return dwError;
  3691. }
  3692. // from this point on, go to exit.
  3693. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3694. szKeyStateExt,
  3695. 0,
  3696. KEY_READ,
  3697. &hKeyExt);
  3698. if ( dwError != ERROR_SUCCESS )
  3699. {
  3700. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to create state key with %d", dwError ) );
  3701. goto Exit;
  3702. }
  3703. dwSize = sizeof(DWORD);
  3704. dwError = RegQueryValueEx(hKeyExt, STARTTIME1, 0, &dwType,
  3705. (BYTE *)(&((lpRsopExtStatus->ftStartTime).dwLowDateTime)),
  3706. &dwSize);
  3707. if ( dwError != ERROR_SUCCESS )
  3708. {
  3709. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to set STARTTIME1 with %d", dwError ) );
  3710. goto Exit;
  3711. }
  3712. dwSize = sizeof(DWORD);
  3713. dwError = RegQueryValueEx(hKeyExt, STARTTIME2, 0, &dwType,
  3714. (BYTE *)(&((lpRsopExtStatus->ftStartTime).dwHighDateTime)),
  3715. &dwSize);
  3716. if ( dwError != ERROR_SUCCESS )
  3717. {
  3718. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to set STARTTIME1 with %d", dwError ) );
  3719. goto Exit;
  3720. }
  3721. dwSize = sizeof(DWORD);
  3722. dwError = RegQueryValueEx(hKeyExt, ENDTIME1, 0, &dwType,
  3723. (BYTE *)(&((lpRsopExtStatus->ftEndTime).dwLowDateTime)),
  3724. &dwSize);
  3725. if ( dwError != ERROR_SUCCESS )
  3726. {
  3727. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to set ENDTIME1 with %d", dwError ) );
  3728. goto Exit;
  3729. }
  3730. dwSize = sizeof(DWORD);
  3731. dwError = RegQueryValueEx(hKeyExt, ENDTIME2, 0, &dwType,
  3732. (BYTE *)(&((lpRsopExtStatus->ftEndTime).dwHighDateTime)),
  3733. &dwSize);
  3734. if ( dwError != ERROR_SUCCESS )
  3735. {
  3736. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to set ENDTIME2 with %d", dwError ) );
  3737. goto Exit;
  3738. }
  3739. dwSize = sizeof(DWORD);
  3740. dwError = RegQueryValueEx(hKeyExt, STATUS, 0, &dwType,
  3741. (BYTE *)(&(lpRsopExtStatus->dwStatus)),
  3742. &dwSize);
  3743. if ( dwError != ERROR_SUCCESS )
  3744. {
  3745. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to set STATUS with %d", dwError ) );
  3746. goto Exit;
  3747. }
  3748. dwSize = sizeof(DWORD);
  3749. dwError = RegQueryValueEx(hKeyExt, LOGSTATUS, 0, &dwType,
  3750. (BYTE *)(&(lpRsopExtStatus->dwLoggingStatus)),
  3751. &dwSize);
  3752. if ( dwError != ERROR_SUCCESS )
  3753. {
  3754. DebugMsg( ( DM_WARNING, L"ReadLoggingStatus: Failed to set LOGSTATUS with %d", dwError ) );
  3755. goto Exit;
  3756. }
  3757. Exit:
  3758. if (hKeyExt)
  3759. RegCloseKey(hKeyExt);
  3760. return dwError;
  3761. }
  3762. #define POLICY_KEY L"Software\\Policies\\Microsoft\\Windows NT\\CurrentVersion\\winlogon"
  3763. #define PREFERENCE_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon"
  3764. #define GP_SYNCFGREFRESH L"SyncForegroundPolicy"
  3765. BOOL WINAPI
  3766. GetFgPolicySetting( HKEY hKeyRoot )
  3767. {
  3768. HKEY hKeyPolicy = 0;
  3769. HKEY hKeyPreference = 0;
  3770. DWORD dwError = ERROR_SUCCESS;
  3771. DWORD dwType = REG_DWORD;
  3772. DWORD dwSize = sizeof( DWORD );
  3773. BOOL bSync = FALSE;
  3774. //
  3775. // async only on Pro
  3776. //
  3777. OSVERSIONINFOEXW version;
  3778. version.dwOSVersionInfoSize = sizeof(version);
  3779. if ( !GetVersionEx( (LPOSVERSIONINFO) &version ) )
  3780. {
  3781. //
  3782. // conservatively assume non Pro SKU
  3783. //
  3784. return TRUE;
  3785. }
  3786. else
  3787. {
  3788. if ( version.wProductType != VER_NT_WORKSTATION )
  3789. {
  3790. //
  3791. // force sync refresh on non Pro SKU
  3792. //
  3793. return TRUE;
  3794. }
  3795. }
  3796. dwError = RegOpenKeyEx( hKeyRoot,
  3797. PREFERENCE_KEY,
  3798. 0,
  3799. KEY_READ,
  3800. &hKeyPreference );
  3801. if ( dwError == ERROR_SUCCESS )
  3802. {
  3803. //
  3804. // read the preference value
  3805. //
  3806. RegQueryValueEx(hKeyPreference,
  3807. GP_SYNCFGREFRESH,
  3808. 0,
  3809. &dwType,
  3810. (LPBYTE) &bSync,
  3811. &dwSize );
  3812. RegCloseKey( hKeyPreference );
  3813. }
  3814. dwError = RegOpenKeyEx( hKeyRoot,
  3815. POLICY_KEY,
  3816. 0,
  3817. KEY_READ,
  3818. &hKeyPolicy );
  3819. if ( dwError == ERROR_SUCCESS )
  3820. {
  3821. //
  3822. // read the policy
  3823. //
  3824. RegQueryValueEx(hKeyPolicy,
  3825. GP_SYNCFGREFRESH,
  3826. 0,
  3827. &dwType,
  3828. (LPBYTE) &bSync,
  3829. &dwSize );
  3830. RegCloseKey( hKeyPolicy );
  3831. }
  3832. return bSync;
  3833. }
  3834. #define PREVREFRESHMODE L"PrevRefreshMode"
  3835. #define NEXTREFRESHMODE L"NextRefreshMode"
  3836. #define PREVREFRESHREASON L"PrevRefreshReason"
  3837. #define NEXTREFRESHREASON L"NextRefreshReason"
  3838. #define STATE_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\State\\"
  3839. DWORD WINAPI
  3840. gpGetFgPolicyRefreshInfo(BOOL bPrev,
  3841. LPWSTR szUserSid,
  3842. LPFgPolicyRefreshInfo pInfo )
  3843. {
  3844. DWORD dwError = ERROR_SUCCESS;
  3845. WCHAR szKeyState[MAX_PATH+1] = STATE_KEY;
  3846. HKEY hKeyState = 0;
  3847. DWORD dwType;
  3848. DWORD dwSize;
  3849. HRESULT hr = S_OK;
  3850. XLastError xe;
  3851. if ( !pInfo )
  3852. {
  3853. return ERROR_INVALID_PARAMETER;
  3854. }
  3855. pInfo->mode = GP_ModeUnknown;
  3856. pInfo->reason = GP_ReasonUnknown;
  3857. //
  3858. // determine the subkey to create
  3859. //
  3860. if ( !szUserSid )
  3861. {
  3862. hr = StringCchCat( szKeyState, ARRAYSIZE(szKeyState), L"Machine" );
  3863. }
  3864. else
  3865. {
  3866. hr = StringCchCat( szKeyState, ARRAYSIZE(szKeyState), szUserSid );
  3867. }
  3868. if (FAILED(hr))
  3869. {
  3870. xe = dwError = HRESULT_CODE(hr);
  3871. return dwError;
  3872. }
  3873. dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  3874. szKeyState,
  3875. 0,
  3876. KEY_READ,
  3877. &hKeyState );
  3878. if ( dwError != ERROR_SUCCESS )
  3879. {
  3880. goto Exit;
  3881. }
  3882. //
  3883. // refresh mode
  3884. //
  3885. dwType = REG_DWORD;
  3886. dwSize = sizeof( DWORD );
  3887. dwError = RegQueryValueEx( hKeyState,
  3888. bPrev ? PREVREFRESHMODE : NEXTREFRESHMODE ,
  3889. 0,
  3890. &dwType,
  3891. (LPBYTE) &pInfo->mode,
  3892. &dwSize );
  3893. if ( dwError != ERROR_SUCCESS )
  3894. {
  3895. goto Exit;
  3896. }
  3897. //
  3898. // refresh reason
  3899. //
  3900. dwType = REG_DWORD;
  3901. dwSize = sizeof( DWORD );
  3902. dwError = RegQueryValueEx( hKeyState,
  3903. bPrev ? PREVREFRESHREASON : NEXTREFRESHREASON ,
  3904. 0,
  3905. &dwType,
  3906. (LPBYTE) &pInfo->reason,
  3907. &dwSize );
  3908. Exit:
  3909. //
  3910. // cleanup
  3911. //
  3912. if ( hKeyState )
  3913. {
  3914. RegCloseKey( hKeyState );
  3915. }
  3916. //
  3917. // assume first logon/startup
  3918. //
  3919. if ( dwError == ERROR_FILE_NOT_FOUND )
  3920. {
  3921. pInfo->mode = GP_ModeSyncForeground;
  3922. pInfo->reason = GP_ReasonFirstPolicy;
  3923. dwError = ERROR_SUCCESS;
  3924. }
  3925. return dwError;
  3926. }
  3927. LPWSTR g_szModes[] =
  3928. {
  3929. L"Unknown",
  3930. L"Synchronous",
  3931. L"Asynchronous",
  3932. };
  3933. LPWSTR g_szReasons[] =
  3934. {
  3935. L"NoNeedForSync",
  3936. L"FirstPolicyRefresh",
  3937. L"CSERequiresForeground",
  3938. L"CSEReturnedError",
  3939. L"ForcedSyncRefresh",
  3940. L"SyncPolicy",
  3941. L"NonCachedCredentials",
  3942. L"SKU",
  3943. };
  3944. DWORD WINAPI
  3945. gpSetFgPolicyRefreshInfo(BOOL bPrev,
  3946. LPWSTR szUserSid,
  3947. FgPolicyRefreshInfo info )
  3948. {
  3949. DWORD dwError = ERROR_SUCCESS;
  3950. WCHAR szKeyState[MAX_PATH+1] = STATE_KEY;
  3951. HKEY hKeyState = 0;
  3952. DWORD dwType = REG_DWORD;
  3953. DWORD dwSize = sizeof( DWORD );
  3954. HRESULT hr = S_OK;
  3955. XLastError xe;
  3956. //
  3957. // determine the subkey to create
  3958. //
  3959. if ( !szUserSid )
  3960. {
  3961. hr = StringCchCat( szKeyState, ARRAYSIZE(szKeyState), L"Machine" );
  3962. }
  3963. else
  3964. {
  3965. hr = StringCchCat( szKeyState, ARRAYSIZE(szKeyState), szUserSid );
  3966. }
  3967. if (FAILED(hr))
  3968. {
  3969. xe = dwError = HRESULT_CODE(hr);
  3970. return dwError;
  3971. }
  3972. dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  3973. szKeyState,
  3974. 0,
  3975. KEY_ALL_ACCESS,
  3976. &hKeyState );
  3977. if ( dwError != ERROR_SUCCESS )
  3978. {
  3979. goto Exit;
  3980. }
  3981. //
  3982. // refresh mode
  3983. //
  3984. dwError = RegSetValueEx(hKeyState,
  3985. bPrev ? PREVREFRESHMODE : NEXTREFRESHMODE ,
  3986. 0,
  3987. REG_DWORD,
  3988. (LPBYTE) &info.mode,
  3989. sizeof( DWORD ) );
  3990. if ( dwError != ERROR_SUCCESS )
  3991. {
  3992. goto Exit;
  3993. }
  3994. //
  3995. // refresh reason
  3996. //
  3997. dwType = REG_DWORD;
  3998. dwSize = sizeof( DWORD );
  3999. dwError = RegSetValueEx(hKeyState,
  4000. bPrev ? PREVREFRESHREASON : NEXTREFRESHREASON ,
  4001. 0,
  4002. REG_DWORD,
  4003. (LPBYTE) &info.reason,
  4004. sizeof( DWORD ) );
  4005. Exit:
  4006. //
  4007. // cleanup
  4008. //
  4009. if ( hKeyState )
  4010. {
  4011. RegCloseKey( hKeyState );
  4012. }
  4013. if ( dwError == ERROR_SUCCESS )
  4014. {
  4015. DebugMsg( ( DM_VERBOSE,
  4016. L"SetFgRefreshInfo: %s %s Fg policy %s, Reason: %s.",
  4017. bPrev ? L"Previous" : L"Next",
  4018. szUserSid ? L"User" : L"Machine",
  4019. g_szModes[info.mode % ARRAYSIZE( g_szModes )],
  4020. g_szReasons[info.reason % ARRAYSIZE( g_szReasons )] ) );
  4021. }
  4022. return dwError;
  4023. }
  4024. USERENVAPI
  4025. DWORD
  4026. WINAPI
  4027. GetPreviousFgPolicyRefreshInfo( LPWSTR szUserSid,
  4028. FgPolicyRefreshInfo* pInfo )
  4029. {
  4030. return gpGetFgPolicyRefreshInfo( TRUE, szUserSid, pInfo );
  4031. }
  4032. USERENVAPI
  4033. DWORD
  4034. WINAPI
  4035. GetNextFgPolicyRefreshInfo( LPWSTR szUserSid,
  4036. FgPolicyRefreshInfo* pInfo )
  4037. {
  4038. return gpGetFgPolicyRefreshInfo( FALSE, szUserSid, pInfo );
  4039. }
  4040. USERENVAPI
  4041. DWORD
  4042. WINAPI
  4043. GetCurrentFgPolicyRefreshInfo( LPWSTR szUserSid,
  4044. FgPolicyRefreshInfo* pInfo )
  4045. {
  4046. return gpGetFgPolicyRefreshInfo( FALSE, szUserSid, pInfo );
  4047. }
  4048. USERENVAPI
  4049. DWORD
  4050. WINAPI
  4051. SetPreviousFgPolicyRefreshInfo( LPWSTR szUserSid,
  4052. FgPolicyRefreshInfo info )
  4053. {
  4054. return gpSetFgPolicyRefreshInfo( TRUE, szUserSid, info );
  4055. }
  4056. USERENVAPI
  4057. DWORD
  4058. WINAPI
  4059. SetNextFgPolicyRefreshInfo( LPWSTR szUserSid,
  4060. FgPolicyRefreshInfo info )
  4061. {
  4062. return gpSetFgPolicyRefreshInfo( FALSE, szUserSid, info );
  4063. }
  4064. USERENVAPI
  4065. DWORD
  4066. WINAPI
  4067. ForceSyncFgPolicy( LPWSTR szUserSid )
  4068. {
  4069. FgPolicyRefreshInfo info = { GP_ReasonSyncForced, GP_ModeSyncForeground };
  4070. return gpSetFgPolicyRefreshInfo( FALSE, szUserSid, info );
  4071. }
  4072. USERENVAPI
  4073. BOOL
  4074. WINAPI
  4075. IsSyncForegroundPolicyRefresh( BOOL bMachine,
  4076. HANDLE hToken )
  4077. {
  4078. BOOL bSyncRefresh;
  4079. DWORD dwError = ERROR_SUCCESS;
  4080. bSyncRefresh = GetFgPolicySetting( HKEY_LOCAL_MACHINE );
  4081. if ( bSyncRefresh )
  4082. {
  4083. //
  4084. // policy sez sync
  4085. //
  4086. DebugMsg( ( DM_VERBOSE, L"IsSyncForegroundPolicyRefresh: Synchronous, Reason: policy set to SYNC" ) );
  4087. return TRUE;
  4088. }
  4089. LPWSTR szSid = !bMachine ? GetSidString( hToken ) : 0;
  4090. FgPolicyRefreshInfo info;
  4091. dwError = GetCurrentFgPolicyRefreshInfo( szSid, &info );
  4092. if ( szSid )
  4093. {
  4094. DeleteSidString( szSid );
  4095. }
  4096. if ( dwError != ERROR_SUCCESS )
  4097. {
  4098. //
  4099. // error reading the refresh mode, treat as sync
  4100. //
  4101. DebugMsg( ( DM_VERBOSE, L"IsSyncForegroundPolicyRefresh: Synchronous, Reason: Error 0x%x ", dwError ) );
  4102. return TRUE;
  4103. }
  4104. bSyncRefresh = ( info.mode == GP_ModeAsyncForeground ) ? FALSE : TRUE;
  4105. DebugMsg( ( DM_VERBOSE,
  4106. L"IsSyncForegroundPolicyRefresh: %s, Reason: %s",
  4107. g_szModes[info.mode % ARRAYSIZE( g_szModes )],
  4108. g_szReasons[info.reason % ARRAYSIZE( g_szReasons )] ) );
  4109. return bSyncRefresh;
  4110. }