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.

1123 lines
32 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: result.cpp
  7. //
  8. // Contents: implementation of the result pane
  9. //
  10. // Classes: CResultPane
  11. //
  12. // History: 03-17-1998 stevebl Created
  13. // 07-16-1998 rahulth added calls to IGPEInformation::PolicyChanged()
  14. //
  15. //---------------------------------------------------------------------------
  16. #include "precomp.hxx"
  17. #include <shlobj.h>
  18. #include <atlimpl.cpp>
  19. #include <wbemcli.h>
  20. #include "rsoputil.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. const int HeaderWidths [] =
  27. {
  28. 200, //name
  29. 60, //size
  30. 100, //type
  31. 100 //modified date
  32. };
  33. const int RSOPHeaderWidths [] =
  34. {
  35. 150, // precedence
  36. 200, // redirected path
  37. 100, // group
  38. 75, // setting
  39. 100, // gpo
  40. 60, // exclusive
  41. 50, // move
  42. 150 // policy removal
  43. };
  44. long CResultPane::lDataObjectRefCount = 0;
  45. // Internal private format
  46. const wchar_t* SNAPIN_INTERNAL = L"FDE_INTERNAL";
  47. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  48. //+--------------------------------------------------------------------------
  49. //
  50. // Function: ExtractInternalFormat
  51. //
  52. // Synopsis: Returns a pointer to our private object format given an
  53. // LPDATAOBJECT
  54. //
  55. // Arguments: [lpDataObject] - pointer to a DATAOBJECT, generally from a
  56. // MMC call.
  57. //
  58. // Returns: A pointer to INTERNAL, our internal object structure.
  59. // NULL - if the object doesn't contain one of our objects
  60. // (wasn't created by us)
  61. //
  62. // History: 3-13-1998 stevebl Commented
  63. //
  64. //---------------------------------------------------------------------------
  65. INTERNAL* ExtractInternalFormat(LPDATAOBJECT lpDataObject)
  66. {
  67. INTERNAL* internal = NULL;
  68. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  69. FORMATETC formatetc = { (CLIPFORMAT)CDataObject::m_cfInternal, NULL,
  70. DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  71. };
  72. if (!lpDataObject)
  73. return NULL;
  74. // Allocate memory for the stream
  75. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, sizeof(INTERNAL));
  76. // Attempt to get data from the object
  77. do
  78. {
  79. if (stgmedium.hGlobal == NULL)
  80. break;
  81. if (FAILED(lpDataObject->GetDataHere(&formatetc, &stgmedium)))
  82. break;
  83. internal = reinterpret_cast<INTERNAL*>(stgmedium.hGlobal);
  84. if (internal == NULL)
  85. break;
  86. } while (FALSE);
  87. return internal;
  88. }
  89. /////////////////////////////////////////////////////////////////////////////
  90. // CResultPane's IComponent implementation
  91. STDMETHODIMP CResultPane::GetResultViewType(MMC_COOKIE cookie, BSTR* ppViewType, LONG * pViewOptions)
  92. {
  93. // Use default view
  94. return S_FALSE;
  95. }
  96. STDMETHODIMP CResultPane::Initialize(LPCONSOLE lpConsole)
  97. {
  98. ASSERT(lpConsole != NULL);
  99. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  100. // Save the IConsole pointer
  101. m_pConsole = lpConsole;
  102. m_pConsole->AddRef();
  103. // Load resource strings
  104. LoadResources();
  105. // QI for a IHeaderCtrl
  106. HRESULT hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
  107. reinterpret_cast<void**>(&m_pHeader));
  108. // Give the console the header control interface pointer
  109. if (SUCCEEDED(hr))
  110. m_pConsole->SetHeader(m_pHeader);
  111. m_pConsole->QueryInterface(IID_IResultData,
  112. reinterpret_cast<void**>(&m_pResult));
  113. hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
  114. ASSERT(hr == S_OK);
  115. return S_OK;
  116. }
  117. STDMETHODIMP CResultPane::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  118. {
  119. HRESULT hr = S_OK;
  120. MMC_COOKIE cookie;
  121. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  122. if (event == MMCN_PROPERTY_CHANGE)
  123. {
  124. hr = OnPropertyChange(param);
  125. }
  126. else if (event == MMCN_VIEW_CHANGE)
  127. {
  128. hr = OnUpdateView(lpDataObject);
  129. }
  130. else
  131. {
  132. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  133. if (pInternal == NULL)
  134. {
  135. cookie = 0;
  136. }
  137. else
  138. {
  139. cookie = pInternal->m_cookie;
  140. }
  141. switch(event)
  142. {
  143. case MMCN_ACTIVATE:
  144. hr = OnActivate(cookie, arg, param);
  145. break;
  146. case MMCN_CLICK:
  147. hr = OnResultItemClkOrDblClk(cookie, FALSE);
  148. break;
  149. case MMCN_DBLCLICK:
  150. if (pInternal && pInternal->m_type == CCT_RESULT)
  151. hr = OnResultItemClkOrDblClk(cookie, TRUE);
  152. else
  153. hr = S_FALSE;
  154. break;
  155. case MMCN_ADD_IMAGES:
  156. hr = OnAddImages(cookie, arg, param);
  157. break;
  158. case MMCN_SHOW:
  159. hr = OnShow (cookie, arg, param);
  160. break;
  161. case MMCN_MINIMIZED:
  162. hr = OnMinimize(cookie, arg, param);
  163. break;
  164. case MMCN_SELECT:
  165. if (pInternal)
  166. hr = OnSelect(pInternal->m_type, cookie, arg, param);
  167. else
  168. hr = S_FALSE;
  169. break;
  170. case MMCN_COLUMNS_CHANGED:
  171. break;
  172. case MMCN_COLUMN_CLICK:
  173. // retain column number and sort option flags so we can pass
  174. // them in to sort in the event we need to trigger a resort of
  175. // the result pane
  176. m_nSortColumn = arg;
  177. m_dwSortOptions = param;
  178. break;
  179. case MMCN_CONTEXTHELP:
  180. hr = OnContextHelp();
  181. break;
  182. // Note - Future expansion of notify types possible
  183. default:
  184. //perform the default action
  185. hr = S_FALSE;
  186. break;
  187. }
  188. if (pInternal)
  189. {
  190. FREE_INTERNAL(pInternal);
  191. }
  192. }
  193. return hr;
  194. }
  195. STDMETHODIMP CResultPane::Destroy(MMC_COOKIE cookie)
  196. {
  197. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  198. // Release the interfaces that we QI'ed
  199. if (m_pConsole != NULL)
  200. {
  201. // Tell the console to release the header control interface
  202. m_pConsole->SetHeader(NULL);
  203. SAFE_RELEASE(m_pHeader);
  204. SAFE_RELEASE(m_pResult);
  205. SAFE_RELEASE(m_pConsoleVerb);
  206. // Release the IConsole interface last
  207. SAFE_RELEASE(m_pConsole);
  208. if (m_pScopePane)
  209. {
  210. ((IComponentData*)m_pScopePane)->Release(); // QI'ed in IComponentDataImpl::CreateComponent
  211. }
  212. }
  213. return S_OK;
  214. }
  215. STDMETHODIMP CResultPane::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  216. LPDATAOBJECT* ppDataObject)
  217. {
  218. ASSERT(ppDataObject != NULL);
  219. CComObject<CDataObject>* pObject = NULL;
  220. CComObject<CDataObject>::CreateInstance(&pObject);
  221. ASSERT(pObject != NULL);
  222. if (!pObject)
  223. return E_UNEXPECTED;
  224. // Save cookie and type for delayed rendering
  225. pObject->SetType(type);
  226. pObject->SetCookie(cookie);
  227. return pObject->QueryInterface(IID_IDataObject,
  228. reinterpret_cast<void**>(ppDataObject));
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. // CResultPane's implementation specific members
  232. DEBUG_DECLARE_INSTANCE_COUNTER(CResultPane);
  233. CResultPane::CResultPane()
  234. {
  235. DEBUG_INCREMENT_INSTANCE_COUNTER(CResultPane);
  236. CResultPane::lDataObjectRefCount = 0;
  237. m_lViewMode = LVS_REPORT;
  238. m_nSortColumn = 0;
  239. m_dwSortOptions = 0;
  240. m_nIndex = 0;
  241. Construct();
  242. }
  243. CResultPane::~CResultPane()
  244. {
  245. #if DBG
  246. ASSERT(dbg_cRef == 0);
  247. #endif
  248. DEBUG_DECREMENT_INSTANCE_COUNTER(CResultPane);
  249. // Make sure the interfaces have been released
  250. ASSERT(m_pConsole == NULL);
  251. ASSERT(m_pHeader == NULL);
  252. Construct();
  253. ASSERT(CResultPane::lDataObjectRefCount == 0);
  254. }
  255. void CResultPane::Construct()
  256. {
  257. #if DBG
  258. dbg_cRef = 0;
  259. #endif
  260. m_pConsole = NULL;
  261. m_pHeader = NULL;
  262. m_pResult = NULL;
  263. m_pScopePane = NULL;
  264. m_hCurrScopeItem = -1;
  265. }
  266. void CResultPane::LoadResources()
  267. {
  268. // Load strings from resources
  269. int i, j;
  270. for (j = 0, i = IDS_FIRST_COL; i < IDS_LAST_COL; i++, j++)
  271. m_columns[j].LoadString(i);
  272. for (j = 0, i = IDS_FIRST_RSOP_COL; i < IDS_LAST_RSOP_COL; i++, j++)
  273. m_RSOP_columns[j].LoadString(i);
  274. m_szFolderTitle.LoadString(IDS_FOLDER_TITLE);
  275. }
  276. HRESULT CResultPane::InitializeHeaders(MMC_COOKIE cookie)
  277. {
  278. HRESULT hr = S_OK;
  279. int i;
  280. ASSERT(m_pHeader);
  281. // Put the correct headers depending on the cookie
  282. // Note - cookie ignored for this sample
  283. if (m_pScopePane->m_fRSOP && cookie != IDS_FOLDER_TITLE)
  284. {
  285. for (i = 0; i < RSOPCOLUMNID(IDS_LAST_RSOP_COL); i++)
  286. m_pHeader->InsertColumn(i, m_RSOP_columns[i], LVCFMT_LEFT, RSOPHeaderWidths[i]); //add the columns
  287. }
  288. else
  289. {
  290. for (i = 0; i < COLUMNID(IDS_LAST_COL); i++)
  291. m_pHeader->InsertColumn(i, m_columns[i], LVCFMT_LEFT, HeaderWidths[i]); //add the columns
  292. }
  293. return hr;
  294. }
  295. /////////////////////////////////////////////////////////////////////////////
  296. // IExtendContextMenu Implementation
  297. STDMETHODIMP CResultPane::AddMenuItems(LPDATAOBJECT pDataObject,
  298. LPCONTEXTMENUCALLBACK pContextMenuCallback, LONG * pInsertionAllowed)
  299. {
  300. //we do not have any special commands on the menu
  301. return S_OK;
  302. }
  303. STDMETHODIMP CResultPane::Command(long nCommandID, LPDATAOBJECT pDataObject)
  304. {
  305. //we do not have any special commands on the menu
  306. return S_OK;
  307. }
  308. HRESULT CResultPane::OnAddImages(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  309. {
  310. if (arg == 0)
  311. {
  312. return E_INVALIDARG;
  313. }
  314. // add the images for the scope tree
  315. CBitmap bmp16x16;
  316. CBitmap bmp32x32;
  317. LPIMAGELIST lpScopeImage = (LPIMAGELIST)arg;
  318. // Load the bitmaps from the dll
  319. bmp16x16.LoadBitmap(IDB_16x16);
  320. bmp32x32.LoadBitmap(IDB_32x32);
  321. // Set the images
  322. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
  323. reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp32x32)),
  324. 0, RGB(255,0,255));
  325. return S_OK;
  326. }
  327. /////////////////////////////////////////////////////////////////////////////
  328. // IExtendPropertySheet Implementation
  329. // Result item property pages:
  330. STDMETHODIMP CResultPane::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  331. LONG_PTR handle,
  332. LPDATAOBJECT lpIDataObject)
  333. {
  334. if (!m_pScopePane->m_fRSOP)
  335. return S_FALSE;
  336. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  337. HRESULT hr = S_FALSE;
  338. INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
  339. if (! pInternal)
  340. return S_FALSE;
  341. DWORD cookie = pInternal->m_cookie;
  342. LONG i;
  343. BOOL fShowPage = FALSE;
  344. AFX_OLDPROPSHEETPAGE * pPsp;
  345. CRSOPInfo * pRSOPInfo;
  346. //it is one of the folders
  347. pRSOPInfo = &(m_RSOPData[cookie]);
  348. if (!pRSOPInfo->m_pRsopProp) //make sure that the property page is not already up.
  349. {
  350. pRSOPInfo->m_pRsopProp = new CRsopProp;
  351. pRSOPInfo->m_pRsopProp->m_ppThis = &(pRSOPInfo->m_pRsopProp);
  352. pRSOPInfo->m_pRsopProp->m_pInfo = pRSOPInfo;
  353. pRSOPInfo->m_pRsopProp->m_szFolder = pRSOPInfo->m_pRsopProp->m_pInfo->m_szFolder;
  354. fShowPage = TRUE;
  355. pPsp = (AFX_OLDPROPSHEETPAGE *)&(pRSOPInfo->m_pRsopProp->m_psp);
  356. }
  357. if (fShowPage) //show page if it is not already up.
  358. {
  359. hr = SetPropPageToDeleteOnClose (pPsp);
  360. if (SUCCEEDED(hr))
  361. {
  362. HPROPSHEETPAGE hProp = CreateThemedPropertySheetPage(pPsp);
  363. if (NULL == hProp)
  364. hr = E_UNEXPECTED;
  365. else
  366. {
  367. lpProvider->AddPage(hProp);
  368. hr = S_OK;
  369. }
  370. }
  371. }
  372. FREE_INTERNAL(pInternal);
  373. return hr;
  374. }
  375. // Result items property pages:
  376. STDMETHODIMP CResultPane::QueryPagesFor(LPDATAOBJECT lpDataObject)
  377. {
  378. if (!m_pScopePane->m_fRSOP)
  379. return S_FALSE;
  380. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  381. if (! pInternal)
  382. return S_FALSE;
  383. MMC_COOKIE cookie = pInternal->m_cookie;
  384. HRESULT hr = S_FALSE;
  385. CError error;
  386. if (CCT_RESULT == pInternal->m_type)
  387. {
  388. hr = S_OK;
  389. }
  390. FREE_INTERNAL(pInternal);
  391. return hr;
  392. }
  393. STDMETHODIMP CResultPane::CompareObjects(LPDATAOBJECT lpDataObjectA,
  394. LPDATAOBJECT lpDataObjectB)
  395. {
  396. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  397. return E_POINTER;
  398. // Make sure both data object are mine
  399. INTERNAL* pA;
  400. INTERNAL* pB;
  401. HRESULT hr = S_FALSE;
  402. pA = ExtractInternalFormat(lpDataObjectA);
  403. pB = ExtractInternalFormat(lpDataObjectB);
  404. if (pA != NULL && pB != NULL)
  405. hr = ((pA->m_type == pB->m_type) && (pA->m_cookie == pB->m_cookie)) ? S_OK : S_FALSE;
  406. FREE_INTERNAL(pA);
  407. FREE_INTERNAL(pB);
  408. return hr;
  409. }
  410. STDMETHODIMP CResultPane::Compare(LPARAM lUserParam,
  411. MMC_COOKIE cookieA,
  412. MMC_COOKIE cookieB,
  413. int* pnResult)
  414. {
  415. if (pnResult == NULL)
  416. {
  417. ASSERT(FALSE);
  418. return E_POINTER;
  419. }
  420. // check col range
  421. int nCol = *pnResult;
  422. *pnResult = 0;
  423. // Retrieve the objects referred to by the two cookies and compare them
  424. // based upon the data that's associated with nCol. (The values you
  425. // compare depends on which column the caller asks for.)
  426. CString szA, szB;
  427. CRSOPInfo &dataA = m_RSOPData[cookieA];
  428. CRSOPInfo &dataB = m_RSOPData[cookieB];
  429. switch (nCol)
  430. {
  431. case 0: // precedence
  432. *pnResult = dataA.m_nPrecedence - dataB.m_nPrecedence;
  433. return S_OK;
  434. case 1: // redirected path
  435. szA = dataA.m_szPath;
  436. szB = dataB.m_szPath;
  437. break;
  438. case 2: // group
  439. szA = dataA.m_szGroup;
  440. szB = dataB.m_szGroup;
  441. break;
  442. case 3: // GPO
  443. szA = dataA.m_szGPO;
  444. szB = dataB.m_szGPO;
  445. break;
  446. case 4: // setting
  447. szA.LoadString(dataA.m_nInstallationType + IDS_SETTINGS);
  448. szB.LoadString(dataB.m_nInstallationType + IDS_SETTINGS);
  449. break;
  450. case 5: // exclusive
  451. szA.LoadString(dataA.m_fGrantType ? IDS_YES : IDS_NO);
  452. szB.LoadString(dataB.m_fGrantType ? IDS_YES : IDS_NO);
  453. break;
  454. case 6: // move
  455. szA.LoadString(dataA.m_fMoveType ? IDS_YES : IDS_NO);
  456. szB.LoadString(dataB.m_fMoveType ? IDS_YES : IDS_NO);
  457. break;
  458. case 7: // policy removal
  459. szA.LoadString(IDS_ONPOLICYREMOVAL + dataA.m_nPolicyRemoval);
  460. szB.LoadString(IDS_ONPOLICYREMOVAL + dataB.m_nPolicyRemoval);
  461. break;
  462. }
  463. *pnResult = szA.CompareNoCase(szB);
  464. return S_OK;
  465. }
  466. STDMETHODIMP CResultPane::GetDisplayInfo(LPRESULTDATAITEM pResult)
  467. {
  468. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  469. static CString sz;
  470. CString szExt;
  471. ASSERT(pResult != NULL);
  472. ASSERT(pResult->bScopeItem);
  473. if (pResult)
  474. {
  475. if (pResult->bScopeItem)
  476. {
  477. switch (pResult->nCol)
  478. {
  479. case 0: //display name
  480. if (IDS_FOLDER_TITLE == pResult->lParam)
  481. sz.LoadString (IDS_FOLDER_TITLE);
  482. else
  483. sz = m_pScopePane->m_FolderData[GETINDEX(pResult->lParam)].m_szDisplayname;
  484. break;
  485. case 1: //type
  486. sz = m_pScopePane->m_FolderData[GETINDEX(pResult->lParam)].m_szTypename;
  487. break;
  488. default:
  489. sz = TEXT("");
  490. break;
  491. }
  492. }
  493. else
  494. {
  495. CRSOPInfo &data = m_RSOPData[pResult->lParam];
  496. switch (pResult->nCol)
  497. {
  498. case 0: // precedence
  499. sz.Format(TEXT("(%u) %s"), data.m_nPrecedence, data.m_szFolder);
  500. break;
  501. case 1: // redirected path
  502. sz = data.m_szPath;
  503. break;
  504. case 2: // group
  505. sz = data.m_szGroup;
  506. break;
  507. case 3: // GPO
  508. sz = data.m_szGPO;
  509. break;
  510. case 4: // setting
  511. sz.LoadString(data.m_nInstallationType + IDS_SETTINGS);
  512. break;
  513. case 5: // exclusive
  514. sz.LoadString(data.m_fGrantType ? IDS_YES : IDS_NO);
  515. break;
  516. case 6: // move
  517. sz.LoadString(data.m_fMoveType ? IDS_YES : IDS_NO);
  518. break;
  519. case 7: // policy removal
  520. sz.LoadString(IDS_ONPOLICYREMOVAL + data.m_nPolicyRemoval);
  521. break;
  522. default:
  523. sz = TEXT("");
  524. break;
  525. }
  526. }
  527. pResult->str = (unsigned short *)((LPCOLESTR)sz);
  528. }
  529. return S_OK;
  530. }
  531. HRESULT CResultPane::OnFolder(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  532. {
  533. ASSERT(FALSE);
  534. return S_OK;
  535. }
  536. HRESULT CResultPane::TestForRSOPData(MMC_COOKIE cookie)
  537. {
  538. HRESULT hr = S_OK;
  539. ASSERT(m_pScopePane != NULL);
  540. // Test for RSOP data for this folder
  541. RESULTDATAITEM resultItem;
  542. memset(&resultItem, 0, sizeof(resultItem));
  543. resultItem.mask = RDI_STR | RDI_PARAM;
  544. resultItem.str = MMC_CALLBACK;
  545. IWbemLocator * pLocator = NULL;
  546. IWbemServices * pNamespace = NULL;
  547. IWbemClassObject * pObj = NULL;
  548. IEnumWbemClassObject * pEnum = NULL;
  549. BSTR strQueryLanguage = SysAllocString(TEXT("WQL"));
  550. CString szQuery = TEXT("SELECT * FROM RSOP_FolderRedirectionPolicySetting");
  551. if (cookie && (cookie != IDS_FOLDER_TITLE))
  552. {
  553. szQuery = TEXT("SELECT * FROM RSOP_FolderRedirectionPolicySetting where id = \"");
  554. szQuery += g_szEnglishNames[GETINDEX(cookie)];
  555. szQuery += TEXT("\"");
  556. }
  557. BSTR strQuery = SysAllocString(szQuery);
  558. BSTR strNamespace = SysAllocString(m_pScopePane->m_szRSOPNamespace);
  559. ULONG n = 0;
  560. hr = CoCreateInstance(CLSID_WbemLocator,
  561. 0,
  562. CLSCTX_INPROC_SERVER,
  563. IID_IWbemLocator,
  564. (LPVOID *) & pLocator);
  565. if (FAILED(hr))
  566. {
  567. goto cleanup;
  568. }
  569. hr = pLocator->ConnectServer(strNamespace,
  570. NULL,
  571. NULL,
  572. NULL,
  573. 0,
  574. NULL,
  575. NULL,
  576. &pNamespace);
  577. if (FAILED(hr))
  578. {
  579. goto cleanup;
  580. }
  581. hr = pNamespace->ExecQuery(strQueryLanguage,
  582. strQuery,
  583. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  584. NULL,
  585. &pEnum);
  586. if (FAILED(hr))
  587. {
  588. goto cleanup;
  589. }
  590. hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &n);
  591. if (FAILED(hr))
  592. {
  593. goto cleanup;
  594. }
  595. if (n == 0)
  596. {
  597. hr = E_FAIL;
  598. }
  599. cleanup:
  600. SysFreeString(strQueryLanguage);
  601. SysFreeString(strQuery);
  602. SysFreeString(strNamespace);
  603. if (pObj)
  604. {
  605. pObj->Release();
  606. }
  607. if (pEnum)
  608. {
  609. pEnum->Release();
  610. }
  611. if (pNamespace)
  612. {
  613. pNamespace->Release();
  614. }
  615. if (pLocator)
  616. {
  617. pLocator->Release();
  618. }
  619. m_pResult->Sort(m_nSortColumn, m_dwSortOptions, -1);
  620. return hr;
  621. }
  622. HRESULT CResultPane::OnShow(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  623. {
  624. HRESULT hr = S_OK;
  625. // Note - arg is TRUE when it is time to enumerate
  626. if (arg == TRUE)
  627. {
  628. // Show the headers for this nodetype
  629. ASSERT(m_pScopePane != NULL);
  630. m_pResult->SetViewMode(m_lViewMode);
  631. InitializeHeaders(cookie);
  632. m_hCurrScopeItem = m_pScopePane->m_FolderData[GETINDEX(cookie)].m_scopeID;
  633. if (m_pScopePane->m_fRSOP)
  634. {
  635. // Enumerate the RSOP data for this folder
  636. // and add a result item for each entry
  637. RESULTDATAITEM resultItem;
  638. memset(&resultItem, 0, sizeof(resultItem));
  639. resultItem.mask = RDI_STR | RDI_PARAM;
  640. resultItem.str = MMC_CALLBACK;
  641. HRESULT hr = S_OK;
  642. IWbemLocator * pLocator = NULL;
  643. IWbemServices * pNamespace = NULL;
  644. IWbemClassObject * pObj = NULL;
  645. IEnumWbemClassObject * pEnum = NULL;
  646. BSTR strQueryLanguage = SysAllocString(TEXT("WQL"));
  647. CString szQuery = TEXT("SELECT * FROM RSOP_FolderRedirectionPolicySetting where name = \"");
  648. szQuery += g_szEnglishNames[GETINDEX(cookie)];
  649. szQuery += TEXT("\"");
  650. BSTR strQuery = SysAllocString(szQuery);
  651. BSTR strNamespace = SysAllocString(m_pScopePane->m_szRSOPNamespace);
  652. ULONG n = 0;
  653. hr = CoCreateInstance(CLSID_WbemLocator,
  654. 0,
  655. CLSCTX_INPROC_SERVER,
  656. IID_IWbemLocator,
  657. (LPVOID *) & pLocator);
  658. if (FAILED(hr))
  659. {
  660. goto cleanup;
  661. }
  662. hr = pLocator->ConnectServer(strNamespace,
  663. NULL,
  664. NULL,
  665. NULL,
  666. 0,
  667. NULL,
  668. NULL,
  669. &pNamespace);
  670. if (FAILED(hr))
  671. {
  672. goto cleanup;
  673. }
  674. // First perform the query
  675. hr = pNamespace->ExecQuery(strQueryLanguage,
  676. strQuery,
  677. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  678. NULL,
  679. &pEnum);
  680. if (FAILED(hr))
  681. {
  682. goto cleanup;
  683. }
  684. do
  685. {
  686. hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &n);
  687. if (FAILED(hr))
  688. {
  689. goto cleanup;
  690. }
  691. if (n > 0)
  692. {
  693. // process the data
  694. UINT nPrecedence;
  695. LPTSTR pszGPOName = NULL;
  696. CString szGPOID;
  697. UINT nGroups = 0;
  698. TCHAR * * rgszGroups = NULL;
  699. UINT nPaths = 0;
  700. TCHAR * * rgszPaths = NULL;
  701. BOOL fGrantType;
  702. BOOL fMoveType;
  703. UINT nPolicyRemoval;
  704. UINT nInstallationType;
  705. CString ResultantPath;
  706. CString RedirectingGroup;
  707. hr = GetParameter(pObj,
  708. TEXT("GPOID"),
  709. szGPOID);
  710. hr = GetGPOFriendlyName(pNamespace,
  711. (LPTSTR)((LPCTSTR) szGPOID),
  712. strQueryLanguage,
  713. &pszGPOName);
  714. hr = GetParameter(pObj,
  715. TEXT("Precedence"),
  716. nPrecedence);
  717. hr = GetParameter(pObj,
  718. TEXT("GrantType"),
  719. fGrantType);
  720. hr = GetParameter(pObj,
  721. TEXT("MoveType"),
  722. fMoveType);
  723. hr = GetParameter(pObj,
  724. TEXT("PolicyRemoval"),
  725. nPolicyRemoval);
  726. hr = GetParameter(pObj,
  727. TEXT("securityGroups"),
  728. nGroups,
  729. rgszGroups);
  730. hr = GetParameter(pObj,
  731. TEXT("RedirectedPaths"),
  732. nPaths,
  733. rgszPaths);
  734. hr = GetParameter(pObj,
  735. TEXT("installationType"),
  736. nInstallationType);
  737. hr = GetParameter(pObj,
  738. TEXT("resultantPath"),
  739. ResultantPath);
  740. hr = GetParameter(pObj,
  741. TEXT("redirectingGroup"),
  742. RedirectingGroup);
  743. if (nInstallationType != 2)
  744. {
  745. // force a valid value
  746. nInstallationType = 1;
  747. }
  748. if (nPaths != nGroups)
  749. {
  750. // If we don't have the same number of paths
  751. // as groups then we have a problem.
  752. hr = E_UNEXPECTED;
  753. }
  754. CString szDir;
  755. CString szAcct;
  756. CRSOPInfo & info = m_RSOPData[m_nIndex++];
  757. info.m_nPrecedence = nPrecedence;
  758. info.m_szPath = ResultantPath;
  759. if (STATUS_SUCCESS == GetFriendlyNameFromStringSid(
  760. RedirectingGroup,
  761. szDir,
  762. szAcct))
  763. {
  764. if (!szDir.IsEmpty())
  765. szAcct = szDir + '\\' + szAcct;
  766. }
  767. else //just display the unfriendly string if the friendly name cannot be obtained
  768. {
  769. szAcct = RedirectingGroup;
  770. szAcct.MakeUpper();
  771. }
  772. info.m_szGroup = szAcct;
  773. info.m_szGPO = pszGPOName;
  774. info.m_fGrantType = FALSE != fGrantType;
  775. info.m_fMoveType = FALSE != fMoveType;
  776. info.m_nPolicyRemoval = nPolicyRemoval;
  777. info.m_nInstallationType = nInstallationType;
  778. info.m_szFolder = m_pScopePane->m_FolderData[GETINDEX(cookie)].m_szDisplayname;
  779. resultItem.lParam = m_nIndex - 1;;
  780. m_pResult->InsertItem(&resultItem);
  781. // erase allocated data
  782. OLESAFE_DELETE(pszGPOName);
  783. while (nPaths--)
  784. {
  785. OLESAFE_DELETE(rgszPaths[nPaths]);
  786. }
  787. OLESAFE_DELETE(rgszPaths);
  788. while (nGroups--)
  789. {
  790. OLESAFE_DELETE(rgszGroups[nGroups]);
  791. }
  792. OLESAFE_DELETE(rgszGroups);
  793. }
  794. } while (n > 0);
  795. cleanup:
  796. SysFreeString(strQueryLanguage);
  797. SysFreeString(strQuery);
  798. SysFreeString(strNamespace);
  799. if (pObj)
  800. {
  801. pObj->Release();
  802. }
  803. if (pEnum)
  804. {
  805. pEnum->Release();
  806. }
  807. if (pNamespace)
  808. {
  809. pNamespace->Release();
  810. }
  811. if (pLocator)
  812. {
  813. pLocator->Release();
  814. }
  815. m_pResult->Sort(m_nSortColumn, m_dwSortOptions, -1);
  816. }
  817. }
  818. else
  819. {
  820. m_pResult->GetViewMode(&m_lViewMode);
  821. }
  822. return hr;
  823. }
  824. HRESULT CResultPane::OnActivate(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  825. {
  826. return S_OK;
  827. }
  828. HRESULT CResultPane::OnResultItemClkOrDblClk(MMC_COOKIE cookie, BOOL fDblClick)
  829. {
  830. return S_FALSE;
  831. }
  832. HRESULT CResultPane::OnMinimize(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  833. {
  834. return S_OK;
  835. }
  836. HRESULT CResultPane::OnSelect(DATA_OBJECT_TYPES type, MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  837. {
  838. if (m_pConsoleVerb)
  839. {
  840. if (m_pScopePane->m_fRSOP)
  841. {
  842. if (type == CCT_RESULT)
  843. {
  844. // Set the default verb to properties
  845. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  846. // Enable the properties verb.
  847. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, FALSE);
  848. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
  849. }
  850. else
  851. {
  852. // Set the default verb to open
  853. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  854. // disable the properties verb
  855. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, TRUE);
  856. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, FALSE);
  857. }
  858. }
  859. else
  860. {
  861. if (type == CCT_SCOPE)
  862. {
  863. // Set the default verb to open
  864. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  865. if (IDS_FOLDER_TITLE != cookie)
  866. {
  867. m_pConsoleVerb->SetVerbState (MMC_VERB_PROPERTIES, HIDDEN, FALSE);
  868. m_pConsoleVerb->SetVerbState (MMC_VERB_PROPERTIES, ENABLED, TRUE);
  869. }
  870. else
  871. {
  872. m_pConsoleVerb->SetVerbState (MMC_VERB_PROPERTIES, HIDDEN, TRUE);
  873. m_pConsoleVerb->SetVerbState (MMC_VERB_PROPERTIES, ENABLED, FALSE);
  874. }
  875. }
  876. }
  877. }
  878. return S_OK;
  879. }
  880. HRESULT CResultPane::OnPropertyChange(LPARAM param) // param is the cookie of the item that changed
  881. {
  882. HRESULT hr = S_OK;
  883. // UNDONE - Make any updates to internal structures or visual
  884. // representation that might be necessary.
  885. m_pResult->Sort(m_nSortColumn, m_dwSortOptions, -1);
  886. return hr;
  887. }
  888. HRESULT CResultPane::OnUpdateView(LPDATAOBJECT lpDataObject)
  889. {
  890. if (m_pScopePane->m_fRSOP)
  891. {
  892. return S_OK;
  893. }
  894. INTERNAL* pInternal = ExtractInternalFormat (lpDataObject);
  895. if (!pInternal)
  896. return E_UNEXPECTED;
  897. if (m_hCurrScopeItem == pInternal->m_scopeID)
  898. {
  899. //also update the folders
  900. m_pScopePane->m_pScope->DeleteItem (pInternal->m_scopeID, FALSE);
  901. m_pScopePane->EnumerateScopePane (pInternal->m_cookie, pInternal->m_scopeID);
  902. //reenumerate the scope pane
  903. m_pConsole->SelectScopeItem (pInternal->m_scopeID);
  904. }
  905. FREE_INTERNAL (pInternal);
  906. return S_OK;
  907. }
  908. HRESULT CResultPane::OnContextHelp(void)
  909. {
  910. LPOLESTR lpHelpTopic;
  911. LPCTSTR pszHelpTopic = L"gpedit.chm::/Folder.htm";
  912. ASSERT (m_pDisplayHelp);
  913. lpHelpTopic = (LPOLESTR) CoTaskMemAlloc ((wcslen(pszHelpTopic) + 1) * sizeof(WCHAR));
  914. if (!lpHelpTopic)
  915. {
  916. DbgMsg((TEXT("CScopePane::OnContexHelp: Failed to allocate memory.")));
  917. return E_OUTOFMEMORY;
  918. }
  919. wcscpy (lpHelpTopic, pszHelpTopic);
  920. return m_pScopePane->m_pDisplayHelp->ShowTopic (lpHelpTopic);
  921. }
  922. // This code is needed to ensure that property pages get cleaned up properly.
  923. // This ensures that when the property sheet is closed all my of property
  924. // pages that are associated with that property sheet will get deleted.
  925. LPFNPSPCALLBACK _MMCHookProp;
  926. UINT CALLBACK HookPropertySheetProp(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  927. {
  928. UINT i = _MMCHookProp(hwnd, uMsg, ppsp);
  929. switch (uMsg)
  930. {
  931. case PSPCB_RELEASE:
  932. delete (CPropertyPage *) ppsp->lParam;
  933. return TRUE;
  934. default:
  935. break;
  936. }
  937. return i;
  938. }
  939. LRESULT SetPropPageToDeleteOnClose(void * vpsp)
  940. {
  941. HRESULT hr = MMCPropPageCallback(vpsp);
  942. if (SUCCEEDED(hr))
  943. {
  944. if (vpsp == NULL)
  945. return E_POINTER;
  946. LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE)vpsp;
  947. if ((void*)psp->pfnCallback == (void*)HookPropertySheetProp)
  948. return E_UNEXPECTED;
  949. _MMCHookProp = psp->pfnCallback;
  950. psp->pfnCallback = HookPropertySheetProp;
  951. }
  952. return hr;
  953. }