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.

2043 lines
52 KiB

  1. #include "gptext.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include "SmartPtr.h"
  6. LPWSTR
  7. StripLinkPrefix( LPWSTR pwszPath )
  8. {
  9. WCHAR wszPrefix[] = L"LDAP://";
  10. INT iPrefixLen = lstrlen( wszPrefix );
  11. WCHAR *pwszPathSuffix;
  12. //
  13. // Strip out prefix to get the canonical path to Som
  14. //
  15. if ( wcslen(pwszPath) <= (DWORD) iPrefixLen ) {
  16. return pwszPath;
  17. }
  18. if ( CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  19. pwszPath, iPrefixLen, wszPrefix, iPrefixLen ) == CSTR_EQUAL ) {
  20. pwszPathSuffix = pwszPath + iPrefixLen;
  21. } else
  22. pwszPathSuffix = pwszPath;
  23. return pwszPathSuffix;
  24. }
  25. HRESULT
  26. SystemTimeToWbemTime( SYSTEMTIME& sysTime, XBStr& xbstrWbemTime )
  27. {
  28. XPtrST<WCHAR> xTemp = new WCHAR[25 + 1];
  29. if ( !xTemp )
  30. {
  31. return E_OUTOFMEMORY;
  32. }
  33. int nRes = wsprintf(xTemp, L"%04d%02d%02d%02d%02d%02d.000000+000",
  34. sysTime.wYear,
  35. sysTime.wMonth,
  36. sysTime.wDay,
  37. sysTime.wHour,
  38. sysTime.wMinute,
  39. sysTime.wSecond);
  40. if ( nRes != 25 )
  41. {
  42. return E_FAIL;
  43. }
  44. xbstrWbemTime = xTemp;
  45. if ( !xbstrWbemTime )
  46. {
  47. return E_OUTOFMEMORY;
  48. }
  49. return S_OK;
  50. }
  51. PSID
  52. GetUserSid( HANDLE UserToken )
  53. {
  54. XPtrLF<TOKEN_USER> pUser;
  55. PTOKEN_USER pTemp;
  56. PSID pSid;
  57. DWORD BytesRequired = 200;
  58. NTSTATUS status;
  59. //
  60. // Allocate space for the user info
  61. //
  62. pUser = (PTOKEN_USER) LocalAlloc( LMEM_FIXED, BytesRequired );
  63. if ( !pUser )
  64. {
  65. return 0;
  66. }
  67. //
  68. // Read in the UserInfo
  69. //
  70. status = NtQueryInformationToken(
  71. UserToken, // Handle
  72. TokenUser, // TokenInformationClass
  73. pUser, // TokenInformation
  74. BytesRequired, // TokenInformationLength
  75. &BytesRequired // ReturnLength
  76. );
  77. if ( status == STATUS_BUFFER_TOO_SMALL )
  78. {
  79. //
  80. // Allocate a bigger buffer and try again.
  81. //
  82. pTemp = (PTOKEN_USER) LocalReAlloc( pUser, BytesRequired, LMEM_MOVEABLE );
  83. if ( !pTemp )
  84. {
  85. return 0;
  86. }
  87. pUser = pTemp;
  88. status = NtQueryInformationToken(
  89. UserToken, // Handle
  90. TokenUser, // TokenInformationClass
  91. pUser, // TokenInformation
  92. BytesRequired, // TokenInformationLength
  93. &BytesRequired // ReturnLength
  94. );
  95. }
  96. if ( !NT_SUCCESS(status) )
  97. {
  98. return 0;
  99. }
  100. BytesRequired = RtlLengthSid(pUser->User.Sid);
  101. pSid = LocalAlloc(LMEM_FIXED, BytesRequired);
  102. if ( !pSid )
  103. {
  104. return NULL;
  105. }
  106. status = RtlCopySid(BytesRequired, pSid, pUser->User.Sid);
  107. if ( !NT_SUCCESS(status) )
  108. {
  109. LocalFree(pSid);
  110. pSid = 0;
  111. }
  112. return pSid;
  113. }
  114. LPWSTR
  115. GetSidString( HANDLE UserToken )
  116. {
  117. NTSTATUS NtStatus;
  118. PSID UserSid;
  119. UNICODE_STRING UnicodeString;
  120. //
  121. // Get the user sid
  122. //
  123. UserSid = GetUserSid( UserToken );
  124. if ( !UserSid )
  125. {
  126. return 0;
  127. }
  128. //
  129. // Convert user SID to a string.
  130. //
  131. NtStatus = RtlConvertSidToUnicodeString(&UnicodeString,
  132. UserSid,
  133. (BOOLEAN)TRUE ); // Allocate
  134. LocalFree( UserSid );
  135. if ( !NT_SUCCESS(NtStatus) )
  136. {
  137. return 0;
  138. }
  139. return UnicodeString.Buffer ;
  140. }
  141. void
  142. DeleteSidString( LPWSTR SidString )
  143. {
  144. UNICODE_STRING String;
  145. RtlInitUnicodeString( &String, SidString );
  146. RtlFreeUnicodeString( &String );
  147. }
  148. DWORD
  149. SecureRegKey( HANDLE hToken,
  150. HKEY hKey )
  151. {
  152. DWORD dwError;
  153. SECURITY_DESCRIPTOR sd;
  154. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  155. PACL pAcl = 0;
  156. PSID psidUser = 0,
  157. psidSystem = 0,
  158. psidAdmin = 0;
  159. DWORD cbAcl, AceIndex;
  160. ACE_HEADER* lpAceHeader;
  161. //
  162. // Create the security descriptor that will be applied to the key
  163. //
  164. if ( hToken )
  165. {
  166. //
  167. // Get the user's sid
  168. //
  169. psidUser = GetUserSid( hToken );
  170. if ( !psidUser )
  171. {
  172. return GetLastError();
  173. }
  174. }
  175. else
  176. {
  177. //
  178. // Get the authenticated users sid
  179. //
  180. if ( !AllocateAndInitializeSid( &authNT,
  181. 1,
  182. SECURITY_AUTHENTICATED_USER_RID,
  183. 0,
  184. 0,
  185. 0,
  186. 0,
  187. 0,
  188. 0,
  189. 0,
  190. &psidUser ) )
  191. {
  192. return GetLastError();
  193. }
  194. }
  195. //
  196. // Get the system sid
  197. //
  198. if ( !AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  199. 0, 0, 0, 0, 0, 0, 0, &psidSystem))
  200. {
  201. dwError = GetLastError();
  202. goto Exit;
  203. }
  204. //
  205. // Get the admin sid
  206. //
  207. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  208. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  209. 0, 0, 0, 0, &psidAdmin))
  210. {
  211. dwError = GetLastError();
  212. goto Exit;
  213. }
  214. //
  215. // Allocate space for the ACL
  216. //
  217. cbAcl = (2 * GetLengthSid (psidUser)) + (2 * GetLengthSid (psidSystem)) +
  218. (2 * GetLengthSid (psidAdmin)) + sizeof(ACL) +
  219. (6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
  220. pAcl = (PACL) GlobalAlloc( GMEM_FIXED, cbAcl );
  221. if ( !pAcl )
  222. {
  223. dwError = GetLastError();
  224. goto Exit;
  225. }
  226. if ( !InitializeAcl( pAcl, cbAcl, ACL_REVISION ) )
  227. {
  228. dwError = GetLastError();
  229. goto Exit;
  230. }
  231. //
  232. // Add Aces for User, System, and Admin. Non-inheritable ACEs first
  233. //
  234. AceIndex = 0;
  235. if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidUser) )
  236. {
  237. dwError = GetLastError();
  238. goto Exit;
  239. }
  240. AceIndex++;
  241. if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidSystem) )
  242. {
  243. dwError = GetLastError();
  244. goto Exit;
  245. }
  246. AceIndex++;
  247. if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidAdmin) )
  248. {
  249. dwError = GetLastError();
  250. goto Exit;
  251. }
  252. //
  253. // Now the inheritable ACEs
  254. //
  255. AceIndex++;
  256. if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidUser) )
  257. {
  258. dwError = GetLastError();
  259. goto Exit;
  260. }
  261. if ( !GetAce(pAcl, AceIndex, (void**) &lpAceHeader) )
  262. {
  263. dwError = GetLastError();
  264. goto Exit;
  265. }
  266. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  267. AceIndex++;
  268. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem))
  269. {
  270. dwError = GetLastError();
  271. goto Exit;
  272. }
  273. if ( !GetAce( pAcl, AceIndex, (void**) &lpAceHeader ) )
  274. {
  275. dwError = GetLastError();
  276. goto Exit;
  277. }
  278. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  279. AceIndex++;
  280. if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin) )
  281. {
  282. dwError = GetLastError();
  283. goto Exit;
  284. }
  285. if ( !GetAce(pAcl, AceIndex, (void**) &lpAceHeader) )
  286. {
  287. dwError = GetLastError();
  288. goto Exit;
  289. }
  290. lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
  291. //
  292. // Put together the security descriptor
  293. //
  294. if ( !InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) )
  295. {
  296. dwError = GetLastError();
  297. goto Exit;
  298. }
  299. if ( !SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE) )
  300. {
  301. dwError = GetLastError();
  302. goto Exit;
  303. }
  304. //
  305. // secure the registry key
  306. //
  307. dwError = RegSetKeySecurity( hKey, DACL_SECURITY_INFORMATION, &sd );
  308. Exit:
  309. //
  310. // LocalFree the sids and acl
  311. //
  312. if ( psidUser )
  313. {
  314. if ( hToken )
  315. {
  316. LocalFree( psidUser );
  317. }
  318. else
  319. {
  320. FreeSid( psidUser );
  321. }
  322. }
  323. if (psidSystem)
  324. {
  325. FreeSid( psidSystem );
  326. }
  327. if (psidAdmin)
  328. {
  329. FreeSid( psidAdmin );
  330. }
  331. if (pAcl)
  332. {
  333. GlobalFree( pAcl );
  334. }
  335. return dwError;
  336. }
  337. #define GPO_SCRIPTS_KEY L"Software\\Policies\\Microsoft\\Windows\\System\\Scripts"
  338. #define GP_STATE_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\State"
  339. #define SCRIPT L"Script"
  340. #define PARAMETERS L"Parameters"
  341. #define EXECTIME L"ExecTime"
  342. #define GPOID L"GPO-ID"
  343. #define SOMID L"SOM-ID"
  344. #define FILESYSPATH L"FileSysPath"
  345. #define DISPLAYNAME L"DisplayName"
  346. #define GPONAME L"GPOName"
  347. #define SCR_STARTUP L"Startup"
  348. #define SCR_SHUTDOWN L"Shutdown"
  349. #define SCR_LOGON L"Logon"
  350. #define SCR_LOGOFF L"Logoff"
  351. DWORD
  352. ScrGPOToReg( LPWSTR szIni,
  353. LPWSTR szScrType,
  354. LPWSTR szGPOName,
  355. LPWSTR szGPOID,
  356. LPWSTR szSOMID,
  357. LPWSTR szFileSysPath,
  358. LPWSTR szDisplayName,
  359. HKEY hKeyPolicy,
  360. HKEY hKeyState,
  361. HANDLE hToken )
  362. {
  363. DWORD dwError = ERROR_SUCCESS;
  364. WIN32_FILE_ATTRIBUTE_DATA fad;
  365. HANDLE hOldToken;
  366. if ( ImpersonateUser( hToken, &hOldToken ) ) {
  367. if ( !GetFileAttributesEx( szIni, GetFileExInfoStandard, &fad ) )
  368. {
  369. return GetLastError();
  370. }
  371. RevertToUser( &hOldToken );
  372. }
  373. else
  374. {
  375. return GetLastError();
  376. }
  377. SYSTEMTIME execTime;
  378. ZeroMemory( &execTime, sizeof( execTime ) );
  379. BOOL bFirst = TRUE;
  380. for( DWORD dwIndex = 0; ; dwIndex++ )
  381. {
  382. WCHAR szTemp[32];
  383. WCHAR szScripts[3*MAX_PATH];
  384. WCHAR szParams[3*MAX_PATH];
  385. XKey hKeyScr;
  386. XKey hKeyScrState;
  387. DWORD dwBytes;
  388. if ( ImpersonateUser( hToken, &hOldToken ) )
  389. {
  390. //
  391. // Get the command line
  392. //
  393. szScripts[0] = 0;
  394. wsprintf( szTemp, L"%dCmdLine", dwIndex );
  395. GetPrivateProfileString(szScrType,
  396. szTemp,
  397. L"",
  398. szScripts,
  399. ARRAYSIZE(szScripts),
  400. szIni );
  401. //
  402. // Get the parameters
  403. //
  404. szParams[0] = 0;
  405. wsprintf( szTemp, L"%dParameters", dwIndex);
  406. GetPrivateProfileString(szScrType,
  407. szTemp,
  408. L"",
  409. szParams,
  410. ARRAYSIZE(szParams),
  411. szIni );
  412. RevertToUser( &hOldToken );
  413. }
  414. else
  415. {
  416. return GetLastError();
  417. }
  418. //
  419. // If the command line is empty, we're finished
  420. //
  421. if ( szScripts[0] == 0 )
  422. {
  423. if ( bFirst )
  424. {
  425. //
  426. // hack error code to detect no scripts
  427. //
  428. return ERROR_INVALID_FUNCTION;
  429. }
  430. break;
  431. }
  432. bFirst = FALSE;
  433. //
  434. // create a subkey for each script in the ini file
  435. //
  436. dwError = RegCreateKeyEx( hKeyPolicy,
  437. _itow( dwIndex, szTemp, 16 ),
  438. 0,
  439. 0,
  440. 0,
  441. KEY_ALL_ACCESS,
  442. 0,
  443. &hKeyScr,
  444. 0 );
  445. if ( dwError != ERROR_SUCCESS )
  446. {
  447. break;
  448. }
  449. //
  450. // create a subkey for each script in the ini file
  451. //
  452. dwError = RegCreateKeyEx( hKeyState,
  453. szTemp,
  454. 0,
  455. 0,
  456. 0,
  457. KEY_ALL_ACCESS,
  458. 0,
  459. &hKeyScrState,
  460. 0 );
  461. if ( dwError != ERROR_SUCCESS )
  462. {
  463. break;
  464. }
  465. //
  466. // script command line
  467. //
  468. dwBytes = sizeof( WCHAR ) * ( wcslen( szScripts ) + 1 );
  469. dwError = RegSetValueEx(hKeyScr,
  470. SCRIPT,
  471. 0,
  472. REG_SZ,
  473. (BYTE*) szScripts,
  474. dwBytes );
  475. if ( dwError != ERROR_SUCCESS )
  476. {
  477. break;
  478. }
  479. dwError = RegSetValueEx(hKeyScrState,
  480. SCRIPT,
  481. 0,
  482. REG_SZ,
  483. (BYTE*) szScripts,
  484. dwBytes );
  485. if ( dwError != ERROR_SUCCESS )
  486. {
  487. break;
  488. }
  489. //
  490. // parameters
  491. //
  492. dwBytes = sizeof( WCHAR ) * ( wcslen( szParams ) + 1 );
  493. dwError = RegSetValueEx(hKeyScr,
  494. PARAMETERS,
  495. 0,
  496. REG_SZ,
  497. (BYTE*) szParams,
  498. dwBytes );
  499. if ( dwError != ERROR_SUCCESS )
  500. {
  501. break;
  502. }
  503. dwError = RegSetValueEx(hKeyScrState,
  504. PARAMETERS,
  505. 0,
  506. REG_SZ,
  507. (BYTE*) szParams,
  508. dwBytes );
  509. if ( dwError != ERROR_SUCCESS )
  510. {
  511. break;
  512. }
  513. //
  514. // execution time
  515. //
  516. dwError = RegSetValueEx(hKeyScr,
  517. EXECTIME,
  518. 0,
  519. REG_QWORD,
  520. (BYTE*) &execTime,
  521. sizeof( execTime ) );
  522. if ( dwError != ERROR_SUCCESS )
  523. {
  524. break;
  525. }
  526. dwError = RegSetValueEx(hKeyScrState,
  527. EXECTIME,
  528. 0,
  529. REG_QWORD,
  530. (BYTE*) &execTime,
  531. sizeof( execTime ) );
  532. if ( dwError != ERROR_SUCCESS )
  533. {
  534. break;
  535. }
  536. }
  537. DWORD dwBytes;
  538. //
  539. // GPOID
  540. //
  541. dwBytes = sizeof( WCHAR ) * ( wcslen( szGPOID ) + 1 );
  542. dwError = RegSetValueEx(hKeyPolicy,
  543. GPOID,
  544. 0,
  545. REG_SZ,
  546. (BYTE*) szGPOID,
  547. dwBytes );
  548. if ( dwError != ERROR_SUCCESS )
  549. {
  550. return dwError;
  551. }
  552. dwError = RegSetValueEx(hKeyState,
  553. GPOID,
  554. 0,
  555. REG_SZ,
  556. (BYTE*) szGPOID,
  557. dwBytes );
  558. if ( dwError != ERROR_SUCCESS )
  559. {
  560. return dwError;
  561. }
  562. //
  563. // SOMID
  564. //
  565. dwBytes = sizeof( WCHAR ) * ( wcslen( szSOMID ) + 1 );
  566. dwError = RegSetValueEx(hKeyPolicy,
  567. SOMID,
  568. 0,
  569. REG_SZ,
  570. (BYTE*) szSOMID,
  571. dwBytes );
  572. if ( dwError != ERROR_SUCCESS )
  573. {
  574. return dwError;
  575. }
  576. dwError = RegSetValueEx(hKeyState,
  577. SOMID,
  578. 0,
  579. REG_SZ,
  580. (BYTE*) szSOMID,
  581. dwBytes );
  582. if ( dwError != ERROR_SUCCESS )
  583. {
  584. return dwError;
  585. }
  586. //
  587. // FILESYSPATH
  588. //
  589. dwBytes = sizeof( WCHAR ) * ( wcslen( szFileSysPath ) + 1 );
  590. dwError = RegSetValueEx(hKeyPolicy,
  591. FILESYSPATH,
  592. 0,
  593. REG_SZ,
  594. (BYTE*) szFileSysPath,
  595. dwBytes );
  596. if ( dwError != ERROR_SUCCESS )
  597. {
  598. return dwError;
  599. }
  600. dwError = RegSetValueEx(hKeyState,
  601. FILESYSPATH,
  602. 0,
  603. REG_SZ,
  604. (BYTE*) szFileSysPath,
  605. dwBytes );
  606. if ( dwError != ERROR_SUCCESS )
  607. {
  608. return dwError;
  609. }
  610. //
  611. // DISPLAYNAME
  612. //
  613. dwBytes = sizeof( WCHAR ) * ( wcslen( szDisplayName ) + 1 );
  614. dwError = RegSetValueEx(hKeyPolicy,
  615. DISPLAYNAME,
  616. 0,
  617. REG_SZ,
  618. (BYTE*) szDisplayName,
  619. dwBytes );
  620. if ( dwError != ERROR_SUCCESS )
  621. {
  622. return dwError;
  623. }
  624. dwError = RegSetValueEx(hKeyState,
  625. DISPLAYNAME,
  626. 0,
  627. REG_SZ,
  628. (BYTE*) szDisplayName,
  629. dwBytes );
  630. if ( dwError != ERROR_SUCCESS )
  631. {
  632. return dwError;
  633. }
  634. //
  635. // GPONAME
  636. //
  637. dwBytes = sizeof( WCHAR ) * ( wcslen( szGPOName ) + 1 );
  638. dwError = RegSetValueEx(hKeyPolicy,
  639. GPONAME,
  640. 0,
  641. REG_SZ,
  642. (BYTE*) szGPOName,
  643. dwBytes );
  644. if ( dwError != ERROR_SUCCESS )
  645. {
  646. return dwError;
  647. }
  648. dwError = RegSetValueEx(hKeyState,
  649. GPONAME,
  650. 0,
  651. REG_SZ,
  652. (BYTE*) szGPOName,
  653. dwBytes );
  654. if ( dwError != ERROR_SUCCESS )
  655. {
  656. return dwError;
  657. }
  658. return dwError;
  659. }
  660. DWORD
  661. ScrGPOListToReg(PGROUP_POLICY_OBJECT pGPO,
  662. BOOL bMachine,
  663. HKEY hKeyRoot,
  664. HKEY hKeyState,
  665. HANDLE hToken )
  666. {
  667. DWORD dwError = ERROR_SUCCESS;
  668. WCHAR szScriptKey[MAX_PATH];
  669. WCHAR szStateKey[MAX_PATH];
  670. WCHAR szFileSysPath[MAX_PATH];
  671. WCHAR szTemp[32];
  672. DWORD dwLogon, dwLogoff, dwStartup, dwShutdown;
  673. dwLogon = dwLogoff = dwStartup = dwShutdown = 0;
  674. //
  675. // for each GPO
  676. //
  677. for ( ; pGPO ; pGPO = pGPO->pNext )
  678. {
  679. XKey hKeyTypePolicy;
  680. XKey hKeyTypeState;
  681. LPWSTR szType;
  682. LPWSTR szGPOID = wcschr( pGPO->lpDSPath, L',' );
  683. if ( szGPOID )
  684. {
  685. szGPOID++;
  686. }
  687. else
  688. {
  689. szGPOID = pGPO->lpDSPath;
  690. }
  691. LPWSTR szSOMID = StripLinkPrefix( pGPO->lpLink );
  692. //
  693. // construct \\<domain-DNS>\SysVol\<domain-DNS>\Policies\{<GPOID>}\Machine\Scripts\Scripts.ini
  694. //
  695. wcscpy( szFileSysPath, pGPO->lpFileSysPath );
  696. wcscat( szFileSysPath, L"\\Scripts\\Scripts.ini");
  697. //
  698. // construct "Software\\Policies\\Microsoft\\Windows\\System\\Scripts\\<Type>\\<Index>"
  699. // hKeyState == "Software\\Microsoft\\Windows\\Group Policy\\State\\Scripts\\<Target>"
  700. // construct hKeyState:"<Type>\\<Index>"
  701. //
  702. wcscpy( szScriptKey, GPO_SCRIPTS_KEY );
  703. if ( bMachine )
  704. {
  705. szType = SCR_STARTUP;
  706. wcscat( szScriptKey, L"\\" SCR_STARTUP L"\\" );
  707. wcscat( szScriptKey, _itow( dwStartup, szTemp, 16 ) );
  708. wcscpy( szStateKey, SCR_STARTUP L"\\" );
  709. wcscat( szStateKey, szTemp );
  710. }
  711. else
  712. {
  713. szType = SCR_LOGON;
  714. wcscat( szScriptKey, L"\\" SCR_LOGON L"\\" );
  715. wcscat( szScriptKey, _itow( dwLogon, szTemp, 16 ) );
  716. wcscpy( szStateKey, SCR_LOGON L"\\" );
  717. wcscat( szStateKey, szTemp );
  718. }
  719. //
  720. // open/create the state key
  721. //
  722. dwError = RegCreateKeyEx( hKeyState,
  723. szStateKey,
  724. 0,
  725. 0,
  726. 0,
  727. KEY_ALL_ACCESS,
  728. 0,
  729. &hKeyTypeState,
  730. 0 );
  731. if ( dwError != ERROR_SUCCESS )
  732. {
  733. break;
  734. }
  735. //
  736. // open/create the script key
  737. //
  738. dwError = RegCreateKeyEx( hKeyRoot,
  739. szScriptKey,
  740. 0,
  741. 0,
  742. 0,
  743. KEY_ALL_ACCESS,
  744. 0,
  745. &hKeyTypePolicy,
  746. 0 );
  747. if ( dwError != ERROR_SUCCESS )
  748. {
  749. break;
  750. }
  751. //
  752. // dump the scripts to the registry
  753. //
  754. dwError = ScrGPOToReg( szFileSysPath,
  755. szType,
  756. pGPO->szGPOName,
  757. szGPOID,
  758. szSOMID,
  759. pGPO->lpFileSysPath,
  760. pGPO->lpDisplayName,
  761. hKeyTypePolicy,
  762. hKeyTypeState,
  763. hToken );
  764. if ( dwError == ERROR_INVALID_FUNCTION )
  765. {
  766. dwError = ERROR_SUCCESS;
  767. RegDelnode( hKeyRoot, szScriptKey );
  768. RegDelnode( hKeyState, szStateKey );
  769. // continue processing
  770. }
  771. else if ( dwError != ERROR_SUCCESS )
  772. {
  773. break;
  774. }
  775. else {
  776. if ( bMachine )
  777. {
  778. dwStartup++;
  779. }
  780. else
  781. {
  782. dwLogon++;
  783. }
  784. }
  785. //
  786. // construct "Software\\Policies\\Microsoft\\Windows\\System\\Scripts\\<Type>\\<Index>"
  787. // hKeyState == "Software\\Microsoft\\Windows\\Group Policy\\State\\Scripts\\<Target>"
  788. // construct hKeyState:"<Type>\\<Index>"
  789. //
  790. wcscpy( szScriptKey, GPO_SCRIPTS_KEY );
  791. if ( bMachine )
  792. {
  793. szType = SCR_SHUTDOWN;
  794. wcscat( szScriptKey, L"\\" SCR_SHUTDOWN L"\\" );
  795. wcscat( szScriptKey, _itow( dwShutdown, szTemp, 16 ) );
  796. wcscpy( szStateKey, SCR_SHUTDOWN L"\\" );
  797. wcscat( szStateKey, szTemp );
  798. }
  799. else
  800. {
  801. szType = SCR_LOGOFF;
  802. wcscat( szScriptKey, L"\\" SCR_LOGOFF L"\\" );
  803. wcscat( szScriptKey, _itow( dwLogoff, szTemp, 16 ) );
  804. wcscpy( szStateKey, SCR_LOGOFF L"\\" );
  805. wcscat( szStateKey, szTemp );
  806. }
  807. //
  808. // open/create the state key
  809. //
  810. dwError = RegCreateKeyEx( hKeyState,
  811. szStateKey,
  812. 0,
  813. 0,
  814. 0,
  815. KEY_ALL_ACCESS,
  816. 0,
  817. &hKeyTypeState,
  818. 0 );
  819. if ( dwError != ERROR_SUCCESS )
  820. {
  821. break;
  822. }
  823. //
  824. // open/create the script key
  825. //
  826. hKeyTypePolicy = 0;
  827. dwError = RegCreateKeyEx( hKeyRoot,
  828. szScriptKey,
  829. 0,
  830. 0,
  831. 0,
  832. KEY_ALL_ACCESS,
  833. 0,
  834. &hKeyTypePolicy,
  835. 0 );
  836. if ( dwError != ERROR_SUCCESS )
  837. {
  838. break;
  839. }
  840. //
  841. // dump the scripts to the registry
  842. //
  843. dwError = ScrGPOToReg( szFileSysPath,
  844. szType,
  845. pGPO->szGPOName,
  846. szGPOID,
  847. szSOMID,
  848. pGPO->lpFileSysPath,
  849. pGPO->lpDisplayName,
  850. hKeyTypePolicy,
  851. hKeyTypeState,
  852. hToken );
  853. if ( dwError == ERROR_INVALID_FUNCTION )
  854. {
  855. dwError = ERROR_SUCCESS;
  856. RegDelnode( hKeyRoot, szScriptKey );
  857. RegDelnode( hKeyState, szStateKey );
  858. // continue processing
  859. }
  860. else if ( dwError != ERROR_SUCCESS )
  861. {
  862. break;
  863. }
  864. else {
  865. if ( bMachine )
  866. {
  867. dwShutdown++;
  868. }
  869. else
  870. {
  871. dwLogoff++;
  872. }
  873. }
  874. }
  875. return dwError;
  876. }
  877. class CGPOScriptsLogger
  878. {
  879. public:
  880. CGPOScriptsLogger( IWbemServices* pServices ) :
  881. m_bInitialized(FALSE),
  882. m_cScripts( 0 ),
  883. m_pServices( pServices )
  884. {
  885. XBStr xsz;
  886. XInterface<IWbemClassObject> xClass;
  887. //
  888. // WBEM version of CF for RSOP_ScriptPolicySetting
  889. // Script Policy Object, RSOP_ScriptPolicySetting in MOF
  890. //
  891. xsz = L"RSOP_ScriptPolicySetting";
  892. if ( !xsz )
  893. return;
  894. HRESULT hr = pServices->GetObject( xsz,
  895. 0L,
  896. 0,
  897. &xClass,
  898. 0 );
  899. if ( FAILED(hr) )
  900. {
  901. return;
  902. }
  903. //
  904. // spawn an instance of RSOP_ScriptPolicySetting
  905. //
  906. hr = xClass->SpawnInstance( 0, &m_pInstSetting );
  907. if ( FAILED (hr) )
  908. {
  909. return;
  910. }
  911. //
  912. // WBEM version of CF for RSOP_ScriptCmd
  913. // individual script commands, RSOP_ScriptCmd in MOF
  914. //
  915. xsz = L"RSOP_ScriptCmd";
  916. if ( !xsz )
  917. {
  918. return;
  919. }
  920. xClass = 0;
  921. hr = pServices->GetObject( xsz,
  922. 0L,
  923. 0,
  924. &xClass,
  925. 0 );
  926. if ( FAILED(hr) )
  927. {
  928. return;
  929. }
  930. //
  931. // spawn an instance of RSOP_ScriptCmd
  932. //
  933. hr = xClass->SpawnInstance( 0, &m_pInstCmd );
  934. if ( FAILED (hr) )
  935. {
  936. return;
  937. }
  938. m_bInitialized = TRUE;
  939. }
  940. BOOL Initialized()
  941. {
  942. return m_bInitialized;
  943. }
  944. DWORD SetGPOID( LPWSTR sz )
  945. {
  946. VARIANT var;
  947. XBStr x = sz;
  948. var.vt = VT_BSTR;
  949. var.bstrVal = x;
  950. return m_pInstSetting->Put( L"GPOID", 0, &var, 0 );
  951. }
  952. DWORD SetID( LPWSTR sz )
  953. {
  954. m_szID = (LPWSTR) LocalAlloc( LPTR, sizeof( WCHAR ) * ( wcslen( sz ) + 1 ) );
  955. if ( !m_szID )
  956. {
  957. return GetLastError();
  958. }
  959. wcscpy( m_szID, sz );
  960. return ERROR_SUCCESS;
  961. }
  962. DWORD SetSOMID( LPWSTR sz )
  963. {
  964. VARIANT var;
  965. XBStr x = sz;
  966. var.vt = VT_BSTR;
  967. var.bstrVal = x;
  968. return m_pInstSetting->Put( L"SOMID", 0, &var, 0 );
  969. }
  970. DWORD SetName( LPWSTR sz )
  971. {
  972. VARIANT var;
  973. XBStr x = sz;
  974. var.vt = VT_BSTR;
  975. var.bstrVal = x;
  976. return m_pInstSetting->Put( L"name", 0, &var, 0 );
  977. }
  978. DWORD SetScriptType( LPWSTR sz )
  979. {
  980. m_szScriptType = (LPWSTR) LocalAlloc( LPTR, ( wcslen( sz ) + 1 ) * sizeof( WCHAR ) );
  981. if ( m_szScriptType )
  982. {
  983. wcscpy( m_szScriptType, sz );
  984. return 0;
  985. }
  986. else
  987. {
  988. return GetLastError();
  989. }
  990. }
  991. DWORD SetScriptOrder( DWORD cOrder )
  992. {
  993. VARIANT var;
  994. var.vt = VT_I4;
  995. var.lVal = cOrder;
  996. return m_pInstSetting->Put( L"ScriptOrder", 0, &var, 0 );
  997. }
  998. DWORD SetScriptCount( DWORD cScripts )
  999. {
  1000. m_cScripts = 0;
  1001. SAFEARRAYBOUND arrayBound[1];
  1002. arrayBound[0].lLbound = 0;
  1003. arrayBound[0].cElements = cScripts;
  1004. //
  1005. // create a SafeArray of RSOP_ScriptCmd
  1006. //
  1007. m_aScripts = SafeArrayCreate( VT_UNKNOWN, 1, arrayBound );
  1008. if ( !m_aScripts )
  1009. {
  1010. return E_OUTOFMEMORY;
  1011. }
  1012. return 0;
  1013. }
  1014. DWORD AddScript( LPWSTR szScript, LPWSTR szParameters, SYSTEMTIME* pExecTime )
  1015. {
  1016. HRESULT hr = S_OK;
  1017. IUnknown* pUnk = 0;
  1018. VARIANT var;
  1019. XBStr xsz;
  1020. XInterface<IWbemClassObject> pClone;
  1021. hr = m_pInstCmd->Clone( &pClone );
  1022. if ( FAILED (hr) )
  1023. {
  1024. return hr;
  1025. }
  1026. var.vt = VT_BSTR;
  1027. xsz = szScript;
  1028. var.bstrVal = xsz;
  1029. hr = pClone->Put( L"Script", 0, &var, 0 );
  1030. if ( FAILED (hr) )
  1031. {
  1032. return hr;
  1033. }
  1034. //
  1035. // set the Arguments field for RSOP_ScriptCmd
  1036. //
  1037. xsz = szParameters;
  1038. var.bstrVal = xsz;
  1039. hr = pClone->Put( L"Arguments", 0, &var, 0 );
  1040. if ( FAILED (hr) )
  1041. {
  1042. return hr;
  1043. }
  1044. //
  1045. // set the executionTime field for RSOP_ScriptCmd
  1046. //
  1047. xsz = 0;
  1048. hr = SystemTimeToWbemTime( *pExecTime, xsz );
  1049. if ( FAILED (hr) )
  1050. {
  1051. return hr;
  1052. }
  1053. var.bstrVal = xsz;
  1054. hr = pClone->Put( L"executionTime", 0, &var, 0 );
  1055. if ( FAILED (hr) )
  1056. {
  1057. return hr;
  1058. }
  1059. hr = pClone->QueryInterface( IID_IUnknown, (void **)&pUnk );
  1060. if ( FAILED (hr) )
  1061. {
  1062. return hr;
  1063. }
  1064. hr = SafeArrayPutElement( m_aScripts, (LONG*) &m_cScripts, pUnk );
  1065. if ( FAILED (hr) )
  1066. {
  1067. pUnk->Release();
  1068. return hr;
  1069. }
  1070. m_cScripts++;
  1071. return hr;
  1072. }
  1073. DWORD Log()
  1074. {
  1075. HRESULT hr;
  1076. VARIANT var;
  1077. XBStr x;
  1078. WCHAR szName[128];
  1079. var.vt = VT_I4;
  1080. var.lVal = 1;
  1081. hr = m_pInstSetting->Put( L"precedence", 0, &var, 0 );
  1082. if ( FAILED (hr) )
  1083. {
  1084. return hr;
  1085. }
  1086. wcscpy( szName, m_szID );
  1087. wcscat( szName, L"-" );
  1088. wcscat( szName, m_szScriptType );
  1089. var.vt = VT_BSTR;
  1090. var.bstrVal = szName;
  1091. hr = m_pInstSetting->Put( L"id", 0, &var, 0 );
  1092. if ( FAILED (hr) )
  1093. {
  1094. return hr;
  1095. }
  1096. DWORD dwType;
  1097. if ( !wcscmp( m_szScriptType, SCR_LOGON ) )
  1098. {
  1099. dwType = 1;
  1100. }
  1101. else if ( !wcscmp( m_szScriptType, SCR_LOGOFF ) )
  1102. {
  1103. dwType = 2;
  1104. }
  1105. else if ( !wcscmp( m_szScriptType, SCR_STARTUP ) )
  1106. {
  1107. dwType = 3;
  1108. }
  1109. else
  1110. {
  1111. dwType = 4;
  1112. }
  1113. var.vt = VT_I4;
  1114. var.lVal = dwType;
  1115. hr = m_pInstSetting->Put( L"ScriptType", 0, &var, 0 );
  1116. if ( FAILED (hr) )
  1117. {
  1118. return hr;
  1119. }
  1120. var.vt = VT_ARRAY | VT_UNKNOWN;
  1121. var.parray = m_aScripts;
  1122. hr = m_pInstSetting->Put( L"ScriptList", 0, &var, 0 );
  1123. if ( FAILED (hr) )
  1124. {
  1125. return hr;
  1126. }
  1127. return m_pServices->PutInstance(m_pInstSetting,
  1128. WBEM_FLAG_CREATE_OR_UPDATE,
  1129. 0,
  1130. 0 );
  1131. }
  1132. private:
  1133. BOOL m_bInitialized;
  1134. XPtrLF<WCHAR> m_szID;
  1135. DWORD m_cScripts;
  1136. IWbemServices* m_pServices;
  1137. XSafeArray m_aScripts;
  1138. XInterface<IWbemClassObject> m_pInstSetting;
  1139. XInterface<IWbemClassObject> m_pInstCmd;
  1140. XPtrLF<WCHAR> m_szScriptType;
  1141. };
  1142. DWORD
  1143. ScrRegGPOToWbem(HKEY hKeyGPO,
  1144. LPWSTR szScrType,
  1145. DWORD dwScriptOrder,
  1146. CGPOScriptsLogger* pLogger )
  1147. {
  1148. DWORD dwError = ERROR_SUCCESS;
  1149. DWORD cSubKeys = 0;
  1150. WCHAR szBuffer[MAX_PATH];
  1151. DWORD dwType;
  1152. DWORD dwSize;
  1153. //
  1154. // ID
  1155. //
  1156. dwType = REG_SZ;
  1157. dwSize = sizeof( szBuffer );
  1158. szBuffer[0] = 0;
  1159. dwError = RegQueryValueEx( hKeyGPO,
  1160. GPONAME,
  1161. 0,
  1162. &dwType,
  1163. (LPBYTE) szBuffer,
  1164. &dwSize );
  1165. if ( dwError != ERROR_SUCCESS )
  1166. {
  1167. return dwError;
  1168. }
  1169. dwError = pLogger->SetID( szBuffer );
  1170. if ( dwError != ERROR_SUCCESS )
  1171. {
  1172. return dwError;
  1173. }
  1174. //
  1175. // GPOID
  1176. //
  1177. dwType = REG_SZ;
  1178. dwSize = sizeof( szBuffer );
  1179. szBuffer[0] = 0;
  1180. dwError = RegQueryValueEx( hKeyGPO,
  1181. GPOID,
  1182. 0,
  1183. &dwType,
  1184. (LPBYTE) szBuffer,
  1185. &dwSize );
  1186. if ( dwError != ERROR_SUCCESS )
  1187. {
  1188. return dwError;
  1189. }
  1190. dwError = pLogger->SetGPOID( szBuffer );
  1191. if ( dwError != ERROR_SUCCESS )
  1192. {
  1193. return dwError;
  1194. }
  1195. //
  1196. // SOMID
  1197. //
  1198. dwType = REG_SZ;
  1199. dwSize = sizeof( szBuffer );
  1200. szBuffer[0] = 0;
  1201. dwError = RegQueryValueEx( hKeyGPO,
  1202. SOMID,
  1203. 0,
  1204. &dwType,
  1205. (LPBYTE) szBuffer,
  1206. &dwSize );
  1207. if ( dwError != ERROR_SUCCESS )
  1208. {
  1209. return dwError;
  1210. }
  1211. dwError = pLogger->SetSOMID( szBuffer );
  1212. if ( dwError != ERROR_SUCCESS )
  1213. {
  1214. return dwError;
  1215. }
  1216. //
  1217. // DISPLAYNAME
  1218. //
  1219. dwType = REG_SZ;
  1220. dwSize = sizeof( szBuffer );
  1221. szBuffer[0] = 0;
  1222. dwError = RegQueryValueEx( hKeyGPO,
  1223. DISPLAYNAME,
  1224. 0,
  1225. &dwType,
  1226. (LPBYTE) szBuffer,
  1227. &dwSize );
  1228. if ( dwError != ERROR_SUCCESS )
  1229. {
  1230. return dwError;
  1231. }
  1232. dwError = pLogger->SetName( szBuffer );
  1233. if ( dwError != ERROR_SUCCESS )
  1234. {
  1235. return dwError;
  1236. }
  1237. //
  1238. // script type
  1239. //
  1240. dwError = pLogger->SetScriptType( szScrType );
  1241. if ( dwError != ERROR_SUCCESS )
  1242. {
  1243. return dwError;
  1244. }
  1245. //
  1246. // script order
  1247. //
  1248. dwError = pLogger->SetScriptOrder( dwScriptOrder );
  1249. if ( dwError != ERROR_SUCCESS )
  1250. {
  1251. return dwError;
  1252. }
  1253. //
  1254. // get the numer of Scripts
  1255. //
  1256. dwError = RegQueryInfoKey( hKeyGPO,
  1257. 0,
  1258. 0,
  1259. 0,
  1260. &cSubKeys,
  1261. 0,
  1262. 0,
  1263. 0,
  1264. 0,
  1265. 0,
  1266. 0,
  1267. 0 );
  1268. if ( dwError != ERROR_SUCCESS )
  1269. {
  1270. return dwError;
  1271. }
  1272. pLogger->SetScriptCount( cSubKeys );
  1273. if ( dwError != ERROR_SUCCESS )
  1274. {
  1275. return dwError;
  1276. }
  1277. //
  1278. // for every Script
  1279. //
  1280. for ( DWORD dwIndex = 0 ; dwIndex < cSubKeys ; dwIndex++ )
  1281. {
  1282. XKey hKeyScript;
  1283. WCHAR szTemp[32];
  1284. SYSTEMTIME execTime;
  1285. WCHAR szScript[MAX_PATH];
  1286. WCHAR szParameters[MAX_PATH];
  1287. //
  1288. // open the Script key
  1289. //
  1290. dwError = RegOpenKeyEx( hKeyGPO,
  1291. _itow( dwIndex, szTemp, 16 ),
  1292. 0,
  1293. KEY_ALL_ACCESS,
  1294. &hKeyScript );
  1295. if ( dwError != ERROR_SUCCESS )
  1296. {
  1297. break;
  1298. }
  1299. //
  1300. // script
  1301. //
  1302. dwType = REG_SZ;
  1303. dwSize = sizeof( szScript );
  1304. szScript[0] = 0;
  1305. dwError = RegQueryValueEx( hKeyScript,
  1306. SCRIPT,
  1307. 0,
  1308. &dwType,
  1309. (LPBYTE) szScript,
  1310. &dwSize );
  1311. if ( dwError != ERROR_SUCCESS )
  1312. {
  1313. break;
  1314. }
  1315. //
  1316. // parameters
  1317. //
  1318. dwType = REG_SZ;
  1319. dwSize = sizeof( szParameters );
  1320. szParameters[0] = 0;
  1321. dwError = RegQueryValueEx( hKeyScript,
  1322. PARAMETERS,
  1323. 0,
  1324. &dwType,
  1325. (LPBYTE) szParameters,
  1326. &dwSize );
  1327. if ( dwError != ERROR_SUCCESS )
  1328. {
  1329. break;
  1330. }
  1331. //
  1332. // exec time
  1333. //
  1334. dwType = REG_QWORD;
  1335. dwSize = sizeof( execTime );
  1336. dwError = RegQueryValueEx( hKeyScript,
  1337. EXECTIME,
  1338. 0,
  1339. &dwType,
  1340. (LPBYTE) &execTime,
  1341. &dwSize );
  1342. if ( dwError != ERROR_SUCCESS )
  1343. {
  1344. break;
  1345. }
  1346. dwError = pLogger->AddScript( szScript, szParameters, &execTime );
  1347. if ( dwError != ERROR_SUCCESS )
  1348. {
  1349. break;
  1350. }
  1351. }
  1352. if ( !FAILED( dwError ) )
  1353. {
  1354. dwError = pLogger->Log();
  1355. }
  1356. return dwError;
  1357. }
  1358. DWORD
  1359. pScrRegGPOListToWbem( LPWSTR szSID,
  1360. LPWSTR szType,
  1361. CGPOScriptsLogger* pLogger )
  1362. {
  1363. DWORD dwError = ERROR_SUCCESS;
  1364. WCHAR szBuffer[MAX_PATH] = L"";
  1365. XKey hKeyType;
  1366. BOOL bMachine = !szSID;
  1367. //
  1368. // open the following key
  1369. // HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State\<Target>\Scripts\Type
  1370. //
  1371. wcscpy( szBuffer, GP_STATE_KEY L"\\" );
  1372. if ( bMachine )
  1373. {
  1374. wcscat( szBuffer, L"Machine\\Scripts\\" );
  1375. }
  1376. else
  1377. {
  1378. wcscat( szBuffer, szSID );
  1379. wcscat( szBuffer, L"\\Scripts\\" );
  1380. }
  1381. wcscat( szBuffer, szType );
  1382. //
  1383. // open the key
  1384. //
  1385. dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1386. szBuffer,
  1387. 0,
  1388. KEY_ALL_ACCESS,
  1389. &hKeyType );
  1390. if ( dwError != ERROR_SUCCESS )
  1391. {
  1392. if ( dwError == ERROR_FILE_NOT_FOUND )
  1393. {
  1394. dwError = ERROR_SUCCESS;
  1395. }
  1396. return dwError;
  1397. }
  1398. DWORD cSubKeys = 0;
  1399. //
  1400. // get the numer of GPOs
  1401. //
  1402. dwError = RegQueryInfoKey( hKeyType,
  1403. 0,
  1404. 0,
  1405. 0,
  1406. &cSubKeys,
  1407. 0,
  1408. 0,
  1409. 0,
  1410. 0,
  1411. 0,
  1412. 0,
  1413. 0 );
  1414. if ( dwError != ERROR_SUCCESS )
  1415. {
  1416. return dwError;
  1417. }
  1418. //
  1419. // for every GPO
  1420. //
  1421. for ( DWORD dwIndex = 0 ; dwIndex < cSubKeys ; dwIndex++ )
  1422. {
  1423. XKey hKeyGPO;
  1424. //
  1425. // open the GPO key
  1426. //
  1427. dwError = RegOpenKeyEx( hKeyType,
  1428. _itow( dwIndex, szBuffer, 16 ),
  1429. 0,
  1430. KEY_ALL_ACCESS,
  1431. &hKeyGPO );
  1432. if ( dwError != ERROR_SUCCESS )
  1433. {
  1434. break;
  1435. }
  1436. //
  1437. // dump all scripts in the GPO into Wbem
  1438. //
  1439. dwError = ScrRegGPOToWbem( hKeyGPO, szType, dwIndex + 1, pLogger );
  1440. if ( dwError != ERROR_SUCCESS )
  1441. {
  1442. break;
  1443. }
  1444. }
  1445. return dwError;
  1446. }
  1447. extern "C" DWORD
  1448. ScrRegGPOListToWbem(LPWSTR szSID,
  1449. IWbemServices* pServices );
  1450. DWORD
  1451. ScrRegGPOListToWbem(LPWSTR szSID,
  1452. IWbemServices* pServices )
  1453. {
  1454. DWORD dwError = ERROR_SUCCESS;
  1455. CGPOScriptsLogger logger( pServices );
  1456. if ( !logger.Initialized() )
  1457. {
  1458. return GetLastError();
  1459. }
  1460. dwError = pScrRegGPOListToWbem( szSID,
  1461. !szSID ? SCR_STARTUP : SCR_LOGON,
  1462. &logger );
  1463. if ( dwError == ERROR_SUCCESS )
  1464. {
  1465. dwError = pScrRegGPOListToWbem( szSID,
  1466. !szSID ? SCR_SHUTDOWN : SCR_LOGOFF,
  1467. &logger );
  1468. }
  1469. return dwError;
  1470. }
  1471. DWORD
  1472. ScrGPOToWbem( LPWSTR szIni,
  1473. LPWSTR szScrType,
  1474. LPWSTR szGPOName,
  1475. LPWSTR szGPOID,
  1476. LPWSTR szSOMID,
  1477. LPWSTR szFileSysPath,
  1478. LPWSTR szDisplayName,
  1479. DWORD& dwScriptOrder,
  1480. HANDLE hToken,
  1481. CGPOScriptsLogger* pLogger )
  1482. {
  1483. DWORD dwError = ERROR_SUCCESS;
  1484. WIN32_FILE_ATTRIBUTE_DATA fad;
  1485. if ( !GetFileAttributesEx( szIni, GetFileExInfoStandard, &fad ) )
  1486. {
  1487. return GetLastError();
  1488. }
  1489. DWORD dwGrantedAccessMask;
  1490. BOOL bAccess = TRUE;
  1491. //
  1492. // Check if the RsopToken has access to this file.
  1493. //
  1494. dwError = RsopFileAccessCheck( szIni,
  1495. (PRSOPTOKEN) hToken,
  1496. GENERIC_READ,
  1497. &dwGrantedAccessMask,
  1498. &bAccess );
  1499. if ( FAILED( dwError ) )
  1500. {
  1501. return dwError;
  1502. }
  1503. if ( !bAccess )
  1504. {
  1505. return ERROR_SUCCESS;
  1506. }
  1507. //
  1508. // GPONAME
  1509. //
  1510. dwError = pLogger->SetID( szGPOName );
  1511. if ( dwError != ERROR_SUCCESS )
  1512. {
  1513. return dwError;
  1514. }
  1515. //
  1516. // GPOID
  1517. //
  1518. dwError = pLogger->SetGPOID( szGPOID );
  1519. if ( dwError != ERROR_SUCCESS )
  1520. {
  1521. return dwError;
  1522. }
  1523. //
  1524. // SOMID
  1525. //
  1526. dwError = pLogger->SetSOMID( szSOMID );
  1527. if ( dwError != ERROR_SUCCESS )
  1528. {
  1529. return dwError;
  1530. }
  1531. //
  1532. // NAME
  1533. //
  1534. dwError = pLogger->SetName( szDisplayName );
  1535. if ( dwError != ERROR_SUCCESS )
  1536. {
  1537. return dwError;
  1538. }
  1539. //
  1540. // script type
  1541. //
  1542. dwError = pLogger->SetScriptType( szScrType );
  1543. if ( dwError != ERROR_SUCCESS )
  1544. {
  1545. return dwError;
  1546. }
  1547. //
  1548. // script order
  1549. //
  1550. dwError = pLogger->SetScriptOrder( dwScriptOrder );
  1551. if ( dwError != ERROR_SUCCESS )
  1552. {
  1553. return dwError;
  1554. }
  1555. //
  1556. // count the number of scripts
  1557. //
  1558. for( DWORD cScripts = 0; ; cScripts++ )
  1559. {
  1560. WCHAR szTemp[32];
  1561. WCHAR szBuffer[3*MAX_PATH];
  1562. //
  1563. // Get the command line
  1564. //
  1565. szBuffer[0] = 0;
  1566. wsprintf( szTemp, L"%dCmdLine", cScripts );
  1567. GetPrivateProfileString(szScrType,
  1568. szTemp,
  1569. L"",
  1570. szBuffer,
  1571. ARRAYSIZE(szBuffer),
  1572. szIni );
  1573. //
  1574. // If the command line is empty, we're finished
  1575. //
  1576. if ( szBuffer[0] == 0 )
  1577. {
  1578. break;
  1579. }
  1580. }
  1581. if ( !cScripts )
  1582. {
  1583. return S_OK;
  1584. }
  1585. else
  1586. {
  1587. dwScriptOrder++;
  1588. }
  1589. //
  1590. // set script count
  1591. //
  1592. pLogger->SetScriptCount( cScripts );
  1593. SYSTEMTIME execTime;
  1594. ZeroMemory( &execTime, sizeof( execTime ) );
  1595. for( DWORD dwIndex = 0; dwIndex < cScripts ; dwIndex++ )
  1596. {
  1597. WCHAR szTemp[32];
  1598. WCHAR szScript[MAX_PATH];
  1599. WCHAR szParams[MAX_PATH];
  1600. //
  1601. // Get the command line
  1602. //
  1603. szScript[0] = 0;
  1604. wsprintf( szTemp, L"%dCmdLine", dwIndex );
  1605. GetPrivateProfileString(szScrType,
  1606. szTemp,
  1607. L"",
  1608. szScript,
  1609. ARRAYSIZE(szScript),
  1610. szIni );
  1611. //
  1612. // If the command line is empty, we're finished
  1613. //
  1614. if ( szScript[0] == 0 )
  1615. {
  1616. break;
  1617. }
  1618. //
  1619. // Get the parameters
  1620. //
  1621. szParams[0] = 0;
  1622. wsprintf( szTemp, L"%dParameters", dwIndex);
  1623. GetPrivateProfileString(szScrType,
  1624. szTemp,
  1625. L"",
  1626. szParams,
  1627. ARRAYSIZE(szParams),
  1628. szIni );
  1629. dwError = pLogger->AddScript( szScript, szParams, &execTime );
  1630. if ( dwError != ERROR_SUCCESS )
  1631. {
  1632. break;
  1633. }
  1634. }
  1635. if ( !FAILED( dwError ) )
  1636. {
  1637. dwError = pLogger->Log();
  1638. }
  1639. return dwError;
  1640. }
  1641. DWORD
  1642. ScrGPOListToWbem( PGROUP_POLICY_OBJECT pGPO,
  1643. BOOL bMachine,
  1644. HANDLE hToken,
  1645. IWbemServices* pServices )
  1646. {
  1647. DWORD dwError = ERROR_SUCCESS;
  1648. CGPOScriptsLogger logger( pServices );
  1649. if ( !logger.Initialized() )
  1650. {
  1651. return GetLastError();
  1652. }
  1653. //
  1654. // for each GPO
  1655. //
  1656. for ( DWORD dwIndex1 = 1, dwIndex2 = 1 ; pGPO ; pGPO = pGPO->pNext )
  1657. {
  1658. WCHAR szBuffer[MAX_PATH];
  1659. WCHAR szTemp[32];
  1660. LPWSTR szType;
  1661. if ( bMachine )
  1662. {
  1663. szType = SCR_STARTUP;
  1664. }
  1665. else
  1666. {
  1667. szType = SCR_LOGON;
  1668. }
  1669. //
  1670. // construct \\<domain-DNS>\SysVol\<domain-DNS>\Policies\{<GPOID>}\Machine\Scripts\Scripts.ini
  1671. //
  1672. wcscpy( szBuffer, pGPO->lpFileSysPath );
  1673. wcscat( szBuffer, L"\\Scripts\\Scripts.ini");
  1674. LPWSTR szGPOID = wcschr( pGPO->lpDSPath, L',' );
  1675. if ( szGPOID )
  1676. {
  1677. szGPOID++;
  1678. }
  1679. LPWSTR szSOMID = StripLinkPrefix( pGPO->lpLink );
  1680. //
  1681. // dump the scripts to the registry
  1682. //
  1683. dwError = ScrGPOToWbem( szBuffer,
  1684. szType,
  1685. pGPO->szGPOName,
  1686. szGPOID,
  1687. szSOMID,
  1688. pGPO->lpFileSysPath,
  1689. pGPO->lpDisplayName,
  1690. dwIndex1,
  1691. hToken,
  1692. &logger );
  1693. if ( dwError != ERROR_SUCCESS )
  1694. {
  1695. break;
  1696. }
  1697. if ( bMachine )
  1698. {
  1699. szType = SCR_SHUTDOWN;
  1700. }
  1701. else
  1702. {
  1703. szType = SCR_LOGOFF;
  1704. }
  1705. //
  1706. // construct \\<domain-DNS>\SysVol\<domain-DNS>\Policies\{<GPOID>}\User\Scripts\Scripts.ini
  1707. //
  1708. wcscpy( szBuffer, pGPO->lpFileSysPath );
  1709. wcscat( szBuffer, L"\\Scripts\\Scripts.ini");
  1710. //
  1711. // dump the scripts to the registry
  1712. //
  1713. dwError = ScrGPOToWbem( szBuffer,
  1714. szType,
  1715. pGPO->szGPOName,
  1716. szGPOID,
  1717. szSOMID,
  1718. pGPO->lpFileSysPath,
  1719. pGPO->lpDisplayName,
  1720. dwIndex2,
  1721. hToken,
  1722. &logger );
  1723. if ( dwError != ERROR_SUCCESS )
  1724. {
  1725. break;
  1726. }
  1727. }
  1728. return dwError;
  1729. }
  1730. DWORD
  1731. ProcessScripts( DWORD dwFlags,
  1732. HANDLE hToken,
  1733. HKEY hKeyRoot,
  1734. PGROUP_POLICY_OBJECT pDeletedGPOList,
  1735. PGROUP_POLICY_OBJECT pChangedGPOList,
  1736. BOOL* pbAbort,
  1737. BOOL bRSoPPlanningMode,
  1738. IWbemServices* pWbemServices,
  1739. HRESULT* phrRsopStatus )
  1740. {
  1741. HANDLE hOldToken;
  1742. DWORD dwError = ERROR_SUCCESS;
  1743. BOOL bMachine = ( dwFlags & GPO_INFO_FLAG_MACHINE ) != 0;
  1744. BOOL bLinkTransition = (dwFlags & GPO_INFO_FLAG_LINKTRANSITION) && (dwFlags & GPO_INFO_FLAG_SLOWLINK);
  1745. if ( bRSoPPlanningMode )
  1746. {
  1747. if ( !bLinkTransition )
  1748. {
  1749. dwError = ScrGPOListToWbem( pChangedGPOList, bMachine, hToken, pWbemServices );
  1750. }
  1751. }
  1752. else
  1753. {
  1754. XKey hKeyState;
  1755. WCHAR szBuffer[MAX_PATH];
  1756. //
  1757. // create and secure the following key
  1758. // HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State\<Target>\Scripts
  1759. //
  1760. wcscpy( szBuffer, GP_STATE_KEY L"\\" );
  1761. if ( bMachine )
  1762. {
  1763. wcscat( szBuffer, L"Machine\\Scripts" );
  1764. }
  1765. else
  1766. {
  1767. LPWSTR szSid = GetSidString( hToken );
  1768. if ( !szSid )
  1769. {
  1770. return GetLastError();
  1771. }
  1772. wcscat( szBuffer, szSid );
  1773. wcscat( szBuffer, L"\\Scripts" );
  1774. DeleteSidString( szSid );
  1775. }
  1776. dwError = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1777. szBuffer,
  1778. 0,
  1779. 0,
  1780. 0,
  1781. KEY_ALL_ACCESS,
  1782. 0,
  1783. &hKeyState,
  1784. 0 );
  1785. if ( dwError != ERROR_SUCCESS )
  1786. {
  1787. return dwError;
  1788. }
  1789. dwError = SecureRegKey( hToken, hKeyState );
  1790. if ( dwError != ERROR_SUCCESS )
  1791. {
  1792. return dwError;
  1793. }
  1794. if ( bMachine )
  1795. {
  1796. //
  1797. // delete the Startup and Shutdown keys
  1798. //
  1799. RegDelnode( hKeyRoot, GPO_SCRIPTS_KEY L"\\" SCR_STARTUP );
  1800. RegDelnode( hKeyRoot, GPO_SCRIPTS_KEY L"\\" SCR_SHUTDOWN );
  1801. RegDelnode( hKeyState, SCR_STARTUP );
  1802. RegDelnode( hKeyState, SCR_SHUTDOWN );
  1803. }
  1804. else
  1805. {
  1806. //
  1807. // delete the Logon and Logoff keys
  1808. //
  1809. RegDelnode( hKeyRoot, GPO_SCRIPTS_KEY L"\\" SCR_LOGON );
  1810. RegDelnode( hKeyRoot, GPO_SCRIPTS_KEY L"\\" SCR_LOGOFF );
  1811. RegDelnode( hKeyState, SCR_LOGON );
  1812. RegDelnode( hKeyState, SCR_LOGOFF );
  1813. }
  1814. dwError = ScrGPOListToReg( pChangedGPOList,
  1815. bMachine,
  1816. hKeyRoot,
  1817. hKeyState,
  1818. hToken );
  1819. }
  1820. return dwError;
  1821. }