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

2282 lines
54 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_USER_DEFAULT, 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_USER_DEFAULT, 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_USER_DEFAULT, 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. if (lpPath)
  690. {
  691. LocalFree (lpPath);
  692. }
  693. lpPath = (LPTSTR) LocalAlloc (LPTR, (lstrlen(szComputerName) + 1) * sizeof(TCHAR));
  694. if (lpPath)
  695. {
  696. lstrcpy (lpPath, szComputerName);
  697. dwFlags &= ~MSC_FLAG_LOCAL_GPO;
  698. dwFlags &= ~MSC_FLAG_DS_GPO;
  699. dwFlags |= MSC_FLAG_REMOTE_GPO;
  700. }
  701. }
  702. continue;
  703. }
  704. iTemp = lstrlen (CMD_LINE_GPO);
  705. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  706. CMD_LINE_GPO, iTemp,
  707. lpTemp, iTemp) == CSTR_EQUAL)
  708. {
  709. //
  710. // Found the gpo switch
  711. //
  712. lpTemp += iTemp + 1;
  713. if (lpPath)
  714. {
  715. LocalFree (lpPath);
  716. }
  717. lpPath = (LPTSTR) LocalAlloc (LPTR, 512 * sizeof(TCHAR));
  718. if (!lpPath)
  719. {
  720. lpTemp++;
  721. continue;
  722. }
  723. dwFlags &= ~MSC_FLAG_LOCAL_GPO;
  724. dwFlags &= ~MSC_FLAG_REMOTE_GPO;
  725. dwFlags |= MSC_FLAG_DS_GPO;
  726. lpName = lpPath;
  727. while (*lpTemp && ((*lpTemp) != TEXT('\"')))
  728. *lpName++ = *lpTemp++;
  729. if ((*lpTemp) == TEXT('\"'))
  730. lpTemp++;
  731. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Command line path is: <%s>"), lpPath));
  732. continue;
  733. }
  734. }
  735. lpTemp++;
  736. } while (*lpTemp);
  737. }
  738. else if (dwFlags & MSC_FLAG_DS_GPO && dwPathLen > 0)
  739. {
  740. //
  741. // Get the friendly domain name
  742. //
  743. pszDomain = GetDomainFromLDAPPath(lpPath);
  744. if (!pszDomain)
  745. {
  746. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to get domain name")));
  747. hr = E_FAIL;
  748. goto Exit;
  749. }
  750. //
  751. // Convert LDAP to dot (DN) style
  752. //
  753. hr = ConvertToDotStyle (pszDomain, &lpDomainName);
  754. delete [] pszDomain;
  755. if (FAILED(hr))
  756. {
  757. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to convert domain name with 0x%x"), hr));
  758. goto Exit;
  759. }
  760. //
  761. // Get the domain controller for this domain
  762. //
  763. lpDCName = GetDCName (lpDomainName, NULL, NULL, TRUE, 0);
  764. LocalFree (lpDomainName);
  765. if (!lpDCName)
  766. {
  767. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to get DC name")));
  768. hr = HRESULT_FROM_WIN32(GetLastError());
  769. goto Exit;
  770. }
  771. //
  772. // Make a full path
  773. //
  774. lpTemp = MakeFullPath (lpPath, lpDCName);
  775. LocalFree (lpDCName);
  776. if (!lpTemp)
  777. {
  778. DebugMsg((DM_WARNING, TEXT("CComponentData::Load: Failed to make full path")));
  779. hr = HRESULT_FROM_WIN32(GetLastError());
  780. goto Exit;
  781. }
  782. //
  783. // Swap the relative path with the full path
  784. //
  785. LocalFree (lpPath);
  786. lpPath = lpTemp;
  787. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Full Path is: <%s>"), lpPath));
  788. }
  789. //
  790. // Do the appropriate action
  791. //
  792. if (dwFlags & MSC_FLAG_LOCAL_GPO)
  793. {
  794. hr = m_pGPO->OpenLocalMachineGPO(TRUE);
  795. if (FAILED(hr))
  796. {
  797. ReportError(m_hwndFrame, hr, IDS_FAILEDLOCAL);
  798. }
  799. }
  800. else if (dwFlags & MSC_FLAG_REMOTE_GPO)
  801. {
  802. if (lpPath)
  803. {
  804. hr = m_pGPO->OpenRemoteMachineGPO(lpPath, TRUE);
  805. if (FAILED(hr))
  806. {
  807. ReportError(m_hwndFrame, hr, IDS_FAILEDREMOTE, lpPath);
  808. }
  809. }
  810. else
  811. {
  812. hr = E_FAIL;
  813. ReportError(m_hwndFrame, hr, IDS_INVALIDMSC);
  814. }
  815. }
  816. else
  817. {
  818. if (lpPath)
  819. {
  820. hr = m_pGPO->OpenDSGPO(lpPath, GPO_OPEN_LOAD_REGISTRY);
  821. if (FAILED(hr))
  822. {
  823. ReportError(m_hwndFrame, hr, IDS_FAILEDDS, lpPath);
  824. }
  825. }
  826. else
  827. {
  828. hr = E_FAIL;
  829. ReportError(m_hwndFrame, hr, IDS_INVALIDMSC);
  830. }
  831. }
  832. if (SUCCEEDED(hr))
  833. {
  834. ClearDirty();
  835. m_gpHint = gpHint;
  836. BuildDisplayName();
  837. }
  838. Exit:
  839. if (FAILED(hr) && m_pGPO)
  840. {
  841. m_pGPO->Release();
  842. m_pGPO = NULL;
  843. }
  844. if (lpPath)
  845. {
  846. LocalFree (lpPath);
  847. }
  848. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Load: Leaving with 0x%x."), hr));
  849. return hr;
  850. }
  851. STDMETHODIMP CComponentData::Save(IStream *pStm, BOOL fClearDirty)
  852. {
  853. HRESULT hr = STG_E_CANTSAVE;
  854. ULONG nBytesWritten;
  855. DWORD dwTemp;
  856. DWORD dwFlags;
  857. GROUP_POLICY_OBJECT_TYPE gpoType;
  858. LPTSTR lpPath = NULL;
  859. LPTSTR lpTemp;
  860. DWORD dwPathSize = 1024;
  861. if (!pStm)
  862. {
  863. return E_FAIL;
  864. }
  865. if (!m_pGPO)
  866. {
  867. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: No GPO. Leaving.")));
  868. goto Exit;
  869. }
  870. //
  871. // Allocate a buffer to hold the path
  872. //
  873. lpPath = (LPTSTR) LocalAlloc(LPTR, dwPathSize * sizeof(TCHAR));
  874. if (!lpPath)
  875. {
  876. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to alloc buffer for path with %d."), GetLastError()));
  877. goto Exit;
  878. }
  879. //
  880. // Determine what the flags are
  881. //
  882. dwFlags = 0;
  883. if (m_bOverride)
  884. {
  885. dwFlags |= MSC_FLAG_OVERRIDE;
  886. }
  887. m_pGPO->GetType (&gpoType);
  888. if (gpoType == GPOTypeLocal)
  889. {
  890. dwFlags |= MSC_FLAG_LOCAL_GPO;
  891. hr = S_OK;
  892. }
  893. else if (gpoType == GPOTypeRemote)
  894. {
  895. dwFlags |= MSC_FLAG_REMOTE_GPO;
  896. hr = m_pGPO->GetMachineName (lpPath, dwPathSize);
  897. }
  898. else
  899. {
  900. dwFlags |= MSC_FLAG_DS_GPO;
  901. hr = m_pGPO->GetPath (lpPath, dwPathSize);
  902. if (SUCCEEDED(hr))
  903. {
  904. lpTemp = MakeNamelessPath (lpPath);
  905. if (!lpTemp)
  906. {
  907. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to get nameless path")));
  908. goto Exit;
  909. }
  910. DebugMsg((DM_VERBOSE, TEXT("CComponentData::Save: Nameless GPO path is: %s"), lpTemp));
  911. LocalFree (lpPath);
  912. lpPath = lpTemp;
  913. }
  914. }
  915. if (FAILED(hr))
  916. {
  917. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to get path with %d."), hr));
  918. goto Exit;
  919. }
  920. //
  921. // Save the version number
  922. //
  923. dwTemp = PERSIST_DATA_VERSION;
  924. hr = pStm->Write(&dwTemp, sizeof(dwTemp), &nBytesWritten);
  925. if ((hr != S_OK) || (nBytesWritten != sizeof(dwTemp)))
  926. {
  927. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write version number with %d."), hr));
  928. goto Exit;
  929. }
  930. //
  931. // Save the flags
  932. //
  933. hr = pStm->Write(&dwFlags, sizeof(dwFlags), &nBytesWritten);
  934. if ((hr != S_OK) || (nBytesWritten != sizeof(dwFlags)))
  935. {
  936. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write flags with %d."), hr));
  937. goto Exit;
  938. }
  939. //
  940. // Save the hint information
  941. //
  942. hr = pStm->Write(&m_gpHint, sizeof(m_gpHint), &nBytesWritten);
  943. if ((hr != S_OK) || (nBytesWritten != sizeof(m_gpHint)))
  944. {
  945. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write hint with %d."), hr));
  946. goto Exit;
  947. }
  948. //
  949. // Save the path length
  950. //
  951. dwTemp = lstrlen (lpPath);
  952. if (dwTemp)
  953. {
  954. dwTemp = (dwTemp + 1) * sizeof (TCHAR);
  955. }
  956. hr = pStm->Write(&dwTemp, sizeof(dwTemp), &nBytesWritten);
  957. if ((hr != S_OK) || (nBytesWritten != sizeof(dwTemp)))
  958. {
  959. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write ds path length with %d."), hr));
  960. goto Exit;
  961. }
  962. if (dwTemp)
  963. {
  964. //
  965. // Save the path
  966. //
  967. hr = pStm->Write(lpPath, dwTemp, &nBytesWritten);
  968. if ((hr != S_OK) || (nBytesWritten != dwTemp))
  969. {
  970. DebugMsg((DM_WARNING, TEXT("CComponentData::Save: Failed to write ds path with %d."), hr));
  971. goto Exit;
  972. }
  973. }
  974. if (fClearDirty)
  975. {
  976. ClearDirty();
  977. }
  978. Exit:
  979. if (lpPath)
  980. {
  981. LocalFree (lpPath);
  982. }
  983. return hr;
  984. }
  985. STDMETHODIMP CComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  986. {
  987. HRESULT hr = E_FAIL;
  988. DWORD dwSize;
  989. LPTSTR lpPath = NULL;
  990. LPTSTR lpTemp;
  991. GROUP_POLICY_OBJECT_TYPE gpoType;
  992. DWORD dwPathSize = 1024;
  993. DWORD dwStrLen;
  994. //
  995. // Check arguments
  996. //
  997. if (!pcbSize)
  998. {
  999. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: NULL pcbSize argument")));
  1000. goto Exit;
  1001. }
  1002. //
  1003. // Allocate a buffer to hold the path
  1004. //
  1005. lpPath = (LPTSTR) LocalAlloc(LPTR, dwPathSize * sizeof(TCHAR));
  1006. if (!lpPath)
  1007. {
  1008. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: Failed to alloc buffer for path with %d."), GetLastError()));
  1009. goto Exit;
  1010. }
  1011. //
  1012. // Get the path if appropriate
  1013. //
  1014. m_pGPO->GetType (&gpoType);
  1015. if (gpoType == GPOTypeLocal)
  1016. {
  1017. hr = S_OK;
  1018. }
  1019. else if (gpoType == GPOTypeRemote)
  1020. {
  1021. hr = m_pGPO->GetMachineName (lpPath, dwPathSize);
  1022. }
  1023. else
  1024. {
  1025. hr = m_pGPO->GetPath (lpPath, dwPathSize);
  1026. if (SUCCEEDED(hr))
  1027. {
  1028. lpTemp = MakeNamelessPath (lpPath);
  1029. if (!lpTemp)
  1030. {
  1031. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: Failed to get nameless path")));
  1032. goto Exit;
  1033. }
  1034. LocalFree (lpPath);
  1035. lpPath = lpTemp;
  1036. }
  1037. }
  1038. if (FAILED(hr))
  1039. {
  1040. DebugMsg((DM_WARNING, TEXT("CComponentData::GetSizeMax: Failed to get path with %d."), hr));
  1041. goto Exit;
  1042. }
  1043. //
  1044. // Set the stream size. Version Number + Flags + Length + Unicode String + null
  1045. //
  1046. dwSize = 3 * sizeof(DWORD);
  1047. dwStrLen = lstrlen(lpPath);
  1048. if (dwStrLen)
  1049. {
  1050. dwSize += (dwStrLen + 1) * sizeof (TCHAR);
  1051. }
  1052. ULISet32(*pcbSize, dwSize);
  1053. hr = S_OK;
  1054. Exit:
  1055. if (lpPath)
  1056. {
  1057. LocalFree (lpPath);
  1058. }
  1059. return hr;
  1060. }
  1061. STDMETHODIMP CComponentData::InitNew(void)
  1062. {
  1063. return S_OK;
  1064. }
  1065. ///////////////////////////////////////////////////////////////////////////////
  1066. // //
  1067. // CComponentData object implementation (ISnapinHelp) //
  1068. // //
  1069. ///////////////////////////////////////////////////////////////////////////////
  1070. STDMETHODIMP CComponentData::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  1071. {
  1072. LPOLESTR lpHelpFile;
  1073. lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
  1074. if (!lpHelpFile)
  1075. {
  1076. DebugMsg((DM_WARNING, TEXT("CComponentData::GetHelpTopic: Failed to allocate memory.")));
  1077. return E_OUTOFMEMORY;
  1078. }
  1079. ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gpedit.chm",
  1080. lpHelpFile, MAX_PATH);
  1081. *lpCompiledHelpFile = lpHelpFile;
  1082. return S_OK;
  1083. }
  1084. ///////////////////////////////////////////////////////////////////////////////
  1085. // //
  1086. // CComponentData object implementation (Internal functions) //
  1087. // //
  1088. ///////////////////////////////////////////////////////////////////////////////
  1089. HRESULT CComponentData::InitializeNewGPO(HWND hDlg)
  1090. {
  1091. HRESULT hr;
  1092. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: Entering")));
  1093. SetWaitCursor();
  1094. //
  1095. // Clean up existing GPO
  1096. //
  1097. if (m_pGPO)
  1098. {
  1099. m_pGPO->Release();
  1100. }
  1101. //
  1102. // Create a new GPO object to work with
  1103. //
  1104. hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL,
  1105. CLSCTX_SERVER, IID_IGroupPolicyObject,
  1106. (void**)&m_pGPO);
  1107. if (FAILED(hr))
  1108. {
  1109. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to create GPO with 0x%x."), hr));
  1110. goto Exit;
  1111. }
  1112. //
  1113. // Determine which item was selected
  1114. //
  1115. switch (m_tChooseGPOType)
  1116. {
  1117. case GPOTypeLocal:
  1118. //
  1119. // Open local policy
  1120. //
  1121. hr = m_pGPO->OpenLocalMachineGPO(TRUE);
  1122. if (FAILED(hr))
  1123. {
  1124. ReportError(hDlg, hr, IDS_FAILEDLOCAL);
  1125. }
  1126. else
  1127. {
  1128. m_gpHint = GPHintMachine;
  1129. }
  1130. break;
  1131. case GPOTypeRemote:
  1132. //
  1133. // Open remote policy
  1134. //
  1135. hr = m_pGPO->OpenRemoteMachineGPO (m_pChoosePath, TRUE);
  1136. if (FAILED(hr))
  1137. {
  1138. ReportError(hDlg, hr, IDS_FAILEDREMOTE, m_pChoosePath);
  1139. }
  1140. else
  1141. {
  1142. m_gpHint = GPHintMachine;
  1143. }
  1144. break;
  1145. case GPOTypeDS:
  1146. {
  1147. LPOLESTR pszDomain;
  1148. LPTSTR lpDomainName;
  1149. LPTSTR lpDCName;
  1150. LPTSTR lpTemp;
  1151. //
  1152. // Open existing DS GPO
  1153. //
  1154. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: User selected %s"), m_pChoosePath));
  1155. //
  1156. // Get the friendly domain name
  1157. //
  1158. pszDomain = GetDomainFromLDAPPath(m_pChoosePath);
  1159. if (!pszDomain)
  1160. {
  1161. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to get domain name")));
  1162. hr = E_FAIL;
  1163. goto Exit;
  1164. }
  1165. //
  1166. // Convert LDAP to dot (DN) style
  1167. //
  1168. hr = ConvertToDotStyle (pszDomain, &lpDomainName);
  1169. delete [] pszDomain;
  1170. if (FAILED(hr))
  1171. {
  1172. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to convert domain name with 0x%x"), hr));
  1173. goto Exit;
  1174. }
  1175. //
  1176. // Get the domain controller for this domain
  1177. //
  1178. lpDCName = GetDCName (lpDomainName, NULL, hDlg, TRUE, 0);
  1179. LocalFree (lpDomainName);
  1180. if (!lpDCName)
  1181. {
  1182. DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeNewGPO: Failed to get DC name")));
  1183. goto Exit;
  1184. }
  1185. //
  1186. // Build the full path
  1187. //
  1188. lpTemp = MakeFullPath (m_pChoosePath, lpDCName);
  1189. LocalFree (lpDCName);
  1190. if (!lpTemp)
  1191. {
  1192. hr = HRESULT_FROM_WIN32(GetLastError());
  1193. goto Exit;
  1194. }
  1195. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: Full ADSI path is %s"),
  1196. lpTemp));
  1197. hr = m_pGPO->OpenDSGPO (lpTemp, GPO_OPEN_LOAD_REGISTRY);
  1198. if (FAILED(hr))
  1199. {
  1200. ReportError(hDlg, hr, IDS_FAILEDDS, lpTemp);
  1201. }
  1202. else
  1203. {
  1204. m_gpHint = GPHintUnknown;
  1205. }
  1206. LocalFree (lpTemp);
  1207. }
  1208. break;
  1209. default:
  1210. hr = E_FAIL;
  1211. }
  1212. Exit:
  1213. ClearWaitCursor();
  1214. if (SUCCEEDED(hr))
  1215. {
  1216. if (IsDlgButtonChecked (hDlg, IDC_OVERRIDE))
  1217. {
  1218. m_bOverride = TRUE;
  1219. }
  1220. else
  1221. {
  1222. m_bOverride = FALSE;
  1223. }
  1224. SetDirty();
  1225. BuildDisplayName();
  1226. }
  1227. else
  1228. {
  1229. if (m_pGPO)
  1230. {
  1231. m_pGPO->Release();
  1232. m_pGPO = NULL;
  1233. }
  1234. }
  1235. DebugMsg((DM_VERBOSE, TEXT("CComponentData::InitializeNewGPO: Leaving with 0x%x."), hr));
  1236. return hr;
  1237. }
  1238. HRESULT CComponentData::BuildDisplayName(void)
  1239. {
  1240. WCHAR szDispName[50];
  1241. WCHAR szDisplayName[MAX_FRIENDLYNAME + MAX_PATH + 20];
  1242. WCHAR szFriendlyName[MAX_FRIENDLYNAME];
  1243. WCHAR szDCName[MAX_PATH];
  1244. GROUP_POLICY_OBJECT_TYPE type;
  1245. szDisplayName[0] = TEXT('\0');
  1246. if (SUCCEEDED(m_pGPO->GetDisplayName(szFriendlyName, ARRAYSIZE(szFriendlyName))))
  1247. {
  1248. if (SUCCEEDED(m_pGPO->GetMachineName(szDCName, ARRAYSIZE(szDCName))))
  1249. {
  1250. if (SUCCEEDED(m_pGPO->GetType(&type)))
  1251. {
  1252. if ((szDCName[0] == TEXT('\0')) || (type != GPOTypeDS))
  1253. {
  1254. LoadStringW (g_hInstance, IDS_DISPLAYNAME, szDispName, ARRAYSIZE(szDispName));
  1255. wsprintf (szDisplayName, szDispName, szFriendlyName);
  1256. }
  1257. else
  1258. {
  1259. LoadStringW (g_hInstance, IDS_DISPLAYNAME2, szDispName, ARRAYSIZE(szDispName));
  1260. wsprintf (szDisplayName, szDispName, szFriendlyName, szDCName);
  1261. }
  1262. }
  1263. }
  1264. }
  1265. if (szDisplayName[0] == TEXT('\0'))
  1266. {
  1267. LoadStringW (g_hInstance, IDS_SNAPIN_NAME, szDisplayName, ARRAYSIZE(szDisplayName));
  1268. }
  1269. m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(szDisplayName) + 1) * sizeof(TCHAR));
  1270. if (m_pDisplayName)
  1271. {
  1272. lstrcpy (m_pDisplayName, szDisplayName);
  1273. }
  1274. return S_OK;
  1275. }
  1276. //
  1277. // Returns S_OK if this is the GPO root in the scope pane or results pane.
  1278. // S_FALSE if not.
  1279. //
  1280. HRESULT CComponentData::IsGPORoot (LPDATAOBJECT lpDataObject)
  1281. {
  1282. HRESULT hr = S_FALSE;
  1283. LPGPEDATAOBJECT pGPEDataObject;
  1284. DATA_OBJECT_TYPES type;
  1285. MMC_COOKIE cookie;
  1286. //
  1287. // We can determine if this is a GPO DataObject by trying to
  1288. // QI for the private IGPEDataObject interface. If found,
  1289. // it belongs to us.
  1290. //
  1291. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IGPEDataObject,
  1292. (LPVOID *)&pGPEDataObject)))
  1293. {
  1294. pGPEDataObject->GetType(&type);
  1295. pGPEDataObject->GetCookie(&cookie);
  1296. if ((type == CCT_SCOPE) && (cookie == 0))
  1297. {
  1298. hr = S_OK;
  1299. }
  1300. pGPEDataObject->Release();
  1301. }
  1302. return (hr);
  1303. }
  1304. HRESULT CComponentData::IsSnapInManager (LPDATAOBJECT lpDataObject)
  1305. {
  1306. HRESULT hr = S_FALSE;
  1307. LPGPEDATAOBJECT pGPEDataObject;
  1308. DATA_OBJECT_TYPES type;
  1309. //
  1310. // We can determine if this is a GPO DataObject by trying to
  1311. // QI for the private IGPEDataObject interface. If found,
  1312. // it belongs to us.
  1313. //
  1314. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IGPEDataObject,
  1315. (LPVOID *)&pGPEDataObject)))
  1316. {
  1317. //
  1318. // This is a GPO object. Now see if is a scope pane
  1319. // data object. We only want to display the property
  1320. // sheet for the scope pane.
  1321. //
  1322. if (SUCCEEDED(pGPEDataObject->GetType(&type)))
  1323. {
  1324. if (type == CCT_SNAPIN_MANAGER)
  1325. {
  1326. hr = S_OK;
  1327. }
  1328. }
  1329. pGPEDataObject->Release();
  1330. }
  1331. return (hr);
  1332. }
  1333. HRESULT CComponentData::GetDefaultDomain (LPTSTR *lpDomain, HWND hDlg)
  1334. {
  1335. LPTSTR lpUserName = NULL;
  1336. LPTSTR lpFullUserName = NULL;
  1337. LPTSTR lpResult = NULL;
  1338. LPTSTR lpDCName = NULL;
  1339. LPOLESTR lpDomainTemp = NULL;
  1340. LPTSTR lpFullDomain = NULL;
  1341. HRESULT hr = S_OK;
  1342. //
  1343. // Get the username in DN format
  1344. //
  1345. lpUserName = MyGetUserName (NameFullyQualifiedDN);
  1346. if (!lpUserName) {
  1347. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: MyGetUserName failed for DN style name with %d"),
  1348. GetLastError()));
  1349. hr = E_FAIL;
  1350. goto Exit;
  1351. }
  1352. lpFullUserName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(lpUserName) + 10) * sizeof(TCHAR));
  1353. if (!lpFullUserName)
  1354. {
  1355. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to allocate memory for full user name with %d"),
  1356. GetLastError()));
  1357. hr = E_FAIL;
  1358. goto Exit;
  1359. }
  1360. lstrcpy (lpFullUserName, TEXT("LDAP://"));
  1361. lstrcat (lpFullUserName, lpUserName);
  1362. //
  1363. // Get the domain from the ldap path
  1364. //
  1365. lpDomainTemp = GetDomainFromLDAPPath(lpFullUserName);
  1366. if (!lpDomainTemp) {
  1367. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to get domain from ldap path")));
  1368. hr = E_FAIL;
  1369. goto Exit;
  1370. }
  1371. //
  1372. // Get the domain controller for this domain
  1373. //
  1374. hr = ConvertToDotStyle (lpDomainTemp, &lpResult);
  1375. if (FAILED(hr))
  1376. {
  1377. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to convert domain name with 0x%x"), hr));
  1378. hr = E_FAIL;
  1379. goto Exit;
  1380. }
  1381. lpDCName = GetDCName (lpResult, NULL, hDlg, TRUE, 0);
  1382. if (!lpDCName)
  1383. {
  1384. DebugMsg((DM_WARNING, TEXT("CComponentData::GetDefaultDomain: Failed to query <%s> for a DC name with 0xd"),
  1385. lpResult, GetLastError()));
  1386. hr = E_FAIL;
  1387. goto Exit;
  1388. }
  1389. //
  1390. // Build a fully qualified domain name to a specific DC
  1391. //
  1392. lpFullDomain = MakeFullPath (lpDomainTemp, lpDCName);
  1393. if (!lpFullDomain)
  1394. {
  1395. hr = E_FAIL;
  1396. goto Exit;
  1397. }
  1398. *lpDomain = lpFullDomain;
  1399. Exit:
  1400. if (lpDomainTemp)
  1401. delete [] lpDomainTemp;
  1402. if (lpUserName)
  1403. LocalFree (lpUserName);
  1404. if (lpFullUserName)
  1405. LocalFree (lpFullUserName);
  1406. if (lpResult)
  1407. LocalFree (lpResult);
  1408. if (lpDCName)
  1409. LocalFree (lpDCName);
  1410. return hr;
  1411. }
  1412. INT_PTR CALLBACK CComponentData::ChooseInitDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1413. {
  1414. CComponentData * pCD;
  1415. switch (message)
  1416. {
  1417. case WM_INITDIALOG:
  1418. {
  1419. TCHAR szDefaultGPO[128];
  1420. pCD = (CComponentData *) (((LPPROPSHEETPAGE)lParam)->lParam);
  1421. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pCD);
  1422. pCD->m_pChoosePath = NULL;
  1423. pCD->m_tChooseGPOType = GPOTypeLocal;
  1424. SendDlgItemMessage (hDlg, IDC_DS_GPO, BM_SETCHECK, BST_CHECKED, 0);
  1425. if (!pCD->m_hChooseBitmap)
  1426. {
  1427. pCD->m_hChooseBitmap = (HBITMAP) LoadImage (g_hInstance,
  1428. MAKEINTRESOURCE(IDB_WIZARD),
  1429. IMAGE_BITMAP, 0, 0,
  1430. LR_DEFAULTCOLOR);
  1431. }
  1432. if (pCD->m_hChooseBitmap)
  1433. {
  1434. SendDlgItemMessage (hDlg, IDC_BITMAP, STM_SETIMAGE,
  1435. IMAGE_BITMAP, (LPARAM) pCD->m_hChooseBitmap);
  1436. }
  1437. LoadString(g_hInstance, IDS_LOCAL_DISPLAY_NAME, szDefaultGPO,
  1438. ARRAYSIZE(szDefaultGPO));
  1439. SetDlgItemText (hDlg, IDC_OPEN_NAME, szDefaultGPO);
  1440. }
  1441. break;
  1442. case WM_COMMAND:
  1443. {
  1444. pCD = (CComponentData *) GetWindowLongPtr (hDlg, DWLP_USER);
  1445. if (!pCD) {
  1446. break;
  1447. }
  1448. switch (LOWORD(wParam))
  1449. {
  1450. case IDC_OPEN_BROWSE:
  1451. {
  1452. LPTSTR lpDomain = NULL;
  1453. TCHAR szPath[512];
  1454. TCHAR szName[MAX_FRIENDLYNAME];
  1455. GPOBROWSEINFO info;
  1456. ZeroMemory (&info, sizeof(GPOBROWSEINFO));
  1457. if (!IsStandaloneComputer())
  1458. {
  1459. pCD->GetDefaultDomain (&lpDomain, hDlg);
  1460. }
  1461. info.dwSize = sizeof(GPOBROWSEINFO);
  1462. info.hwndOwner = hDlg;
  1463. info.lpInitialOU = lpDomain;
  1464. info.lpDSPath = szPath;
  1465. info.dwDSPathSize = ARRAYSIZE(szPath);
  1466. info.lpName = szName;
  1467. info.dwNameSize = ARRAYSIZE(szName);
  1468. if (!lpDomain)
  1469. {
  1470. info.dwFlags = GPO_BROWSE_NODSGPOS;
  1471. }
  1472. if (SUCCEEDED(BrowseForGPO(&info)))
  1473. {
  1474. if (pCD->m_pChoosePath)
  1475. {
  1476. LocalFree (pCD->m_pChoosePath);
  1477. pCD->m_pChoosePath = NULL;
  1478. }
  1479. pCD->m_tChooseGPOType = info.gpoType;
  1480. switch (pCD->m_tChooseGPOType)
  1481. {
  1482. default:
  1483. case GPOTypeLocal:
  1484. LoadString(g_hInstance, IDS_LOCAL_DISPLAY_NAME, szPath, ARRAYSIZE(szPath));
  1485. break;
  1486. case GPOTypeRemote:
  1487. pCD->m_pChoosePath = (LPTSTR) LocalAlloc (LPTR, (lstrlen (szName) + 1) * sizeof(TCHAR));
  1488. if (pCD->m_pChoosePath)
  1489. {
  1490. lstrcpy (pCD->m_pChoosePath, szName);
  1491. }
  1492. LoadString(g_hInstance, IDS_REMOTE_DISPLAY_NAME, szPath, ARRAYSIZE(szPath));
  1493. lstrcat(szPath, szName);
  1494. break;
  1495. case GPOTypeDS:
  1496. pCD->m_pChoosePath = (LPTSTR) LocalAlloc (LPTR, (lstrlen (szPath) + 1) * sizeof(TCHAR));
  1497. if (pCD->m_pChoosePath)
  1498. {
  1499. lstrcpy (pCD->m_pChoosePath, szPath);
  1500. }
  1501. lstrcpy(szPath, szName);
  1502. break;
  1503. }
  1504. SetDlgItemText (hDlg, IDC_OPEN_NAME, szPath);
  1505. }
  1506. if (lpDomain)
  1507. {
  1508. LocalFree (lpDomain);
  1509. }
  1510. }
  1511. break;
  1512. }
  1513. }
  1514. break;
  1515. case WM_REFRESHDISPLAY:
  1516. SetFocus (GetDlgItem(hDlg, IDC_OPEN_NAME));
  1517. break;
  1518. case WM_NOTIFY:
  1519. pCD = (CComponentData *) GetWindowLongPtr (hDlg, DWLP_USER);
  1520. if (!pCD) {
  1521. break;
  1522. }
  1523. switch (((NMHDR FAR*)lParam)->code)
  1524. {
  1525. case PSN_SETACTIVE:
  1526. PropSheet_SetWizButtons (GetParent(hDlg), PSWIZB_FINISH);
  1527. break;
  1528. case PSN_WIZFINISH:
  1529. if (FAILED(pCD->InitializeNewGPO(hDlg)))
  1530. {
  1531. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1532. PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0);
  1533. return TRUE;
  1534. }
  1535. // fall through
  1536. case PSN_RESET:
  1537. if (pCD->m_pChoosePath)
  1538. {
  1539. LocalFree (pCD->m_pChoosePath);
  1540. pCD->m_pChoosePath = NULL;
  1541. }
  1542. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  1543. return TRUE;
  1544. }
  1545. break;
  1546. }
  1547. return FALSE;
  1548. }
  1549. HRESULT CComponentData::EnumerateScopePane (LPDATAOBJECT lpDataObject, HSCOPEITEM hParent)
  1550. {
  1551. SCOPEDATAITEM item;
  1552. HRESULT hr;
  1553. DWORD dwIndex, i;
  1554. if (!m_hRoot) {
  1555. m_hRoot = hParent;
  1556. if (!m_bRefocusInit)
  1557. {
  1558. SCOPEDATAITEM item;
  1559. DebugMsg((DM_VERBOSE, TEXT("CComponentData::EnumerateScopePane: Resetting the root node")));
  1560. m_bRefocusInit = TRUE;
  1561. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  1562. item.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1563. item.displayname = MMC_CALLBACK;
  1564. if (m_pGPO)
  1565. {
  1566. item.nImage = 2;
  1567. item.nOpenImage = 2;
  1568. }
  1569. else
  1570. {
  1571. item.nImage = 3;
  1572. item.nOpenImage = 3;
  1573. }
  1574. item.ID = hParent;
  1575. m_pScope->SetItem (&item);
  1576. }
  1577. }
  1578. if (!m_pGPO)
  1579. {
  1580. if (m_hRoot == hParent)
  1581. {
  1582. SCOPEDATAITEM item;
  1583. DebugMsg((DM_VERBOSE, TEXT("CComponentData::EnumerateScopePane: No GPO available. Exiting.")));
  1584. ZeroMemory (&item, sizeof(SCOPEDATAITEM));
  1585. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  1586. item.displayname = MMC_CALLBACK;
  1587. item.nImage = 3;
  1588. item.nOpenImage = 3;
  1589. item.nState = 0;
  1590. item.cChildren = 0;
  1591. item.lParam = g_NameSpace[0].dwID;
  1592. item.relativeID = hParent;
  1593. m_pScope->InsertItem (&item);
  1594. }
  1595. return S_OK;
  1596. }
  1597. if (m_hRoot == hParent)
  1598. {
  1599. dwIndex = 0;
  1600. }
  1601. else
  1602. {
  1603. item.mask = SDI_PARAM;
  1604. item.ID = hParent;
  1605. hr = m_pScope->GetItem (&item);
  1606. if (FAILED(hr))
  1607. return hr;
  1608. dwIndex = (DWORD)item.lParam;
  1609. }
  1610. for (i = 0; i < g_dwNameSpaceItems; i++)
  1611. {
  1612. if (g_NameSpace[i].dwParent == dwIndex)
  1613. {
  1614. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  1615. item.displayname = MMC_CALLBACK;
  1616. item.nImage = g_NameSpace[i].iIcon;
  1617. item.nOpenImage = g_NameSpace[i].iOpenIcon;
  1618. item.nState = 0;
  1619. item.cChildren = g_NameSpace[i].cChildren;
  1620. item.lParam = g_NameSpace[i].dwID;
  1621. item.relativeID = hParent;
  1622. if (SUCCEEDED(m_pScope->InsertItem (&item)))
  1623. {
  1624. if (i == 1)
  1625. {
  1626. m_hMachine = item.ID;
  1627. }
  1628. else if (i == 2)
  1629. {
  1630. m_hUser = item.ID;
  1631. }
  1632. }
  1633. }
  1634. }
  1635. return S_OK;
  1636. }
  1637. HRESULT CComponentData::GetOptions (DWORD * pdwOptions)
  1638. {
  1639. if (!pdwOptions)
  1640. {
  1641. return E_INVALIDARG;
  1642. }
  1643. *pdwOptions = 0;
  1644. return S_OK;
  1645. }
  1646. ///////////////////////////////////////////////////////////////////////////////
  1647. // //
  1648. // Class factory object implementation //
  1649. // //
  1650. ///////////////////////////////////////////////////////////////////////////////
  1651. CComponentDataCF::CComponentDataCF()
  1652. {
  1653. m_cRef = 1;
  1654. InterlockedIncrement(&g_cRefThisDll);
  1655. }
  1656. CComponentDataCF::~CComponentDataCF()
  1657. {
  1658. InterlockedDecrement(&g_cRefThisDll);
  1659. }
  1660. ///////////////////////////////////////////////////////////////////////////////
  1661. // //
  1662. // Class factory object implementation (IUnknown) //
  1663. // //
  1664. ///////////////////////////////////////////////////////////////////////////////
  1665. STDMETHODIMP_(ULONG)
  1666. CComponentDataCF::AddRef()
  1667. {
  1668. return ++m_cRef;
  1669. }
  1670. STDMETHODIMP_(ULONG)
  1671. CComponentDataCF::Release()
  1672. {
  1673. if (--m_cRef == 0)
  1674. {
  1675. delete this;
  1676. return 0;
  1677. }
  1678. return m_cRef;
  1679. }
  1680. STDMETHODIMP
  1681. CComponentDataCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  1682. {
  1683. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  1684. {
  1685. *ppv = (LPCLASSFACTORY)this;
  1686. m_cRef++;
  1687. return S_OK;
  1688. }
  1689. else
  1690. {
  1691. *ppv = NULL;
  1692. return E_NOINTERFACE;
  1693. }
  1694. }
  1695. ///////////////////////////////////////////////////////////////////////////////
  1696. // //
  1697. // Class factory object implementation (IClassFactory) //
  1698. // //
  1699. ///////////////////////////////////////////////////////////////////////////////
  1700. STDMETHODIMP
  1701. CComponentDataCF::CreateInstance(LPUNKNOWN pUnkOuter,
  1702. REFIID riid,
  1703. LPVOID FAR* ppvObj)
  1704. {
  1705. *ppvObj = NULL;
  1706. if (pUnkOuter)
  1707. return CLASS_E_NOAGGREGATION;
  1708. CComponentData *pComponentData = new CComponentData(); // ref count == 1
  1709. if (!pComponentData)
  1710. return E_OUTOFMEMORY;
  1711. HRESULT hr = pComponentData->QueryInterface(riid, ppvObj);
  1712. pComponentData->Release(); // release initial ref
  1713. return hr;
  1714. }
  1715. STDMETHODIMP
  1716. CComponentDataCF::LockServer(BOOL fLock)
  1717. {
  1718. return E_NOTIMPL;
  1719. }