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.

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