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.

7475 lines
204 KiB

  1. //*************************************************************
  2. // File name: GPOBJ.CPP
  3. //
  4. // Description: Group Policy Object class
  5. //
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 1998
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #include "main.h"
  13. #include "browser.h"
  14. //
  15. // Help ids
  16. //
  17. DWORD aPropertiesHelpIds[] =
  18. {
  19. IDC_TITLE, IDH_PROP_TITLE,
  20. IDC_DISABLE_COMPUTER, IDH_PROP_DISABLE_COMPUTER,
  21. IDC_DISABLE_USER, IDH_PROP_DISABLE_USER,
  22. 0, 0
  23. };
  24. DWORD aLinkHelpIds[] =
  25. {
  26. IDC_CBDOMAIN, IDH_LINK_DOMAIN,
  27. IDC_ACTION, IDH_LINK_BUTTON,
  28. IDC_RESULTLIST, IDH_LINK_RESULT,
  29. 0, 0
  30. };
  31. DWORD aWQLFilterHelpIds[] =
  32. {
  33. IDC_NONE, IDH_WQL_FILTER_NONE,
  34. IDC_THIS_FILTER, IDH_WQL_FILTER_THIS_FILTER,
  35. IDC_FILTER_NAME, IDH_WQL_FILTER_NAME,
  36. IDC_FILTER_BROWSE, IDH_WQL_FILTER_BROWSE,
  37. 0, 0
  38. };
  39. ///////////////////////////////////////////////////////////////////////////////
  40. // //
  41. // CGroupPolicyObject implementation //
  42. // //
  43. ///////////////////////////////////////////////////////////////////////////////
  44. CGroupPolicyObject::CGroupPolicyObject()
  45. {
  46. InterlockedIncrement(&g_cRefThisDll);
  47. m_cRef = 1;
  48. m_bInitialized = FALSE;
  49. m_pADs = NULL;
  50. m_gpoType = GPOTypeLocal;
  51. m_dwFlags = 0;
  52. m_pName = NULL;
  53. m_pDisplayName = NULL;
  54. m_pMachineName = NULL;
  55. m_pUser = NULL;
  56. m_pMachine = NULL;
  57. m_hinstDSSec = NULL;
  58. m_pfnDSCreateSecurityPage = NULL;
  59. m_pTempFilterString = NULL;
  60. m_pDSPath = NULL;
  61. m_pFileSysPath = NULL;
  62. }
  63. CGroupPolicyObject::~CGroupPolicyObject()
  64. {
  65. CleanUp();
  66. if (m_hinstDSSec)
  67. {
  68. FreeLibrary (m_hinstDSSec);
  69. }
  70. InterlockedDecrement(&g_cRefThisDll);
  71. }
  72. ///////////////////////////////////////////////////////////////////////////////
  73. // //
  74. // CGroupPolicyObject object implementation (IUnknown) //
  75. // //
  76. ///////////////////////////////////////////////////////////////////////////////
  77. HRESULT CGroupPolicyObject::QueryInterface (REFIID riid, void **ppv)
  78. {
  79. if (IsEqualIID(riid, IID_IGroupPolicyObject) || IsEqualIID(riid, IID_IUnknown))
  80. {
  81. *ppv = (LPGROUPPOLICYOBJECT)this;
  82. m_cRef++;
  83. return S_OK;
  84. }
  85. else
  86. {
  87. *ppv = NULL;
  88. return E_NOINTERFACE;
  89. }
  90. }
  91. ULONG CGroupPolicyObject::AddRef (void)
  92. {
  93. return ++m_cRef;
  94. }
  95. ULONG CGroupPolicyObject::Release (void)
  96. {
  97. if (--m_cRef == 0) {
  98. delete this;
  99. return 0;
  100. }
  101. return m_cRef;
  102. }
  103. ///////////////////////////////////////////////////////////////////////////////
  104. // //
  105. // CGroupPolicyObject object implementation (IGroupPolicyObject) //
  106. // //
  107. ///////////////////////////////////////////////////////////////////////////////
  108. //*************************************************************
  109. //
  110. // CGroupPolicyObject::New()
  111. //
  112. // Purpose: Creates a new GPO in the DS
  113. //
  114. // Parameters: pszDomainName - Domain to create GPO in
  115. // pszDisplayName - GPO friendly name (optional)
  116. // dwFlags - Open / creation flags
  117. //
  118. // Note: The domain passed in should be in this format:
  119. // LDAP://DC=domain,DC=company,DC=COM
  120. //
  121. // Return: S_OK if successful
  122. //
  123. //*************************************************************
  124. STDMETHODIMP CGroupPolicyObject::New (LPOLESTR pszDomainName, LPOLESTR pszDisplayName,
  125. DWORD dwFlags)
  126. {
  127. HRESULT hr = E_FAIL;
  128. IADsPathname * pADsPathname = NULL;
  129. BSTR bstrContainer = NULL;
  130. BSTR bstrGPC = NULL;
  131. LPTSTR lpResult = NULL, lpDCName = NULL;
  132. LPTSTR lpEnd = NULL, lpTemp = NULL, lpGPTPath = NULL;
  133. LPTSTR lpForest = NULL;
  134. DWORD dwResult;
  135. GUID guid;
  136. TCHAR szGPOName[50];
  137. TCHAR szTemp[100];
  138. TCHAR szGPOPath[2*MAX_PATH];
  139. WIN32_FILE_ATTRIBUTE_DATA fad;
  140. IADs *pADs = NULL;
  141. ULONG ulNoChars;
  142. PSECURITY_DESCRIPTOR pSD = NULL;
  143. SECURITY_INFORMATION si = (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  144. DACL_SECURITY_INFORMATION);
  145. //
  146. // Check if this object has already been initialized
  147. //
  148. if (m_bInitialized)
  149. {
  150. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Called on an initialized object.")));
  151. return STG_E_INUSE;
  152. }
  153. //
  154. // Check parameters
  155. //
  156. if (!pszDomainName)
  157. {
  158. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Null domain name")));
  159. hr = E_INVALIDARG;
  160. goto Exit;
  161. }
  162. if (CompareString (LOCALE_USER_DEFAULT, NORM_STOP_ON_NULL, TEXT("LDAP://"),
  163. 7, pszDomainName, 7) != CSTR_EQUAL)
  164. {
  165. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Domain name does not start with LDAP://")));
  166. hr = E_INVALIDARG;
  167. goto Exit;
  168. }
  169. //
  170. // Verbose output
  171. //
  172. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Entering with:")));
  173. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Domain Name: %s"), pszDomainName));
  174. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Flags: 0x%x"), dwFlags));
  175. //
  176. // Convert the ADSI domain name into a DNS style name
  177. //
  178. hr = ConvertToDotStyle (pszDomainName, &lpResult);
  179. if (FAILED(hr))
  180. {
  181. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to convert domain name with 0x%x"), hr));
  182. goto Exit;
  183. }
  184. //
  185. // If we are working on the enterprise then we need to get the name of the
  186. // forest.
  187. //
  188. #if FGPO_SUPPORT
  189. if (GPO_OPEN_FOREST == (dwFlags & GPO_OPEN_FOREST))
  190. {
  191. DWORD dwResult = QueryForForestName(NULL,
  192. lpResult,
  193. DS_PDC_REQUIRED | DS_RETURN_DNS_NAME,
  194. &lpTemp);
  195. if (dwResult != ERROR_SUCCESS)
  196. {
  197. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: QueryForestName failed for domain name %s with %d"),
  198. lpResult, dwResult));
  199. hr = HRESULT_FROM_WIN32(dwResult);
  200. goto Exit;
  201. }
  202. int cch = 0;
  203. int n=0;
  204. // count the dots in lpTemp;
  205. while (lpTemp[n])
  206. {
  207. if (L'.' == lpTemp[n])
  208. {
  209. cch++;
  210. }
  211. n++;
  212. }
  213. cch *= 3; // multiply the number of dots by 3;
  214. cch += 11; // add 10 + 1 (for the null)
  215. cch += n; // add the string size;
  216. lpForest = (LPTSTR) LocalAlloc(LPTR, sizeof(WCHAR) * cch);
  217. if (!lpForest)
  218. {
  219. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for forest name with %d"),
  220. GetLastError()));
  221. hr = HRESULT_FROM_WIN32(GetLastError());
  222. goto Exit;
  223. }
  224. NameToPath(lpForest, lpTemp, cch);
  225. // substitute the forest's dot path for the domain's dot path
  226. LocalFree(lpResult);
  227. lpResult = lpTemp;
  228. lpTemp = NULL;
  229. //
  230. // Check to see if we have a domain path to a specific DC.
  231. // If we don't then the string will start "LDAP://DC=".
  232. // The equal sign in particular can only be there if we don't have a specific
  233. // DC so we'll just check for the equal sign.
  234. //
  235. if (*(pszDomainName + 9) != TEXT('='))
  236. {
  237. // we have a path to a specific DC
  238. // need to extract the server path and prepend it to the forest name
  239. lpDCName = ExtractServerName(pszDomainName);
  240. if (!lpDCName)
  241. {
  242. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to extract server name for Forest path")));
  243. hr = HRESULT_FROM_WIN32(GetLastError());
  244. goto Exit;
  245. }
  246. lpTemp = MakeFullPath(lpForest, lpDCName);
  247. if (!lpTemp)
  248. {
  249. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to combine server name with Forest path")));
  250. hr = HRESULT_FROM_WIN32(GetLastError());
  251. goto Exit;
  252. }
  253. // clean up the variables we just borrowed so they can be used later
  254. LocalFree(lpDCName);
  255. lpDCName = NULL;
  256. LocalFree(lpForest);
  257. lpForest = lpTemp;
  258. lpTemp = NULL;
  259. }
  260. // Substitute the path to the forest for the path to the domain
  261. pszDomainName = lpForest;
  262. }
  263. #endif
  264. //
  265. // Check to see if we have a domain path to a specific DC.
  266. // If we don't then the string will start "LDAP://DC=".
  267. // The equal sign in particular can only be there if we don't have a specific
  268. // DC so we'll just check for the equal sign.
  269. //
  270. if (*(pszDomainName + 9) == TEXT('='))
  271. {
  272. //
  273. // Convert LDAP to dot (DN) style
  274. //
  275. hr = ConvertToDotStyle (pszDomainName, &lpTemp);
  276. if (FAILED(hr))
  277. {
  278. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to convert domain name with 0x%x"), hr));
  279. goto Exit;
  280. }
  281. //
  282. // Get the GPO DC for this domain
  283. //
  284. lpDCName = GetDCName (lpTemp, NULL, NULL, FALSE, 0);
  285. if (!lpDCName)
  286. {
  287. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to get DC name with %d"),
  288. GetLastError()));
  289. hr = HRESULT_FROM_WIN32(GetLastError());
  290. goto Exit;
  291. }
  292. //
  293. // Build a fully qualified domain name to a specific DC
  294. //
  295. lpTemp = MakeFullPath (pszDomainName, lpDCName);
  296. if (!lpTemp)
  297. {
  298. hr = HRESULT_FROM_WIN32(GetLastError());
  299. goto Exit;
  300. }
  301. }
  302. else
  303. {
  304. lpDCName = ExtractServerName (pszDomainName);
  305. if (!lpDCName)
  306. {
  307. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to extract server name from ADSI path")));
  308. hr = HRESULT_FROM_WIN32(GetLastError());
  309. goto Exit;
  310. }
  311. ulNoChars = lstrlen(pszDomainName) + 1;
  312. lpTemp = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  313. if (!lpTemp)
  314. {
  315. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for true domain name with %d"),
  316. GetLastError()));
  317. hr = HRESULT_FROM_WIN32(GetLastError());
  318. goto Exit;
  319. }
  320. hr = StringCchCopy (lpTemp, ulNoChars, pszDomainName);
  321. ASSERT(SUCCEEDED(hr));
  322. }
  323. //
  324. // Create a pathname object we can work with
  325. //
  326. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  327. IID_IADsPathname, (LPVOID*)&pADsPathname);
  328. if (FAILED(hr))
  329. {
  330. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create adspathname instance with 0x%x"), hr));
  331. LocalFree (lpTemp);
  332. goto Exit;
  333. }
  334. //
  335. // Add the domain name
  336. //
  337. BSTR bstrTemp = SysAllocString( lpTemp );
  338. if ( bstrTemp == NULL )
  339. {
  340. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR")));
  341. LocalFree(lpTemp);
  342. hr = E_OUTOFMEMORY;
  343. goto Exit;
  344. }
  345. hr = pADsPathname->Set (bstrTemp, ADS_SETTYPE_FULL);
  346. SysFreeString( bstrTemp );
  347. LocalFree (lpTemp);
  348. if (FAILED(hr))
  349. {
  350. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set pathname with 0x%x"), hr));
  351. goto Exit;
  352. }
  353. #if FGPO_SUPPORT
  354. if (GPO_OPEN_FOREST != (dwFlags & GPO_OPEN_FOREST))
  355. {
  356. #endif
  357. //
  358. // Add the system folder to the path unless we're on the enterprise
  359. //
  360. BSTR bstrCNSystem = SysAllocString( TEXT("CN=System") );
  361. if ( bstrCNSystem == NULL )
  362. {
  363. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR")));
  364. hr = E_OUTOFMEMORY;
  365. goto Exit;
  366. }
  367. hr = pADsPathname->AddLeafElement ( bstrCNSystem );
  368. SysFreeString( bstrCNSystem );
  369. if (FAILED(hr))
  370. {
  371. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add system folder with 0x%x"), hr));
  372. goto Exit;
  373. }
  374. #if FGPO_SUPPORT
  375. }
  376. else
  377. {
  378. //
  379. // We're on the enterprise so point at the Configuration folder instead
  380. //
  381. BSTR bstrCNConfiguration = SysAllocString(TEXT("CN=Configuration"));
  382. if ( bstrCNConfiguration == NULL )
  383. {
  384. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR")));
  385. hr = E_OUTOFMEMORY;
  386. goto Exit;
  387. }
  388. hr = pADsPathname->AddLeafElement (bstrCNConfiguration);
  389. SysFreeString( bstrCNConfiguration );
  390. if (FAILED(hr))
  391. {
  392. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add system folder with 0x%x"), hr));
  393. goto Exit;
  394. }
  395. }
  396. #endif
  397. //
  398. // Retreive the container path - this is the path to the parent of the policies folder
  399. //
  400. hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrContainer);
  401. if (FAILED(hr))
  402. {
  403. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to retreive container path with 0x%x"), hr));
  404. goto Exit;
  405. }
  406. //
  407. // Create the Policies container
  408. //
  409. hr = CreateContainer (bstrContainer, TEXT("Policies"), FALSE);
  410. if (FAILED(hr))
  411. {
  412. if (hr != HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS))
  413. {
  414. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the gpo container with 0x%x"), hr));
  415. goto Exit;
  416. }
  417. }
  418. SysFreeString (bstrContainer);
  419. bstrContainer = NULL;
  420. //
  421. // Add the policies container to the path
  422. //
  423. BSTR bstrCNPolicies = SysAllocString(TEXT("CN=Policies"));
  424. if ( bstrCNPolicies == NULL )
  425. {
  426. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR")));
  427. hr = E_OUTOFMEMORY;
  428. goto Exit;
  429. }
  430. hr = pADsPathname->AddLeafElement (bstrCNPolicies);
  431. SysFreeString( bstrCNPolicies );
  432. if (FAILED(hr))
  433. {
  434. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add policies folder with 0x%x"), hr));
  435. goto Exit;
  436. }
  437. //
  438. // Retreive the container path - this is the path to the policies folder
  439. //
  440. hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrContainer);
  441. if (FAILED(hr))
  442. {
  443. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to retreive container path with 0x%x"), hr));
  444. goto Exit;
  445. }
  446. //
  447. // Create a new GPO name (guid)
  448. //
  449. if (FAILED(CoCreateGuid(&guid)))
  450. {
  451. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create GUID.")));
  452. goto Exit;
  453. }
  454. if (!StringFromGUID2 (guid, szGPOName, ARRAYSIZE(szGPOName)))
  455. {
  456. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to convert GUID.")));
  457. goto Exit;
  458. }
  459. //
  460. // Create a container for this GPO
  461. //
  462. hr = CreateContainer (bstrContainer, szGPOName, TRUE);
  463. if (FAILED(hr)) {
  464. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the gpo container with 0x%x"), hr));
  465. goto Exit;
  466. }
  467. SysFreeString (bstrContainer);
  468. bstrContainer = NULL;
  469. //
  470. // Add the GPO name to the path
  471. //
  472. hr = StringCchCopy (szTemp, ARRAYSIZE(szTemp), TEXT("CN="));
  473. if (SUCCEEDED(hr))
  474. {
  475. hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), szGPOName);
  476. }
  477. if (FAILED(hr))
  478. {
  479. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO name with 0x%x"), hr));
  480. goto Exit;
  481. }
  482. bstrTemp = SysAllocString(szTemp);
  483. if ( bstrTemp == NULL )
  484. {
  485. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR")));
  486. hr = E_OUTOFMEMORY;
  487. goto Exit;
  488. }
  489. hr = pADsPathname->AddLeafElement (bstrTemp);
  490. SysFreeString( bstrTemp );
  491. if (FAILED(hr))
  492. {
  493. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add machine folder with 0x%x"), hr));
  494. goto Exit;
  495. }
  496. //
  497. // Retreive the GPC path
  498. //
  499. hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrGPC);
  500. if (FAILED(hr))
  501. {
  502. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to retreive container path with 0x%x"), hr));
  503. goto Exit;
  504. }
  505. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: GPO container path is: %s"), bstrGPC));
  506. //
  507. // Now create the machine and user containers
  508. //
  509. hr = CreateContainer (bstrGPC, MACHINE_SECTION, FALSE);
  510. if (FAILED(hr)) {
  511. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the machine container with 0x%x"), hr));
  512. goto Exit;
  513. }
  514. hr = CreateContainer (bstrGPC, USER_SECTION, FALSE);
  515. if (FAILED(hr)) {
  516. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the user container with 0x%x"), hr));
  517. goto Exit;
  518. }
  519. //
  520. // Prepare the file system storage on the sysvol
  521. //
  522. // Build the name
  523. //
  524. hr = StringCchPrintf (szGPOPath,
  525. ARRAYSIZE(szGPOPath),
  526. TEXT("\\\\%s\\SysVol\\%s\\Policies\\%s"),
  527. lpDCName,
  528. lpResult,
  529. szGPOName);
  530. if (FAILED(hr))
  531. {
  532. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr));
  533. goto Exit;
  534. }
  535. ulNoChars = lstrlen(szGPOPath) + 1;
  536. lpGPTPath = (LPTSTR) LocalAlloc(LPTR, ulNoChars * sizeof(TCHAR));
  537. if (!lpGPTPath)
  538. {
  539. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for GPT path with %d"),
  540. GetLastError()));
  541. hr = HRESULT_FROM_WIN32(GetLastError());
  542. goto Exit;
  543. }
  544. hr = StringCchCopy (lpGPTPath, ulNoChars, szGPOPath);
  545. ASSERT(SUCCEEDED(hr));
  546. if (!CreateNestedDirectory (szGPOPath, NULL))
  547. {
  548. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create file system directory %s with %d"),
  549. szGPOPath, GetLastError()));
  550. hr = HRESULT_FROM_WIN32(GetLastError());
  551. goto Exit;
  552. }
  553. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: File system folder is: %s"), szGPOPath));
  554. //
  555. // Set the security of the sysvol to match the security of the DS
  556. //
  557. // First, enable some security privilages so we can set the owner / sacl information
  558. //
  559. if (!EnableSecurityPrivs())
  560. {
  561. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to enable the security privilages with %d"),
  562. GetLastError()));
  563. hr = HRESULT_FROM_WIN32(GetLastError());
  564. goto Exit;
  565. }
  566. //
  567. // Bind to the GPO
  568. //
  569. hr = OpenDSObject(bstrGPC, IID_IADs, (void **)&pADs);
  570. if (FAILED(hr)) {
  571. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to get gpo IADs interface with 0x%x"), hr));
  572. (void) SetThreadToken(NULL, NULL);
  573. goto Exit;
  574. }
  575. //
  576. // Get the security descriptor from the DS
  577. //
  578. hr = GetSecurityDescriptor (pADs, si, &pSD);
  579. if (FAILED(hr)) {
  580. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to query the security descriptor with 0x%x"), hr));
  581. (void) SetThreadToken(NULL, NULL);
  582. goto Exit;
  583. }
  584. //
  585. // Set the security information on the sysvol
  586. //
  587. dwResult = SetSysvolSecurity (szGPOPath, si, pSD);
  588. if (dwResult != ERROR_SUCCESS)
  589. {
  590. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set sysvol security for %s with %d"),
  591. szGPOPath, dwResult));
  592. hr = HRESULT_FROM_WIN32(dwResult);
  593. (void) SetThreadToken(NULL, NULL);
  594. goto Exit;
  595. }
  596. //
  597. // Reset the security privilages
  598. //
  599. if ( !SetThreadToken(NULL, NULL) )
  600. {
  601. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Call to SetThreadToken failed with %d"), GetLastError()));
  602. hr = HRESULT_FROM_WIN32(GetLastError());
  603. goto Exit;
  604. }
  605. lpEnd = CheckSlash(szGPOPath);
  606. ulNoChars = lstrlen(szGPOPath);
  607. //
  608. // Set the initial version number
  609. //
  610. hr = StringCchCat (szGPOPath, ARRAYSIZE(szGPOPath), TEXT("GPT.INI"));
  611. if (FAILED(hr))
  612. {
  613. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr));
  614. goto Exit;
  615. }
  616. if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"), TEXT("0"),
  617. szGPOPath))
  618. {
  619. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set initial version number for %s with %d"),
  620. szGPOPath, GetLastError()));
  621. hr = HRESULT_FROM_WIN32(GetLastError());
  622. goto Exit;
  623. }
  624. //
  625. // Create the user and machine directories
  626. //
  627. hr = StringCchCopy (lpEnd, ARRAYSIZE(szGPOPath) - ulNoChars, MACHINE_SECTION);
  628. if (FAILED(hr))
  629. {
  630. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr));
  631. goto Exit;
  632. }
  633. if (!CreateNestedDirectory (szGPOPath, NULL))
  634. {
  635. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create machine file system directory %s with %d"),
  636. szGPOPath, GetLastError()));
  637. hr = HRESULT_FROM_WIN32(GetLastError());
  638. goto Exit;
  639. }
  640. hr = StringCchCopy (lpEnd, ARRAYSIZE(szGPOPath) - ulNoChars, USER_SECTION);
  641. if (FAILED(hr))
  642. {
  643. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr));
  644. goto Exit;
  645. }
  646. if (!CreateNestedDirectory (szGPOPath, NULL))
  647. {
  648. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create user file system directory %s with %d"),
  649. szGPOPath, GetLastError()));
  650. hr = HRESULT_FROM_WIN32(GetLastError());
  651. goto Exit;
  652. }
  653. //
  654. // Set the GPO specific information
  655. //
  656. // Note that we use the nameless form of the sysvol path
  657. //
  658. hr = StringCchPrintf (szGPOPath,
  659. ARRAYSIZE(szGPOPath),
  660. TEXT("\\\\%s\\SysVol\\%s\\Policies\\%s"),
  661. lpResult,
  662. lpResult,
  663. szGPOName);
  664. if (FAILED(hr))
  665. {
  666. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr));
  667. goto Exit;
  668. }
  669. hr = SetGPOInfo (bstrGPC, pszDisplayName, szGPOPath);
  670. if (FAILED(hr)) {
  671. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set GPO information with 0x%x"), hr));
  672. goto Exit;
  673. }
  674. //
  675. // Call OpenDSGPO to do the loading work
  676. //
  677. hr = OpenDSGPO(bstrGPC, dwFlags);
  678. Exit:
  679. if (lpForest)
  680. {
  681. LocalFree (lpForest);
  682. }
  683. if (lpDCName)
  684. {
  685. LocalFree (lpDCName);
  686. }
  687. if (lpResult)
  688. {
  689. LocalFree (lpResult);
  690. }
  691. if (bstrContainer)
  692. {
  693. SysFreeString (bstrContainer);
  694. }
  695. if (bstrGPC)
  696. {
  697. if (FAILED(hr))
  698. {
  699. if (FAILED(DSDelnode(bstrGPC)))
  700. {
  701. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to delete GPC with 0x%x"), hr));
  702. }
  703. }
  704. SysFreeString (bstrGPC);
  705. }
  706. if (lpGPTPath)
  707. {
  708. if (FAILED(hr))
  709. {
  710. if (!Delnode(lpGPTPath))
  711. {
  712. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to delete GPT with %d"),
  713. GetLastError()));
  714. }
  715. }
  716. }
  717. if (pADsPathname)
  718. {
  719. pADsPathname->Release();
  720. }
  721. if (pADs)
  722. {
  723. pADs->Release();
  724. }
  725. if (pSD)
  726. {
  727. LocalFree (pSD);
  728. }
  729. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Leaving with a status of 0x%x"), hr));
  730. return hr;
  731. }
  732. //*************************************************************
  733. //
  734. // OpenDSGPO()
  735. //
  736. // Purpose: Opens a DS Group Policy Object
  737. //
  738. // Parameters: pszPath - Path to the GPO to open
  739. // dwFlags - Open / creation flags
  740. //
  741. // Return: S_OK if successful
  742. //
  743. //*************************************************************
  744. STDMETHODIMP CGroupPolicyObject::OpenDSGPO (LPOLESTR pszPath, DWORD dwFlags)
  745. {
  746. HRESULT hr = E_FAIL;
  747. VARIANT var;
  748. IADsPathname * pADsPathname = NULL;
  749. IADsObjectOptions *pOptions = NULL;
  750. BSTR bstrProperty;
  751. BSTR bstrGPOName = NULL;
  752. BSTR bstrContainer;
  753. BSTR bstrDCName;
  754. TCHAR* szUserKeyName = NULL;
  755. TCHAR* szMachineKeyName = NULL;
  756. TCHAR szPath[2*MAX_PATH];
  757. LPTSTR lpTemp;
  758. LPTSTR lpEnd;
  759. LPTSTR pszFullPath = NULL;
  760. DWORD dwResult;
  761. WIN32_FILE_ATTRIBUTE_DATA fad;
  762. DFS_INFO_101 Info101;
  763. LPTSTR lpDCName = NULL;
  764. LPOLESTR pszDomain;
  765. UINT uiSize;
  766. TCHAR szFormat[10];
  767. LPTSTR lpNames[2];
  768. ULONG ulNoChars;
  769. LPTSTR lpDottedDomainName = NULL;
  770. //
  771. // Check if this object has already been initialized
  772. //
  773. if (m_bInitialized)
  774. {
  775. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Called on an uninitialized object.")));
  776. return STG_E_INUSE;
  777. }
  778. //
  779. // Check parameters
  780. //
  781. if (!pszPath)
  782. {
  783. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: NULL GPO name")));
  784. return E_INVALIDARG;
  785. }
  786. if (CompareString (LOCALE_USER_DEFAULT, NORM_STOP_ON_NULL, TEXT("LDAP://"),
  787. 7, pszPath, 7) != CSTR_EQUAL)
  788. {
  789. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: %s does not start with LDAP://"), pszPath));
  790. hr = E_INVALIDARG;
  791. goto Exit;
  792. }
  793. //
  794. // Verbose output
  795. //
  796. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Entering with:")));
  797. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: GPO Path: %s"), pszPath));
  798. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Flags: %d"), dwFlags));
  799. //
  800. // Save the flags
  801. //
  802. m_dwFlags = dwFlags;
  803. //
  804. // Retreive the server name if defined
  805. //
  806. lpDCName = ExtractServerName (pszPath);
  807. if (lpDCName)
  808. {
  809. pszFullPath = pszPath;
  810. }
  811. else
  812. {
  813. //
  814. // Get the domain name
  815. //
  816. pszDomain = GetDomainFromLDAPPath(pszPath);
  817. if (!pszDomain)
  818. {
  819. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get domain name")));
  820. hr = E_FAIL;
  821. goto Exit;
  822. }
  823. //
  824. // Convert LDAP to dot (DN) style
  825. //
  826. hr = ConvertToDotStyle (pszDomain, &lpTemp);
  827. delete [] pszDomain;
  828. if (FAILED(hr))
  829. {
  830. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr));
  831. goto Exit;
  832. }
  833. //
  834. // Get the GPO DC for this domain
  835. //
  836. lpDCName = GetDCName (lpTemp, NULL, NULL, FALSE, 0);
  837. LocalFree (lpTemp);
  838. if (!lpDCName)
  839. {
  840. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get DC name with %d"),
  841. GetLastError()));
  842. hr = HRESULT_FROM_WIN32(GetLastError());
  843. goto Exit;
  844. }
  845. //
  846. // Make the fully qualified path
  847. //
  848. pszFullPath = MakeFullPath (pszPath, lpDCName);
  849. if (!pszFullPath)
  850. {
  851. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to make full GPO path")));
  852. hr = HRESULT_FROM_WIN32(GetLastError());
  853. goto Exit;
  854. }
  855. }
  856. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Using server %s"), lpDCName));
  857. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Using fully qualifed pathname of %s"), pszFullPath));
  858. //
  859. // Save the DC name
  860. //
  861. ulNoChars = lstrlen(lpDCName) + 1;
  862. m_pMachineName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  863. if (!m_pMachineName)
  864. {
  865. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for machine name")));
  866. hr = HRESULT_FROM_WIN32(GetLastError());
  867. goto Exit;
  868. }
  869. hr = StringCchCopy (m_pMachineName, ulNoChars, lpDCName);
  870. ASSERT(SUCCEEDED(hr));
  871. //
  872. // Save the DS path
  873. //
  874. ulNoChars = lstrlen(pszFullPath) + 2;
  875. m_pDSPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  876. if (!m_pDSPath)
  877. {
  878. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for ds path")));
  879. hr = HRESULT_FROM_WIN32(GetLastError());
  880. goto Exit;
  881. }
  882. hr = StringCchCopy (m_pDSPath, ulNoChars, pszFullPath);
  883. ASSERT(SUCCEEDED(hr));
  884. //
  885. // Bind to the DS object. Note we hold on to this bind until
  886. // the object goes away. This way other ADSI calls will go to
  887. // the same DC.
  888. //
  889. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Binding to the object")));
  890. hr = OpenDSObject(m_pDSPath, IID_IADs, (void **)&m_pADs);
  891. if (FAILED(hr))
  892. {
  893. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: OpenDSObject failed with 0x%x"), hr));
  894. goto Exit;
  895. }
  896. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Bound successfully.")));
  897. //
  898. // Check if the user has write permission to the GPO
  899. //
  900. if (!(m_dwFlags & GPO_OPEN_READ_ONLY))
  901. {
  902. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Checking for write access")));
  903. hr = CheckDSWriteAccess ((LPUNKNOWN)m_pADs, TEXT("versionNumber"));
  904. if (FAILED(hr))
  905. {
  906. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: CheckDSWriteAccess failed with 0x%x"), hr));
  907. goto Exit;
  908. }
  909. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Write access granted")));
  910. }
  911. //
  912. // Query for the file system path
  913. //
  914. bstrProperty = SysAllocString (GPT_PATH_PROPERTY);
  915. if (!bstrProperty)
  916. {
  917. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory")));
  918. hr = ERROR_OUTOFMEMORY;
  919. goto Exit;
  920. }
  921. VariantInit(&var);
  922. hr = m_pADs->Get(bstrProperty, &var);
  923. if (FAILED(hr))
  924. {
  925. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to query GPT path with 0x%x"), hr));
  926. SysFreeString (bstrProperty);
  927. VariantClear (&var);
  928. goto Exit;
  929. }
  930. ulNoChars = lstrlen(var.bstrVal) + 2;
  931. m_pFileSysPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  932. if (!m_pFileSysPath)
  933. {
  934. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for gpt path")));
  935. SysFreeString (bstrProperty);
  936. VariantClear (&var);
  937. hr = HRESULT_FROM_WIN32(GetLastError());
  938. goto Exit;
  939. }
  940. hr = StringCchCopy (m_pFileSysPath, ulNoChars, var.bstrVal);
  941. ASSERT(SUCCEEDED(hr));
  942. SysFreeString (bstrProperty);
  943. VariantClear (&var);
  944. //
  945. // Query for the display name
  946. //
  947. bstrProperty = SysAllocString (GPO_NAME_PROPERTY);
  948. if (!bstrProperty)
  949. {
  950. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory")));
  951. hr = ERROR_OUTOFMEMORY;
  952. goto Exit;
  953. }
  954. VariantInit(&var);
  955. hr = m_pADs->Get(bstrProperty, &var);
  956. if (FAILED(hr))
  957. {
  958. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to query for display name with 0x%x"), hr));
  959. SysFreeString (bstrProperty);
  960. VariantClear (&var);
  961. goto Exit;
  962. }
  963. ulNoChars = lstrlen(var.bstrVal) + 1;
  964. m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  965. if (!m_pDisplayName)
  966. {
  967. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for display name")));
  968. SysFreeString (bstrProperty);
  969. VariantClear (&var);
  970. hr = HRESULT_FROM_WIN32(GetLastError());
  971. goto Exit;
  972. }
  973. hr = StringCchCopy (m_pDisplayName, ulNoChars, var.bstrVal);
  974. ASSERT(SUCCEEDED(hr));
  975. SysFreeString (bstrProperty);
  976. VariantClear (&var);
  977. //
  978. // Create a pathname object we can work with
  979. //
  980. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  981. IID_IADsPathname, (LPVOID*)&pADsPathname);
  982. if (FAILED(hr))
  983. {
  984. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to create adspathname instance with 0x%x"), hr));
  985. goto Exit;
  986. }
  987. //
  988. // Add the domain name
  989. //
  990. BSTR bstrDSPath = SysAllocString( m_pDSPath );
  991. if ( bstrDSPath == NULL )
  992. {
  993. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate BSTR memory")));
  994. hr = E_OUTOFMEMORY;
  995. goto Exit;
  996. }
  997. hr = pADsPathname->Set (bstrDSPath, ADS_SETTYPE_FULL);
  998. SysFreeString( bstrDSPath );
  999. if (FAILED(hr))
  1000. {
  1001. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to set pathname with 0x%x"), hr));
  1002. goto Exit;
  1003. }
  1004. //
  1005. // Retrieve the GPO name
  1006. //
  1007. hr = pADsPathname->GetElement (0, &bstrGPOName);
  1008. if (FAILED(hr))
  1009. {
  1010. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to retreive GPO name with 0x%x"), hr));
  1011. goto Exit;
  1012. }
  1013. //
  1014. // Make a copy of the GPO name
  1015. //
  1016. ulNoChars = lstrlen(bstrGPOName) + 1 - 3;
  1017. m_pName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1018. if (!m_pName)
  1019. {
  1020. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for gpo name")));
  1021. hr = HRESULT_FROM_WIN32(GetLastError());
  1022. goto Exit;
  1023. }
  1024. hr = StringCchCopy (m_pName, ulNoChars, (bstrGPOName + 3));
  1025. if (FAILED(hr))
  1026. {
  1027. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy GPO name")));
  1028. goto Exit;
  1029. }
  1030. //
  1031. // Set the ADSI preferred DC.
  1032. //
  1033. hr = m_pADs->QueryInterface(IID_IADsObjectOptions, (void**)&pOptions);
  1034. if (SUCCEEDED(hr))
  1035. {
  1036. //
  1037. // Get the domain name
  1038. //
  1039. pszDomain = GetDomainFromLDAPPath(pszPath);
  1040. if (!pszDomain)
  1041. {
  1042. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get domain name")));
  1043. hr = E_FAIL;
  1044. goto Exit;
  1045. }
  1046. //
  1047. // Convert LDAP to dot (DN) style
  1048. //
  1049. hr = ConvertToDotStyle (pszDomain, &lpTemp);
  1050. delete [] pszDomain;
  1051. if (FAILED(hr))
  1052. {
  1053. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr));
  1054. goto Exit;
  1055. }
  1056. //
  1057. // Build a variant containing the domain and dc names
  1058. //
  1059. VariantInit(&var);
  1060. lpNames[0] = lpTemp;
  1061. lpNames[1] = lpDCName;
  1062. hr = ADsBuildVarArrayStr (lpNames, 2, &var);
  1063. LocalFree (lpTemp);
  1064. if (FAILED(hr))
  1065. {
  1066. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr));
  1067. goto Exit;
  1068. }
  1069. //
  1070. // Set the DC name
  1071. //
  1072. hr = pOptions->SetOption(ADS_PRIVATE_OPTION_SPECIFIC_SERVER, var);
  1073. VariantClear (&var);
  1074. if (FAILED(hr))
  1075. {
  1076. //
  1077. // TODO: Remove this block after lab03 RI's -- or -- remove post whistler beta2
  1078. //
  1079. if (hr == E_ADS_BAD_PARAMETER)
  1080. {
  1081. //
  1082. // Set the DC name the old way
  1083. //
  1084. VariantInit(&var);
  1085. var.vt = VT_BSTR;
  1086. var.bstrVal = SysAllocString (lpDCName);
  1087. if (var.bstrVal)
  1088. {
  1089. hr = pOptions->SetOption(ADS_PRIVATE_OPTION_SPECIFIC_SERVER, var);
  1090. }
  1091. else
  1092. {
  1093. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate bstr DCName string")));
  1094. }
  1095. VariantClear (&var);
  1096. }
  1097. else
  1098. {
  1099. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to set private DC name with 0x%x"), hr));
  1100. }
  1101. }
  1102. pOptions->Release();
  1103. }
  1104. else
  1105. {
  1106. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get DS object options interface with 0x%x"), hr));
  1107. }
  1108. //
  1109. // Ask the MUP to read/write to this DC's sysvol.
  1110. // We first have to get attributes for the nameless path. This causes the MUP's
  1111. // cache to be initialize if it isn't already. Then we can tell
  1112. // the MUP which server to use.
  1113. //
  1114. if (!GetFileAttributesEx (m_pFileSysPath, GetFileExInfoStandard, &fad))
  1115. {
  1116. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: GetFileAttributes for %s FAILED with %d."), m_pFileSysPath, GetLastError()));
  1117. }
  1118. //
  1119. // Now we need to take the full path and trim it down to just
  1120. // domain name \ share
  1121. //
  1122. hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath);
  1123. if (FAILED(hr))
  1124. {
  1125. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy GPO Path")));
  1126. goto Exit;
  1127. }
  1128. if ((szPath[0] != TEXT('\\')) || (szPath[1] != TEXT('\\')))
  1129. {
  1130. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Sysvol path doesn't start with \\\\")));
  1131. goto Exit;
  1132. }
  1133. lpTemp = szPath + 2;
  1134. while (*lpTemp && (*lpTemp != TEXT('\\')))
  1135. lpTemp++;
  1136. if (!(*lpTemp))
  1137. {
  1138. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to find slash between domain name and share")));
  1139. goto Exit;
  1140. }
  1141. lpTemp++;
  1142. while (*lpTemp && (*lpTemp != TEXT('\\')))
  1143. lpTemp++;
  1144. if (!(*lpTemp))
  1145. {
  1146. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to find slash between share and directory")));
  1147. goto Exit;
  1148. }
  1149. *lpTemp = TEXT('\0');
  1150. Info101.State = DFS_STORAGE_STATE_ACTIVE;
  1151. dwResult = NetDfsSetClientInfo (szPath, lpDCName,
  1152. L"SysVol", 101, (LPBYTE)&Info101);
  1153. if (dwResult != NERR_Success)
  1154. {
  1155. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to set %s as the active sysvol with %d"),
  1156. lpDCName, dwResult));
  1157. }
  1158. //
  1159. // Now load the registry information
  1160. //
  1161. if (m_dwFlags & GPO_OPEN_LOAD_REGISTRY)
  1162. {
  1163. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Loading registry files")));
  1164. hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath);
  1165. if (FAILED(hr))
  1166. {
  1167. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy Sysvol path")));
  1168. goto Exit;
  1169. }
  1170. lpEnd = CheckSlash (szPath);
  1171. ulNoChars = lstrlen(szPath);
  1172. //
  1173. // Initialize the user registry (HKCU)
  1174. //
  1175. m_pUser = new CRegistryHive();
  1176. if (!m_pUser)
  1177. {
  1178. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to create User registry")));
  1179. hr = HRESULT_FROM_WIN32(GetLastError());
  1180. goto Exit;
  1181. }
  1182. hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - ulNoChars, USER_SECTION);
  1183. if (SUCCEEDED(hr))
  1184. {
  1185. hr = StringCchCat (lpEnd, ARRAYSIZE(szPath) - ulNoChars, TEXT("\\Registry.pol"));
  1186. }
  1187. if (FAILED(hr))
  1188. {
  1189. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy Sysvol path")));
  1190. goto Exit;
  1191. }
  1192. //
  1193. // Get the domain name
  1194. //
  1195. pszDomain = GetDomainFromLDAPPath(pszPath);
  1196. if (!pszDomain)
  1197. {
  1198. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get domain name")));
  1199. hr = E_FAIL;
  1200. goto Exit;
  1201. }
  1202. //
  1203. // Convert LDAP to dot (DN) style
  1204. //
  1205. hr = ConvertToDotStyle (pszDomain, &lpDottedDomainName);
  1206. delete [] pszDomain;
  1207. if (FAILED(hr))
  1208. {
  1209. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr));
  1210. goto Exit;
  1211. }
  1212. GUID tmpGuid;
  1213. TCHAR szTmpGuid[50];
  1214. hr = CoCreateGuid(&tmpGuid);
  1215. if (FAILED(hr))
  1216. {
  1217. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Registry couldn't create guid")));
  1218. goto Exit;
  1219. }
  1220. if (!StringFromGUID2(tmpGuid, szTmpGuid, ARRAYSIZE(szTmpGuid)))
  1221. {
  1222. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Registry couldn't convert guid to string")));
  1223. goto Exit;
  1224. }
  1225. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Mapping Registry to Guid <%s>"), szTmpGuid));
  1226. //
  1227. // The key name looks like <domain name><a tmp guid><user_section_name>
  1228. //
  1229. DWORD cchUserKeyName = lstrlen( lpDottedDomainName ) + lstrlen( szTmpGuid ) + sizeof(USER_SECTION) / sizeof(WCHAR) + 1;
  1230. szUserKeyName = new TCHAR[ cchUserKeyName ];
  1231. if ( ! szUserKeyName )
  1232. {
  1233. hr = E_OUTOFMEMORY;
  1234. goto Exit;
  1235. }
  1236. hr = StringCchCopy (szUserKeyName, cchUserKeyName, lpDottedDomainName );
  1237. if (SUCCEEDED(hr))
  1238. {
  1239. hr = StringCchCat (szUserKeyName, cchUserKeyName, szTmpGuid);
  1240. }
  1241. if (SUCCEEDED(hr))
  1242. {
  1243. hr = StringCchCat (szUserKeyName, cchUserKeyName, USER_SECTION);
  1244. }
  1245. if (FAILED(hr))
  1246. {
  1247. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy key name")));
  1248. goto Exit;
  1249. }
  1250. hr = m_pUser->Initialize (szPath, szUserKeyName);
  1251. if (FAILED(hr))
  1252. {
  1253. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: User registry failed to initialize")));
  1254. goto Exit;
  1255. }
  1256. //
  1257. // Initialize the machine registry (HKLM)
  1258. //
  1259. m_pMachine = new CRegistryHive();
  1260. if (!m_pMachine)
  1261. {
  1262. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to create machine registry")));
  1263. hr = HRESULT_FROM_WIN32(GetLastError());
  1264. goto Exit;
  1265. }
  1266. hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - ulNoChars, MACHINE_SECTION);
  1267. if (SUCCEEDED(hr))
  1268. {
  1269. hr = StringCchCat (lpEnd, ARRAYSIZE(szPath) - ulNoChars, TEXT("\\Registry.pol"));
  1270. }
  1271. //
  1272. // The key name looks like <domain name><a tmp guid><machine_section_name>
  1273. //
  1274. DWORD cchMachineKeyName = 0;
  1275. if ( SUCCEEDED(hr) )
  1276. {
  1277. cchMachineKeyName = lstrlen( lpDottedDomainName ) + lstrlen( szTmpGuid ) + sizeof(MACHINE_SECTION) / sizeof(WCHAR) + 1;
  1278. szMachineKeyName = new TCHAR[ cchMachineKeyName ];
  1279. if ( ! szMachineKeyName )
  1280. {
  1281. hr = E_OUTOFMEMORY;
  1282. }
  1283. }
  1284. if (SUCCEEDED(hr))
  1285. {
  1286. hr = StringCchCopy (szMachineKeyName, cchMachineKeyName, lpDottedDomainName);
  1287. }
  1288. if (SUCCEEDED(hr))
  1289. {
  1290. hr = StringCchCat (szMachineKeyName, cchMachineKeyName, szTmpGuid);
  1291. }
  1292. if (SUCCEEDED(hr))
  1293. {
  1294. hr = StringCchCat (szMachineKeyName, cchMachineKeyName, MACHINE_SECTION);
  1295. }
  1296. if (FAILED(hr))
  1297. {
  1298. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: Could not copy GPO path")));
  1299. goto Exit;
  1300. }
  1301. hr = m_pMachine->Initialize (szPath, szMachineKeyName);
  1302. if (FAILED(hr))
  1303. {
  1304. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: machine registry failed to initialize")));
  1305. goto Exit;
  1306. }
  1307. }
  1308. //
  1309. // Success
  1310. //
  1311. hr = S_OK;
  1312. Exit:
  1313. if (pADsPathname)
  1314. {
  1315. pADsPathname->Release();
  1316. }
  1317. if (bstrGPOName)
  1318. {
  1319. SysFreeString (bstrGPOName);
  1320. }
  1321. if (lpDCName)
  1322. {
  1323. LocalFree (lpDCName);
  1324. }
  1325. if (lpDottedDomainName)
  1326. {
  1327. LocalFree (lpDottedDomainName );
  1328. }
  1329. if (pszFullPath != pszPath)
  1330. {
  1331. LocalFree (pszFullPath);
  1332. }
  1333. if (SUCCEEDED(hr))
  1334. {
  1335. m_gpoType = GPOTypeDS;
  1336. m_bInitialized = TRUE;
  1337. } else {
  1338. CleanUp();
  1339. }
  1340. delete [] szUserKeyName;
  1341. delete [] szMachineKeyName;
  1342. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Leaving with a status of 0x%x"), hr));
  1343. return hr;
  1344. }
  1345. //*************************************************************
  1346. //
  1347. // OpenLocalMachineGPO()
  1348. //
  1349. // Purpose: Opens this machines GPO
  1350. //
  1351. // Parameters: dwFlags - load flags
  1352. //
  1353. // Return: S_OK if successful
  1354. //
  1355. //*************************************************************
  1356. STDMETHODIMP CGroupPolicyObject::OpenLocalMachineGPO (DWORD dwFlags)
  1357. {
  1358. HRESULT hr = E_FAIL;
  1359. TCHAR szBuffer[MAX_PATH];
  1360. TCHAR szKeyName[100];
  1361. LPTSTR lpEnd;
  1362. TCHAR szPath[MAX_PATH];
  1363. TCHAR szFuncVersion[10];
  1364. UINT uRet = 0;
  1365. ULONG ulNoChars;
  1366. //
  1367. // Check if this object has already been initialized
  1368. //
  1369. if (m_bInitialized)
  1370. {
  1371. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Called on an uninitialized object.")));
  1372. return STG_E_INUSE;
  1373. }
  1374. //
  1375. // Save the flags
  1376. //
  1377. m_dwFlags = dwFlags;
  1378. //
  1379. // Get the path to the local GPO
  1380. //
  1381. ExpandEnvironmentStrings (LOCAL_GPO_DIRECTORY, szBuffer, ARRAYSIZE(szBuffer));
  1382. //
  1383. // Save the file system path
  1384. //
  1385. ulNoChars = lstrlen(szBuffer) + 1;
  1386. m_pFileSysPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1387. if (!m_pFileSysPath)
  1388. {
  1389. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to allocate memory for gpt path")));
  1390. hr = HRESULT_FROM_WIN32(GetLastError());
  1391. goto Exit;
  1392. }
  1393. hr = StringCchCopy (m_pFileSysPath, ulNoChars, szBuffer);
  1394. ASSERT(SUCCEEDED(hr));
  1395. //
  1396. // We disable 32-bit redirection on 64-bit for the local gpo contents -- note
  1397. // that we do not re-enable it, since these files should always be redirected
  1398. // on this thread
  1399. //
  1400. DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szBuffer);
  1401. //
  1402. // Create the directory
  1403. //
  1404. uRet = CreateSecureDirectory (szBuffer);
  1405. if (!uRet)
  1406. {
  1407. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create file system directory %s with %d"),
  1408. szBuffer, GetLastError()));
  1409. hr = HRESULT_FROM_WIN32(GetLastError());
  1410. goto Exit;
  1411. }
  1412. SetFileAttributes (szBuffer, FILE_ATTRIBUTE_HIDDEN);
  1413. //
  1414. // Check if the user has write access to the directory
  1415. //
  1416. if (!(m_dwFlags & GPO_OPEN_READ_ONLY))
  1417. {
  1418. hr = CheckFSWriteAccess (szBuffer);
  1419. if (FAILED(hr))
  1420. {
  1421. if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  1422. {
  1423. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: User does not have write access to this GPO (access denied).")));
  1424. goto Exit;
  1425. }
  1426. else
  1427. {
  1428. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: CheckFSWriteAccess failed with 0x%x"), hr));
  1429. }
  1430. }
  1431. }
  1432. if ( uRet != ERROR_ALREADY_EXISTS )
  1433. {
  1434. hr = StringCchCopy( szPath, ARRAYSIZE(szPath), m_pFileSysPath);
  1435. if (SUCCEEDED(hr))
  1436. {
  1437. lpEnd = CheckSlash(szPath);
  1438. hr = StringCchCat( szPath, ARRAYSIZE(szPath), TEXT("gpt.ini") );
  1439. }
  1440. if (SUCCEEDED(hr))
  1441. {
  1442. hr = StringCchPrintf( szFuncVersion,
  1443. ARRAYSIZE(szFuncVersion),
  1444. TEXT("%d"),
  1445. GPO_FUNCTIONALITY_VERSION );
  1446. }
  1447. if (FAILED(hr))
  1448. {
  1449. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr));
  1450. goto Exit;
  1451. }
  1452. DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szPath);
  1453. if (!WritePrivateProfileString (TEXT("General"), TEXT("gPCFunctionalityVersion"),
  1454. szFuncVersion, szPath))
  1455. {
  1456. hr = HRESULT_FROM_WIN32(GetLastError());
  1457. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to write functionality version with 0x%x"), hr));
  1458. goto Exit;
  1459. }
  1460. }
  1461. lpEnd = CheckSlash(szBuffer);
  1462. ulNoChars = lstrlen(szBuffer);
  1463. //
  1464. // Create the user and machine directories
  1465. //
  1466. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, MACHINE_SECTION);
  1467. if (FAILED(hr))
  1468. {
  1469. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr));
  1470. goto Exit;
  1471. }
  1472. DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szBuffer);
  1473. if (!CreateNestedDirectory (szBuffer, NULL))
  1474. {
  1475. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create machine subdirectory with %d"),
  1476. GetLastError()));
  1477. hr = HRESULT_FROM_WIN32(GetLastError());
  1478. goto Exit;
  1479. }
  1480. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION);
  1481. if (FAILED(hr))
  1482. {
  1483. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr));
  1484. goto Exit;
  1485. }
  1486. DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szBuffer);
  1487. if (!CreateNestedDirectory (szBuffer, NULL))
  1488. {
  1489. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create user subdirectory with %d"),
  1490. GetLastError()));
  1491. hr = HRESULT_FROM_WIN32(GetLastError());
  1492. goto Exit;
  1493. }
  1494. //
  1495. // Load the GPO name
  1496. //
  1497. LoadString (g_hInstance, IDS_LOCAL_NAME, szBuffer, ARRAYSIZE(szBuffer));
  1498. ulNoChars = lstrlen(szBuffer) + 2;
  1499. m_pName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1500. if (!m_pName)
  1501. {
  1502. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to allocate memory for name")));
  1503. hr = HRESULT_FROM_WIN32(GetLastError());
  1504. goto Exit;
  1505. }
  1506. hr = StringCchCopy (m_pName, ulNoChars, szBuffer);
  1507. ASSERT(SUCCEEDED(hr));
  1508. //
  1509. // Load the display name
  1510. //
  1511. LoadString (g_hInstance, IDS_LOCAL_DISPLAY_NAME, szBuffer, ARRAYSIZE(szBuffer));
  1512. ulNoChars = lstrlen(szBuffer) + 2;
  1513. m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1514. if (!m_pDisplayName)
  1515. {
  1516. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to allocate memory for display name")));
  1517. hr = HRESULT_FROM_WIN32(GetLastError());
  1518. goto Exit;
  1519. }
  1520. hr = StringCchCopy (m_pDisplayName, ulNoChars, szBuffer);
  1521. ASSERT(SUCCEEDED(hr));
  1522. //
  1523. // Now load the registry information
  1524. //
  1525. if (m_dwFlags & GPO_OPEN_LOAD_REGISTRY)
  1526. {
  1527. hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), m_pFileSysPath);
  1528. if (FAILED(hr))
  1529. {
  1530. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr));
  1531. goto Exit;
  1532. }
  1533. lpEnd = CheckSlash (szBuffer);
  1534. ulNoChars = lstrlen(szBuffer);
  1535. //
  1536. // Initialize the user registry (HKCU)
  1537. //
  1538. GUID tmpGuid;
  1539. TCHAR szTmpGuid[50];
  1540. hr = CoCreateGuid(&tmpGuid);
  1541. if (FAILED(hr))
  1542. {
  1543. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Registry couldn't create guid")));
  1544. goto Exit;
  1545. }
  1546. if (!StringFromGUID2(tmpGuid, szTmpGuid, ARRAYSIZE(szTmpGuid)))
  1547. {
  1548. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Registry couldn't convert guid to string")));
  1549. goto Exit;
  1550. }
  1551. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Mapping Registry to Guid <%s>"), szTmpGuid));
  1552. m_pUser = new CRegistryHive();
  1553. if (!m_pUser)
  1554. {
  1555. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create User registry")));
  1556. hr = HRESULT_FROM_WIN32(GetLastError());
  1557. goto Exit;
  1558. }
  1559. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION);
  1560. if (SUCCEEDED(hr))
  1561. {
  1562. hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol"));
  1563. }
  1564. if (SUCCEEDED(hr))
  1565. {
  1566. hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid);
  1567. }
  1568. if (SUCCEEDED(hr))
  1569. {
  1570. hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), USER_SECTION);
  1571. }
  1572. if (FAILED(hr))
  1573. {
  1574. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr));
  1575. goto Exit;
  1576. }
  1577. hr = m_pUser->Initialize (szBuffer, szKeyName);
  1578. if (FAILED(hr))
  1579. {
  1580. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: User registry failed to initialize")));
  1581. goto Exit;
  1582. }
  1583. //
  1584. // Initialize the machine registry (HKLM)
  1585. //
  1586. m_pMachine = new CRegistryHive();
  1587. if (!m_pMachine)
  1588. {
  1589. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create machine registry")));
  1590. hr = HRESULT_FROM_WIN32(GetLastError());
  1591. goto Exit;
  1592. }
  1593. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, MACHINE_SECTION);
  1594. if (SUCCEEDED(hr))
  1595. {
  1596. hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol"));
  1597. }
  1598. if (SUCCEEDED(hr))
  1599. {
  1600. hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid);
  1601. }
  1602. if (SUCCEEDED(hr))
  1603. {
  1604. hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), MACHINE_SECTION);
  1605. }
  1606. if (FAILED(hr))
  1607. {
  1608. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr));
  1609. goto Exit;
  1610. }
  1611. hr = m_pMachine->Initialize (szBuffer, szKeyName);
  1612. if (FAILED(hr))
  1613. {
  1614. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: machine registry failed to initialize")));
  1615. goto Exit;
  1616. }
  1617. }
  1618. //
  1619. // Success
  1620. //
  1621. hr = S_OK;
  1622. Exit:
  1623. if (SUCCEEDED(hr))
  1624. {
  1625. m_gpoType = GPOTypeLocal;
  1626. m_bInitialized = TRUE;
  1627. } else {
  1628. CleanUp();
  1629. }
  1630. return hr;
  1631. }
  1632. //*************************************************************
  1633. //
  1634. // OpenRemoteMachineGPO()
  1635. //
  1636. // Purpose: Opens a remote machines GPO
  1637. // dwFlags - load flags
  1638. //
  1639. // Parameters: pszComputerName - name of computer
  1640. //
  1641. // Return: S_OK if successful
  1642. //
  1643. //*************************************************************
  1644. STDMETHODIMP CGroupPolicyObject::OpenRemoteMachineGPO (LPOLESTR pszComputerName,
  1645. DWORD dwFlags)
  1646. {
  1647. HRESULT hr = E_FAIL;
  1648. TCHAR szComputerName[MAX_PATH];
  1649. TCHAR szBuffer[MAX_PATH];
  1650. TCHAR szKeyName[100];
  1651. LPTSTR lpEnd;
  1652. TCHAR szPath[MAX_PATH];
  1653. TCHAR szFuncVersion[10];
  1654. UINT uRet = 0;
  1655. ULONG ulNoChars;
  1656. //
  1657. // Check if this object has already been initialized
  1658. //
  1659. if (m_bInitialized)
  1660. {
  1661. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Called on an uninitialized object.")));
  1662. return STG_E_INUSE;
  1663. }
  1664. //
  1665. // Check parameters
  1666. //
  1667. if (!pszComputerName)
  1668. return E_INVALIDARG;
  1669. //
  1670. // Save the flags
  1671. //
  1672. m_dwFlags = dwFlags;
  1673. //
  1674. // Parse the computer name
  1675. //
  1676. if ((pszComputerName[0] == TEXT('\\')) && (pszComputerName[1] == TEXT('\\')))
  1677. {
  1678. hr = StringCchCopy (szComputerName, ARRAYSIZE(szComputerName), pszComputerName+2);
  1679. }
  1680. else
  1681. {
  1682. hr = StringCchCopy (szComputerName, ARRAYSIZE(szComputerName), pszComputerName);
  1683. }
  1684. if (FAILED(hr))
  1685. {
  1686. return hr;
  1687. }
  1688. //
  1689. // Save the machine name
  1690. //
  1691. ulNoChars = lstrlen(szComputerName) + 1;
  1692. m_pMachineName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1693. if (!m_pMachineName)
  1694. {
  1695. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for machine name")));
  1696. hr = HRESULT_FROM_WIN32(GetLastError());
  1697. goto Exit;
  1698. }
  1699. hr = StringCchCopy (m_pMachineName, ulNoChars, szComputerName);
  1700. ASSERT(SUCCEEDED(hr));
  1701. //
  1702. // Get the path to the local GPO
  1703. //
  1704. hr = StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), REMOTE_GPO_DIRECTORY, szComputerName);
  1705. if (FAILED(hr))
  1706. {
  1707. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy path to local GPO")));
  1708. goto Exit;
  1709. }
  1710. //
  1711. // Save the file system path
  1712. //
  1713. ulNoChars = lstrlen(szBuffer) + 1;
  1714. m_pFileSysPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1715. if (!m_pFileSysPath)
  1716. {
  1717. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for gpt path")));
  1718. hr = HRESULT_FROM_WIN32(GetLastError());
  1719. goto Exit;
  1720. }
  1721. hr = StringCchCopy (m_pFileSysPath, ulNoChars, szBuffer);
  1722. ASSERT(SUCCEEDED(hr));
  1723. //
  1724. // Create the directory
  1725. //
  1726. uRet = CreateSecureDirectory (szBuffer);
  1727. if (!uRet)
  1728. {
  1729. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create file system directory %s with %d"),
  1730. szBuffer, GetLastError()));
  1731. hr = HRESULT_FROM_WIN32(GetLastError());
  1732. goto Exit;
  1733. }
  1734. SetFileAttributes (szBuffer, FILE_ATTRIBUTE_HIDDEN);
  1735. //
  1736. // Check if the user has write access to the directory
  1737. //
  1738. if (!(m_dwFlags & GPO_OPEN_READ_ONLY))
  1739. {
  1740. hr = CheckFSWriteAccess (szBuffer);
  1741. if (FAILED(hr))
  1742. {
  1743. if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  1744. {
  1745. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: User does not have write access to this GPO (access denied).")));
  1746. goto Exit;
  1747. }
  1748. else
  1749. {
  1750. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: CheckFSWriteAccess failed with 0x%x"), hr));
  1751. }
  1752. }
  1753. }
  1754. if ( uRet != ERROR_ALREADY_EXISTS )
  1755. {
  1756. hr = StringCchCopy ( szPath, ARRAYSIZE(szPath), m_pFileSysPath );
  1757. if (SUCCEEDED(hr))
  1758. {
  1759. lpEnd = CheckSlash(szPath);
  1760. hr = StringCchCat ( szPath, ARRAYSIZE(szPath), TEXT("gpt.ini") );
  1761. }
  1762. if (SUCCEEDED(hr))
  1763. {
  1764. hr = StringCchPrintf( szFuncVersion, ARRAYSIZE(szFuncVersion), TEXT("%d"), GPO_FUNCTIONALITY_VERSION );
  1765. }
  1766. if (FAILED(hr))
  1767. {
  1768. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  1769. goto Exit;
  1770. }
  1771. if (!WritePrivateProfileString (TEXT("General"), TEXT("gPCFunctionalityVersion"),
  1772. szFuncVersion, szPath))
  1773. {
  1774. hr = HRESULT_FROM_WIN32(GetLastError());
  1775. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to write functionality version with 0x%x"), hr));
  1776. goto Exit;
  1777. }
  1778. }
  1779. lpEnd = CheckSlash(szBuffer);
  1780. ulNoChars = lstrlen(szBuffer);
  1781. //
  1782. // Create the user and machine directories
  1783. //
  1784. hr = StringCchCat (szBuffer, ARRAYSIZE(szBuffer), MACHINE_SECTION);
  1785. if (FAILED(hr))
  1786. {
  1787. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  1788. goto Exit;
  1789. }
  1790. if (!CreateNestedDirectory (szBuffer, NULL))
  1791. {
  1792. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create machine subdirectory with %d"),
  1793. GetLastError()));
  1794. hr = HRESULT_FROM_WIN32(GetLastError());
  1795. goto Exit;
  1796. }
  1797. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION);
  1798. if (FAILED(hr))
  1799. {
  1800. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  1801. goto Exit;
  1802. }
  1803. if (!CreateNestedDirectory (szBuffer, NULL))
  1804. {
  1805. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create user subdirectory with %d"),
  1806. GetLastError()));
  1807. hr = HRESULT_FROM_WIN32(GetLastError());
  1808. goto Exit;
  1809. }
  1810. //
  1811. // Load the GPO name
  1812. //
  1813. ulNoChars = lstrlen(szComputerName) + 2;
  1814. m_pName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1815. if (!m_pName)
  1816. {
  1817. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for name")));
  1818. hr = HRESULT_FROM_WIN32(GetLastError());
  1819. goto Exit;
  1820. }
  1821. hr = StringCchCopy (m_pName, ulNoChars, szComputerName);
  1822. ASSERT(SUCCEEDED(hr));
  1823. //
  1824. // Load the display name
  1825. //
  1826. ulNoChars = lstrlen(szComputerName) + 2;
  1827. m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1828. if (!m_pDisplayName)
  1829. {
  1830. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for display name")));
  1831. hr = HRESULT_FROM_WIN32(GetLastError());
  1832. goto Exit;
  1833. }
  1834. hr = StringCchCopy (m_pDisplayName, ulNoChars, szComputerName);
  1835. ASSERT(SUCCEEDED(hr));
  1836. //
  1837. // Now load the registry information
  1838. //
  1839. if (m_dwFlags & GPO_OPEN_LOAD_REGISTRY)
  1840. {
  1841. hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), m_pFileSysPath);
  1842. if (FAILED(hr))
  1843. {
  1844. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  1845. goto Exit;
  1846. }
  1847. lpEnd = CheckSlash (szBuffer);
  1848. ulNoChars = lstrlen(szBuffer);
  1849. GUID tmpGuid;
  1850. TCHAR szTmpGuid[50];
  1851. hr = CoCreateGuid(&tmpGuid);
  1852. if (FAILED(hr))
  1853. {
  1854. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Registry couldn't create guid")));
  1855. goto Exit;
  1856. }
  1857. if (!StringFromGUID2(tmpGuid, szTmpGuid, ARRAYSIZE(szTmpGuid)))
  1858. {
  1859. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Registry couldn't convert guid to string")));
  1860. goto Exit;
  1861. }
  1862. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Mapping Registry to Guid <%s>"), szTmpGuid));
  1863. //
  1864. // Initialize the user registry (HKCU)
  1865. //
  1866. m_pUser = new CRegistryHive();
  1867. if (!m_pUser)
  1868. {
  1869. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create User registry")));
  1870. hr = HRESULT_FROM_WIN32(GetLastError());
  1871. goto Exit;
  1872. }
  1873. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION);
  1874. if (SUCCEEDED(hr))
  1875. {
  1876. hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol"));
  1877. }
  1878. if (SUCCEEDED(hr))
  1879. {
  1880. hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid);
  1881. }
  1882. if (SUCCEEDED(hr))
  1883. {
  1884. hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), USER_SECTION);
  1885. }
  1886. if (FAILED(hr))
  1887. {
  1888. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  1889. goto Exit;
  1890. }
  1891. hr = m_pUser->Initialize (szBuffer, szKeyName);
  1892. if (FAILED(hr))
  1893. {
  1894. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: User registry failed to initialize")));
  1895. goto Exit;
  1896. }
  1897. //
  1898. // Initialize the machine registry (HKLM)
  1899. //
  1900. m_pMachine = new CRegistryHive();
  1901. if (!m_pMachine)
  1902. {
  1903. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create machine registry")));
  1904. hr = HRESULT_FROM_WIN32(GetLastError());
  1905. goto Exit;
  1906. }
  1907. hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, MACHINE_SECTION);
  1908. if (SUCCEEDED(hr))
  1909. {
  1910. hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol"));
  1911. }
  1912. if (SUCCEEDED(hr))
  1913. {
  1914. hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid);
  1915. }
  1916. if (SUCCEEDED(hr))
  1917. {
  1918. hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), MACHINE_SECTION);
  1919. }
  1920. if (FAILED(hr))
  1921. {
  1922. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  1923. goto Exit;
  1924. }
  1925. hr = m_pMachine->Initialize (szBuffer, szKeyName);
  1926. if (FAILED(hr))
  1927. {
  1928. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: machine registry failed to initialize")));
  1929. goto Exit;
  1930. }
  1931. }
  1932. //
  1933. // Success
  1934. //
  1935. hr = S_OK;
  1936. Exit:
  1937. if (SUCCEEDED(hr))
  1938. {
  1939. m_gpoType = GPOTypeRemote;
  1940. m_bInitialized = TRUE;
  1941. } else {
  1942. CleanUp();
  1943. }
  1944. return hr;
  1945. }
  1946. //*************************************************************
  1947. //
  1948. // Save()
  1949. //
  1950. // Purpose: Saves the registry information and bumps the
  1951. // version number
  1952. //
  1953. // Parameters: none
  1954. //
  1955. // Return: S_OK if successful
  1956. //
  1957. //*************************************************************
  1958. STDMETHODIMP CGroupPolicyObject::Save (BOOL bMachine, BOOL bAdd, GUID *pGuidExtension, GUID *pGuidSnapin)
  1959. {
  1960. HRESULT hr;
  1961. TCHAR szPath[2*MAX_PATH];
  1962. TCHAR szVersion[25];
  1963. ULONG ulVersion, ulOriginal;
  1964. USHORT uMachine, uUser;
  1965. BSTR bstrName;
  1966. VARIANT var;
  1967. GUID RegistryGuid = REGISTRY_EXTENSION_GUID;
  1968. BOOL bEmpty;
  1969. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::Save: Entering with bMachine = %d and bAdd = %d"),
  1970. bMachine, bAdd));
  1971. if (!m_bInitialized)
  1972. {
  1973. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Called on an uninitialized object.")));
  1974. return OLE_E_BLANK;
  1975. }
  1976. if ( pGuidExtension == 0 || pGuidSnapin == 0 )
  1977. {
  1978. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: One of the guids is null")));
  1979. return ERROR_INVALID_PARAMETER;
  1980. }
  1981. if (m_dwFlags & GPO_OPEN_READ_ONLY)
  1982. {
  1983. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Called on a READ ONLY GPO")));
  1984. return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  1985. }
  1986. //
  1987. // Save registry settings
  1988. //
  1989. if (!CompareGuid (pGuidExtension, &RegistryGuid))
  1990. {
  1991. if (bMachine)
  1992. {
  1993. if (m_pMachine)
  1994. {
  1995. hr = m_pMachine->Save();
  1996. if (FAILED(hr))
  1997. {
  1998. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to save the machine registry with 0x%x"), hr));
  1999. return hr;
  2000. }
  2001. hr = m_pMachine->IsRegistryEmpty(&bEmpty);
  2002. if (SUCCEEDED(hr) && bEmpty)
  2003. {
  2004. bAdd = FALSE;
  2005. }
  2006. else
  2007. {
  2008. bAdd = TRUE;
  2009. }
  2010. }
  2011. }
  2012. else
  2013. {
  2014. if (m_pUser)
  2015. {
  2016. hr = m_pUser->Save();
  2017. if (FAILED(hr))
  2018. {
  2019. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to save the user registry with 0x%x"), hr));
  2020. return hr;
  2021. }
  2022. hr = m_pUser->IsRegistryEmpty(&bEmpty);
  2023. if (SUCCEEDED(hr) && bEmpty)
  2024. {
  2025. bAdd = FALSE;
  2026. }
  2027. else
  2028. {
  2029. bAdd = TRUE;
  2030. }
  2031. }
  2032. }
  2033. }
  2034. XPtrST<TCHAR> xValueIn;
  2035. hr = GetProperty( bMachine ? GPO_MACHEXTENSION_NAMES
  2036. : GPO_USEREXTENSION_NAMES,
  2037. xValueIn );
  2038. if ( FAILED(hr) )
  2039. {
  2040. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to GetProperty with 0x%x"), hr));
  2041. return hr;
  2042. }
  2043. CGuidList guidList;
  2044. hr = guidList.UnMarshallGuids( xValueIn.GetPointer() );
  2045. if ( FAILED(hr) )
  2046. {
  2047. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to unmarshall guids with 0x%x"), hr));
  2048. return hr;
  2049. }
  2050. hr = guidList.Update( bAdd, pGuidExtension, pGuidSnapin );
  2051. if ( FAILED(hr) )
  2052. {
  2053. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to update with 0x%x"), hr));
  2054. return hr;
  2055. }
  2056. if ( guidList.GuidsChanged() )
  2057. {
  2058. XPtrST<TCHAR> xValueOut;
  2059. hr = guidList.MarshallGuids( xValueOut );
  2060. if ( FAILED(hr ) )
  2061. {
  2062. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to marshall guids with 0x%x"), hr));
  2063. return hr;
  2064. }
  2065. hr = SetProperty( bMachine ? GPO_MACHEXTENSION_NAMES
  2066. : GPO_USEREXTENSION_NAMES,
  2067. xValueOut.GetPointer() );
  2068. if ( FAILED(hr ) )
  2069. {
  2070. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to set property guids with 0x%x"), hr));
  2071. return hr;
  2072. }
  2073. }
  2074. //
  2075. // Get the current version number
  2076. //
  2077. hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath);
  2078. if (SUCCEEDED(hr))
  2079. {
  2080. hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("\\GPT.INI"));
  2081. }
  2082. if (FAILED(hr))
  2083. {
  2084. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path")));
  2085. return hr;
  2086. }
  2087. if (m_gpoType == GPOTypeDS)
  2088. {
  2089. bstrName = SysAllocString (GPO_VERSION_PROPERTY);
  2090. if (!bstrName)
  2091. {
  2092. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to allocate memory")));
  2093. return E_OUTOFMEMORY;
  2094. }
  2095. VariantInit(&var);
  2096. hr = m_pADs->Get(bstrName, &var);
  2097. if (SUCCEEDED(hr))
  2098. {
  2099. ulOriginal = var.lVal;
  2100. }
  2101. SysFreeString (bstrName);
  2102. VariantClear (&var);
  2103. if (FAILED(hr))
  2104. {
  2105. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to get ds version number with 0x%x"), hr));
  2106. return hr;
  2107. }
  2108. }
  2109. else
  2110. {
  2111. //
  2112. // We disable 32-bit redirection on 64-bit for the local gpt.ini -- note
  2113. // that we do not re-enable it, since this file should always be redirected
  2114. // on this thread
  2115. //
  2116. DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szPath)
  2117. ulOriginal = GetPrivateProfileInt(TEXT("General"), TEXT("Version"), 0, szPath);
  2118. }
  2119. //
  2120. // Separate the user and machine version numbers
  2121. //
  2122. uUser = (USHORT) HIWORD(ulOriginal);
  2123. uMachine = (USHORT) LOWORD(ulOriginal);
  2124. //
  2125. // Increment the version number
  2126. //
  2127. if (bMachine)
  2128. {
  2129. uMachine = uMachine + 1;
  2130. if (uMachine == 0)
  2131. uMachine++;
  2132. }
  2133. else
  2134. {
  2135. uUser = uUser + 1;
  2136. if (uUser == 0)
  2137. uUser++;
  2138. }
  2139. //
  2140. // Put the version number back together
  2141. //
  2142. ulVersion = (ULONG) MAKELONG (uMachine, uUser);
  2143. //
  2144. // Update version number in the GPT
  2145. //
  2146. hr = StringCchPrintf (szVersion, ARRAYSIZE(szVersion), TEXT("%d"), ulVersion);
  2147. if (FAILED(hr))
  2148. {
  2149. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO version")));
  2150. return hr;
  2151. }
  2152. if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"),
  2153. szVersion, szPath))
  2154. {
  2155. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to write sysvol version number with %d"),
  2156. GetLastError()));
  2157. return HRESULT_FROM_WIN32(GetLastError());
  2158. }
  2159. //
  2160. // Put the original version number in szVersion in case
  2161. // we need to roll backwards below
  2162. //
  2163. hr = StringCchPrintf (szVersion, ARRAYSIZE(szVersion), TEXT("%d"), ulOriginal);
  2164. if (FAILED(hr))
  2165. {
  2166. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO original version")));
  2167. return hr;
  2168. }
  2169. //
  2170. // Set the version number in the GPC
  2171. //
  2172. if (m_gpoType == GPOTypeDS)
  2173. {
  2174. bstrName = SysAllocString (GPO_VERSION_PROPERTY);
  2175. if (bstrName)
  2176. {
  2177. VariantInit(&var);
  2178. var.vt = VT_I4;
  2179. var.lVal = ulVersion;
  2180. hr = m_pADs->Put(bstrName, var);
  2181. VariantClear (&var);
  2182. SysFreeString (bstrName);
  2183. }
  2184. else
  2185. {
  2186. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to allocate memory")));
  2187. hr = E_OUTOFMEMORY;
  2188. }
  2189. if (SUCCEEDED(hr))
  2190. {
  2191. //
  2192. // Commit the changes
  2193. //
  2194. hr = m_pADs->SetInfo();
  2195. if (FAILED(hr))
  2196. {
  2197. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to commit version number update with 0x%x"), hr));
  2198. if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"),
  2199. szVersion, szPath))
  2200. {
  2201. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to reset the sysvol version number with %d"),
  2202. GetLastError()));
  2203. }
  2204. }
  2205. } else {
  2206. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to update version number with 0x%x"), hr));
  2207. if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"), szVersion, szPath))
  2208. {
  2209. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to reset the sysvol version number with %d"),
  2210. GetLastError()));
  2211. }
  2212. }
  2213. }
  2214. //
  2215. // If we are editing the local group policy object, then call
  2216. // RefreshGroupPolicy() so that the end user can see the results
  2217. // immediately.
  2218. //
  2219. if (m_gpoType == GPOTypeLocal)
  2220. {
  2221. RefreshGroupPolicy (bMachine);
  2222. }
  2223. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::Save: Leaving with 0x%x"), hr));
  2224. return hr;
  2225. }
  2226. //*************************************************************
  2227. //
  2228. // Delete()
  2229. //
  2230. // Purpose: Deletes this Group Policy Object
  2231. //
  2232. // Parameters: none
  2233. //
  2234. // Return: S_OK if successful
  2235. //
  2236. //*************************************************************
  2237. STDMETHODIMP CGroupPolicyObject::Delete (void)
  2238. {
  2239. HRESULT hr;
  2240. if (!m_bInitialized)
  2241. {
  2242. return OLE_E_BLANK;
  2243. }
  2244. if (m_dwFlags & GPO_OPEN_READ_ONLY)
  2245. {
  2246. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Delete: Delete called on a READ ONLY GPO")));
  2247. return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  2248. }
  2249. //
  2250. // Unmount the registry information
  2251. //
  2252. if (m_pUser)
  2253. {
  2254. m_pUser->Release();
  2255. m_pUser = NULL;
  2256. }
  2257. if (m_pMachine)
  2258. {
  2259. m_pMachine->Release();
  2260. m_pMachine = NULL;
  2261. }
  2262. //
  2263. // Clean out the DS stuff
  2264. //
  2265. if (m_gpoType == GPOTypeDS)
  2266. {
  2267. hr = DSDelnode (m_pDSPath);
  2268. if (FAILED(hr))
  2269. {
  2270. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Delete: Failed to delete DS storage with 0x%x"), hr));
  2271. goto Exit;
  2272. }
  2273. }
  2274. //
  2275. // Delete the file system stuff
  2276. //
  2277. if (Delnode (m_pFileSysPath))
  2278. {
  2279. hr = S_OK;
  2280. }
  2281. else
  2282. {
  2283. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Delete: Failed to delete file system storage with %d"),
  2284. GetLastError()));
  2285. hr = HRESULT_FROM_WIN32(GetLastError());
  2286. }
  2287. if (SUCCEEDED(hr))
  2288. {
  2289. CleanUp();
  2290. }
  2291. Exit:
  2292. return hr;
  2293. }
  2294. //*************************************************************
  2295. //
  2296. // GetName()
  2297. //
  2298. // Purpose: Gets the unique GPO name
  2299. //
  2300. // Parameters: pszName is a pointer to a buffer which receives the name
  2301. // cchMaxLength is the max size of the buffer
  2302. //
  2303. // Return: S_OK if successful
  2304. //
  2305. //*************************************************************
  2306. STDMETHODIMP CGroupPolicyObject::GetName (LPOLESTR pszName, int cchMaxLength)
  2307. {
  2308. //
  2309. // Check parameters
  2310. //
  2311. if (!pszName || (cchMaxLength <= 0))
  2312. return E_INVALIDARG;
  2313. if (!m_bInitialized)
  2314. {
  2315. return OLE_E_BLANK;
  2316. }
  2317. //
  2318. // Save the name
  2319. //
  2320. if ((lstrlen (m_pName) + 1) <= cchMaxLength)
  2321. {
  2322. HRESULT hr;
  2323. hr = StringCchCopy (pszName, cchMaxLength, m_pName);
  2324. return hr;
  2325. }
  2326. return E_OUTOFMEMORY;
  2327. }
  2328. //*************************************************************
  2329. //
  2330. // GetDisplayName()
  2331. //
  2332. // Purpose: Gets the friendly name for this GPO
  2333. //
  2334. // Parameters: pszName is a pointer to a buffer which receives the name
  2335. // cchMaxLength is the max size of the buffer
  2336. //
  2337. // Return: S_OK if successful
  2338. //
  2339. //*************************************************************
  2340. STDMETHODIMP CGroupPolicyObject::GetDisplayName (LPOLESTR pszName, int cchMaxLength)
  2341. {
  2342. //
  2343. // Check parameters
  2344. //
  2345. if (!pszName || (cchMaxLength <= 0))
  2346. return E_INVALIDARG;
  2347. if (!m_bInitialized)
  2348. {
  2349. return OLE_E_BLANK;
  2350. }
  2351. if ((lstrlen (m_pDisplayName) + 1) <= cchMaxLength)
  2352. {
  2353. HRESULT hr;
  2354. hr = StringCchCopy (pszName, cchMaxLength, m_pDisplayName);
  2355. return hr;
  2356. }
  2357. return E_OUTOFMEMORY;
  2358. }
  2359. //+--------------------------------------------------------------------------
  2360. //
  2361. // Member: CGroupPolicyObject::SetDisplayName
  2362. //
  2363. // Synopsis: changes the friendly display name for a group policy object
  2364. //
  2365. // Arguments: [pszName] - new name (can be NULL to clear name)
  2366. //
  2367. // Returns: S_OK - success
  2368. //
  2369. // Modifies:
  2370. //
  2371. // Derivation:
  2372. //
  2373. // History: 05-002-1998 stevebl Created
  2374. //
  2375. // Notes:
  2376. //
  2377. //---------------------------------------------------------------------------
  2378. STDMETHODIMP CGroupPolicyObject::SetDisplayName (LPOLESTR lpDisplayName)
  2379. {
  2380. HRESULT hr = E_FAIL;
  2381. BSTR bstrName;
  2382. VARIANT var;
  2383. LPOLESTR lpNewName;
  2384. LPTSTR lpPath, lpEnd;
  2385. DWORD dwSize;
  2386. //
  2387. // Check parameters
  2388. //
  2389. if (!m_bInitialized)
  2390. {
  2391. return OLE_E_BLANK;
  2392. }
  2393. if (m_gpoType != GPOTypeDS)
  2394. {
  2395. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayName: Called for a non DS GPO")));
  2396. hr = E_INVALIDARG;
  2397. goto Exit;
  2398. }
  2399. if (!lpDisplayName)
  2400. {
  2401. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayName: NULL display name")));
  2402. hr = E_INVALIDARG;
  2403. goto Exit;
  2404. }
  2405. if (m_dwFlags & GPO_OPEN_READ_ONLY)
  2406. {
  2407. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayName: Called for a READ ONLY GPO")));
  2408. hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  2409. goto Exit;
  2410. }
  2411. //
  2412. // Call the internal method to set the display name
  2413. //
  2414. hr = SetDisplayNameI (m_pADs, lpDisplayName, m_pFileSysPath, TRUE);
  2415. Exit:
  2416. return hr;
  2417. }
  2418. //*************************************************************
  2419. //
  2420. // GetPath()
  2421. //
  2422. // Purpose: Returns the path to the GPO
  2423. //
  2424. // If the GPO is in the DS, this is an DN path
  2425. // If the GPO is machine based, it is a file system path
  2426. //
  2427. // Parameters: pszPath is a pointer to a buffer which receives the path
  2428. // cchMaxLength is the max size of the buffer
  2429. //
  2430. // Return: S_OK if successful
  2431. //
  2432. //*************************************************************
  2433. STDMETHODIMP CGroupPolicyObject::GetPath (LPOLESTR pszPath, int cchMaxLength)
  2434. {
  2435. LPTSTR lpTemp;
  2436. //
  2437. // Check parameters
  2438. //
  2439. if (!pszPath || (cchMaxLength <= 0))
  2440. return E_INVALIDARG;
  2441. if (!m_bInitialized)
  2442. {
  2443. return OLE_E_BLANK;
  2444. }
  2445. if (m_gpoType == GPOTypeDS)
  2446. {
  2447. lpTemp = MakeNamelessPath (m_pDSPath);
  2448. if (lpTemp)
  2449. {
  2450. if ((lstrlen (lpTemp) + 1) <= cchMaxLength)
  2451. {
  2452. HRESULT hr;
  2453. hr = StringCchCopy (pszPath, cchMaxLength, lpTemp);
  2454. LocalFree (lpTemp);
  2455. return hr;
  2456. }
  2457. LocalFree (lpTemp);
  2458. }
  2459. }
  2460. else
  2461. {
  2462. if ((lstrlen (m_pFileSysPath) + 1) <= cchMaxLength)
  2463. {
  2464. HRESULT hr;
  2465. hr = StringCchCopy (pszPath, cchMaxLength, m_pFileSysPath);
  2466. return hr;
  2467. }
  2468. }
  2469. return E_OUTOFMEMORY;
  2470. }
  2471. //*************************************************************
  2472. //
  2473. // GetDSPath()
  2474. //
  2475. // Purpose: Returns a DS path to the requested section
  2476. //
  2477. // Parameters: dwSection identifies root vs user vs machine
  2478. // pszPath is a pointer to a buffer which receives the path
  2479. // cchMaxLength is the max size of the buffer
  2480. //
  2481. // Return: S_OK if successful
  2482. //
  2483. //*************************************************************
  2484. STDMETHODIMP CGroupPolicyObject::GetDSPath (DWORD dwSection, LPOLESTR pszPath, int cchMaxPath)
  2485. {
  2486. HRESULT hr = E_FAIL;
  2487. BSTR bstrPath = NULL;
  2488. TCHAR szTemp[100];
  2489. IADsPathname * pADsPathname = NULL;
  2490. //
  2491. // Check for initialization
  2492. //
  2493. if (!m_bInitialized)
  2494. {
  2495. return OLE_E_BLANK;
  2496. }
  2497. //
  2498. // Check parameters
  2499. //
  2500. if (!pszPath || (cchMaxPath <= 0))
  2501. return E_INVALIDARG;
  2502. if ((dwSection != GPO_SECTION_ROOT) &&
  2503. (dwSection != GPO_SECTION_USER) &&
  2504. (dwSection != GPO_SECTION_MACHINE))
  2505. return E_INVALIDARG;
  2506. //
  2507. // If this is a local or remote machine GPO, then the
  2508. // caller gets an empty string back.
  2509. //
  2510. if (m_gpoType != GPOTypeDS)
  2511. {
  2512. *pszPath = TEXT('\0');
  2513. hr = S_OK;
  2514. goto Exit;
  2515. }
  2516. //
  2517. // Create a pathname object we can work with
  2518. //
  2519. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  2520. IID_IADsPathname, (LPVOID*)&pADsPathname);
  2521. if (FAILED(hr))
  2522. {
  2523. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to create adspathname instance with 0x%x"), hr));
  2524. goto Exit;
  2525. }
  2526. //
  2527. // Add the GPO name
  2528. //
  2529. BSTR bstrDSPath = SysAllocString( m_pDSPath );
  2530. if ( bstrDSPath == NULL )
  2531. {
  2532. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to allocate BSTR memory")));
  2533. hr = E_OUTOFMEMORY;
  2534. goto Exit;
  2535. }
  2536. hr = pADsPathname->Set (bstrDSPath, ADS_SETTYPE_FULL);
  2537. SysFreeString( bstrDSPath );
  2538. if (FAILED(hr))
  2539. {
  2540. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to set pathname with 0x%x"), hr));
  2541. goto Exit;
  2542. }
  2543. //
  2544. // Add the appropriate subcontainer
  2545. //
  2546. if (dwSection != GPO_SECTION_ROOT)
  2547. {
  2548. hr = StringCchCopy (szTemp, ARRAYSIZE(szTemp), TEXT("CN="));
  2549. if (SUCCEEDED(hr))
  2550. {
  2551. if (dwSection == GPO_SECTION_USER)
  2552. {
  2553. hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), USER_SECTION);
  2554. }
  2555. else
  2556. {
  2557. hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), MACHINE_SECTION);
  2558. }
  2559. }
  2560. if (FAILED(hr))
  2561. {
  2562. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Could not copy GPO path with 0x%x"), hr));
  2563. goto Exit;
  2564. }
  2565. BSTR bstrTemp = SysAllocString( szTemp );
  2566. if ( bstrTemp == NULL )
  2567. {
  2568. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to allocate BSTR memory")));
  2569. hr = E_OUTOFMEMORY;
  2570. goto Exit;
  2571. }
  2572. hr = pADsPathname->AddLeafElement (bstrTemp);
  2573. SysFreeString( bstrTemp );
  2574. if (FAILED(hr))
  2575. {
  2576. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to add subcontainer with 0x%x"), hr));
  2577. goto Exit;
  2578. }
  2579. }
  2580. hr = pADsPathname->Retrieve (ADS_FORMAT_X500_NO_SERVER, &bstrPath);
  2581. if (FAILED(hr))
  2582. {
  2583. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to retreive container path with 0x%x"), hr));
  2584. goto Exit;
  2585. }
  2586. if ((lstrlen(bstrPath) + 1) <= cchMaxPath)
  2587. {
  2588. hr = StringCchCopy (pszPath, cchMaxPath, bstrPath);
  2589. }
  2590. else
  2591. {
  2592. hr = E_OUTOFMEMORY;
  2593. }
  2594. SysFreeString (bstrPath);
  2595. Exit:
  2596. if (pADsPathname)
  2597. {
  2598. pADsPathname->Release();
  2599. }
  2600. return hr;
  2601. }
  2602. //*************************************************************
  2603. //
  2604. // GetFileSysPath()
  2605. //
  2606. // Purpose: Returns the file system path to the requested section
  2607. //
  2608. // Parameters: dwSection identifies user vs machine
  2609. // pszPath is a pointer to a buffer which receives the path
  2610. // cchMaxLength is the max size of the buffer
  2611. //
  2612. // Return: S_OK if successful
  2613. //
  2614. //*************************************************************
  2615. STDMETHODIMP CGroupPolicyObject::GetFileSysPath (DWORD dwSection, LPOLESTR pszPath, int cchMaxPath)
  2616. {
  2617. TCHAR szPath[2*MAX_PATH];
  2618. HRESULT hr;
  2619. //
  2620. // Check parameters
  2621. //
  2622. if (!pszPath || (cchMaxPath <= 0))
  2623. return E_INVALIDARG;
  2624. if (!m_bInitialized)
  2625. {
  2626. return OLE_E_BLANK;
  2627. }
  2628. hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath);
  2629. if (FAILED(hr))
  2630. {
  2631. return hr;
  2632. }
  2633. if (dwSection != GPO_SECTION_ROOT)
  2634. {
  2635. if (dwSection == GPO_SECTION_USER)
  2636. {
  2637. (void) CheckSlash (szPath);
  2638. hr = StringCchCat (szPath, ARRAYSIZE(szPath), USER_SECTION);
  2639. }
  2640. else if (dwSection == GPO_SECTION_MACHINE)
  2641. {
  2642. (void) CheckSlash (szPath);
  2643. hr = StringCchCat (szPath, ARRAYSIZE(szPath), MACHINE_SECTION);
  2644. }
  2645. else
  2646. {
  2647. return E_INVALIDARG;
  2648. }
  2649. if (FAILED(hr))
  2650. {
  2651. return hr;
  2652. }
  2653. }
  2654. if ((lstrlen(szPath) + 1) <= cchMaxPath)
  2655. {
  2656. hr = StringCchCopy (pszPath, cchMaxPath, szPath);
  2657. return hr;
  2658. }
  2659. return E_OUTOFMEMORY;
  2660. }
  2661. //*************************************************************
  2662. //
  2663. // GetRegistryKey()
  2664. //
  2665. // Purpose: Returns the requested registry key
  2666. //
  2667. // Parameters: dwSection identifies user vs machine
  2668. // hKey receives the opened registry key
  2669. //
  2670. // Return: S_OK if successful
  2671. //
  2672. //*************************************************************
  2673. STDMETHODIMP CGroupPolicyObject::GetRegistryKey (DWORD dwSection, HKEY *hKey)
  2674. {
  2675. HRESULT hr = E_FAIL;
  2676. if (!m_bInitialized)
  2677. {
  2678. return OLE_E_BLANK;
  2679. }
  2680. switch (dwSection)
  2681. {
  2682. case GPO_SECTION_USER:
  2683. if (m_pUser)
  2684. {
  2685. hr = m_pUser->GetHKey(hKey);
  2686. }
  2687. break;
  2688. case GPO_SECTION_MACHINE:
  2689. if (m_pMachine)
  2690. {
  2691. hr = m_pMachine->GetHKey(hKey);
  2692. }
  2693. break;
  2694. }
  2695. return (hr);
  2696. }
  2697. //*************************************************************
  2698. //
  2699. // GetOptions()
  2700. //
  2701. // Purpose: Gets the GPO options
  2702. //
  2703. // Parameters: dwOptions receives the options
  2704. //
  2705. // Return: S_OK if successful
  2706. //
  2707. //*************************************************************
  2708. STDMETHODIMP CGroupPolicyObject::GetOptions (DWORD * dwOptions)
  2709. {
  2710. HRESULT hr;
  2711. //
  2712. // Check for initialization
  2713. //
  2714. if (!m_bInitialized)
  2715. {
  2716. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Called on an uninitialized object.")));
  2717. return OLE_E_BLANK;
  2718. }
  2719. //
  2720. // Check argument
  2721. //
  2722. if (!dwOptions)
  2723. {
  2724. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Received a NULL ptr.")));
  2725. return E_INVALIDARG;
  2726. }
  2727. //
  2728. // If this is a DS GPO, the options are stored as a property on the
  2729. // GPC. If this a machine GPO, they are in the gpt.ini file.
  2730. //
  2731. if (m_gpoType == GPOTypeDS)
  2732. {
  2733. VARIANT var;
  2734. BSTR bstrProperty;
  2735. //
  2736. // Query for the options
  2737. //
  2738. bstrProperty = SysAllocString (GPO_OPTIONS_PROPERTY);
  2739. if (bstrProperty)
  2740. {
  2741. VariantInit(&var);
  2742. hr = m_pADs->Get(bstrProperty, &var);
  2743. if (SUCCEEDED(hr))
  2744. {
  2745. *dwOptions = var.lVal;
  2746. }
  2747. else
  2748. {
  2749. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Failed to query for options with 0x%x"), hr));
  2750. }
  2751. VariantClear (&var);
  2752. SysFreeString (bstrProperty);
  2753. }
  2754. else
  2755. {
  2756. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Failed to allocate memory")));
  2757. hr = ERROR_OUTOFMEMORY;
  2758. }
  2759. }
  2760. else
  2761. {
  2762. TCHAR szPath[2*MAX_PATH];
  2763. LPTSTR lpEnd;
  2764. //
  2765. // Get the file system path
  2766. //
  2767. hr = GetPath (szPath, ARRAYSIZE(szPath));
  2768. if (FAILED(hr))
  2769. {
  2770. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Failed to get path with 0x%x"), hr));
  2771. return hr;
  2772. }
  2773. //
  2774. // Tack on gpt.ini
  2775. //
  2776. lpEnd = CheckSlash (szPath);
  2777. hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI"));
  2778. if (FAILED(hr))
  2779. {
  2780. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Could not copy GPO path with 0x%x"), hr));
  2781. return hr;
  2782. }
  2783. //
  2784. // Get the options
  2785. //
  2786. *dwOptions = GetPrivateProfileInt (TEXT("General"), TEXT("Options"),
  2787. 0, szPath);
  2788. hr = S_OK;
  2789. }
  2790. return hr;
  2791. }
  2792. //*************************************************************
  2793. //
  2794. // SetOptions()
  2795. //
  2796. // Purpose: Sets the GPO options
  2797. //
  2798. // Parameters: dwOptions is the new options
  2799. // dwMask states which options should be set
  2800. //
  2801. // Return: S_OK if successful
  2802. //
  2803. //*************************************************************
  2804. STDMETHODIMP CGroupPolicyObject::SetOptions (DWORD dwOptions, DWORD dwMask)
  2805. {
  2806. HRESULT hr;
  2807. DWORD dwResult = 0, dwOriginal;
  2808. //
  2809. // Check for initialization
  2810. //
  2811. if (!m_bInitialized)
  2812. {
  2813. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Called on an uninitialized object.")));
  2814. return OLE_E_BLANK;
  2815. }
  2816. if (m_dwFlags & GPO_OPEN_READ_ONLY)
  2817. {
  2818. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Called for a READ ONLY GPO")));
  2819. return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  2820. }
  2821. //
  2822. // Query for the current options
  2823. //
  2824. hr = GetOptions (&dwResult);
  2825. if (FAILED(hr))
  2826. {
  2827. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to get previous options with 0x%x"), hr));
  2828. return hr;
  2829. }
  2830. //
  2831. // Save the original options so we can compare later
  2832. //
  2833. dwOriginal = dwResult;
  2834. //
  2835. // Check for the machine disabled option
  2836. //
  2837. if (dwMask & GPO_OPTION_DISABLE_MACHINE)
  2838. {
  2839. if (dwOptions & GPO_OPTION_DISABLE_MACHINE)
  2840. {
  2841. dwResult |= GPO_OPTION_DISABLE_MACHINE;
  2842. }
  2843. else
  2844. {
  2845. dwResult &= ~GPO_OPTION_DISABLE_MACHINE;
  2846. }
  2847. }
  2848. //
  2849. // Check for the user disabled option
  2850. //
  2851. if (dwMask & GPO_OPTION_DISABLE_USER)
  2852. {
  2853. if (dwOptions & GPO_OPTION_DISABLE_USER)
  2854. {
  2855. dwResult |= GPO_OPTION_DISABLE_USER;
  2856. }
  2857. else
  2858. {
  2859. dwResult &= ~GPO_OPTION_DISABLE_USER;
  2860. }
  2861. }
  2862. //
  2863. // If something changed, set the options back in the GPO
  2864. //
  2865. if (dwResult != dwOriginal)
  2866. {
  2867. //
  2868. // Set the options in the DS or gpt.ini as appropriate
  2869. //
  2870. if (m_gpoType == GPOTypeDS)
  2871. {
  2872. VARIANT var;
  2873. BSTR bstrName;
  2874. bstrName = SysAllocString (GPO_OPTIONS_PROPERTY);
  2875. if (bstrName)
  2876. {
  2877. VariantInit(&var);
  2878. var.vt = VT_I4;
  2879. var.lVal = dwResult;
  2880. hr = m_pADs->Put(bstrName, var);
  2881. VariantClear (&var);
  2882. SysFreeString (bstrName);
  2883. }
  2884. else
  2885. {
  2886. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to allocate memory")));
  2887. hr = ERROR_OUTOFMEMORY;
  2888. }
  2889. if (SUCCEEDED(hr))
  2890. {
  2891. hr = m_pADs->SetInfo();
  2892. }
  2893. if (FAILED(hr))
  2894. {
  2895. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to set options with 0x%x"), hr));
  2896. }
  2897. }
  2898. else
  2899. {
  2900. TCHAR szPath[2*MAX_PATH];
  2901. TCHAR szOptions[20];
  2902. LPTSTR lpEnd;
  2903. //
  2904. // Get the file system path
  2905. //
  2906. hr = GetPath (szPath, ARRAYSIZE(szPath));
  2907. if (FAILED(hr))
  2908. {
  2909. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to get path with 0x%x"), hr));
  2910. return hr;
  2911. }
  2912. //
  2913. // Tack on gpt.ini
  2914. //
  2915. lpEnd = CheckSlash (szPath);
  2916. hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI"));
  2917. if (FAILED(hr))
  2918. {
  2919. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Could not copy GPO path with 0x%x"), hr));
  2920. return hr;
  2921. }
  2922. //
  2923. // Convert the options to string format
  2924. //
  2925. _itot (dwResult, szOptions, 10);
  2926. //
  2927. // Set the options
  2928. //
  2929. if (!WritePrivateProfileString (TEXT("General"), TEXT("Options"),
  2930. szOptions, szPath))
  2931. {
  2932. hr = HRESULT_FROM_WIN32(GetLastError());
  2933. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to set options with 0x%x"), hr));
  2934. return hr;
  2935. }
  2936. //
  2937. // If this is the local GPO, trigger a policy refresh if appropriate
  2938. //
  2939. if (m_gpoType == GPOTypeLocal)
  2940. {
  2941. RefreshGroupPolicy (TRUE);
  2942. RefreshGroupPolicy (FALSE);
  2943. }
  2944. hr = S_OK;
  2945. }
  2946. }
  2947. else
  2948. {
  2949. hr = S_OK;
  2950. }
  2951. return hr;
  2952. }
  2953. //*************************************************************
  2954. //
  2955. // GetType()
  2956. //
  2957. // Purpose: Gets the GPO type
  2958. //
  2959. // Parameters: gpoType receives the type
  2960. //
  2961. //
  2962. // Return: S_OK if successful
  2963. //
  2964. //*************************************************************
  2965. STDMETHODIMP CGroupPolicyObject::GetType (GROUP_POLICY_OBJECT_TYPE *gpoType)
  2966. {
  2967. //
  2968. // Check for initialization
  2969. //
  2970. if (!m_bInitialized)
  2971. {
  2972. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetType: Called on an uninitialized object.")));
  2973. return OLE_E_BLANK;
  2974. }
  2975. //
  2976. // Check argument
  2977. //
  2978. if (!gpoType)
  2979. {
  2980. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetType: Received a NULL ptr.")));
  2981. return E_INVALIDARG;
  2982. }
  2983. //
  2984. // Store type
  2985. //
  2986. *gpoType = m_gpoType;
  2987. return S_OK;
  2988. }
  2989. //*************************************************************
  2990. //
  2991. // GetMachineName()
  2992. //
  2993. // Purpose: Gets the machine name of the remote GPO
  2994. //
  2995. // Parameters: pszName is a pointer to a buffer which receives the name
  2996. // cchMaxLength is the max size of the buffer
  2997. //
  2998. // Note: This method returns the name passed to OpenRemoteMachineGPO
  2999. //
  3000. // Return: S_OK if successful
  3001. //
  3002. //*************************************************************
  3003. STDMETHODIMP CGroupPolicyObject::GetMachineName (LPOLESTR pszName, int cchMaxLength)
  3004. {
  3005. HRESULT hr = S_OK;
  3006. //
  3007. // Check parameters
  3008. //
  3009. if (!pszName || (cchMaxLength <= 0))
  3010. return E_INVALIDARG;
  3011. if (!m_bInitialized)
  3012. {
  3013. return OLE_E_BLANK;
  3014. }
  3015. if (m_pMachineName)
  3016. {
  3017. //
  3018. // Save the name
  3019. //
  3020. if ((lstrlen (m_pMachineName) + 1) <= cchMaxLength)
  3021. {
  3022. hr = StringCchCopy (pszName, cchMaxLength, m_pMachineName);
  3023. }
  3024. else
  3025. {
  3026. hr = E_OUTOFMEMORY;
  3027. }
  3028. }
  3029. else
  3030. {
  3031. *pszName = TEXT('\0');
  3032. }
  3033. return hr;
  3034. }
  3035. BOOL
  3036. EnableWMIFilters( LPWSTR );
  3037. //*************************************************************
  3038. //
  3039. // GetPropertySheetPages()
  3040. //
  3041. // Purpose: Returns an array of property sheet pages for
  3042. // the callee to use. The callee needs to free
  3043. // the buffer with LocalFree when finished.
  3044. //
  3045. // Parameters: hPages receives a pointer to an array of page handles
  3046. // uPageCount receives the number of pages in hPages
  3047. //
  3048. // Return: S_OK if successful
  3049. //
  3050. //*************************************************************
  3051. STDMETHODIMP CGroupPolicyObject::GetPropertySheetPages (HPROPSHEETPAGE **hPages,
  3052. UINT *uPageCount)
  3053. {
  3054. HPROPSHEETPAGE hTempPages[4];
  3055. HPROPSHEETPAGE *lpPages;
  3056. PROPSHEETPAGE psp;
  3057. UINT i, uTempPageCount = 0;
  3058. HRESULT hr;
  3059. //
  3060. // Create the General property sheet
  3061. //
  3062. psp.dwSize = sizeof(PROPSHEETPAGE);
  3063. psp.dwFlags = 0;
  3064. psp.hInstance = g_hInstance;
  3065. psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPERTIES);
  3066. psp.pfnDlgProc = PropertiesDlgProc;
  3067. psp.lParam = (LPARAM) this;
  3068. hTempPages[uTempPageCount] = CreatePropertySheetPage(&psp);
  3069. if (!hTempPages[uTempPageCount])
  3070. {
  3071. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create property sheet page with %d."),
  3072. GetLastError()));
  3073. return E_FAIL;
  3074. }
  3075. uTempPageCount++;
  3076. //
  3077. // If this is a DS GPO, then create the links, DS security, and WMI filter pages
  3078. //
  3079. if (m_gpoType == GPOTypeDS)
  3080. {
  3081. // Create the search for links page
  3082. psp.dwSize = sizeof(PROPSHEETPAGE);
  3083. psp.dwFlags = 0;
  3084. psp.hInstance = g_hInstance;
  3085. psp.pszTemplate = MAKEINTRESOURCE(IDD_GPE_LINKS);
  3086. psp.pfnDlgProc = GPELinksDlgProc;
  3087. psp.lParam = (LPARAM) this;
  3088. hTempPages[uTempPageCount] = CreatePropertySheetPage(&psp);
  3089. if (!hTempPages[uTempPageCount])
  3090. {
  3091. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create property sheet page with %d."),
  3092. GetLastError()));
  3093. // destroy the previous prop page
  3094. DestroyPropertySheetPage(hTempPages[uTempPageCount - 1]);
  3095. return E_FAIL;
  3096. }
  3097. uTempPageCount++;
  3098. //
  3099. // Load DSSec.dll
  3100. //
  3101. if (!m_hinstDSSec)
  3102. {
  3103. m_hinstDSSec = LoadLibrary (TEXT("dssec.dll"));
  3104. }
  3105. if (m_hinstDSSec)
  3106. {
  3107. if (!m_pfnDSCreateSecurityPage)
  3108. {
  3109. m_pfnDSCreateSecurityPage = (PFNDSCREATESECPAGE) GetProcAddress (
  3110. m_hinstDSSec, "DSCreateSecurityPage");
  3111. }
  3112. if (m_pfnDSCreateSecurityPage)
  3113. {
  3114. //
  3115. // Call DSCreateSecurityPage
  3116. //
  3117. hr = m_pfnDSCreateSecurityPage (m_pDSPath, L"groupPolicyContainer",
  3118. DSSI_IS_ROOT | ((m_dwFlags & GPO_OPEN_READ_ONLY) ? DSSI_READ_ONLY : 0),
  3119. &hTempPages[uTempPageCount],
  3120. ReadSecurityDescriptor,
  3121. WriteSecurityDescriptor, (LPARAM)this);
  3122. if (SUCCEEDED(hr))
  3123. {
  3124. uTempPageCount++;
  3125. }
  3126. else
  3127. {
  3128. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create DS security page with 0x%x."), hr));
  3129. }
  3130. }
  3131. else
  3132. {
  3133. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to get function entry point with %d."), GetLastError()));
  3134. }
  3135. }
  3136. else
  3137. {
  3138. DebugMsg((DM_WARNING, TEXT("CComponentData::CreatePropertyPages: Failed to load dssec.dll with %d."), GetLastError()));
  3139. }
  3140. if ( EnableWMIFilters( m_pDSPath ) )
  3141. {
  3142. // Create the WQL filter page
  3143. psp.dwSize = sizeof(PROPSHEETPAGE);
  3144. psp.dwFlags = 0;
  3145. psp.hInstance = g_hInstance;
  3146. psp.pszTemplate = MAKEINTRESOURCE(IDD_WQLFILTER);
  3147. psp.pfnDlgProc = WQLFilterDlgProc;
  3148. psp.lParam = (LPARAM) this;
  3149. hTempPages[uTempPageCount] = CreatePropertySheetPage(&psp);
  3150. if (!hTempPages[uTempPageCount])
  3151. {
  3152. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create property sheet page with %d."),
  3153. GetLastError()));
  3154. for (i=0; i < uTempPageCount; i++)
  3155. {
  3156. DestroyPropertySheetPage(hTempPages[i]);
  3157. }
  3158. return E_FAIL;
  3159. }
  3160. uTempPageCount++;
  3161. }
  3162. }
  3163. //
  3164. // Save the results
  3165. //
  3166. lpPages = (HPROPSHEETPAGE *)LocalAlloc (LPTR, sizeof(HPROPSHEETPAGE) * uTempPageCount);
  3167. if (!lpPages)
  3168. {
  3169. for (i=0; i < uTempPageCount; i++)
  3170. {
  3171. DestroyPropertySheetPage(hTempPages[i]);
  3172. }
  3173. return E_OUTOFMEMORY;
  3174. }
  3175. for (i=0; i < uTempPageCount; i++)
  3176. {
  3177. lpPages[i] = hTempPages[i];
  3178. }
  3179. *hPages = lpPages;
  3180. *uPageCount = uTempPageCount;
  3181. return S_OK;
  3182. }
  3183. ///////////////////////////////////////////////////////////////////////////////
  3184. // //
  3185. // Internal methods //
  3186. // //
  3187. ///////////////////////////////////////////////////////////////////////////////
  3188. STDMETHODIMP CGroupPolicyObject::CreateContainer (LPOLESTR lpParent,
  3189. LPOLESTR lpCommonName,
  3190. BOOL bGPC)
  3191. {
  3192. HRESULT hr = E_FAIL;
  3193. VARIANT var;
  3194. IADs * pADs = NULL;
  3195. IADsContainer * pADsContainer = NULL;
  3196. IDispatch * pDispatch = NULL;
  3197. BSTR bstrProvider = NULL;
  3198. BSTR bstrName = NULL;
  3199. TCHAR szTemp[MAX_PATH];
  3200. // test to see if the container already exists
  3201. {
  3202. szTemp[0] = 0;
  3203. // scan lpParent to find the first instance of "CN="
  3204. LPTSTR lpSub = StrStr(lpParent, TEXT("CN="));
  3205. // insert CN=lpCommonName at that point
  3206. if (lpSub)
  3207. {
  3208. lstrcpyn(szTemp, lpParent, ((int)(lpSub - lpParent)) + 1);
  3209. hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), TEXT("CN="));
  3210. if (SUCCEEDED(hr))
  3211. {
  3212. hr = StringCchCat(szTemp, ARRAYSIZE(szTemp), lpCommonName);
  3213. }
  3214. if (SUCCEEDED(hr))
  3215. {
  3216. hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), TEXT(","));
  3217. }
  3218. if (SUCCEEDED(hr))
  3219. {
  3220. hr = StringCchCat(szTemp, ARRAYSIZE(szTemp), lpSub);
  3221. }
  3222. if (FAILED(hr))
  3223. {
  3224. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Could not copy container name with 0x%x"), hr));
  3225. goto Exit;
  3226. }
  3227. }
  3228. BSTR bstrTemp = SysAllocString( szTemp );
  3229. if ( bstrTemp == NULL )
  3230. {
  3231. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory")));
  3232. hr = E_OUTOFMEMORY;
  3233. goto Exit;
  3234. }
  3235. hr = OpenDSObject(bstrTemp, IID_IADsContainer, (void **)&pADsContainer);
  3236. SysFreeString( bstrTemp );
  3237. if (SUCCEEDED(hr))
  3238. {
  3239. hr = ERROR_OBJECT_ALREADY_EXISTS;
  3240. goto Exit;
  3241. }
  3242. }
  3243. //
  3244. // Bind to the parent object so we can create the container
  3245. //
  3246. BSTR bstrParent = SysAllocString( lpParent );
  3247. if ( bstrParent == NULL )
  3248. {
  3249. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory")));
  3250. hr = E_OUTOFMEMORY;
  3251. goto Exit;
  3252. }
  3253. hr = OpenDSObject(bstrParent, IID_IADsContainer, (void **)&pADsContainer);
  3254. SysFreeString( bstrParent );
  3255. if (FAILED(hr)) {
  3256. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to get gpo container interface with 0x%x"), hr));
  3257. goto Exit;
  3258. }
  3259. //
  3260. // Create the container (either GPC or normal container)
  3261. //
  3262. hr = StringCchCopy (szTemp, ARRAYSIZE(szTemp), TEXT("CN="));
  3263. if (SUCCEEDED(hr))
  3264. {
  3265. hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), lpCommonName);
  3266. }
  3267. if (FAILED(hr))
  3268. {
  3269. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Could not copy container name with 0x%x"), hr));
  3270. goto Exit;
  3271. }
  3272. BSTR bstrTemp = SysAllocString( szTemp );
  3273. if ( bstrTemp == NULL )
  3274. {
  3275. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory")));
  3276. hr = E_OUTOFMEMORY;
  3277. goto Exit;
  3278. }
  3279. BSTR bstrContainer = SysAllocString( (bGPC ? TEXT("groupPolicyContainer") : TEXT("container")) );
  3280. if ( bstrContainer == NULL )
  3281. {
  3282. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory")));
  3283. hr = E_OUTOFMEMORY;
  3284. SysFreeString( bstrTemp );
  3285. goto Exit;
  3286. }
  3287. hr = pADsContainer->Create ( bstrContainer, bstrTemp, &pDispatch);
  3288. SysFreeString( bstrTemp );
  3289. SysFreeString( bstrContainer );
  3290. if (FAILED(hr)) {
  3291. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to create container with 0x%x"), hr));
  3292. goto Exit;
  3293. }
  3294. //
  3295. // Query for the IADs interface so we can set the CN name and
  3296. // commit the changes
  3297. //
  3298. hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
  3299. if (FAILED(hr)) {
  3300. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: QI for IADs failed with 0x%x"), hr));
  3301. goto Exit;
  3302. }
  3303. //
  3304. // Set the common name (aka "cn")
  3305. //
  3306. bstrName = SysAllocString (L"cn");
  3307. if (bstrName)
  3308. {
  3309. VariantInit(&var);
  3310. var.vt = VT_BSTR;
  3311. var.bstrVal = SysAllocString (lpCommonName);
  3312. hr = pADs->Put(bstrName, var);
  3313. VariantClear (&var);
  3314. SysFreeString (bstrName);
  3315. }
  3316. else
  3317. {
  3318. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate memory")));
  3319. hr = ERROR_OUTOFMEMORY;
  3320. }
  3321. if (FAILED(hr))
  3322. {
  3323. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to put common name with 0x%x"), hr));
  3324. goto Exit;
  3325. }
  3326. //
  3327. // Call SetInfo to commit the changes
  3328. //
  3329. hr = pADs->SetInfo();
  3330. Exit:
  3331. if (pDispatch)
  3332. {
  3333. pDispatch->Release();
  3334. }
  3335. if (pADs)
  3336. {
  3337. pADs->Release();
  3338. }
  3339. if (pADsContainer)
  3340. {
  3341. pADsContainer->Release();
  3342. }
  3343. return hr;
  3344. }
  3345. STDMETHODIMP CGroupPolicyObject::SetDisplayNameI (IADs * pADs, LPOLESTR lpDisplayName,
  3346. LPOLESTR lpGPTPath, BOOL bUpdateDisplayVar)
  3347. {
  3348. HRESULT hr = E_FAIL;
  3349. BSTR bstrName;
  3350. VARIANT var;
  3351. LPOLESTR lpNewName;
  3352. LPTSTR lpPath, lpEnd;
  3353. DWORD dwSize;
  3354. //
  3355. // Make a copy of the display name and limit it to MAX_FRIENDLYNAME characters
  3356. //
  3357. dwSize = lstrlen(lpDisplayName);
  3358. if (dwSize > (MAX_FRIENDLYNAME - 1))
  3359. {
  3360. dwSize = (MAX_FRIENDLYNAME - 1);
  3361. }
  3362. lpNewName = (LPOLESTR) LocalAlloc (LPTR, (dwSize + 2) * sizeof(OLECHAR));
  3363. if (!lpNewName)
  3364. {
  3365. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to allocate memory for display name")));
  3366. hr = HRESULT_FROM_WIN32(GetLastError());
  3367. goto Exit;
  3368. }
  3369. lstrcpyn (lpNewName, lpDisplayName, (dwSize + 1));
  3370. //
  3371. // Set the display name
  3372. //
  3373. bstrName = SysAllocString (GPO_NAME_PROPERTY);
  3374. if (!bstrName)
  3375. {
  3376. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to allocate memory")));
  3377. LocalFree (lpNewName);
  3378. return ERROR_OUTOFMEMORY;
  3379. }
  3380. VariantInit(&var);
  3381. var.vt = VT_BSTR;
  3382. var.bstrVal = SysAllocString (lpNewName);
  3383. if (var.bstrVal)
  3384. {
  3385. hr = pADs->Put(bstrName, var);
  3386. }
  3387. else
  3388. {
  3389. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to allocate memory")));
  3390. hr = ERROR_OUTOFMEMORY;
  3391. }
  3392. SysFreeString (bstrName);
  3393. VariantClear (&var);
  3394. if (FAILED(hr))
  3395. {
  3396. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to put display name with 0x%x"), hr));
  3397. LocalFree (lpNewName);
  3398. goto Exit;
  3399. }
  3400. //
  3401. // Commit the changes
  3402. //
  3403. hr = pADs->SetInfo();
  3404. if (FAILED(hr))
  3405. {
  3406. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to commit changes with 0x%x"), hr));
  3407. LocalFree (lpNewName);
  3408. goto Exit;
  3409. }
  3410. //
  3411. // Put the display name in the gpt.ini file also
  3412. //
  3413. ULONG ulNoChars;
  3414. ulNoChars = lstrlen(lpGPTPath) + 10;
  3415. lpPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  3416. if (lpPath)
  3417. {
  3418. hr = StringCchCopy(lpPath, ulNoChars, lpGPTPath);
  3419. if (SUCCEEDED(hr))
  3420. {
  3421. lpEnd = CheckSlash(lpPath);
  3422. hr = StringCchCat (lpPath, ulNoChars, TEXT("gpt.ini"));
  3423. }
  3424. if (FAILED(hr))
  3425. {
  3426. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Could not copy GPO path with 0x%x"), hr));
  3427. LocalFree(lpPath);
  3428. LocalFree (lpNewName);
  3429. goto Exit;
  3430. }
  3431. if (!WritePrivateProfileString (TEXT("General"), GPO_NAME_PROPERTY,
  3432. lpNewName, lpPath))
  3433. {
  3434. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to write display name to gpt.ini with 0x%x"), hr));
  3435. }
  3436. LocalFree (lpPath);
  3437. }
  3438. //
  3439. // Update the member variable if appropriate
  3440. //
  3441. if (bUpdateDisplayVar)
  3442. {
  3443. //
  3444. // Update the display name variable
  3445. //
  3446. if (m_pDisplayName)
  3447. {
  3448. LocalFree (m_pDisplayName);
  3449. m_pDisplayName = NULL;
  3450. }
  3451. m_pDisplayName = lpNewName;
  3452. }
  3453. else
  3454. {
  3455. LocalFree (lpNewName);
  3456. }
  3457. Exit:
  3458. return hr;
  3459. }
  3460. STDMETHODIMP CGroupPolicyObject::SetGPOInfo (LPOLESTR lpGPO,
  3461. LPOLESTR lpDisplayName,
  3462. LPOLESTR lpGPTPath)
  3463. {
  3464. HRESULT hr = E_FAIL;
  3465. IADs * pADs = NULL;
  3466. BSTR bstrName;
  3467. VARIANT var;
  3468. TCHAR szDefaultName[MAX_FRIENDLYNAME];
  3469. //
  3470. // Bind to the GPO container
  3471. //
  3472. hr = OpenDSObject(lpGPO, IID_IADs, (void **)&pADs);
  3473. if (FAILED(hr)) {
  3474. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to get gpo interface with 0x%x"), hr));
  3475. goto Exit;
  3476. }
  3477. //
  3478. // Set the display name
  3479. //
  3480. GetNewGPODisplayName (szDefaultName, ARRAYSIZE(szDefaultName));
  3481. hr = SetDisplayNameI (pADs, (lpDisplayName ? lpDisplayName : szDefaultName),
  3482. lpGPTPath, FALSE);
  3483. if (FAILED(hr))
  3484. {
  3485. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set display name")));
  3486. goto Exit;
  3487. }
  3488. //
  3489. // Set the GPT location
  3490. //
  3491. bstrName = SysAllocString (GPT_PATH_PROPERTY);
  3492. if (bstrName)
  3493. {
  3494. VariantInit(&var);
  3495. var.vt = VT_BSTR;
  3496. var.bstrVal = SysAllocString (lpGPTPath);
  3497. if (var.bstrVal)
  3498. {
  3499. hr = pADs->Put(bstrName, var);
  3500. }
  3501. else
  3502. {
  3503. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory")));
  3504. hr = ERROR_OUTOFMEMORY;
  3505. }
  3506. VariantClear (&var);
  3507. SysFreeString (bstrName);
  3508. }
  3509. else
  3510. {
  3511. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory")));
  3512. hr = ERROR_OUTOFMEMORY;
  3513. }
  3514. if (FAILED(hr))
  3515. {
  3516. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to save GPT path with 0x%x"), hr));
  3517. goto Exit;
  3518. }
  3519. //
  3520. // Set the version number
  3521. //
  3522. bstrName = SysAllocString (GPO_VERSION_PROPERTY);
  3523. if (bstrName)
  3524. {
  3525. VariantInit(&var);
  3526. var.vt = VT_I4;
  3527. var.lVal = 0;
  3528. hr = pADs->Put(bstrName, var);
  3529. VariantClear (&var);
  3530. SysFreeString (bstrName);
  3531. }
  3532. else
  3533. {
  3534. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory")));
  3535. hr = ERROR_OUTOFMEMORY;
  3536. }
  3537. if (FAILED(hr))
  3538. {
  3539. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set version number with 0x%x"), hr));
  3540. goto Exit;
  3541. }
  3542. //
  3543. // Set the functionality version number
  3544. //
  3545. bstrName = SysAllocString (GPO_FUNCTION_PROPERTY);
  3546. if (bstrName)
  3547. {
  3548. VariantInit(&var);
  3549. var.vt = VT_I4;
  3550. var.lVal = GPO_FUNCTIONALITY_VERSION;
  3551. hr = pADs->Put(bstrName, var);
  3552. VariantClear (&var);
  3553. SysFreeString (bstrName);
  3554. }
  3555. else
  3556. {
  3557. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory")));
  3558. hr = ERROR_OUTOFMEMORY;
  3559. }
  3560. if (FAILED(hr))
  3561. {
  3562. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set functionality version number with 0x%x"), hr));
  3563. goto Exit;
  3564. }
  3565. //
  3566. // Set the options
  3567. //
  3568. bstrName = SysAllocString (GPO_OPTIONS_PROPERTY);
  3569. if (bstrName)
  3570. {
  3571. VariantInit(&var);
  3572. var.vt = VT_I4;
  3573. var.lVal = 0;
  3574. hr = pADs->Put(bstrName, var);
  3575. VariantClear (&var);
  3576. SysFreeString (bstrName);
  3577. }
  3578. else
  3579. {
  3580. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory")));
  3581. hr = ERROR_OUTOFMEMORY;
  3582. }
  3583. if (FAILED(hr))
  3584. {
  3585. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set options with 0x%x"), hr));
  3586. goto Exit;
  3587. }
  3588. //
  3589. // Commit the changes
  3590. //
  3591. hr = pADs->SetInfo();
  3592. Exit:
  3593. if (pADs)
  3594. {
  3595. pADs->Release();
  3596. }
  3597. return hr;
  3598. }
  3599. STDMETHODIMP CGroupPolicyObject::CheckFSWriteAccess (LPOLESTR lpLocalGPO)
  3600. {
  3601. TCHAR szBuffer[MAX_PATH];
  3602. LPTSTR lpEnd;
  3603. HRESULT hr;
  3604. hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), lpLocalGPO);
  3605. if (SUCCEEDED(hr))
  3606. {
  3607. lpEnd = CheckSlash (szBuffer);
  3608. hr = StringCchCat (szBuffer, ARRAYSIZE(szBuffer), TEXT("gpt.ini"));
  3609. }
  3610. if (SUCCEEDED(hr))
  3611. {
  3612. if (!WritePrivateProfileString (TEXT("General"), TEXT("AccessCheck"),
  3613. TEXT("test"), szBuffer))
  3614. {
  3615. hr = HRESULT_FROM_WIN32(GetLastError());
  3616. }
  3617. else
  3618. {
  3619. WritePrivateProfileString (TEXT("General"), TEXT("AccessCheck"),
  3620. NULL, szBuffer);
  3621. hr = S_OK;
  3622. }
  3623. }
  3624. return hr;
  3625. }
  3626. STDMETHODIMP CGroupPolicyObject::GetSecurityDescriptor (IADs *pADs,
  3627. SECURITY_INFORMATION si,
  3628. PSECURITY_DESCRIPTOR *pSD)
  3629. {
  3630. HRESULT hr;
  3631. VARIANT var;
  3632. LPWSTR pszSDProperty = L"nTSecurityDescriptor";
  3633. IDirectoryObject *pDsObject = NULL;
  3634. IADsObjectOptions *pOptions = NULL;
  3635. PADS_ATTR_INFO pSDAttributeInfo = NULL;
  3636. DWORD dwAttributesReturned;
  3637. //
  3638. // Retreive the DS Object interface
  3639. //
  3640. hr = pADs->QueryInterface(IID_IDirectoryObject, (void**)&pDsObject);
  3641. if (FAILED(hr)) {
  3642. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to get gpo DS object interface with 0x%x"), hr));
  3643. goto Exit;
  3644. }
  3645. //
  3646. // Retreive the DS Object Options interface
  3647. //
  3648. hr = pADs->QueryInterface(IID_IADsObjectOptions, (void**)&pOptions);
  3649. if (FAILED(hr)) {
  3650. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to get DS object options interface with 0x%x"), hr));
  3651. goto Exit;
  3652. }
  3653. //
  3654. // Set the SECURITY_INFORMATION mask
  3655. //
  3656. VariantInit(&var);
  3657. var.vt = VT_I4;
  3658. var.lVal = si;
  3659. hr = pOptions->SetOption(ADS_OPTION_SECURITY_MASK, var);
  3660. VariantClear (&var);
  3661. if (FAILED(hr)) {
  3662. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to set ADSI security options with 0x%x"), hr));
  3663. goto Exit;
  3664. }
  3665. //
  3666. // Read the security descriptor
  3667. //
  3668. hr = pDsObject->GetObjectAttributes(&pszSDProperty, 1, &pSDAttributeInfo,
  3669. &dwAttributesReturned);
  3670. if (SUCCEEDED(hr) && !pSDAttributeInfo)
  3671. {
  3672. hr = E_ACCESSDENIED; // This happens for SACL if no SecurityPrivilege
  3673. }
  3674. if (FAILED(hr)) {
  3675. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to get DS object attributes with 0x%x"), hr));
  3676. goto Exit;
  3677. }
  3678. //
  3679. // Duplicate the security descriptor
  3680. //
  3681. *pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, pSDAttributeInfo->pADsValues->SecurityDescriptor.dwLength);
  3682. if (!*pSD)
  3683. {
  3684. hr = HRESULT_FROM_WIN32(GetLastError());
  3685. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to allocate memory with 0x%x"), hr));
  3686. goto Exit;
  3687. }
  3688. CopyMemory(*pSD, pSDAttributeInfo->pADsValues->SecurityDescriptor.lpValue,
  3689. pSDAttributeInfo->pADsValues->SecurityDescriptor.dwLength);
  3690. Exit:
  3691. if (pSDAttributeInfo)
  3692. {
  3693. FreeADsMem(pSDAttributeInfo);
  3694. }
  3695. if (pOptions)
  3696. {
  3697. pOptions->Release();
  3698. }
  3699. if (pDsObject)
  3700. {
  3701. pDsObject->Release();
  3702. }
  3703. return hr;
  3704. }
  3705. BOOL CGroupPolicyObject::EnableSecurityPrivs(void)
  3706. {
  3707. BOOL bResult;
  3708. HANDLE hToken;
  3709. HANDLE hNewToken;
  3710. BYTE buffer[sizeof(PRIVILEGE_SET) + sizeof(LUID_AND_ATTRIBUTES)];
  3711. PTOKEN_PRIVILEGES pPrivileges = (PTOKEN_PRIVILEGES)buffer;
  3712. //
  3713. // Get a token and enable the Security and Take Ownership
  3714. // privileges, if possible.
  3715. //
  3716. bResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, TRUE, &hToken);
  3717. if (!bResult)
  3718. {
  3719. bResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken);
  3720. }
  3721. if (!bResult)
  3722. {
  3723. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to get both thread and process token with %d"),
  3724. GetLastError()));
  3725. return FALSE;
  3726. }
  3727. bResult = DuplicateTokenEx(hToken,
  3728. TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  3729. NULL, // PSECURITY_ATTRIBUTES
  3730. SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
  3731. TokenImpersonation, // TokenType
  3732. &hNewToken); // Duplicate token
  3733. if (!bResult)
  3734. {
  3735. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to duplicate the token with %d"),
  3736. GetLastError()));
  3737. CloseHandle(hToken);
  3738. return FALSE;
  3739. }
  3740. //
  3741. // PRIVILEGE_SET contains 1 LUID_AND_ATTRIBUTES already, so
  3742. // this is enough for 2 LUID_AND_ATTRIBUTES (2 privileges).
  3743. //
  3744. CloseHandle(hToken);
  3745. hToken = hNewToken;
  3746. pPrivileges->PrivilegeCount = 2;
  3747. pPrivileges->Privileges[0].Luid = RtlConvertUlongToLuid(SE_SECURITY_PRIVILEGE);
  3748. pPrivileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  3749. pPrivileges->Privileges[1].Luid = RtlConvertUlongToLuid(SE_TAKE_OWNERSHIP_PRIVILEGE);
  3750. pPrivileges->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
  3751. bResult = AdjustTokenPrivileges(hToken, // TokenHandle
  3752. FALSE, // DisableAllPrivileges
  3753. pPrivileges,// NewState
  3754. 0, // BufferLength
  3755. NULL, // PreviousState
  3756. NULL); // ReturnLength
  3757. if (!bResult)
  3758. {
  3759. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to AdjustTokenPrivileges with %d"),
  3760. GetLastError()));
  3761. CloseHandle(hToken);
  3762. return FALSE;
  3763. }
  3764. //
  3765. // Set the new thread token
  3766. //
  3767. if ( !SetThreadToken(NULL, hToken) )
  3768. {
  3769. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to SetThreadToken with %d"), GetLastError() ) );
  3770. CloseHandle(hToken);
  3771. return FALSE;
  3772. }
  3773. CloseHandle(hToken);
  3774. return TRUE;
  3775. }
  3776. DWORD CGroupPolicyObject::EnableInheritance (PACL pAcl)
  3777. {
  3778. WORD wIndex;
  3779. DWORD dwResult = ERROR_SUCCESS;
  3780. ACE_HEADER *pAceHeader;
  3781. if (pAcl)
  3782. {
  3783. //
  3784. // Loop through the ACL looking at each ACE entry
  3785. //
  3786. for (wIndex = 0; wIndex < pAcl->AceCount; wIndex++)
  3787. {
  3788. if (!GetAce (pAcl, (DWORD)wIndex, (LPVOID *)&pAceHeader))
  3789. {
  3790. dwResult = GetLastError();
  3791. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableInheritance: GetAce failed with %d"),
  3792. dwResult));
  3793. goto Exit;
  3794. }
  3795. //
  3796. // Turn on the inheritance flags
  3797. //
  3798. pAceHeader->AceFlags |= (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
  3799. }
  3800. }
  3801. Exit:
  3802. return dwResult;
  3803. }
  3804. //
  3805. // This method will convert a DS security access list into a
  3806. // file system security access list and actually set the security
  3807. //
  3808. DWORD CGroupPolicyObject::SetSysvolSecurity (LPTSTR lpFileSysPath, SECURITY_INFORMATION si,
  3809. PSECURITY_DESCRIPTOR pSD)
  3810. {
  3811. return SetSysvolSecurityFromDSSecurity(
  3812. lpFileSysPath,
  3813. si,
  3814. pSD);
  3815. }
  3816. HRESULT WINAPI CGroupPolicyObject::ReadSecurityDescriptor (LPCWSTR lpGPOPath,
  3817. SECURITY_INFORMATION si,
  3818. PSECURITY_DESCRIPTOR *pSD,
  3819. LPARAM lpContext)
  3820. {
  3821. CGroupPolicyObject * pGPO;
  3822. HRESULT hr;
  3823. //
  3824. // Convert lpContext into a pGPO
  3825. //
  3826. pGPO = (CGroupPolicyObject*)lpContext;
  3827. if (!pGPO)
  3828. {
  3829. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::ReadSecurityDescriptor: GPO interface pointer is NULL")));
  3830. return E_FAIL;
  3831. }
  3832. hr = pGPO->GetSecurityDescriptor (pGPO->m_pADs, si, pSD);
  3833. if (FAILED(hr))
  3834. {
  3835. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::ReadSecurityDescriptor: GetSecurityDescriptor returned 0x%x"), hr));
  3836. }
  3837. return (hr);
  3838. }
  3839. HRESULT WINAPI CGroupPolicyObject::WriteSecurityDescriptor (LPCWSTR lpGPOPath,
  3840. SECURITY_INFORMATION si,
  3841. PSECURITY_DESCRIPTOR pSD,
  3842. LPARAM lpContext)
  3843. {
  3844. CGroupPolicyObject * pGPO;
  3845. IDirectoryObject *pDsObject = NULL;
  3846. IADsObjectOptions *pOptions = NULL;
  3847. DWORD dwResult = ERROR_SUCCESS;
  3848. HRESULT hr;
  3849. VARIANT var;
  3850. ADSVALUE attributeValue;
  3851. ADS_ATTR_INFO attributeInfo;
  3852. DWORD dwAttributesModified;
  3853. DWORD dwSDLength;
  3854. PSECURITY_DESCRIPTOR psd = NULL, pSDOrg = NULL;
  3855. SECURITY_DESCRIPTOR_CONTROL sdControl = 0;
  3856. DWORD dwRevision;
  3857. PACL pAcl;
  3858. BOOL bPresent, bDefault;
  3859. //
  3860. // Convert lpContext into a pGPO
  3861. //
  3862. pGPO = (CGroupPolicyObject*)lpContext;
  3863. if (!pGPO)
  3864. {
  3865. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: GPO interface pointer is NULL")));
  3866. return E_FAIL;
  3867. }
  3868. //
  3869. // Get the original security descriptor from the DS
  3870. //
  3871. hr = pGPO->GetSecurityDescriptor (pGPO->m_pADs, si, &pSDOrg);
  3872. if (FAILED(hr)) {
  3873. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to query the security descriptor with 0x%x"), hr));
  3874. goto Exit;
  3875. }
  3876. //
  3877. // Retreive the DS Object interface
  3878. //
  3879. hr = pGPO->m_pADs->QueryInterface(IID_IDirectoryObject, (void**)&pDsObject);
  3880. if (FAILED(hr)) {
  3881. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get DS object interface with 0x%x"), hr));
  3882. goto Exit;
  3883. }
  3884. //
  3885. // Retreive the DS Object Options interface
  3886. //
  3887. hr = pGPO->m_pADs->QueryInterface(IID_IADsObjectOptions, (void**)&pOptions);
  3888. if (FAILED(hr)) {
  3889. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get DS object options interface with 0x%x"), hr));
  3890. goto Exit;
  3891. }
  3892. //
  3893. // Set the SECURITY_INFORMATION mask
  3894. //
  3895. VariantInit(&var);
  3896. var.vt = VT_I4;
  3897. var.lVal = si;
  3898. hr = pOptions->SetOption(ADS_OPTION_SECURITY_MASK, var);
  3899. VariantClear (&var);
  3900. if (FAILED(hr)) {
  3901. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get DS object options interface with 0x%x"), hr));
  3902. goto Exit;
  3903. }
  3904. //
  3905. // Need the total size of the security descriptor
  3906. //
  3907. dwSDLength = GetSecurityDescriptorLength(pSD);
  3908. //
  3909. // If necessary, make a self-relative copy of the security descriptor
  3910. //
  3911. if (!GetSecurityDescriptorControl(pSD, &sdControl, &dwRevision))
  3912. {
  3913. dwResult = GetLastError();
  3914. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get security descriptor control with %d"),
  3915. dwResult));
  3916. hr = HRESULT_FROM_WIN32(dwResult);
  3917. goto Exit;
  3918. }
  3919. if (!(sdControl & SE_SELF_RELATIVE))
  3920. {
  3921. psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwSDLength);
  3922. if (!psd)
  3923. {
  3924. dwResult = GetLastError();
  3925. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to allocate memory for new SD with %d"),
  3926. dwResult));
  3927. hr = HRESULT_FROM_WIN32(dwResult);
  3928. goto Exit;
  3929. }
  3930. if (!MakeSelfRelativeSD(pSD, psd, &dwSDLength))
  3931. {
  3932. dwResult = GetLastError();
  3933. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: MakeSelfRelativeSD failed with %d"),
  3934. dwResult));
  3935. hr = HRESULT_FROM_WIN32(dwResult);
  3936. goto Exit;
  3937. }
  3938. //
  3939. // Point to the self-relative copy
  3940. //
  3941. pSD = psd;
  3942. }
  3943. //
  3944. // By default, the general page will set things up so the inheritance
  3945. // is for the root container only. We really want the inheritance to
  3946. // be for the root and all sub-containers, so run through the
  3947. // DACL and SACL and set the new inheritance flags
  3948. //
  3949. if (si & DACL_SECURITY_INFORMATION)
  3950. {
  3951. if (!GetSecurityDescriptorDacl(pSD, &bPresent, &pAcl, &bDefault))
  3952. {
  3953. dwResult = GetLastError();
  3954. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: GetSecurityDescriptorDacl failed with %d"),
  3955. dwResult));
  3956. hr = HRESULT_FROM_WIN32(dwResult);
  3957. goto Exit;
  3958. }
  3959. dwResult = pGPO->EnableInheritance (pAcl);
  3960. if (dwResult != ERROR_SUCCESS)
  3961. {
  3962. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: EnableInheritance failed with %d"),
  3963. dwResult));
  3964. hr = HRESULT_FROM_WIN32(dwResult);
  3965. goto Exit;
  3966. }
  3967. }
  3968. if (si & SACL_SECURITY_INFORMATION)
  3969. {
  3970. if (!GetSecurityDescriptorSacl(pSD, &bPresent, &pAcl, &bDefault))
  3971. {
  3972. dwResult = GetLastError();
  3973. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: GetSecurityDescriptorSacl failed with %d"),
  3974. dwResult));
  3975. hr = HRESULT_FROM_WIN32(dwResult);
  3976. goto Exit;
  3977. }
  3978. dwResult = pGPO->EnableInheritance (pAcl);
  3979. if (dwResult != ERROR_SUCCESS)
  3980. {
  3981. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: EnableInheritance failed with %d"),
  3982. dwResult));
  3983. hr = HRESULT_FROM_WIN32(dwResult);
  3984. goto Exit;
  3985. }
  3986. }
  3987. //
  3988. // Set the DS security
  3989. //
  3990. attributeValue.dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  3991. attributeValue.SecurityDescriptor.dwLength = dwSDLength;
  3992. attributeValue.SecurityDescriptor.lpValue = (LPBYTE)pSD;
  3993. attributeInfo.pszAttrName = L"nTSecurityDescriptor";
  3994. attributeInfo.dwControlCode = ADS_ATTR_UPDATE;
  3995. attributeInfo.dwADsType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  3996. attributeInfo.pADsValues = &attributeValue;
  3997. attributeInfo.dwNumValues = 1;
  3998. hr = pDsObject->SetObjectAttributes(&attributeInfo, 1, &dwAttributesModified);
  3999. if (FAILED(hr)) {
  4000. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to set DS security with 0x%x"), hr));
  4001. goto Exit;
  4002. }
  4003. //
  4004. // Set the sysvol security
  4005. //
  4006. dwResult = pGPO->SetSysvolSecurity (pGPO->m_pFileSysPath, si, pSD);
  4007. if (dwResult != ERROR_SUCCESS)
  4008. {
  4009. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to set the security for the file system portion <%s> with %d"),
  4010. pGPO->m_pFileSysPath, dwResult));
  4011. hr = HRESULT_FROM_WIN32(dwResult);
  4012. //
  4013. // Restore the orignal DS security
  4014. //
  4015. attributeValue.dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  4016. attributeValue.SecurityDescriptor.dwLength = GetSecurityDescriptorLength(pSDOrg);
  4017. attributeValue.SecurityDescriptor.lpValue = (LPBYTE)pSDOrg;
  4018. attributeInfo.pszAttrName = L"nTSecurityDescriptor";
  4019. attributeInfo.dwControlCode = ADS_ATTR_UPDATE;
  4020. attributeInfo.dwADsType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  4021. attributeInfo.pADsValues = &attributeValue;
  4022. attributeInfo.dwNumValues = 1;
  4023. if (FAILED(pDsObject->SetObjectAttributes(&attributeInfo, 1, &dwAttributesModified)))
  4024. {
  4025. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to restore DS security")));
  4026. }
  4027. goto Exit;
  4028. }
  4029. Exit:
  4030. if (pDsObject)
  4031. {
  4032. pDsObject->Release();
  4033. }
  4034. if (pOptions)
  4035. {
  4036. pOptions->Release();
  4037. }
  4038. if (psd)
  4039. {
  4040. LocalFree(psd);
  4041. }
  4042. if (pSDOrg)
  4043. {
  4044. LocalFree(pSDOrg);
  4045. }
  4046. return (hr);
  4047. }
  4048. STDMETHODIMP CGroupPolicyObject::CleanUp (void)
  4049. {
  4050. if (m_pUser)
  4051. {
  4052. m_pUser->Release();
  4053. m_pUser = NULL;
  4054. }
  4055. if (m_pMachine)
  4056. {
  4057. m_pMachine->Release();
  4058. m_pMachine = NULL;
  4059. }
  4060. if (m_pName)
  4061. {
  4062. LocalFree (m_pName);
  4063. m_pName = NULL;
  4064. }
  4065. if (m_pDisplayName)
  4066. {
  4067. LocalFree (m_pDisplayName);
  4068. m_pDisplayName = NULL;
  4069. }
  4070. if (m_pDSPath)
  4071. {
  4072. LocalFree (m_pDSPath);
  4073. m_pDSPath = NULL;
  4074. }
  4075. if (m_pFileSysPath)
  4076. {
  4077. LocalFree (m_pFileSysPath);
  4078. m_pFileSysPath = NULL;
  4079. }
  4080. if (m_pMachineName)
  4081. {
  4082. LocalFree (m_pMachineName);
  4083. m_pMachineName = NULL;
  4084. }
  4085. if (m_pADs)
  4086. {
  4087. m_pADs->Release();
  4088. m_pADs = NULL;
  4089. }
  4090. m_gpoType = GPOTypeLocal;
  4091. m_bInitialized = FALSE;
  4092. return S_OK;
  4093. }
  4094. STDMETHODIMP CGroupPolicyObject::RefreshGroupPolicy (BOOL bMachine)
  4095. {
  4096. HINSTANCE hInstUserEnv;
  4097. PFNREFRESHPOLICY pfnRefreshPolicy;
  4098. //
  4099. // Load the function we need
  4100. //
  4101. hInstUserEnv = LoadLibrary (TEXT("userenv.dll"));
  4102. if (!hInstUserEnv) {
  4103. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::RefreshGroupPolicy: Failed to load userenv with %d."),
  4104. GetLastError()));
  4105. return (HRESULT_FROM_WIN32(GetLastError()));
  4106. }
  4107. pfnRefreshPolicy = (PFNREFRESHPOLICY)GetProcAddress (hInstUserEnv,
  4108. "RefreshPolicy");
  4109. if (!pfnRefreshPolicy) {
  4110. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::RefreshGroupPolicy: Failed to find RefreshPolicy with %d."),
  4111. GetLastError()));
  4112. FreeLibrary (hInstUserEnv);
  4113. return (HRESULT_FROM_WIN32(GetLastError()));
  4114. }
  4115. //
  4116. // Refresh policy
  4117. //
  4118. pfnRefreshPolicy (bMachine);
  4119. //
  4120. // Clean up
  4121. //
  4122. FreeLibrary (hInstUserEnv);
  4123. return S_OK;
  4124. }
  4125. BSTR
  4126. ParseDomainName( LPWSTR szDomain )
  4127. {
  4128. BSTR bstrDomain = 0;
  4129. if ( szDomain )
  4130. {
  4131. WCHAR szXDomain[MAX_PATH*2];
  4132. DWORD dwSize = MAX_PATH*2;
  4133. if ( TranslateName( szDomain,
  4134. NameUnknown,
  4135. NameCanonical,
  4136. szXDomain,
  4137. &dwSize ) )
  4138. {
  4139. LPWSTR szTemp = wcschr( szXDomain, L'/' );
  4140. if ( szTemp )
  4141. {
  4142. *szTemp = 0;
  4143. }
  4144. bstrDomain = SysAllocString( szXDomain );
  4145. }
  4146. }
  4147. DebugMsg((DM_VERBOSE, TEXT("ParseDomainName: *** %s ***"), bstrDomain ? bstrDomain : L"" ));
  4148. return bstrDomain;
  4149. }
  4150. BSTR
  4151. ParseDomainName2( LPWSTR szDSObject )
  4152. {
  4153. BSTR bstrDomain = 0;
  4154. if ( !szDSObject )
  4155. {
  4156. return bstrDomain;
  4157. }
  4158. if ( CompareString( LOCALE_INVARIANT,
  4159. NORM_IGNORECASE,
  4160. szDSObject,
  4161. 7,
  4162. L"LDAP://",
  4163. 7 ) == CSTR_EQUAL )
  4164. {
  4165. szDSObject += 7;
  4166. }
  4167. if ( *szDSObject )
  4168. {
  4169. WCHAR szXDomain[MAX_PATH*2];
  4170. DWORD dwSize = MAX_PATH*2;
  4171. if ( TranslateName( szDSObject,
  4172. NameUnknown,
  4173. NameCanonical,
  4174. szXDomain,
  4175. &dwSize ) )
  4176. {
  4177. LPWSTR szTemp = wcschr( szXDomain, L'/' );
  4178. if ( szTemp )
  4179. {
  4180. *szTemp = 0;
  4181. }
  4182. bstrDomain = SysAllocString( szXDomain );
  4183. }
  4184. }
  4185. DebugMsg((DM_VERBOSE, TEXT("ParseDomainName2: *** %s ***"), bstrDomain ? bstrDomain : L"" ));
  4186. return bstrDomain;
  4187. }
  4188. INT_PTR CALLBACK CGroupPolicyObject::WQLFilterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  4189. {
  4190. CGroupPolicyObject* pGPO;
  4191. switch (message)
  4192. {
  4193. case WM_INITDIALOG:
  4194. {
  4195. HRESULT hr;
  4196. BSTR bstrName;
  4197. VARIANT var;
  4198. LPTSTR lpDisplayName;
  4199. pGPO = (CGroupPolicyObject*) (((LPPROPSHEETPAGE)lParam)->lParam);
  4200. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pGPO);
  4201. //
  4202. // Set the defaults
  4203. //
  4204. pGPO->m_pTempFilterString = NULL;
  4205. CheckDlgButton (hDlg, IDC_NONE, BST_CHECKED);
  4206. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), FALSE);
  4207. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), FALSE);
  4208. if (pGPO->m_dwFlags & GPO_OPEN_READ_ONLY)
  4209. {
  4210. EnableWindow (GetDlgItem(hDlg, IDC_NONE), FALSE);
  4211. EnableWindow (GetDlgItem(hDlg, IDC_THIS_FILTER), FALSE);
  4212. }
  4213. //
  4214. // Query for the filter
  4215. //
  4216. bstrName = SysAllocString (GPO_WQLFILTER_PROPERTY);
  4217. if (!bstrName)
  4218. {
  4219. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory")));
  4220. break;
  4221. }
  4222. VariantInit(&var);
  4223. hr = pGPO->m_pADs->Get(bstrName, &var);
  4224. //
  4225. // If we find a filter, initialize the UI and save the filter string in the
  4226. // temporary buffer
  4227. //
  4228. if (SUCCEEDED(hr))
  4229. {
  4230. //
  4231. // Check if we found a null filter (defined as one space character)
  4232. //
  4233. if (*var.bstrVal != TEXT(' '))
  4234. {
  4235. ULONG ulNoChars = lstrlen(var.bstrVal) + 1;
  4236. pGPO->m_pTempFilterString = new TCHAR [ulNoChars];
  4237. if (!pGPO->m_pTempFilterString)
  4238. {
  4239. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory for filter")));
  4240. SysFreeString (bstrName);
  4241. VariantClear (&var);
  4242. break;
  4243. }
  4244. hr = StringCchCopy (pGPO->m_pTempFilterString, ulNoChars, var.bstrVal);
  4245. ASSERT(SUCCEEDED(hr));
  4246. lpDisplayName = GetWMIFilterDisplayName (hDlg, pGPO->m_pTempFilterString, TRUE, FALSE);
  4247. if (lpDisplayName)
  4248. {
  4249. SetDlgItemText (hDlg, IDC_FILTER_NAME, lpDisplayName);
  4250. delete [] lpDisplayName;
  4251. CheckDlgButton (hDlg, IDC_NONE, BST_UNCHECKED);
  4252. CheckDlgButton (hDlg, IDC_THIS_FILTER, BST_CHECKED);
  4253. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), TRUE);
  4254. if (!(pGPO->m_dwFlags & GPO_OPEN_READ_ONLY))
  4255. {
  4256. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), TRUE);
  4257. }
  4258. }
  4259. }
  4260. }
  4261. else
  4262. {
  4263. if (hr != E_ADS_PROPERTY_NOT_FOUND)
  4264. {
  4265. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to query filter with 0x%x"), hr));
  4266. }
  4267. }
  4268. SysFreeString (bstrName);
  4269. VariantClear (&var);
  4270. break;
  4271. }
  4272. case WM_COMMAND:
  4273. {
  4274. pGPO = (CGroupPolicyObject *) GetWindowLongPtr (hDlg, DWLP_USER);
  4275. if (!pGPO) {
  4276. break;
  4277. }
  4278. if (LOWORD(wParam) == IDC_FILTER_BROWSE)
  4279. {
  4280. LPTSTR lpDisplayName = NULL, lpFilter = NULL;
  4281. WCHAR szDomain[2*MAX_PATH];
  4282. HRESULT hr = pGPO->GetPath( szDomain, ARRAYSIZE( szDomain ) );
  4283. if ( FAILED( hr ) )
  4284. {
  4285. break;
  4286. }
  4287. BSTR bstrDomain = ParseDomainName2( szDomain );
  4288. if (!GetWMIFilter(FALSE, hDlg, TRUE, &lpDisplayName, &(pGPO->m_pTempFilterString), bstrDomain ))
  4289. {
  4290. SysFreeString( bstrDomain );
  4291. break;
  4292. }
  4293. SysFreeString( bstrDomain );
  4294. if (!(pGPO->m_pTempFilterString)) {
  4295. SetDlgItemText (hDlg, IDC_FILTER_NAME, TEXT(""));
  4296. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), FALSE);
  4297. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), FALSE);
  4298. CheckDlgButton (hDlg, IDC_NONE, BST_CHECKED);
  4299. CheckDlgButton (hDlg, IDC_THIS_FILTER, BST_UNCHECKED);
  4300. SetFocus (GetDlgItem(hDlg, IDC_NONE));
  4301. SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0);
  4302. }
  4303. else {
  4304. SetDlgItemText (hDlg, IDC_FILTER_NAME, lpDisplayName);
  4305. delete [] lpDisplayName;
  4306. SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0);
  4307. }
  4308. }
  4309. if (LOWORD(wParam) == IDC_NONE)
  4310. {
  4311. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), FALSE);
  4312. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), FALSE);
  4313. if (pGPO->m_pTempFilterString)
  4314. {
  4315. delete [] pGPO->m_pTempFilterString;
  4316. pGPO->m_pTempFilterString = NULL;
  4317. }
  4318. }
  4319. else if (LOWORD(wParam) == IDC_THIS_FILTER)
  4320. {
  4321. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), TRUE);
  4322. EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), TRUE);
  4323. }
  4324. break;
  4325. }
  4326. case WM_NOTIFY:
  4327. {
  4328. pGPO = (CGroupPolicyObject *) GetWindowLongPtr (hDlg, DWLP_USER);
  4329. if (!pGPO) {
  4330. break;
  4331. }
  4332. switch (((NMHDR FAR*)lParam)->code)
  4333. {
  4334. case PSN_APPLY:
  4335. {
  4336. HRESULT hr;
  4337. BSTR bstrName;
  4338. VARIANT var;
  4339. //
  4340. // Save the current WQL filter
  4341. //
  4342. bstrName = SysAllocString (GPO_WQLFILTER_PROPERTY);
  4343. if (!bstrName)
  4344. {
  4345. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory")));
  4346. break;
  4347. }
  4348. VariantInit(&var);
  4349. var.vt = VT_BSTR;
  4350. var.bstrVal = SysAllocString (pGPO->m_pTempFilterString ? pGPO->m_pTempFilterString : TEXT(" "));
  4351. if (var.bstrVal)
  4352. {
  4353. hr = pGPO->m_pADs->Put(bstrName, var);
  4354. }
  4355. else
  4356. {
  4357. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory")));
  4358. SysFreeString (bstrName);
  4359. break;
  4360. }
  4361. SysFreeString (bstrName);
  4362. VariantClear (&var);
  4363. if (FAILED(hr))
  4364. {
  4365. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to put display name with 0x%x"), hr));
  4366. break;
  4367. }
  4368. //
  4369. // Commit the changes
  4370. //
  4371. hr = pGPO->m_pADs->SetInfo();
  4372. if (FAILED(hr))
  4373. {
  4374. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to commit changes with 0x%x"), hr));
  4375. break;
  4376. }
  4377. //
  4378. // Free the filter string if appropriate
  4379. //
  4380. if (((PSHNOTIFY *)lParam)->lParam)
  4381. {
  4382. if (pGPO->m_pTempFilterString)
  4383. {
  4384. delete [] pGPO->m_pTempFilterString;
  4385. pGPO->m_pTempFilterString = NULL;
  4386. }
  4387. }
  4388. break;
  4389. }
  4390. case PSN_RESET:
  4391. {
  4392. if (pGPO->m_pTempFilterString)
  4393. {
  4394. delete [] pGPO->m_pTempFilterString;
  4395. pGPO->m_pTempFilterString = NULL;
  4396. }
  4397. break;
  4398. }
  4399. }
  4400. break;
  4401. }
  4402. case WM_HELP: // F1
  4403. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  4404. (ULONG_PTR) (LPSTR) aWQLFilterHelpIds);
  4405. break;
  4406. case WM_CONTEXTMENU: // right mouse click
  4407. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  4408. (ULONG_PTR) (LPSTR) aWQLFilterHelpIds);
  4409. return (TRUE);
  4410. default:
  4411. break;
  4412. }
  4413. return FALSE;
  4414. }
  4415. #define MAX_BUTTON_LEN 64
  4416. //////////////////////////////////////////////////////////////////////////////
  4417. //
  4418. //////////////////////////////////////////////////////////////////////////////
  4419. INT_PTR CALLBACK CGroupPolicyObject::GPELinksDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  4420. {
  4421. GLPARAM * pglp = NULL;
  4422. switch (message)
  4423. {
  4424. case WM_INITDIALOG:
  4425. {
  4426. LV_COLUMN lvc = {LVCF_WIDTH};
  4427. RECT rc;
  4428. HWND hList = GetDlgItem(hDlg, IDC_RESULTLIST);
  4429. // Allocate the per dialog structure
  4430. pglp = (GLPARAM*)LocalAlloc (LPTR, sizeof(GLPARAM));
  4431. if (pglp)
  4432. {
  4433. pglp->pGPO = (CGroupPolicyObject*) (((LPPROPSHEETPAGE)lParam)->lParam);
  4434. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pglp);
  4435. pglp->pGPO->FillDomainList (GetDlgItem(hDlg, IDC_CBDOMAIN));
  4436. }
  4437. else
  4438. {
  4439. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: Failed to LocalAlloc in WM_INITDIALOG")));
  4440. }
  4441. // Set the Columns, in the list view
  4442. if (IsWindow(hList))
  4443. {
  4444. SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_LABELTIP,
  4445. LVS_EX_LABELTIP);
  4446. GetClientRect(hList, &rc);
  4447. lvc.cx = (rc.right - rc.left);
  4448. ListView_InsertColumn(hList, 0, &lvc);
  4449. }
  4450. // Show icon in the corner
  4451. Animate_Open(GetDlgItem(hDlg, IDAC_FIND), MAKEINTRESOURCE(IDA_FIND));
  4452. break;
  4453. }
  4454. case WM_COMMAND:
  4455. {
  4456. pglp = (GLPARAM *) GetWindowLongPtr (hDlg, DWLP_USER);
  4457. if (!pglp)
  4458. {
  4459. break;
  4460. }
  4461. if ((IDC_CBDOMAIN == LOWORD(wParam)) && ((CBN_SELCHANGE == HIWORD(wParam)) || (CBN_SELENDOK == HIWORD(wParam))))
  4462. {
  4463. // Clear the list view
  4464. pglp->fAbort = TRUE;
  4465. SendDlgItemMessage(hDlg, IDC_RESULTLIST, LVM_DELETEALLITEMS, 0, 0L);
  4466. break;
  4467. }
  4468. // If the IDC_ACTION was clicked then do search
  4469. if ((IDC_ACTION == LOWORD(wParam)) && (BN_CLICKED == HIWORD(wParam)))
  4470. {
  4471. // If we are have been asked to start a search, create the thread to do so
  4472. if (!pglp->fFinding)
  4473. {
  4474. HANDLE hThread = NULL;
  4475. DWORD dwThreadId = 0;
  4476. GLTHREADPARAM * pgltp = NULL;
  4477. int nCurSel = 0;
  4478. // Make sure something has been selected in the combo box
  4479. nCurSel = (int)SendDlgItemMessage (hDlg, IDC_CBDOMAIN, CB_GETCURSEL, 0, 0L);
  4480. if (CB_ERR == nCurSel)
  4481. {
  4482. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: There was no Domain selected in the combo box. Exiting.")));
  4483. break;
  4484. }
  4485. // Allocate the Thread Param structure
  4486. pgltp = (GLTHREADPARAM*)LocalAlloc (LPTR, sizeof(GLTHREADPARAM));
  4487. if (!pgltp)
  4488. {
  4489. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: Failed to LocalAlloc Thread Param structure")));
  4490. break;
  4491. }
  4492. pgltp->hDlg = hDlg;
  4493. pgltp->pGPO = pglp->pGPO;
  4494. pgltp->pfAbort = &pglp->fAbort;
  4495. pgltp->pszLDAPName = (LPOLESTR)SendDlgItemMessage (hDlg, IDC_CBDOMAIN, CB_GETITEMDATA, nCurSel, 0L);
  4496. if (!pgltp->pszLDAPName)
  4497. {
  4498. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: The LDAP name buffer was NULL.")));
  4499. LocalFree(pgltp);
  4500. break;
  4501. }
  4502. pgltp->pszLDAPName = MakeFullPath (pgltp->pszLDAPName, pglp->pGPO->m_pMachineName);
  4503. // Unset the abort flag
  4504. pglp->fAbort = FALSE;
  4505. // Clear the list view
  4506. SendDlgItemMessage(hDlg, IDC_RESULTLIST, LVM_DELETEALLITEMS, 0, 0L);
  4507. // Fire off the thread to fill the list view
  4508. hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)GLThreadFunc, pgltp, 0, &dwThreadId);
  4509. if (!hThread)
  4510. {
  4511. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: Could not create the search thread.")));
  4512. LocalFree(pgltp);
  4513. break;
  4514. }
  4515. CloseHandle (hThread);
  4516. // Change the text on the button to "Stop"
  4517. SendMessage (hDlg, PDM_CHANGEBUTTONTEXT, 0, 0L);
  4518. }
  4519. else
  4520. {
  4521. // The user wants to stop the search
  4522. pglp->fAbort = TRUE;
  4523. }
  4524. }
  4525. break;
  4526. }
  4527. case PDM_CHANGEBUTTONTEXT:
  4528. {
  4529. TCHAR szButtonText[MAX_BUTTON_LEN] = {0};
  4530. pglp = (GLPARAM *) GetWindowLongPtr (hDlg, DWLP_USER);
  4531. if (!pglp)
  4532. {
  4533. break;
  4534. }
  4535. if (!pglp->fFinding)
  4536. Animate_Play(GetDlgItem(hDlg, IDAC_FIND), 0, -1, -1);
  4537. else
  4538. Animate_Stop(GetDlgItem(hDlg, IDAC_FIND));
  4539. // Set the button to show appropriate text
  4540. LoadString (g_hInstance, pglp->fFinding ? IDS_FINDNOW: IDS_STOP, szButtonText, ARRAYSIZE(szButtonText));
  4541. SetDlgItemText (hDlg, IDC_ACTION, szButtonText);
  4542. // Flip the toggle
  4543. pglp->fFinding = !pglp->fFinding;
  4544. break;
  4545. }
  4546. case WM_NOTIFY:
  4547. {
  4548. pglp = (GLPARAM *) GetWindowLongPtr (hDlg, DWLP_USER);
  4549. if (!pglp)
  4550. {
  4551. break;
  4552. }
  4553. switch (((NMHDR FAR*)lParam)->code)
  4554. {
  4555. // In case thr user wants to cancel, bail from the thread
  4556. case PSN_QUERYCANCEL:
  4557. pglp->fAbort = TRUE;
  4558. break;
  4559. // In case thr user wants to close the prop sheet, bail from the thread
  4560. case PSN_APPLY:
  4561. case PSN_RESET:
  4562. {
  4563. int nCount = 0;
  4564. PSHNOTIFY * pNotify = (PSHNOTIFY *) lParam;
  4565. // User just hit the Apply button don't destroy everything.
  4566. if (!pNotify->lParam)
  4567. {
  4568. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  4569. return TRUE;
  4570. }
  4571. pglp->fAbort = TRUE;
  4572. // When the dialog is going away, delete all the data that was stored with each CB item in
  4573. // FillDomainList() are freed
  4574. if (IsWindow(GetDlgItem(hDlg, IDC_CBDOMAIN)))
  4575. {
  4576. nCount = (int) SendDlgItemMessage(hDlg, IDC_CBDOMAIN, CB_GETCOUNT, 0, 0L);
  4577. for (int nIndex = 0; nIndex < nCount; nIndex++)
  4578. {
  4579. LPOLESTR pszStr;
  4580. pszStr = (LPOLESTR)SendDlgItemMessage(hDlg, IDC_CBDOMAIN, CB_GETITEMDATA, nIndex, 0L);
  4581. if (pszStr)
  4582. delete [] pszStr;
  4583. }
  4584. }
  4585. // Free the per dialog structure
  4586. LocalFree (pglp);
  4587. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) NULL);
  4588. Animate_Close(GetDlgItem(hDlg, IDAC_FIND));
  4589. break;
  4590. }
  4591. }
  4592. break;
  4593. }
  4594. case WM_HELP: // F1
  4595. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  4596. (ULONG_PTR) (LPSTR) aLinkHelpIds);
  4597. break;
  4598. case WM_CONTEXTMENU: // right mouse click
  4599. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  4600. (ULONG_PTR) (LPSTR) aLinkHelpIds);
  4601. return (TRUE);
  4602. default:
  4603. break;
  4604. }
  4605. return FALSE;
  4606. }
  4607. //////////////////////////////////////////////////////////////////////////////
  4608. // The thread that will look call the recursive find function. This function will clean up
  4609. // the param structure that has been passed in
  4610. //////////////////////////////////////////////////////////////////////////////
  4611. DWORD WINAPI CGroupPolicyObject::GLThreadFunc(GLTHREADPARAM * pgltp)
  4612. {
  4613. LPTSTR lpGPO;
  4614. DWORD dwRet;
  4615. HINSTANCE hInstance = LoadLibrary(TEXT("GPEdit.dll"));
  4616. HRESULT hr;
  4617. //
  4618. // Initialize COM
  4619. //
  4620. hr = CoInitialize(NULL);
  4621. if (FAILED(hr))
  4622. {
  4623. return 0L;
  4624. }
  4625. //
  4626. // Make sure we have a thread param structure
  4627. //
  4628. if (pgltp)
  4629. {
  4630. pgltp->pGPO->AddRef();
  4631. lpGPO = MakeNamelessPath (pgltp->pGPO->m_pDSPath);
  4632. if (lpGPO)
  4633. {
  4634. //
  4635. // Check if the user wants to abort. Otherwise make recursive call
  4636. //
  4637. if (!*(pgltp->pfAbort))
  4638. {
  4639. dwRet = pgltp->pGPO->FindLinkInDomain(pgltp, lpGPO);
  4640. }
  4641. if ((!*(pgltp->pfAbort)) && dwRet)
  4642. {
  4643. pgltp->pGPO->FindLinkInSite(pgltp, lpGPO);
  4644. }
  4645. if (IsWindow(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST)))
  4646. {
  4647. ListView_SetItemState(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), 0, LVIS_SELECTED |LVIS_FOCUSED, LVIS_SELECTED |LVIS_FOCUSED);
  4648. }
  4649. //
  4650. // Switch the button text, change the cursor, and free the param that the
  4651. // dialog proc allocated and sent to us
  4652. //
  4653. SendMessage(pgltp->hDlg, PDM_CHANGEBUTTONTEXT, 0, 0L);
  4654. LocalFree (lpGPO);
  4655. }
  4656. pgltp->pGPO->Release();
  4657. LocalFree(pgltp->pszLDAPName);
  4658. LocalFree(pgltp);
  4659. }
  4660. //
  4661. // Uninitialize COM
  4662. //
  4663. CoUninitialize();
  4664. FreeLibraryAndExitThread(hInstance, 0);
  4665. return 0L;
  4666. }
  4667. DWORD WINAPI CGroupPolicyObject::FindLinkInSite(GLTHREADPARAM * pgltp, LPTSTR lpGPO)
  4668. {
  4669. IADsContainer * pADsContainer = NULL;
  4670. HRESULT hr;
  4671. IEnumVARIANT *pVar = NULL;
  4672. IADs * pADs = NULL;
  4673. VARIANT var;
  4674. ULONG ulResult;
  4675. IDispatch * pDispatch = NULL;
  4676. BSTR bstrClassName;
  4677. BSTR bstrSite = NULL;
  4678. IADsPathname * pADsPathname = NULL;
  4679. //
  4680. // Create a pathname object we can work with
  4681. //
  4682. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  4683. IID_IADsPathname, (LPVOID*)&pADsPathname);
  4684. if (FAILED(hr))
  4685. {
  4686. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to create adspathname instance with 0x%x"), hr));
  4687. goto Exit;
  4688. }
  4689. //
  4690. // Add the gpo name
  4691. //
  4692. BSTR bstrLDAPName = SysAllocString( pgltp->pszLDAPName );
  4693. if ( bstrLDAPName == NULL )
  4694. {
  4695. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to allocate BSTR memory")));
  4696. hr = E_OUTOFMEMORY;
  4697. goto Exit;
  4698. }
  4699. hr = pADsPathname->Set ( bstrLDAPName, ADS_SETTYPE_FULL);
  4700. SysFreeString( bstrLDAPName );
  4701. if (FAILED(hr))
  4702. {
  4703. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to set pathname with 0x%x"), hr));
  4704. goto Exit;
  4705. }
  4706. //
  4707. // Add the configuration folder to the path
  4708. //
  4709. BSTR bstrCNConfiguration = SysAllocString( TEXT("CN=Configuration") );
  4710. if ( bstrCNConfiguration == NULL )
  4711. {
  4712. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to allocate BSTR memory")));
  4713. hr = E_OUTOFMEMORY;
  4714. goto Exit;
  4715. }
  4716. hr = pADsPathname->AddLeafElement ( bstrCNConfiguration );
  4717. SysFreeString( bstrCNConfiguration );
  4718. if (FAILED(hr))
  4719. {
  4720. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to add configuration folder with 0x%x"), hr));
  4721. goto Exit;
  4722. }
  4723. //
  4724. // Add the sites container to the path
  4725. //
  4726. BSTR bstrCNSites = SysAllocString( TEXT("CN=Sites") );
  4727. if ( bstrCNSites == NULL )
  4728. {
  4729. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to allocate BSTR memory")));
  4730. hr = E_OUTOFMEMORY;
  4731. goto Exit;
  4732. }
  4733. hr = pADsPathname->AddLeafElement (bstrCNSites);
  4734. SysFreeString( bstrCNSites );
  4735. if (FAILED(hr))
  4736. {
  4737. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to add sites folder with 0x%x"), hr));
  4738. goto Exit;
  4739. }
  4740. //
  4741. // Retreive the container path
  4742. //
  4743. hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrSite);
  4744. if (FAILED(hr))
  4745. {
  4746. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to retreive site path with 0x%x"), hr));
  4747. goto Exit;
  4748. }
  4749. // Create Enumerator
  4750. hr = OpenDSObject(bstrSite, IID_IADsContainer, (void **)&pADsContainer);
  4751. if (FAILED(hr))
  4752. {
  4753. DebugMsg((DM_VERBOSE, TEXT("FindLinkInSite: Failed to get gpo container interface with 0x%x for object %s"),
  4754. hr, bstrSite));
  4755. goto Exit;
  4756. }
  4757. // Build the enumerator
  4758. hr = ADsBuildEnumerator (pADsContainer, &pVar);
  4759. if (FAILED(hr))
  4760. {
  4761. DebugMsg((DM_WARNING, TEXT("FindLinkInSite: Failed to get enumerator with 0x%x"), hr));
  4762. goto Exit;
  4763. }
  4764. //
  4765. // Enumerate
  4766. //
  4767. while (TRUE)
  4768. {
  4769. TCHAR lpSite[] = TEXT("site");
  4770. DWORD dwStrLen = lstrlen (lpSite);
  4771. // Check if the user wants to abort. Before proceeding
  4772. if (*(pgltp->pfAbort))
  4773. {
  4774. break;
  4775. }
  4776. VariantInit(&var);
  4777. hr = ADsEnumerateNext(pVar, 1, &var, &ulResult);
  4778. if (S_FALSE == hr)
  4779. {
  4780. VariantClear (&var);
  4781. break;
  4782. }
  4783. if ((FAILED(hr)) || (var.vt != VT_DISPATCH))
  4784. {
  4785. DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to enumerator with 0x%x or we didn't get the IDispatch"), hr));
  4786. VariantClear (&var);
  4787. break;
  4788. }
  4789. if (*(pgltp->pfAbort))
  4790. {
  4791. VariantClear (&var);
  4792. break;
  4793. }
  4794. //
  4795. // We found something, get the IDispatch interface
  4796. //
  4797. pDispatch = var.pdispVal;
  4798. if (!pDispatch)
  4799. {
  4800. VariantClear (&var);
  4801. goto Exit;
  4802. }
  4803. //
  4804. // Now query for the IADs interface so we can get some
  4805. // properties from this object
  4806. //
  4807. hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
  4808. if (FAILED(hr))
  4809. {
  4810. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: QI for IADs failed with 0x%x"), hr));
  4811. VariantClear (&var);
  4812. goto Exit;
  4813. }
  4814. //
  4815. // Get the relative and class names
  4816. //
  4817. hr = pADs->get_Class (&bstrClassName);
  4818. if (FAILED(hr))
  4819. {
  4820. DebugMsg((DM_WARNING, TEXT("DSDelnodeRecurse: Failed get class name with 0x%x"), hr));
  4821. pADs->Release();
  4822. VariantClear (&var);
  4823. goto Exit;
  4824. }
  4825. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  4826. lpSite, dwStrLen, bstrClassName, dwStrLen) == CSTR_EQUAL)
  4827. {
  4828. VARIANT varLink;
  4829. BSTR bstrLinkProp;
  4830. VariantInit(&varLink);
  4831. bstrLinkProp = SysAllocString(GPM_LINK_PROPERTY);
  4832. if (bstrLinkProp)
  4833. {
  4834. // Now get the Name property
  4835. hr = pADs->Get(bstrLinkProp, &varLink);
  4836. // Create the new LDAP:// string and call FindLinkInDomain() recursively
  4837. if (SUCCEEDED(hr) && wcsstr(varLink.bstrVal, lpGPO))
  4838. {
  4839. VARIANT varName;
  4840. BSTR bstrNameProp;
  4841. VariantInit(&varName);
  4842. bstrNameProp = SysAllocString(GPM_NAME_PROPERTY);
  4843. if (bstrNameProp)
  4844. {
  4845. // Now get the Name property
  4846. hr = pADs->Get(bstrNameProp, &varName);
  4847. if (SUCCEEDED(hr))
  4848. {
  4849. LV_ITEM lvi = {LVIF_TEXT};
  4850. LPTSTR pszTemp = MakeNamelessPath(bstrSite);
  4851. if (pszTemp)
  4852. {
  4853. ULONG ulLen = wcslen(pszTemp) + 2 + wcslen(varName.bstrVal);
  4854. LPOLESTR pszTranslated = new OLECHAR[ulLen];
  4855. if (pszTranslated)
  4856. {
  4857. // Move pointer over the lDAP:// string and insert the rest into the listview
  4858. pszTemp += wcslen(TEXT("LDAP://"));
  4859. lvi.iItem = 0x7FFFFFFF;
  4860. ULONG ulNeeded = ulLen;
  4861. BOOL bTranslated;
  4862. bTranslated = TranslateName(pszTemp, NameFullyQualifiedDN, NameCanonical, pszTranslated, &ulNeeded);
  4863. if ( ! bTranslated && ( ulNeeded > ulLen ) )
  4864. {
  4865. delete [] pszTranslated;
  4866. pszTranslated = new OLECHAR[ulNeeded];
  4867. if ( pszTranslated )
  4868. {
  4869. bTranslated = TranslateName(pszTemp, NameFullyQualifiedDN, NameCanonical, pszTranslated, &ulNeeded);
  4870. }
  4871. }
  4872. ulLen = ulNeeded;
  4873. if ( bTranslated )
  4874. {
  4875. ULONG ulFullPath;
  4876. WCHAR* pszFullPath;
  4877. ulFullPath = ulLen + sizeof(L'/') / sizeof(WCHAR) + lstrlen( varName.bstrVal ) + 1;
  4878. pszFullPath = new OLECHAR[ ulFullPath ];
  4879. if ( pszFullPath )
  4880. {
  4881. HRESULT hrCopy;
  4882. hrCopy = StringCchCopy( pszFullPath, ulFullPath, pszTranslated );
  4883. ASSERT(SUCCEEDED(hrCopy));
  4884. hrCopy = StringCchCat (pszFullPath, ulFullPath, TEXT("/"));
  4885. ASSERT(SUCCEEDED(hrCopy));
  4886. hrCopy = StringCchCat (pszFullPath, ulFullPath, varName.bstrVal);
  4887. ASSERT(SUCCEEDED(hrCopy));
  4888. lvi.pszText = pszFullPath;
  4889. ListView_InsertItem(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), &lvi);
  4890. delete [] pszFullPath;
  4891. }
  4892. }
  4893. delete [] pszTranslated;
  4894. }
  4895. LocalFree (pszTemp);
  4896. }
  4897. }
  4898. SysFreeString (bstrNameProp);
  4899. }
  4900. VariantClear (&varName);
  4901. }
  4902. SysFreeString (bstrLinkProp);
  4903. }
  4904. VariantClear (&varLink);
  4905. }
  4906. pADs->Release();
  4907. SysFreeString (bstrClassName);
  4908. }
  4909. Exit:
  4910. if (pADsContainer)
  4911. pADsContainer->Release();
  4912. if (pADsPathname)
  4913. pADsPathname->Release();
  4914. if (bstrSite)
  4915. SysFreeString (bstrSite);
  4916. return 1L;
  4917. }
  4918. //////////////////////////////////////////////////////////////////////////////
  4919. // Recursive call that will look through all domains and OUs for our GUID
  4920. //////////////////////////////////////////////////////////////////////////////
  4921. DWORD WINAPI CGroupPolicyObject::FindLinkInDomain(GLTHREADPARAM * pgltp, LPTSTR lpGPO)
  4922. {
  4923. IADs * pADs = NULL;
  4924. IADsContainer * pADsContainer = NULL;
  4925. HRESULT hr;
  4926. IEnumVARIANT *pVar = NULL;
  4927. VARIANT var;
  4928. ULONG ulResult;
  4929. BSTR bstrClassName;
  4930. IDispatch * pDispatch = NULL;
  4931. DWORD dwResult = 1;
  4932. // Check if the user wants to abort. Before proceeding
  4933. if (*(pgltp->pfAbort))
  4934. {
  4935. return 0;
  4936. }
  4937. // Bind to Object
  4938. hr = OpenDSObject(pgltp->pszLDAPName, IID_IADs, (void **)&pADs);
  4939. if (SUCCEEDED(hr))
  4940. {
  4941. BSTR bstrLinkProp;
  4942. VariantInit(&var);
  4943. bstrLinkProp = SysAllocString(GPM_LINK_PROPERTY);
  4944. if (bstrLinkProp)
  4945. {
  4946. // Now get the link property
  4947. hr = pADs->Get(bstrLinkProp, &var);
  4948. // Check if out GUID is in there.
  4949. if (SUCCEEDED(hr) && StrStrI(var.bstrVal, lpGPO))
  4950. {
  4951. LV_ITEM lvi = {LVIF_TEXT};
  4952. //
  4953. // Check if this is a forest path
  4954. //
  4955. if (IsForest(pgltp->pszLDAPName))
  4956. {
  4957. TCHAR szForest[50] = {0};
  4958. LoadString (g_hInstance, IDS_FOREST, szForest, ARRAYSIZE(szForest));
  4959. lvi.iItem = 0x7FFFFFFF;
  4960. lvi.pszText = szForest;
  4961. ListView_InsertItem(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), &lvi);
  4962. }
  4963. else
  4964. {
  4965. LPTSTR pszTemp = MakeNamelessPath(pgltp->pszLDAPName);
  4966. if (pszTemp)
  4967. {
  4968. ULONG ulLen = wcslen(pszTemp) + 2;
  4969. LPOLESTR pszTranslated = new OLECHAR[ulLen];
  4970. if (pszTranslated)
  4971. {
  4972. // Move pointer over the lDAP:// string and insert the rest into the listview
  4973. pszTemp += wcslen(TEXT("LDAP://"));
  4974. lvi.iItem = 0x7FFFFFFF;
  4975. if (TranslateName(pszTemp, NameFullyQualifiedDN, NameCanonical, pszTranslated, &ulLen))
  4976. {
  4977. lvi.pszText = pszTranslated;
  4978. ListView_InsertItem(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), &lvi);
  4979. }
  4980. delete [] pszTranslated;
  4981. }
  4982. LocalFree (pszTemp);
  4983. }
  4984. }
  4985. }
  4986. // Cleanup
  4987. SysFreeString(bstrLinkProp);
  4988. }
  4989. VariantClear(&var);
  4990. pADs->Release();
  4991. }
  4992. else
  4993. {
  4994. DebugMsg((DM_VERBOSE, TEXT("FindLinkInDomain: Failed to get IID_IADs. hr: 0x%x, for %s"),hr, pgltp->pszLDAPName));
  4995. ReportError(pgltp->hDlg, hr, IDS_DSBINDFAILED);
  4996. dwResult = 0;
  4997. goto Exit;
  4998. }
  4999. // Check if the user wants to abort. Before proceeding
  5000. if (*(pgltp->pfAbort))
  5001. {
  5002. dwResult = 0;
  5003. goto Exit;
  5004. }
  5005. // Create Enumerator
  5006. hr = OpenDSObject(pgltp->pszLDAPName, IID_IADsContainer, (void **)&pADsContainer);
  5007. if (FAILED(hr))
  5008. {
  5009. DebugMsg((DM_VERBOSE, TEXT("FindLinkInDomain: Failed to get gpo container interface with 0x%x for object %s"),
  5010. hr, pgltp->pszLDAPName));
  5011. dwResult = 0;
  5012. goto Exit;
  5013. }
  5014. hr = ADsBuildEnumerator (pADsContainer, &pVar);
  5015. if (FAILED(hr))
  5016. {
  5017. DebugMsg((DM_WARNING, TEXT("FindLinkInDomain: Failed to get enumerator with 0x%x"), hr));
  5018. dwResult = 0;
  5019. goto Exit;
  5020. }
  5021. //
  5022. // Enumerate
  5023. //
  5024. while (TRUE)
  5025. {
  5026. TCHAR lpOU[] = TEXT("organizationalUnit");
  5027. DWORD dwStrLen = lstrlen (lpOU);
  5028. // Check if the user wants to abort. Before proceeding
  5029. if (*(pgltp->pfAbort))
  5030. {
  5031. break;
  5032. }
  5033. VariantInit(&var);
  5034. hr = ADsEnumerateNext(pVar, 1, &var, &ulResult);
  5035. if (S_FALSE == hr)
  5036. {
  5037. VariantClear (&var);
  5038. break;
  5039. }
  5040. if ((FAILED(hr)) || (var.vt != VT_DISPATCH))
  5041. {
  5042. VariantClear (&var);
  5043. break;
  5044. }
  5045. if (*(pgltp->pfAbort))
  5046. {
  5047. VariantClear (&var);
  5048. break;
  5049. }
  5050. //
  5051. // We found something, get the IDispatch interface
  5052. //
  5053. pDispatch = var.pdispVal;
  5054. if (!pDispatch)
  5055. {
  5056. VariantClear (&var);
  5057. dwResult = 0;
  5058. goto Exit;
  5059. }
  5060. //
  5061. // Now query for the IADs interface so we can get some
  5062. // properties from this object
  5063. //
  5064. hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
  5065. if (FAILED(hr))
  5066. {
  5067. DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: QI for IADs failed with 0x%x"), hr));
  5068. VariantClear (&var);
  5069. dwResult = 0;
  5070. goto Exit;
  5071. }
  5072. //
  5073. // Get the relative and class names
  5074. //
  5075. hr = pADs->get_Class (&bstrClassName);
  5076. if (FAILED(hr))
  5077. {
  5078. DebugMsg((DM_WARNING, TEXT("DSDelnodeRecurse: Failed get class name with 0x%x"), hr));
  5079. pADs->Release();
  5080. VariantClear (&var);
  5081. dwResult = 0;
  5082. goto Exit;
  5083. }
  5084. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5085. lpOU, dwStrLen, bstrClassName, dwStrLen) == CSTR_EQUAL)
  5086. {
  5087. VARIANT varName;
  5088. BSTR bstrNameProp;
  5089. VariantInit(&varName);
  5090. bstrNameProp = SysAllocString(GPM_NAME_PROPERTY);
  5091. if (bstrNameProp)
  5092. {
  5093. // Now get the Name property
  5094. hr = pADs->Get(bstrNameProp, &varName);
  5095. // Create the new LDAP:// string and call FindLinkInDomain() recursively
  5096. if (SUCCEEDED(hr))
  5097. {
  5098. GLTHREADPARAM gltp = *pgltp;
  5099. IADsPathname * pADsPathname;
  5100. ULONG ulNoChars = wcslen(varName.bstrVal) + 10;
  5101. LPOLESTR pszNewName = new OLECHAR[ulNoChars];
  5102. BSTR bstr;
  5103. //
  5104. // Build the new element name
  5105. //
  5106. if (!pszNewName)
  5107. {
  5108. dwResult = 0;
  5109. goto Exit;
  5110. }
  5111. hr = StringCchCopy(pszNewName, ulNoChars, TEXT("OU="));
  5112. if (SUCCEEDED(hr))
  5113. {
  5114. hr = StringCchCat(pszNewName, ulNoChars, varName.bstrVal);
  5115. }
  5116. if (FAILED(hr))
  5117. {
  5118. delete [] pszNewName;
  5119. dwResult = 0;
  5120. goto Exit;
  5121. }
  5122. //
  5123. // Create a pathname object we can work with
  5124. //
  5125. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  5126. IID_IADsPathname, (LPVOID*)&pADsPathname);
  5127. if (FAILED(hr))
  5128. {
  5129. delete [] pszNewName;
  5130. dwResult = 0;
  5131. goto Exit;
  5132. }
  5133. //
  5134. // Set the current name
  5135. //
  5136. BSTR bstrLDAPName = SysAllocString( pgltp->pszLDAPName );
  5137. if ( bstrLDAPName == NULL )
  5138. {
  5139. delete [] pszNewName;
  5140. pADsPathname->Release();
  5141. dwResult = 0;
  5142. goto Exit;
  5143. }
  5144. hr = pADsPathname->Set ( bstrLDAPName, ADS_SETTYPE_FULL);
  5145. SysFreeString( bstrLDAPName );
  5146. if (FAILED(hr))
  5147. {
  5148. delete [] pszNewName;
  5149. pADsPathname->Release();
  5150. dwResult = 0;
  5151. goto Exit;
  5152. }
  5153. //
  5154. // Check for escape characters
  5155. //
  5156. BSTR bstrNewName = SysAllocString( pszNewName );
  5157. delete [] pszNewName;
  5158. if ( bstrNewName == NULL )
  5159. {
  5160. pADsPathname->Release();
  5161. dwResult = 0;
  5162. goto Exit;
  5163. }
  5164. hr = pADsPathname->GetEscapedElement (0, bstrNewName, &bstr);
  5165. SysFreeString( bstrNewName );
  5166. if (FAILED(hr))
  5167. {
  5168. pADsPathname->Release();
  5169. dwResult = 0;
  5170. goto Exit;
  5171. }
  5172. //
  5173. // Add the new element
  5174. //
  5175. hr = pADsPathname->AddLeafElement (bstr);
  5176. SysFreeString (bstr);
  5177. if (FAILED(hr))
  5178. {
  5179. pADsPathname->Release();
  5180. dwResult = 0;
  5181. goto Exit;
  5182. }
  5183. //
  5184. // Get the new path
  5185. //
  5186. hr = pADsPathname->Retrieve(ADS_FORMAT_X500, &bstr);
  5187. pADsPathname->Release();
  5188. if (FAILED(hr))
  5189. {
  5190. dwResult = 0;
  5191. goto Exit;
  5192. }
  5193. //
  5194. // Recurse
  5195. //
  5196. gltp.pszLDAPName = bstr;
  5197. if (FindLinkInDomain(&gltp, lpGPO) == 0)
  5198. {
  5199. SysFreeString( bstr );
  5200. dwResult = 0;
  5201. goto Exit;
  5202. }
  5203. SysFreeString (bstr);
  5204. }
  5205. SysFreeString (bstrNameProp);
  5206. }
  5207. VariantClear (&varName);
  5208. }
  5209. pADs->Release();
  5210. SysFreeString (bstrClassName);
  5211. }
  5212. Exit:
  5213. if (pADsContainer)
  5214. pADsContainer->Release();
  5215. return dwResult;
  5216. }
  5217. //////////////////////////////////////////////////////////////////////////////
  5218. // Fill the combobox with available domains
  5219. //////////////////////////////////////////////////////////////////////////////
  5220. BOOL CGroupPolicyObject::FillDomainList (HWND hWndCombo)
  5221. {
  5222. HRESULT hr;
  5223. DWORD dwIndex = 0;
  5224. LPOLESTR pszDomain;
  5225. LPTSTR lpTemp;
  5226. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  5227. // get the ordered tree of domains
  5228. LOOKDATA * pDomainList = BuildDomainList(NULL);
  5229. LOOKDATA *pRemember = pDomainList;
  5230. // now walk the tree, adding elements to the dialog box
  5231. int nCBIndex;
  5232. // start at the head
  5233. while (pDomainList)
  5234. {
  5235. // add the LDAP path for the doman in this node
  5236. //SendMessage(hWndCombo, CB_INSERTSTRING, (WPARAM) -1, (LPARAM)(LPCTSTR) pDomainList->szData);
  5237. nCBIndex = (int)SendMessage(hWndCombo, CB_INSERTSTRING, (WPARAM) -1, (LPARAM)(LPCTSTR) pDomainList->szName);
  5238. SendMessage(hWndCombo, CB_SETITEMDATA, (WPARAM) nCBIndex, (LPARAM)(LPCTSTR) pDomainList->szData);
  5239. if (pDomainList->pChild)
  5240. {
  5241. // go to its child
  5242. pDomainList = pDomainList->pChild;
  5243. }
  5244. else
  5245. {
  5246. if (pDomainList->pSibling)
  5247. {
  5248. // go to its sibling if there are no children
  5249. pDomainList = pDomainList->pSibling;
  5250. }
  5251. else
  5252. {
  5253. // there are no children and no siblings
  5254. // back up until we find a parent with a sibling
  5255. // or there are no more parents (we're done)
  5256. do
  5257. {
  5258. pDomainList = pDomainList->pParent;
  5259. if (pDomainList)
  5260. {
  5261. if (pDomainList->pSibling)
  5262. {
  5263. pDomainList = pDomainList->pSibling;
  5264. break;
  5265. }
  5266. }
  5267. else
  5268. {
  5269. break;
  5270. }
  5271. } while (TRUE);
  5272. }
  5273. }
  5274. }
  5275. FreeDomainInfo (pRemember);
  5276. //
  5277. // Select the current domain in the combobox
  5278. //
  5279. pszDomain = GetDomainFromLDAPPath(m_pDSPath);
  5280. if (pszDomain)
  5281. {
  5282. //
  5283. // Convert LDAP to dot (DN) style
  5284. //
  5285. hr = ConvertToDotStyle (pszDomain, &lpTemp);
  5286. if (SUCCEEDED(hr))
  5287. {
  5288. dwIndex = (DWORD) SendMessage (hWndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1,
  5289. (LONG_PTR)lpTemp);
  5290. if (dwIndex == CB_ERR)
  5291. {
  5292. dwIndex = 0;
  5293. }
  5294. LocalFree (lpTemp);
  5295. }
  5296. delete [] pszDomain;
  5297. }
  5298. SendMessage (hWndCombo, CB_SETCURSEL, (WPARAM)dwIndex, 0);
  5299. SetCursor(hcur);
  5300. return TRUE;
  5301. }
  5302. INT_PTR CALLBACK CGroupPolicyObject::PropertiesDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  5303. {
  5304. CGroupPolicyObject * pGPO;
  5305. static BOOL bDirty;
  5306. static BOOL bDisableWarningIssued;
  5307. switch (message)
  5308. {
  5309. case WM_INITDIALOG:
  5310. {
  5311. DWORD dwTemp;
  5312. LPTSTR lpEnd;
  5313. TCHAR szBuffer[2*MAX_PATH];
  5314. TCHAR szDate[100];
  5315. TCHAR szTime[100];
  5316. TCHAR szFormat[80];
  5317. TCHAR szVersion[100];
  5318. WIN32_FILE_ATTRIBUTE_DATA fad;
  5319. FILETIME filetime, CreateTime, ChangeTime;
  5320. SYSTEMTIME systime;
  5321. LPTSTR lpResult;
  5322. LPOLESTR pszDomain;
  5323. ULONG ulVersion = 0;
  5324. USHORT uMachine, uUser;
  5325. VARIANT var;
  5326. BSTR bstrName;
  5327. LPTSTR lpDisplayName;
  5328. WORD wDosDate, wDosTime;
  5329. ULONG ulNoChars;
  5330. HRESULT hr;
  5331. pGPO = (CGroupPolicyObject *) (((LPPROPSHEETPAGE)lParam)->lParam);
  5332. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pGPO);
  5333. //
  5334. // Initialize
  5335. //
  5336. if ((pGPO->m_pMachineName) && (pGPO->m_gpoType == GPOTypeDS))
  5337. {
  5338. ulNoChars = lstrlen(pGPO->m_pDisplayName) + lstrlen(pGPO->m_pMachineName) + 5;
  5339. lpDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  5340. if (lpDisplayName)
  5341. {
  5342. LoadString (g_hInstance, IDS_NAMEFORMAT, szFormat, ARRAYSIZE(szFormat));
  5343. (void) StringCchPrintf (lpDisplayName, ulNoChars, szFormat, pGPO->m_pDisplayName, pGPO->m_pMachineName);
  5344. SetDlgItemText (hDlg, IDC_TITLE, lpDisplayName);
  5345. LocalFree (lpDisplayName);
  5346. }
  5347. }
  5348. else
  5349. {
  5350. SetDlgItemText (hDlg, IDC_TITLE, pGPO->m_pDisplayName);
  5351. }
  5352. if (pGPO->m_gpoType == GPOTypeDS)
  5353. {
  5354. if (IsForest(pGPO->m_pDSPath))
  5355. {
  5356. LoadString (g_hInstance, IDS_FORESTHEADING, szBuffer, ARRAYSIZE(szBuffer));
  5357. SetDlgItemText (hDlg, IDC_DOMAIN_HEADING, szBuffer);
  5358. }
  5359. pszDomain = GetDomainFromLDAPPath(pGPO->m_pDSPath);
  5360. if (pszDomain)
  5361. {
  5362. if (SUCCEEDED(ConvertToDotStyle (pszDomain, &lpResult)))
  5363. {
  5364. SetDlgItemText (hDlg, IDC_DOMAIN, lpResult);
  5365. LocalFree (lpResult);
  5366. }
  5367. delete [] pszDomain;
  5368. }
  5369. SetDlgItemText (hDlg, IDC_UNIQUE_NAME, pGPO->m_pName);
  5370. }
  5371. else
  5372. {
  5373. LoadString (g_hInstance, IDS_NOTAPPLICABLE, szBuffer, ARRAYSIZE(szBuffer));
  5374. SetDlgItemText (hDlg, IDC_DOMAIN, szBuffer);
  5375. SetDlgItemText (hDlg, IDC_UNIQUE_NAME, szBuffer);
  5376. }
  5377. if (SUCCEEDED(pGPO->GetOptions(&dwTemp)))
  5378. {
  5379. if (dwTemp & GPO_OPTION_DISABLE_MACHINE)
  5380. {
  5381. CheckDlgButton (hDlg, IDC_DISABLE_COMPUTER, BST_CHECKED);
  5382. }
  5383. if (dwTemp & GPO_OPTION_DISABLE_USER)
  5384. {
  5385. CheckDlgButton (hDlg, IDC_DISABLE_USER, BST_CHECKED);
  5386. }
  5387. }
  5388. hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), pGPO->m_pFileSysPath);
  5389. if (SUCCEEDED(hr))
  5390. {
  5391. lpEnd = CheckSlash (szBuffer);
  5392. hr = StringCchCat (szBuffer, ARRAYSIZE(szBuffer), TEXT("gpt.ini"));
  5393. }
  5394. if (SUCCEEDED(hr))
  5395. {
  5396. if (pGPO->m_gpoType == GPOTypeDS)
  5397. {
  5398. VariantInit(&var);
  5399. bstrName = SysAllocString (GPO_VERSION_PROPERTY);
  5400. if (bstrName)
  5401. {
  5402. if (SUCCEEDED(pGPO->m_pADs->Get(bstrName, &var)))
  5403. {
  5404. ulVersion = var.lVal;
  5405. }
  5406. SysFreeString (bstrName);
  5407. }
  5408. VariantClear (&var);
  5409. }
  5410. else
  5411. {
  5412. ulVersion = GetPrivateProfileInt(TEXT("General"), TEXT("Version"), 0, szBuffer);
  5413. }
  5414. }
  5415. uMachine = (USHORT) LOWORD(ulVersion);
  5416. uUser = (USHORT) HIWORD(ulVersion);
  5417. LoadString (g_hInstance, IDS_REVISIONFORMAT, szFormat, ARRAYSIZE(szFormat));
  5418. (void) StringCchPrintf (szVersion, ARRAYSIZE(szVersion), szFormat, uMachine, uUser);
  5419. SetDlgItemText (hDlg, IDC_REVISION, szVersion);
  5420. //
  5421. // Get the date / time info
  5422. //
  5423. CreateTime.dwLowDateTime = 0;
  5424. CreateTime.dwHighDateTime = 0;
  5425. ChangeTime.dwLowDateTime = 0;
  5426. ChangeTime.dwHighDateTime = 0;
  5427. if (pGPO->m_gpoType == GPOTypeDS)
  5428. {
  5429. //
  5430. // Get the creation time
  5431. //
  5432. VariantInit(&var);
  5433. bstrName = SysAllocString (TEXT("whenCreated"));
  5434. if (bstrName)
  5435. {
  5436. if (SUCCEEDED(pGPO->m_pADs->Get(bstrName, &var)))
  5437. {
  5438. if (VariantTimeToDosDateTime (var.date, &wDosDate, &wDosTime))
  5439. {
  5440. DosDateTimeToFileTime (wDosDate, wDosTime, &CreateTime);
  5441. }
  5442. }
  5443. SysFreeString (bstrName);
  5444. }
  5445. VariantClear (&var);
  5446. //
  5447. // Get the last write time
  5448. //
  5449. VariantInit(&var);
  5450. bstrName = SysAllocString (TEXT("whenChanged"));
  5451. if (bstrName)
  5452. {
  5453. if (SUCCEEDED(pGPO->m_pADs->Get(bstrName, &var)))
  5454. {
  5455. if (VariantTimeToDosDateTime (var.date, &wDosDate, &wDosTime))
  5456. {
  5457. DosDateTimeToFileTime (wDosDate, wDosTime, &ChangeTime);
  5458. }
  5459. }
  5460. SysFreeString (bstrName);
  5461. }
  5462. VariantClear (&var);
  5463. }
  5464. else
  5465. {
  5466. //
  5467. // Get the time info from the gpt.ini file
  5468. //
  5469. if (GetFileAttributesEx (szBuffer, GetFileExInfoStandard, &fad))
  5470. {
  5471. CreateTime.dwLowDateTime = fad.ftCreationTime.dwLowDateTime;
  5472. CreateTime.dwHighDateTime = fad.ftCreationTime.dwHighDateTime;
  5473. ChangeTime.dwLowDateTime = fad.ftLastWriteTime.dwLowDateTime;
  5474. ChangeTime.dwHighDateTime = fad.ftLastWriteTime.dwHighDateTime;
  5475. }
  5476. }
  5477. //
  5478. // Format & display the date / time information
  5479. //
  5480. FileTimeToLocalFileTime (&CreateTime, &filetime);
  5481. FileTimeToSystemTime (&filetime, &systime);
  5482. GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
  5483. NULL, szDate, ARRAYSIZE (szDate));
  5484. GetTimeFormat (LOCALE_USER_DEFAULT, 0, &systime,
  5485. NULL, szTime, ARRAYSIZE (szTime));
  5486. LoadString (g_hInstance, IDS_DATETIMEFORMAT, szFormat, ARRAYSIZE(szFormat));
  5487. (void) StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), szFormat, szDate, szTime);
  5488. SetDlgItemText (hDlg, IDC_CREATE_DATE, szBuffer);
  5489. FileTimeToLocalFileTime (&ChangeTime, &filetime);
  5490. FileTimeToSystemTime (&filetime, &systime);
  5491. GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
  5492. NULL, szDate, ARRAYSIZE (szDate));
  5493. GetTimeFormat (LOCALE_USER_DEFAULT, 0, &systime,
  5494. NULL, szTime, ARRAYSIZE (szTime));
  5495. (void) StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), szFormat, szDate, szTime);
  5496. SetDlgItemText (hDlg, IDC_MODIFIED_DATE, szBuffer);
  5497. if (pGPO->m_dwFlags & GPO_OPEN_READ_ONLY)
  5498. {
  5499. EnableWindow (GetDlgItem(hDlg, IDC_DISABLE_COMPUTER), FALSE);
  5500. EnableWindow (GetDlgItem(hDlg, IDC_DISABLE_USER), FALSE);
  5501. }
  5502. bDirty = FALSE;
  5503. bDisableWarningIssued = FALSE;
  5504. break;
  5505. }
  5506. case WM_COMMAND:
  5507. if (HIWORD(wParam) == BN_CLICKED)
  5508. {
  5509. if ((LOWORD(wParam) == IDC_DISABLE_COMPUTER) ||
  5510. (LOWORD(wParam) == IDC_DISABLE_USER))
  5511. {
  5512. if (!bDisableWarningIssued)
  5513. {
  5514. if (IsDlgButtonChecked (hDlg, LOWORD(wParam)) == BST_CHECKED)
  5515. {
  5516. TCHAR szMessage[200];
  5517. TCHAR szTitle[100];
  5518. bDisableWarningIssued = TRUE;
  5519. LoadString (g_hInstance, IDS_CONFIRMDISABLE, szMessage, ARRAYSIZE(szMessage));
  5520. LoadString (g_hInstance, IDS_CONFIRMTITLE2, szTitle, ARRAYSIZE(szTitle));
  5521. if (MessageBox (hDlg, szMessage, szTitle, MB_YESNO |
  5522. MB_ICONWARNING | MB_DEFBUTTON2) == IDNO) {
  5523. CheckDlgButton (hDlg, LOWORD(wParam), BST_UNCHECKED);
  5524. break;
  5525. }
  5526. }
  5527. }
  5528. }
  5529. if (!bDirty)
  5530. {
  5531. SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0);
  5532. bDirty = TRUE;
  5533. }
  5534. }
  5535. break;
  5536. case WM_NOTIFY:
  5537. pGPO = (CGroupPolicyObject *) GetWindowLongPtr (hDlg, DWLP_USER);
  5538. if (!pGPO) {
  5539. break;
  5540. }
  5541. switch (((NMHDR FAR*)lParam)->code)
  5542. {
  5543. case PSN_APPLY:
  5544. {
  5545. if (bDirty)
  5546. {
  5547. DWORD dwTemp = 0;
  5548. HRESULT hr;
  5549. //
  5550. // Set the disable flags in the GPO
  5551. //
  5552. if (IsDlgButtonChecked (hDlg, IDC_DISABLE_COMPUTER) == BST_CHECKED)
  5553. {
  5554. dwTemp |= GPO_OPTION_DISABLE_MACHINE;
  5555. }
  5556. if (IsDlgButtonChecked (hDlg, IDC_DISABLE_USER) == BST_CHECKED)
  5557. {
  5558. dwTemp |= GPO_OPTION_DISABLE_USER;
  5559. }
  5560. hr = pGPO->SetOptions (dwTemp, (GPO_OPTION_DISABLE_MACHINE | GPO_OPTION_DISABLE_USER));
  5561. if (FAILED(hr))
  5562. {
  5563. ReportError(hDlg, hr, IDS_FAILEDPROPERTIES);
  5564. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  5565. return TRUE;
  5566. }
  5567. bDirty = FALSE;
  5568. }
  5569. }
  5570. // fall through...
  5571. case PSN_RESET:
  5572. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  5573. return TRUE;
  5574. }
  5575. break;
  5576. case WM_HELP: // F1
  5577. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  5578. (ULONG_PTR) (LPSTR) aPropertiesHelpIds);
  5579. break;
  5580. case WM_CONTEXTMENU: // right mouse click
  5581. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  5582. (ULONG_PTR) (LPSTR) aPropertiesHelpIds);
  5583. return (TRUE);
  5584. }
  5585. return FALSE;
  5586. }
  5587. ///////////////////////////////////////////////////////////////////////////////
  5588. // //
  5589. // Class factory object implementation //
  5590. // //
  5591. ///////////////////////////////////////////////////////////////////////////////
  5592. CGroupPolicyObjectCF::CGroupPolicyObjectCF()
  5593. {
  5594. m_cRef = 1;
  5595. InterlockedIncrement(&g_cRefThisDll);
  5596. }
  5597. CGroupPolicyObjectCF::~CGroupPolicyObjectCF()
  5598. {
  5599. InterlockedDecrement(&g_cRefThisDll);
  5600. }
  5601. ///////////////////////////////////////////////////////////////////////////////
  5602. // //
  5603. // Class factory object implementation (IUnknown) //
  5604. // //
  5605. ///////////////////////////////////////////////////////////////////////////////
  5606. STDMETHODIMP_(ULONG)
  5607. CGroupPolicyObjectCF::AddRef()
  5608. {
  5609. return ++m_cRef;
  5610. }
  5611. STDMETHODIMP_(ULONG)
  5612. CGroupPolicyObjectCF::Release()
  5613. {
  5614. if (--m_cRef == 0)
  5615. {
  5616. delete this;
  5617. return 0;
  5618. }
  5619. return m_cRef;
  5620. }
  5621. STDMETHODIMP
  5622. CGroupPolicyObjectCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  5623. {
  5624. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  5625. {
  5626. *ppv = (LPCLASSFACTORY)this;
  5627. m_cRef++;
  5628. return S_OK;
  5629. }
  5630. else
  5631. {
  5632. *ppv = NULL;
  5633. return E_NOINTERFACE;
  5634. }
  5635. }
  5636. ///////////////////////////////////////////////////////////////////////////////
  5637. // //
  5638. // Class factory object implementation (IClassFactory) //
  5639. // //
  5640. ///////////////////////////////////////////////////////////////////////////////
  5641. STDMETHODIMP
  5642. CGroupPolicyObjectCF::CreateInstance(LPUNKNOWN pUnkOuter,
  5643. REFIID riid,
  5644. LPVOID FAR* ppvObj)
  5645. {
  5646. *ppvObj = NULL;
  5647. if (pUnkOuter)
  5648. return CLASS_E_NOAGGREGATION;
  5649. CGroupPolicyObject *pGroupPolicyObject = new CGroupPolicyObject(); // ref count == 1
  5650. if (!pGroupPolicyObject)
  5651. return E_OUTOFMEMORY;
  5652. HRESULT hr = pGroupPolicyObject->QueryInterface(riid, ppvObj);
  5653. pGroupPolicyObject->Release(); // release initial ref
  5654. return hr;
  5655. }
  5656. STDMETHODIMP
  5657. CGroupPolicyObjectCF::LockServer(BOOL fLock)
  5658. {
  5659. return E_NOTIMPL;
  5660. }
  5661. //*************************************************************
  5662. //
  5663. // CGroupPolicyObject::GetProperty
  5664. //
  5665. // Purpose: Retrieves a property from DS or from gpt.ini
  5666. //
  5667. // Parameters: pszProp - Property to get
  5668. // xValueIn - Value returned here
  5669. //
  5670. // Returns: S_OK if successful
  5671. //
  5672. //*************************************************************
  5673. HRESULT CGroupPolicyObject::GetProperty( TCHAR *pszProp, XPtrST<TCHAR>& xValueIn )
  5674. {
  5675. HRESULT hr = E_FAIL;
  5676. if ( m_gpoType == GPOTypeDS )
  5677. {
  5678. VARIANT var;
  5679. BSTR bstrProperty;
  5680. VariantInit( &var );
  5681. bstrProperty = SysAllocString( pszProp );
  5682. if ( bstrProperty == NULL )
  5683. return E_OUTOFMEMORY;
  5684. hr = m_pADs->Get( bstrProperty, &var );
  5685. if ( SUCCEEDED(hr) )
  5686. {
  5687. ULONG ulNoChars = lstrlen(var.bstrVal) + 1;
  5688. TCHAR *pszValue = new TCHAR[ulNoChars];
  5689. if ( pszValue == 0 )
  5690. hr = E_OUTOFMEMORY;
  5691. else
  5692. {
  5693. hr = StringCchCopy ( pszValue, ulNoChars, var.bstrVal );
  5694. ASSERT(SUCCEEDED(hr));
  5695. xValueIn.Set( pszValue );
  5696. hr = S_OK;
  5697. }
  5698. } else if ( hr == E_ADS_PROPERTY_NOT_FOUND )
  5699. {
  5700. //
  5701. // Property has not be written out before
  5702. //
  5703. hr = S_OK;
  5704. }
  5705. if ( FAILED(hr) ) {
  5706. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetProperty: Failed with errorcode 0x%x"), hr));
  5707. }
  5708. SysFreeString( bstrProperty );
  5709. VariantClear( &var );
  5710. return hr;
  5711. }
  5712. else
  5713. {
  5714. TCHAR szPath[2*MAX_PATH];
  5715. //
  5716. // Get the file system path
  5717. //
  5718. hr = GetPath (szPath, ARRAYSIZE(szPath));
  5719. if ( FAILED(hr) ) {
  5720. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetProperty: Failed with errorcode 0x%x"), hr));
  5721. }
  5722. (void) CheckSlash (szPath);
  5723. hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI"));
  5724. if (FAILED(hr))
  5725. {
  5726. return hr;
  5727. }
  5728. XPtrST<TCHAR> xszValue( new TCHAR[2*MAX_PATH] );
  5729. if ( xszValue.GetPointer() == NULL )
  5730. return E_OUTOFMEMORY;
  5731. DWORD dwSize = (2*MAX_PATH);
  5732. DWORD dwCount = GetPrivateProfileString( TEXT("General"),
  5733. pszProp,
  5734. TEXT(""),
  5735. xszValue.GetPointer(),
  5736. dwSize,
  5737. szPath );
  5738. while ( dwCount == dwSize - 1 )
  5739. {
  5740. //
  5741. // Value has been truncated, so retry with larger buffer
  5742. //
  5743. dwSize *= 2;
  5744. delete xszValue.Acquire();
  5745. xszValue.Set( new TCHAR[dwSize] );
  5746. if ( xszValue.GetPointer() == NULL )
  5747. return E_OUTOFMEMORY;
  5748. dwCount = GetPrivateProfileString( TEXT("General"),
  5749. pszProp,
  5750. TEXT(""),
  5751. xszValue.GetPointer(),
  5752. dwSize,
  5753. szPath );
  5754. }
  5755. xValueIn.Set( xszValue.Acquire() );
  5756. return S_OK;
  5757. }
  5758. }
  5759. //*************************************************************
  5760. //
  5761. // CGroupPolicyObject::SetProperty
  5762. //
  5763. // Purpose: Writes a property to DS or to gpt.ini
  5764. //
  5765. // Parameters: pszProp - Property to set
  5766. // pszPropValue - Property value
  5767. //
  5768. // Returns: S_OK if successful
  5769. //
  5770. //*************************************************************
  5771. HRESULT CGroupPolicyObject::SetProperty( TCHAR *pszProp, TCHAR *pszPropValue )
  5772. {
  5773. HRESULT hr = E_FAIL;
  5774. if ( m_gpoType == GPOTypeDS )
  5775. {
  5776. VARIANT var;
  5777. VariantInit( &var );
  5778. var.vt = VT_BSTR;
  5779. var.bstrVal = SysAllocString( pszPropValue );
  5780. if ( var.bstrVal == 0 )
  5781. return E_OUTOFMEMORY;
  5782. BSTR bstrProperty = SysAllocString( pszProp );
  5783. if ( bstrProperty == 0 )
  5784. {
  5785. VariantClear( &var );
  5786. return E_OUTOFMEMORY;
  5787. }
  5788. hr = m_pADs->Put( bstrProperty, var );
  5789. if ( FAILED(hr) )
  5790. {
  5791. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetProperty: Failed with errorcode 0x%x"), hr));
  5792. return hr;
  5793. }
  5794. SysFreeString( bstrProperty );
  5795. VariantClear( &var );
  5796. return S_OK;
  5797. }
  5798. else
  5799. {
  5800. TCHAR szPath[2*MAX_PATH];
  5801. //
  5802. // Get the file system path
  5803. //
  5804. hr = GetPath (szPath, ARRAYSIZE(szPath));
  5805. if ( FAILED(hr) ) {
  5806. DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetProperty: Failed with errorcode 0x%x"), hr));
  5807. }
  5808. (void) CheckSlash (szPath);
  5809. hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI"));
  5810. if (FAILED(hr))
  5811. {
  5812. return hr;
  5813. }
  5814. BOOL bOk = WritePrivateProfileString( TEXT("General"),
  5815. pszProp,
  5816. pszPropValue,
  5817. szPath );
  5818. if ( bOk )
  5819. hr = S_OK;
  5820. else
  5821. hr = GetLastError();
  5822. return hr;
  5823. }
  5824. }