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.

2601 lines
56 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. iisobj.cpp
  5. Abstract:
  6. IIS Object
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "common.h"
  15. #include "inetprop.h"
  16. #include "InetMgrApp.h"
  17. #include "supdlgs.h"
  18. #include "connects.h"
  19. #include "iisobj.h"
  20. #include "ftpsht.h"
  21. #include "w3sht.h"
  22. #include "fltdlg.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char BASED_CODE THIS_FILE[] = __FILE__;
  26. #endif
  27. #define new DEBUG_NEW
  28. //
  29. // CInetMgrComponentData
  30. //
  31. static const GUID CInetMgrGUID_NODETYPE
  32. = {0xa841b6c2, 0x7577, 0x11d0, { 0xbb, 0x1f, 0x0, 0xa0, 0xc9, 0x22, 0xe7, 0x9c}};
  33. //BOOL CIISObject::m_fIsExtension = FALSE;
  34. #define TB_COLORMASK RGB(192,192,192) // Lt. Gray
  35. LPOLESTR
  36. CoTaskDupString(
  37. IN LPCOLESTR szString
  38. )
  39. /*++
  40. Routine Description:
  41. Helper function to duplicate a OLESTR
  42. Arguments:
  43. LPOLESTR szString : Source string
  44. Return Value:
  45. Pointer to the new string or NULL
  46. --*/
  47. {
  48. OLECHAR * lpString = (OLECHAR *)CoTaskMemAlloc(
  49. sizeof(OLECHAR)*(lstrlen(szString) + 1)
  50. );
  51. if (lpString != NULL)
  52. {
  53. lstrcpy(lpString, szString);
  54. }
  55. return lpString;
  56. }
  57. const GUID * CIISObject::m_NODETYPE = &CLSID_InetMgr; //&CInetMgrGUID_NODETYPE;
  58. const OLECHAR * CIISObject::m_SZNODETYPE = OLESTR("A841B6C2-7577-11d0-BB1F-00A0C922E79C");
  59. const CLSID * CIISObject::m_SNAPIN_CLASSID = &CLSID_InetMgr;
  60. //
  61. // Backup/restore taskpad gif resource
  62. //
  63. #define RES_TASKPAD_BACKUP _T("/img\\backup.gif")
  64. //
  65. // CIISObject implementation
  66. //
  67. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  68. //
  69. // Important! The array indices below must ALWAYS be one
  70. // less than the menu ID -- keep in sync with enumeration
  71. // in iisobj.h!!!!
  72. //
  73. /* static */ CIISObject::CONTEXTMENUITEM_RC CIISObject::_menuItemDefs[] =
  74. {
  75. //
  76. // Menu Commands in toolbar order
  77. //
  78. //nNameID nStatusID nDescriptionID lCmdID lInsertionPointID fSpecialFlags
  79. // lpszMouseOverBitmap lpszMouseOffBitmap
  80. { IDS_MENU_CONNECT, IDS_MENU_TT_CONNECT, -1, IDM_CONNECT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  81. { IDS_MENU_DISCOVER, IDS_MENU_TT_DISCOVER, -1, IDM_DISCOVER, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  82. { IDS_MENU_START, IDS_MENU_TT_START, -1, IDM_START, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  83. { IDS_MENU_STOP, IDS_MENU_TT_STOP, -1, IDM_STOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  84. { IDS_MENU_PAUSE, IDS_MENU_TT_PAUSE, -1, IDM_PAUSE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  85. //
  86. // These are menu commands that do not show up in the toolbar
  87. //
  88. { IDS_MENU_EXPLORE, IDS_MENU_TT_EXPLORE, -1, IDM_EXPLORE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  89. { IDS_MENU_OPEN, IDS_MENU_TT_OPEN, -1, IDM_OPEN, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  90. { IDS_MENU_BROWSE, IDS_MENU_TT_BROWSE, -1, IDM_BROWSE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  91. { IDS_MENU_RECYCLE, IDS_MENU_TT_RECYCLE, -1, IDM_RECYCLE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  92. #if defined(_DEBUG) || DBG
  93. { IDS_MENU_IMPERSONATE, IDS_MENU_TT_IMPERSONATE, -1, IDM_IMPERSONATE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  94. { IDS_MENU_REM_IMPERS, IDS_MENU_TT_REM_IMPERS, -1, IDM_REMOVE_IMPERSONATION, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  95. #endif // _DEBUG
  96. { IDS_MENU_PROPERTIES, IDS_MENU_TT_PROPERTIES, -1, IDM_CONFIGURE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  97. { IDS_MENU_DISCONNECT, IDS_MENU_TT_DISCONNECT, -1, IDM_DISCONNECT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, },
  98. { IDS_MENU_BACKUP, IDS_MENU_TT_BACKUP, IDS_MENU_TT_BACKUP, IDM_METABACKREST, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, NULL, NULL, },
  99. { IDS_MENU_SHUTDOWN_IIS, IDS_MENU_TT_SHUTDOWN_IIS, -1, IDM_SHUTDOWN, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, NULL, NULL, },
  100. { IDS_MENU_NEWVROOT, IDS_MENU_TT_NEWVROOT, IDS_MENU_DS_NEWVROOT, IDM_NEW_VROOT, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWVROOT, RES_TASKPAD_NEWVROOT, },
  101. { IDS_MENU_NEWINSTANCE, IDS_MENU_TT_NEWINSTANCE, IDS_MENU_DS_NEWINSTANCE, IDM_NEW_INSTANCE, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, },
  102. { IDS_MENU_NEWFTPSITE, IDS_MENU_TT_NEWFTPSITE, IDS_MENU_DS_NEWFTPSITE, IDM_NEW_FTP_SITE, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, },
  103. { IDS_MENU_NEWFTPVDIR, IDS_MENU_TT_NEWFTPVDIR, IDS_MENU_DS_NEWFTPVDIR, IDM_NEW_FTP_VDIR, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, },
  104. { IDS_MENU_NEWWEBSITE, IDS_MENU_TT_NEWWEBSITE, IDS_MENU_DS_NEWWEBSITE, IDM_NEW_WEB_SITE, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, },
  105. { IDS_MENU_NEWWEBVDIR, IDS_MENU_TT_NEWWEBVDIR, IDS_MENU_DS_NEWWEBVDIR, IDM_NEW_WEB_VDIR, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, },
  106. { IDS_MENU_NEWAPPPOOL, IDS_MENU_TT_NEWAPPPOOL, IDS_MENU_DS_NEWAPPPOOL, IDM_NEW_APP_POOL, CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, RES_TASKPAD_NEWSITE, RES_TASKPAD_NEWSITE, },
  107. { IDS_MENU_TASKPAD, IDS_MENU_TT_TASKPAD, -1, IDM_VIEW_TASKPAD, CCM_INSERTIONPOINTID_PRIMARY_VIEW, 0, NULL, NULL, },
  108. { IDS_MENU_SECURITY_WIZARD, IDS_MENU_TT_SECURITY_WIZARD, IDS_MENU_TT_SECURITY_WIZARD, IDM_TASK_SECURITY_WIZARD, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, RES_TASKPAD_SECWIZ, RES_TASKPAD_SECWIZ, },
  109. };
  110. //
  111. // Image background colour for the toolbar buttons
  112. //
  113. #define RGB_BK_IMAGES (RGB(255,0,255)) // purple
  114. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  115. //
  116. // Toolbar Definition. String IDs for menu and tooltip
  117. // text will be resolved at initialization. The _SnapinButtons
  118. // button text and tooltips text will be loaded from the _SnapinButtonIDs
  119. // below, and should be kept in sync
  120. //
  121. /* static */ UINT CIISObject::_SnapinButtonIDs[] =
  122. {
  123. /* IDM_CONNECT */ IDS_MENU_CONNECT, IDS_MENU_TT_CONNECT,
  124. // /* IDM_DISCOVER */ IDS_MENU_DISCOVER, IDS_MENU_TT_CONNECT,
  125. /* IDM_START */ IDS_MENU_START, IDS_MENU_TT_START,
  126. /* IDM_STOP */ IDS_MENU_STOP, IDS_MENU_TT_STOP,
  127. /* IDM_PAUSE */ IDS_MENU_PAUSE, IDS_MENU_TT_PAUSE,
  128. };
  129. /* static */ MMCBUTTON CIISObject::_SnapinButtons[] =
  130. {
  131. { IDM_CONNECT - 1, IDM_CONNECT, TBSTATE_ENABLED, TBSTYLE_BUTTON, NULL, NULL },
  132. // { IDM_DISCOVER - 1, IDM_DISCOVER, TBSTATE_ENABLED, TBSTYLE_BUTTON, NULL, NULL },
  133. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, _T(" "), _T("") },
  134. { IDM_START - 1, IDM_START, TBSTATE_ENABLED, TBSTYLE_BUTTON, NULL, NULL },
  135. { IDM_STOP - 1, IDM_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, NULL, NULL },
  136. { IDM_PAUSE - 1, IDM_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, NULL, NULL },
  137. { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, _T(" "), _T("") },
  138. //
  139. // Add-on tools come here
  140. //
  141. };
  142. #define NUM_BUTTONS (ARRAYLEN(CIISObject::_SnapinButtons))
  143. #define NUM_BITMAPS (5)
  144. /* static */ CComBSTR CIISObject::_bstrResult;
  145. /* static */ CComBSTR CIISObject::_bstrLocalHost = _T("localhost");
  146. /* static */ HBITMAP CIISObject::_hImage16 = NULL;
  147. /* static */ HBITMAP CIISObject::_hImage32 = NULL;
  148. /* static */ HBITMAP CIISObject::_hToolBar = NULL;
  149. /* static */ CComPtr<IConsoleNameSpace> CIISObject::_lpConsoleNameSpace = NULL;
  150. /* static */ CComPtr<IConsole> CIISObject::_lpConsole = NULL;
  151. /* static */ CComPtr<IControlbar> CIISObject::_lpControlBar = NULL;
  152. /* static */ CComPtr<IToolbar> CIISObject::_lpToolBar = NULL;
  153. /* static */
  154. HRESULT
  155. CIISObject::Initialize()
  156. /*++
  157. Routine Description:
  158. Initialize static objects. Called once during lifetime of the snap-in.
  159. Arguments:
  160. None
  161. Return Value:
  162. HRESULT
  163. --*/
  164. {
  165. //
  166. // Initialize only once
  167. //
  168. if (_hImage16 != NULL || _hImage32 != NULL || _hToolBar != NULL)
  169. {
  170. return S_OK;
  171. }
  172. // ASSERT(_hImage16 == NULL);
  173. // ASSERT(_hImage32 == NULL);
  174. // ASSERT(_hToolBar == NULL);
  175. _hImage16 = ::LoadBitmap(
  176. _Module.GetResourceInstance(),
  177. MAKEINTRESOURCE(IDB_INETMGR16)
  178. );
  179. _hImage32 = ::LoadBitmap(
  180. _Module.GetResourceInstance(),
  181. MAKEINTRESOURCE(IDB_INETMGR32)
  182. );
  183. _hToolBar = ::LoadBitmap(
  184. _Module.GetResourceInstance(),
  185. MAKEINTRESOURCE(IDB_TOOLBAR)
  186. );
  187. if (!_hImage16 || !_hImage32 || !_hToolBar)
  188. {
  189. return E_OUTOFMEMORY;
  190. }
  191. //
  192. // Resolve tool tips texts
  193. //
  194. CComBSTR bstr;
  195. CString str;
  196. int j = 0;
  197. for (int i = 0; i < NUM_BUTTONS; ++i)
  198. {
  199. if (_SnapinButtons[i].idCommand != 0)
  200. {
  201. VERIFY(bstr.LoadString(_SnapinButtonIDs[j++]));
  202. VERIFY(bstr.LoadString(_SnapinButtonIDs[j++]));
  203. _SnapinButtons[i].lpButtonText = AllocString(bstr);
  204. _SnapinButtons[i].lpTooltipText = AllocString(bstr);
  205. }
  206. }
  207. return S_OK;
  208. }
  209. /* static */
  210. HRESULT
  211. CIISObject::Destroy()
  212. /*++
  213. Routine Description:
  214. Destroy static objects. Called when the snap-in is shut down
  215. Routine Description:
  216. None
  217. Return Value:
  218. HRESULT
  219. --*/
  220. {
  221. SAFE_DELETE_OBJECT(_hImage16);
  222. SAFE_DELETE_OBJECT(_hImage32);
  223. SAFE_DELETE_OBJECT(_hToolBar);
  224. for (int i = 0; i < NUM_BUTTONS; ++i)
  225. {
  226. if (_SnapinButtons[i].idCommand != 0)
  227. {
  228. SAFE_FREEMEM(_SnapinButtons[i].lpButtonText);
  229. SAFE_FREEMEM(_SnapinButtons[i].lpTooltipText);
  230. }
  231. }
  232. return S_OK;
  233. }
  234. /* static */
  235. HRESULT
  236. CIISObject::SetImageList(
  237. IN LPIMAGELIST lpImageList
  238. )
  239. /*++
  240. Routine Description:
  241. Set the image list
  242. Arguments:
  243. LPIMAGELIST lpImageList
  244. Return Value:
  245. HRESULT
  246. --*/
  247. {
  248. ASSERT(_hImage16 != NULL);
  249. ASSERT(_hImage32 != NULL);
  250. if (lpImageList->ImageListSetStrip(
  251. (LONG_PTR *)_hImage16,
  252. (LONG_PTR *)_hImage32,
  253. 0,
  254. RGB_BK_IMAGES
  255. ) != S_OK)
  256. {
  257. TRACEEOLID("IImageList::ImageListSetStrip failed");
  258. return E_UNEXPECTED;
  259. }
  260. return S_OK;
  261. }
  262. /* static */
  263. HRESULT
  264. CIISObject::AttachScopeView(
  265. IN LPUNKNOWN lpUnknown
  266. )
  267. /*++
  268. Routine Description:
  269. Cache interfaces to the scope view.
  270. Arguments:
  271. IN LPUNKNOWN lpUnknown : IUnknown
  272. Return Value:
  273. HRESULT
  274. --*/
  275. {
  276. ASSERT(_lpConsoleNameSpace == NULL); // BUGBUG: Fires on opening another console file
  277. ASSERT(_lpConsole == NULL); // BUGBUG: Fires on opening another console file
  278. ASSERT_PTR(lpUnknown);
  279. HRESULT hr = E_UNEXPECTED;
  280. do
  281. {
  282. //
  283. // Query the interfaces for console name space and console
  284. //
  285. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace>
  286. lpConsoleNameSpace(lpUnknown);
  287. if (!lpConsoleNameSpace)
  288. {
  289. break;
  290. }
  291. CComQIPtr<IConsole, &IID_IConsole> lpConsole(lpConsoleNameSpace);
  292. if (!lpConsole)
  293. {
  294. break;
  295. }
  296. //
  297. // Cache the interfaces
  298. //
  299. _lpConsoleNameSpace = lpConsoleNameSpace;
  300. _lpConsole = lpConsole;
  301. hr = S_OK;
  302. }
  303. while(FALSE);
  304. return hr;
  305. }
  306. /* static */
  307. void
  308. CIISObject::BuildResultView(
  309. IN LPHEADERCTRL lpHeader,
  310. IN int cColumns,
  311. IN int * pnIDS,
  312. IN int * pnWidths
  313. )
  314. /*++
  315. Routine Description:
  316. Build the result view columns.
  317. Routine Description:
  318. LPHEADERCTRL lpHeader : Header control
  319. int cColumns : Number of columns
  320. int * pnIDS : Array of column header strings
  321. int * pnWidths : Array of column widths
  322. Routine Description:
  323. None
  324. --*/
  325. {
  326. ASSERT_READ_PTR(lpHeader);
  327. CComBSTR bstr;
  328. for (int n = 0; n < cColumns; ++n)
  329. {
  330. VERIFY(bstr.LoadString(pnIDS[n]));
  331. lpHeader->InsertColumn(n, bstr, LVCFMT_LEFT, pnWidths[n]);
  332. }
  333. }
  334. /* static */
  335. CWnd *
  336. CIISObject::GetMainWindow()
  337. /*++
  338. Routine Description:
  339. Get a pointer to main window object.
  340. Arguments:
  341. None
  342. Return Value:
  343. Pointer to main window object. This object is temporary and should not be
  344. cached.
  345. --*/
  346. {
  347. HWND hWnd;
  348. CWnd * pWnd = NULL;
  349. ASSERT_PTR(_lpConsole);
  350. HRESULT hr = _lpConsole->GetMainWindow(&hWnd);
  351. if (SUCCEEDED(hr))
  352. {
  353. pWnd = CWnd::FromHandle(hWnd);
  354. }
  355. return pWnd;
  356. }
  357. /* static */
  358. HRESULT
  359. CIISObject::__SetControlbar(
  360. IN LPCONTROLBAR lpControlBar,
  361. IN LPEXTENDCONTROLBAR lpExtendControlBar
  362. )
  363. /*++
  364. Routine Description:
  365. Initialize or remove the toolbar.
  366. Arguments:
  367. LPCONTROLBAR lpControlBar : Control bar or NULL
  368. LPEXTENDCONTROLBAR lpExtendControlBar : ExtendControlBar class
  369. Return Value:
  370. HRESULT
  371. --*/
  372. {
  373. //
  374. // Cache the control bar
  375. //
  376. HRESULT hr = S_OK;
  377. if (lpControlBar)
  378. {
  379. if (_lpControlBar)
  380. {
  381. _lpControlBar.Release();
  382. }
  383. _lpControlBar = lpControlBar;
  384. do
  385. {
  386. //
  387. // Create our toolbar
  388. //
  389. hr = _lpControlBar->Create(
  390. TOOLBAR,
  391. lpExtendControlBar,
  392. (LPUNKNOWN *)&_lpToolBar
  393. );
  394. if (FAILED(hr))
  395. {
  396. break;
  397. }
  398. //
  399. // Add 16x16 bitmaps
  400. //
  401. hr = _lpToolBar->AddBitmap(
  402. NUM_BITMAPS,
  403. _hToolBar,
  404. 16,
  405. 16,
  406. TB_COLORMASK
  407. );
  408. if (FAILED(hr))
  409. {
  410. break;
  411. }
  412. //
  413. // Add the buttons to the toolbar
  414. //
  415. hr = _lpToolBar->AddButtons(NUM_BUTTONS, _SnapinButtons);
  416. }
  417. while(FALSE);
  418. }
  419. else
  420. {
  421. //
  422. // Release existing controlbar
  423. //
  424. _lpControlBar.Release();
  425. }
  426. return hr;
  427. }
  428. /* static */
  429. HRESULT
  430. CIISObject::AddMMCPage(
  431. IN LPPROPERTYSHEETCALLBACK lpProvider,
  432. IN CPropertyPage * pPage
  433. )
  434. /*++
  435. Routine Description:
  436. Add MMC page to providers sheet.
  437. Arguments:
  438. LPPROPERTYSHEETCALLBACK lpProvider : Property sheet provider
  439. CPropertyPage * pPage : Property page to add
  440. Return:
  441. HRESULT
  442. --*/
  443. {
  444. ASSERT_READ_PTR(pPage);
  445. if (pPage == NULL)
  446. {
  447. TRACEEOLID("NULL page pointer passed to AddMMCPage");
  448. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  449. }
  450. PROPSHEETPAGE_LATEST pspLatest;
  451. ZeroMemory(&pspLatest, sizeof(PROPSHEETPAGE_LATEST));
  452. CopyMemory (&pspLatest, &pPage->m_psp, pPage->m_psp.dwSize);
  453. pspLatest.dwSize = sizeof(pspLatest);
  454. //
  455. // MFC Bug work-around.
  456. //
  457. MMCPropPageCallback(&pspLatest);
  458. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pspLatest);
  459. if (hPage == NULL)
  460. {
  461. return E_UNEXPECTED;
  462. }
  463. return lpProvider->AddPage(hPage);
  464. }
  465. CIISObject::CIISObject()
  466. : m_hScopeItem(NULL),
  467. m_hResultItem(0),
  468. m_fSkipEnumResult(FALSE)
  469. {
  470. m_fIsExtension = FALSE;
  471. }
  472. CIISObject::~CIISObject()
  473. {
  474. }
  475. /* virtual */
  476. HRESULT
  477. CIISObject::ControlbarNotify(
  478. IN MMC_NOTIFY_TYPE event,
  479. IN LPARAM arg,
  480. IN LPARAM param
  481. )
  482. /*++
  483. Routine Description:
  484. Handle control bar notification messages, such as select or click.
  485. Arguments:
  486. MMC_NOTIFY_TYPE event : Notification message
  487. long arg : Message specific argument
  488. long param : Message specific parameter
  489. Return Value:
  490. HRESULT
  491. --*/
  492. {
  493. BOOL fSelect = (BOOL)HIWORD(arg);
  494. BOOL fScope = (BOOL)LOWORD(arg);
  495. HRESULT hr = S_OK;
  496. switch(event)
  497. {
  498. case MMCN_SELECT:
  499. //
  500. // Handle selection of this node by attaching the toolbar
  501. // and enabling/disabling specific buttons
  502. //
  503. ASSERT_PTR(_lpToolBar);
  504. ASSERT_PTR(_lpControlBar);
  505. hr = _lpControlBar->Attach(TOOLBAR, _lpToolBar);
  506. if (SUCCEEDED(hr))
  507. {
  508. SetToolBarStates();
  509. }
  510. break;
  511. case MMCN_BTN_CLICK:
  512. //
  513. // Handle button-click by passing the command ID of the
  514. // button to the command handler
  515. //
  516. hr = Command((long)param, NULL, fScope ? CCT_SCOPE : CCT_RESULT);
  517. break;
  518. case MMCN_HELP:
  519. break;
  520. default:
  521. ASSERT_MSG("Invalid control bar notification received");
  522. };
  523. return hr;
  524. }
  525. /* virtual */
  526. HRESULT
  527. CIISObject::SetToolBarStates()
  528. /*++
  529. Routine Description:
  530. Set the toolbar states depending on the state of this object
  531. Arguments:
  532. None
  533. Return Value:
  534. HRESULT
  535. --*/
  536. {
  537. if (_lpToolBar)
  538. {
  539. _lpToolBar->SetButtonState(IDM_CONNECT, ENABLED, IsConnectable());
  540. _lpToolBar->SetButtonState(IDM_PAUSE, ENABLED, IsPausable());
  541. _lpToolBar->SetButtonState(IDM_START, ENABLED, IsStartable());
  542. _lpToolBar->SetButtonState(IDM_STOP, ENABLED, IsStoppable());
  543. _lpToolBar->SetButtonState(IDM_PAUSE, BUTTONPRESSED, IsPaused());
  544. }
  545. return S_OK;
  546. }
  547. HRESULT
  548. CIISObject::GetScopePaneInfo(
  549. IN OUT LPSCOPEDATAITEM lpScopeDataItem
  550. )
  551. /*++
  552. Routine Description:
  553. Return information about scope pane.
  554. Arguments:
  555. LPSCOPEDATAITEM lpScopeDataItem : Scope data item
  556. Return Value:
  557. HRESULT
  558. --*/
  559. {
  560. ASSERT_READ_WRITE_PTR(lpScopeDataItem);
  561. if (lpScopeDataItem->mask & SDI_STR)
  562. {
  563. lpScopeDataItem->displayname = QueryDisplayName();
  564. }
  565. if (lpScopeDataItem->mask & SDI_IMAGE)
  566. {
  567. lpScopeDataItem->nImage = QueryImage();
  568. }
  569. if (lpScopeDataItem->mask & SDI_OPENIMAGE)
  570. {
  571. lpScopeDataItem->nOpenImage = QueryImage();
  572. }
  573. if (lpScopeDataItem->mask & SDI_PARAM)
  574. {
  575. lpScopeDataItem->lParam = (LPARAM)this;
  576. }
  577. if (lpScopeDataItem->mask & SDI_STATE)
  578. {
  579. //
  580. // BUGBUG: Wotz all this then?
  581. //
  582. ASSERT_MSG("State requested");
  583. lpScopeDataItem->nState = 0;
  584. }
  585. //
  586. // TODO : Add code for SDI_CHILDREN
  587. //
  588. return S_OK;
  589. }
  590. /* virtual */
  591. int
  592. CIISObject::CompareScopeItem(
  593. IN CIISObject * pObject
  594. )
  595. /*++
  596. Routine Description:
  597. Standard comparison method to compare lexically on display name.
  598. Derived classes should override if anything other than lexical
  599. sort on the display name is required.
  600. Arguments:
  601. CIISObject * pObject : Object to compare against
  602. Return Value:
  603. 0 if the two objects are identical
  604. <0 if this object is less than pObject
  605. >0 if this object is greater than pObject
  606. --*/
  607. {
  608. ASSERT_READ_PTR(pObject);
  609. //
  610. // First criteria is object type
  611. //
  612. int n1 = QuerySortWeight();
  613. int n2 = pObject->QuerySortWeight();
  614. if (n1 != n2)
  615. {
  616. return n1 - n2;
  617. }
  618. //
  619. // Else sort lexically on the display name.
  620. //
  621. return ::lstrcmpi(QueryDisplayName(), pObject->QueryDisplayName());
  622. }
  623. /* virtual */
  624. int
  625. CIISObject::CompareResultPaneItem(
  626. IN CIISObject * pObject,
  627. IN int nCol
  628. )
  629. /*++
  630. Routine Description:
  631. Compare two CIISObjects on sort item criteria
  632. Arguments:
  633. CIISObject * pObject : Object to compare against
  634. int nCol : Column number to sort on
  635. Return Value:
  636. 0 if the two objects are identical
  637. <0 if this object is less than pObject
  638. >0 if this object is greater than pObject
  639. --*/
  640. {
  641. ASSERT_READ_PTR(pObject);
  642. if (nCol == 0)
  643. {
  644. return CompareScopeItem(pObject);
  645. }
  646. //
  647. // First criteria is object type
  648. //
  649. int n1 = QuerySortWeight();
  650. int n2 = pObject->QuerySortWeight();
  651. if (n1 != n2)
  652. {
  653. return n1 - n2;
  654. }
  655. //
  656. // Sort lexically on column text
  657. //
  658. return ::lstrcmpi(
  659. GetResultPaneColInfo(nCol),
  660. pObject->GetResultPaneColInfo(nCol)
  661. );
  662. }
  663. HRESULT
  664. CIISObject::GetResultPaneInfo(LPRESULTDATAITEM lpResultDataItem)
  665. /*++
  666. Routine Description:
  667. Get information about result pane item
  668. Arguments:
  669. LPRESULTDATAITEM lpResultDataItem : Result data item
  670. Return Value:
  671. HRESULT
  672. --*/
  673. {
  674. ASSERT_READ_WRITE_PTR(lpResultDataItem);
  675. if (lpResultDataItem->bScopeItem)
  676. {
  677. if (lpResultDataItem->mask & RDI_STR)
  678. {
  679. lpResultDataItem->str = GetResultPaneColInfo(lpResultDataItem->nCol);
  680. }
  681. if (lpResultDataItem->mask & RDI_IMAGE)
  682. {
  683. lpResultDataItem->nImage = QueryImage();
  684. }
  685. if (lpResultDataItem->mask & RDI_PARAM)
  686. {
  687. lpResultDataItem->lParam = (LPARAM)this;
  688. }
  689. return S_OK;
  690. }
  691. if (lpResultDataItem->mask & RDI_STR)
  692. {
  693. lpResultDataItem->str = GetResultPaneColInfo(lpResultDataItem->nCol);
  694. }
  695. if (lpResultDataItem->mask & RDI_IMAGE)
  696. {
  697. lpResultDataItem->nImage = QueryImage();
  698. }
  699. if (lpResultDataItem->mask & RDI_PARAM)
  700. {
  701. lpResultDataItem->lParam = (LPARAM)this;
  702. }
  703. if (lpResultDataItem->mask & RDI_INDEX)
  704. {
  705. //
  706. // BUGBUG: Wotz all this then?
  707. //
  708. ASSERT_MSG("INDEX???");
  709. lpResultDataItem->nIndex = 0;
  710. }
  711. return S_OK;
  712. }
  713. /* virtual */
  714. LPOLESTR
  715. CIISObject::GetResultPaneColInfo(int nCol)
  716. /*++
  717. Routine Description:
  718. Return result pane string for the given column number
  719. Arguments:
  720. int nCol : Column number
  721. Return Value:
  722. String
  723. --*/
  724. {
  725. if (nCol == 0)
  726. {
  727. return QueryDisplayName();
  728. }
  729. ASSERT_MSG("Override GetResultPaneColInfo");
  730. return OLESTR("Override GetResultPaneColInfo");
  731. }
  732. /* virtual */
  733. HRESULT
  734. CIISObject::GetResultViewType(
  735. OUT LPOLESTR * lplpViewType,
  736. OUT long * lpViewOptions
  737. )
  738. /*++
  739. Routine Description:
  740. Tell MMC what our result view looks like
  741. Arguments:
  742. BSTR * lplpViewType : Return view type here
  743. long * lpViewOptions : View options
  744. Return Value:
  745. S_FALSE to use default view type, S_OK indicates the
  746. view type is returned in *ppViewType
  747. --*/
  748. {
  749. *lplpViewType = NULL;
  750. *lpViewOptions = MMC_VIEW_OPTIONS_USEFONTLINKING;
  751. //
  752. // Default View
  753. //
  754. return S_FALSE;
  755. }
  756. /* virtual */
  757. HRESULT
  758. CIISObject::CreatePropertyPages(
  759. IN LPPROPERTYSHEETCALLBACK lpProvider,
  760. IN LONG_PTR handle,
  761. IN IUnknown * pUnk,
  762. IN DATA_OBJECT_TYPES type
  763. )
  764. /*++
  765. Routine Description:
  766. Create the property pages for the given object
  767. Arguments:
  768. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  769. LONG_PTR handle : Handle.
  770. IUnknown * pUnk,
  771. DATA_OBJECT_TYPES type
  772. Return Value:
  773. HRESULT
  774. --*/
  775. {
  776. //
  777. // No Pages
  778. //
  779. return S_OK;
  780. }
  781. /* virtual */
  782. HRESULT
  783. CIISObject::QueryPagesFor(
  784. IN DATA_OBJECT_TYPES type
  785. )
  786. /*++
  787. Routine Description:
  788. Check to see if a property sheet should be brought up for this data
  789. object
  790. Arguments:
  791. DATA_OBJECT_TYPES type : Data object type
  792. Return Value:
  793. S_OK, if properties may be brought up for this item, S_FALSE otherwise
  794. --*/
  795. {
  796. return IsConfigurable() ? S_OK : S_FALSE;
  797. }
  798. /* virtual */
  799. CIISRoot *
  800. CIISObject::GetRoot()
  801. /*++
  802. Routine Description:
  803. Get the CIISRoot object of this tree.
  804. Arguments:
  805. None
  806. Return Value:
  807. CIISRoot * or NULL
  808. --*/
  809. {
  810. ASSERT(!m_fIsExtension);
  811. LONG_PTR cookie;
  812. HSCOPEITEM hParent;
  813. ASSERT_PTR(_lpConsoleNameSpace);
  814. HRESULT hr = _lpConsoleNameSpace->GetParentItem(m_hScopeItem, &hParent, &cookie);
  815. if (SUCCEEDED(hr))
  816. {
  817. CIISMBNode * pNode = (CIISMBNode *)cookie;
  818. ASSERT_PTR(pNode);
  819. ASSERT_PTR(hParent);
  820. if (pNode)
  821. {
  822. return pNode->GetRoot();
  823. }
  824. }
  825. ASSERT_MSG("Unable to find CIISRoot object!");
  826. return NULL;
  827. }
  828. HRESULT
  829. CIISObject::AskForAndAddMachine()
  830. /*++
  831. Routine Description:
  832. Ask user to add a computer name, verify the computer is alive, and add it to
  833. the list.
  834. Arguments:
  835. None
  836. Return Value:
  837. HRESULT
  838. --*/
  839. {
  840. CError err;
  841. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  842. ConnectServerDlg dlg(GetMainWindow());
  843. if (dlg.DoModal() == IDOK)
  844. {
  845. CIISMachine * pMachine = dlg.GetMachine();
  846. //
  847. // The machine object we get from the dialog
  848. // is guaranteed to be good and valid.
  849. //
  850. ASSERT_PTR(pMachine);
  851. ASSERT(pMachine->HasInterface());
  852. CIISRoot * pRoot = GetRoot();
  853. if (pRoot)
  854. {
  855. //
  856. // Add new machine object as child of the IIS root
  857. // object.
  858. //
  859. if (pRoot->m_scServers.Add(pMachine))
  860. {
  861. err = pMachine->AddToScopePaneSorted(pRoot->QueryScopeItem());
  862. if (err.Succeeded())
  863. {
  864. //
  865. // Select the item in the scope view
  866. //
  867. err = pMachine->SelectScopeItem();
  868. }
  869. }
  870. else
  871. {
  872. //
  873. // Duplicate machine already in cache. Find it and select
  874. // it.
  875. //
  876. TRACEEOLID("Machine already in scope view.");
  877. CIISObject * pIdentical = pRoot->FindIdenticalScopePaneItem(
  878. pMachine
  879. );
  880. //
  881. // Duplicate must exist!
  882. //
  883. ASSERT_READ_PTR(pIdentical);
  884. if (pIdentical)
  885. {
  886. err = pIdentical->SelectScopeItem();
  887. }
  888. delete pMachine;
  889. }
  890. }
  891. }
  892. return err;
  893. }
  894. /* static */
  895. HRESULT
  896. CIISObject::AddMenuItemByCommand(
  897. IN LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  898. IN LONG lCmdID,
  899. IN LONG fFlags
  900. )
  901. /*++
  902. Routine Description:
  903. Add menu item by command
  904. Arguments:
  905. LPCONTEXTMENUCALLBACK lpContextMenuCallback : Callback pointer
  906. LONG lCmdID : Command ID
  907. LONG fFlags : Flags
  908. Return Value:
  909. HRESULT
  910. --*/
  911. {
  912. ASSERT_READ_PTR(lpContextMenuCallback);
  913. //
  914. // Offset 1 menu commands
  915. //
  916. LONG l = lCmdID -1;
  917. CComBSTR strName;
  918. CComBSTR strStatus;
  919. VERIFY(strName.LoadString(_menuItemDefs[l].nNameID));
  920. VERIFY(strStatus.LoadString(_menuItemDefs[l].nStatusID));
  921. CONTEXTMENUITEM cmi;
  922. cmi.strName = strName;
  923. cmi.strStatusBarText = strStatus;
  924. cmi.lCommandID = _menuItemDefs[l].lCmdID;
  925. cmi.lInsertionPointID = _menuItemDefs[l].lInsertionPointID;
  926. cmi.fFlags = fFlags;
  927. cmi.fSpecialFlags = _menuItemDefs[l].fSpecialFlags;
  928. return lpContextMenuCallback->AddItem(&cmi);
  929. }
  930. /* static */
  931. HRESULT
  932. CIISObject::AddMenuSeparator(
  933. IN LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  934. IN LONG lInsertionPointID
  935. )
  936. /*++
  937. Routine Description:
  938. Add a separator to the given insertion point menu.
  939. Arguments:
  940. LPCONTEXTMENUCALLBACK lpContextMenuCallback : Callback pointer
  941. LONG lInsertionPointID : Insertion point menu id.
  942. Return Value:
  943. HRESULT
  944. --*/
  945. {
  946. ASSERT_READ_PTR(lpContextMenuCallback);
  947. CONTEXTMENUITEM menuSep =
  948. {
  949. NULL,
  950. NULL,
  951. -1,
  952. lInsertionPointID,
  953. 0,
  954. CCM_SPECIAL_SEPARATOR
  955. };
  956. return lpContextMenuCallback->AddItem(&menuSep);
  957. }
  958. BOOL
  959. CIISObject::IsExpanded() const
  960. /*++
  961. Routine Description:
  962. Determine if this object has been expanded.
  963. Arguments:
  964. None
  965. Return Value:
  966. TRUE if the node has been expanded,
  967. FALSE if it has not.
  968. --*/
  969. {
  970. ASSERT_PTR(_lpConsoleNameSpace != NULL);
  971. ASSERT(m_hScopeItem != NULL);
  972. SCOPEDATAITEM scopeDataItem;
  973. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  974. scopeDataItem.mask = SDI_STATE;
  975. scopeDataItem.ID = m_hScopeItem;
  976. HRESULT hr = _lpConsoleNameSpace->GetItem(&scopeDataItem);
  977. return SUCCEEDED(hr) &&
  978. scopeDataItem.nState == MMC_SCOPE_ITEM_STATE_EXPANDEDONCE;
  979. }
  980. CIISObject *
  981. CIISObject::FindIdenticalScopePaneItem(
  982. IN CIISObject * pObject
  983. )
  984. /*++
  985. Routine Description:
  986. Find CIISObject in the scope view. The scope view is assumed
  987. to be sorted.
  988. Arguments:
  989. CIISObject * pObject : Item to search for
  990. Return Value:
  991. Pointer to iis object, or NULL if the item was not found
  992. Notes:
  993. Note that any item with a 0 comparison value is returned, not
  994. necessarily the identical CIISObject.
  995. --*/
  996. {
  997. ASSERT_PTR(_lpConsoleNameSpace);
  998. ASSERT(m_hScopeItem != NULL);
  999. //
  1000. // Find proper insertion point
  1001. //
  1002. HSCOPEITEM hChildItem = NULL;
  1003. CIISObject * pReturn = NULL;
  1004. CIISObject * pItem;
  1005. LONG_PTR cookie;
  1006. int nSwitch;
  1007. HRESULT hr = _lpConsoleNameSpace->GetChildItem(
  1008. m_hScopeItem, &hChildItem, &cookie);
  1009. while(SUCCEEDED(hr) && hChildItem)
  1010. {
  1011. //
  1012. // The cookie is really the IISObject, which is what we stuff
  1013. // in the lparam.
  1014. //
  1015. pItem = (CIISObject *)cookie;
  1016. ASSERT_PTR(pItem);
  1017. nSwitch = pItem->CompareScopeItem(pObject);
  1018. if (nSwitch == 0)
  1019. {
  1020. //
  1021. // Found it.
  1022. //
  1023. pReturn = pItem;
  1024. }
  1025. if (nSwitch > 0)
  1026. {
  1027. //
  1028. // Should have found it by now.
  1029. //
  1030. break;
  1031. }
  1032. //
  1033. // Advance to next child of same parent
  1034. //
  1035. hr = _lpConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1036. }
  1037. return pReturn;
  1038. }
  1039. /* virtual */
  1040. HRESULT
  1041. CIISObject::AddMenuItems(
  1042. IN LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  1043. IN OUT long * pInsertionAllowed,
  1044. IN DATA_OBJECT_TYPES type
  1045. )
  1046. /*++
  1047. Routine Description:
  1048. Add menu items to the context menu
  1049. Arguments:
  1050. LPCONTEXTMENUCALLBACK lpContextMenuCallback : Context menu callback
  1051. long * pInsertionAllowed : Insertion allowed
  1052. DATA_OBJECT_TYPES type : Object type
  1053. Return Value:
  1054. HRESULT
  1055. --*/
  1056. {
  1057. ASSERT_READ_PTR(lpContextMenuCallback);
  1058. ASSERT(pInsertionAllowed != NULL);
  1059. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) != 0)
  1060. {
  1061. if (IsConnectable() && !m_fIsExtension)
  1062. {
  1063. AddMenuItemByCommand(lpContextMenuCallback, IDM_CONNECT);
  1064. }
  1065. if (IsDisconnectable() && !m_fIsExtension)
  1066. {
  1067. ASSERT(IsConnectable());
  1068. AddMenuItemByCommand(lpContextMenuCallback, IDM_DISCONNECT);
  1069. }
  1070. if (IsExplorable())
  1071. {
  1072. AddMenuSeparator(lpContextMenuCallback);
  1073. AddMenuItemByCommand(lpContextMenuCallback, IDM_EXPLORE);
  1074. }
  1075. if (IsOpenable())
  1076. {
  1077. AddMenuItemByCommand(lpContextMenuCallback, IDM_OPEN);
  1078. }
  1079. if (IsBrowsable())
  1080. {
  1081. AddMenuItemByCommand(lpContextMenuCallback, IDM_BROWSE);
  1082. }
  1083. if (IsControllable())
  1084. {
  1085. AddMenuSeparator(lpContextMenuCallback);
  1086. UINT nPauseFlags = IsPausable() ? 0 : MF_GRAYED;
  1087. if (IsPaused())
  1088. {
  1089. nPauseFlags |= MF_CHECKED;
  1090. }
  1091. AddMenuItemByCommand(lpContextMenuCallback, IDM_START, IsStartable() ? 0 : MF_GRAYED);
  1092. AddMenuItemByCommand(lpContextMenuCallback, IDM_STOP, IsStoppable() ? 0 : MF_GRAYED);
  1093. AddMenuItemByCommand(lpContextMenuCallback, IDM_PAUSE, nPauseFlags);
  1094. }
  1095. }
  1096. return S_OK;
  1097. }
  1098. /* virtual */
  1099. HRESULT
  1100. CIISObject::Command(
  1101. IN long lCommandID,
  1102. IN CSnapInObjectRootBase * lpObj,
  1103. IN DATA_OBJECT_TYPES type
  1104. )
  1105. /*++
  1106. Routine Description:
  1107. Handle command from context menu.
  1108. Arguments:
  1109. long lCommandID : Command ID
  1110. CSnapInObjectRootBase * lpObj : Base object
  1111. DATA_OBJECT_TYPES type : Data object type
  1112. Return Value:
  1113. HRESULT
  1114. --*/
  1115. {
  1116. HRESULT hr = S_OK;
  1117. switch (lCommandID)
  1118. {
  1119. case IDM_CONNECT:
  1120. hr = AskForAndAddMachine();
  1121. break;
  1122. }
  1123. return hr;
  1124. }
  1125. #if defined(_DEBUG) || DBG
  1126. LPCTSTR
  1127. ParseEvent(MMC_NOTIFY_TYPE event)
  1128. {
  1129. LPCTSTR p = NULL;
  1130. switch (event)
  1131. {
  1132. case MMCN_ACTIVATE: p = _T("MMCN_ACTIVATE"); break;
  1133. case MMCN_ADD_IMAGES: p = _T("MMCN_ADD_IMAGES"); break;
  1134. case MMCN_BTN_CLICK: p = _T("MMCN_BTN_CLICK"); break;
  1135. case MMCN_CLICK: p = _T("MMCN_CLICK"); break;
  1136. case MMCN_COLUMN_CLICK: p = _T("MMCN_COLUMN_CLICK"); break;
  1137. case MMCN_CONTEXTMENU: p = _T("MMCN_CONTEXTMENU"); break;
  1138. case MMCN_CUTORMOVE: p = _T("MMCN_CUTORMOVE"); break;
  1139. case MMCN_DBLCLICK: p = _T("MMCN_DBLCLICK"); break;
  1140. case MMCN_DELETE: p = _T("MMCN_DELETE"); break;
  1141. case MMCN_DESELECT_ALL: p = _T("MMCN_DESELECT_ALL"); break;
  1142. case MMCN_EXPAND: p = _T("MMCN_EXPAND"); break;
  1143. case MMCN_HELP: p = _T("MMCN_HELP"); break;
  1144. case MMCN_MENU_BTNCLICK: p = _T("MMCN_MENU_BTNCLICK"); break;
  1145. case MMCN_MINIMIZED: p = _T("MMCN_MINIMIZED"); break;
  1146. case MMCN_PASTE: p = _T("MMCN_PASTE"); break;
  1147. case MMCN_PROPERTY_CHANGE: p = _T("MMCN_PROPERTY_CHANGE"); break;
  1148. case MMCN_QUERY_PASTE: p = _T("MMCN_QUERY_PASTE"); break;
  1149. case MMCN_REFRESH: p = _T("MMCN_REFRESH"); break;
  1150. case MMCN_REMOVE_CHILDREN: p = _T("MMCN_REMOVE_CHILDREN"); break;
  1151. case MMCN_RENAME: p = _T("MMCN_RENAME"); break;
  1152. case MMCN_SELECT: p = _T("MMCN_SELECT"); break;
  1153. case MMCN_SHOW: p = _T("MMCN_SHOW"); break;
  1154. case MMCN_VIEW_CHANGE: p = _T("MMCN_VIEW_CHANGE"); break;
  1155. case MMCN_SNAPINHELP: p = _T("MMCN_SNAPINHELP"); break;
  1156. case MMCN_CONTEXTHELP: p = _T("MMCN_CONTEXTHELP"); break;
  1157. case MMCN_INITOCX: p = _T("MMCN_INITOCX"); break;
  1158. case MMCN_FILTER_CHANGE: p = _T("MMCN_FILTER_CHANGE"); break;
  1159. case MMCN_FILTERBTN_CLICK: p = _T("MMCN_FILTERBTN_CLICK"); break;
  1160. case MMCN_RESTORE_VIEW: p = _T("MMCN_RESTORE_VIEW"); break;
  1161. case MMCN_PRINT: p = _T("MMCN_PRINT"); break;
  1162. case MMCN_PRELOAD: p = _T("MMCN_PRELOAD"); break;
  1163. case MMCN_LISTPAD: p = _T("MMCN_LISTPAD"); break;
  1164. case MMCN_EXPANDSYNC: p = _T("MMCN_EXPANDSYNC"); break;
  1165. case MMCN_COLUMNS_CHANGED: p = _T("MMCN_COLUMNS_CHANGED"); break;
  1166. case MMCN_CANPASTE_OUTOFPROC: p = _T("MMCN_CANPASTE_OUTOFPROC"); break;
  1167. default: p = _T("Unknown"); break;
  1168. }
  1169. return p;
  1170. }
  1171. #endif
  1172. HRESULT
  1173. CIISObject::Notify(
  1174. IN MMC_NOTIFY_TYPE event,
  1175. IN LPARAM arg,
  1176. IN LPARAM param,
  1177. IN IComponentData * lpComponentData,
  1178. IN IComponent * lpComponent,
  1179. IN DATA_OBJECT_TYPES type
  1180. )
  1181. /*++
  1182. Routine Description:
  1183. Notification handler
  1184. Arguments:
  1185. MMC_NOTIFY_TYPE event : Notification type
  1186. long arg : Event-specific argument
  1187. long param : Event-specific parameter
  1188. IComponentData * pComponentData : IComponentData
  1189. IComponent * pComponent : IComponent
  1190. DATA_OBJECT_TYPES type : Data object type
  1191. Return Value:
  1192. HRESULT
  1193. --*/
  1194. {
  1195. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1196. CError err(E_NOTIMPL);
  1197. ASSERT(lpComponentData != NULL || lpComponent != NULL);
  1198. // CComPtr<IConsole> lpConsole;
  1199. IConsole * lpConsole;
  1200. CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> lpHeader;
  1201. CComQIPtr<IResultData, &IID_IResultData> lpResultData;
  1202. if (lpComponentData != NULL)
  1203. {
  1204. lpConsole = ((CInetMgr *)lpComponentData)->m_spConsole;
  1205. }
  1206. else
  1207. {
  1208. lpConsole = ((CInetMgrComponent *)lpComponent)->m_spConsole;
  1209. }
  1210. lpHeader = lpConsole;
  1211. lpResultData = lpConsole;
  1212. switch (event)
  1213. {
  1214. case MMCN_PROPERTY_CHANGE:
  1215. err = OnPropertyChange((BOOL)arg, lpResultData);
  1216. break;
  1217. case MMCN_SHOW:
  1218. if (m_fSkipEnumResult)
  1219. {
  1220. m_fSkipEnumResult = FALSE;
  1221. }
  1222. else
  1223. {
  1224. err = EnumerateResultPane((BOOL)arg, lpHeader, lpResultData);
  1225. if (err.Failed())
  1226. {
  1227. // Fail code will prevent MMC from enabling verbs
  1228. err.Reset();
  1229. }
  1230. }
  1231. break;
  1232. case MMCN_EXPAND:
  1233. {
  1234. CWaitCursor wait;
  1235. err = EnumerateScopePane((HSCOPEITEM)param);
  1236. }
  1237. break;
  1238. case MMCN_ADD_IMAGES:
  1239. err = AddImages((LPIMAGELIST)arg);
  1240. break;
  1241. case MMCN_DELETE:
  1242. err = DeleteNode(lpResultData);
  1243. break;
  1244. case MMCN_REMOVE_CHILDREN:
  1245. err = DeleteChildObjects((HSCOPEITEM)arg);
  1246. break;
  1247. case MMCN_VIEW_CHANGE:
  1248. TRACEEOL("MMCN_VIEW_CHANGE arg " << arg << " param " << param);
  1249. case MMCN_REFRESH:
  1250. // Refresh current node, and re-enumerate
  1251. // child nodes of the child nodes had previously
  1252. // been expanded.
  1253. //
  1254. err = Refresh(!IsLeafNode() && IsExpanded());
  1255. if (err.Succeeded() && HasResultItems())
  1256. {
  1257. err = CleanResult(lpResultData);
  1258. if (err.Succeeded())
  1259. {
  1260. err = EnumerateResultPane(TRUE, lpHeader, lpResultData);
  1261. }
  1262. }
  1263. break;
  1264. case MMCN_SELECT:
  1265. {
  1266. //
  1267. // Item has been selected -- set verb states
  1268. //
  1269. ASSERT_PTR(lpConsole);
  1270. CComPtr<IConsoleVerb> lpConsoleVerb;
  1271. lpConsole->QueryConsoleVerb(&lpConsoleVerb);
  1272. ASSERT_PTR(lpConsoleVerb);
  1273. if (lpConsoleVerb)
  1274. {
  1275. err = SetStandardVerbs(lpConsoleVerb);
  1276. }
  1277. }
  1278. break;
  1279. case MMCN_RENAME:
  1280. err = RenameItem((LPOLESTR)param);
  1281. break;
  1282. case MMCN_DBLCLICK:
  1283. err = SelectScopeItem();
  1284. break;
  1285. case MMCN_COLUMNS_CHANGED:
  1286. err = ChangeVisibleColumns((MMC_VISIBLE_COLUMNS *)param);
  1287. break;
  1288. }
  1289. // TRACEEOLID("CIISObject::Notify -> " << ParseEvent(event) << " error " << err);
  1290. return err;
  1291. }
  1292. HRESULT
  1293. CIISObject::AddToScopePane(
  1294. IN HSCOPEITEM hRelativeID,
  1295. IN BOOL fChild,
  1296. IN BOOL fNext,
  1297. IN BOOL fIsParent
  1298. )
  1299. /*++
  1300. Routine Description:
  1301. Add current object to console namespace. Either as the last child
  1302. of a parent item, or right before/after sibling item
  1303. Arguments:
  1304. HSCOPEITEM hRelativeID : Relative scope ID (either parent or sibling)
  1305. BOOL fChild : If TRUE, object will be added as child of
  1306. hRelativeID
  1307. BOOL fNext : If fChild is TRUE, this parameter is ignored
  1308. If fChild is FALSE, and fNext is TRUE,
  1309. object will be added before hRelativeID
  1310. If fChild is FALSE, and fNext is FALSE,
  1311. object will be added after hRelativeID
  1312. BOOL fIsParent : If TRUE, it will add the [+] to indicate
  1313. that this node may have childnodes.
  1314. Return Value
  1315. HRESULT
  1316. --*/
  1317. {
  1318. ASSERT_PTR(_lpConsoleNameSpace);
  1319. DWORD dwMask = fChild ? SDI_PARENT : fNext ? SDI_NEXT : SDI_PREVIOUS;
  1320. SCOPEDATAITEM scopeDataItem;
  1321. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  1322. scopeDataItem.mask =
  1323. SDI_STR | SDI_IMAGE | SDI_CHILDREN | SDI_OPENIMAGE | SDI_PARAM | dwMask;
  1324. scopeDataItem.displayname = MMC_CALLBACK;
  1325. scopeDataItem.nImage = scopeDataItem.nOpenImage = MMC_IMAGECALLBACK;//QueryImage();
  1326. scopeDataItem.lParam = (LPARAM)this;
  1327. scopeDataItem.relativeID = hRelativeID;
  1328. scopeDataItem.cChildren = fIsParent ? 1 : 0;
  1329. HRESULT hr = _lpConsoleNameSpace->InsertItem(&scopeDataItem);
  1330. if (SUCCEEDED(hr))
  1331. {
  1332. //
  1333. // Cache the scope item handle
  1334. //
  1335. ASSERT(m_hScopeItem == NULL);
  1336. m_hScopeItem = scopeDataItem.ID;
  1337. // BUGBUG: looks like MMC_IMAGECALLBACK doesn't work in InsertItem. Update it here.
  1338. scopeDataItem.mask =
  1339. SDI_IMAGE | SDI_OPENIMAGE;
  1340. _lpConsoleNameSpace->SetItem(&scopeDataItem);
  1341. }
  1342. return hr;
  1343. }
  1344. HRESULT
  1345. CIISObject::AddToScopePaneSorted(
  1346. IN HSCOPEITEM hParent,
  1347. IN BOOL fIsParent
  1348. )
  1349. /*++
  1350. Routine Description:
  1351. Add current object to console namespace, sorted in its proper location.
  1352. Arguments:
  1353. HSCOPEITEM hParent : Parent object
  1354. BOOL fIsParent : If TRUE, it will add the [+] to indicate
  1355. that this node may have childnodes.
  1356. Return Value
  1357. HRESULT
  1358. --*/
  1359. {
  1360. ASSERT_PTR(_lpConsoleNameSpace);
  1361. //
  1362. // Find proper insertion point
  1363. //
  1364. BOOL fChild = TRUE;
  1365. HSCOPEITEM hChildItem = NULL;
  1366. CIISObject * pItem;
  1367. LONG_PTR cookie;
  1368. int nSwitch;
  1369. HRESULT hr = _lpConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  1370. while(SUCCEEDED(hr) && hChildItem)
  1371. {
  1372. //
  1373. // The cookie is really the IISObject, which is what we stuff
  1374. // in the lparam.
  1375. //
  1376. pItem = (CIISObject *)cookie;
  1377. ASSERT_PTR(pItem);
  1378. nSwitch = CompareScopeItem(pItem);
  1379. //
  1380. // Dups should be weeded out by now.
  1381. //
  1382. ASSERT(nSwitch != 0);
  1383. if (nSwitch < 0)
  1384. {
  1385. //
  1386. // Insert before this item
  1387. //
  1388. fChild = FALSE;
  1389. break;
  1390. }
  1391. //
  1392. // Advance to next child of same parent
  1393. //
  1394. hr = _lpConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1395. }
  1396. return AddToScopePane(hChildItem ? hChildItem : hParent, fChild, fIsParent);
  1397. }
  1398. /* virtual */
  1399. HRESULT
  1400. CIISObject::RemoveScopeItem()
  1401. /*++
  1402. Routine Description:
  1403. Remove the current item from the scope view. This method is virtual
  1404. to allow derived classes to do cleanup.
  1405. Arguments:
  1406. None
  1407. Return Value:
  1408. HRESULT
  1409. --*/
  1410. {
  1411. ASSERT_PTR(_lpConsoleNameSpace);
  1412. ASSERT(m_hScopeItem != NULL);
  1413. return _lpConsoleNameSpace->DeleteItem(m_hScopeItem, TRUE);
  1414. }
  1415. HRESULT
  1416. CIISObject::ChangeVisibleColumns(MMC_VISIBLE_COLUMNS * pCol)
  1417. {
  1418. return S_OK;
  1419. }
  1420. HRESULT
  1421. CIISObject::SelectScopeItem()
  1422. /*++
  1423. Routine Description:
  1424. Select this item in the scope view.
  1425. Arguments:
  1426. None
  1427. Return Value:
  1428. HRESULT
  1429. --*/
  1430. {
  1431. ASSERT_PTR(_lpConsoleNameSpace);
  1432. ASSERT_PTR(_lpConsole);
  1433. ASSERT(m_hScopeItem != NULL);
  1434. return _lpConsole->SelectScopeItem(m_hScopeItem);
  1435. }
  1436. HRESULT
  1437. CIISObject::SetCookie()
  1438. /*++
  1439. Routine Description:
  1440. Store the cookie (a pointer to the current CIISObject) in the
  1441. scope view object associated with it.
  1442. Arguments:
  1443. None
  1444. Return Value:
  1445. HRESULT
  1446. --*/
  1447. {
  1448. ASSERT_PTR(_lpConsoleNameSpace);
  1449. ASSERT(m_hScopeItem != NULL);
  1450. SCOPEDATAITEM scopeDataItem;
  1451. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  1452. scopeDataItem.mask = SDI_PARAM;
  1453. scopeDataItem.ID = m_hScopeItem;
  1454. scopeDataItem.lParam = (LPARAM)this;
  1455. return _lpConsoleNameSpace->SetItem(&scopeDataItem);
  1456. }
  1457. HRESULT
  1458. CIISObject::RefreshDisplay()
  1459. /*++
  1460. Routine Description:
  1461. Refresh the display parameters of the current node.
  1462. Arguments:
  1463. None
  1464. Return Value
  1465. HRESULT
  1466. Note: This does not fetch any configuration information from the metabase,
  1467. that's done in RefreshData();
  1468. --*/
  1469. {
  1470. HRESULT hr = S_OK;
  1471. if (m_hResultItem == 0)
  1472. {
  1473. SetToolBarStates();
  1474. ASSERT_PTR(_lpConsoleNameSpace);
  1475. ASSERT(m_hScopeItem != NULL);
  1476. SCOPEDATAITEM scopeDataItem;
  1477. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  1478. scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1479. scopeDataItem.displayname = MMC_CALLBACK;
  1480. scopeDataItem.nImage = scopeDataItem.nOpenImage = QueryImage();
  1481. scopeDataItem.ID = m_hScopeItem;
  1482. hr = _lpConsoleNameSpace->SetItem(&scopeDataItem);
  1483. }
  1484. else
  1485. {
  1486. RESULTDATAITEM ri;
  1487. ::ZeroMemory(&ri, sizeof(ri));
  1488. ri.itemID = m_hResultItem;
  1489. ri.mask = RDI_STR | RDI_IMAGE;
  1490. ri.str = MMC_CALLBACK;
  1491. ri.nImage = QueryImage();
  1492. CComQIPtr<IResultData, &IID_IResultData> pResultData(_lpConsole);
  1493. if (pResultData != NULL)
  1494. {
  1495. pResultData->SetItem(&ri);
  1496. }
  1497. }
  1498. ASSERT(SUCCEEDED(hr));
  1499. return hr;
  1500. }
  1501. /* virtual */
  1502. HRESULT
  1503. CIISObject::DeleteChildObjects(
  1504. IN HSCOPEITEM hParent
  1505. )
  1506. /*++
  1507. Routine Description:
  1508. Free the iisobject pointers belonging to the descendants of the current
  1509. nodes. This is in response to a MMCN_REMOVE_CHILDREN objects typically,
  1510. and does not remove the scope nodes from the scope view (for that see
  1511. RemoveChildren())
  1512. Arguments:
  1513. HSCOPEITEM hParent : Parent scope item handle
  1514. Return Value:
  1515. HRESULT
  1516. --*/
  1517. {
  1518. HSCOPEITEM hChildItem;
  1519. CIISObject * pItem;
  1520. LONG_PTR cookie;
  1521. ASSERT_PTR(_lpConsoleNameSpace);
  1522. HRESULT hr = _lpConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  1523. while(SUCCEEDED(hr) && hChildItem)
  1524. {
  1525. //
  1526. // The cookie is really the IISObject, which is what we stuff
  1527. // in the lparam.
  1528. //
  1529. pItem = (CIISObject *)cookie;
  1530. ASSERT_PTR(pItem);
  1531. if (pItem)
  1532. {
  1533. //
  1534. // Recursively commit infanticide
  1535. //
  1536. pItem->DeleteChildObjects(hChildItem);
  1537. delete pItem;
  1538. }
  1539. //
  1540. // Advance to next child of same parent
  1541. //
  1542. hr = _lpConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1543. }
  1544. //
  1545. // BUGBUG: For some reason GetNextItem() returns 1
  1546. // when no more child items exist, not a true HRESULT
  1547. //
  1548. return S_OK;
  1549. }
  1550. /*virtual*/
  1551. HRESULT
  1552. CIISObject::DeleteNode(IResultData * pResult)
  1553. {
  1554. ASSERT(IsDeletable());
  1555. return S_OK;
  1556. }
  1557. /* virtual */
  1558. HRESULT
  1559. CIISObject::RemoveChildren(
  1560. IN HSCOPEITEM hParent
  1561. )
  1562. /*++
  1563. Routine Description:
  1564. Similar to DeleteChildObjects() this method will actually remove
  1565. the child nodes from the scope view.
  1566. Arguments:
  1567. HSCOPEITEM hParent : Parent scope item handle
  1568. Return Value:
  1569. HRESULT
  1570. --*/
  1571. {
  1572. HSCOPEITEM hChildItem, hItem;
  1573. CIISObject * pItem;
  1574. LONG_PTR cookie;
  1575. ASSERT_PTR(_lpConsoleNameSpace);
  1576. HRESULT hr = _lpConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  1577. while(SUCCEEDED(hr) && hChildItem)
  1578. {
  1579. //
  1580. // The cookie is really the IISObject, which is what we stuff
  1581. // in the lparam.
  1582. //
  1583. pItem = (CIISObject *)cookie;
  1584. ASSERT_PTR(pItem);
  1585. hItem = pItem ? hChildItem : NULL;
  1586. //
  1587. // Determine next sibling before killing current sibling
  1588. //
  1589. hr = _lpConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1590. //
  1591. // Now delete the current item from the tree
  1592. //
  1593. if (hItem)
  1594. {
  1595. hr = _lpConsoleNameSpace->DeleteItem(hItem, TRUE);
  1596. //
  1597. // ISSUE: Why doesn't DeleteItem above call some sort of
  1598. // notification so that I don't have to do this?
  1599. //
  1600. delete pItem;
  1601. }
  1602. }
  1603. //
  1604. // BUGBUG: For some reason GetNextItem() returns 1
  1605. // when no more child items exist, not a true HRESULT
  1606. //
  1607. return S_OK;
  1608. }
  1609. /* virtual */
  1610. HRESULT
  1611. CIISObject::EnumerateResultPane(
  1612. IN BOOL fExpand,
  1613. IN IHeaderCtrl * lpHeader,
  1614. IN IResultData * lpResultData
  1615. )
  1616. /*++
  1617. Routine Description:
  1618. Enumerate or destroy the result pane.
  1619. Arguments:
  1620. BOOL fExpand : TRUE to create the result view,
  1621. FALSE to destroy it
  1622. IHeaderCtrl * lpHeader : Header control
  1623. IResultData * pResultData : Result view
  1624. Return Value:
  1625. HRESULT
  1626. --*/
  1627. {
  1628. if (fExpand)
  1629. {
  1630. if (lpHeader != NULL)
  1631. {
  1632. ASSERT_READ_PTR(lpHeader);
  1633. //
  1634. // Build Result View for object of child type
  1635. //
  1636. InitializeChildHeaders(lpHeader);
  1637. }
  1638. }
  1639. else
  1640. {
  1641. //
  1642. // Destroy child result items
  1643. //
  1644. }
  1645. return S_OK;
  1646. }
  1647. /* virtual */
  1648. HRESULT
  1649. CIISObject::SetStandardVerbs(LPCONSOLEVERB lpConsoleVerb)
  1650. /*++
  1651. Routine Description:
  1652. Set the standard MMC verbs based on the this object type
  1653. and state.
  1654. Arguments:
  1655. LPCONSOLEVERB lpConsoleVerb : Console verb interface
  1656. Return Value:
  1657. HRESULT
  1658. --*/
  1659. {
  1660. CError err;
  1661. ASSERT_READ_PTR(lpConsoleVerb);
  1662. //
  1663. // Set enabled/disabled verb states
  1664. //
  1665. lpConsoleVerb->SetVerbState(MMC_VERB_COPY, HIDDEN, TRUE);
  1666. lpConsoleVerb->SetVerbState(MMC_VERB_PASTE, HIDDEN, TRUE);
  1667. lpConsoleVerb->SetVerbState(MMC_VERB_PRINT, HIDDEN, TRUE);
  1668. lpConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, IsRenamable());
  1669. lpConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, IsDeletable());
  1670. lpConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, IsRefreshable());
  1671. lpConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, IsConfigurable());
  1672. //
  1673. // Set default verb
  1674. //
  1675. if (IsConfigurable())
  1676. {
  1677. lpConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  1678. }
  1679. if (IsOpenable())
  1680. {
  1681. lpConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  1682. }
  1683. return err;
  1684. }
  1685. HRESULT
  1686. CIISObject::FillCustomData(CLIPFORMAT cf, LPSTREAM pStream)
  1687. {
  1688. ASSERT(FALSE);
  1689. return E_FAIL;
  1690. }
  1691. HRESULT
  1692. CIISObject::FillData(CLIPFORMAT cf, LPSTREAM pStream)
  1693. {
  1694. HRESULT hr = CSnapInItemImpl<CIISObject>::FillData(cf, pStream);
  1695. if (hr == DV_E_CLIPFORMAT)
  1696. {
  1697. hr = FillCustomData(cf, pStream);
  1698. }
  1699. return hr;
  1700. }
  1701. //
  1702. // CIISRoot implementation
  1703. //
  1704. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1705. CIISRoot::CIISRoot() :
  1706. m_fRootAdded(FALSE),
  1707. m_pMachine(NULL)
  1708. {
  1709. VERIFY(m_bstrDisplayName.LoadString(IDS_ROOT_NODE));
  1710. }
  1711. CIISRoot::~CIISRoot()
  1712. {
  1713. }
  1714. /* virtual */
  1715. HRESULT
  1716. CIISRoot::EnumerateScopePane(
  1717. IN HSCOPEITEM hParent
  1718. )
  1719. /*++
  1720. Routine Description:
  1721. Enumerate scope child items of the root object -- i.e. machine nodes.
  1722. The machine nodes are expected to have been filled by via the IPersist
  1723. methods.
  1724. Arguments:
  1725. HSCOPEITEM hParent : Parent console handle
  1726. Return Value:
  1727. HRESULT
  1728. --*/
  1729. {
  1730. ASSERT_PTR(_lpConsoleNameSpace);
  1731. if (m_fIsExtension)
  1732. {
  1733. return EnumerateScopePaneExt(hParent);
  1734. }
  1735. //
  1736. // The CIISRoot item was not added in the conventional way.
  1737. // Cache the scope item handle, and set the cookie, so that
  1738. // GetRoot() will work for child objects.
  1739. //
  1740. ASSERT(m_hScopeItem == NULL);
  1741. m_hScopeItem = hParent;
  1742. CError err(SetCookie());
  1743. if (err.Failed())
  1744. {
  1745. //
  1746. // We're in deep trouble. For some reason, we couldn't
  1747. // store the CIISRoot cookie in the scope view. That
  1748. // means anything depending on fetching the root object
  1749. // isn't going to work. Cough up a hairball, and bail
  1750. // out now.
  1751. //
  1752. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1753. ASSERT_MSG("Unable to cache root object");
  1754. err.MessageBox();
  1755. return err;
  1756. }
  1757. //
  1758. // Expand the computer cache
  1759. //
  1760. if (m_scServers.IsEmpty())
  1761. {
  1762. //
  1763. // Try to create the local machine
  1764. //
  1765. CIISMachine * pLocal = new CIISMachine();
  1766. if (pLocal)
  1767. {
  1768. //
  1769. // Verify the machine object is created.
  1770. //
  1771. err = CIISMachine::VerifyMachine(pLocal);
  1772. if (err.Succeeded())
  1773. {
  1774. TRACEEOLID("Added local computer to cache: ");
  1775. m_scServers.Add(pLocal);
  1776. }
  1777. err.Reset();
  1778. }
  1779. }
  1780. //
  1781. // Add each cached server to the view...
  1782. //
  1783. CIISMachine * pMachine = m_scServers.GetFirst();
  1784. while (pMachine)
  1785. {
  1786. TRACEEOLID("Adding " << pMachine->QueryServerName() << " to scope pane");
  1787. err = pMachine->AddToScopePane(hParent);
  1788. if (err.Failed())
  1789. {
  1790. break;
  1791. }
  1792. pMachine = m_scServers.GetNext();
  1793. }
  1794. return err;
  1795. }
  1796. HRESULT
  1797. CIISRoot::EnumerateScopePaneExt(HSCOPEITEM hParent)
  1798. {
  1799. CError err;
  1800. ASSERT(m_scServers.IsEmpty());
  1801. if (!m_fRootAdded)
  1802. {
  1803. CComAuthInfo auth(m_ExtMachineName);
  1804. m_pMachine = new CIISMachine(&auth, this);
  1805. if (m_pMachine != NULL)
  1806. {
  1807. err = m_pMachine->AddToScopePane(hParent);
  1808. m_fRootAdded = err.Succeeded();
  1809. ASSERT(m_hScopeItem == NULL);
  1810. m_hScopeItem = m_pMachine->QueryScopeItem();
  1811. }
  1812. else
  1813. {
  1814. err = ERROR_NOT_ENOUGH_MEMORY;
  1815. }
  1816. }
  1817. return err;
  1818. }
  1819. HRESULT
  1820. ExtractComputerNameExt(
  1821. IDataObject * pDataObject,
  1822. CString& strComputer)
  1823. {
  1824. //
  1825. // Find the computer name from the ComputerManagement snapin
  1826. //
  1827. CLIPFORMAT CCF_MyComputMachineName = (CLIPFORMAT)RegisterClipboardFormat(MYCOMPUT_MACHINE_NAME);
  1828. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  1829. FORMATETC formatetc = {
  1830. CCF_MyComputMachineName, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  1831. };
  1832. //
  1833. // Allocate memory for the stream
  1834. //
  1835. int len = MAX_PATH;
  1836. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, len);
  1837. if(stgmedium.hGlobal == NULL)
  1838. return ERROR_NOT_ENOUGH_MEMORY;
  1839. HRESULT hr = pDataObject->GetDataHere(&formatetc, &stgmedium);
  1840. ASSERT(SUCCEEDED(hr));
  1841. //
  1842. // Get the computer name
  1843. //
  1844. strComputer = (LPTSTR)stgmedium.hGlobal;
  1845. GlobalFree(stgmedium.hGlobal);
  1846. return hr;
  1847. }
  1848. HRESULT
  1849. CIISRoot::InitAsExtension(IDataObject * pDataObject)
  1850. {
  1851. ASSERT(!m_fIsExtension);
  1852. m_fIsExtension = TRUE;
  1853. CString buf;
  1854. return ExtractComputerNameExt(pDataObject, m_ExtMachineName);
  1855. }
  1856. HRESULT
  1857. CIISRoot::ResetAsExtension()
  1858. {
  1859. ASSERT(m_fIsExtension);
  1860. CIISObject::m_fIsExtension = FALSE;
  1861. // Remove machine node from the scope
  1862. CError err = RemoveScopeItem();
  1863. m_hScopeItem = NULL;
  1864. // Delete machine object
  1865. delete m_pMachine;
  1866. m_pMachine = NULL;
  1867. m_fRootAdded = FALSE;
  1868. // Empty machine name
  1869. m_ExtMachineName.Empty();
  1870. // clean out
  1871. return err;
  1872. }
  1873. /* virtual */
  1874. HRESULT
  1875. CIISRoot::DeleteChildObjects(
  1876. IN HSCOPEITEM hParent
  1877. )
  1878. /*++
  1879. Routine Description:
  1880. We need this method for extension case. CompMgmt send this event when
  1881. snapin is connected to another machine. We should clean all computer relevant
  1882. stuff from here and the root, because after that we will get MMCN_EXPAND, as
  1883. at the very beginning of extension cycle.
  1884. Arguments:
  1885. HSCOPEITEM hParent : Parent scope item handle
  1886. Return Value:
  1887. HRESULT
  1888. --*/
  1889. {
  1890. HRESULT hr = CIISObject::DeleteChildObjects(m_hScopeItem);
  1891. if (SUCCEEDED(hr) && m_fIsExtension)
  1892. {
  1893. hr = ResetAsExtension();
  1894. }
  1895. return hr;
  1896. }
  1897. /* virtual */
  1898. void
  1899. CIISRoot::InitializeChildHeaders(
  1900. IN LPHEADERCTRL lpHeader
  1901. )
  1902. /*++
  1903. Routine Description:
  1904. Build result view for immediate descendant type
  1905. Arguments:
  1906. LPHEADERCTRL lpHeader : Header control
  1907. Return Value:
  1908. None
  1909. --*/
  1910. {
  1911. ASSERT(!m_fIsExtension);
  1912. CIISMachine::InitializeHeaders(lpHeader);
  1913. }
  1914. HRESULT
  1915. CIISRoot::FillCustomData(CLIPFORMAT cf, LPSTREAM pStream)
  1916. {
  1917. return E_FAIL;
  1918. }
  1919. /* virtual */
  1920. LPOLESTR
  1921. CIISRoot::GetResultPaneColInfo(int nCol)
  1922. {
  1923. if (nCol == 0)
  1924. {
  1925. return QueryDisplayName();
  1926. }
  1927. else if (nCol == 1)
  1928. {
  1929. }
  1930. else if (nCol == 2)
  1931. {
  1932. }
  1933. return OLESTR("");
  1934. }