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.

2320 lines
58 KiB

  1. //*************************************************************
  2. // File name: COMPDATA.C
  3. //
  4. // Description: Main component of the GPE snapin
  5. //
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 1998
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #include "main.h"
  13. #include <initguid.h>
  14. #include "compdata.h"
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // //
  17. // CComponentData object implementation //
  18. // //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. CComponentData::CComponentData()
  21. {
  22. InterlockedIncrement(&g_cRefThisDll);
  23. m_cRef = 1;
  24. m_hwndFrame = NULL;
  25. m_bOverride = FALSE;
  26. m_bDirty = FALSE;
  27. m_bRefocusInit = FALSE;
  28. m_pGPO = NULL;
  29. m_pScope = NULL;
  30. m_pConsole = NULL;
  31. m_hRoot = NULL;
  32. m_hMachine = NULL;
  33. m_hUser = NULL;
  34. m_gpHint = GPHintUnknown;
  35. m_pDisplayName = NULL;
  36. m_pChoosePath = NULL;
  37. m_hChooseBitmap = NULL;
  38. m_tChooseGPOType = GPOTypeLocal;
  39. }
  40. CComponentData::~CComponentData()
  41. {
  42. if (m_pDisplayName)
  43. {
  44. LocalFree (m_pDisplayName);
  45. }
  46. if (m_pChoosePath)
  47. {
  48. LocalFree (m_pChoosePath);
  49. }
  50. if (m_hChooseBitmap)
  51. {
  52. DeleteObject (m_hChooseBitmap);
  53. }
  54. if (m_pGPO)
  55. {
  56. m_pGPO->Release();
  57. }
  58. if (m_pScope)
  59. {
  60. m_pScope->Release();
  61. }
  62. if (m_pConsole)
  63. {
  64. m_pConsole->Release();
  65. }
  66. InterlockedDecrement(&g_cRefThisDll);
  67. }
  68. ///////////////////////////////////////////////////////////////////////////////
  69. // //
  70. // CComponentData object implementation (IUnknown) //
  71. // //
  72. ///////////////////////////////////////////////////////////////////////////////
  73. HRESULT CComponentData::QueryInterface (REFIID riid, void **ppv)
  74. {
  75. if (IsEqualIID(riid, IID_IComponentData) || IsEqualIID(riid, IID_IUnknown))
  76. {
  77. *ppv = (LPCOMPONENT)this;
  78. m_cRef++;
  79. return S_OK;
  80. }
  81. else if (IsEqualIID(riid, IID_IExtendPropertySheet2))
  82. {
  83. *ppv = (LPEXTENDPROPERTYSHEET)this;
  84. m_cRef++;
  85. return S_OK;
  86. }
  87. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  88. {
  89. *ppv = (LPEXTENDCONTEXTMENU)this;
  90. m_cRef++;
  91. return S_OK;
  92. }
  93. else if (IsEqualIID(riid, IID_IPersistStreamInit))
  94. {
  95. *ppv = (LPPERSISTSTREAMINIT)this;
  96. m_cRef++;
  97. return S_OK;
  98. }
  99. else if (IsEqualIID(riid, IID_ISnapinHelp))
  100. {
  101. *ppv = (LPSNAPINHELP)this;
  102. m_cRef++;
  103. return S_OK;
  104. }
  105. else
  106. {
  107. *ppv = NULL;
  108. return E_NOINTERFACE;
  109. }
  110. }
  111. ULONG CComponentData::AddRef (void)
  112. {
  113. return ++m_cRef;
  114. }
  115. ULONG CComponentData::Release (void)
  116. {
  117. if (--m_cRef == 0) {
  118. delete this;
  119. return 0;
  120. }
  121. return m_cRef;
  122. }
  123. ///////////////////////////////////////////////////////////////////////////////
  124. // //
  125. // CComponentData object implementation (IComponentData) //
  126. // //
  127. ///////////////////////////////////////////////////////////////////////////////
  128. STDMETHODIMP CComponentData::Initialize(LPUNKNOWN pUnknown)
  129. {
  130. HRESULT hr;
  131. HBITMAP bmp16x16;
  132. HBITMAP hbmp32x32;
  133. LPIMAGELIST lpScopeImage;
  134. //
  135. // QI for IConsoleNameSpace
  136. //
  137. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace, (LPVOID *)&m_pScope);
  138. if (FAILED(hr))
  139. {
  140. DebugMsg((DM_WARNING, TEXT("CComponentData::Initialize: Failed to QI for IConsoleNameSpace.")));
  141. return hr;
  142. }
  143. //
  144. // QI for IConsole
  145. //
  146. hr = pUnknown->QueryInterface(IID_IConsole, (LPVOID *)&m_pConsole);
  147. if (FAILED(hr))
  148. {
  149. DebugMsg((DM_WARNING, TEXT("CComponentData::Initialize: Failed to QI for IConsole.")));
  150. m_pScope->Release();
  151. m_pScope = NULL;
  152. return hr;
  153. }
  154. m_pConsole->GetMainWindow (&m_hwndFrame);
  155. //
  156. // Query for the scope imagelist interface
  157. //
  158. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  159. if (FAILED(hr))
  160. {
  161. DebugMsg((DM_WARNING, TEXT("CComponentData::Initialize: Failed to QI for scope imagelist.")));
  162. m_pScope->Release();
  163. m_pScope = NULL;
  164. m_pConsole->Release();
  165. m_pConsole=NULL;
  166. return hr;
  167. }
  168. // Load the bitmaps from the dll
  169. bmp16x16=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  170. hbmp32x32 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_32x32));
  171. // Set the images
  172. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(bmp16x16),
  173. reinterpret_cast<LONG_PTR *>(hbmp32x32),
  174. 0, RGB(255, 0, 255));
  175. lpScopeImage->Release();
  176. return S_OK;
  177. }
  178. STDMETHODIMP CComponentData::Destroy(VOID)
  179. {
  180. return S_OK;
  181. }
  182. STDMETHODIMP CComponentData::CreateComponent(LPCOMPONENT *ppComponent)
  183. {
  184. HRESULT hr;
  185. CSnapIn *pSnapIn;
  186. DebugMsg((DM_VERBOSE, TEXT("CComponentData::CreateComponent: Entering.")));
  187. //
  188. // Initialize
  189. //
  190. *ppComponent = NULL;
  191. //
  192. // Create the snapin view
  193. //
  194. pSnapIn = new CSnapIn(this);
  195. if (!pSnapIn)
  196. {
  197. DebugMsg((DM_WARNING, TEXT("CComponentData::CreateComponent: Failed to create CSnapIn.")));
  198. return E_OUTOFMEMORY;
  199. }
  200. //
  201. // QI for IComponent
  202. //
  203. hr = pSnapIn->QueryInterface(IID_IComponent, (LPVOID *)ppComponent);
  204. pSnapIn->Release(); // release QI
  205. return hr;
  206. }
  207. STDMETHODIMP CComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  208. LPDATAOBJECT* ppDataObject)
  209. {
  210. HRESULT hr = E_NOINTERFACE;
  211. CDataObject *pDataObject;
  212. LPGPEDATAOBJECT pGPEDataObject;
  213. //
  214. // Create a new DataObject
  215. //
  216. pDataObject = new CDataObject(this); // ref == 1
  217. if (!pDataObject)
  218. return E_OUTOFMEMORY;
  219. //
  220. // QI for the private GPODataObject interface so we can set the cookie
  221. // and type information.
  222. //
  223. hr = pDataObject->QueryInterface(IID_IGPEDataObject, (LPVOID *)&pGPEDataObject);
  224. if (FAILED(hr))
  225. {
  226. pDataObject->Release();
  227. return (hr);
  228. }
  229. pGPEDataObject->SetType(type);
  230. pGPEDataObject->SetCookie(cookie);
  231. pGPEDataObject->Release();
  232. //
  233. // QI for a normal IDataObject to return.
  234. //
  235. hr = pDataObject->QueryInterface(IID_IDataObject, (LPVOID *)ppDataObject);
  236. pDataObject->Release(); // release initial ref
  237. return hr;
  238. }
  239. STDMETHODIMP CComponentData::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  240. {
  241. HRESULT hr = S_OK;
  242. switch(event)
  243. {
  244. case MMCN_EXPAND:
  245. if (arg == TRUE)
  246. hr = EnumerateScopePane(lpDataObject, (HSCOPEITEM)param);
  247. break;
  248. case MMCN_PRELOAD:
  249. if (!m_bRefocusInit)
  250. {
  251. SCOPEDATAITEM item;
  252. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Notify: Received MMCN_PRELOAD event.")));
  253. m_bRefocusInit = TRUE;
  254. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  255. item.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  256. item.displayname = MMC_CALLBACK;
  257. if (m_pGPO)
  258. {
  259. item.nImage = 2;
  260. item.nOpenImage = 2;
  261. }
  262. else
  263. {
  264. item.nImage = 3;
  265. item.nOpenImage = 3;
  266. }
  267. item.ID = (HSCOPEITEM) arg;
  268. m_pScope->SetItem (&item);
  269. }
  270. break;
  271. default:
  272. break;
  273. }
  274. return hr;
  275. }
  276. STDMETHODIMP CComponentData::GetDisplayInfo(LPSCOPEDATAITEM pItem)
  277. {
  278. DWORD dwIndex;
  279. if (pItem == NULL)
  280. return E_POINTER;
  281. for (dwIndex = 0; dwIndex < g_dwNameSpaceItems; dwIndex++)
  282. {
  283. if (g_NameSpace[dwIndex].dwID == (DWORD) pItem->lParam)
  284. break;
  285. }
  286. if (dwIndex == g_dwNameSpaceItems)
  287. pItem->displayname = NULL;
  288. else
  289. {
  290. if (((DWORD) pItem->lParam == 0) && m_pDisplayName)
  291. pItem->displayname = m_pDisplayName;
  292. else
  293. pItem->displayname = g_NameSpace[dwIndex].szDisplayName;
  294. }
  295. return S_OK;
  296. }
  297. STDMETHODIMP CComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  298. {
  299. HRESULT hr = S_FALSE;
  300. LPGPEDATAOBJECT pGPEDataObjectA, pGPEDataObjectB;
  301. MMC_COOKIE cookie1, cookie2;
  302. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  303. return E_POINTER;
  304. //
  305. // QI for the private GPODataObject interface
  306. //
  307. if (FAILED(lpDataObjectA->QueryInterface(IID_IGPEDataObject,
  308. (LPVOID *)&pGPEDataObjectA)))
  309. {
  310. return S_FALSE;
  311. }
  312. if (FAILED(lpDataObjectB->QueryInterface(IID_IGPEDataObject,
  313. (LPVOID *)&pGPEDataObjectB)))
  314. {
  315. pGPEDataObjectA->Release();
  316. return S_FALSE;
  317. }
  318. pGPEDataObjectA->GetCookie(&cookie1);
  319. pGPEDataObjectB->GetCookie(&cookie2);
  320. if (cookie1 == cookie2)
  321. {
  322. hr = S_OK;
  323. }
  324. pGPEDataObjectA->Release();
  325. pGPEDataObjectB->Release();
  326. return hr;
  327. }
  328. ///////////////////////////////////////////////////////////////////////////////
  329. // //
  330. // CComponentData object implementation (IExtendPropertySheet) //
  331. // //
  332. ///////////////////////////////////////////////////////////////////////////////
  333. STDMETHODIMP CComponentData::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  334. LONG_PTR handle, LPDATAOBJECT lpDataObject)
  335. {
  336. HRESULT hr;
  337. PROPSHEETPAGE psp;
  338. HPROPSHEETPAGE hPage;
  339. HPROPSHEETPAGE *hPages;
  340. UINT i, uPageCount;
  341. TCHAR szTitle[150];
  342. if (IsSnapInManager(lpDataObject) == S_OK)
  343. {
  344. //
  345. // Create the wizard property sheet
  346. //
  347. LoadString (g_hInstance, IDS_GPE_WELCOME, szTitle, ARRAYSIZE(szTitle));
  348. psp.dwSize = sizeof(PROPSHEETPAGE);
  349. psp.dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  350. psp.hInstance = g_hInstance;
  351. psp.pszTemplate = MAKEINTRESOURCE(IDD_CHOOSE_INTRO);
  352. psp.pfnDlgProc = ChooseInitDlgProc;
  353. psp.lParam = (LPARAM) this;
  354. psp.pszHeaderTitle = szTitle;
  355. psp.pszHeaderSubTitle = NULL;
  356. hPage = CreatePropertySheetPage(&psp);
  357. if (!hPage)
  358. {
  359. DebugMsg((DM_WARNING, TEXT("CComponentData::CreatePropertyPages: Failed to create property sheet page with %d."),
  360. GetLastError()));
  361. return E_FAIL;
  362. }
  363. return (lpProvider->AddPage(hPage));
  364. }
  365. //
  366. // If we don't have a GPO, exit now.
  367. //
  368. if (!m_pGPO)
  369. {
  370. return E_FAIL;
  371. }
  372. //
  373. // Check if this is the GPO root object. If so we'll display a
  374. // properties page.
  375. //
  376. if (IsGPORoot(lpDataObject) != S_OK)
  377. {
  378. return E_FAIL;
  379. }
  380. //
  381. // Ask the GPO for the property sheet pages
  382. //
  383. hr = m_pGPO->GetPropertySheetPages (&hPages, &uPageCount);
  384. if (FAILED(hr))
  385. {
  386. DebugMsg((DM_WARNING, TEXT("CComponentData::CreatePropertyPages: Failed to query property sheet pages with 0x%x."), hr));
  387. return hr;
  388. }
  389. //
  390. // Add the pages
  391. //
  392. for (i = 0; i < uPageCount; i++)
  393. {
  394. hr = lpProvider->AddPage(hPages[i]);
  395. if (FAILED(hr))
  396. {
  397. DebugMsg((DM_WARNING, TEXT("CComponentData::CreatePropertyPages: Failed to add property sheet page with 0x%x."), hr));
  398. return hr;
  399. }
  400. }
  401. LocalFree (hPages);
  402. return hr;
  403. }
  404. STDMETHODIMP CComponentData::QueryPagesFor(LPDATAOBJECT lpDataObject)
  405. {
  406. HRESULT hr;
  407. hr = IsSnapInManager(lpDataObject);
  408. if (hr != S_OK)
  409. {
  410. hr = IsGPORoot(lpDataObject);
  411. if ((hr == S_OK) && !m_pGPO)
  412. {
  413. hr = E_FAIL;
  414. }
  415. }
  416. return hr;
  417. }
  418. STDMETHODIMP CComponentData::GetWatermarks(LPDATAOBJECT lpIDataObject,
  419. HBITMAP* lphWatermark,
  420. HBITMAP* lphHeader,
  421. HPALETTE* lphPalette,
  422. BOOL* pbStretch)
  423. {
  424. *lphPalette = NULL;
  425. *lphHeader = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_HEADER));
  426. *lphWatermark = NULL;
  427. *pbStretch = TRUE;
  428. return S_OK;
  429. }
  430. ///////////////////////////////////////////////////////////////////////////////
  431. // //
  432. // CComponentData object implementation (IExtendContextMenu) //
  433. // //
  434. ///////////////////////////////////////////////////////////////////////////////
  435. STDMETHODIMP CComponentData::AddMenuItems(LPDATAOBJECT piDataObject,
  436. LPCONTEXTMENUCALLBACK pCallback,
  437. LONG *pInsertionAllowed)
  438. {
  439. HRESULT hr = S_OK;
  440. TCHAR szMenuItem[100];
  441. TCHAR szDescription[250];
  442. CONTEXTMENUITEM item;
  443. if (!m_pGPO)
  444. {
  445. DebugMsg((DM_VERBOSE, TEXT("CComponentData::AddMenuItems: No GPO available. Exiting.")));
  446. return S_OK;
  447. }
  448. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  449. {
  450. if (IsGPORoot(piDataObject) == S_OK)
  451. {
  452. LoadString (g_hInstance, IDS_DCOPTIONS, szMenuItem, 100);
  453. LoadString (g_hInstance, IDS_DCOPTIONSDESC, szDescription, 250);
  454. item.strName = szMenuItem;
  455. item.strStatusBarText = szDescription;
  456. item.lCommandID = IDM_DCOPTIONS;
  457. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  458. item.fFlags = 0;
  459. item.fSpecialFlags = 0;
  460. hr = pCallback->AddItem(&item);
  461. }
  462. }
  463. return (hr);
  464. }
  465. STDMETHODIMP CComponentData::Command(LONG lCommandID, LPDATAOBJECT piDataObject)
  466. {
  467. DCSELINFO SelInfo;
  468. INT iResult = 1;
  469. HKEY hKey;
  470. DWORD dwDisp, dwSize, dwType;
  471. if (lCommandID == IDM_DCOPTIONS)
  472. {
  473. //
  474. // Get the user's current DC preference
  475. //
  476. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  477. {
  478. dwSize = sizeof(iResult);
  479. RegQueryValueEx(hKey, DCOPTION_VALUE, NULL, &dwType,
  480. (LPBYTE)&iResult, &dwSize);
  481. RegCloseKey(hKey);
  482. }
  483. //
  484. // Show the dialog
  485. //
  486. SelInfo.bError = FALSE;
  487. SelInfo.bAllowInherit = TRUE;
  488. SelInfo.iDefault = iResult;
  489. SelInfo.lpDomainName = NULL;
  490. iResult = (INT)DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_NODC), NULL,
  491. DCDlgProc, (LPARAM) &SelInfo);
  492. //
  493. // Save the preference if appropriate
  494. //
  495. if (iResult > 0)
  496. {
  497. if (RegCreateKeyEx (HKEY_CURRENT_USER, GPE_KEY, 0, NULL,
  498. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  499. &hKey, &dwDisp) == ERROR_SUCCESS)
  500. {
  501. RegSetValueEx (hKey, DCOPTION_VALUE, 0, REG_DWORD,
  502. (LPBYTE)&iResult, sizeof(iResult));
  503. RegCloseKey (hKey);
  504. }
  505. }
  506. }
  507. return S_OK;
  508. }
  509. ///////////////////////////////////////////////////////////////////////////////
  510. // //
  511. // CComponentData object implementation (IPersistStreamInit) //
  512. // //
  513. ///////////////////////////////////////////////////////////////////////////////
  514. STDMETHODIMP CComponentData::GetClassID(CLSID *pClassID)
  515. {
  516. if (!pClassID)
  517. {
  518. return E_FAIL;
  519. }
  520. *pClassID = CLSID_GPESnapIn;
  521. return S_OK;
  522. }
  523. STDMETHODIMP CComponentData::IsDirty(VOID)
  524. {
  525. return ThisIsDirty() ? S_OK : S_FALSE;
  526. }
  527. STDMETHODIMP CComponentData::Load(IStream *pStm)
  528. {
  529. HRESULT hr = E_FAIL;
  530. DWORD dwVersion;
  531. DWORD dwPathLen;
  532. ULONG nBytesRead;
  533. DWORD dwFlags = 0;
  534. LPTSTR lpPath = NULL;
  535. LPTSTR lpCommandLine = NULL;
  536. GROUP_POLICY_HINT_TYPE gpHint;
  537. LPOLESTR pszDomain;
  538. LPTSTR lpDomainName;
  539. LPTSTR lpDCName;
  540. LPTSTR lpTemp, lpHint, lpName;
  541. TCHAR szHint[10];
  542. TCHAR szComputerName[MAX_PATH];
  543. INT iStrLen, iTemp;
  544. //
  545. // Parameter / initialization check
  546. //
  547. if (!pStm)
  548. return E_FAIL;
  549. if (m_pGPO)
  550. return E_UNEXPECTED;
  551. //
  552. // Get the command line
  553. //
  554. lpCommandLine = GetCommandLine();
  555. //
  556. // Create a GPO object to work with
  557. //
  558. hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL,
  559. CLSCTX_SERVER, IID_IGroupPolicyObject,
  560. (void**)&m_pGPO);
  561. if (FAILED(hr))
  562. {
  563. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to create a GPO object with 0x%x."), hr));
  564. goto Exit;
  565. }
  566. //
  567. // Read in the saved data version number
  568. //
  569. hr = pStm->Read(&dwVersion, sizeof(dwVersion), &nBytesRead);
  570. if ((hr != S_OK) || (nBytesRead != sizeof(dwVersion)))
  571. {
  572. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to read version number with 0x%x."), hr));
  573. hr = E_FAIL;
  574. goto Exit;
  575. }
  576. //
  577. // Confirm that we are working with version 2
  578. //
  579. if (dwVersion != PERSIST_DATA_VERSION)
  580. {
  581. ReportError(m_hwndFrame, 0, IDS_INVALIDMSC);
  582. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Wrong version number (%d)."), dwVersion));
  583. hr = E_FAIL;
  584. goto Exit;
  585. }
  586. //
  587. // Read the flags
  588. //
  589. hr = pStm->Read(&dwFlags, sizeof(dwFlags), &nBytesRead);
  590. if ((hr != S_OK) || (nBytesRead != sizeof(dwFlags)))
  591. {
  592. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to read flags with 0x%x."), hr));
  593. hr = E_FAIL;
  594. goto Exit;
  595. }
  596. //
  597. // Read the hint information
  598. //
  599. hr = pStm->Read(&gpHint, sizeof(gpHint), &nBytesRead);
  600. if ((hr != S_OK) || (nBytesRead != sizeof(gpHint)))
  601. {
  602. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to read hint with 0x%x."), hr));
  603. hr = E_FAIL;
  604. goto Exit;
  605. }
  606. //
  607. // Read in the path string length (including null terminator)
  608. //
  609. hr = pStm->Read(&dwPathLen, sizeof(dwPathLen), &nBytesRead);
  610. if ((hr != S_OK) || (nBytesRead != sizeof(dwPathLen)))
  611. {
  612. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to read path size with 0x%x."), hr));
  613. hr = E_FAIL;
  614. goto Exit;
  615. }
  616. //
  617. // Read in the path if there is one
  618. //
  619. if (dwPathLen > 0)
  620. {
  621. lpPath = (LPTSTR) LocalAlloc (LPTR, dwPathLen);
  622. if (!lpPath)
  623. {
  624. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to allocate memory with %d."),
  625. GetLastError()));
  626. hr = E_FAIL;
  627. goto Exit;
  628. }
  629. hr = pStm->Read(lpPath, dwPathLen, &nBytesRead);
  630. if ((hr != S_OK) || (nBytesRead != dwPathLen))
  631. {
  632. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to read path with 0x%x."), hr));
  633. hr = E_FAIL;
  634. goto Exit;
  635. }
  636. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Path is: <%s>"), lpPath));
  637. }
  638. //
  639. // Parse the command line
  640. //
  641. if (dwFlags & MSC_FLAG_OVERRIDE)
  642. {
  643. m_bOverride = TRUE;
  644. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Command line switch override enabled. Command line = %s"), lpCommandLine));
  645. lpTemp = lpCommandLine;
  646. iStrLen = lstrlen (CMD_LINE_START);
  647. do
  648. {
  649. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  650. CMD_LINE_START, iStrLen,
  651. lpTemp, iStrLen) == CSTR_EQUAL)
  652. {
  653. iTemp = lstrlen (CMD_LINE_HINT);
  654. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  655. CMD_LINE_HINT, iTemp,
  656. lpTemp, iTemp) == CSTR_EQUAL)
  657. {
  658. //
  659. // Found the hint switch
  660. //
  661. lpTemp += iTemp;
  662. ZeroMemory (szHint, sizeof(szHint));
  663. lpHint = szHint;
  664. while (*lpTemp && ((*lpTemp) != TEXT(' ')))
  665. *lpHint++ = *lpTemp++;
  666. if (szHint[0] != TEXT('\0'))
  667. {
  668. gpHint = (GROUP_POLICY_HINT_TYPE) _ttoi(szHint);
  669. }
  670. continue;
  671. }
  672. iTemp = lstrlen (CMD_LINE_COMPUTER);
  673. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  674. CMD_LINE_COMPUTER, iTemp,
  675. lpTemp, iTemp) == CSTR_EQUAL)
  676. {
  677. //
  678. // Found the computer switch
  679. //
  680. lpTemp += iTemp + 1;
  681. ZeroMemory (szComputerName, sizeof(szComputerName));
  682. lpName = szComputerName;
  683. while (*lpTemp && ((*lpTemp) != TEXT('\"')))
  684. *lpName++ = *lpTemp++;
  685. if ((*lpTemp) == TEXT('\"'))
  686. lpTemp++;
  687. if (szComputerName[0] != TEXT('\0'))
  688. {
  689. ULONG ulNoChars;
  690. if (lpPath)
  691. {
  692. LocalFree (lpPath);
  693. }
  694. ulNoChars = lstrlen(szComputerName) + 1;
  695. lpPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  696. if (lpPath)
  697. {
  698. hr = StringCchCopy (lpPath, ulNoChars, szComputerName);
  699. ASSERT(SUCCEEDED(hr));
  700. dwFlags &= ~MSC_FLAG_LOCAL_GPO;
  701. dwFlags &= ~MSC_FLAG_DS_GPO;
  702. dwFlags |= MSC_FLAG_REMOTE_GPO;
  703. }
  704. }
  705. continue;
  706. }
  707. iTemp = lstrlen (CMD_LINE_GPO);
  708. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  709. CMD_LINE_GPO, iTemp,
  710. lpTemp, iTemp) == CSTR_EQUAL)
  711. {
  712. //
  713. // Found the gpo switch
  714. //
  715. lpTemp += iTemp + 1;
  716. if (lpPath)
  717. {
  718. LocalFree (lpPath);
  719. }
  720. lpPath = (LPTSTR) LocalAlloc (LPTR, 512 * sizeof(TCHAR));
  721. if (!lpPath)
  722. {
  723. lpTemp++;
  724. continue;
  725. }
  726. dwFlags &= ~MSC_FLAG_LOCAL_GPO;
  727. dwFlags &= ~MSC_FLAG_REMOTE_GPO;
  728. dwFlags |= MSC_FLAG_DS_GPO;
  729. lpName = lpPath;
  730. while (*lpTemp && ((*lpTemp) != TEXT('\"')))
  731. *lpName++ = *lpTemp++;
  732. if ((*lpTemp) == TEXT('\"'))
  733. lpTemp++;
  734. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Command line path is: <%s>"), lpPath));
  735. continue;
  736. }
  737. }
  738. lpTemp++;
  739. } while (*lpTemp);
  740. }
  741. else if (dwFlags & MSC_FLAG_DS_GPO && dwPathLen > 0)
  742. {
  743. //
  744. // Get the friendly domain name
  745. //
  746. pszDomain = GetDomainFromLDAPPath(lpPath);
  747. if (!pszDomain)
  748. {
  749. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to get domain name")));
  750. hr = E_FAIL;
  751. goto Exit;
  752. }
  753. //
  754. // Convert LDAP to dot (DN) style
  755. //
  756. hr = ConvertToDotStyle (pszDomain, &lpDomainName);
  757. delete [] pszDomain;
  758. if (FAILED(hr))
  759. {
  760. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to convert domain name with 0x%x"), hr));
  761. goto Exit;
  762. }
  763. //
  764. // Get the domain controller for this domain
  765. //
  766. lpDCName = GetDCName (lpDomainName, NULL, NULL, TRUE, 0);
  767. LocalFree (lpDomainName);
  768. if (!lpDCName)
  769. {
  770. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to get DC name")));
  771. hr = HRESULT_FROM_WIN32(GetLastError());
  772. goto Exit;
  773. }
  774. //
  775. // Make a full path
  776. //
  777. lpTemp = MakeFullPath (lpPath, lpDCName);
  778. LocalFree (lpDCName);
  779. if (!lpTemp)
  780. {
  781. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to make full path")));
  782. hr = HRESULT_FROM_WIN32(GetLastError());
  783. goto Exit;
  784. }
  785. //
  786. // Swap the relative path with the full path
  787. //
  788. LocalFree (lpPath);
  789. lpPath = lpTemp;
  790. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Full Path is: <%s>"), lpPath));
  791. }
  792. //
  793. // Do the appropriate action
  794. //
  795. if (dwFlags & MSC_FLAG_LOCAL_GPO)
  796. {
  797. hr = m_pGPO->OpenLocalMachineGPO(TRUE);
  798. if (FAILED(hr))
  799. {
  800. ReportError(m_hwndFrame, hr, IDS_FAILEDLOCAL);
  801. }
  802. }
  803. else if (dwFlags & MSC_FLAG_REMOTE_GPO)
  804. {
  805. if (lpPath)
  806. {
  807. hr = m_pGPO->OpenRemoteMachineGPO(lpPath, TRUE);
  808. if (FAILED(hr))
  809. {
  810. ReportError(m_hwndFrame, hr, IDS_FAILEDREMOTE, lpPath);
  811. }
  812. }
  813. else
  814. {
  815. hr = E_FAIL;
  816. ReportError(m_hwndFrame, hr, IDS_INVALIDMSC);
  817. }
  818. }
  819. else
  820. {
  821. if (lpPath)
  822. {
  823. hr = m_pGPO->OpenDSGPO(lpPath, GPO_OPEN_LOAD_REGISTRY);
  824. if (FAILED(hr))
  825. {
  826. ReportError(m_hwndFrame, hr, IDS_FAILEDDS, lpPath);
  827. }
  828. }
  829. else
  830. {
  831. hr = E_FAIL;
  832. ReportError(m_hwndFrame, hr, IDS_INVALIDMSC);
  833. }
  834. }
  835. if (SUCCEEDED(hr))
  836. {
  837. ClearDirty();
  838. m_gpHint = gpHint;
  839. BuildDisplayName();
  840. }
  841. Exit:
  842. if (FAILED(hr) && m_pGPO)
  843. {
  844. m_pGPO->Release();
  845. m_pGPO = NULL;
  846. }
  847. if (lpPath)
  848. {
  849. LocalFree (lpPath);
  850. }
  851. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Leaving with 0x%x."), hr));
  852. return hr;
  853. }
  854. STDMETHODIMP CComponentData::Save(IStream *pStm, BOOL fClearDirty)
  855. {
  856. HRESULT hr = STG_E_CANTSAVE;
  857. ULONG nBytesWritten;
  858. DWORD dwTemp;
  859. DWORD dwFlags;
  860. GROUP_POLICY_OBJECT_TYPE gpoType;
  861. LPTSTR lpPath = NULL;
  862. LPTSTR lpTemp;
  863. DWORD dwPathSize = 1024;
  864. if (!pStm)
  865. {
  866. return E_FAIL;
  867. }
  868. if (!m_pGPO)
  869. {
  870. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: No GPO. Leaving.")));
  871. goto Exit;
  872. }
  873. //
  874. // Allocate a buffer to hold the path
  875. //
  876. lpPath = (LPTSTR) LocalAlloc(LPTR, dwPathSize * sizeof(TCHAR));
  877. if (!lpPath)
  878. {
  879. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to alloc buffer for path with %d."), GetLastError()));
  880. goto Exit;
  881. }
  882. //
  883. // Determine what the flags are
  884. //
  885. dwFlags = 0;
  886. if (m_bOverride)
  887. {
  888. dwFlags |= MSC_FLAG_OVERRIDE;
  889. }
  890. m_pGPO->GetType (&gpoType);
  891. if (gpoType == GPOTypeLocal)
  892. {
  893. dwFlags |= MSC_FLAG_LOCAL_GPO;
  894. hr = S_OK;
  895. }
  896. else if (gpoType == GPOTypeRemote)
  897. {
  898. dwFlags |= MSC_FLAG_REMOTE_GPO;
  899. hr = m_pGPO->GetMachineName (lpPath, dwPathSize);
  900. }
  901. else
  902. {
  903. dwFlags |= MSC_FLAG_DS_GPO;
  904. hr = m_pGPO->GetPath (lpPath, dwPathSize);
  905. if (SUCCEEDED(hr))
  906. {
  907. lpTemp = MakeNamelessPath (lpPath);
  908. if (!lpTemp)
  909. {
  910. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to get nameless path")));
  911. goto Exit;
  912. }
  913. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Save: Nameless GPO path is: %s"), lpTemp));
  914. LocalFree (lpPath);
  915. lpPath = lpTemp;
  916. }
  917. }
  918. if (FAILED(hr))
  919. {
  920. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to get path with %d."), hr));
  921. goto Exit;
  922. }
  923. //
  924. // Save the version number
  925. //
  926. dwTemp = PERSIST_DATA_VERSION;
  927. hr = pStm->Write(&dwTemp, sizeof(dwTemp), &nBytesWritten);
  928. if ((hr != S_OK) || (nBytesWritten != sizeof(dwTemp)))
  929. {
  930. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write version number with %d."), hr));
  931. goto Exit;
  932. }
  933. //
  934. // Save the flags
  935. //
  936. hr = pStm->Write(&dwFlags, sizeof(dwFlags), &nBytesWritten);
  937. if ((hr != S_OK) || (nBytesWritten != sizeof(dwFlags)))
  938. {
  939. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write flags with %d."), hr));
  940. goto Exit;
  941. }
  942. //
  943. // Save the hint information
  944. //
  945. hr = pStm->Write(&m_gpHint, sizeof(m_gpHint), &nBytesWritten);
  946. if ((hr != S_OK) || (nBytesWritten != sizeof(m_gpHint)))
  947. {
  948. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write hint with %d."), hr));
  949. goto Exit;
  950. }
  951. //
  952. // Save the path length
  953. //
  954. dwTemp = lstrlen (lpPath);
  955. if (dwTemp)
  956. {
  957. dwTemp = (dwTemp + 1) * sizeof (TCHAR);
  958. }
  959. hr = pStm->Write(&dwTemp, sizeof(dwTemp), &nBytesWritten);
  960. if ((hr != S_OK) || (nBytesWritten != sizeof(dwTemp)))
  961. {
  962. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write ds path length with %d."), hr));
  963. goto Exit;
  964. }
  965. if (dwTemp)
  966. {
  967. //
  968. // Save the path
  969. //
  970. hr = pStm->Write(lpPath, dwTemp, &nBytesWritten);
  971. if ((hr != S_OK) || (nBytesWritten != dwTemp))
  972. {
  973. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write ds path with %d."), hr));
  974. goto Exit;
  975. }
  976. }
  977. if (fClearDirty)
  978. {
  979. ClearDirty();
  980. }
  981. Exit:
  982. if (lpPath)
  983. {
  984. LocalFree (lpPath);
  985. }
  986. return hr;
  987. }
  988. STDMETHODIMP CComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  989. {
  990. HRESULT hr = E_FAIL;
  991. DWORD dwSize;
  992. LPTSTR lpPath = NULL;
  993. LPTSTR lpTemp;
  994. GROUP_POLICY_OBJECT_TYPE gpoType;
  995. DWORD dwPathSize = 1024;
  996. DWORD dwStrLen;
  997. //
  998. // Check arguments
  999. //
  1000. if (!pcbSize)
  1001. {
  1002. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: NULL pcbSize argument")));
  1003. goto Exit;
  1004. }
  1005. //
  1006. // Allocate a buffer to hold the path
  1007. //
  1008. lpPath = (LPTSTR) LocalAlloc(LPTR, dwPathSize * sizeof(TCHAR));
  1009. if (!lpPath)
  1010. {
  1011. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: Failed to alloc buffer for path with %d."), GetLastError()));
  1012. goto Exit;
  1013. }
  1014. //
  1015. // Get the path if appropriate
  1016. //
  1017. m_pGPO->GetType (&gpoType);
  1018. if (gpoType == GPOTypeLocal)
  1019. {
  1020. hr = S_OK;
  1021. }
  1022. else if (gpoType == GPOTypeRemote)
  1023. {
  1024. hr = m_pGPO->GetMachineName (lpPath, dwPathSize);
  1025. }
  1026. else
  1027. {
  1028. hr = m_pGPO->GetPath (lpPath, dwPathSize);
  1029. if (SUCCEEDED(hr))
  1030. {
  1031. lpTemp = MakeNamelessPath (lpPath);
  1032. if (!lpTemp)
  1033. {
  1034. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: Failed to get nameless path")));
  1035. goto Exit;
  1036. }
  1037. LocalFree (lpPath);
  1038. lpPath = lpTemp;
  1039. }
  1040. }
  1041. if (FAILED(hr))
  1042. {
  1043. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: Failed to get path with %d."), hr));
  1044. goto Exit;
  1045. }
  1046. //
  1047. // Set the stream size. Version Number + Flags + Length + Unicode String + null
  1048. //
  1049. dwSize = 3 * sizeof(DWORD);
  1050. dwStrLen = lstrlen(lpPath);
  1051. if (dwStrLen)
  1052. {
  1053. dwSize += (dwStrLen + 1) * sizeof (TCHAR);
  1054. }
  1055. ULISet32(*pcbSize, dwSize);
  1056. hr = S_OK;
  1057. Exit:
  1058. if (lpPath)
  1059. {
  1060. LocalFree (lpPath);
  1061. }
  1062. return hr;
  1063. }
  1064. STDMETHODIMP CComponentData::InitNew(void)
  1065. {
  1066. return S_OK;
  1067. }
  1068. ///////////////////////////////////////////////////////////////////////////////
  1069. // //
  1070. // CComponentData object implementation (ISnapinHelp) //
  1071. // //
  1072. ///////////////////////////////////////////////////////////////////////////////
  1073. STDMETHODIMP CComponentData::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  1074. {
  1075. LPOLESTR lpHelpFile;
  1076. lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
  1077. if (!lpHelpFile)
  1078. {
  1079. DebugMsg((DM_WARNING, TEXT("CComponentData::GetHelpTopic: Failed to allocate memory.")));
  1080. return E_OUTOFMEMORY;
  1081. }
  1082. ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gpedit.chm",
  1083. lpHelpFile, MAX_PATH);
  1084. *lpCompiledHelpFile = lpHelpFile;
  1085. return S_OK;
  1086. }
  1087. ///////////////////////////////////////////////////////////////////////////////
  1088. // //
  1089. // CComponentData object implementation (Internal functions) //
  1090. // //
  1091. ///////////////////////////////////////////////////////////////////////////////
  1092. HRESULT CComponentData::InitializeNewGPO(HWND hDlg)
  1093. {
  1094. HRESULT hr;
  1095. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: Entering")));
  1096. SetWaitCursor();
  1097. //
  1098. // Clean up existing GPO
  1099. //
  1100. if (m_pGPO)
  1101. {
  1102. m_pGPO->Release();
  1103. }
  1104. //
  1105. // Create a new GPO object to work with
  1106. //
  1107. hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL,
  1108. CLSCTX_SERVER, IID_IGroupPolicyObject,
  1109. (void**)&m_pGPO);
  1110. if (FAILED(hr))
  1111. {
  1112. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to create GPO with 0x%x."), hr));
  1113. goto Exit;
  1114. }
  1115. //
  1116. // Determine which item was selected
  1117. //
  1118. switch (m_tChooseGPOType)
  1119. {
  1120. case GPOTypeLocal:
  1121. //
  1122. // Open local policy
  1123. //
  1124. hr = m_pGPO->OpenLocalMachineGPO(TRUE);
  1125. if (FAILED(hr))
  1126. {
  1127. ReportError(hDlg, hr, IDS_FAILEDLOCAL);
  1128. }
  1129. else
  1130. {
  1131. m_gpHint = GPHintMachine;
  1132. }
  1133. break;
  1134. case GPOTypeRemote:
  1135. //
  1136. // Open remote policy
  1137. //
  1138. hr = m_pGPO->OpenRemoteMachineGPO (m_pChoosePath, TRUE);
  1139. if (FAILED(hr))
  1140. {
  1141. ReportError(hDlg, hr, IDS_FAILEDREMOTE, m_pChoosePath);
  1142. }
  1143. else
  1144. {
  1145. m_gpHint = GPHintMachine;
  1146. }
  1147. break;
  1148. case GPOTypeDS:
  1149. {
  1150. LPOLESTR pszDomain;
  1151. LPTSTR lpDomainName;
  1152. LPTSTR lpDCName;
  1153. LPTSTR lpTemp;
  1154. //
  1155. // Open existing DS GPO
  1156. //
  1157. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: User selected %s"), m_pChoosePath));
  1158. //
  1159. // Get the friendly domain name
  1160. //
  1161. pszDomain = GetDomainFromLDAPPath(m_pChoosePath);
  1162. if (!pszDomain)
  1163. {
  1164. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to get domain name")));
  1165. hr = E_FAIL;
  1166. goto Exit;
  1167. }
  1168. //
  1169. // Convert LDAP to dot (DN) style
  1170. //
  1171. hr = ConvertToDotStyle (pszDomain, &lpDomainName);
  1172. delete [] pszDomain;
  1173. if (FAILED(hr))
  1174. {
  1175. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to convert domain name with 0x%x"), hr));
  1176. goto Exit;
  1177. }
  1178. //
  1179. // Get the domain controller for this domain
  1180. //
  1181. lpDCName = GetDCName (lpDomainName, NULL, hDlg, TRUE, 0);
  1182. LocalFree (lpDomainName);
  1183. if (!lpDCName)
  1184. {
  1185. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to get DC name")));
  1186. goto Exit;
  1187. }
  1188. //
  1189. // Build the full path
  1190. //
  1191. lpTemp = MakeFullPath (m_pChoosePath, lpDCName);
  1192. LocalFree (lpDCName);
  1193. if (!lpTemp)
  1194. {
  1195. hr = HRESULT_FROM_WIN32(GetLastError());
  1196. goto Exit;
  1197. }
  1198. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: Full ADSI path is %s"),
  1199. lpTemp));
  1200. hr = m_pGPO->OpenDSGPO (lpTemp, GPO_OPEN_LOAD_REGISTRY);
  1201. if (FAILED(hr))
  1202. {
  1203. ReportError(hDlg, hr, IDS_FAILEDDS, lpTemp);
  1204. }
  1205. else
  1206. {
  1207. m_gpHint = GPHintUnknown;
  1208. }
  1209. LocalFree (lpTemp);
  1210. }
  1211. break;
  1212. default:
  1213. hr = E_FAIL;
  1214. }
  1215. Exit:
  1216. ClearWaitCursor();
  1217. if (SUCCEEDED(hr))
  1218. {
  1219. if (IsDlgButtonChecked (hDlg, IDC_OVERRIDE))
  1220. {
  1221. m_bOverride = TRUE;
  1222. }
  1223. else
  1224. {
  1225. m_bOverride = FALSE;
  1226. }
  1227. SetDirty();
  1228. BuildDisplayName();
  1229. }
  1230. else
  1231. {
  1232. if (m_pGPO)
  1233. {
  1234. m_pGPO->Release();
  1235. m_pGPO = NULL;
  1236. }
  1237. }
  1238. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: Leaving with 0x%x."), hr));
  1239. return hr;
  1240. }
  1241. HRESULT CComponentData::BuildDisplayName(void)
  1242. {
  1243. WCHAR szDispName[50];
  1244. WCHAR szDisplayName[MAX_FRIENDLYNAME + MAX_PATH + 20];
  1245. WCHAR szFriendlyName[MAX_FRIENDLYNAME];
  1246. WCHAR szDCName[MAX_PATH];
  1247. GROUP_POLICY_OBJECT_TYPE type;
  1248. szDisplayName[0] = TEXT('\0');
  1249. if (SUCCEEDED(m_pGPO->GetDisplayName(szFriendlyName, ARRAYSIZE(szFriendlyName))))
  1250. {
  1251. if (SUCCEEDED(m_pGPO->GetMachineName(szDCName, ARRAYSIZE(szDCName))))
  1252. {
  1253. if (SUCCEEDED(m_pGPO->GetType(&type)))
  1254. {
  1255. if ((szDCName[0] == TEXT('\0')) || (type != GPOTypeDS))
  1256. {
  1257. LoadStringW (g_hInstance, IDS_DISPLAYNAME, szDispName, ARRAYSIZE(szDispName));
  1258. // Display name is truncated if more than the sizeof szDisplayName
  1259. (void) StringCchPrintf (szDisplayName,
  1260. sizeof(szDisplayName)/sizeof(szDisplayName[0]),
  1261. szDispName,
  1262. szFriendlyName);
  1263. }
  1264. else
  1265. {
  1266. LoadStringW (g_hInstance, IDS_DISPLAYNAME2, szDispName, ARRAYSIZE(szDispName));
  1267. // Display name is truncated if more than the sizeof szDisplayName
  1268. (void) StringCchPrintf (szDisplayName,
  1269. sizeof(szDisplayName)/sizeof(szDisplayName[0]),
  1270. szDispName,
  1271. szFriendlyName,
  1272. szDCName);
  1273. }
  1274. }
  1275. }
  1276. }
  1277. if (szDisplayName[0] == TEXT('\0'))
  1278. {
  1279. LoadStringW (g_hInstance, IDS_SNAPIN_NAME, szDisplayName, ARRAYSIZE(szDisplayName));
  1280. }
  1281. ULONG ulNoChars = lstrlen(szDisplayName) + 1;
  1282. m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1283. if (m_pDisplayName)
  1284. {
  1285. HRESULT hr;
  1286. hr = StringCchCopy (m_pDisplayName, ulNoChars, szDisplayName);
  1287. ASSERT(SUCCEEDED(hr));
  1288. }
  1289. return S_OK;
  1290. }
  1291. //
  1292. // Returns S_OK if this is the GPO root in the scope pane or results pane.
  1293. // S_FALSE if not.
  1294. //
  1295. HRESULT CComponentData::IsGPORoot (LPDATAOBJECT lpDataObject)
  1296. {
  1297. HRESULT hr = S_FALSE;
  1298. LPGPEDATAOBJECT pGPEDataObject;
  1299. DATA_OBJECT_TYPES type;
  1300. MMC_COOKIE cookie;
  1301. //
  1302. // We can determine if this is a GPO DataObject by trying to
  1303. // QI for the private IGPEDataObject interface. If found,
  1304. // it belongs to us.
  1305. //
  1306. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IGPEDataObject,
  1307. (LPVOID *)&pGPEDataObject)))
  1308. {
  1309. pGPEDataObject->GetType(&type);
  1310. pGPEDataObject->GetCookie(&cookie);
  1311. if ((type == CCT_SCOPE) && (cookie == 0))
  1312. {
  1313. hr = S_OK;
  1314. }
  1315. pGPEDataObject->Release();
  1316. }
  1317. return (hr);
  1318. }
  1319. HRESULT CComponentData::IsSnapInManager (LPDATAOBJECT lpDataObject)
  1320. {
  1321. HRESULT hr = S_FALSE;
  1322. LPGPEDATAOBJECT pGPEDataObject;
  1323. DATA_OBJECT_TYPES type;
  1324. //
  1325. // We can determine if this is a GPO DataObject by trying to
  1326. // QI for the private IGPEDataObject interface. If found,
  1327. // it belongs to us.
  1328. //
  1329. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IGPEDataObject,
  1330. (LPVOID *)&pGPEDataObject)))
  1331. {
  1332. //
  1333. // This is a GPO object. Now see if is a scope pane
  1334. // data object. We only want to display the property
  1335. // sheet for the scope pane.
  1336. //
  1337. if (SUCCEEDED(pGPEDataObject->GetType(&type)))
  1338. {
  1339. if (type == CCT_SNAPIN_MANAGER)
  1340. {
  1341. hr = S_OK;
  1342. }
  1343. }
  1344. pGPEDataObject->Release();
  1345. }
  1346. return (hr);
  1347. }
  1348. HRESULT CComponentData::GetDefaultDomain (LPTSTR *lpDomain, HWND hDlg)
  1349. {
  1350. LPTSTR lpUserName = NULL;
  1351. LPTSTR lpFullUserName = NULL;
  1352. LPTSTR lpResult = NULL;
  1353. LPTSTR lpDCName = NULL;
  1354. LPOLESTR lpDomainTemp = NULL;
  1355. LPTSTR lpFullDomain = NULL;
  1356. HRESULT hr = S_OK;
  1357. //
  1358. // Get the username in DN format
  1359. //
  1360. lpUserName = MyGetUserName (NameFullyQualifiedDN);
  1361. if (!lpUserName) {
  1362. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: MyGetUserName failed for DN style name with %d"),
  1363. GetLastError()));
  1364. hr = E_FAIL;
  1365. goto Exit;
  1366. }
  1367. ULONG ulNoChars = lstrlen(lpUserName) + 10;
  1368. lpFullUserName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1369. if (!lpFullUserName)
  1370. {
  1371. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to allocate memory for full user name with %d"),
  1372. GetLastError()));
  1373. hr = E_FAIL;
  1374. goto Exit;
  1375. }
  1376. hr = StringCchCopy (lpFullUserName, ulNoChars, TEXT("LDAP://"));
  1377. if (SUCCEEDED(hr))
  1378. {
  1379. hr = StringCchCat (lpFullUserName, ulNoChars, lpUserName);
  1380. }
  1381. if (FAILED(hr))
  1382. {
  1383. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to copy user name")));
  1384. goto Exit;
  1385. }
  1386. //
  1387. // Get the domain from the ldap path
  1388. //
  1389. lpDomainTemp = GetDomainFromLDAPPath(lpFullUserName);
  1390. if (!lpDomainTemp) {
  1391. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to get domain from ldap path")));
  1392. hr = E_FAIL;
  1393. goto Exit;
  1394. }
  1395. //
  1396. // Get the domain controller for this domain
  1397. //
  1398. hr = ConvertToDotStyle (lpDomainTemp, &lpResult);
  1399. if (FAILED(hr))
  1400. {
  1401. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to convert domain name with 0x%x"), hr));
  1402. hr = E_FAIL;
  1403. goto Exit;
  1404. }
  1405. lpDCName = GetDCName (lpResult, NULL, hDlg, TRUE, 0);
  1406. if (!lpDCName)
  1407. {
  1408. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to query <%s> for a DC name with 0xd"),
  1409. lpResult, GetLastError()));
  1410. hr = E_FAIL;
  1411. goto Exit;
  1412. }
  1413. //
  1414. // Build a fully qualified domain name to a specific DC
  1415. //
  1416. lpFullDomain = MakeFullPath (lpDomainTemp, lpDCName);
  1417. if (!lpFullDomain)
  1418. {
  1419. hr = E_FAIL;
  1420. goto Exit;
  1421. }
  1422. *lpDomain = lpFullDomain;
  1423. Exit:
  1424. if (lpDomainTemp)
  1425. delete [] lpDomainTemp;
  1426. if (lpUserName)
  1427. LocalFree (lpUserName);
  1428. if (lpFullUserName)
  1429. LocalFree (lpFullUserName);
  1430. if (lpResult)
  1431. LocalFree (lpResult);
  1432. if (lpDCName)
  1433. LocalFree (lpDCName);
  1434. return hr;
  1435. }
  1436. INT_PTR CALLBACK CComponentData::ChooseInitDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1437. {
  1438. CComponentData * pCD;
  1439. switch (message)
  1440. {
  1441. case WM_INITDIALOG:
  1442. {
  1443. TCHAR szDefaultGPO[128];
  1444. pCD = (CComponentData *) (((LPPROPSHEETPAGE)lParam)->lParam);
  1445. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pCD);
  1446. pCD->m_pChoosePath = NULL;
  1447. pCD->m_tChooseGPOType = GPOTypeLocal;
  1448. SendDlgItemMessage (hDlg, IDC_DS_GPO, BM_SETCHECK, BST_CHECKED, 0);
  1449. if (!pCD->m_hChooseBitmap)
  1450. {
  1451. pCD->m_hChooseBitmap = (HBITMAP) LoadImage (g_hInstance,
  1452. MAKEINTRESOURCE(IDB_WIZARD),
  1453. IMAGE_BITMAP, 0, 0,
  1454. LR_DEFAULTCOLOR);
  1455. }
  1456. if (pCD->m_hChooseBitmap)
  1457. {
  1458. SendDlgItemMessage (hDlg, IDC_BITMAP, STM_SETIMAGE,
  1459. IMAGE_BITMAP, (LPARAM) pCD->m_hChooseBitmap);
  1460. }
  1461. LoadString(g_hInstance, IDS_LOCAL_DISPLAY_NAME, szDefaultGPO,
  1462. ARRAYSIZE(szDefaultGPO));
  1463. SetDlgItemText (hDlg, IDC_OPEN_NAME, szDefaultGPO);
  1464. }
  1465. break;
  1466. case WM_COMMAND:
  1467. {
  1468. pCD = (CComponentData *) GetWindowLongPtr (hDlg, DWLP_USER);
  1469. if (!pCD) {
  1470. break;
  1471. }
  1472. switch (LOWORD(wParam))
  1473. {
  1474. case IDC_OPEN_BROWSE:
  1475. {
  1476. LPTSTR lpDomain = NULL;
  1477. TCHAR szPath[512];
  1478. TCHAR szName[MAX_FRIENDLYNAME];
  1479. GPOBROWSEINFO info;
  1480. ZeroMemory (&info, sizeof(GPOBROWSEINFO));
  1481. if (!IsStandaloneComputer())
  1482. {
  1483. pCD->GetDefaultDomain (&lpDomain, hDlg);
  1484. }
  1485. info.dwSize = sizeof(GPOBROWSEINFO);
  1486. info.hwndOwner = hDlg;
  1487. info.lpInitialOU = lpDomain;
  1488. info.lpDSPath = szPath;
  1489. info.dwDSPathSize = ARRAYSIZE(szPath);
  1490. info.lpName = szName;
  1491. info.dwNameSize = ARRAYSIZE(szName);
  1492. if (!lpDomain)
  1493. {
  1494. info.dwFlags = GPO_BROWSE_NODSGPOS;
  1495. }
  1496. if (SUCCEEDED(BrowseForGPO(&info)))
  1497. {
  1498. if (pCD->m_pChoosePath)
  1499. {
  1500. LocalFree (pCD->m_pChoosePath);
  1501. pCD->m_pChoosePath = NULL;
  1502. }
  1503. pCD->m_tChooseGPOType = info.gpoType;
  1504. switch (pCD->m_tChooseGPOType)
  1505. {
  1506. HRESULT hr;
  1507. ULONG ulNoChars;
  1508. default:
  1509. case GPOTypeLocal:
  1510. LoadString(g_hInstance, IDS_LOCAL_DISPLAY_NAME, szPath, ARRAYSIZE(szPath));
  1511. break;
  1512. case GPOTypeRemote:
  1513. ulNoChars = lstrlen (szName) + 1;
  1514. pCD->m_pChoosePath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1515. if (pCD->m_pChoosePath)
  1516. {
  1517. hr = StringCchCopy (pCD->m_pChoosePath, ulNoChars, szName);
  1518. ASSERT(SUCCEEDED(hr));
  1519. }
  1520. LoadString(g_hInstance, IDS_REMOTE_DISPLAY_NAME, szPath, ARRAYSIZE(szPath));
  1521. (void) StringCchCat(szPath, ARRAYSIZE(szPath), szName);
  1522. break;
  1523. case GPOTypeDS:
  1524. ulNoChars = lstrlen (szPath) + 1;
  1525. pCD->m_pChoosePath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
  1526. if (pCD->m_pChoosePath)
  1527. {
  1528. hr = StringCchCopy (pCD->m_pChoosePath, ulNoChars, szPath);
  1529. ASSERT(SUCCEEDED(hr));
  1530. }
  1531. (void) StringCchCopy(szPath, ARRAYSIZE(szPath),szName );
  1532. break;
  1533. }
  1534. SetDlgItemText (hDlg, IDC_OPEN_NAME, szPath);
  1535. }
  1536. if (lpDomain)
  1537. {
  1538. LocalFree (lpDomain);
  1539. }
  1540. }
  1541. break;
  1542. }
  1543. }
  1544. break;
  1545. case WM_REFRESHDISPLAY:
  1546. SetFocus (GetDlgItem(hDlg, IDC_OPEN_NAME));
  1547. break;
  1548. case WM_NOTIFY:
  1549. pCD = (CComponentData *) GetWindowLongPtr (hDlg, DWLP_USER);
  1550. if (!pCD) {
  1551. break;
  1552. }
  1553. switch (((NMHDR FAR*)lParam)->code)
  1554. {
  1555. case PSN_SETACTIVE:
  1556. PropSheet_SetWizButtons (GetParent(hDlg), PSWIZB_FINISH);
  1557. break;
  1558. case PSN_WIZFINISH:
  1559. if (FAILED(pCD->InitializeNewGPO(hDlg)))
  1560. {
  1561. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1562. PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0);
  1563. return TRUE;
  1564. }
  1565. // fall through
  1566. case PSN_RESET:
  1567. if (pCD->m_pChoosePath)
  1568. {
  1569. LocalFree (pCD->m_pChoosePath);
  1570. pCD->m_pChoosePath = NULL;
  1571. }
  1572. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  1573. return TRUE;
  1574. }
  1575. break;
  1576. }
  1577. return FALSE;
  1578. }
  1579. HRESULT CComponentData::EnumerateScopePane (LPDATAOBJECT lpDataObject, HSCOPEITEM hParent)
  1580. {
  1581. if (!m_hRoot) {
  1582. m_hRoot = hParent;
  1583. if (!m_bRefocusInit)
  1584. {
  1585. SCOPEDATAITEM rootItem;
  1586. DebugMsg((DM_VERBOSE, TEXT("CComponentData::EnumerateScopePane: Resetting the root node")));
  1587. m_bRefocusInit = TRUE;
  1588. ZeroMemory (&rootItem, sizeof(SCOPEDATAITEM));
  1589. rootItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1590. rootItem.displayname = MMC_CALLBACK;
  1591. if (m_pGPO)
  1592. {
  1593. rootItem.nImage = 2;
  1594. rootItem.nOpenImage = 2;
  1595. }
  1596. else
  1597. {
  1598. rootItem.nImage = 3;
  1599. rootItem.nOpenImage = 3;
  1600. }
  1601. rootItem.ID = hParent;
  1602. m_pScope->SetItem (&rootItem);
  1603. }
  1604. }
  1605. if (!m_pGPO)
  1606. {
  1607. if (m_hRoot == hParent)
  1608. {
  1609. SCOPEDATAITEM rootItem;
  1610. DebugMsg((DM_VERBOSE, TEXT("CComponentData::EnumerateScopePane: No GPO available. Exiting.")));
  1611. ZeroMemory (&rootItem, sizeof(SCOPEDATAITEM));
  1612. rootItem.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  1613. rootItem.displayname = MMC_CALLBACK;
  1614. rootItem.nImage = 3;
  1615. rootItem.nOpenImage = 3;
  1616. rootItem.nState = 0;
  1617. rootItem.cChildren = 0;
  1618. rootItem.lParam = g_NameSpace[0].dwID;
  1619. rootItem.relativeID = hParent;
  1620. m_pScope->InsertItem (&rootItem);
  1621. }
  1622. return S_OK;
  1623. }
  1624. // Now to do the actual enumeration ...
  1625. SCOPEDATAITEM item;
  1626. HRESULT hr;
  1627. DWORD dwIndex, i;
  1628. if (m_hRoot == hParent)
  1629. {
  1630. dwIndex = 0;
  1631. }
  1632. else
  1633. {
  1634. item.mask = SDI_PARAM;
  1635. item.ID = hParent;
  1636. hr = m_pScope->GetItem (&item);
  1637. if (FAILED(hr))
  1638. return hr;
  1639. dwIndex = (DWORD)item.lParam;
  1640. }
  1641. for (i = 0; i < g_dwNameSpaceItems; i++)
  1642. {
  1643. if (g_NameSpace[i].dwParent == dwIndex)
  1644. {
  1645. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  1646. item.displayname = MMC_CALLBACK;
  1647. item.nImage = g_NameSpace[i].iIcon;
  1648. item.nOpenImage = g_NameSpace[i].iOpenIcon;
  1649. item.nState = 0;
  1650. item.cChildren = g_NameSpace[i].cChildren;
  1651. item.lParam = g_NameSpace[i].dwID;
  1652. item.relativeID = hParent;
  1653. if (SUCCEEDED(m_pScope->InsertItem (&item)))
  1654. {
  1655. if (i == 1)
  1656. {
  1657. m_hMachine = item.ID;
  1658. }
  1659. else if (i == 2)
  1660. {
  1661. m_hUser = item.ID;
  1662. }
  1663. }
  1664. }
  1665. }
  1666. return S_OK;
  1667. }
  1668. HRESULT CComponentData::GetOptions (DWORD * pdwOptions)
  1669. {
  1670. if (!pdwOptions)
  1671. {
  1672. return E_INVALIDARG;
  1673. }
  1674. *pdwOptions = 0;
  1675. return S_OK;
  1676. }
  1677. ///////////////////////////////////////////////////////////////////////////////
  1678. // //
  1679. // Class factory object implementation //
  1680. // //
  1681. ///////////////////////////////////////////////////////////////////////////////
  1682. CComponentDataCF::CComponentDataCF()
  1683. {
  1684. m_cRef = 1;
  1685. InterlockedIncrement(&g_cRefThisDll);
  1686. }
  1687. CComponentDataCF::~CComponentDataCF()
  1688. {
  1689. InterlockedDecrement(&g_cRefThisDll);
  1690. }
  1691. ///////////////////////////////////////////////////////////////////////////////
  1692. // //
  1693. // Class factory object implementation (IUnknown) //
  1694. // //
  1695. ///////////////////////////////////////////////////////////////////////////////
  1696. STDMETHODIMP_(ULONG)
  1697. CComponentDataCF::AddRef()
  1698. {
  1699. return ++m_cRef;
  1700. }
  1701. STDMETHODIMP_(ULONG)
  1702. CComponentDataCF::Release()
  1703. {
  1704. if (--m_cRef == 0)
  1705. {
  1706. delete this;
  1707. return 0;
  1708. }
  1709. return m_cRef;
  1710. }
  1711. STDMETHODIMP
  1712. CComponentDataCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  1713. {
  1714. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  1715. {
  1716. *ppv = (LPCLASSFACTORY)this;
  1717. m_cRef++;
  1718. return S_OK;
  1719. }
  1720. else
  1721. {
  1722. *ppv = NULL;
  1723. return E_NOINTERFACE;
  1724. }
  1725. }
  1726. ///////////////////////////////////////////////////////////////////////////////
  1727. // //
  1728. // Class factory object implementation (IClassFactory) //
  1729. // //
  1730. ///////////////////////////////////////////////////////////////////////////////
  1731. STDMETHODIMP
  1732. CComponentDataCF::CreateInstance(LPUNKNOWN pUnkOuter,
  1733. REFIID riid,
  1734. LPVOID FAR* ppvObj)
  1735. {
  1736. *ppvObj = NULL;
  1737. if (pUnkOuter)
  1738. return CLASS_E_NOAGGREGATION;
  1739. CComponentData *pComponentData = new CComponentData(); // ref count == 1
  1740. if (!pComponentData)
  1741. return E_OUTOFMEMORY;
  1742. HRESULT hr = pComponentData->QueryInterface(riid, ppvObj);
  1743. pComponentData->Release(); // release initial ref
  1744. return hr;
  1745. }
  1746. STDMETHODIMP
  1747. CComponentDataCF::LockServer(BOOL fLock)
  1748. {
  1749. return E_NOTIMPL;
  1750. }