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.

954 lines
28 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: scope.cpp
  7. //
  8. // Contents: implementation of the scope pane
  9. //
  10. // Classes: CScopePane
  11. //
  12. // History: 03-14-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 <winnetwk.h>
  19. // Comment this line to stop trying to set the main snapin icon in the
  20. // scope pane.
  21. #define SET_SCOPE_ICONS 1
  22. // Un-comment the next line to persist snap-in related data. (This really
  23. // shouldn't be necessary since I get all my info from my parent anyway.)
  24. // #define PERSIST_DATA 1
  25. ///////////////////////////////////////////////////////////////////////////////
  26. // IComponentData implementation
  27. DEBUG_DECLARE_INSTANCE_COUNTER(CScopePane);
  28. CScopePane::CScopePane()
  29. {
  30. HKEY hKey;
  31. DWORD dwDisp;
  32. DEBUG_INCREMENT_INSTANCE_COUNTER(CScopePane);
  33. m_bIsDirty = FALSE;
  34. m_fRSOP = FALSE;
  35. m_pScope = NULL;
  36. m_pConsole = NULL;
  37. m_pIPropertySheetProvider = NULL;
  38. m_fLoaded = FALSE;
  39. m_fExtension = FALSE;
  40. m_pIGPEInformation = NULL;
  41. m_pIRSOPInformation = NULL;
  42. }
  43. CScopePane::~CScopePane()
  44. {
  45. DEBUG_DECREMENT_INSTANCE_COUNTER(CScopePane);
  46. ASSERT(m_pScope == NULL);
  47. ASSERT(CResultPane::lDataObjectRefCount == 0);
  48. }
  49. #include <msi.h>
  50. //+--------------------------------------------------------------------------
  51. //
  52. // Member: CScopePane::CreateNestedDirectory
  53. //
  54. // Synopsis: Ensures the existance of a path. If any directory along the
  55. // path doesn't exist, this routine will create it.
  56. //
  57. // Arguments: [lpDirectory] - path to the leaf directory
  58. // [lpSecurityAttributes] - security attributes
  59. //
  60. // Returns: 1 on success
  61. // 0 on failure
  62. //
  63. // History: 3-17-1998 stevebl Copied from ADE
  64. //
  65. // Notes: Originally written by EricFlo
  66. //
  67. //---------------------------------------------------------------------------
  68. UINT CScopePane::CreateNestedDirectory (LPTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  69. {
  70. TCHAR szDirectory[MAX_PATH];
  71. LPTSTR lpEnd;
  72. //
  73. // Check for NULL pointer
  74. //
  75. if (!lpDirectory || !(*lpDirectory)) {
  76. SetLastError(ERROR_INVALID_DATA);
  77. return 0;
  78. }
  79. //
  80. // First, see if we can create the directory without having
  81. // to build parent directories.
  82. //
  83. if (CreateDirectory (lpDirectory, lpSecurityAttributes)) {
  84. return 1;
  85. }
  86. //
  87. // If this directory exists already, this is OK too.
  88. //
  89. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  90. return ERROR_ALREADY_EXISTS;
  91. }
  92. //
  93. // No luck, copy the string to a buffer we can munge
  94. //
  95. HRESULT hr;
  96. hr = StringCchCopy(szDirectory, sizeof(szDirectory)/sizeof(szDirectory[0]), lpDirectory);
  97. if (FAILED(hr))
  98. {
  99. SetLastError(HRESULT_CODE(hr));
  100. return 0;
  101. }
  102. //
  103. // Find the first subdirectory name
  104. //
  105. lpEnd = szDirectory;
  106. if (szDirectory[1] == TEXT(':')) {
  107. lpEnd += 3;
  108. } else if (szDirectory[1] == TEXT('\\')) {
  109. //
  110. // Skip the first two slashes
  111. //
  112. lpEnd += 2;
  113. //
  114. // Find the slash between the server name and
  115. // the share name.
  116. //
  117. while (*lpEnd && *lpEnd != TEXT('\\')) {
  118. lpEnd++;
  119. }
  120. if (!(*lpEnd)) {
  121. return 0;
  122. }
  123. //
  124. // Skip the slash, and find the slash between
  125. // the share name and the directory name.
  126. //
  127. lpEnd++;
  128. while (*lpEnd && *lpEnd != TEXT('\\')) {
  129. lpEnd++;
  130. }
  131. if (!(*lpEnd)) {
  132. return 0;
  133. }
  134. //
  135. // Leave pointer at the beginning of the directory.
  136. //
  137. lpEnd++;
  138. } else if (szDirectory[0] == TEXT('\\')) {
  139. lpEnd++;
  140. }
  141. while (*lpEnd) {
  142. while (*lpEnd && *lpEnd != TEXT('\\')) {
  143. lpEnd++;
  144. }
  145. if (*lpEnd == TEXT('\\')) {
  146. *lpEnd = TEXT('\0');
  147. if (!CreateDirectory (szDirectory, NULL)) {
  148. if (GetLastError() != ERROR_ALREADY_EXISTS) {
  149. return 0;
  150. }
  151. }
  152. *lpEnd = TEXT('\\');
  153. lpEnd++;
  154. }
  155. }
  156. //
  157. // Create the final directory
  158. //
  159. if (CreateDirectory (szDirectory, lpSecurityAttributes)) {
  160. return 1;
  161. }
  162. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  163. return ERROR_ALREADY_EXISTS;
  164. }
  165. //
  166. // Failed
  167. //
  168. return 0;
  169. }
  170. STDMETHODIMP CScopePane::Initialize(LPUNKNOWN pUnknown)
  171. {
  172. ASSERT(pUnknown != NULL);
  173. HRESULT hr;
  174. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  175. // MMC should only call ::Initialize once!
  176. ASSERT(m_pScope == NULL);
  177. pUnknown->QueryInterface(IID_IConsoleNameSpace,
  178. reinterpret_cast<void**>(&m_pScope));
  179. ASSERT(hr == S_OK);
  180. hr = pUnknown->QueryInterface(IID_IPropertySheetProvider,
  181. (void **)&m_pIPropertySheetProvider);
  182. hr = pUnknown->QueryInterface(IID_IConsole, reinterpret_cast<void**>(&m_pConsole));
  183. ASSERT(hr == S_OK);
  184. hr = m_pConsole->QueryInterface (IID_IDisplayHelp, reinterpret_cast<void**>(&m_pDisplayHelp));
  185. ASSERT(hr == S_OK);
  186. #ifdef SET_SCOPE_ICONS
  187. LPIMAGELIST lpScopeImage;
  188. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  189. ASSERT(hr == S_OK);
  190. // Load the bitmaps from the dll
  191. CBitmap bmp16x16;
  192. CBitmap bmp32x32;
  193. bmp16x16.LoadBitmap(IDB_16x16);
  194. bmp32x32.LoadBitmap(IDB_32x32);
  195. // Set the images
  196. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
  197. reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp32x32)),
  198. 0, RGB(255,0,255));
  199. lpScopeImage->Release();
  200. #endif
  201. return S_OK;
  202. }
  203. STDMETHODIMP CScopePane::CreateComponent(LPCOMPONENT* ppComponent)
  204. {
  205. ASSERT(ppComponent != NULL);
  206. CComObject<CResultPane>* pObject;
  207. HRESULT hr = CComObject<CResultPane>::CreateInstance(&pObject);
  208. if ( FAILED(hr) )
  209. {
  210. return hr;
  211. }
  212. ASSERT(pObject != NULL);
  213. m_pResultPane = pObject;
  214. // Store IComponentData
  215. pObject->SetIComponentData(this);
  216. return pObject->QueryInterface(IID_IComponent,
  217. reinterpret_cast<void**>(ppComponent));
  218. }
  219. STDMETHODIMP CScopePane::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  220. {
  221. ASSERT(m_pScope != NULL);
  222. HRESULT hr = S_OK;
  223. UINT i;
  224. // Since it's my folder it has an internal format.
  225. // Design Note: for extension. I can use the fact, that the data object doesn't have
  226. // my internal format and I should look at the node type and see how to extend it.
  227. if (event == MMCN_PROPERTY_CHANGE)
  228. {
  229. // perform any action needed as a result of result property changes
  230. hr = OnProperties(param);
  231. }
  232. else if ( event == MMCN_REMOVE_CHILDREN )
  233. {
  234. //
  235. // In RSoP, we may get called to refresh the scope pane when the query
  236. // is re-executed -- if this happens, current nodes will be removed and
  237. // we must reset all of our cached information. We reset the relevant
  238. // information below
  239. //
  240. if ( ((HSCOPEITEM)arg != NULL) && m_fRSOP && (m_pIRSOPInformation != NULL) )
  241. {
  242. m_pIRSOPInformation->Release();
  243. m_pIRSOPInformation = NULL;
  244. }
  245. }
  246. else
  247. {
  248. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  249. MMC_COOKIE cookie = 0;
  250. if (pInternal != NULL)
  251. {
  252. cookie = pInternal->m_cookie;
  253. FREE_INTERNAL(pInternal);
  254. }
  255. else
  256. {
  257. // only way we could not be able to extract our own format is if we're operating as an extension
  258. m_fExtension = TRUE;
  259. }
  260. if (m_fRSOP)
  261. {
  262. WCHAR szBuffer[MAX_DS_PATH];
  263. if (m_pIRSOPInformation == NULL)
  264. {
  265. IRSOPInformation * pIRSOPInformation;
  266. hr = lpDataObject->QueryInterface(IID_IRSOPInformation,
  267. reinterpret_cast<void**>(&pIRSOPInformation));
  268. if (SUCCEEDED(hr))
  269. {
  270. m_pIRSOPInformation = pIRSOPInformation;
  271. m_pIRSOPInformation->AddRef();
  272. /* extract the namespace here */
  273. hr = m_pIRSOPInformation->GetNamespace(GPO_SECTION_USER, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
  274. if (SUCCEEDED(hr))
  275. {
  276. m_szRSOPNamespace = szBuffer;
  277. }
  278. pIRSOPInformation->Release();
  279. }
  280. }
  281. }
  282. else
  283. {
  284. if (m_pIGPEInformation == NULL)
  285. {
  286. IGPEInformation * pIGPEInformation;
  287. hr = lpDataObject->QueryInterface(IID_IGPEInformation,
  288. reinterpret_cast<void**>(&pIGPEInformation));
  289. if (SUCCEEDED(hr))
  290. {
  291. GROUP_POLICY_OBJECT_TYPE gpoType;
  292. hr = pIGPEInformation->GetType(&gpoType);
  293. if (SUCCEEDED(hr))
  294. {
  295. if (gpoType == GPOTypeDS)
  296. {
  297. WCHAR szBuffer[MAX_PATH];
  298. do
  299. {
  300. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  301. hr = pIGPEInformation->GetFileSysPath(GPO_SECTION_USER, szBuffer, MAX_PATH);
  302. if (FAILED(hr))
  303. break;
  304. m_pIGPEInformation = pIGPEInformation;
  305. m_pIGPEInformation->AddRef();
  306. m_szFileRoot = szBuffer;
  307. m_szFileRoot += L"\\Documents & Settings";
  308. CreateNestedDirectory (((LPOLESTR)(LPCOLESTR)(m_szFileRoot)), NULL);
  309. //initialize the folder data.
  310. for (i = IDS_DIRS_START; i < IDS_DIRS_END; i++)
  311. {
  312. m_FolderData[GETINDEX(i)].Initialize (i,
  313. (LPCTSTR) m_szFileRoot);
  314. }
  315. ConvertOldStyleSection (m_szFileRoot);
  316. } while (0);
  317. }
  318. else
  319. {
  320. // force this to fail
  321. hr = E_FAIL;
  322. }
  323. }
  324. pIGPEInformation->Release();
  325. }
  326. }
  327. }
  328. if (SUCCEEDED(hr))
  329. {
  330. switch(event)
  331. {
  332. case MMCN_EXPAND:
  333. {
  334. hr = OnExpand(cookie, arg, param);
  335. }
  336. break;
  337. case MMCN_SELECT:
  338. hr = OnSelect(cookie, arg, param);
  339. break;
  340. case MMCN_CONTEXTMENU:
  341. hr = OnContextMenu(cookie, arg, param);
  342. break;
  343. default:
  344. //perform the default action
  345. hr = S_FALSE;
  346. break;
  347. }
  348. }
  349. }
  350. return hr;
  351. }
  352. STDMETHODIMP CScopePane::Destroy()
  353. {
  354. SAFE_RELEASE(m_pScope);
  355. SAFE_RELEASE(m_pDisplayHelp);
  356. SAFE_RELEASE(m_pConsole);
  357. SAFE_RELEASE(m_pIPropertySheetProvider);
  358. SAFE_RELEASE(m_pIGPEInformation);
  359. SAFE_RELEASE(m_pIRSOPInformation);
  360. return S_OK;
  361. }
  362. STDMETHODIMP CScopePane::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  363. {
  364. ASSERT(ppDataObject != NULL);
  365. CComObject<CDataObject>* pObject = NULL;
  366. CComObject<CDataObject>::CreateInstance(&pObject);
  367. ASSERT(pObject != NULL);
  368. if (!pObject)
  369. return E_UNEXPECTED;
  370. // Save cookie and type for delayed rendering
  371. pObject->SetID (m_FolderData[GETINDEX(cookie)].m_scopeID);
  372. pObject->SetType(type);
  373. pObject->SetCookie(cookie);
  374. return pObject->QueryInterface(IID_IDataObject,
  375. reinterpret_cast<void**>(ppDataObject));
  376. }
  377. ///////////////////////////////////////////////////////////////////////////////
  378. //// IPersistStreamInit interface members
  379. STDMETHODIMP CScopePane::GetClassID(CLSID *pClassID)
  380. {
  381. ASSERT(pClassID != NULL);
  382. // Copy the CLSID for this snapin
  383. *pClassID = CLSID_Snapin;
  384. return S_OK;
  385. }
  386. STDMETHODIMP CScopePane::IsDirty()
  387. {
  388. return ThisIsDirty() ? S_OK : S_FALSE;
  389. }
  390. STDMETHODIMP CScopePane::Load(IStream *pStm)
  391. {
  392. #ifdef PERSIST_DATA
  393. ASSERT(pStm);
  394. // UNDONE - Read data from the stream here.
  395. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  396. #else
  397. return S_OK;
  398. #endif
  399. }
  400. STDMETHODIMP CScopePane::Save(IStream *pStm, BOOL fClearDirty)
  401. {
  402. #ifdef PERSIST_DATA
  403. ASSERT(pStm);
  404. // UNDONE - Write data to the stream here.
  405. // on error, return STG_E_CANTSAVE;
  406. #endif
  407. if (fClearDirty)
  408. ClearDirty();
  409. return S_OK;
  410. }
  411. STDMETHODIMP CScopePane::GetSizeMax(ULARGE_INTEGER *pcbSize)
  412. {
  413. ASSERT(pcbSize);
  414. // UNDONE - set the size of the string to be saved
  415. ULONG cb = 0;
  416. // Set the size of the string to be saved
  417. ULISet32(*pcbSize, cb);
  418. return S_OK;
  419. }
  420. STDMETHODIMP CScopePane::InitNew(void)
  421. {
  422. return S_OK;
  423. }
  424. ///////////////////////////////////////////////////////////////////////////////
  425. //// Notify handlers for IComponentData
  426. HRESULT CScopePane::OnAdd(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  427. {
  428. return E_UNEXPECTED;
  429. }
  430. HRESULT CScopePane::OnExpand(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  431. {
  432. if (arg == TRUE) //MMC never sends arg = FALSE (for collapse)
  433. {
  434. // Did Initialize get called?
  435. ASSERT(m_pScope != NULL);
  436. EnumerateScopePane(cookie,
  437. param);
  438. }
  439. return S_OK;
  440. }
  441. HRESULT CScopePane::OnSelect(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  442. {
  443. return E_UNEXPECTED;
  444. }
  445. HRESULT CScopePane::OnContextMenu(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  446. {
  447. return S_OK;
  448. }
  449. HRESULT CScopePane::OnProperties(LPARAM param)
  450. {
  451. if (param == NULL)
  452. {
  453. return S_OK;
  454. }
  455. ASSERT(param != NULL);
  456. return S_OK;
  457. }
  458. void CScopePane::EnumerateScopePane(MMC_COOKIE cookie, HSCOPEITEM pParent)
  459. {
  460. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  461. CString szFullPathname;
  462. CString szParent;
  463. SCOPEDATAITEM scopeItem;
  464. FILETIME ftCurr;
  465. LONG i;
  466. int cChildren = 0;
  467. DWORD myDocsFlags = REDIR_DONT_CARE;
  468. DWORD myPicsFlags = REDIR_DONT_CARE;
  469. memset(&scopeItem, 0, sizeof(SCOPEDATAITEM));
  470. CHourglass hourglass; //this may take some time, so put up an hourglass
  471. GetSystemTimeAsFileTime (&ftCurr);
  472. //set the common members for the scope pane items
  473. scopeItem.mask = SDI_STR | SDI_PARAM | SDI_CHILDREN;
  474. #ifdef SET_SCOPE_ICONS
  475. scopeItem.mask |= SDI_IMAGE | SDI_OPENIMAGE;
  476. scopeItem.nImage = IMG_CLOSEDBOX;
  477. scopeItem.nOpenImage = IMG_OPENBOX;
  478. #endif
  479. scopeItem.relativeID = pParent;
  480. scopeItem.displayname = MMC_CALLBACK;
  481. if (m_fExtension)
  482. {
  483. switch(cookie)
  484. {
  485. case NULL: //getting the folder
  486. // if we're an extension then add a root folder to hang everything off of
  487. if (m_fRSOP)
  488. {
  489. // make sure that nodes don't get enumerated if they contain no data
  490. if (FAILED(m_pResultPane->TestForRSOPData(cookie)))
  491. {
  492. if (m_pIRSOPInformation)
  493. {
  494. m_pIRSOPInformation->Release();
  495. m_pIRSOPInformation = NULL;
  496. }
  497. return;
  498. }
  499. }
  500. scopeItem.lParam = IDS_FOLDER_TITLE; //use resource id's as cookies
  501. scopeItem.cChildren = 1;
  502. m_pScope->InsertItem(&scopeItem);
  503. break;
  504. case IDS_FOLDER_TITLE:
  505. for (i = IDS_LEVEL1_DIRS_START; i < IDS_LEVEL1_DIRS_END; i++)
  506. {
  507. BOOL fInsert = TRUE;
  508. if (m_fRSOP)
  509. {
  510. if (FAILED(m_pResultPane->TestForRSOPData(i)))
  511. {
  512. fInsert = FALSE;
  513. }
  514. }
  515. if (fInsert)
  516. {
  517. scopeItem.lParam = i;
  518. m_FolderData[GETINDEX(i)].Initialize(i,
  519. (LPCTSTR) m_szFileRoot
  520. );
  521. if (i == IDS_MYDOCS && !m_fRSOP)
  522. {
  523. //
  524. // Show the My Pictures folder only if it does not follow MyDocs.
  525. // and only if there is no registry setting overriding the hiding behavior
  526. // for My Pics
  527. //
  528. if (AlwaysShowMyPicsNode())
  529. {
  530. cChildren = 1;
  531. m_FolderData[GETINDEX(i)].m_bHideChildren = FALSE;
  532. }
  533. else
  534. {
  535. m_FolderData[GETINDEX(IDS_MYPICS)].Initialize(IDS_MYPICS,
  536. (LPCTSTR) m_szFileRoot
  537. );
  538. m_FolderData[GETINDEX(i)].LoadSection();
  539. m_FolderData[GETINDEX(IDS_MYPICS)].LoadSection();
  540. myDocsFlags = m_FolderData[GETINDEX(i)].m_dwFlags;
  541. myPicsFlags = m_FolderData[GETINDEX(IDS_MYPICS)].m_dwFlags;
  542. if (((REDIR_DONT_CARE & myDocsFlags) && (REDIR_DONT_CARE & myPicsFlags)) ||
  543. ((REDIR_FOLLOW_PARENT & myPicsFlags) && (!(REDIR_DONT_CARE & myDocsFlags)))
  544. )
  545. {
  546. cChildren = 0;
  547. m_FolderData[GETINDEX(i)].m_bHideChildren = TRUE;
  548. }
  549. else
  550. {
  551. cChildren = 1;
  552. m_FolderData[GETINDEX(i)].m_bHideChildren = FALSE;
  553. }
  554. }
  555. }
  556. scopeItem.cChildren = cChildren; //only My Docs will possibly have children
  557. m_pScope->InsertItem(&scopeItem);
  558. m_FolderData[GETINDEX(i)].SetScopeItemID(scopeItem.ID);
  559. }
  560. if (IDS_MYDOCS == i && m_fRSOP && SUCCEEDED(m_pResultPane->TestForRSOPData(IDS_MYPICS)))
  561. {
  562. // In RSOP mode we put My Pictures after My Documents
  563. // instead of under it. Otherwise the results pane
  564. // for My Documents would contain a folder along with
  565. // the data and it would look very odd.
  566. scopeItem.lParam = IDS_MYPICS;
  567. scopeItem.cChildren = 0;
  568. m_pScope->InsertItem(&scopeItem);
  569. m_FolderData[GETINDEX(IDS_MYPICS)].Initialize (IDS_MYPICS,
  570. (LPCTSTR) m_szFileRoot
  571. );
  572. m_FolderData[GETINDEX(IDS_MYPICS)].SetScopeItemID(scopeItem.ID);
  573. }
  574. }
  575. break;
  576. case IDS_MYDOCS: //of all levels 1 folder, only MyDocs has children
  577. if (!m_fRSOP && !(m_FolderData[GETINDEX(IDS_MYDOCS)].m_bHideChildren))
  578. {
  579. scopeItem.lParam = IDS_MYPICS;
  580. scopeItem.cChildren = 0;
  581. m_pScope->InsertItem(&scopeItem);
  582. m_FolderData[GETINDEX(IDS_MYPICS)].Initialize (IDS_MYPICS,
  583. (LPCTSTR) m_szFileRoot
  584. );
  585. m_FolderData[GETINDEX(IDS_MYPICS)].SetScopeItemID(scopeItem.ID);
  586. }
  587. break;
  588. }
  589. }
  590. }
  591. STDMETHODIMP CScopePane::GetSnapinDescription(LPOLESTR * lpDescription)
  592. {
  593. // UNDONE
  594. OLESAFE_COPYSTRING(*lpDescription, L"description");
  595. return S_OK;
  596. }
  597. STDMETHODIMP CScopePane::GetProvider(LPOLESTR * lpName)
  598. {
  599. // UNDONE
  600. OLESAFE_COPYSTRING(*lpName, L"provider");
  601. return S_OK;
  602. }
  603. STDMETHODIMP CScopePane::GetSnapinVersion(LPOLESTR * lpVersion)
  604. {
  605. // UNDONE
  606. OLESAFE_COPYSTRING(*lpVersion, L"version");
  607. return S_OK;
  608. }
  609. STDMETHODIMP CScopePane::GetSnapinImage(HICON * hAppIcon)
  610. {
  611. // UNDONE
  612. return E_NOTIMPL;
  613. }
  614. STDMETHODIMP CScopePane::GetStaticFolderImage(HBITMAP * hSmallImage,
  615. HBITMAP * hSmallImageOpen,
  616. HBITMAP * hLargeImage,
  617. COLORREF * cMask)
  618. {
  619. // UNDONE
  620. return E_NOTIMPL;
  621. }
  622. STDMETHODIMP CScopePane::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  623. {
  624. LPOLESTR lpHelpFile;
  625. lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
  626. if (!lpHelpFile)
  627. {
  628. DbgMsg((TEXT("CScopePane::GetHelpTopic: Failed to allocate memory.")));
  629. return E_OUTOFMEMORY;
  630. }
  631. ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gpedit.chm",
  632. lpHelpFile, MAX_PATH);
  633. *lpCompiledHelpFile = lpHelpFile;
  634. return S_OK;
  635. }
  636. STDMETHODIMP CScopePane::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
  637. {
  638. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  639. LONG i;
  640. ASSERT(pScopeDataItem != NULL);
  641. if (pScopeDataItem == NULL)
  642. return E_POINTER;
  643. if (IDS_FOLDER_TITLE == pScopeDataItem->lParam)
  644. {
  645. m_szFolderTitle.LoadString(IDS_FOLDER_TITLE);
  646. pScopeDataItem->displayname = (unsigned short *)((LPCOLESTR)m_szFolderTitle);
  647. }
  648. else
  649. {
  650. pScopeDataItem->displayname = L"???";
  651. if (-1 != (i = GETINDEX(pScopeDataItem->lParam)))
  652. pScopeDataItem->displayname = (unsigned short*)((LPCOLESTR)(m_FolderData[i].m_szDisplayname));
  653. }
  654. ASSERT(pScopeDataItem->displayname != NULL);
  655. return S_OK;
  656. }
  657. STDMETHODIMP CScopePane::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  658. {
  659. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  660. return E_POINTER;
  661. // Make sure both data object are mine
  662. INTERNAL* pA;
  663. INTERNAL* pB;
  664. HRESULT hr = S_FALSE;
  665. pA = ExtractInternalFormat(lpDataObjectA);
  666. pB = ExtractInternalFormat(lpDataObjectB);
  667. if (pA != NULL && pB != NULL)
  668. hr = ((pA->m_type == pB->m_type) && (pA->m_cookie == pB->m_cookie)) ? S_OK : S_FALSE;
  669. FREE_INTERNAL(pA);
  670. FREE_INTERNAL(pB);
  671. return hr;
  672. }
  673. // Scope item property pages:
  674. STDMETHODIMP CScopePane::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  675. LONG_PTR handle,
  676. LPDATAOBJECT lpIDataObject)
  677. {
  678. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  679. HRESULT hr = S_FALSE;
  680. INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
  681. if (! pInternal)
  682. return S_FALSE;
  683. DWORD cookie = pInternal->m_cookie;
  684. LONG i;
  685. BOOL fShowPage = FALSE;
  686. AFX_OLDPROPSHEETPAGE * pPsp;
  687. AFX_OLDPROPSHEETPAGE * pPspSettings;
  688. CFileInfo* pFileInfo;
  689. //it is one of the folders
  690. i = GETINDEX (cookie);
  691. pFileInfo = &(m_FolderData[i]);
  692. if (!pFileInfo->m_pRedirPage) //make sure that the property page is not already up.
  693. {
  694. pFileInfo->m_pRedirPage = new CRedirect(cookie);
  695. pFileInfo->m_pRedirPage->m_ppThis = &(pFileInfo->m_pRedirPage);
  696. pFileInfo->m_pRedirPage->m_pScope = this;
  697. pFileInfo->m_pRedirPage->m_pFileInfo = pFileInfo;
  698. fShowPage = TRUE;
  699. pPsp = (AFX_OLDPROPSHEETPAGE *)&(pFileInfo->m_pRedirPage->m_psp);
  700. //create the settings page;
  701. pFileInfo->m_pSettingsPage = new CRedirPref();
  702. pFileInfo->m_pSettingsPage->m_ppThis = &(pFileInfo->m_pSettingsPage);
  703. pFileInfo->m_pSettingsPage->m_pFileInfo = pFileInfo;
  704. pPspSettings = (AFX_OLDPROPSHEETPAGE *)&(pFileInfo->m_pSettingsPage->m_psp);
  705. }
  706. if (fShowPage) //show page if it is not already up.
  707. {
  708. hr = SetPropPageToDeleteOnClose (pPsp);
  709. if (SUCCEEDED (hr))
  710. hr = SetPropPageToDeleteOnClose (pPspSettings);
  711. if (SUCCEEDED(hr))
  712. {
  713. HPROPSHEETPAGE hProp = CreateThemedPropertySheetPage(pPsp);
  714. HPROPSHEETPAGE hPropSettings = CreateThemedPropertySheetPage(pPspSettings);
  715. if (NULL == hProp || NULL == hPropSettings )
  716. hr = E_UNEXPECTED;
  717. else
  718. {
  719. lpProvider->AddPage(hProp);
  720. lpProvider->AddPage (hPropSettings);
  721. hr = S_OK;
  722. }
  723. }
  724. }
  725. FREE_INTERNAL(pInternal);
  726. return hr;
  727. }
  728. // Scope item property pages:
  729. STDMETHODIMP CScopePane::QueryPagesFor(LPDATAOBJECT lpDataObject)
  730. {
  731. // scope panes don't have property pages in RSOP mode
  732. if (m_fRSOP)
  733. {
  734. return S_FALSE;
  735. }
  736. //the only property sheets we are presenting right now are those
  737. //for built-in folder redirection
  738. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  739. if (! pInternal)
  740. return S_FALSE;
  741. MMC_COOKIE cookie = pInternal->m_cookie;
  742. HRESULT hr = S_FALSE;
  743. CError error;
  744. if (CCT_SCOPE == pInternal->m_type)
  745. {
  746. if (SUCCEEDED(m_FolderData[GETINDEX(cookie)].LoadSection()))
  747. hr = S_OK;
  748. else
  749. {
  750. error.ShowConsoleMessage (m_pConsole, IDS_SECTIONLOAD_ERROR,
  751. m_FolderData[GETINDEX(cookie)].m_szDisplayname);
  752. hr = S_FALSE;
  753. }
  754. }
  755. FREE_INTERNAL(pInternal);
  756. return hr;
  757. }
  758. BOOL CScopePane::IsScopePaneNode(LPDATAOBJECT lpDataObject)
  759. {
  760. BOOL bResult = FALSE;
  761. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  762. if (! pInternal)
  763. return bResult;
  764. if (pInternal->m_type == CCT_SCOPE)
  765. bResult = TRUE;
  766. FREE_INTERNAL(pInternal);
  767. return bResult;
  768. }
  769. ///////////////////////////////////////////////////////////////////////////////
  770. // IExtendContextMenu implementation
  771. //
  772. STDMETHODIMP CScopePane::AddMenuItems(LPDATAOBJECT pDataObject,
  773. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  774. LONG * pInsertionAllowed)
  775. {
  776. //we do not have any commands on the menu.
  777. return S_OK;
  778. }
  779. STDMETHODIMP CScopePane::Command(long nCommandID, LPDATAOBJECT pDataObject)
  780. {
  781. //we do not have any commands on the menu
  782. return S_OK;
  783. }