Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2289 lines
60 KiB

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