Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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