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.

3052 lines
82 KiB

  1. /*++
  2. Copyright (c) 1994-2001 Microsoft Corporation
  3. Module Name :
  4. iisobj.cpp
  5. Abstract:
  6. IIS Object
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. #include "stdafx.h"
  15. #include "common.h"
  16. #include "inetprop.h"
  17. #include "InetMgrApp.h"
  18. #include "supdlgs.h"
  19. #include "connects.h"
  20. #include "iisobj.h"
  21. #include "ftpsht.h"
  22. #include "w3sht.h"
  23. #include "fltdlg.h"
  24. #include "util.h"
  25. #include "tracker.h"
  26. #ifdef _DEBUG
  27. #undef THIS_FILE
  28. static char BASED_CODE THIS_FILE[] = __FILE__;
  29. #endif
  30. #define new DEBUG_NEW
  31. extern CInetmgrApp theApp;
  32. extern INT g_iDebugOutputLevel;
  33. extern DWORD g_dwInetmgrParamFlags;
  34. // global list keep to track of open property sheets, project wide.
  35. CPropertySheetTracker g_OpenPropertySheetTracker;
  36. CWNetConnectionTrackerGlobal g_GlobalConnections;
  37. #if defined(_DEBUG) || DBG
  38. CDebug_IISObject g_Debug_IISObject;
  39. #endif
  40. #define GLOBAL_DEFAULT_HELP_PATH _T("::/htm/iiswelcome.htm")
  41. BOOL IsValidAddress(const void* lp, UINT nBytes, BOOL bReadWrite)
  42. {
  43. BOOL bRet = FALSE;
  44. // simple version using Win-32 APIs for pointer validation.
  45. if (lp == NULL)
  46. {
  47. return FALSE;
  48. }
  49. #ifndef _WIN64
  50. if (lp == (const void *) 0xfeeefeee){return FALSE;}
  51. if (lp == (const void *) 0xfefefefe){return FALSE;}
  52. if (lp == (const void *) 0xdddddddd){return FALSE;}
  53. if (lp == (const void *) 0x0badf00d){return FALSE;}
  54. if (lp == (const void *) 0xbaadf00d){return FALSE;}
  55. if (lp == (const void *) 0xbadf00d2){return FALSE;}
  56. if (lp == (const void *) 0xbaadf000){return FALSE;}
  57. if (lp == (const void *) 0xdeadbeef){return FALSE;}
  58. #else
  59. if (lp == (const void *) 0xfeeefeeefeeefeee){return FALSE;}
  60. if (lp == (const void *) 0xfefefefefefefefe){return FALSE;}
  61. if (lp == (const void *) 0xdddddddddddddddd){return FALSE;}
  62. if (lp == (const void *) 0x0badf00d0badf00d){return FALSE;}
  63. if (lp == (const void *) 0xbaadf00dbaadf00d){return FALSE;}
  64. if (lp == (const void *) 0xbadf00d2badf00d2){return FALSE;}
  65. if (lp == (const void *) 0xbaadf000baadf000){return FALSE;}
  66. if (lp == (const void *) 0xdeadbeefdeadbeef){return FALSE;}
  67. #endif
  68. // Check for valid read ptr
  69. // this will break into debugger on Chk build
  70. if (0 == IsBadReadPtr(lp, nBytes))
  71. {
  72. bRet = TRUE;
  73. }
  74. // Check for bad write ptr
  75. // this will break into debugger on Chk build
  76. if (TRUE == bRet && bReadWrite)
  77. {
  78. bRet = FALSE;
  79. if (0 == IsBadWritePtr((LPVOID)lp, nBytes))
  80. {
  81. bRet = TRUE;
  82. }
  83. }
  84. if (FALSE == bRet)
  85. {
  86. DebugTrace(_T("Bad Pointer:%p"),lp);
  87. }
  88. return bRet;
  89. }
  90. //
  91. // CInetMgrComponentData
  92. //
  93. static const GUID CInetMgrGUID_NODETYPE
  94. = {0xa841b6c2, 0x7577, 0x11d0, { 0xbb, 0x1f, 0x0, 0xa0, 0xc9, 0x22, 0xe7, 0x9c}};
  95. //BOOL CIISObject::m_fIsExtension = FALSE;
  96. #define TB_COLORMASK RGB(192,192,192) // Lt. Gray
  97. LPOLESTR
  98. CoTaskDupString(
  99. IN LPCOLESTR szString
  100. )
  101. /*++
  102. Routine Description:
  103. Helper function to duplicate a OLESTR
  104. Arguments:
  105. LPOLESTR szString : Source string
  106. Return Value:
  107. Pointer to the new string or NULL
  108. --*/
  109. {
  110. OLECHAR * lpString = (OLECHAR *)CoTaskMemAlloc(
  111. sizeof(OLECHAR)*(lstrlen(szString) + 1)
  112. );
  113. if (lpString != NULL)
  114. {
  115. lstrcpy(lpString, szString);
  116. }
  117. return lpString;
  118. }
  119. const GUID * CIISObject::m_NODETYPE = &CLSID_InetMgr; //&CInetMgrGUID_NODETYPE;
  120. const OLECHAR * CIISObject::m_SZNODETYPE = OLESTR("A841B6C2-7577-11d0-BB1F-00A0C922E79C");
  121. const CLSID * CIISObject::m_SNAPIN_CLASSID = &CLSID_InetMgr;
  122. //
  123. // Backup/restore taskpad gif resource
  124. //
  125. #define RES_TASKPAD_BACKUP _T("/img\\backup.gif")
  126. //
  127. // CIISObject implementation
  128. //
  129. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  130. //
  131. // Important! The array indices below must ALWAYS be one
  132. // less than the menu ID -- keep in sync with enumeration
  133. // in iisobj.h!!!!
  134. //
  135. /* static */ CIISObject::CONTEXTMENUITEM_RC CIISObject::_menuItemDefs[] =
  136. {
  137. //
  138. // Menu Commands in toolbar order
  139. //
  140. //nNameID nStatusID nDescriptionID lCmdID lInsertionPointID fSpecialFlags
  141. // lpszMouseOverBitmap lpszMouseOffBitmap lpszLanguageIndenpendentID
  142. { IDS_MENU_CONNECT, IDS_MENU_TT_CONNECT, -1, IDM_CONNECT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_CONNECT"), },
  143. { IDS_MENU_DISCOVER, IDS_MENU_TT_DISCOVER, -1, IDM_DISCOVER, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_DISCOVER"), },
  144. { IDS_MENU_START, IDS_MENU_TT_START, -1, IDM_START, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_START"), },
  145. { IDS_MENU_STOP, IDS_MENU_TT_STOP, -1, IDM_STOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_STOP"), },
  146. { IDS_MENU_PAUSE, IDS_MENU_TT_PAUSE, -1, IDM_PAUSE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_PAUSE"), },
  147. //
  148. // These are menu commands that do not show up in the toolbar
  149. //
  150. { IDS_MENU_EXPLORE, IDS_MENU_TT_EXPLORE, -1, IDM_EXPLORE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_EXPLORE"), },
  151. { IDS_MENU_OPEN, IDS_MENU_TT_OPEN, -1, IDM_OPEN, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_OPEN"), },
  152. { IDS_MENU_BROWSE, IDS_MENU_TT_BROWSE, -1, IDM_BROWSE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_BROWSE"), },
  153. { IDS_MENU_RECYCLE, IDS_MENU_TT_RECYCLE, -1, IDM_RECYCLE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_RECYCLE"), },
  154. { IDS_MENU_PERMISSION, IDS_MENU_TT_PERMISSION, -1, IDM_PERMISSION, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_PERMISSION"), },
  155. #if defined(_DEBUG) || DBG
  156. { IDS_MENU_IMPERSONATE, IDS_MENU_TT_IMPERSONATE, -1, IDM_IMPERSONATE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_IMPERSONATE"), },
  157. { IDS_MENU_REM_IMPERS, IDS_MENU_TT_REM_IMPERS, -1, IDM_REMOVE_IMPERSONATION, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_REM_IMPERS"), },
  158. #endif // _DEBUG
  159. { IDS_MENU_PROPERTIES, IDS_MENU_TT_PROPERTIES, -1, IDM_CONFIGURE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_PROPERTIES"), },
  160. { IDS_MENU_DISCONNECT, IDS_MENU_TT_DISCONNECT, -1, IDM_DISCONNECT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_DISCONNECT"), },
  161. { IDS_MENU_BACKUP, IDS_MENU_TT_BACKUP, IDS_MENU_TT_BACKUP, IDM_METABACKREST, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, NULL, NULL, _T("IDS_MENU_BACKUP"), },
  162. { IDS_MENU_SHUTDOWN_IIS, IDS_MENU_TT_SHUTDOWN_IIS, -1, IDM_SHUTDOWN, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, NULL, NULL, _T("IDS_MENU_SHUTDOWN_IIS"), },
  163. { IDS_MENU_SAVE_DATA, IDS_MENU_TT_SAVE_DATA, -1, IDM_SAVE_DATA, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, NULL, NULL, _T("IDS_MENU_SAVE_DATA"), },
  164. { 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, _T("IDS_MENU_NEWVROOT"), },
  165. { 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, _T("IDS_MENU_NEWINSTANCE"), },
  166. { 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, _T("IDS_MENU_NEWFTPSITE"), },
  167. { IDS_MENU_NEWFTPSITE_FROMFILE, IDS_MENU_TT_NEWFTPSITE_FROMFILE, -1, IDM_NEW_FTP_SITE_FROM_FILE,CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, NULL, NULL, _T("IDS_MENU_NEWFTPSITE_FROMFILE"), },
  168. { 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, _T("IDS_MENU_NEWFTPVDIR"), },
  169. { IDS_MENU_NEWFTPVDIR_FROMFILE, IDS_MENU_TT_NEWFTPVDIR_FROMFILE, -1, IDM_NEW_FTP_VDIR_FROM_FILE,CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, NULL, NULL, _T("IDS_MENU_NEWFTPVDIR_FROMFILE"), },
  170. { 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, _T("IDS_MENU_NEWWEBSITE"), },
  171. { IDS_MENU_NEWWEBSITE_FROMFILE, IDS_MENU_TT_NEWWEBSITE_FROMFILE, -1, IDM_NEW_WEB_SITE_FROM_FILE,CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, NULL, NULL, _T("IDS_MENU_NEWWEBSITE_FROMFILE"), },
  172. { 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, _T("IDS_MENU_NEWWEBVDIR"), },
  173. { IDS_MENU_NEWWEBVDIR_FROMFILE, IDS_MENU_TT_NEWWEBVDIR_FROMFILE, -1, IDM_NEW_WEB_VDIR_FROM_FILE,CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, NULL, NULL, _T("IDS_MENU_NEWWEBVDIR_FROMFILE"), },
  174. { 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, _T("IDS_MENU_NEWAPPPOOL"), },
  175. { IDS_MENU_NEWAPPPOOL_FROMFILE, IDS_MENU_TT_NEWAPPPOOL_FROMFILE, -1, IDM_NEW_APP_POOL_FROM_FILE,CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, NULL, NULL, _T("IDS_MENU_NEWAPPPOOL_FROMFILE"), },
  176. { IDS_MENU_TASKPAD, IDS_MENU_TT_TASKPAD, -1, IDM_VIEW_TASKPAD, CCM_INSERTIONPOINTID_PRIMARY_VIEW,0, NULL, NULL, _T("IDS_MENU_TASKPAD"), },
  177. { IDS_MENU_EXPORT_CONFIG_WIZARD, IDS_MENU_TT_EXPORT_CONFIG_WIZARD, -1, IDM_TASK_EXPORT_CONFIG_WIZARD, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, NULL, NULL, _T("IDS_MENU_EXPORT_CONFIG_WIZARD"), },
  178. { IDS_MENU_WEBEXT_CONTAINER_ADD1, IDS_MENU_TT_WEBEXT_CONTAINER_ADD1, -1, IDM_WEBEXT_CONTAINER_ADD1, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_WEBEXT_CONTAINER_ADD1"), },
  179. { IDS_MENU_WEBEXT_CONTAINER_ADD2, IDS_MENU_TT_WEBEXT_CONTAINER_ADD2, -1, IDM_WEBEXT_CONTAINER_ADD2, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_WEBEXT_CONTAINER_ADD2"), },
  180. { IDS_MENU_WEBEXT_CONTAINER_PROHIBIT_ALL, IDS_MENU_TT_WEBEXT_CONTAINER_PROHIBIT_ALL, -1, IDM_WEBEXT_CONTAINER_PROHIBIT_ALL, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_WEBEXT_CONTAINER_PROHIBIT_ALL"), },
  181. { IDS_MENU_WEBEXT_ALLOW, IDS_MENU_TT_WEBEXT_ALLOW, -1, IDM_WEBEXT_ALLOW, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_WEBEXT_ALLOW"), },
  182. { IDS_MENU_WEBEXT_PROHIBIT, IDS_MENU_TT_WEBEXT_PROHIBIT, -1, IDM_WEBEXT_PROHIBIT, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_WEBEXT_PROHIBIT"), },
  183. // { IDS_MENU_SERVICE_START, IDS_MENU_TT_SERVICE_START, -1, IDM_SERVICE_START, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_SERVICE_START"), },
  184. // { IDS_MENU_SERVICE_STOP, IDS_MENU_TT_SERVICE_STOP, -1, IDM_SERVICE_STOP, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_SERVICE_STOP"), },
  185. // { IDS_MENU_SERVICE_ENABLE, IDS_MENU_TT_SERVICE_ENABLE, -1, IDM_SERVICE_ENABLE, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, NULL, NULL, _T("IDS_MENU_SERVICE_ENABLE"), },
  186. };
  187. /* static */ CComBSTR CIISObject::_bstrResult;
  188. /* static */ CComBSTR CIISObject::_bstrLocalHost = _T("localhost");
  189. /* static */ CComPtr<IComponent> CIISObject::_lpComponent = NULL;
  190. /* static */ CComPtr<IComponentData> CIISObject::_lpComponentData = NULL;
  191. /* static */ IToolbar * CIISObject::_lpToolBar = NULL;
  192. /* static */
  193. HRESULT
  194. CIISObject::SetImageList(
  195. IN LPIMAGELIST lpImageList
  196. )
  197. /*++
  198. Routine Description:
  199. Set the image list
  200. Arguments:
  201. LPIMAGELIST lpImageList
  202. Return Value:
  203. HRESULT
  204. --*/
  205. {
  206. HBITMAP hImage16 = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_INETMGR16));
  207. HBITMAP hImage32 = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_INETMGR32));
  208. ASSERT(hImage16 != NULL);
  209. ASSERT(hImage32 != NULL);
  210. HRESULT hr = S_OK;
  211. if (hImage16 != NULL && hImage32 != NULL)
  212. {
  213. if (S_OK != lpImageList->ImageListSetStrip(
  214. (LONG_PTR *)hImage16,
  215. (LONG_PTR *)hImage32,
  216. 0,
  217. RGB_BK_IMAGES
  218. ))
  219. {
  220. hr = E_UNEXPECTED;
  221. }
  222. ::DeleteObject(hImage16);
  223. ::DeleteObject(hImage32);
  224. }
  225. else
  226. {
  227. hr = E_UNEXPECTED;
  228. }
  229. return hr;
  230. }
  231. IConsoleNameSpace * CIISObject::GetConsoleNameSpace()
  232. {
  233. if (!_lpConsoleNameSpace)
  234. {
  235. // Our Machine node should this info for us.
  236. CIISObject * pMyMachine = GetMachineObject();
  237. if (pMyMachine)
  238. {
  239. if (pMyMachine != this)
  240. {
  241. _lpConsoleNameSpace = pMyMachine->GetConsoleNameSpace();
  242. }
  243. }
  244. }
  245. ASSERT(_lpConsoleNameSpace);
  246. return _lpConsoleNameSpace;
  247. }
  248. IConsole * CIISObject::GetConsole()
  249. {
  250. if (!_lpConsole)
  251. {
  252. // Our Machine node should this info for us.
  253. CIISObject * pMyMachine = GetMachineObject();
  254. if (pMyMachine)
  255. {
  256. if (pMyMachine != this)
  257. {
  258. _lpConsole = pMyMachine->GetConsole();
  259. }
  260. }
  261. }
  262. ASSERT(_lpConsole);
  263. return _lpConsole;
  264. }
  265. /* static */
  266. void
  267. CIISObject::BuildResultView(
  268. IN LPHEADERCTRL lpHeader,
  269. IN int cColumns,
  270. IN int * pnIDS,
  271. IN int * pnWidths
  272. )
  273. /*++
  274. Routine Description:
  275. Build the result view columns.
  276. Routine Description:
  277. LPHEADERCTRL lpHeader : Header control
  278. int cColumns : Number of columns
  279. int * pnIDS : Array of column header strings
  280. int * pnWidths : Array of column widths
  281. Routine Description:
  282. None
  283. --*/
  284. {
  285. ASSERT_READ_PTR(lpHeader);
  286. CComBSTR bstr;
  287. for (int n = 0; n < cColumns; ++n)
  288. {
  289. if (pnIDS[n] != 0)
  290. {
  291. VERIFY(bstr.LoadString(pnIDS[n]));
  292. lpHeader->InsertColumn(n, bstr, LVCFMT_LEFT, pnWidths[n]);
  293. }
  294. }
  295. }
  296. /* static */
  297. CWnd *
  298. CIISObject::GetMainWindow(IConsole * pConsole)
  299. /*++
  300. Routine Description:
  301. Get a pointer to main window object.
  302. Arguments:
  303. None
  304. Return Value:
  305. Pointer to main window object. This object is temporary and should not be
  306. cached.
  307. --*/
  308. {
  309. HWND hWnd;
  310. CWnd * pWnd = NULL;
  311. if (pConsole)
  312. {
  313. HRESULT hr = pConsole->GetMainWindow(&hWnd);
  314. if (SUCCEEDED(hr))
  315. {
  316. pWnd = CWnd::FromHandle(hWnd);
  317. }
  318. }
  319. return pWnd;
  320. }
  321. /* static */
  322. HRESULT
  323. CIISObject::AddMMCPage(
  324. IN LPPROPERTYSHEETCALLBACK lpProvider,
  325. IN CPropertyPage * pPage
  326. )
  327. /*++
  328. Routine Description:
  329. Add MMC page to providers sheet.
  330. Arguments:
  331. LPPROPERTYSHEETCALLBACK lpProvider : Property sheet provider
  332. CPropertyPage * pPage : Property page to add
  333. Return:
  334. HRESULT
  335. --*/
  336. {
  337. ASSERT_READ_PTR(pPage);
  338. if (pPage == NULL)
  339. {
  340. TRACEEOLID("NULL page pointer passed to AddMMCPage");
  341. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  342. }
  343. PROPSHEETPAGE_LATEST pspLatest;
  344. ZeroMemory(&pspLatest, sizeof(PROPSHEETPAGE_LATEST));
  345. CopyMemory (&pspLatest, &pPage->m_psp, pPage->m_psp.dwSize);
  346. pspLatest.dwSize = sizeof(pspLatest);
  347. //
  348. // MFC Bug work-around.
  349. //
  350. MMCPropPageCallback(&pspLatest);
  351. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pspLatest);
  352. if (hPage == NULL)
  353. {
  354. return E_UNEXPECTED;
  355. }
  356. return lpProvider->AddPage(hPage);
  357. }
  358. HRESULT
  359. CIISObject::GetProperty(
  360. LPDATAOBJECT pDataObject,
  361. BSTR szPropertyName,
  362. BSTR* pbstrProperty)
  363. {
  364. CString strProperty;
  365. if (!_wcsicmp(L"CCF_HTML_DETAILS",szPropertyName))
  366. {
  367. // return back html/javascript into strProperty
  368. //*pbstrProperty = ::SysAllocString(strProperty);
  369. }
  370. else if (!_wcsicmp(L"CCF_DESCRIPTION",szPropertyName))
  371. {
  372. // Display data in Description field...
  373. }
  374. else
  375. {
  376. return S_FALSE; // unknown strPropertyName
  377. }
  378. return S_OK;
  379. }
  380. CIISObject::CIISObject()
  381. : m_hScopeItem(NULL),
  382. m_use_count(0),
  383. m_hResultItem(0),
  384. m_fSkipEnumResult(FALSE),
  385. m_fFlaggedForDeletion(FALSE),
  386. m_hwnd(NULL),
  387. m_ppHandle(NULL)
  388. {
  389. m_fIsExtension = FALSE;
  390. #if defined(_DEBUG) || DBG
  391. // Add to the global list of CIISObjects
  392. // and keep track of it.
  393. g_Debug_IISObject.Add(this);
  394. #endif
  395. }
  396. CIISObject::~CIISObject()
  397. {
  398. #if defined(_DEBUG) || DBG
  399. // Add to the global list of CIISObjects
  400. // and keep track of it.
  401. g_Debug_IISObject.Del(this);
  402. #endif
  403. }
  404. /* virtual */
  405. HRESULT
  406. CIISObject::ControlbarNotify(
  407. IN MMC_NOTIFY_TYPE event,
  408. IN LPARAM arg,
  409. IN LPARAM param
  410. )
  411. /*++
  412. Routine Description:
  413. Handle control bar notification messages, such as select or click.
  414. Arguments:
  415. MMC_NOTIFY_TYPE event : Notification message
  416. long arg : Message specific argument
  417. long param : Message specific parameter
  418. Return Value:
  419. HRESULT
  420. --*/
  421. {
  422. BOOL fSelect = (BOOL)HIWORD(arg);
  423. BOOL fScope = (BOOL)LOWORD(arg);
  424. HRESULT hr = S_OK;
  425. switch(event)
  426. {
  427. case MMCN_SELECT:
  428. {
  429. //
  430. // Handle selection of this node by attaching the toolbar
  431. // and enabling/disabling specific buttons
  432. //
  433. _lpToolBar = (IToolbar *) (* (LPUNKNOWN *) param);
  434. if (_lpToolBar)
  435. {
  436. SetToolBarStates(_lpToolBar);
  437. }
  438. }
  439. break;
  440. case MMCN_BTN_CLICK:
  441. //
  442. // Handle button-click by passing the command ID of the
  443. // button to the command handler
  444. //
  445. hr = Command((long)param, NULL, fScope ? CCT_SCOPE : CCT_RESULT);
  446. break;
  447. case MMCN_HELP:
  448. break;
  449. default:
  450. ASSERT_MSG("Invalid control bar notification received");
  451. };
  452. return hr;
  453. }
  454. /* virtual */
  455. HRESULT
  456. CIISObject::SetToolBarStates(CComPtr<IToolbar> lpToolBar)
  457. /*++
  458. Routine Description:
  459. Set the toolbar states depending on the state of this object
  460. Arguments:
  461. None
  462. Return Value:
  463. HRESULT
  464. --*/
  465. {
  466. if (lpToolBar)
  467. {
  468. lpToolBar->SetButtonState(IDM_CONNECT, ENABLED, IsConnectable());
  469. lpToolBar->SetButtonState(IDM_PAUSE, ENABLED, IsPausable());
  470. lpToolBar->SetButtonState(IDM_START, ENABLED, IsStartable());
  471. lpToolBar->SetButtonState(IDM_STOP, ENABLED, IsStoppable());
  472. lpToolBar->SetButtonState(IDM_PAUSE, BUTTONPRESSED, IsPaused());
  473. }
  474. return S_OK;
  475. }
  476. HRESULT
  477. CIISObject::GetScopePaneInfo(
  478. IN OUT LPSCOPEDATAITEM lpScopeDataItem
  479. )
  480. /*++
  481. Routine Description:
  482. Return information about scope pane.
  483. Arguments:
  484. LPSCOPEDATAITEM lpScopeDataItem : Scope data item
  485. Return Value:
  486. HRESULT
  487. --*/
  488. {
  489. ASSERT_READ_WRITE_PTR(lpScopeDataItem);
  490. if (lpScopeDataItem->mask & SDI_STR)
  491. {
  492. lpScopeDataItem->displayname = QueryDisplayName();
  493. }
  494. if (lpScopeDataItem->mask & SDI_IMAGE)
  495. {
  496. lpScopeDataItem->nImage = QueryImage();
  497. }
  498. if (lpScopeDataItem->mask & SDI_OPENIMAGE)
  499. {
  500. lpScopeDataItem->nOpenImage = QueryImage();
  501. }
  502. if (lpScopeDataItem->mask & SDI_PARAM)
  503. {
  504. lpScopeDataItem->lParam = (LPARAM)this;
  505. }
  506. if (lpScopeDataItem->mask & SDI_STATE)
  507. {
  508. //
  509. // BUGBUG: Wotz all this then?
  510. //
  511. ASSERT_MSG("State requested");
  512. lpScopeDataItem->nState = 0;
  513. }
  514. //
  515. // TODO : Add code for SDI_CHILDREN
  516. //
  517. return S_OK;
  518. }
  519. /* virtual */
  520. int
  521. CIISObject::CompareScopeItem(
  522. IN CIISObject * pObject
  523. )
  524. /*++
  525. Routine Description:
  526. Standard comparison method to compare lexically on display name.
  527. Derived classes should override if anything other than lexical
  528. sort on the display name is required.
  529. Arguments:
  530. CIISObject * pObject : Object to compare against
  531. Return Value:
  532. 0 if the two objects are identical
  533. <0 if this object is less than pObject
  534. >0 if this object is greater than pObject
  535. --*/
  536. {
  537. ASSERT_READ_PTR(pObject);
  538. //
  539. // First criteria is object type
  540. //
  541. int n1 = QuerySortWeight();
  542. int n2 = pObject->QuerySortWeight();
  543. if (n1 != n2)
  544. {
  545. return n1 - n2;
  546. }
  547. //
  548. // Else sort lexically on the display name.
  549. //
  550. return ::lstrcmpi(QueryDisplayName(), pObject->QueryDisplayName());
  551. }
  552. /* virtual */
  553. int
  554. CIISObject::CompareResultPaneItem(
  555. IN CIISObject * pObject,
  556. IN int nCol
  557. )
  558. /*++
  559. Routine Description:
  560. Compare two CIISObjects on sort item criteria
  561. Arguments:
  562. CIISObject * pObject : Object to compare against
  563. int nCol : Column number to sort on
  564. Return Value:
  565. 0 if the two objects are identical
  566. <0 if this object is less than pObject
  567. >0 if this object is greater than pObject
  568. --*/
  569. {
  570. ASSERT_READ_PTR(pObject);
  571. if (nCol == 0)
  572. {
  573. return CompareScopeItem(pObject);
  574. }
  575. //
  576. // First criteria is object type
  577. //
  578. int n1 = QuerySortWeight();
  579. int n2 = pObject->QuerySortWeight();
  580. if (n1 != n2)
  581. {
  582. return n1 - n2;
  583. }
  584. //
  585. // Sort lexically on column text
  586. //
  587. return ::lstrcmpi(
  588. GetResultPaneColInfo(nCol),
  589. pObject->GetResultPaneColInfo(nCol)
  590. );
  591. }
  592. HRESULT
  593. CIISObject::GetResultPaneInfo(LPRESULTDATAITEM lpResultDataItem)
  594. /*++
  595. Routine Description:
  596. Get information about result pane item
  597. Arguments:
  598. LPRESULTDATAITEM lpResultDataItem : Result data item
  599. Return Value:
  600. HRESULT
  601. --*/
  602. {
  603. ASSERT_READ_WRITE_PTR(lpResultDataItem);
  604. if (lpResultDataItem->mask & RDI_STR)
  605. {
  606. lpResultDataItem->str = GetResultPaneColInfo(lpResultDataItem->nCol);
  607. }
  608. if (lpResultDataItem->mask & RDI_IMAGE)
  609. {
  610. lpResultDataItem->nImage = QueryImage();
  611. }
  612. if (lpResultDataItem->mask & RDI_PARAM)
  613. {
  614. lpResultDataItem->lParam = (LPARAM)this;
  615. }
  616. if (lpResultDataItem->mask & RDI_INDEX)
  617. {
  618. //
  619. // BUGBUG: Wotz all this then?
  620. //
  621. ASSERT_MSG("INDEX???");
  622. lpResultDataItem->nIndex = 0;
  623. }
  624. return S_OK;
  625. }
  626. /* virtual */
  627. LPOLESTR
  628. CIISObject::GetResultPaneColInfo(int nCol)
  629. /*++
  630. Routine Description:
  631. Return result pane string for the given column number
  632. Arguments:
  633. int nCol : Column number
  634. Return Value:
  635. String
  636. --*/
  637. {
  638. if (nCol == 0)
  639. {
  640. return QueryDisplayName();
  641. }
  642. ASSERT_MSG("Override GetResultPaneColInfo");
  643. return OLESTR("Override GetResultPaneColInfo");
  644. }
  645. /* virtual */
  646. HRESULT
  647. CIISObject::GetResultViewType(
  648. OUT LPOLESTR * lplpViewType,
  649. OUT long * lpViewOptions
  650. )
  651. /*++
  652. Routine Description:
  653. Tell MMC what our result view looks like
  654. Arguments:
  655. BSTR * lplpViewType : Return view type here
  656. long * lpViewOptions : View options
  657. Return Value:
  658. S_FALSE to use default view type, S_OK indicates the
  659. view type is returned in *ppViewType
  660. --*/
  661. {
  662. *lplpViewType = NULL;
  663. *lpViewOptions = MMC_VIEW_OPTIONS_USEFONTLINKING;
  664. //
  665. // Default View
  666. //
  667. return S_FALSE;
  668. }
  669. /* virtual */
  670. HRESULT
  671. CIISObject::CreatePropertyPages(
  672. IN LPPROPERTYSHEETCALLBACK lpProvider,
  673. IN LONG_PTR handle,
  674. IN IUnknown * pUnk,
  675. IN DATA_OBJECT_TYPES type
  676. )
  677. /*++
  678. Routine Description:
  679. Create the property pages for the given object
  680. Arguments:
  681. LPPROPERTYSHEETCALLBACK lpProvider : Provider
  682. LONG_PTR handle : Handle.
  683. IUnknown * pUnk,
  684. DATA_OBJECT_TYPES type
  685. Return Value:
  686. HRESULT
  687. --*/
  688. {
  689. CComQIPtr<IPropertySheetProvider, &IID_IPropertySheetProvider> sp(GetConsole());
  690. CError err = sp->FindPropertySheet(
  691. reinterpret_cast<MMC_COOKIE>(this),
  692. 0,
  693. (LPDATAOBJECT)this);
  694. if (err == S_OK)
  695. {
  696. return S_FALSE;
  697. }
  698. return S_OK;
  699. }
  700. /* virtual */
  701. HRESULT
  702. CIISObject::QueryPagesFor(
  703. IN DATA_OBJECT_TYPES type
  704. )
  705. /*++
  706. Routine Description:
  707. Check to see if a property sheet should be brought up for this data
  708. object
  709. Arguments:
  710. DATA_OBJECT_TYPES type : Data object type
  711. Return Value:
  712. S_OK, if properties may be brought up for this item, S_FALSE otherwise
  713. --*/
  714. {
  715. return IsConfigurable() ? S_OK : S_FALSE;
  716. }
  717. /* virtual */
  718. CIISRoot *
  719. CIISObject::GetRoot()
  720. /*++
  721. Routine Description:
  722. Get the CIISRoot object of this tree.
  723. Arguments:
  724. None
  725. Return Value:
  726. CIISRoot * or NULL
  727. --*/
  728. {
  729. ASSERT(!m_fIsExtension);
  730. LONG_PTR cookie;
  731. HSCOPEITEM hParent;
  732. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  733. HRESULT hr = pConsoleNameSpace->GetParentItem(m_hScopeItem, &hParent, &cookie);
  734. if (SUCCEEDED(hr))
  735. {
  736. CIISMBNode * pNode = (CIISMBNode *)cookie;
  737. ASSERT_PTR(pNode);
  738. ASSERT_PTR(hParent);
  739. if (pNode)
  740. {
  741. return pNode->GetRoot();
  742. }
  743. }
  744. ASSERT_MSG("Unable to find CIISRoot object!");
  745. return NULL;
  746. }
  747. HRESULT
  748. CIISObject::AskForAndAddMachine()
  749. /*++
  750. Routine Description:
  751. Ask user to add a computer name, verify the computer is alive, and add it to
  752. the list.
  753. Arguments:
  754. None
  755. Return Value:
  756. HRESULT
  757. --*/
  758. {
  759. CError err;
  760. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  761. // ensure the dialog gets themed
  762. CThemeContextActivator activator(theApp.GetFusionInitHandle());
  763. ConnectServerDlg dlg(GetConsoleNameSpace(),GetConsole(),GetMainWindow(GetConsole()));
  764. if (dlg.DoModal() == IDOK)
  765. {
  766. CIISMachine * pMachine = dlg.GetMachine();
  767. //
  768. // The machine object we get from the dialog
  769. // is guaranteed to be good and valid.
  770. //
  771. ASSERT_PTR(pMachine);
  772. ASSERT(pMachine->HasInterface());
  773. CIISRoot * pRoot = GetRoot();
  774. if (pRoot)
  775. {
  776. pMachine->SetConsoleData(pRoot->GetConsoleNameSpace(),pRoot->GetConsole());
  777. //
  778. // Add new machine object as child of the IIS root
  779. // object.
  780. //
  781. if (pRoot->m_scServers.Add(pMachine))
  782. {
  783. pMachine->AddRef();
  784. err = pMachine->AddToScopePaneSorted(pRoot->QueryScopeItem());
  785. if (err.Succeeded())
  786. {
  787. //
  788. // Select the item in the scope view
  789. //
  790. err = pMachine->SelectScopeItem();
  791. }
  792. }
  793. else
  794. {
  795. //
  796. // Duplicate machine already in cache. Find it and select
  797. // it.
  798. //
  799. TRACEEOLID("Machine already in scope view.");
  800. CIISObject * pIdentical = pRoot->FindIdenticalScopePaneItem(pMachine);
  801. //
  802. // Duplicate must exist!
  803. //
  804. ASSERT_READ_PTR(pIdentical);
  805. if (pIdentical)
  806. {
  807. err = pIdentical->SelectScopeItem();
  808. }
  809. pMachine->Release();
  810. }
  811. }
  812. }
  813. return err;
  814. }
  815. /* static */
  816. HRESULT
  817. CIISObject::AddMenuItemByCommand(
  818. IN LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  819. IN LONG lCmdID,
  820. IN LONG fFlags
  821. )
  822. /*++
  823. Routine Description:
  824. Add menu item by command
  825. Arguments:
  826. LPCONTEXTMENUCALLBACK lpContextMenuCallback : Callback pointer
  827. LONG lCmdID : Command ID
  828. LONG fFlags : Flags
  829. Return Value:
  830. HRESULT
  831. --*/
  832. {
  833. BOOL bAdded = FALSE;
  834. ASSERT_READ_PTR(lpContextMenuCallback);
  835. //
  836. // Offset 1 menu commands
  837. //
  838. LONG l = lCmdID -1;
  839. CComBSTR strName;
  840. CComBSTR strStatus;
  841. VERIFY(strName.LoadString(_menuItemDefs[l].nNameID));
  842. VERIFY(strStatus.LoadString(_menuItemDefs[l].nStatusID));
  843. // Try to use IContextMenuCallback2 because of language independent string
  844. CONTEXTMENUITEM2 contextmenuitem;
  845. IContextMenuCallback2* pIContextMenuCallback2 = NULL;
  846. HRESULT hr = lpContextMenuCallback->QueryInterface(IID_IContextMenuCallback2, (void**)&pIContextMenuCallback2);
  847. if(hr == S_OK && pIContextMenuCallback2 != NULL)
  848. {
  849. ::ZeroMemory( &contextmenuitem, sizeof(contextmenuitem) );
  850. contextmenuitem.strName = strName;
  851. contextmenuitem.strStatusBarText = strStatus;
  852. contextmenuitem.lCommandID = _menuItemDefs[l].lCmdID;
  853. contextmenuitem.lInsertionPointID = _menuItemDefs[l].lInsertionPointID;
  854. contextmenuitem.fFlags = fFlags;
  855. contextmenuitem.fSpecialFlags = _menuItemDefs[l].fSpecialFlags;
  856. // Here is the language independent ID
  857. // We must use this to refer to the Menu item otherwise we will have problems in every language (mainly far east (FE) languages.
  858. contextmenuitem.strLanguageIndependentName = (LPWSTR) _menuItemDefs[l].lpszLanguageIndenpendentID;
  859. hr = pIContextMenuCallback2->AddItem( &contextmenuitem );
  860. if( hr == S_OK)
  861. {
  862. bAdded = TRUE;
  863. }
  864. pIContextMenuCallback2->Release();
  865. pIContextMenuCallback2 = NULL;
  866. }
  867. if (!bAdded)
  868. {
  869. CONTEXTMENUITEM cmi;
  870. cmi.strName = strName;
  871. cmi.strStatusBarText = strStatus;
  872. cmi.lCommandID = _menuItemDefs[l].lCmdID;
  873. cmi.lInsertionPointID = _menuItemDefs[l].lInsertionPointID;
  874. cmi.fFlags = fFlags;
  875. cmi.fSpecialFlags = _menuItemDefs[l].fSpecialFlags;
  876. hr = lpContextMenuCallback->AddItem(&cmi);
  877. }
  878. return hr;
  879. }
  880. /* static */
  881. HRESULT
  882. CIISObject::AddMenuSeparator(
  883. IN LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  884. IN LONG lInsertionPointID
  885. )
  886. /*++
  887. Routine Description:
  888. Add a separator to the given insertion point menu.
  889. Arguments:
  890. LPCONTEXTMENUCALLBACK lpContextMenuCallback : Callback pointer
  891. LONG lInsertionPointID : Insertion point menu id.
  892. Return Value:
  893. HRESULT
  894. --*/
  895. {
  896. ASSERT_READ_PTR(lpContextMenuCallback);
  897. CONTEXTMENUITEM menuSep =
  898. {
  899. NULL,
  900. NULL,
  901. -1,
  902. lInsertionPointID,
  903. 0,
  904. CCM_SPECIAL_SEPARATOR
  905. };
  906. return lpContextMenuCallback->AddItem(&menuSep);
  907. }
  908. BOOL
  909. CIISObject::IsExpanded() const
  910. /*++
  911. Routine Description:
  912. Determine if this object has been expanded.
  913. Arguments:
  914. None
  915. Return Value:
  916. TRUE if the node has been expanded,
  917. FALSE if it has not.
  918. --*/
  919. {
  920. ASSERT(m_hScopeItem != NULL);
  921. SCOPEDATAITEM scopeDataItem;
  922. CIISObject * ThisConst = (CIISObject *)this;
  923. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *) ThisConst->GetConsoleNameSpace();
  924. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  925. scopeDataItem.mask = SDI_STATE;
  926. scopeDataItem.ID = m_hScopeItem;
  927. HRESULT hr = pConsoleNameSpace->GetItem(&scopeDataItem);
  928. return SUCCEEDED(hr) &&
  929. scopeDataItem.nState == MMC_SCOPE_ITEM_STATE_EXPANDEDONCE;
  930. }
  931. CIISObject *
  932. CIISObject::FindIdenticalScopePaneItem(
  933. IN CIISObject * pObject
  934. )
  935. /*++
  936. Routine Description:
  937. Find CIISObject in the scope view. The scope view is assumed
  938. to be sorted.
  939. Arguments:
  940. CIISObject * pObject : Item to search for
  941. Return Value:
  942. Pointer to iis object, or NULL if the item was not found
  943. Notes:
  944. Note that any item with a 0 comparison value is returned, not
  945. necessarily the identical CIISObject.
  946. --*/
  947. {
  948. ASSERT(m_hScopeItem != NULL);
  949. //
  950. // Find proper insertion point
  951. //
  952. HSCOPEITEM hChildItem = NULL;
  953. CIISObject * pReturn = NULL;
  954. CIISObject * pItem;
  955. LONG_PTR cookie;
  956. int nSwitch;
  957. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  958. HRESULT hr = pConsoleNameSpace->GetChildItem(
  959. m_hScopeItem, &hChildItem, &cookie);
  960. while(SUCCEEDED(hr) && hChildItem)
  961. {
  962. //
  963. // The cookie is really the IISObject, which is what we stuff
  964. // in the lparam.
  965. //
  966. pItem = (CIISObject *)cookie;
  967. ASSERT_PTR(pItem);
  968. nSwitch = pItem->CompareScopeItem(pObject);
  969. if (nSwitch == 0)
  970. {
  971. //
  972. // Found it.
  973. //
  974. pReturn = pItem;
  975. }
  976. if (nSwitch > 0)
  977. {
  978. //
  979. // Should have found it by now.
  980. //
  981. break;
  982. }
  983. //
  984. // Advance to next child of same parent
  985. //
  986. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  987. }
  988. return pReturn;
  989. }
  990. /* virtual */
  991. HRESULT
  992. CIISObject::AddMenuItems(
  993. IN LPCONTEXTMENUCALLBACK lpContextMenuCallback,
  994. IN OUT long * pInsertionAllowed,
  995. IN DATA_OBJECT_TYPES type
  996. )
  997. /*++
  998. Routine Description:
  999. Add menu items to the context menu
  1000. Arguments:
  1001. LPCONTEXTMENUCALLBACK lpContextMenuCallback : Context menu callback
  1002. long * pInsertionAllowed : Insertion allowed
  1003. DATA_OBJECT_TYPES type : Object type
  1004. Return Value:
  1005. HRESULT
  1006. --*/
  1007. {
  1008. ASSERT_READ_PTR(lpContextMenuCallback);
  1009. ASSERT(pInsertionAllowed != NULL);
  1010. if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) != 0)
  1011. {
  1012. if (IsConnectable() && !m_fIsExtension)
  1013. {
  1014. AddMenuItemByCommand(lpContextMenuCallback, IDM_CONNECT);
  1015. }
  1016. if (IsDisconnectable() && !m_fIsExtension)
  1017. {
  1018. ASSERT(IsConnectable());
  1019. AddMenuItemByCommand(lpContextMenuCallback, IDM_DISCONNECT);
  1020. }
  1021. // Check if it should be disabled...
  1022. BOOL bHasFiles = HasFileSystemFiles();
  1023. if (IsExplorable())
  1024. {
  1025. AddMenuSeparator(lpContextMenuCallback);
  1026. AddMenuItemByCommand(lpContextMenuCallback, IDM_EXPLORE, bHasFiles ? 0 : MF_GRAYED);
  1027. }
  1028. if (IsOpenable())
  1029. {
  1030. AddMenuItemByCommand(lpContextMenuCallback, IDM_OPEN, bHasFiles ? 0 : MF_GRAYED);
  1031. }
  1032. if (IsPermissionable())
  1033. {
  1034. AddMenuItemByCommand(lpContextMenuCallback, IDM_PERMISSION, bHasFiles ? 0 : MF_GRAYED);
  1035. }
  1036. if (IsBrowsable())
  1037. {
  1038. AddMenuItemByCommand(lpContextMenuCallback, IDM_BROWSE);
  1039. }
  1040. if (IsControllable())
  1041. {
  1042. AddMenuSeparator(lpContextMenuCallback);
  1043. UINT nPauseFlags = IsPausable() ? 0 : MF_GRAYED;
  1044. if (IsPaused())
  1045. {
  1046. nPauseFlags |= MF_CHECKED;
  1047. }
  1048. AddMenuItemByCommand(lpContextMenuCallback, IDM_START, IsStartable() ? 0 : MF_GRAYED);
  1049. AddMenuItemByCommand(lpContextMenuCallback, IDM_STOP, IsStoppable() ? 0 : MF_GRAYED);
  1050. AddMenuItemByCommand(lpContextMenuCallback, IDM_PAUSE, nPauseFlags);
  1051. }
  1052. #if defined(_DEBUG) || DBG
  1053. g_Debug_IISObject.Dump(2);
  1054. #endif
  1055. #if defined(_DEBUG) || DBG
  1056. CIISObject * pOpenItem = NULL;
  1057. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1058. g_OpenPropertySheetTracker.IsPropertySheetOpenBelowMe(pConsoleNameSpace,this,&pOpenItem);
  1059. #endif
  1060. }
  1061. return S_OK;
  1062. }
  1063. /* virtual */
  1064. HRESULT
  1065. CIISObject::Command(
  1066. IN long lCommandID,
  1067. IN CSnapInObjectRootBase * lpObj,
  1068. IN DATA_OBJECT_TYPES type
  1069. )
  1070. /*++
  1071. Routine Description:
  1072. Handle command from context menu.
  1073. Arguments:
  1074. long lCommandID : Command ID
  1075. CSnapInObjectRootBase * lpObj : Base object
  1076. DATA_OBJECT_TYPES type : Data object type
  1077. Return Value:
  1078. HRESULT
  1079. --*/
  1080. {
  1081. HRESULT hr = S_OK;
  1082. switch (lCommandID)
  1083. {
  1084. case IDM_CONNECT:
  1085. hr = AskForAndAddMachine();
  1086. break;
  1087. }
  1088. return hr;
  1089. }
  1090. #if defined(_DEBUG) || DBG
  1091. LPCTSTR
  1092. ParseEvent(MMC_NOTIFY_TYPE event)
  1093. {
  1094. LPCTSTR p = NULL;
  1095. switch (event)
  1096. {
  1097. case MMCN_ACTIVATE: p = _T("MMCN_ACTIVATE"); break;
  1098. case MMCN_ADD_IMAGES: p = _T("MMCN_ADD_IMAGES"); break;
  1099. case MMCN_BTN_CLICK: p = _T("MMCN_BTN_CLICK"); break;
  1100. case MMCN_CLICK: p = _T("MMCN_CLICK"); break;
  1101. case MMCN_COLUMN_CLICK: p = _T("MMCN_COLUMN_CLICK"); break;
  1102. case MMCN_CONTEXTMENU: p = _T("MMCN_CONTEXTMENU"); break;
  1103. case MMCN_CUTORMOVE: p = _T("MMCN_CUTORMOVE"); break;
  1104. case MMCN_DBLCLICK: p = _T("MMCN_DBLCLICK"); break;
  1105. case MMCN_DELETE: p = _T("MMCN_DELETE"); break;
  1106. case MMCN_DESELECT_ALL: p = _T("MMCN_DESELECT_ALL"); break;
  1107. case MMCN_EXPAND: p = _T("MMCN_EXPAND"); break;
  1108. case MMCN_HELP: p = _T("MMCN_HELP"); break;
  1109. case MMCN_MENU_BTNCLICK: p = _T("MMCN_MENU_BTNCLICK"); break;
  1110. case MMCN_MINIMIZED: p = _T("MMCN_MINIMIZED"); break;
  1111. case MMCN_PASTE: p = _T("MMCN_PASTE"); break;
  1112. case MMCN_PROPERTY_CHANGE: p = _T("MMCN_PROPERTY_CHANGE"); break;
  1113. case MMCN_QUERY_PASTE: p = _T("MMCN_QUERY_PASTE"); break;
  1114. case MMCN_REFRESH: p = _T("MMCN_REFRESH"); break;
  1115. case MMCN_REMOVE_CHILDREN: p = _T("MMCN_REMOVE_CHILDREN"); break;
  1116. case MMCN_RENAME: p = _T("MMCN_RENAME"); break;
  1117. case MMCN_SELECT: p = _T("MMCN_SELECT"); break;
  1118. case MMCN_SHOW: p = _T("MMCN_SHOW"); break;
  1119. case MMCN_VIEW_CHANGE: p = _T("MMCN_VIEW_CHANGE"); break;
  1120. case MMCN_SNAPINHELP: p = _T("MMCN_SNAPINHELP"); break;
  1121. case MMCN_CONTEXTHELP: p = _T("MMCN_CONTEXTHELP"); break;
  1122. case MMCN_INITOCX: p = _T("MMCN_INITOCX"); break;
  1123. case MMCN_FILTER_CHANGE: p = _T("MMCN_FILTER_CHANGE"); break;
  1124. case MMCN_FILTERBTN_CLICK: p = _T("MMCN_FILTERBTN_CLICK"); break;
  1125. case MMCN_RESTORE_VIEW: p = _T("MMCN_RESTORE_VIEW"); break;
  1126. case MMCN_PRINT: p = _T("MMCN_PRINT"); break;
  1127. case MMCN_PRELOAD: p = _T("MMCN_PRELOAD"); break;
  1128. case MMCN_LISTPAD: p = _T("MMCN_LISTPAD"); break;
  1129. case MMCN_EXPANDSYNC: p = _T("MMCN_EXPANDSYNC"); break;
  1130. case MMCN_COLUMNS_CHANGED: p = _T("MMCN_COLUMNS_CHANGED"); break;
  1131. case MMCN_CANPASTE_OUTOFPROC: p = _T("MMCN_CANPASTE_OUTOFPROC"); break;
  1132. default: p = _T("Unknown"); break;
  1133. }
  1134. return p;
  1135. }
  1136. #endif
  1137. extern HRESULT
  1138. GetHelpTopic(LPOLESTR *lpCompiledHelpFile);
  1139. void CIISObject::DoRunOnce(
  1140. IN MMC_NOTIFY_TYPE event,
  1141. IN LPARAM arg,
  1142. IN LPARAM param
  1143. )
  1144. {
  1145. static bActivateCalled = FALSE;
  1146. static iSelectionCount = 0;
  1147. switch (event)
  1148. {
  1149. case MMCN_ACTIVATE:
  1150. {
  1151. bActivateCalled = TRUE;
  1152. }
  1153. case MMCN_SHOW:
  1154. {
  1155. if (!(g_dwInetmgrParamFlags & INETMGR_PARAM_RUNONCE_HAPPENED))
  1156. {
  1157. // only on the Root node
  1158. if (IsEqualGUID(* (GUID *) GetNodeType(),cInternetRootNode))
  1159. {
  1160. // This RunOnce thing will only work
  1161. // if we select the container twice...
  1162. //
  1163. // after the second selection (which is really the 2nd MMCN_SHOW for the root item)
  1164. // it will stick....
  1165. //
  1166. // and this will only also work when the additonal runonce code in
  1167. // CIISRoot::EnumerateScopePane is executed...
  1168. if (bActivateCalled && iSelectionCount <= 1)
  1169. {
  1170. CIISRoot * pRoot = (CIISRoot *) this;
  1171. if (pRoot)
  1172. {
  1173. CIISMachine * pMach = pRoot->m_scServers.GetFirst();
  1174. if (pMach)
  1175. {
  1176. if (pMach->IsLocal())
  1177. {
  1178. CWebServiceExtensionContainer * pContainer = pMach->QueryWebSvcExtContainer();
  1179. if (pContainer)
  1180. {
  1181. if ((BOOL)arg)
  1182. {
  1183. pContainer->SelectScopeItem();
  1184. iSelectionCount++;
  1185. }
  1186. }
  1187. }
  1188. }
  1189. }
  1190. if (iSelectionCount > 1)
  1191. {
  1192. // Set the flag to say we did runonce already!
  1193. SetInetmgrParamFlag(INETMGR_PARAM_RUNONCE_HAPPENED,TRUE);
  1194. }
  1195. }
  1196. }
  1197. }
  1198. }
  1199. break;
  1200. default:
  1201. break;
  1202. }
  1203. return;
  1204. }
  1205. HRESULT
  1206. CIISObject::Notify(
  1207. IN MMC_NOTIFY_TYPE event,
  1208. IN LPARAM arg,
  1209. IN LPARAM param,
  1210. IN IComponentData * lpComponentData,
  1211. IN IComponent * lpComponent,
  1212. IN DATA_OBJECT_TYPES type
  1213. )
  1214. /*++
  1215. Routine Description:
  1216. Notification handler
  1217. Arguments:
  1218. MMC_NOTIFY_TYPE event : Notification type
  1219. long arg : Event-specific argument
  1220. long param : Event-specific parameter
  1221. IComponentData * pComponentData : IComponentData
  1222. IComponent * pComponent : IComponent
  1223. DATA_OBJECT_TYPES type : Data object type
  1224. Return Value:
  1225. HRESULT
  1226. --*/
  1227. {
  1228. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  1229. if (g_iDebugOutputLevel & DEBUG_FLAG_MMC_NOTIFY)
  1230. {
  1231. TRACEEOL("CIISObject::Notify -> " << ParseEvent(event));
  1232. }
  1233. static BOOL s_bLastEventSel = FALSE;
  1234. CError err(E_NOTIMPL);
  1235. ASSERT(lpComponentData != NULL || lpComponent != NULL);
  1236. // CComPtr<IConsole> lpConsole;
  1237. IConsole * lpConsole;
  1238. CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> lpHeader;
  1239. CComQIPtr<IResultData, &IID_IResultData> lpResultData;
  1240. // Cache the passed in pointers
  1241. _lpComponent = lpComponent;
  1242. _lpComponentData = lpComponentData;
  1243. if (lpComponentData != NULL)
  1244. {
  1245. lpConsole = ((CInetMgr *)lpComponentData)->m_spConsole;
  1246. }
  1247. else
  1248. {
  1249. lpConsole = ((CInetMgrComponent *)lpComponent)->m_spConsole;
  1250. }
  1251. lpHeader = lpConsole;
  1252. lpResultData = lpConsole;
  1253. #if defined(_DEBUG) || DBG
  1254. if (g_iDebugOutputLevel & DEBUG_FLAG_MMC_NOTIFY)
  1255. {
  1256. SCOPEDATAITEM si;
  1257. ::ZeroMemory(&si, sizeof(SCOPEDATAITEM));
  1258. si.mask = SDI_PARAM;
  1259. si.ID = m_hScopeItem;
  1260. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1261. if (SUCCEEDED(pConsoleNameSpace->GetItem(&si)))
  1262. {
  1263. CIISObject * pNode = (CIISObject *)si.lParam;
  1264. DumpFriendlyName(pNode);
  1265. }
  1266. }
  1267. #endif
  1268. switch (event)
  1269. {
  1270. case MMCN_ACTIVATE:
  1271. if (!(g_dwInetmgrParamFlags & INETMGR_PARAM_RUNONCE_HAPPENED))
  1272. {
  1273. DoRunOnce(event,arg,param);
  1274. }
  1275. err = S_OK;
  1276. break;
  1277. case MMCN_PROPERTY_CHANGE:
  1278. // err = OnPropertyChange((BOOL)arg, lpResultData);
  1279. TRACEEOLID("MMCN_PROPERTY_CHANGE");
  1280. break;
  1281. case MMCN_SHOW:
  1282. // The notification is sent to the snap-in's IComponent implementation
  1283. // when a scope item is selected or deselected.
  1284. //
  1285. // arg: TRUE if selecting. Indicates that the snap-in should set up the
  1286. // result pane and add the enumerated items. FALSE if deselecting.
  1287. // Indicates that the snap-in is going out of focus and that it
  1288. // should clean up all result item cookies, because the current
  1289. // result pane will be replaced by a new one.
  1290. // param: The HSCOPEITEM of the selected or deselected item.
  1291. if (m_fSkipEnumResult)
  1292. {
  1293. m_fSkipEnumResult = FALSE;
  1294. }
  1295. else
  1296. {
  1297. if (!m_fFlaggedForDeletion)
  1298. {
  1299. if (IsEqualGUID(* (GUID *) GetNodeType(),cWebServiceExtensionContainer))
  1300. {
  1301. CWebServiceExtensionContainer * pTemp = (CWebServiceExtensionContainer *) this;
  1302. if (pTemp)
  1303. {
  1304. err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,pTemp,FALSE,METABASE_PATH_FOR_RESTRICT_LIST);
  1305. }
  1306. if (err.Win32Error() == RPC_S_SERVER_UNAVAILABLE)
  1307. {
  1308. // if the Metabase is reconnected in EnumerateResultPane() during MMCN_SHOW
  1309. // then it will be hosed. don't enumerate this node
  1310. // and just let user hit refresh.
  1311. // create the column headers at least
  1312. err = CIISObject::EnumerateResultPane((BOOL)arg, lpHeader, lpResultData);
  1313. }
  1314. else
  1315. {
  1316. EnumerateResultPane((BOOL)arg, lpHeader, lpResultData);
  1317. }
  1318. }
  1319. else
  1320. {
  1321. EnumerateResultPane((BOOL)arg, lpHeader, lpResultData);
  1322. }
  1323. }
  1324. }
  1325. if (!(g_dwInetmgrParamFlags & INETMGR_PARAM_RUNONCE_HAPPENED))
  1326. {
  1327. // Call runonce during the MMCN_SHOW
  1328. DoRunOnce(event,arg,param);
  1329. }
  1330. // Fail code will prevent MMC from enabling verbs
  1331. err.Reset();
  1332. break;
  1333. case MMCN_EXPAND:
  1334. {
  1335. #if defined(_DEBUG) || DBG
  1336. g_Debug_IISObject.Dump(0);
  1337. #endif
  1338. CWaitCursor wait;
  1339. if (!m_fFlaggedForDeletion)
  1340. {
  1341. err = EnumerateScopePane((HSCOPEITEM)param);
  1342. }
  1343. }
  1344. break;
  1345. case MMCN_ADD_IMAGES:
  1346. // The MMCN_ADD_IMAGES notification is sent to the snap-in's IComponent
  1347. // implementation to add images for the result pane.
  1348. //
  1349. // lpDataObject: [in] Pointer to the data object of the currently selected scope item.
  1350. // arg: Pointer to the result pane's image list (IImageList).
  1351. // This pointer is valid only while the specific MMCN_ADD_IMAGES notification is
  1352. // being processed and should not be stored for later use. Additionally, the
  1353. // snap-in must not call the Release method of IImageList because MMC is responsible
  1354. // for releasing it.
  1355. // param: Specifies the HSCOPEITEM of the currently selected scope item. The snap-in
  1356. // can use this parameter to add images that apply specifically to the result
  1357. // items of this scope item, or the snap-in can ignore this parameter and add
  1358. // all possible images.
  1359. err = AddImages((LPIMAGELIST)arg);
  1360. break;
  1361. case MMCN_DELETE:
  1362. err = DeleteNode(lpResultData);
  1363. break;
  1364. case MMCN_REMOVE_CHILDREN:
  1365. #if defined(_DEBUG) || DBG
  1366. g_Debug_IISObject.Dump(0);
  1367. #endif
  1368. err = DeleteChildObjects((HSCOPEITEM)arg);
  1369. break;
  1370. case MMCN_VIEW_CHANGE:
  1371. // The MMCN_VIEW_CHANGE notification message is sent to the snap-in's
  1372. // IComponent implementation so it can update the view when a change occurs.
  1373. // This notification is generated when the snap-in (IComponent or IComponentData)
  1374. // calls IConsole2::UpdateAllViews.
  1375. //
  1376. // lpDataObject: [in] Pointer to the data object passed to IConsole::UpdateAllViews.
  1377. // arg: [in] The data parameter passed to IConsole::UpdateAllViews.
  1378. // param: [in] The hint parameter passed to IConsole::UpdateAllViews.
  1379. err = OnViewChange(type == CCT_SCOPE, lpResultData, lpHeader, (DWORD) param);
  1380. break;
  1381. case MMCN_REFRESH:
  1382. {
  1383. // The MMCN_REFRESH notification message is sent to a snap-in's IComponent
  1384. // implementation when the refresh verb is selected. Refresh can be invoked
  1385. // through the context menu, through the toolbar, or by pressing F5.
  1386. //
  1387. // lpDataObject: [in] Pointer to the data object of the currently selected scope item.
  1388. // arg: Not used.
  1389. // param: Not used.
  1390. // Refresh current node, and re-enumerate
  1391. // child nodes of the child nodes had previously
  1392. // been expanded.
  1393. // check if we're doing the IISMachine Node...
  1394. if (IsEqualGUID(* (GUID *) GetNodeType(),cMachineNode))
  1395. {
  1396. CIISObject * pOpenItem = NULL;
  1397. if (g_OpenPropertySheetTracker.IsPropertySheetOpenComputer(this,FALSE,&pOpenItem))
  1398. {
  1399. g_OpenPropertySheetTracker.Dump();
  1400. if (pOpenItem)
  1401. {
  1402. HWND hHwnd = pOpenItem->IsMyPropertySheetOpen();
  1403. // a property sheet is open somewhere..
  1404. // make sure they close it before proceeding with refresh...
  1405. // Highlight the property sheet.
  1406. if (hHwnd && (hHwnd != (HWND) 1))
  1407. {
  1408. DoHelpMessageBox(NULL,IDS_CLOSE_ALL_PROPERTY_SHEET_REFRESH, MB_OK | MB_ICONINFORMATION, 0);
  1409. if (!SetForegroundWindow(hHwnd))
  1410. {
  1411. // wasn't able to bring this property sheet to
  1412. // the foreground, the propertysheet must not
  1413. // exist anymore. let's just clean the hwnd
  1414. // so that the user will be able to open propertysheet
  1415. pOpenItem->SetMyPropertySheetOpen(0);
  1416. }
  1417. break;
  1418. }
  1419. }
  1420. }
  1421. }
  1422. BOOL fReEnumerate = (!IsLeafNode() && IsExpanded());
  1423. if (fReEnumerate)
  1424. {
  1425. // Look for all of the open property sheets that are a child of
  1426. // this node, and orphan it (erase it's scope/result item info)
  1427. // so that it doesn't send a MMCNotify if the user hits ok
  1428. // (since there is nothing to update anyways and this MMCNotify cause AV).
  1429. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1430. INT iOrphans = g_OpenPropertySheetTracker.OrphanPropertySheetsBelowMe(pConsoleNameSpace,this,TRUE);
  1431. }
  1432. err = Refresh(fReEnumerate);
  1433. if (err.Succeeded() && HasResultItems(lpResultData))
  1434. {
  1435. err = CleanResult(lpResultData);
  1436. if (err.Succeeded())
  1437. {
  1438. // We should use fForRefresh = TRUE here, because MMC will add extra
  1439. // columns on refresh when result pane doesn't contain scope items.
  1440. if (!m_fFlaggedForDeletion)
  1441. {
  1442. err = EnumerateResultPane(TRUE, lpHeader, lpResultData, TRUE);
  1443. }
  1444. }
  1445. }
  1446. {
  1447. // refresh the verbs
  1448. ASSERT_PTR(lpConsole);
  1449. CComPtr<IConsoleVerb> lpConsoleVerb;
  1450. lpConsole->QueryConsoleVerb(&lpConsoleVerb);
  1451. ASSERT_PTR(lpConsoleVerb);
  1452. if (lpConsoleVerb)
  1453. {
  1454. err = SetStandardVerbs(lpConsoleVerb);
  1455. }
  1456. // Refresh() will clean out the scope item
  1457. // Reselect the refreshed item.
  1458. if (!s_bLastEventSel)
  1459. {
  1460. // if the last selection event
  1461. // was not ended upon a "selection" but rather a "deselection"
  1462. // make force a selection...
  1463. SelectScopeItem();
  1464. }
  1465. }
  1466. #if defined(_DEBUG) || DBG
  1467. // check if we leaked anything.
  1468. g_Debug_IISObject.Dump(2);
  1469. #endif
  1470. }
  1471. break;
  1472. case MMCN_SELECT:
  1473. {
  1474. // The MMCN_SELECT notification is sent to the snap-in's IComponent::Notify
  1475. // or IExtendControlbar::ControlbarNotify method when an item is selected in
  1476. // either the scope pane or result pane.
  1477. //
  1478. // lpDataObject: [in] Pointer to the data object of the currently
  1479. // selected/deselected scope pane or result item.
  1480. // arg: BOOL bScope = (BOOL) LOWORD(arg); BOOL bSelect = (BOOL) HIWORD(arg);
  1481. // bScope is TRUE if the selected item is a scope item, or FALSE if
  1482. // the selected item is a result item. For bScope = TRUE, MMC does
  1483. // not provide information about whether the scope item is selected
  1484. // in the scope pane or in the result pane. bSelect is TRUE if the
  1485. // item is selected, or FALSE if the item is deselected.
  1486. // param: ignored.
  1487. #if defined(_DEBUG) || DBG
  1488. g_Debug_IISObject.Dump(0);
  1489. #endif
  1490. BOOL bScope = (BOOL) LOWORD(arg);
  1491. BOOL bSelect = (BOOL) HIWORD(arg);
  1492. s_bLastEventSel = bSelect;
  1493. err.Reset();
  1494. //
  1495. // Item has been selected -- set verb states
  1496. //
  1497. if (bSelect)
  1498. {
  1499. SetToolBarStates(_lpToolBar);
  1500. ASSERT_PTR(lpConsole);
  1501. CComPtr<IConsoleVerb> lpConsoleVerb;
  1502. lpConsole->QueryConsoleVerb(&lpConsoleVerb);
  1503. ASSERT_PTR(lpConsoleVerb);
  1504. if (lpConsoleVerb)
  1505. {
  1506. err = SetStandardVerbs(lpConsoleVerb);
  1507. }
  1508. if (IsEqualGUID(* (GUID *) GetNodeType(),cWebServiceExtensionContainer))
  1509. {
  1510. ForceReportMode(lpResultData);
  1511. }
  1512. // if it's the service node,
  1513. // check if we need to update it's icon (started/stopped)
  1514. if (IsEqualGUID(* (GUID *) GetNodeType(),cServiceCollectorNode))
  1515. {
  1516. CIISService * pTemp = (CIISService *) this;
  1517. // Don't do this on every selection.
  1518. // The SMTP/NNTP nodes require user to select refresh
  1519. // to get the latest status of the server
  1520. // we don't want to stray too far from they're behavior
  1521. // otherwise, the user might think it should be that
  1522. // way for SMTP/NNTP as well...
  1523. pTemp->GetServiceState(); // ahh well...
  1524. if (pTemp->m_dwServiceStateDisplayed != pTemp->m_dwServiceState)
  1525. {
  1526. pTemp->RefreshDisplay(FALSE);
  1527. RefreshDisplay();
  1528. }
  1529. }
  1530. }
  1531. }
  1532. break;
  1533. case MMCN_RENAME:
  1534. err = RenameItem((LPOLESTR)param);
  1535. break;
  1536. case MMCN_DBLCLICK:
  1537. // The MMCN_DBLCLICK notification is sent to the snap-in's IComponent
  1538. // implementation when a user double-clicks a mouse button on a list
  1539. // view item or on a scope item in the result pane. Pressing enter
  1540. // while the list item or scope item has focus in the list view also
  1541. // generates an MMCN_DBLCLICK notification message.
  1542. //
  1543. // lpDataObject: [in] Pointer to the data object of the currently selected item.
  1544. // arg: Not used.
  1545. // param: Not used.
  1546. err = OnDblClick(lpComponentData, lpComponent);
  1547. break;
  1548. case MMCN_COLUMNS_CHANGED:
  1549. err = ChangeVisibleColumns((MMC_VISIBLE_COLUMNS *)param);
  1550. break;
  1551. case MMCN_CONTEXTHELP:
  1552. {
  1553. LPOLESTR pCompiledHelpFile = NULL;
  1554. CError err(E_NOTIMPL);
  1555. err = GetHelpTopic(&pCompiledHelpFile);
  1556. if (err.Succeeded())
  1557. {
  1558. IDisplayHelp * pdh;
  1559. err = lpConsole->QueryInterface(IID_IDisplayHelp, (void **)&pdh);
  1560. if (err.Succeeded())
  1561. {
  1562. CString strDefault;
  1563. CString strHtmlPage;
  1564. CString topic = ::PathFindFileName(pCompiledHelpFile);
  1565. strDefault = GLOBAL_DEFAULT_HELP_PATH ;
  1566. if (SUCCEEDED(GetContextHelp(strHtmlPage)))
  1567. {
  1568. if (!strHtmlPage.IsEmpty())
  1569. {
  1570. strDefault = strHtmlPage;
  1571. }
  1572. }
  1573. topic += strDefault;
  1574. LPTSTR p = topic.GetBuffer(topic.GetLength());
  1575. err = pdh->ShowTopic(p);
  1576. topic.ReleaseBuffer();
  1577. pdh->Release();
  1578. }
  1579. }
  1580. err.MessageBoxOnFailure();
  1581. CoTaskMemFree(pCompiledHelpFile);
  1582. }
  1583. break;
  1584. default:
  1585. return S_FALSE;
  1586. }
  1587. if (!err.Succeeded())
  1588. {
  1589. if (g_iDebugOutputLevel & DEBUG_FLAG_MMC_NOTIFY)
  1590. {
  1591. TRACEEOL("CIISObject::Notify -> " << ParseEvent(event) << " error " << err);
  1592. }
  1593. }
  1594. err.Reset();
  1595. return err;
  1596. }
  1597. HRESULT
  1598. CIISObject::GetContextHelp(CString& strHtmlPage)
  1599. {
  1600. strHtmlPage = GLOBAL_DEFAULT_HELP_PATH ;
  1601. return S_OK;
  1602. }
  1603. HRESULT
  1604. CIISObject::AddToScopePane(
  1605. IN HSCOPEITEM hRelativeID,
  1606. IN BOOL fChild,
  1607. IN BOOL fNext,
  1608. IN BOOL fIsParent
  1609. )
  1610. /*++
  1611. Routine Description:
  1612. Add current object to console namespace. Either as the last child
  1613. of a parent item, or right before/after sibling item
  1614. Arguments:
  1615. HSCOPEITEM hRelativeID : Relative scope ID (either parent or sibling)
  1616. BOOL fChild : If TRUE, object will be added as child of
  1617. hRelativeID
  1618. BOOL fNext : If fChild is TRUE, this parameter is ignored
  1619. If fChild is FALSE, and fNext is TRUE,
  1620. object will be added before hRelativeID
  1621. If fChild is FALSE, and fNext is FALSE,
  1622. object will be added after hRelativeID
  1623. BOOL fIsParent : If TRUE, it will add the [+] to indicate
  1624. that this node may have childnodes.
  1625. Return Value
  1626. HRESULT
  1627. --*/
  1628. {
  1629. DWORD dwMask = fChild ? SDI_PARENT : fNext ? SDI_NEXT : SDI_PREVIOUS;
  1630. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1631. SCOPEDATAITEM scopeDataItem;
  1632. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  1633. scopeDataItem.mask =
  1634. SDI_STR | SDI_IMAGE | SDI_CHILDREN | SDI_OPENIMAGE | SDI_PARAM | dwMask;
  1635. scopeDataItem.displayname = MMC_CALLBACK;
  1636. scopeDataItem.nImage = scopeDataItem.nOpenImage = MMC_IMAGECALLBACK;//QueryImage();
  1637. scopeDataItem.lParam = (LPARAM)this;
  1638. scopeDataItem.relativeID = hRelativeID;
  1639. scopeDataItem.cChildren = fIsParent ? 1 : 0;
  1640. HRESULT hr = pConsoleNameSpace->InsertItem(&scopeDataItem);
  1641. if (SUCCEEDED(hr))
  1642. {
  1643. //
  1644. // Cache the scope item handle
  1645. //
  1646. ASSERT(m_hScopeItem == NULL);
  1647. m_hScopeItem = scopeDataItem.ID;
  1648. // BUGBUG: looks like MMC_IMAGECALLBACK doesn't work in InsertItem. Update it here.
  1649. scopeDataItem.mask =
  1650. SDI_IMAGE | SDI_OPENIMAGE;
  1651. pConsoleNameSpace->SetItem(&scopeDataItem);
  1652. }
  1653. return hr;
  1654. }
  1655. HRESULT
  1656. CIISObject::AddToScopePaneSorted(
  1657. IN HSCOPEITEM hParent,
  1658. IN BOOL fIsParent
  1659. )
  1660. /*++
  1661. Routine Description:
  1662. Add current object to console namespace, sorted in its proper location.
  1663. Arguments:
  1664. HSCOPEITEM hParent : Parent object
  1665. BOOL fIsParent : If TRUE, it will add the [+] to indicate
  1666. that this node may have childnodes.
  1667. Return Value
  1668. HRESULT
  1669. --*/
  1670. {
  1671. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1672. //
  1673. // Find proper insertion point
  1674. //
  1675. BOOL fChild = TRUE;
  1676. HSCOPEITEM hChildItem = NULL;
  1677. CIISObject * pItem;
  1678. LONG_PTR cookie;
  1679. int nSwitch;
  1680. HRESULT hr = pConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  1681. while(SUCCEEDED(hr) && hChildItem)
  1682. {
  1683. //
  1684. // The cookie is really the IISObject, which is what we stuff
  1685. // in the lparam.
  1686. //
  1687. pItem = (CIISObject *)cookie;
  1688. ASSERT_PTR(pItem);
  1689. nSwitch = CompareScopeItem(pItem);
  1690. //
  1691. // Dups should be weeded out by now.
  1692. //
  1693. // ASSERT(nSwitch != 0);
  1694. if (nSwitch < 0)
  1695. {
  1696. //
  1697. // Insert before this item
  1698. //
  1699. fChild = FALSE;
  1700. break;
  1701. }
  1702. //
  1703. // Advance to next child of same parent
  1704. //
  1705. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1706. }
  1707. return AddToScopePane(hChildItem ? hChildItem : hParent, fChild, fIsParent);
  1708. }
  1709. /* virtual */
  1710. HRESULT
  1711. CIISObject::RemoveScopeItem()
  1712. /*++
  1713. Routine Description:
  1714. Remove the current item from the scope view. This method is virtual
  1715. to allow derived classes to do cleanup.
  1716. Arguments:
  1717. None
  1718. Return Value:
  1719. HRESULT
  1720. --*/
  1721. {
  1722. ASSERT(m_hScopeItem != NULL);
  1723. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1724. m_fFlaggedForDeletion = TRUE;
  1725. //RemoveChildren(m_hScopeItem);
  1726. //DeleteChildObjects(m_hScopeItem);
  1727. HRESULT hr = pConsoleNameSpace->DeleteItem(m_hScopeItem, TRUE);
  1728. // set our scope item to point to nothing in the MMC
  1729. ResetScopeItem();
  1730. ResetResultItem();
  1731. return hr;
  1732. }
  1733. HRESULT
  1734. CIISObject::ChangeVisibleColumns(MMC_VISIBLE_COLUMNS * pCol)
  1735. {
  1736. return S_OK;
  1737. }
  1738. HRESULT
  1739. CIISObject::OnDblClick(IComponentData * pcd, IComponent * pc)
  1740. {
  1741. // Default action is to select this item on scope
  1742. return SelectScopeItem();
  1743. }
  1744. HRESULT
  1745. CIISObject::SelectScopeItem()
  1746. /*++
  1747. Routine Description:
  1748. Select this item in the scope view.
  1749. Arguments:
  1750. None
  1751. Return Value:
  1752. HRESULT
  1753. --*/
  1754. {
  1755. // Fix for bug #519763. I found no way of getting hScope from MMC for the
  1756. // root item.
  1757. if (NULL != QueryScopeItem())
  1758. {
  1759. ASSERT(m_hScopeItem != NULL);
  1760. IConsole * pConsole = (IConsole *)GetConsole();
  1761. return pConsole->SelectScopeItem(m_hScopeItem);
  1762. }
  1763. return S_OK;
  1764. }
  1765. HRESULT
  1766. CIISObject::SetCookie()
  1767. /*++
  1768. Routine Description:
  1769. Store the cookie (a pointer to the current CIISObject) in the
  1770. scope view object associated with it.
  1771. Arguments:
  1772. None
  1773. Return Value:
  1774. HRESULT
  1775. --*/
  1776. {
  1777. ASSERT(m_hScopeItem != NULL);
  1778. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1779. SCOPEDATAITEM scopeDataItem;
  1780. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  1781. scopeDataItem.mask = SDI_PARAM;
  1782. scopeDataItem.ID = m_hScopeItem;
  1783. scopeDataItem.lParam = (LPARAM)this;
  1784. return pConsoleNameSpace->SetItem(&scopeDataItem);
  1785. }
  1786. HRESULT
  1787. CIISObject::RefreshDisplay(BOOL bRefreshToolBar)
  1788. /*++
  1789. Routine Description:
  1790. Refresh the display parameters of the current node.
  1791. Arguments:
  1792. None
  1793. Return Value
  1794. HRESULT
  1795. Note: This does not fetch any configuration information from the metabase,
  1796. that's done in RefreshData();
  1797. --*/
  1798. {
  1799. HRESULT hr = S_OK;
  1800. if (m_hResultItem == 0)
  1801. {
  1802. if (bRefreshToolBar)
  1803. {
  1804. SetToolBarStates(_lpToolBar);
  1805. }
  1806. ASSERT(m_hScopeItem != NULL);
  1807. if (m_hScopeItem != NULL)
  1808. {
  1809. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1810. SCOPEDATAITEM scopeDataItem;
  1811. ::ZeroMemory(&scopeDataItem, sizeof(SCOPEDATAITEM));
  1812. scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1813. scopeDataItem.displayname = MMC_CALLBACK;
  1814. scopeDataItem.nImage = scopeDataItem.nOpenImage = QueryImage();
  1815. scopeDataItem.ID = m_hScopeItem;
  1816. hr = pConsoleNameSpace->SetItem(&scopeDataItem);
  1817. }
  1818. }
  1819. else
  1820. {
  1821. RESULTDATAITEM ri;
  1822. ::ZeroMemory(&ri, sizeof(ri));
  1823. ri.itemID = m_hResultItem;
  1824. ri.mask = RDI_STR | RDI_IMAGE;
  1825. ri.str = MMC_CALLBACK;
  1826. ri.nImage = QueryImage();
  1827. IConsole * pConsole = (IConsole *)GetConsole();
  1828. CComQIPtr<IResultData, &IID_IResultData> pResultData(pConsole);
  1829. if (pResultData != NULL)
  1830. {
  1831. pResultData->SetItem(&ri);
  1832. }
  1833. }
  1834. ASSERT(SUCCEEDED(hr));
  1835. return hr;
  1836. }
  1837. /* virtual */
  1838. HRESULT
  1839. CIISObject::DeleteChildObjects(
  1840. IN HSCOPEITEM hParent
  1841. )
  1842. /*++
  1843. Routine Description:
  1844. Free the iisobject pointers belonging to the descendants of the current
  1845. nodes. This is in response to a MMCN_REMOVE_CHILDREN objects typically,
  1846. and does not remove the scope nodes from the scope view (for that see
  1847. RemoveChildren())
  1848. Arguments:
  1849. HSCOPEITEM hParent : Parent scope item handle
  1850. Return Value:
  1851. HRESULT
  1852. --*/
  1853. {
  1854. HSCOPEITEM hChildItem = NULL;
  1855. CIISObject * pItem = NULL;
  1856. LONG_PTR cookie = NULL;
  1857. void ** ppVoid = NULL;
  1858. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1859. HRESULT hr = pConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  1860. while(SUCCEEDED(hr) && hChildItem)
  1861. {
  1862. //
  1863. // The cookie is really the IISObject, which is what we stuff
  1864. // in the lparam.
  1865. //
  1866. pItem = (CIISObject *)cookie;
  1867. ppVoid = (void **) cookie;
  1868. ASSERT_PTR(pItem);
  1869. if (pItem)
  1870. {
  1871. // do this extra check since
  1872. // this cookie object for some reason could be gone already!
  1873. if (ppVoid && (*ppVoid))
  1874. {
  1875. if (pItem != this)
  1876. {
  1877. //
  1878. // Recursively commit infanticide
  1879. // call this objects DeleteChildObjects
  1880. //
  1881. pItem->m_fFlaggedForDeletion = TRUE;
  1882. //
  1883. // Mark the item as orphaned!!
  1884. pItem->ResetScopeItem();
  1885. pItem->ResetResultItem();
  1886. // recursively call on this items children...
  1887. pItem->DeleteChildObjects(hChildItem);
  1888. // this release will delete the object
  1889. pItem->Release();
  1890. }
  1891. }
  1892. }
  1893. //
  1894. // Advance to next child of same parent
  1895. //
  1896. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1897. }
  1898. //
  1899. // BUGBUG: For some reason GetNextItem() returns 1
  1900. // when no more child items exist, not a true HRESULT
  1901. //
  1902. return S_OK;
  1903. }
  1904. /*virtual*/
  1905. HRESULT
  1906. CIISObject::DeleteNode(IResultData * pResult)
  1907. {
  1908. ASSERT(IsDeletable());
  1909. return S_OK;
  1910. }
  1911. /* virtual */
  1912. HRESULT
  1913. CIISObject::RemoveChildren(
  1914. IN HSCOPEITEM hParent
  1915. )
  1916. /*++
  1917. Routine Description:
  1918. Similar to DeleteChildObjects() this method will actually remove
  1919. the child nodes from the scope view.
  1920. Arguments:
  1921. HSCOPEITEM hParent : Parent scope item handle
  1922. Return Value:
  1923. HRESULT
  1924. --*/
  1925. {
  1926. HSCOPEITEM hChildItem, hItem;
  1927. CIISObject * pItem;
  1928. LONG_PTR cookie;
  1929. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  1930. HRESULT hr = pConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  1931. while(SUCCEEDED(hr) && hChildItem)
  1932. {
  1933. //
  1934. // The cookie is really the IISObject, which is what we stuff
  1935. // in the lparam.
  1936. //
  1937. pItem = (CIISObject *)cookie;
  1938. ASSERT_PTR(pItem);
  1939. hItem = pItem ? hChildItem : NULL;
  1940. //
  1941. // Determine next sibling before killing current sibling
  1942. //
  1943. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  1944. //
  1945. // Now delete the current item from the tree
  1946. //
  1947. if (hItem)
  1948. {
  1949. pItem->m_fFlaggedForDeletion = TRUE;
  1950. // get rid of it's scopeitem or result item...
  1951. // this true param should also try to free the item if it's not used.
  1952. hr = pConsoleNameSpace->DeleteItem(hItem, TRUE);
  1953. // set our scope item to point to nothing in the MMC
  1954. pItem->ResetScopeItem();
  1955. pItem->ResetResultItem();
  1956. //
  1957. // ISSUE: Why doesn't DeleteItem above call some sort of
  1958. // notification so that I don't have to do this?
  1959. //
  1960. // this release will delete the object
  1961. pItem->Release();
  1962. }
  1963. }
  1964. //
  1965. // BUGBUG: For some reason GetNextItem() returns 1
  1966. // when no more child items exist, not a true HRESULT
  1967. //
  1968. return S_OK;
  1969. }
  1970. /* virtual */
  1971. HRESULT
  1972. CIISObject::EnumerateResultPane(
  1973. BOOL fExpand,
  1974. IHeaderCtrl * lpHeader,
  1975. IResultData * lpResultData,
  1976. BOOL fForRefresh
  1977. )
  1978. /*++
  1979. Routine Description:
  1980. Enumerate or destroy the result pane.
  1981. Arguments:
  1982. BOOL fExpand : TRUE to create the result view,
  1983. FALSE to destroy it
  1984. IHeaderCtrl * lpHeader : Header control
  1985. IResultData * pResultData : Result view
  1986. BOOL fForRefresh : if true then we don't need to rebuild result view
  1987. Return Value:
  1988. HRESULT
  1989. --*/
  1990. {
  1991. if (fExpand)
  1992. {
  1993. if (lpHeader != NULL)
  1994. {
  1995. ASSERT_READ_PTR(lpHeader);
  1996. if (!fForRefresh)
  1997. {
  1998. InitializeChildHeaders(lpHeader);
  1999. }
  2000. }
  2001. }
  2002. else
  2003. {
  2004. //
  2005. // Destroy child result items
  2006. //
  2007. }
  2008. return S_OK;
  2009. }
  2010. /* virtual */
  2011. HRESULT
  2012. CIISObject::SetStandardVerbs(LPCONSOLEVERB lpConsoleVerb)
  2013. /*++
  2014. Routine Description:
  2015. Set the standard MMC verbs based on the this object type
  2016. and state.
  2017. Arguments:
  2018. LPCONSOLEVERB lpConsoleVerb : Console verb interface
  2019. Return Value:
  2020. HRESULT
  2021. --*/
  2022. {
  2023. CError err;
  2024. ASSERT_READ_PTR(lpConsoleVerb);
  2025. //
  2026. // Set enabled/disabled verb states
  2027. //
  2028. lpConsoleVerb->SetVerbState(MMC_VERB_COPY, HIDDEN, TRUE);
  2029. lpConsoleVerb->SetVerbState(MMC_VERB_PASTE, HIDDEN, TRUE);
  2030. lpConsoleVerb->SetVerbState(MMC_VERB_PRINT, HIDDEN, TRUE);
  2031. // cWebServiceExtension needs special handling since it's different from a regular schope item.
  2032. if (IsEqualGUID(* (GUID *) GetNodeType(),cWebServiceExtension))
  2033. {
  2034. if (UseCount() <= 1)
  2035. {
  2036. lpConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, IsRenamable());
  2037. }
  2038. lpConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, IsDeletable());
  2039. }
  2040. else
  2041. {
  2042. if (UseCount() <= 1)
  2043. {
  2044. lpConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, IsRenamable());
  2045. lpConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, IsDeletable());
  2046. }
  2047. }
  2048. lpConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, IsRefreshable());
  2049. lpConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, IsConfigurable());
  2050. //
  2051. // Set default verb
  2052. //
  2053. if (IsConfigurable())
  2054. {
  2055. lpConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  2056. }
  2057. if (IsOpenable())
  2058. {
  2059. lpConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  2060. }
  2061. return err;
  2062. }
  2063. HRESULT
  2064. CIISObject::FillCustomData(CLIPFORMAT cf, LPSTREAM pStream)
  2065. {
  2066. ASSERT(FALSE);
  2067. return E_FAIL;
  2068. }
  2069. HRESULT
  2070. CIISObject::FillData(CLIPFORMAT cf, LPSTREAM pStream)
  2071. {
  2072. HRESULT hr = CSnapInItemImpl<CIISObject>::FillData(cf, pStream);
  2073. if (hr == DV_E_CLIPFORMAT)
  2074. {
  2075. hr = FillCustomData(cf, pStream);
  2076. }
  2077. return hr;
  2078. }
  2079. //
  2080. // CIISRoot implementation
  2081. //
  2082. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2083. CIISRoot::CIISRoot() :
  2084. m_fRootAdded(FALSE),
  2085. m_pMachine(NULL)
  2086. {
  2087. VERIFY(m_bstrDisplayName.LoadString(IDS_ROOT_NODE));
  2088. TRACEEOL("CIISRoot::CIISRoot");
  2089. }
  2090. CIISRoot::~CIISRoot()
  2091. {
  2092. TRACEEOL("CIISRoot::~CIISRoot");
  2093. }
  2094. /* virtual */
  2095. HRESULT
  2096. CIISRoot::EnumerateScopePane(
  2097. IN HSCOPEITEM hParent
  2098. )
  2099. /*++
  2100. Routine Description:
  2101. Enumerate scope child items of the root object -- i.e. machine nodes.
  2102. The machine nodes are expected to have been filled by via the IPersist
  2103. methods.
  2104. Arguments:
  2105. HSCOPEITEM hParent : Parent console handle
  2106. Return Value:
  2107. HRESULT
  2108. --*/
  2109. {
  2110. if (m_fIsExtension)
  2111. {
  2112. return EnumerateScopePaneExt(hParent);
  2113. }
  2114. //
  2115. // The CIISRoot item was not added in the conventional way.
  2116. // Cache the scope item handle, and set the cookie, so that
  2117. // GetRoot() will work for child objects.
  2118. //
  2119. ASSERT(m_hScopeItem == NULL);
  2120. m_hScopeItem = hParent;
  2121. CError err(SetCookie());
  2122. if (err.Failed())
  2123. {
  2124. //
  2125. // We're in deep trouble. For some reason, we couldn't
  2126. // store the CIISRoot cookie in the scope view. That
  2127. // means anything depending on fetching the root object
  2128. // isn't going to work. Cough up a hairball, and bail
  2129. // out now.
  2130. //
  2131. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  2132. ASSERT_MSG("Unable to cache root object");
  2133. err.MessageBox();
  2134. return err;
  2135. }
  2136. //
  2137. // Expand the computer cache
  2138. //
  2139. if (m_scServers.IsEmpty())
  2140. {
  2141. //
  2142. // Try to create the local machine
  2143. //
  2144. CIISMachine * pLocal = new CIISMachine(GetConsoleNameSpace(),GetConsole());
  2145. if (pLocal)
  2146. {
  2147. //
  2148. // Verify the machine object is created.
  2149. //
  2150. err = CIISMachine::VerifyMachine(pLocal);
  2151. if (err.Succeeded())
  2152. {
  2153. TRACEEOLID("Added local computer to cache: ");
  2154. m_scServers.Add(pLocal);
  2155. }
  2156. err.Reset();
  2157. }
  2158. }
  2159. //
  2160. // Add each cached server to the view...
  2161. //
  2162. CIISMachine * pMachine = m_scServers.GetFirst();
  2163. while (pMachine)
  2164. {
  2165. TRACEEOLID("Adding " << pMachine->QueryServerName() << " to scope pane");
  2166. pMachine->AddRef();
  2167. err = pMachine->AddToScopePane(hParent);
  2168. // Do for runonce
  2169. if (!(g_dwInetmgrParamFlags & INETMGR_PARAM_RUNONCE_HAPPENED))
  2170. {
  2171. IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
  2172. if (pConsoleNameSpace)
  2173. {
  2174. // expand under the covers...
  2175. pConsoleNameSpace->Expand(pMachine->QueryScopeItem());
  2176. }
  2177. }
  2178. if (err.Failed())
  2179. {
  2180. break;
  2181. }
  2182. pMachine = m_scServers.GetNext();
  2183. }
  2184. return err;
  2185. }
  2186. HRESULT
  2187. CIISRoot::EnumerateScopePaneExt(HSCOPEITEM hParent)
  2188. {
  2189. CError err;
  2190. ASSERT(m_scServers.IsEmpty());
  2191. if (!m_fRootAdded)
  2192. {
  2193. CComAuthInfo auth(m_ExtMachineName);
  2194. m_pMachine = new CIISMachine(GetConsoleNameSpace(),GetConsole(),&auth, this);
  2195. if (m_pMachine != NULL)
  2196. {
  2197. m_pMachine->AddRef();
  2198. err = m_pMachine->AddToScopePane(hParent);
  2199. m_fRootAdded = err.Succeeded();
  2200. ASSERT(m_hScopeItem == NULL);
  2201. m_hScopeItem = m_pMachine->QueryScopeItem();
  2202. }
  2203. else
  2204. {
  2205. err = ERROR_NOT_ENOUGH_MEMORY;
  2206. }
  2207. }
  2208. return err;
  2209. }
  2210. HRESULT
  2211. ExtractComputerNameExt(
  2212. IDataObject * pDataObject,
  2213. CString& strComputer)
  2214. {
  2215. //
  2216. // Find the computer name from the ComputerManagement snapin
  2217. //
  2218. CLIPFORMAT CCF_MyComputMachineName = (CLIPFORMAT)RegisterClipboardFormat(MYCOMPUT_MACHINE_NAME);
  2219. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  2220. FORMATETC formatetc = {
  2221. CCF_MyComputMachineName, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  2222. };
  2223. //
  2224. // Allocate memory for the stream
  2225. //
  2226. int len = MAX_PATH;
  2227. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, len);
  2228. if(stgmedium.hGlobal == NULL)
  2229. return ERROR_NOT_ENOUGH_MEMORY;
  2230. HRESULT hr = pDataObject->GetDataHere(&formatetc, &stgmedium);
  2231. ASSERT(SUCCEEDED(hr));
  2232. //
  2233. // Get the computer name
  2234. //
  2235. strComputer = (LPTSTR)stgmedium.hGlobal;
  2236. GlobalFree(stgmedium.hGlobal);
  2237. return hr;
  2238. }
  2239. HRESULT
  2240. CIISRoot::InitAsExtension(IDataObject * pDataObject)
  2241. {
  2242. ASSERT(!m_fIsExtension);
  2243. m_fIsExtension = TRUE;
  2244. CString buf;
  2245. return ExtractComputerNameExt(pDataObject, m_ExtMachineName);
  2246. }
  2247. HRESULT
  2248. CIISRoot::ResetAsExtension()
  2249. {
  2250. ASSERT(m_fIsExtension);
  2251. CIISObject::m_fIsExtension = FALSE;
  2252. // Remove machine node from the scope
  2253. CError err = RemoveScopeItem();
  2254. m_hScopeItem = NULL;
  2255. // Delete machine object
  2256. m_pMachine->Release();
  2257. m_pMachine = NULL;
  2258. m_fRootAdded = FALSE;
  2259. // Empty machine name
  2260. m_ExtMachineName.Empty();
  2261. // clean out
  2262. return err;
  2263. }
  2264. /* virtual */
  2265. HRESULT
  2266. CIISRoot::DeleteChildObjects(
  2267. IN HSCOPEITEM hParent
  2268. )
  2269. /*++
  2270. Routine Description:
  2271. We need this method for extension case. CompMgmt send this event when
  2272. snapin is connected to another machine. We should clean all computer relevant
  2273. stuff from here and the root, because after that we will get MMCN_EXPAND, as
  2274. at the very beginning of extension cycle.
  2275. Arguments:
  2276. HSCOPEITEM hParent : Parent scope item handle
  2277. Return Value:
  2278. HRESULT
  2279. --*/
  2280. {
  2281. HRESULT hr = S_OK;
  2282. if (m_pMachine != NULL)
  2283. {
  2284. m_pMachine->AddRef();
  2285. m_pMachine->DeleteChildObjects(m_hScopeItem);
  2286. m_pMachine->ResetScopeItem();
  2287. m_pMachine->ResetResultItem();
  2288. m_pMachine->m_MachineWNetConnections.Clear();
  2289. m_pMachine->Release();
  2290. }
  2291. else
  2292. {
  2293. CIISMachine * pMachine = m_scServers.GetFirst();
  2294. while (pMachine)
  2295. {
  2296. hr = pMachine->DeleteChildObjects(pMachine->QueryScopeItem());
  2297. pMachine->ResetScopeItem();
  2298. pMachine->ResetResultItem();
  2299. pMachine->m_MachineWNetConnections.Clear();
  2300. m_scServers.Remove(pMachine);
  2301. pMachine->Release();
  2302. pMachine = m_scServers.GetNext();
  2303. }
  2304. }
  2305. if (SUCCEEDED(hr) && m_fIsExtension)
  2306. {
  2307. hr = ResetAsExtension();
  2308. }
  2309. return hr;
  2310. }
  2311. /* virtual */
  2312. void
  2313. CIISRoot::InitializeChildHeaders(
  2314. IN LPHEADERCTRL lpHeader
  2315. )
  2316. /*++
  2317. Routine Description:
  2318. Build result view for immediate descendant type
  2319. Arguments:
  2320. LPHEADERCTRL lpHeader : Header control
  2321. Return Value:
  2322. None
  2323. --*/
  2324. {
  2325. ASSERT(!m_fIsExtension);
  2326. CIISMachine::InitializeHeaders(lpHeader);
  2327. }
  2328. HRESULT
  2329. CIISRoot::FillCustomData(CLIPFORMAT cf, LPSTREAM pStream)
  2330. {
  2331. return E_FAIL;
  2332. }
  2333. /* virtual */
  2334. LPOLESTR
  2335. CIISRoot::GetResultPaneColInfo(int nCol)
  2336. {
  2337. if (nCol == 0)
  2338. {
  2339. return QueryDisplayName();
  2340. }
  2341. else if (nCol == 1)
  2342. {
  2343. }
  2344. else if (nCol == 2)
  2345. {
  2346. }
  2347. return OLESTR("");
  2348. }
  2349. HRESULT CheckForMetabaseAccess(DWORD dwPermissions,
  2350. CIISMBNode * pIISMBNode,
  2351. BOOL bReConnect,
  2352. LPCTSTR path)
  2353. {
  2354. CMetaKey * pKey = NULL;
  2355. CMetaInterface * pMyInterface = NULL;
  2356. CError err;
  2357. BOOL fContinue = TRUE;
  2358. if (!pIISMBNode)
  2359. {
  2360. err = E_POINTER;
  2361. goto CheckForMetabaseAccess_Exit;
  2362. }
  2363. // Check if we have a metabase access first...
  2364. while (fContinue)
  2365. {
  2366. fContinue = FALSE;
  2367. pMyInterface = pIISMBNode->QueryInterface();
  2368. if (pMyInterface)
  2369. {
  2370. if (dwPermissions != 0)
  2371. {
  2372. // METADATA_PERMISSION_READ
  2373. pKey = new CMetaKey(pMyInterface, path, dwPermissions);
  2374. }
  2375. else
  2376. {
  2377. pKey = new CMetaKey(pMyInterface, path);
  2378. }
  2379. if (NULL == pKey)
  2380. {
  2381. TRACEEOLID("RefreshData: Out Of Memory");
  2382. err = ERROR_NOT_ENOUGH_MEMORY;
  2383. break;
  2384. }
  2385. else
  2386. {
  2387. err = pKey->QueryResult();
  2388. }
  2389. }
  2390. else
  2391. {
  2392. err = RPC_S_SERVER_UNAVAILABLE;
  2393. }
  2394. if (pIISMBNode->IsLostInterface(err))
  2395. {
  2396. if (bReConnect)
  2397. {
  2398. SAFE_DELETE(pKey);
  2399. fContinue = pIISMBNode->OnLostInterface(err);
  2400. }
  2401. else
  2402. {
  2403. fContinue = FALSE;
  2404. }
  2405. }
  2406. }
  2407. SAFE_DELETE(pKey);
  2408. CheckForMetabaseAccess_Exit:
  2409. return err;
  2410. }
  2411. HRESULT CheckForMetabaseAccess(DWORD dwPermissions,
  2412. CMetaInterface * pMyInterface,
  2413. LPCTSTR path)
  2414. {
  2415. CMetaKey * pKey = NULL;
  2416. CError err;
  2417. if (!pMyInterface)
  2418. {
  2419. err = RPC_S_SERVER_UNAVAILABLE;
  2420. goto CheckForMetabaseAccess_Exit;
  2421. }
  2422. // Check if we have a metabase access...
  2423. if (dwPermissions != 0)
  2424. {
  2425. // METADATA_PERMISSION_READ
  2426. pKey = new CMetaKey(pMyInterface, path, dwPermissions);
  2427. }
  2428. else
  2429. {
  2430. pKey = new CMetaKey(pMyInterface, path);
  2431. }
  2432. if (NULL == pKey)
  2433. {
  2434. err = ERROR_NOT_ENOUGH_MEMORY;
  2435. }
  2436. else
  2437. {
  2438. err = pKey->QueryResult();
  2439. }
  2440. SAFE_DELETE(pKey);
  2441. CheckForMetabaseAccess_Exit:
  2442. return err;
  2443. }