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.

895 lines
24 KiB

  1. // compdata.cpp : Implementation of CMyComputerComponentData
  2. #include "stdafx.h"
  3. #include <lmerr.h> // For Lan Manager API error codes and return value types.
  4. #include <lmcons.h> // For Lan Manager API constants.
  5. #include <lmapibuf.h> // For NetApiBufferFree.
  6. #include <lmdfs.h> // For DFS APIs.
  7. #include <lmserver.h> // For getting a domain of a server.
  8. #include "macros.h"
  9. USE_HANDLE_MACROS("MMCFMGMT(compdata.cpp)")
  10. #include "dataobj.h"
  11. #include "compdata.h"
  12. #include "cookie.h"
  13. #include "snapmgr.h"
  14. #include "stdutils.h" // IsLocalComputername
  15. #include "chooser2.h"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #include "stdcdata.cpp" // CComponentData implementation
  22. #include "chooser2.cpp" // CHOOSER2_PickTargetComputer implementation
  23. // Helper function to convert message in NETMSG.DLL
  24. int DisplayNetMsgError (
  25. HWND hWndParent,
  26. const CString& computerName,
  27. NET_API_STATUS dwErr,
  28. CString& displayedMessage);
  29. //
  30. // CMyComputerComponentData
  31. //
  32. CMyComputerComponentData::CMyComputerComponentData()
  33. : m_pRootCookie( NULL )
  34. , m_dwFlagsPersist( 0 )
  35. , m_fAllowOverrideMachineName( FALSE )
  36. , m_bCannotConnect (false)
  37. , m_bMessageView (false)
  38. {
  39. //
  40. // We must refcount the root cookie, since a dataobject for it
  41. // might outlive the IComponentData. JonN 9/2/97
  42. //
  43. m_pRootCookie = new CMyComputerCookie( MYCOMPUT_COMPUTER );
  44. ASSERT(NULL != m_pRootCookie);
  45. // JonN 10/27/98 All CRefcountedObject's start with refcount==1
  46. // m_pRootCookie->AddRef();
  47. SetHtmlHelpFileName (L"compmgmt.chm");
  48. }
  49. CMyComputerComponentData::~CMyComputerComponentData()
  50. {
  51. m_pRootCookie->Release();
  52. m_pRootCookie = NULL;
  53. }
  54. DEFINE_FORWARDS_MACHINE_NAME( CMyComputerComponentData, m_pRootCookie )
  55. CCookie& CMyComputerComponentData::QueryBaseRootCookie()
  56. {
  57. ASSERT(NULL != m_pRootCookie);
  58. return (CCookie&)*m_pRootCookie;
  59. }
  60. STDMETHODIMP CMyComputerComponentData::CreateComponent(LPCOMPONENT* ppComponent)
  61. {
  62. MFC_TRY;
  63. ASSERT(ppComponent != NULL);
  64. CComObject<CMyComputerComponent>* pObject;
  65. CComObject<CMyComputerComponent>::CreateInstance(&pObject);
  66. ASSERT(pObject != NULL);
  67. pObject->SetComponentDataPtr( (CMyComputerComponentData*)this );
  68. return pObject->QueryInterface(IID_IComponent,
  69. reinterpret_cast<void**>(ppComponent));
  70. MFC_CATCH;
  71. }
  72. HRESULT CMyComputerComponentData::LoadIcons(LPIMAGELIST pImageList, BOOL /*fLoadLargeIcons*/)
  73. {
  74. HINSTANCE hInstance = AfxGetInstanceHandle();
  75. ASSERT(hInstance != NULL);
  76. // Structure to map a Resource ID to an index of icon
  77. struct RESID2IICON
  78. {
  79. UINT uIconId; // Icon resource ID
  80. int iIcon; // Index of the icon in the image list
  81. };
  82. const static RESID2IICON rgzLoadIconList[] =
  83. {
  84. // Misc icons
  85. { IDI_COMPUTER, iIconComputer },
  86. { IDI_COMPFAIL, iIconComputerFail },
  87. { IDI_SYSTEMTOOLS, iIconSystemTools },
  88. { IDI_STORAGE, iIconStorage },
  89. { IDI_SERVERAPPS, iIconServerApps },
  90. { 0, 0} // Must be last
  91. };
  92. for (int i = 0; rgzLoadIconList[i].uIconId != 0; i++)
  93. {
  94. HICON hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(rgzLoadIconList[i].uIconId));
  95. ASSERT(NULL != hIcon && "Icon ID not found in resources");
  96. HRESULT hr = pImageList->ImageListSetIcon((PLONG_PTR)hIcon, rgzLoadIconList[i].iIcon);
  97. ASSERT(SUCCEEDED(hr) && "Unable to add icon to ImageList");
  98. }
  99. return S_OK;
  100. }
  101. CString g_strMyComputer;
  102. CString g_strSystemTools;
  103. CString g_strServerApps;
  104. CString g_strStorage;
  105. BOOL g_fScopeStringsLoaded = FALSE;
  106. void LoadGlobalCookieStrings()
  107. {
  108. if (!g_fScopeStringsLoaded )
  109. {
  110. g_fScopeStringsLoaded = TRUE;
  111. VERIFY( g_strMyComputer.LoadString(IDS_SCOPE_MYCOMPUTER) );
  112. VERIFY( g_strSystemTools.LoadString(IDS_SCOPE_SYSTEMTOOLS) );
  113. VERIFY( g_strServerApps.LoadString(IDS_SCOPE_SERVERAPPS) );
  114. VERIFY( g_strStorage.LoadString(IDS_SCOPE_STORAGE) );
  115. }
  116. }
  117. // returns TRUE iff the child nodes should be added
  118. // CODEWORK this is probably no longer necessary, we always return true
  119. bool CMyComputerComponentData::ValidateMachine(const CString &sName, bool bDisplayErr)
  120. {
  121. CWaitCursor waitCursor;
  122. int iRetVal = IDYES;
  123. SERVER_INFO_101* psvInfo101 = 0;
  124. DWORD dwr = ERROR_SUCCESS;
  125. DWORD dwServerType = SV_TYPE_NT;
  126. m_bMessageView = false;
  127. // passed-in name is not the same as local machine
  128. if ( !IsLocalComputername(sName) )
  129. {
  130. dwr = ::NetServerGetInfo((LPTSTR)(LPCTSTR)sName,
  131. 101, (LPBYTE*)&psvInfo101);
  132. if (dwr == ERROR_SUCCESS)
  133. {
  134. ASSERT( NULL != psvInfo101 );
  135. dwServerType = psvInfo101->sv101_type;
  136. ::NetApiBufferFree (psvInfo101);
  137. }
  138. if (bDisplayErr && (dwr != ERROR_SUCCESS || !(SV_TYPE_NT & dwServerType)) )
  139. {
  140. CString computerName (sName);
  141. if ( computerName.IsEmpty () )
  142. {
  143. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1 ;
  144. VERIFY (::GetComputerName (
  145. computerName.GetBufferSetLength (dwSize),
  146. &dwSize));
  147. computerName.ReleaseBuffer ();
  148. }
  149. else
  150. {
  151. // Strip off the leading whack-whack
  152. if ( computerName.Find (L"\\\\") == 0 )
  153. {
  154. computerName = computerName.GetBuffer (computerName.GetLength ()) + 2;
  155. computerName.ReleaseBuffer ();
  156. }
  157. }
  158. CString text;
  159. CString caption;
  160. bool bMessageDisplayed = false;
  161. switch (dwr)
  162. {
  163. case ERROR_NETWORK_UNREACHABLE:
  164. text.FormatMessage (IDS_CANT_CONNECT_TO_MACHINE_NETWORK_UNREACHABLE,
  165. computerName);
  166. break;
  167. case ERROR_NETNAME_DELETED:
  168. text.FormatMessage (IDS_CANT_CONNECT_TO_MACHINE_NETNAME_DELETED,
  169. computerName);
  170. break;
  171. case ERROR_SUCCESS:
  172. ASSERT( !(SV_TYPE_NT & dwServerType) );
  173. text.FormatMessage (IDS_CANT_CONNECT_TO_NON_NT_COMPUTER,
  174. computerName);
  175. dwr = ERROR_BAD_NETPATH;
  176. break;
  177. case ERROR_ACCESS_DENIED:
  178. // We will interpret this as success.
  179. return true;
  180. case ERROR_BAD_NETPATH:
  181. default:
  182. {
  183. HWND hWndParent = 0;
  184. m_pConsole->GetMainWindow (&hWndParent);
  185. iRetVal = DisplayNetMsgError (hWndParent, computerName,
  186. dwr, m_strMessageViewMsg);
  187. bMessageDisplayed = true;
  188. m_bMessageView = true;
  189. return false;
  190. }
  191. break;
  192. }
  193. if ( !bMessageDisplayed )
  194. {
  195. VERIFY (caption.LoadString (IDS_TASKPADTITLE_COMPUTER));
  196. m_pConsole->MessageBox (text, caption,
  197. MB_ICONINFORMATION | MB_YESNO, &iRetVal);
  198. }
  199. }
  200. }
  201. if (IDYES != iRetVal)
  202. {
  203. // revert to local computer focus
  204. QueryRootCookie().SetMachineName (L"");
  205. // Set the persistent name. If we are managing the local computer
  206. // this name should be empty.
  207. m_strMachineNamePersist = L"";
  208. VERIFY (SUCCEEDED (ChangeRootNodeName (L"")) );
  209. iRetVal = IDYES;
  210. dwr = ERROR_SUCCESS;
  211. }
  212. m_bCannotConnect = (ERROR_SUCCESS != dwr);
  213. // Change root node icon
  214. SCOPEDATAITEM item;
  215. ::ZeroMemory (&item, sizeof (SCOPEDATAITEM));
  216. item.mask = SDI_IMAGE | SDI_OPENIMAGE;
  217. item.nImage = (m_bCannotConnect) ? iIconComputerFail : iIconComputer;
  218. item.nOpenImage = item.nImage;
  219. item.ID = QueryBaseRootCookie ().m_hScopeItem;
  220. VERIFY (SUCCEEDED (m_pConsoleNameSpace->SetItem (&item)));
  221. return true;
  222. }
  223. HRESULT CMyComputerComponentData::OnNotifyExpand(LPDATAOBJECT lpDataObject, BOOL bExpanding, HSCOPEITEM hParent)
  224. {
  225. ASSERT( NULL != lpDataObject &&
  226. NULL != hParent &&
  227. NULL != m_pConsoleNameSpace );
  228. if (!bExpanding)
  229. return S_OK;
  230. //
  231. // CODEWORK This code will not work if My Computer becomes an extension,
  232. // since the RawCookie format will not be available.
  233. // WARNING cookie cast
  234. //
  235. CCookie* pBaseParentCookie = NULL;
  236. HRESULT hr = ExtractData( lpDataObject,
  237. CMyComputerDataObject::m_CFRawCookie,
  238. reinterpret_cast<PBYTE>(&pBaseParentCookie),
  239. sizeof(pBaseParentCookie) );
  240. ASSERT( SUCCEEDED(hr) );
  241. CMyComputerCookie* pParentCookie = ActiveCookie(pBaseParentCookie);
  242. ASSERT( NULL != pParentCookie );
  243. // save the HSCOPEITEM of the root node
  244. if ( NULL == pParentCookie->m_hScopeItem )
  245. {
  246. pParentCookie->m_hScopeItem = hParent;
  247. // Ensure root node name is formatted correctly.
  248. CString machineName = pParentCookie->QueryNonNULLMachineName ();
  249. hr = ChangeRootNodeName (machineName);
  250. }
  251. else
  252. {
  253. ASSERT( pParentCookie->m_hScopeItem == hParent );
  254. }
  255. switch ( pParentCookie->m_objecttype )
  256. {
  257. // This node type has a child
  258. case MYCOMPUT_COMPUTER:
  259. break;
  260. // This node type has no children in this snapin but may have dynamic extensions
  261. case MYCOMPUT_SERVERAPPS:
  262. return ExpandServerApps( hParent, pParentCookie );
  263. // These node types have no children
  264. case MYCOMPUT_SYSTEMTOOLS:
  265. case MYCOMPUT_STORAGE:
  266. return S_OK;
  267. default:
  268. TRACE( "CMyComputerComponentData::EnumerateScopeChildren bad parent type\n" );
  269. ASSERT( FALSE );
  270. return S_OK;
  271. }
  272. if ( NULL == hParent ||
  273. !((pParentCookie->m_listScopeCookieBlocks).IsEmpty()) )
  274. {
  275. ASSERT(FALSE);
  276. return S_OK;
  277. }
  278. LoadGlobalCookieStrings();
  279. hr = AddScopeNodes (hParent, *pParentCookie);
  280. return S_OK;
  281. }
  282. ///////////////////////////////////////////////////////////////////////////////
  283. //
  284. // AddScopeNodes
  285. //
  286. // Purpose: Add the nodes that appear immediately below the root node
  287. //
  288. ///////////////////////////////////////////////////////////////////////////////
  289. HRESULT CMyComputerComponentData::AddScopeNodes (HSCOPEITEM hParent, CMyComputerCookie& rParentCookie)
  290. {
  291. if ( !(rParentCookie.m_listScopeCookieBlocks.IsEmpty()) )
  292. {
  293. return S_OK; // scope cookies already present
  294. }
  295. HRESULT hr = S_OK;
  296. LPCWSTR lpcszMachineName = rParentCookie.QueryNonNULLMachineName();
  297. if ( ValidateMachine (lpcszMachineName, true) )
  298. {
  299. SCOPEDATAITEM tSDItem;
  300. ::ZeroMemory(&tSDItem,sizeof(tSDItem));
  301. tSDItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_STATE | SDI_PARAM | SDI_PARENT;
  302. tSDItem.displayname = MMC_CALLBACK;
  303. tSDItem.relativeID = hParent;
  304. tSDItem.nState = 0;
  305. // Create new cookies
  306. CMyComputerCookie* pNewCookie = new CMyComputerCookie(
  307. MYCOMPUT_SYSTEMTOOLS,
  308. lpcszMachineName );
  309. rParentCookie.m_listScopeCookieBlocks.AddHead(
  310. (CBaseCookieBlock*)pNewCookie );
  311. // WARNING cookie cast
  312. tSDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pNewCookie);
  313. tSDItem.nImage = QueryImage( *pNewCookie, FALSE );
  314. tSDItem.nOpenImage = QueryImage( *pNewCookie, TRUE );
  315. hr = m_pConsoleNameSpace->InsertItem(&tSDItem);
  316. ASSERT(SUCCEEDED(hr));
  317. pNewCookie->m_hScopeItem = tSDItem.ID;
  318. ASSERT( NULL != pNewCookie->m_hScopeItem );
  319. pNewCookie = new CMyComputerCookie(
  320. MYCOMPUT_STORAGE,
  321. lpcszMachineName );
  322. rParentCookie.m_listScopeCookieBlocks.AddHead(
  323. (CBaseCookieBlock*)pNewCookie );
  324. // WARNING cookie cast
  325. tSDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pNewCookie);
  326. tSDItem.nImage = QueryImage( *pNewCookie, FALSE );
  327. tSDItem.nOpenImage = QueryImage( *pNewCookie, TRUE );
  328. hr = m_pConsoleNameSpace->InsertItem(&tSDItem);
  329. ASSERT(SUCCEEDED(hr));
  330. pNewCookie->m_hScopeItem = tSDItem.ID;
  331. ASSERT( NULL != pNewCookie->m_hScopeItem );
  332. pNewCookie = new CMyComputerCookie(
  333. MYCOMPUT_SERVERAPPS,
  334. lpcszMachineName );
  335. rParentCookie.m_listScopeCookieBlocks.AddHead(
  336. (CBaseCookieBlock*)pNewCookie );
  337. // WARNING cookie cast
  338. tSDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pNewCookie);
  339. tSDItem.nImage = QueryImage( *pNewCookie, FALSE );
  340. tSDItem.nOpenImage = QueryImage( *pNewCookie, TRUE );
  341. hr = m_pConsoleNameSpace->InsertItem(&tSDItem);
  342. ASSERT(SUCCEEDED(hr));
  343. pNewCookie->m_hScopeItem = tSDItem.ID;
  344. ASSERT( NULL != pNewCookie->m_hScopeItem );
  345. }
  346. else
  347. hr = S_FALSE;
  348. return hr;
  349. }
  350. HRESULT CMyComputerComponentData::OnNotifyDelete(LPDATAOBJECT /*lpDataObject*/)
  351. {
  352. // CODEWORK The user hit the Delete key, I should deal with this
  353. return S_OK;
  354. }
  355. HRESULT CMyComputerComponentData::OnNotifyRelease(LPDATAOBJECT /*lpDataObject*/, HSCOPEITEM /*hItem*/)
  356. {
  357. // JonN 01/26/00: COMPMGMT is never an extension
  358. return S_OK;
  359. }
  360. HRESULT CMyComputerComponentData::OnNotifyPreload(LPDATAOBJECT /*lpDataObject*/, HSCOPEITEM hRootScopeItem)
  361. {
  362. ASSERT (m_fAllowOverrideMachineName);
  363. QueryBaseRootCookie ().m_hScopeItem = hRootScopeItem;
  364. CString machineName = QueryRootCookie ().QueryNonNULLMachineName();
  365. return ChangeRootNodeName (machineName);
  366. }
  367. // global space to store the string handed back to GetDisplayInfo()
  368. // CODEWORK should use "bstr" for ANSI-ization
  369. CString g_strResultColumnText;
  370. BSTR CMyComputerComponentData::QueryResultColumnText(
  371. CCookie& basecookieref,
  372. int nCol )
  373. {
  374. CMyComputerCookie& cookieref = (CMyComputerCookie&)basecookieref;
  375. #ifndef UNICODE
  376. #error not ANSI-enabled
  377. #endif
  378. switch ( cookieref.m_objecttype )
  379. {
  380. case MYCOMPUT_COMPUTER:
  381. if (COLNUM_COMPUTER_NAME == nCol)
  382. return const_cast<BSTR>(((LPCTSTR)g_strMyComputer));
  383. break;
  384. case MYCOMPUT_SYSTEMTOOLS:
  385. if (COLNUM_COMPUTER_NAME == nCol)
  386. return const_cast<BSTR>(((LPCTSTR)g_strSystemTools));
  387. break;
  388. case MYCOMPUT_SERVERAPPS:
  389. if (COLNUM_COMPUTER_NAME == nCol)
  390. return const_cast<BSTR>(((LPCTSTR)g_strServerApps));
  391. break;
  392. case MYCOMPUT_STORAGE:
  393. if (COLNUM_COMPUTER_NAME == nCol)
  394. return const_cast<BSTR>(((LPCTSTR)g_strStorage));
  395. break;
  396. default:
  397. TRACE( "CMyComputerComponentData::EnumerateScopeChildren bad parent type\n" );
  398. ASSERT( FALSE );
  399. break;
  400. }
  401. return L"";
  402. }
  403. int CMyComputerComponentData::QueryImage(CCookie& basecookieref, BOOL /*fOpenImage*/)
  404. {
  405. CMyComputerCookie& cookieref = (CMyComputerCookie&)basecookieref;
  406. switch ( cookieref.m_objecttype )
  407. {
  408. case MYCOMPUT_COMPUTER:
  409. if ( m_bCannotConnect )
  410. return iIconComputerFail;
  411. else
  412. return iIconComputer;
  413. case MYCOMPUT_SYSTEMTOOLS:
  414. return iIconSystemTools;
  415. case MYCOMPUT_SERVERAPPS:
  416. return iIconServerApps;
  417. case MYCOMPUT_STORAGE:
  418. return iIconStorage;
  419. default:
  420. TRACE( "CMyComputerComponentData::QueryImage bad parent type\n" );
  421. ASSERT( FALSE );
  422. break;
  423. }
  424. return iIconComputer;
  425. }
  426. ///////////////////////////////////////////////////////////////////////////////
  427. /// IExtendPropertySheet
  428. STDMETHODIMP CMyComputerComponentData::QueryPagesFor(LPDATAOBJECT pDataObject)
  429. {
  430. MFC_TRY;
  431. if (NULL == pDataObject)
  432. {
  433. ASSERT(FALSE);
  434. return E_POINTER;
  435. }
  436. DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE;
  437. HRESULT hr = ExtractData( pDataObject, CMyComputerDataObject::m_CFDataObjectType, (PBYTE)&dataobjecttype, sizeof(dataobjecttype) );
  438. if ( FAILED(hr) )
  439. return hr;
  440. if (CCT_SNAPIN_MANAGER == dataobjecttype)
  441. return S_OK; // Snapin Manager dialog
  442. CCookie* pBaseParentCookie = NULL;
  443. hr = ExtractData( pDataObject,
  444. CMyComputerDataObject::m_CFRawCookie,
  445. reinterpret_cast<PBYTE>(&pBaseParentCookie),
  446. sizeof(pBaseParentCookie) );
  447. ASSERT( SUCCEEDED(hr) );
  448. CMyComputerCookie* pParentCookie = ActiveCookie(pBaseParentCookie);
  449. ASSERT( NULL != pParentCookie );
  450. if ( MYCOMPUT_COMPUTER == pParentCookie->m_objecttype )
  451. return S_OK; // allow extensibility
  452. return S_FALSE;
  453. MFC_CATCH;
  454. }
  455. STDMETHODIMP CMyComputerComponentData::CreatePropertyPages(
  456. LPPROPERTYSHEETCALLBACK pCallBack,
  457. LONG_PTR /*handle*/, // This handle must be saved in the property page object to notify the parent when modified
  458. LPDATAOBJECT pDataObject)
  459. {
  460. MFC_TRY;
  461. if (NULL == pCallBack || NULL == pDataObject)
  462. {
  463. ASSERT(FALSE);
  464. return E_POINTER;
  465. }
  466. DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE;
  467. HRESULT hr = ExtractData( pDataObject, CMyComputerDataObject::m_CFDataObjectType, (PBYTE)&dataobjecttype, sizeof(dataobjecttype) );
  468. if (CCT_SNAPIN_MANAGER != dataobjecttype)
  469. {
  470. CCookie* pBaseParentCookie = NULL;
  471. hr = ExtractData( pDataObject,
  472. CMyComputerDataObject::m_CFRawCookie,
  473. reinterpret_cast<PBYTE>(&pBaseParentCookie),
  474. sizeof(pBaseParentCookie) );
  475. ASSERT( SUCCEEDED(hr) );
  476. CMyComputerCookie* pParentCookie = ActiveCookie(pBaseParentCookie);
  477. ASSERT( NULL != pParentCookie );
  478. if ( MYCOMPUT_COMPUTER == pParentCookie->m_objecttype )
  479. return S_OK; // allow extensibility
  480. return S_FALSE;
  481. }
  482. //
  483. // Note that once we have established that this is a CCT_SNAPIN_MANAGER cookie,
  484. // we don't care about its other properties. A CCT_SNAPIN_MANAGER cookie is
  485. // equivalent to a BOOL flag asking for the Node Properties page instead of a
  486. // managed object property page. JonN 10/9/96
  487. //
  488. CMyComputerGeneral * pPage = new CMyComputerGeneral();
  489. pPage->SetCaption(IDS_SCOPE_MYCOMPUTER);
  490. // Initialize state of object
  491. ASSERT(NULL != m_pRootCookie);
  492. pPage->InitMachineName(m_pRootCookie->QueryTargetServer());
  493. pPage->SetOutputBuffers(
  494. OUT &m_strMachineNamePersist,
  495. OUT &m_fAllowOverrideMachineName,
  496. OUT &m_pRootCookie->m_strMachineName); // Effective machine name
  497. HPROPSHEETPAGE hPage=CreatePropertySheetPage(&pPage->m_psp);
  498. hr = pCallBack->AddPage(hPage);
  499. ASSERT( SUCCEEDED(hr) );
  500. return S_OK;
  501. MFC_CATCH;
  502. }
  503. STDMETHODIMP CMyComputerComponentData::AddMenuItems(
  504. IDataObject* piDataObject,
  505. IContextMenuCallback* piCallback,
  506. long* pInsertionAllowed)
  507. {
  508. MFC_TRY;
  509. TRACE_METHOD(CMyComputerComponent,AddMenuItems);
  510. TEST_NONNULL_PTR_PARAM(piDataObject);
  511. TEST_NONNULL_PTR_PARAM(piCallback);
  512. TEST_NONNULL_PTR_PARAM(pInsertionAllowed);
  513. TRACE( "CMyComputerComponentData: extending menu\n" );
  514. CCookie* pBaseParentCookie = NULL;
  515. HRESULT hr = ExtractData (piDataObject,
  516. CMyComputerDataObject::m_CFRawCookie,
  517. reinterpret_cast<PBYTE>(&pBaseParentCookie),
  518. sizeof(pBaseParentCookie) );
  519. if ( FAILED (hr) )
  520. {
  521. ASSERT (FALSE);
  522. return S_OK;
  523. }
  524. CMyComputerCookie* pCookie = ActiveCookie (pBaseParentCookie);
  525. if ( !pCookie )
  526. {
  527. ASSERT (FALSE);
  528. return S_OK;
  529. }
  530. if ( *pInsertionAllowed & CCM_INSERTIONALLOWED_TOP )
  531. {
  532. if ( MYCOMPUT_COMPUTER == pCookie->m_objecttype &&
  533. QueryBaseRootCookie ().m_hScopeItem)
  534. {
  535. hr = ::LoadAndAddMenuItem (piCallback,
  536. IDM_CHANGE_COMPUTER_TOP, IDM_CHANGE_COMPUTER_TOP,
  537. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  538. 0,
  539. AfxGetInstanceHandle ());
  540. }
  541. }
  542. if ( *pInsertionAllowed & CCM_INSERTIONALLOWED_TASK )
  543. {
  544. if ( MYCOMPUT_COMPUTER == pCookie->m_objecttype &&
  545. QueryBaseRootCookie ().m_hScopeItem)
  546. {
  547. hr = ::LoadAndAddMenuItem (piCallback,
  548. IDM_CHANGE_COMPUTER_TASK, IDM_CHANGE_COMPUTER_TASK,
  549. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  550. 0,
  551. AfxGetInstanceHandle ());
  552. }
  553. }
  554. return hr;
  555. MFC_CATCH;
  556. } // CMyComputerComponentData::AddMenuItems()
  557. STDMETHODIMP CMyComputerComponentData::Command(
  558. LONG lCommandID,
  559. IDataObject* piDataObject )
  560. {
  561. MFC_TRY;
  562. TRACE_METHOD(CMyComputerComponentData,Command);
  563. TEST_NONNULL_PTR_PARAM(piDataObject);
  564. TRACE( "CMyComputerComponentData::Command: command %ld selected\n", lCommandID );
  565. switch (lCommandID)
  566. {
  567. case IDM_CHANGE_COMPUTER_TASK:
  568. case IDM_CHANGE_COMPUTER_TOP:
  569. {
  570. ASSERT (QueryBaseRootCookie ().m_hScopeItem);
  571. return OnChangeComputer (piDataObject);
  572. }
  573. break;
  574. default:
  575. ASSERT(FALSE);
  576. break;
  577. }
  578. return S_OK;
  579. MFC_CATCH;
  580. } // CMyComputerComponentData::Command()
  581. ///////////////////////////////////////////////////////////////////////////////
  582. //
  583. // OnChangeComputer ()
  584. //
  585. // Purpose: Change the machine managed by the snapin
  586. //
  587. // Input: piDataObject - the selected node. This should be the root node
  588. // the snapin.
  589. // Output: Returns S_OK on success
  590. //
  591. ///////////////////////////////////////////////////////////////////////////////
  592. // 1. Launch object picker and get new computer name
  593. // 2. Change root node text
  594. // 3. Save new computer name to persistent name
  595. // 4. Delete subordinate nodes
  596. // 5. Re-add subordinate nodes
  597. HRESULT CMyComputerComponentData::OnChangeComputer(IDataObject * piDataObject)
  598. {
  599. MFC_TRY;
  600. HWND hWndParent = NULL;
  601. HRESULT hr = m_pConsole->GetMainWindow (&hWndParent);
  602. CComBSTR sbstrTargetComputer;
  603. //
  604. // JonN 12/7/99 using CHOOSER2
  605. //
  606. if ( CHOOSER2_PickTargetComputer( AfxGetInstanceHandle(),
  607. hWndParent,
  608. &sbstrTargetComputer ) )
  609. {
  610. CString strTargetComputer = sbstrTargetComputer;
  611. strTargetComputer.MakeUpper ();
  612. // added IsLocalComputername 1/27/99 JonN
  613. // If the user chooses the local computer, treat that as if they had chosen
  614. // "Local Computer" in Snapin Manager. This means that there is no way to
  615. // reset the snapin to target explicitly at this computer without either
  616. // reloading the snapin from Snapin Manager, or going to a different computer.
  617. // When the Choose Target Computer UI is revised, we can make this more
  618. // consistent with Snapin Manager.
  619. if ( IsLocalComputername( strTargetComputer ) )
  620. strTargetComputer = L"";
  621. QueryRootCookie().SetMachineName (strTargetComputer);
  622. // Set the persistent name. If we are managing the local computer
  623. // this name should be empty.
  624. m_strMachineNamePersist = strTargetComputer;
  625. hr = ChangeRootNodeName (strTargetComputer);
  626. if ( SUCCEEDED(hr) )
  627. {
  628. // Delete subordinates and re-add
  629. HSCOPEITEM hRootScopeItem = QueryBaseRootCookie ().m_hScopeItem;
  630. MMC_COOKIE lCookie = 0;
  631. HSCOPEITEM hChild = 0;
  632. do {
  633. hr = m_pConsoleNameSpace->GetChildItem (hRootScopeItem,
  634. &hChild, &lCookie);
  635. if ( S_OK != hr )
  636. break;
  637. hr = m_pConsoleNameSpace->DeleteItem (hChild, TRUE);
  638. ASSERT (SUCCEEDED (hr));
  639. if ( !SUCCEEDED(hr) )
  640. break;
  641. CMyComputerCookie* pCookie =
  642. reinterpret_cast <CMyComputerCookie*> (lCookie);
  643. if ( !pCookie )
  644. continue;
  645. CMyComputerCookie& rootCookie = QueryRootCookie();
  646. POSITION pos1 = 0;
  647. POSITION pos2 = 0;
  648. CBaseCookieBlock* pScopeCookie = 0;
  649. for ( pos1 = rootCookie.m_listScopeCookieBlocks.GetHeadPosition ();
  650. ( pos2 = pos1) != NULL;
  651. )
  652. {
  653. pScopeCookie = rootCookie.m_listScopeCookieBlocks.GetNext (pos1);
  654. ASSERT (pScopeCookie);
  655. if ( pScopeCookie == pCookie )
  656. {
  657. rootCookie.m_listScopeCookieBlocks.RemoveAt (pos2);
  658. pScopeCookie->Release ();
  659. }
  660. }
  661. } while (S_OK == hr);
  662. hr = AddScopeNodes (hRootScopeItem, QueryRootCookie ());
  663. hr = m_pConsole->UpdateAllViews (piDataObject, 0, HINT_SELECT_ROOT_NODE);
  664. }
  665. }
  666. return hr;
  667. MFC_CATCH;
  668. }
  669. ///////////////////////////////////////////////////////////////////////////////
  670. //
  671. // ChangeRootNodeName ()
  672. //
  673. // Purpose: Change the text of the root node
  674. //
  675. // Input: newName - the new machine name that the snapin manages
  676. // Output: Returns S_OK on success
  677. //
  678. ///////////////////////////////////////////////////////////////////////////////
  679. HRESULT CMyComputerComponentData::ChangeRootNodeName(const CString & newName)
  680. {
  681. MFC_TRY;
  682. ASSERT (QueryBaseRootCookie ().m_hScopeItem);
  683. if ( !QueryBaseRootCookie ().m_hScopeItem )
  684. return E_UNEXPECTED;
  685. CString machineName (newName);
  686. CString formattedName = FormatDisplayName (machineName);
  687. SCOPEDATAITEM item;
  688. ::ZeroMemory (&item, sizeof (SCOPEDATAITEM));
  689. item.mask = SDI_STR;
  690. item.displayname = (LPTSTR) (LPCTSTR) formattedName;
  691. item.ID = QueryBaseRootCookie ().m_hScopeItem;
  692. return m_pConsoleNameSpace->SetItem (&item);
  693. MFC_CATCH;
  694. }
  695. CString FormatDisplayName(CString machineName)
  696. {
  697. CString formattedName;
  698. // If strDisplayName is empty, then this manages the local machine. Get
  699. // the local machine name. Then format the computer name with the snapin
  700. // name
  701. if (machineName.IsEmpty())
  702. {
  703. VERIFY (formattedName.LoadString (IDS_SCOPE_MYCOMPUTER_LOCAL_MACHINE));
  704. }
  705. else
  706. {
  707. // strip off the leading whackWhack
  708. if ( machineName.Find (L"\\\\") == 0 )
  709. {
  710. machineName = machineName.GetBuffer (machineName.GetLength ()) + 2;
  711. machineName.ReleaseBuffer ();
  712. }
  713. machineName.MakeUpper ();
  714. formattedName.FormatMessage (IDS_SCOPE_MYCOMPUTER_ON_MACHINE, machineName);
  715. }
  716. return formattedName;
  717. }
  718. int DisplayNetMsgError (HWND hWndParent, const CString& computerName, NET_API_STATUS dwErr, CString& displayedMessage)
  719. {
  720. int retVal = IDNO;
  721. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  722. LPVOID lpMsgBuf = 0;
  723. HMODULE hNetMsgDLL = ::LoadLibrary (L"netmsg.dll");
  724. if ( hNetMsgDLL )
  725. {
  726. ::FormatMessage (
  727. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
  728. hNetMsgDLL,
  729. dwErr,
  730. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  731. (LPTSTR) &lpMsgBuf, 0, NULL);
  732. // Display the string.
  733. CString text;
  734. CString caption;
  735. text.FormatMessage (IDS_CANT_CONNECT_TO_MACHINE, (LPCWSTR) computerName, (LPTSTR) lpMsgBuf);
  736. VERIFY (caption.LoadString (IDS_TASKPADTITLE_COMPUTER));
  737. retVal = ::MessageBox (hWndParent, text, caption, MB_ICONWARNING | MB_OK);
  738. displayedMessage = text;
  739. // Free the buffer.
  740. ::LocalFree (lpMsgBuf);
  741. ::FreeLibrary (hNetMsgDLL);
  742. }
  743. return retVal;
  744. }