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.

1824 lines
58 KiB

  1. // cmponent.cpp : Implementation of CFileMgmtComponent
  2. #include "stdafx.h"
  3. #include "cookie.h"
  4. #include "safetemp.h"
  5. #include "macros.h"
  6. USE_HANDLE_MACROS("FILEMGMT(cmponent.cpp)")
  7. #include "ShrProp.h" // Share Properties Pages
  8. #include "FileSvc.h" // FileServiceProvider
  9. #include "smb.h"
  10. #include "fpnw.h"
  11. #include "sfm.h"
  12. #include "dataobj.h"
  13. #include "cmponent.h" // CFileMgmtComponent
  14. #include "compdata.h" // CFileMgmtComponentData
  15. #include "stdutils.h" // SynchronousCreateProcess
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #include "stdcmpnt.cpp" // CComponent
  22. UINT g_aColumns0[2] =
  23. {IDS_ROOT_NAME, 0};
  24. UINT g_aColumns1[6] =
  25. {IDS_SHARES_SHARED_FOLDER, IDS_SHARES_SHARED_PATH, IDS_SHARES_TRANSPORT,
  26. IDS_SHARES_NUM_SESSIONS, IDS_SHARES_COMMENT, 0};
  27. UINT g_aColumns2[8] =
  28. {IDS_CONN_USERNAME, IDS_CONN_COMPUTERNAME, IDS_CONN_TRANSPORT, IDS_CONN_NUM_FILES,
  29. IDS_CONN_CONNECTED_TIME, IDS_CONN_IDLE_TIME, IDS_CONN_IS_GUEST, 0};
  30. UINT g_aColumns3[6] =
  31. {IDS_FILE_FILENAME, IDS_FILE_USERNAME, IDS_FILE_TRANSPORT, IDS_FILE_NUM_LOCKS,
  32. IDS_FILE_OPEN_MODE, 0};
  33. UINT g_aColumns4[6] =
  34. { IDS_SERVICE_SERVICENAME, IDS_SERVICE_DESCRIPTION, IDS_SERVICE_STATUS,
  35. IDS_SERVICE_STARTUPTYPE, IDS_SERVICE_SECURITYCONTEXT, 0};
  36. UINT* g_Columns[FILEMGMT_NUMTYPES] =
  37. { g_aColumns0, // FILEMGMT_ROOT
  38. g_aColumns1, // FILEMGMT_SHARES
  39. g_aColumns2, // FILEMGMT_SESSIONS
  40. g_aColumns3, // FILEMGMT_RESOURCES
  41. g_aColumns4, // FILEMGMT_SERVICES
  42. NULL, // FILEMGMT_SHARE
  43. NULL, // FILEMGMT_SESSION
  44. NULL, // FILEMGMT_RESOURCE
  45. NULL // FILEMGMT_SERVICE
  46. };
  47. UINT** g_aColumns = g_Columns;
  48. /*
  49. const UINT aColumns[STD_NODETYPE_NUMTYPES][STD_MAX_COLUMNS] =
  50. { {IDS_ROOT_NAME, 0,0,0,0,0,0},
  51. {IDS_SHARES_SHARED_FOLDER, IDS_SHARES_SHARED_PATH, IDS_SHARES_TRANSPORT,
  52. IDS_SHARES_NUM_SESSIONS, IDS_SHARES_COMMENT, 0,0},
  53. {IDS_CONN_USERNAME, IDS_CONN_COMPUTERNAME, IDS_CONN_TRANSPORT, IDS_CONN_NUM_FILES,
  54. IDS_CONN_CONNECTED_TIME, IDS_CONN_IDLE_TIME, IDS_CONN_IS_GUEST},
  55. {IDS_FILE_FILENAME, IDS_FILE_USERNAME, IDS_FILE_TRANSPORT, IDS_FILE_NUM_LOCKS,
  56. IDS_FILE_OPEN_MODE, 0,0},
  57. { IDS_SERVICE_SERVICENAME, IDS_SERVICE_DESCRIPTION, IDS_SERVICE_STATUS,
  58. IDS_SERVICE_STARTUPTYPE, IDS_SERVICE_SECURITYCONTEXT, 0,0 },
  59. {0,0,0,0,0,0},
  60. {0,0,0,0,0,0},
  61. {0,0,0,0,0,0},
  62. {0,0,0,0,0,0}
  63. };
  64. */
  65. //
  66. // CODEWORK this should be in a resource, for example code on loading data resources see
  67. // D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
  68. // JonN 10/11/96
  69. //
  70. int g_aColumnWidths0[1] = {150};
  71. int g_aColumnWidths1[5] = {AUTO_WIDTH,120 ,90 ,AUTO_WIDTH,150};
  72. int g_aColumnWidths2[7] = {100 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH};
  73. int g_aColumnWidths3[5] = {120 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH};
  74. int g_aColumnWidths4[5] = {130 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH};
  75. int* g_ColumnWidths[FILEMGMT_NUMTYPES] =
  76. { g_aColumnWidths0, // FILEMGMT_ROOT
  77. g_aColumnWidths1, // FILEMGMT_SHARES
  78. g_aColumnWidths2, // FILEMGMT_SESSIONS
  79. g_aColumnWidths3, // FILEMGMT_RESOURCES
  80. g_aColumnWidths4, // FILEMGMT_SERVICES
  81. NULL, // FILEMGMT_SHARE
  82. NULL, // FILEMGMT_SESSION
  83. NULL, // FILEMGMT_RESOURCE
  84. NULL // FILEMGMT_SERVICE
  85. };
  86. int** g_aColumnWidths = g_ColumnWidths;
  87. /*
  88. const int aColumnWidths[STD_NODETYPE_NUMTYPES][STD_MAX_COLUMNS] =
  89. { {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_ROOT
  90. {AUTO_WIDTH,120 ,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SHARES
  91. {100 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SESSIONS
  92. {120 ,AUTO_WIDTH,90 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_RESOURCES
  93. {130 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SERVICES
  94. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SHARE
  95. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_SESSION
  96. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // FILEMGMT_RESOURCE
  97. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH} // FILEMGMT_SERVICE
  98. };
  99. */
  100. CString g_cstrClientName;
  101. CString g_cstrGuest;
  102. CString g_cstrYes;
  103. CString g_cstrNo;
  104. // Note that m_pFileMgmtData is still NULL during construction
  105. CFileMgmtComponent::CFileMgmtComponent()
  106. : m_pControlbar( NULL )
  107. , m_pSvcMgmtToolbar( NULL )
  108. , m_pFileMgmtToolbar( NULL )
  109. , m_pViewedCookie( NULL )
  110. , m_pSelectedCookie( NULL )
  111. , m_iSortColumn(0)
  112. , m_dwSortFlags(0)
  113. {
  114. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  115. }
  116. CFileMgmtComponent::~CFileMgmtComponent()
  117. {
  118. TRACE_METHOD(CFileMgmtComponent,ReleaseAll);
  119. /* now in CFileMgmtComponentData
  120. if (m_hScManager != NULL)
  121. {
  122. AFX_MANAGE_STATE(AfxGetStaticModuleState( )); // required for CWaitCursor
  123. CWaitCursor wait;
  124. // Close the service control manager
  125. (void)::CloseServiceHandle(m_hScManager);
  126. } // if
  127. */
  128. VERIFY( SUCCEEDED(ReleaseAll()) );
  129. }
  130. HRESULT CFileMgmtComponent::ReleaseAll()
  131. {
  132. MFC_TRY;
  133. TRACE_METHOD(CFileMgmtComponent,ReleaseAll);
  134. if ( NULL != m_pViewedCookie )
  135. {
  136. // We did not get an equal number of MMCN_SHOW(1) and
  137. // MMCN_SHOW(0) notifications
  138. // CODEWORK should assert here but MMC is currently broken
  139. // ASSERT(FALSE);
  140. m_pViewedCookie->ReleaseResultChildren();
  141. m_pViewedCookie = NULL;
  142. }
  143. // We should get an equal number of MMCN_SELECT(1) and MMCN_SELECT(0) notifications
  144. // CODEWORK should assert this but MMC is broken ASSERT( NULL == m_pSelectedCookie );
  145. SAFE_RELEASE(m_pSvcMgmtToolbar);
  146. SAFE_RELEASE(m_pFileMgmtToolbar);
  147. SAFE_RELEASE(m_pControlbar);
  148. return CComponent::ReleaseAll();
  149. MFC_CATCH;
  150. }
  151. FileServiceProvider* CFileMgmtComponent::GetFileServiceProvider(
  152. FILEMGMT_TRANSPORT transport )
  153. {
  154. return QueryComponentDataRef().GetFileServiceProvider(transport);
  155. }
  156. BOOL CFileMgmtComponent::IsServiceSnapin()
  157. {
  158. return QueryComponentDataRef().IsServiceSnapin();
  159. }
  160. /////////////////////////////////////////////////////////////////////////////
  161. // IComponent Implementation
  162. HRESULT CFileMgmtComponent::LoadStrings()
  163. {
  164. Service_LoadResourceStrings();
  165. return S_OK;
  166. }
  167. HRESULT CFileMgmtComponent::LoadColumns( CFileMgmtCookie* pcookie )
  168. {
  169. TEST_NONNULL_PTR_PARAM(pcookie);
  170. ASSERT(m_pHeader != NULL);
  171. #ifdef SNAPIN_PROTOTYPER
  172. (void)Prototyper_FInsertColumns(pcookie);
  173. return S_OK;
  174. #endif
  175. if (g_cstrGuest.IsEmpty())
  176. VERIFY(g_cstrGuest.LoadString(IDS_GUEST));
  177. if (g_cstrYes.IsEmpty())
  178. VERIFY(g_cstrYes.LoadString(IDS_YES));
  179. if (g_cstrNo.IsEmpty())
  180. VERIFY(g_cstrNo.LoadString(IDS_NO));
  181. return LoadColumnsFromArrays( pcookie->QueryObjectType() );
  182. }
  183. // OnPropertyChange() is generated by MMCPropertyChangeNotify( param )
  184. HRESULT CFileMgmtComponent::OnPropertyChange( LPARAM param )
  185. {
  186. LPDATAOBJECT pdataobject = reinterpret_cast<LPDATAOBJECT> (param);
  187. VERIFY( SUCCEEDED( RefreshAllViews(pdataobject) ) );
  188. // The recipient of this notification is required to release the data object
  189. (void) pdataobject->Release();
  190. return S_OK;
  191. } // CFileMgmtComponent::OnPropertyChange()
  192. //
  193. // In case of multiselect, piDataObject may point to a composite data object (MMC_MS_DO).
  194. // RefreshAllViewsOnSelectedObject will crack down MMC_MS_DO to retrieve SI_MS_DO, then call
  195. // RefreshAllViews on one of the selected objects in the internal list.
  196. //
  197. HRESULT CFileMgmtComponent::RefreshAllViewsOnSelectedObject(LPDATAOBJECT piDataObject)
  198. {
  199. BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject);
  200. if (!bMultiSelectObject)
  201. return RefreshAllViews(piDataObject);
  202. //
  203. // piDataObject is the composite data object (MMC_MS_DO) created by MMC.
  204. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  205. // we provided to MMC in QueryDataObject().
  206. //
  207. IDataObject *piSIMSDO = NULL;
  208. HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO);
  209. if (SUCCEEDED(hr))
  210. {
  211. CFileMgmtDataObject *pDataObj = NULL;
  212. hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
  213. if (SUCCEEDED(hr))
  214. {
  215. //
  216. // get the internal list of data objects of selected items, operate on one of them.
  217. //
  218. CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
  219. ASSERT(!pMultiSelectObjList->empty());
  220. hr = RefreshAllViews(*(pMultiSelectObjList->begin()));
  221. }
  222. }
  223. return hr;
  224. }
  225. // Forces all views of the specified data object to refresh
  226. HRESULT CFileMgmtComponent::RefreshAllViews( LPDATAOBJECT pDataObject )
  227. {
  228. if ( NULL == pDataObject || NULL == m_pConsole )
  229. {
  230. ASSERT(FALSE);
  231. return ERROR_INVALID_PARAMETER;
  232. }
  233. // This is new code for updating the Service list using a mark-and-sweep algorithm.
  234. // Eventually this should be applied to all result cookies.
  235. CCookie* pbasecookie = NULL;
  236. HRESULT hr = ExtractData(
  237. pDataObject,
  238. CDataObject::m_CFRawCookie,
  239. &pbasecookie,
  240. sizeof(pbasecookie) );
  241. RETURN_HR_IF_FAIL; // MMC shouldn't have given me someone else's cookie
  242. pbasecookie = QueryBaseComponentDataRef().ActiveBaseCookie( pbasecookie );
  243. CFileMgmtCookie* pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie);
  244. RETURN_E_FAIL_IF_NULL(pUpdatedCookie);
  245. FileMgmtObjectType objTypeForUpdatedCookie = pUpdatedCookie->QueryObjectType();
  246. if ( FILEMGMT_SERVICE == objTypeForUpdatedCookie )
  247. {
  248. if ( NULL == m_pViewedCookie
  249. || FILEMGMT_SERVICES != m_pViewedCookie->QueryObjectType()
  250. )
  251. {
  252. return S_OK; // not a service cookie update
  253. }
  254. pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(m_pViewedCookie);
  255. RETURN_E_FAIL_IF_NULL(pUpdatedCookie);
  256. objTypeForUpdatedCookie = FILEMGMT_SERVICES;
  257. }
  258. if ( FILEMGMT_SERVICES == objTypeForUpdatedCookie )
  259. {
  260. CFileMgmtScopeCookie* pScopeCookie = dynamic_cast<CFileMgmtScopeCookie*>(pUpdatedCookie);
  261. RETURN_E_FAIL_IF_NULL(pScopeCookie);
  262. // "Mark" -- Mark all existing list elements as "delete"
  263. pScopeCookie->MarkResultChildren( NEWRESULTCOOKIE_DELETE );
  264. // "Sweep" -- Read the new list. When a new element is the same object
  265. // as an existing element not yet seen, mark the old element as "old"
  266. // and update its fields. Otherwise, add it as a "new" element.
  267. hr = QueryComponentDataRef().Service_PopulateServices(m_pResultData, pScopeCookie);
  268. RETURN_HR_IF_FAIL;
  269. // Refresh all views to conform with the new list.
  270. hr = m_pConsole->UpdateAllViews( pDataObject, 2L, 0L );
  271. RETURN_HR_IF_FAIL;
  272. // UpdateToolbar if selected
  273. hr = m_pConsole->UpdateAllViews( pDataObject, 3L, 0L );
  274. RETURN_HR_IF_FAIL;
  275. // Remove items which are still marked "delete".
  276. pScopeCookie->RemoveMarkedChildren();
  277. pScopeCookie->MarkResultChildren( NEWRESULTCOOKIE_OLD );
  278. return S_OK;
  279. }
  280. //
  281. // JonN 1/27/00: WinSE 5875: The refresh action is liable to delete pDataObject
  282. // unless we keep an extra refcount. In practice, this only appears to happen
  283. // when we delete a share in taskpad view.
  284. //
  285. CComPtr<IDataObject> spDataObject = pDataObject;
  286. // clear all views of this data
  287. hr = m_pConsole->UpdateAllViews( pDataObject, 0L, 0L );
  288. RETURN_HR_IF_FAIL;
  289. // reread all views of this data
  290. hr = m_pConsole->UpdateAllViews( pDataObject, 1L, 0L );
  291. RETURN_HR_IF_FAIL;
  292. // UpdateToolbar if selected
  293. hr = m_pConsole->UpdateAllViews( pDataObject, 3L, 0L );
  294. return hr;
  295. } // CFileMgmtComponent::RefreshAllViews()
  296. // OnViewChange is generated by UpdateAllViews( lpDataObject, data, hint )
  297. HRESULT CFileMgmtComponent::OnViewChange( LPDATAOBJECT lpDataObject, LPARAM data, LPARAM /*hint*/ )
  298. {
  299. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  300. CWaitCursor wait;
  301. ASSERT( NULL != lpDataObject );
  302. if (NULL == m_pViewedCookie) // skip this component if not being viewed
  303. return S_OK;
  304. CCookie* pbasecookie = NULL;
  305. HRESULT hr = ExtractData( lpDataObject,
  306. CDataObject::m_CFRawCookie,
  307. &pbasecookie,
  308. sizeof(pbasecookie) );
  309. RETURN_HR_IF_FAIL; // MMC shouldn't have given me someone else's cookie
  310. pbasecookie = QueryBaseComponentDataRef().ActiveBaseCookie( pbasecookie );
  311. CFileMgmtCookie* pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie);
  312. RETURN_E_FAIL_IF_NULL(pUpdatedCookie);
  313. FileMgmtObjectType objTypeForUpdatedCookie = pUpdatedCookie->QueryObjectType();
  314. switch (m_pViewedCookie->QueryObjectType())
  315. {
  316. case FILEMGMT_ROOT:
  317. return S_OK; // there is never any need to refresh this
  318. case FILEMGMT_RESOURCES:
  319. if ( FILEMGMT_RESOURCE == objTypeForUpdatedCookie ||
  320. FILEMGMT_RESOURCES == objTypeForUpdatedCookie)
  321. break;
  322. // fall through
  323. case FILEMGMT_SESSIONS:
  324. if ( FILEMGMT_SESSION == objTypeForUpdatedCookie ||
  325. FILEMGMT_SESSIONS == objTypeForUpdatedCookie)
  326. break;
  327. // fall through
  328. case FILEMGMT_SHARES:
  329. if ( FILEMGMT_SHARE == objTypeForUpdatedCookie ||
  330. FILEMGMT_SHARES == objTypeForUpdatedCookie)
  331. break;
  332. return S_OK;
  333. case FILEMGMT_SERVICES:
  334. if ( FILEMGMT_SERVICE == objTypeForUpdatedCookie ||
  335. FILEMGMT_SERVICES == objTypeForUpdatedCookie)
  336. break;
  337. return S_OK;
  338. case FILEMGMT_SHARE:
  339. case FILEMGMT_SESSION:
  340. case FILEMGMT_RESOURCE:
  341. case FILEMGMT_SERVICE:
  342. default:
  343. ASSERT(FALSE); // this shouldn't be possible
  344. return S_OK;
  345. }
  346. // There should be no need to compare machine name, since these are both from the
  347. // same instance.
  348. if ( 0L == data )
  349. {
  350. ASSERT( NULL != m_pResultData );
  351. VERIFY( SUCCEEDED(m_pResultData->DeleteAllRsltItems()) );
  352. m_pViewedCookie->ReleaseResultChildren();
  353. //
  354. // At this point, m_pViewedCookie is still the viewed cookie for this IComponent
  355. // but (once this has happened to all of the views) its list of result children
  356. // is empty and its m_nResultCookiesRefcount is zero. This must be followed
  357. // promptly with PopulateListbox calls for these views since this is not a good
  358. // state for the cookie.
  359. //
  360. }
  361. else if ( 1L == data )
  362. {
  363. VERIFY( SUCCEEDED(PopulateListbox( m_pViewedCookie )) );
  364. }
  365. else if ( 2L == data )
  366. {
  367. VERIFY( SUCCEEDED(RefreshNewResultCookies( *m_pViewedCookie )) );
  368. }
  369. else if ( 3L == data )
  370. {
  371. if (m_pSelectedCookie == pbasecookie)
  372. UpdateToolbar(lpDataObject, TRUE);
  373. }
  374. else
  375. {
  376. ASSERT(FALSE);
  377. }
  378. return S_OK;
  379. } // CFileMgmtComponent::OnViewChange()
  380. /////////////////////////////////////////////////////////////////////
  381. // CFileMgmtComponent::CComponent::OnNotifyRefresh()
  382. //
  383. // Virtual function called by CComponent::IComponent::Notify(MMCN_REFRESH)
  384. // OnNotifyRefresh is generated by enabling the verb MMC_VERB_REFRESH.
  385. HRESULT CFileMgmtComponent::OnNotifyRefresh( LPDATAOBJECT lpDataObject )
  386. {
  387. TRACE0("CFileMgmtComponent::OnNotifyRefresh()\n");
  388. ASSERT(m_pResultData != NULL);
  389. if ( !m_pResultData )
  390. return E_POINTER;
  391. if ( !m_pViewedCookie )
  392. {
  393. ASSERT(FALSE);
  394. return S_OK;
  395. }
  396. // We used to use the cookie here from lpDataObject. However, if one node
  397. // is selected and the user right clicks on a different one we an
  398. // lpDataObject for a node that is not enumerated in the result pane.
  399. // It results in bizarre behavior. So use the m_pViewedCookie, instead.
  400. HRESULT hr = S_OK;
  401. switch (m_pViewedCookie->QueryObjectType())
  402. {
  403. case FILEMGMT_SHARES:
  404. case FILEMGMT_SESSIONS:
  405. case FILEMGMT_RESOURCES:
  406. case FILEMGMT_SERVICES:
  407. (void) RefreshAllViews( lpDataObject );
  408. break;
  409. case FILEMGMT_ROOT:
  410. case FILEMGMT_SERVICE: // Service was selected
  411. case FILEMGMT_SHARE: // Share was selected
  412. case FILEMGMT_SESSION: // Session was selected
  413. case FILEMGMT_RESOURCE: // Open file was selected
  414. default:
  415. // This can happen if you select Shares, then select Shared Folders,
  416. // then right-click Shares and choose Refresh. JonN 12/7/98
  417. break; // no need to refresh
  418. }
  419. return S_OK;
  420. }
  421. /////////////////////////////////////////////////////////////////////
  422. // CFileMgmtComponent::RefreshNewResultCookies()
  423. // 12/03/98 JonN Created
  424. // In the mark-and-sweep refresh algorithm, we have already marked all cookies
  425. // as "old", "new" or "delete". The view must now be made to conform with the list.
  426. HRESULT CFileMgmtComponent::RefreshNewResultCookies( CCookie& refparentcookie )
  427. {
  428. ASSERT( NULL != m_pResultData );
  429. RESULTDATAITEM tRDItem;
  430. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  431. tRDItem.nCol = 0;
  432. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  433. tRDItem.str = MMC_CALLBACK;
  434. // CODEWORK should use MMC_ICON_CALLBACK here
  435. HRESULT hr = S_OK;
  436. POSITION pos = refparentcookie.m_listResultCookieBlocks.GetHeadPosition();
  437. while (NULL != pos)
  438. {
  439. CBaseCookieBlock* pblock = refparentcookie.m_listResultCookieBlocks.GetNext( pos );
  440. ASSERT( NULL != pblock && 1 == pblock->QueryNumCookies() );
  441. CCookie* pbasecookie = pblock->QueryBaseCookie(0);
  442. CNewResultCookie* pcookie = dynamic_cast<CNewResultCookie*>(pbasecookie);
  443. RETURN_E_FAIL_IF_NULL(pcookie);
  444. if ( pcookie->IsMarkedOld() )
  445. {
  446. continue; // Leave this one alone
  447. }
  448. else if ( pcookie->IsMarkedNew() )
  449. { // This one was just added to the list, add it to the view
  450. tRDItem.nImage = QueryBaseComponentDataRef().QueryImage( *pbasecookie, FALSE );
  451. // WARNING cookie cast
  452. tRDItem.lParam = reinterpret_cast<LPARAM>(pbasecookie);
  453. hr = m_pResultData->InsertItem(&tRDItem);
  454. if ( FAILED(hr) )
  455. {
  456. ASSERT(FALSE);
  457. break;
  458. }
  459. }
  460. else if ( pcookie->IsMarkedChanged() )
  461. { // This one was already in the list but its fields were altered, update
  462. HRESULTITEM hItem = 0;
  463. hr = m_pResultData->FindItemByLParam( reinterpret_cast<LPARAM>(pbasecookie), &hItem );
  464. if ( FAILED(hr) || 0 == hItem )
  465. {
  466. ASSERT(FALSE);
  467. continue;
  468. }
  469. VERIFY( SUCCEEDED(m_pResultData->UpdateItem( hItem )) );
  470. }
  471. else
  472. { // This one was just marked for deletion, remove it from the view
  473. // CODEWORK This may be a performance problem when the list is long
  474. // CODEWORK BryanWal doesn't trust FindItemByLParam! Test carefully!
  475. ASSERT( pcookie->IsMarkedForDeletion() );
  476. HRESULTITEM hItem = 0;
  477. hr = m_pResultData->FindItemByLParam( reinterpret_cast<LPARAM>(pbasecookie), &hItem );
  478. if ( FAILED(hr) || 0 == hItem )
  479. {
  480. ASSERT(FALSE);
  481. continue;
  482. }
  483. VERIFY( SUCCEEDED(m_pResultData->DeleteItem( hItem, 0 )) );
  484. }
  485. }
  486. VERIFY( SUCCEEDED(m_pResultData->Sort( m_iSortColumn , m_dwSortFlags, 0 )) );
  487. return hr;
  488. }
  489. HRESULT CFileMgmtComponent::OnNotifySelect( LPDATAOBJECT lpDataObject, BOOL fSelected )
  490. {
  491. HRESULT hr = S_OK;
  492. BOOL bMultiSelectObject = FALSE;
  493. //
  494. // MMC passes in SI_MS_DO in MMCN_SELECT in case of multiselection.
  495. //
  496. CFileMgmtDataObject *pDataObj = NULL;
  497. hr = ExtractData(lpDataObject, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
  498. if (SUCCEEDED(hr))
  499. {
  500. CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
  501. bMultiSelectObject = !(pMultiSelectObjList->empty());
  502. }
  503. //
  504. // no verbs to add for multi-selected SharedFolders items
  505. //
  506. if (!bMultiSelectObject)
  507. {
  508. CCookie* pbasecookie = NULL;
  509. hr = ExtractData( lpDataObject,
  510. CDataObject::m_CFRawCookie,
  511. &pbasecookie,
  512. sizeof(pbasecookie) );
  513. RETURN_HR_IF_FAIL; // MMC shouldn't have given me someone else's cookie
  514. pbasecookie = QueryBaseComponentDataRef().ActiveBaseCookie( pbasecookie );
  515. CFileMgmtCookie* pUpdatedCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie);
  516. RETURN_E_FAIL_IF_NULL(pUpdatedCookie);
  517. m_pSelectedCookie = (fSelected) ? pUpdatedCookie : NULL;
  518. UpdateDefaultVerbs();
  519. }
  520. return S_OK;
  521. }
  522. void CFileMgmtComponent::UpdateDefaultVerbs()
  523. {
  524. if (NULL == m_pSelectedCookie)
  525. return;
  526. FileMgmtObjectType objtypeSelected = m_pSelectedCookie->QueryObjectType();
  527. if (NULL != m_pViewedCookie)
  528. {
  529. BOOL fEnableRefresh = FALSE;
  530. FileMgmtObjectType objtypeViewed = m_pViewedCookie->QueryObjectType();
  531. switch (objtypeViewed)
  532. {
  533. case FILEMGMT_SHARES:
  534. if (FILEMGMT_SHARES == objtypeSelected || FILEMGMT_SHARE == objtypeSelected)
  535. fEnableRefresh = TRUE;
  536. break;
  537. case FILEMGMT_SESSIONS:
  538. if (FILEMGMT_SESSIONS == objtypeSelected || FILEMGMT_SESSION == objtypeSelected)
  539. fEnableRefresh = TRUE;
  540. break;
  541. case FILEMGMT_RESOURCES:
  542. if (FILEMGMT_RESOURCES == objtypeSelected || FILEMGMT_RESOURCE == objtypeSelected)
  543. fEnableRefresh = TRUE;
  544. break;
  545. case FILEMGMT_SERVICES:
  546. if (FILEMGMT_SERVICES == objtypeSelected || FILEMGMT_SERVICE == objtypeSelected)
  547. fEnableRefresh = TRUE;
  548. break;
  549. }
  550. if (fEnableRefresh)
  551. {
  552. // Enable the refresh menuitem
  553. VERIFY( SUCCEEDED(m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE)) );
  554. }
  555. }
  556. switch (objtypeSelected)
  557. {
  558. case FILEMGMT_SHARE: // Share was selected
  559. //
  560. // don't enable Properties on the menu whenever SimpleSharingUI appears in NT Explorer
  561. //
  562. if (QueryComponentDataRef().GetIsSimpleUI())
  563. {
  564. VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_NONE)) );
  565. break;
  566. }
  567. // fall through
  568. case FILEMGMT_SERVICE: // Service was selected
  569. // Set the default verb to display the properties of the selected object
  570. VERIFY( SUCCEEDED(m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE)) );
  571. VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES)) );
  572. break;
  573. case FILEMGMT_SESSION: // Session was selected
  574. case FILEMGMT_RESOURCE: // Open file was selected
  575. VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_NONE)) );
  576. break;
  577. case FILEMGMT_SHARES:
  578. case FILEMGMT_SESSIONS:
  579. case FILEMGMT_RESOURCES:
  580. case FILEMGMT_SERVICES:
  581. case FILEMGMT_ROOT: // Root node was selected
  582. // set the default verb to open/expand the folder
  583. VERIFY( SUCCEEDED(m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN)) );
  584. break;
  585. default: // shouldn't happen
  586. ASSERT(FALSE);
  587. break;
  588. } // switch
  589. } // CFileMgmtComponent::OnNotifySelect()
  590. STDMETHODIMP CFileMgmtComponent::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  591. {
  592. HRESULT hr = S_OK;
  593. MFC_TRY;
  594. //
  595. // MMC queries us for a multiselect data object (SI_MS_DO) by
  596. // passing the special cookie in this QueryDataObject call.
  597. //
  598. if (IS_SPECIAL_COOKIE(cookie) && MMC_MULTI_SELECT_COOKIE == cookie)
  599. {
  600. CComObject<CFileMgmtDataObject>* pDataObject = NULL;
  601. hr = CComObject<CFileMgmtDataObject>::CreateInstance(&pDataObject);
  602. if (SUCCEEDED(hr))
  603. hr = pDataObject->InitMultiSelectDataObjects(QueryComponentDataRef());
  604. if (SUCCEEDED(hr))
  605. {
  606. //
  607. // We create a multiselect data object (SI_MS_DO), which contains
  608. // an internal list of data objects of selected items.
  609. //
  610. RESULTDATAITEM rdi = {0};
  611. int nIndex = -1;
  612. do
  613. {
  614. ZeroMemory(&rdi, sizeof(RESULTDATAITEM));
  615. rdi.mask = RDI_STATE;
  616. rdi.nCol = 0;
  617. rdi.nIndex = nIndex; // nIndex == -1 to start at first item
  618. rdi.nState = LVIS_SELECTED; // only interested in selected items
  619. hr = m_pResultData->GetNextItem(&rdi);
  620. if (FAILED(hr))
  621. break;
  622. if (rdi.nIndex != -1)
  623. {
  624. //
  625. // rdi is the RESULTDATAITEM of a selected item. its lParam contains the cookie.
  626. // Add it to the internal data object list.
  627. //
  628. CCookie* pbasecookie = reinterpret_cast<CCookie*>(rdi.lParam);
  629. CFileMgmtCookie* pUseThisCookie = QueryComponentDataRef().ActiveCookie((CFileMgmtCookie*)pbasecookie);
  630. pDataObject->AddMultiSelectDataObjects(pUseThisCookie, type);
  631. }
  632. nIndex = rdi.nIndex;
  633. } while (-1 != nIndex);
  634. }
  635. //
  636. // return this SI_MS_DO to MMC
  637. //
  638. if (SUCCEEDED(hr))
  639. hr = pDataObject->QueryInterface(IID_IDataObject, (void **)ppDataObject);
  640. if (FAILED(hr))
  641. delete pDataObject;
  642. }
  643. else
  644. {
  645. // Delegate it to the IComponentData
  646. hr = QueryBaseComponentDataRef().QueryDataObject(cookie, type, ppDataObject);
  647. }
  648. MFC_CATCH;
  649. return hr;
  650. }
  651. STDMETHODIMP CFileMgmtComponent::GetResultViewType(MMC_COOKIE cookie,
  652. BSTR* ppViewType,
  653. long* pViewOptions)
  654. {
  655. *ppViewType = NULL;
  656. //
  657. // we support multiselection in SharedFolders snapin
  658. //
  659. CCookie* pbasecookie = reinterpret_cast<CCookie*>(cookie);
  660. CFileMgmtCookie* pUseThisCookie = QueryComponentDataRef().ActiveCookie((CFileMgmtCookie*)pbasecookie);
  661. FileMgmtObjectType objecttype = pUseThisCookie->QueryObjectType();
  662. if ( FILEMGMT_SHARES == objecttype ||
  663. FILEMGMT_SESSIONS == objecttype ||
  664. FILEMGMT_RESOURCES == objecttype )
  665. {
  666. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  667. } else
  668. {
  669. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  670. }
  671. return S_FALSE;
  672. }
  673. HRESULT CFileMgmtComponent::Show( CCookie* pcookie, LPARAM arg, HSCOPEITEM /*hScopeItem*/ )
  674. {
  675. TEST_NONNULL_PTR_PARAM(pcookie);
  676. #ifndef SNAPIN_PROTOTYPER
  677. if ( 0 == arg )
  678. {
  679. //
  680. // This is a Hide notification
  681. //
  682. if ( NULL == m_pResultData )
  683. {
  684. ASSERT( FALSE );
  685. return E_UNEXPECTED;
  686. }
  687. // We should not get a Hide notification if we are not currently showing
  688. // CODEWORK see 287399: MMC: two MMCN_SHOW(0) notifications
  689. // ASSERT( (CFileMgmtCookie*)pcookie == m_pViewedCookie );
  690. if ( (CFileMgmtScopeCookie*)pcookie == m_pViewedCookie )
  691. {
  692. //
  693. // Only delete the cookies if no other views are using them
  694. //
  695. pcookie->ReleaseResultChildren();
  696. m_pViewedCookie = NULL;
  697. UpdateDefaultVerbs();
  698. }
  699. return S_OK;
  700. } // if
  701. #else
  702. CPrototyperScopeCookie* pScopeCookie = (CPrototyperScopeCookie*) pcookie;
  703. if (pScopeCookie->m_ScopeType == HTML)
  704. return S_OK;
  705. #endif // SNAPIN_PROTOTYPER
  706. // We should not get a Show notification if we are already showing
  707. if ( NULL != m_pViewedCookie )
  708. {
  709. ASSERT(FALSE);
  710. return S_OK;
  711. }
  712. //
  713. // This is a Show notification
  714. // Build new cookies and insert them into the cookie and the view
  715. //
  716. ASSERT( IsAutonomousObjectType( ((CFileMgmtCookie*)pcookie)->QueryObjectType() ) );
  717. m_pViewedCookie = (CFileMgmtScopeCookie*)pcookie;
  718. LoadColumns( m_pViewedCookie );
  719. UpdateDefaultVerbs();
  720. return PopulateListbox( m_pViewedCookie );
  721. } // CFileMgmtComponent::Show()
  722. HRESULT CFileMgmtComponent::OnNotifyAddImages( LPDATAOBJECT /*lpDataObject*/,
  723. LPIMAGELIST lpImageList,
  724. HSCOPEITEM /*hSelectedItem*/ )
  725. {
  726. return QueryComponentDataRef().LoadIcons(lpImageList,TRUE);
  727. }
  728. /////////////////////////////////////////////////////////////////////
  729. // CODEWORK: Rather than repeating the FPNW calls every time, whether
  730. // or not the FPNW server is running or even installed, I should
  731. // remember whether the server is installed. Andy Herron has
  732. // suggested an API which can determine whether FPNW is installed,
  733. // but it has two drawbacks:
  734. // -- It can only determine whether FPNW is installed anywhere on the
  735. // domain, not on an individual server; and
  736. // -- The API will fail if called by a non-administrator.
  737. //
  738. // JonN 11/1/96
  739. //
  740. HRESULT CFileMgmtComponent::PopulateListbox(CFileMgmtScopeCookie* pcookie)
  741. {
  742. TEST_NONNULL_PTR_PARAM(pcookie);
  743. CWaitCursor cwait;
  744. HRESULT hr = S_OK;
  745. //
  746. // If this is the second view on the same data, just insert the same cookies
  747. // which are in the other views
  748. //
  749. if ( 1 < pcookie->AddRefResultChildren() )
  750. {
  751. hr = InsertResultCookies( *pcookie );
  752. if ( SUCCEEDED(hr) )
  753. hr = m_pResultData->Sort( m_iSortColumn , m_dwSortFlags, 0 );
  754. return hr;
  755. }
  756. INT iTransport;
  757. switch ( pcookie->QueryObjectType() )
  758. {
  759. case FILEMGMT_SHARES:
  760. for (iTransport = FILEMGMT_FIRST_TRANSPORT;
  761. iTransport < FILEMGMT_NUM_TRANSPORTS;
  762. iTransport++)
  763. {
  764. hr = GetFileServiceProvider(iTransport)->PopulateShares(m_pResultData,pcookie);
  765. if( FAILED(hr) )
  766. return hr;
  767. }
  768. break;
  769. case FILEMGMT_SESSIONS:
  770. for (iTransport = FILEMGMT_FIRST_TRANSPORT;
  771. iTransport < FILEMGMT_NUM_TRANSPORTS;
  772. iTransport++)
  773. {
  774. ASSERT( NULL != m_pResultData ); // otherwise we close all sessions
  775. hr = GetFileServiceProvider(iTransport)->EnumerateSessions (
  776. m_pResultData, pcookie, true);
  777. if( FAILED(hr) )
  778. return hr;
  779. }
  780. break;
  781. case FILEMGMT_RESOURCES:
  782. for (iTransport = FILEMGMT_FIRST_TRANSPORT;
  783. iTransport < FILEMGMT_NUM_TRANSPORTS;
  784. iTransport++)
  785. {
  786. ASSERT( NULL != m_pResultData ); // otherwise we close all sessions
  787. hr = GetFileServiceProvider(iTransport)->EnumerateResources(m_pResultData,pcookie);
  788. if( FAILED(hr) )
  789. return hr;
  790. }
  791. break;
  792. case FILEMGMT_SERVICES:
  793. //
  794. // JonN 12/03/98 Service_PopulateServices no longer inserts items into the list
  795. //
  796. hr = QueryComponentDataRef().Service_PopulateServices(m_pResultData, pcookie);
  797. if ( SUCCEEDED(hr) )
  798. hr = InsertResultCookies( *pcookie );
  799. if( FAILED(hr) )
  800. return hr;
  801. #ifdef SNAPIN_PROTOTYPER
  802. case FILEMGMT_PROTOTYPER:
  803. return Prototyper_HrPopulateResultPane(pcookie);
  804. #endif
  805. case FILEMGMT_ROOT:
  806. // We no longer need to explicitly insert these
  807. break;
  808. default:
  809. ASSERT( FALSE );
  810. // fall through
  811. }
  812. return m_pResultData->Sort( m_iSortColumn , m_dwSortFlags, 0 );
  813. } // CFileMgmtComponent::PopulateListbox()
  814. HRESULT CFileMgmtComponent::GetSnapinMultiSelectDataObject(
  815. LPDATAOBJECT i_pMMCMultiSelectDataObject,
  816. LPDATAOBJECT *o_ppSnapinMultiSelectDataObject
  817. )
  818. {
  819. if (!i_pMMCMultiSelectDataObject || !o_ppSnapinMultiSelectDataObject)
  820. return E_INVALIDARG;
  821. *o_ppSnapinMultiSelectDataObject = NULL;
  822. //
  823. // i_pMMCMultiSelectDataObject is the composite data object (MMC_MS_DO) created by MMC.
  824. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  825. // we provided to MMC in QueryDataObject().
  826. //
  827. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL};
  828. FORMATETC formatetc = {CFileMgmtDataObject::m_CFMultiSelectSnapins, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  829. HRESULT hr = i_pMMCMultiSelectDataObject->GetData(&formatetc, &stgmedium);
  830. if (SUCCEEDED(hr))
  831. {
  832. if (!stgmedium.hGlobal)
  833. return E_FAIL;
  834. //
  835. // Locate the SI_MS_DO we have provided to MMC in QueryDataObject().
  836. //
  837. SMMCDataObjects *pMMCDO = (SMMCDataObjects*)::GlobalLock(stgmedium.hGlobal);
  838. GUID guidSnapin = GUID_NULL;
  839. VERIFY( SUCCEEDED(QueryComponentDataRef().GetClassID(&guidSnapin)) );
  840. for (int i = 0; i < pMMCDO->count; i++)
  841. {
  842. GUID guid = GUID_NULL;
  843. hr = ExtractData(pMMCDO->lpDataObject[i], CFileMgmtDataObject::m_CFSnapInCLSID, &guid, sizeof(GUID));
  844. if (SUCCEEDED(hr) && guid == guidSnapin)
  845. {
  846. //
  847. // pMMCDO->lpDataObject[i] is the SI_MS_DO we have provided to MMC in QueryDataObject().
  848. //
  849. *o_ppSnapinMultiSelectDataObject = pMMCDO->lpDataObject[i];
  850. (*o_ppSnapinMultiSelectDataObject)->AddRef();
  851. break;
  852. }
  853. }
  854. ::GlobalUnlock(stgmedium.hGlobal);
  855. ::GlobalFree(stgmedium.hGlobal);
  856. }
  857. return hr;
  858. }
  859. /////////////////////////////////////////////////////////////////////////////
  860. // IExtendContextMenu Implementation
  861. STDMETHODIMP CFileMgmtComponent::AddMenuItems(
  862. IDataObject* piDataObject,
  863. IContextMenuCallback* piCallback,
  864. long* pInsertionAllowed)
  865. {
  866. MFC_TRY;
  867. TRACE_METHOD(CFileMgmtComponent,AddMenuItems);
  868. TEST_NONNULL_PTR_PARAM(piDataObject);
  869. TEST_NONNULL_PTR_PARAM(piCallback);
  870. TEST_NONNULL_PTR_PARAM(pInsertionAllowed);
  871. TRACE( "FileMgmt snapin: extending menu\n" );
  872. HRESULT hr = S_OK;
  873. FileMgmtObjectType objecttype = FILEMGMT_NUMTYPES;
  874. //
  875. // need to find out the object type in case of multiselection
  876. //
  877. BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject);
  878. if (!bMultiSelectObject)
  879. {
  880. objecttype = FileMgmtObjectTypeFromIDataObject(piDataObject);
  881. } else
  882. {
  883. //
  884. // piDataObject is the composite data object (MMC_MS_DO) created by MMC.
  885. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  886. // we provided to MMC in QueryDataObject().
  887. //
  888. IDataObject *piSIMSDO = NULL;
  889. hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO);
  890. if (SUCCEEDED(hr))
  891. {
  892. //
  893. // Note: we assume all multiselected items are of the same type.
  894. //
  895. // Now retrieve data type of the currently selected items
  896. //
  897. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL};
  898. FORMATETC formatetc = {CFileMgmtDataObject::m_CFObjectTypesInMultiSelect,
  899. NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  900. hr = piSIMSDO->GetData(&formatetc, &stgmedium);
  901. if (SUCCEEDED(hr) && stgmedium.hGlobal)
  902. {
  903. BYTE* pb = (BYTE*)::GlobalLock(stgmedium.hGlobal);
  904. GUID* pguid = (GUID*)(pb + sizeof(DWORD)); // skip the 1st DWORD - count
  905. objecttype = (FileMgmtObjectType)CheckObjectTypeGUID(pguid);
  906. ::GlobalUnlock(stgmedium.hGlobal);
  907. ::GlobalFree(stgmedium.hGlobal);
  908. }
  909. piSIMSDO->Release();
  910. }
  911. }
  912. switch (objecttype)
  913. {
  914. case FILEMGMT_SHARE:
  915. //
  916. // don't add acl-related menu items whenever SimpleSharingUI appears in NT Explorer
  917. //
  918. if (QueryComponentDataRef().GetIsSimpleUI())
  919. break;
  920. if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) )
  921. {
  922. hr = LoadAndAddMenuItem( piCallback, IDS_DELETE_SHARE_TOP, IDS_DELETE_SHARE_TOP,
  923. CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle() );
  924. ASSERT( SUCCEEDED(hr) );
  925. }
  926. if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) )
  927. {
  928. hr = LoadAndAddMenuItem( piCallback, IDS_DELETE_SHARE_TASK, IDS_DELETE_SHARE_TASK,
  929. CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle() );
  930. ASSERT( SUCCEEDED(hr) );
  931. }
  932. if ( CCM_INSERTIONALLOWED_NEW & (*pInsertionAllowed) )
  933. {
  934. hr = LoadAndAddMenuItem( piCallback, IDS_NEW_SHARE_NEW, IDS_NEW_SHARE_NEW,
  935. CCM_INSERTIONPOINTID_PRIMARY_NEW, 0, AfxGetInstanceHandle() );
  936. ASSERT( SUCCEEDED(hr) );
  937. }
  938. break;
  939. case FILEMGMT_SESSION:
  940. if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) )
  941. {
  942. hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_SESSION_TOP, IDS_CLOSE_SESSION_TOP,
  943. CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle() );
  944. ASSERT( SUCCEEDED(hr) );
  945. }
  946. if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) )
  947. {
  948. hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_SESSION_TASK, IDS_CLOSE_SESSION_TASK,
  949. CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle() );
  950. ASSERT( SUCCEEDED(hr) );
  951. }
  952. break;
  953. case FILEMGMT_RESOURCE:
  954. if ( CCM_INSERTIONALLOWED_TOP & (*pInsertionAllowed) )
  955. {
  956. hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_RESOURCE_TOP, IDS_CLOSE_RESOURCE_TOP,
  957. CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, AfxGetInstanceHandle() );
  958. ASSERT( SUCCEEDED(hr) );
  959. }
  960. if ( CCM_INSERTIONALLOWED_TASK & (*pInsertionAllowed) )
  961. {
  962. hr = LoadAndAddMenuItem( piCallback, IDS_CLOSE_RESOURCE_TASK, IDS_CLOSE_RESOURCE_TASK,
  963. CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, AfxGetInstanceHandle() );
  964. ASSERT( SUCCEEDED(hr) );
  965. }
  966. break;
  967. case FILEMGMT_SERVICE:
  968. QueryComponentDataRef().Service_FAddMenuItems(piCallback, piDataObject);
  969. break;
  970. #ifdef SNAPIN_PROTOTYPER
  971. case FILEMGMT_PROTOTYPER_LEAF:
  972. Prototyper_AddMenuItems(piCallback, piDataObject);
  973. break;
  974. #endif // SNAPIN_PROTOTYPER
  975. default:
  976. {
  977. DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE;
  978. hr = ExtractData( piDataObject,
  979. CFileMgmtDataObject::m_CFDataObjectType,
  980. &dataobjecttype,
  981. sizeof(dataobjecttype) );
  982. ASSERT( SUCCEEDED(hr) );
  983. // perhaps this is a scope node in the result pane
  984. hr = QueryComponentDataRef().DoAddMenuItems( piCallback,
  985. objecttype,
  986. dataobjecttype,
  987. pInsertionAllowed,
  988. piDataObject );
  989. }
  990. break;
  991. } // switch
  992. return hr;
  993. MFC_CATCH;
  994. } // CFileMgmtComponent::AddMenuItems()
  995. STDMETHODIMP CFileMgmtComponent::Command(
  996. LONG lCommandID,
  997. IDataObject* piDataObject )
  998. {
  999. MFC_TRY;
  1000. TRACE_METHOD(CFileMgmtComponent,Command);
  1001. TEST_NONNULL_PTR_PARAM(piDataObject);
  1002. TRACE( "CFileMgmtComponent::Command: command %ld selected\n", lCommandID );
  1003. #ifdef SNAPIN_PROTOTYPER
  1004. Prototyper_ContextMenuCommand(lCommandID, piDataObject);
  1005. return S_OK;
  1006. #endif
  1007. BOOL fFSMRefresh = FALSE;
  1008. BOOL fSVCRefresh = FALSE;
  1009. switch (lCommandID)
  1010. {
  1011. case IDS_DELETE_SHARE_TASK:
  1012. case IDS_DELETE_SHARE_TOP:
  1013. fFSMRefresh = DeleteShare( piDataObject );
  1014. break;
  1015. case IDS_CLOSE_SESSION_TASK:
  1016. case IDS_CLOSE_SESSION_TOP:
  1017. fFSMRefresh = CloseSession( piDataObject );
  1018. break;
  1019. case IDS_CLOSE_RESOURCE_TASK:
  1020. case IDS_CLOSE_RESOURCE_TOP:
  1021. fFSMRefresh = CloseResource( piDataObject );
  1022. break;
  1023. case cmServiceStart:
  1024. case cmServiceStop:
  1025. case cmServicePause:
  1026. case cmServiceResume:
  1027. case cmServiceRestart:
  1028. case cmServiceStartTask:
  1029. case cmServiceStopTask:
  1030. case cmServicePauseTask:
  1031. case cmServiceResumeTask:
  1032. case cmServiceRestartTask:
  1033. fSVCRefresh = QueryComponentDataRef().Service_FDispatchMenuCommand(lCommandID, piDataObject);
  1034. break;
  1035. default:
  1036. return QueryComponentDataRef().Command(lCommandID, piDataObject);
  1037. } // switch
  1038. if (fFSMRefresh)
  1039. {
  1040. //
  1041. // In case of multiselect, piDataObject may point to a composite data object (MMC_MS_DO).
  1042. // RefreshAllViewsOnSelectedObject will crack down MMC_MS_DO to retrieve SI_MS_DO, then call
  1043. // RefreshAllViews on one of the selected objects in the internal list.
  1044. //
  1045. (void) RefreshAllViewsOnSelectedObject(piDataObject);
  1046. }
  1047. if (fSVCRefresh)
  1048. {
  1049. (void) RefreshAllViews( piDataObject );
  1050. }
  1051. return S_OK;
  1052. MFC_CATCH;
  1053. } // CFileMgmtComponent::Command()
  1054. BOOL CFileMgmtComponent::DeleteShare(LPDATAOBJECT piDataObject)
  1055. {
  1056. ASSERT( piDataObject != NULL );
  1057. BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject);
  1058. if (!bMultiSelectObject)
  1059. return DeleteThisOneShare(piDataObject, FALSE);
  1060. BOOL bRefresh = FALSE;
  1061. if (IDYES == DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_s_CONFIRM_DELETEMULTISHARES))
  1062. {
  1063. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1064. CWaitCursor wait;
  1065. //
  1066. // piDataObject is the composite data object (MMC_MS_DO) created by MMC.
  1067. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  1068. // we provided to MMC in QueryDataObject().
  1069. //
  1070. IDataObject *piSIMSDO = NULL;
  1071. HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO);
  1072. if (SUCCEEDED(hr))
  1073. {
  1074. CFileMgmtDataObject *pDataObj = NULL;
  1075. hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
  1076. if (SUCCEEDED(hr))
  1077. {
  1078. //
  1079. // get the internal list of data objects of selected items, operate on each one of them.
  1080. //
  1081. CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
  1082. for (CDataObjectList::iterator i = pMultiSelectObjList->begin(); i != pMultiSelectObjList->end(); i++)
  1083. {
  1084. BOOL bDeleted = DeleteThisOneShare(*i, TRUE);
  1085. if (bDeleted)
  1086. bRefresh = TRUE;
  1087. }
  1088. }
  1089. piSIMSDO->Release();
  1090. }
  1091. }
  1092. return bRefresh;
  1093. }
  1094. BOOL CFileMgmtComponent::DeleteThisOneShare(LPDATAOBJECT piDataObject, BOOL bQuietMode)
  1095. {
  1096. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1097. ASSERT( piDataObject != NULL );
  1098. #ifdef DEBUG
  1099. {
  1100. FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(piDataObject);
  1101. ASSERT(FILEMGMT_SHARE == objecttype);
  1102. }
  1103. #endif
  1104. CString strServerName;
  1105. HRESULT hr = ExtractString( piDataObject, CFileMgmtDataObject::m_CFMachineName, &strServerName, MAX_PATH );
  1106. RETURN_FALSE_IF_FAIL;
  1107. CString strShareName;
  1108. hr = ExtractString( piDataObject, CFileMgmtDataObject::m_CFShareName, &strShareName, MAX_PATH );
  1109. RETURN_FALSE_IF_FAIL;
  1110. FILEMGMT_TRANSPORT transport;
  1111. hr = ExtractData( piDataObject,
  1112. CFileMgmtDataObject::m_CFTransport,
  1113. &transport,
  1114. sizeof(DWORD) );
  1115. RETURN_FALSE_IF_FAIL;
  1116. BOOL fNetLogonShare = (!lstrcmpi(strShareName, _T("SYSVOL")) || !lstrcmpi(strShareName, _T("NETLOGON")));
  1117. BOOL fIPC = FALSE;
  1118. BOOL fAdminShare = FALSE;
  1119. if (!fNetLogonShare && transport == FILEMGMT_SMB)
  1120. {
  1121. DWORD dwShareType = 0;
  1122. GetFileServiceProvider(transport)->ReadShareType(strServerName, strShareName, &dwShareType);
  1123. fAdminShare = (dwShareType & STYPE_SPECIAL);
  1124. fIPC = (STYPE_IPC == (dwShareType & STYPE_IPC));
  1125. }
  1126. if (fIPC)
  1127. {
  1128. DoErrMsgBox(
  1129. GetActiveWindow(),
  1130. MB_OK | MB_ICONEXCLAMATION,
  1131. 0,
  1132. IDS_s_DELETE_IPCSHARE
  1133. );
  1134. return FALSE;
  1135. }
  1136. if ((fNetLogonShare || fAdminShare) &&
  1137. IDYES != DoErrMsgBox(
  1138. GetActiveWindow(),
  1139. MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2,
  1140. 0,
  1141. (fAdminShare ? IDS_s_CONFIRM_DELETE_ADMINSHARE : IDS_s_CONFIRM_DELETE_NETLOGONSHARE),
  1142. strShareName) )
  1143. {
  1144. return FALSE;
  1145. }
  1146. if (!bQuietMode &&
  1147. IDYES != DoErrMsgBox(
  1148. GetActiveWindow(),
  1149. MB_YESNO,
  1150. 0,
  1151. IDS_s_CONFIRM_DELETESHARE,
  1152. strShareName) )
  1153. {
  1154. return FALSE;
  1155. }
  1156. DWORD retval = 0L;
  1157. switch (transport)
  1158. {
  1159. case FILEMGMT_SMB:
  1160. case FILEMGMT_FPNW:
  1161. case FILEMGMT_SFM:
  1162. if (bQuietMode)
  1163. {
  1164. retval = GetFileServiceProvider(transport)->DeleteShare(strServerName, strShareName);
  1165. } else
  1166. {
  1167. CWaitCursor wait;
  1168. retval = GetFileServiceProvider(transport)->DeleteShare(strServerName, strShareName);
  1169. }
  1170. break;
  1171. default:
  1172. ASSERT(FALSE);
  1173. break;
  1174. }
  1175. if (0L != retval)
  1176. {
  1177. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_DELETE_SHARE, strShareName);
  1178. return FALSE;
  1179. }
  1180. return TRUE;
  1181. }
  1182. BOOL CFileMgmtComponent::CloseSession(LPDATAOBJECT piDataObject)
  1183. {
  1184. ASSERT( piDataObject != NULL );
  1185. BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject);
  1186. if (!bMultiSelectObject)
  1187. return CloseThisOneSession(piDataObject, FALSE);
  1188. BOOL bRefresh = FALSE;
  1189. if (IDYES == DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSEMULTISESSIONS))
  1190. {
  1191. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1192. CWaitCursor wait;
  1193. //
  1194. // piDataObject is the composite data object (MMC_MS_DO) created by MMC.
  1195. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  1196. // we provided to MMC in QueryDataObject().
  1197. //
  1198. IDataObject *piSIMSDO = NULL;
  1199. HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO);
  1200. if (SUCCEEDED(hr))
  1201. {
  1202. CFileMgmtDataObject *pDataObj = NULL;
  1203. hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
  1204. if (SUCCEEDED(hr))
  1205. {
  1206. //
  1207. // get the internal list of data objects of selected items, operate on each one of them.
  1208. //
  1209. CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
  1210. for (CDataObjectList::iterator i = pMultiSelectObjList->begin(); i != pMultiSelectObjList->end(); i++)
  1211. {
  1212. BOOL bDeleted = CloseThisOneSession(*i, TRUE);
  1213. if (bDeleted)
  1214. bRefresh = TRUE;
  1215. }
  1216. }
  1217. piSIMSDO->Release();
  1218. }
  1219. }
  1220. return bRefresh;
  1221. }
  1222. BOOL CFileMgmtComponent::CloseThisOneSession(LPDATAOBJECT piDataObject, BOOL bQuietMode)
  1223. {
  1224. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1225. ASSERT( piDataObject != NULL );
  1226. CCookie* pbasecookie = NULL;
  1227. FileMgmtObjectType objecttype = FILEMGMT_ROOT;
  1228. HRESULT hr = ExtractBaseCookie( piDataObject, &pbasecookie, &objecttype );
  1229. ASSERT( SUCCEEDED(hr) && NULL != pbasecookie && FILEMGMT_SESSION == objecttype );
  1230. CFileMgmtResultCookie* pcookie = (CFileMgmtResultCookie*)pbasecookie;
  1231. if ( !bQuietMode && IDYES != DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSESESSION) )
  1232. {
  1233. return FALSE;
  1234. }
  1235. FILEMGMT_TRANSPORT transport = FILEMGMT_SMB;
  1236. VERIFY( SUCCEEDED( pcookie->GetTransport( &transport ) ) );
  1237. DWORD retval = 0;
  1238. if (bQuietMode)
  1239. {
  1240. retval = GetFileServiceProvider(transport)->CloseSession( pcookie );
  1241. } else
  1242. {
  1243. CWaitCursor wait;
  1244. retval = GetFileServiceProvider(transport)->CloseSession( pcookie );
  1245. }
  1246. if (0L != retval)
  1247. {
  1248. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_CLOSE_SESSION);
  1249. return FALSE;
  1250. }
  1251. return TRUE;
  1252. }
  1253. BOOL CFileMgmtComponent::CloseResource(LPDATAOBJECT piDataObject)
  1254. {
  1255. ASSERT( piDataObject != NULL );
  1256. BOOL bMultiSelectObject = IsMultiSelectObject(piDataObject);
  1257. if (!bMultiSelectObject)
  1258. return CloseThisOneResource(piDataObject, FALSE);
  1259. BOOL bRefresh = FALSE;
  1260. if (IDYES == DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSEMULTIRESOURCES))
  1261. {
  1262. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1263. CWaitCursor wait;
  1264. //
  1265. // piDataObject is the composite data object (MMC_MS_DO) created by MMC.
  1266. // We need to crack it to retrieve the multiselect data object (SI_MS_DO)
  1267. // we provided to MMC in QueryDataObject().
  1268. //
  1269. IDataObject *piSIMSDO = NULL;
  1270. HRESULT hr = GetSnapinMultiSelectDataObject(piDataObject, &piSIMSDO);
  1271. if (SUCCEEDED(hr))
  1272. {
  1273. CFileMgmtDataObject *pDataObj = NULL;
  1274. hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
  1275. if (SUCCEEDED(hr))
  1276. {
  1277. //
  1278. // get the internal list of data objects of selected items, operate on each one of them.
  1279. //
  1280. CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
  1281. for (CDataObjectList::iterator i = pMultiSelectObjList->begin(); i != pMultiSelectObjList->end(); i++)
  1282. {
  1283. BOOL bDeleted = CloseThisOneResource(*i, TRUE);
  1284. if (bDeleted)
  1285. bRefresh = TRUE;
  1286. }
  1287. }
  1288. piSIMSDO->Release();
  1289. }
  1290. }
  1291. return bRefresh;
  1292. }
  1293. BOOL CFileMgmtComponent::CloseThisOneResource(LPDATAOBJECT piDataObject, BOOL bQuietMode)
  1294. {
  1295. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1296. ASSERT( piDataObject != NULL );
  1297. CCookie* pbasecookie = NULL;
  1298. FileMgmtObjectType objecttype;
  1299. HRESULT hr = ExtractBaseCookie( piDataObject, &pbasecookie, &objecttype );
  1300. ASSERT( SUCCEEDED(hr) && NULL != pbasecookie && FILEMGMT_RESOURCE == objecttype );
  1301. CFileMgmtResultCookie* pcookie = (CFileMgmtResultCookie*)pbasecookie;
  1302. if ( !bQuietMode && IDYES != DoErrMsgBox(GetActiveWindow(), MB_YESNO, 0, IDS_CONFIRM_CLOSERESOURCE) )
  1303. {
  1304. return FALSE;
  1305. }
  1306. FILEMGMT_TRANSPORT transport = FILEMGMT_SMB;
  1307. VERIFY( SUCCEEDED( pcookie->GetTransport( &transport ) ) );
  1308. DWORD retval = 0;
  1309. if (bQuietMode)
  1310. {
  1311. retval = GetFileServiceProvider(transport)->CloseResource( pcookie );
  1312. } else
  1313. {
  1314. CWaitCursor wait;
  1315. retval = GetFileServiceProvider(transport)->CloseResource( pcookie );
  1316. }
  1317. if (0L != retval)
  1318. {
  1319. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_CLOSE_RESOURCE);
  1320. return FALSE;
  1321. }
  1322. return TRUE;
  1323. }
  1324. ///////////////////////////////////////////////////////////////////////////////
  1325. /// IExtendPropertySheet
  1326. STDMETHODIMP CFileMgmtComponent::QueryPagesFor(LPDATAOBJECT pDataObject)
  1327. {
  1328. MFC_TRY;
  1329. if (NULL == pDataObject)
  1330. {
  1331. ASSERT(FALSE);
  1332. return E_POINTER;
  1333. }
  1334. HRESULT hr = S_OK;
  1335. DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE;
  1336. // extract data from data object
  1337. FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(pDataObject);
  1338. hr = ExtractData( pDataObject, CFileMgmtDataObject::m_CFDataObjectType, &dataobjecttype, sizeof(dataobjecttype) );
  1339. ASSERT( SUCCEEDED(hr) );
  1340. ASSERT( CCT_SCOPE == dataobjecttype ||
  1341. CCT_RESULT == dataobjecttype ||
  1342. CCT_SNAPIN_MANAGER == dataobjecttype );
  1343. // determine if it needs property pages
  1344. switch (objecttype)
  1345. {
  1346. case FILEMGMT_SESSION:
  1347. case FILEMGMT_RESOURCE:
  1348. ASSERT(CCT_SNAPIN_MANAGER != dataobjecttype);
  1349. return S_FALSE;
  1350. case FILEMGMT_SHARE: // now has a property page
  1351. {
  1352. CString strServerName;
  1353. CString strShareName;
  1354. FILEMGMT_TRANSPORT transport;
  1355. hr = ExtractString(pDataObject, CFileMgmtDataObject::m_CFMachineName, &strServerName, MAX_PATH);
  1356. if (SUCCEEDED(hr))
  1357. hr = ExtractString(pDataObject, CFileMgmtDataObject::m_CFShareName, &strShareName, MAX_PATH);
  1358. if (SUCCEEDED(hr))
  1359. hr = ExtractData(pDataObject, CFileMgmtDataObject::m_CFTransport, &transport, sizeof(DWORD));
  1360. if (SUCCEEDED(hr))
  1361. {
  1362. CString strDescription;
  1363. CString strPath;
  1364. DWORD dwRet = GetFileServiceProvider(transport)->ReadShareProperties(
  1365. strServerName,
  1366. strShareName,
  1367. NULL, // ppvPropertyBlock
  1368. strDescription,
  1369. strPath,
  1370. NULL, // pfEditDescription
  1371. NULL, // pfEditPath
  1372. NULL // pdwShareType
  1373. );
  1374. if (NERR_Success == dwRet)
  1375. {
  1376. return S_OK; // yes, we have a property page to display
  1377. } else
  1378. {
  1379. DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, dwRet, IDS_POPUP_QUERY_SHARE, strShareName);
  1380. if ((FILEMGMT_SMB == transport || FILEMGMT_FPNW == transport) && (NERR_NetNameNotFound == dwRet) ||
  1381. (FILEMGMT_SFM == transport) && (AFPERR_VolumeNonExist == dwRet))
  1382. {
  1383. RefreshAllViews(pDataObject);
  1384. }
  1385. }
  1386. }
  1387. return S_FALSE;
  1388. }
  1389. case FILEMGMT_SERVICE:
  1390. ASSERT(CCT_SNAPIN_MANAGER != dataobjecttype);
  1391. return S_OK;
  1392. #ifdef SNAPIN_PROTOTYPER
  1393. case FILEMGMT_PROTOTYPER_LEAF:
  1394. return S_OK;
  1395. #endif
  1396. default:
  1397. break;
  1398. }
  1399. ASSERT(FALSE);
  1400. return S_FALSE;
  1401. MFC_CATCH;
  1402. }
  1403. STDMETHODIMP CFileMgmtComponent::CreatePropertyPages(
  1404. LPPROPERTYSHEETCALLBACK pCallBack,
  1405. LONG_PTR handle, // This handle must be saved in the property page object to notify the parent when modified
  1406. LPDATAOBJECT pDataObject)
  1407. {
  1408. MFC_TRY;
  1409. if (NULL == pCallBack || NULL == pDataObject)
  1410. {
  1411. ASSERT(FALSE);
  1412. return E_POINTER;
  1413. }
  1414. HRESULT hr;
  1415. // extract data from data object
  1416. FileMgmtObjectType objecttype = FileMgmtObjectTypeFromIDataObject(pDataObject);
  1417. DATA_OBJECT_TYPES dataobjecttype = CCT_SCOPE;
  1418. hr = ExtractData( pDataObject, CFileMgmtDataObject::m_CFDataObjectType, &dataobjecttype, sizeof(dataobjecttype) );
  1419. ASSERT( SUCCEEDED(hr) );
  1420. ASSERT( CCT_SCOPE == dataobjecttype ||
  1421. CCT_RESULT == dataobjecttype ||
  1422. CCT_SNAPIN_MANAGER == dataobjecttype );
  1423. // determine if it needs property pages
  1424. switch (objecttype)
  1425. {
  1426. case FILEMGMT_SHARE:
  1427. {
  1428. CWaitCursor cwait;
  1429. if (CCT_SNAPIN_MANAGER == dataobjecttype)
  1430. {
  1431. ASSERT(FALSE);
  1432. return E_UNEXPECTED;
  1433. }
  1434. FILEMGMT_TRANSPORT transport;
  1435. hr = ExtractData( pDataObject,
  1436. CFileMgmtDataObject::m_CFTransport,
  1437. &transport,
  1438. sizeof(DWORD) );
  1439. if ( FAILED(hr) )
  1440. {
  1441. ASSERT( FALSE );
  1442. return E_UNEXPECTED;
  1443. }
  1444. // CODEWORK probably not necessary to split off transport at this point
  1445. GetFileServiceProvider(transport)->DisplayShareProperties(pCallBack, pDataObject, handle);
  1446. return S_OK;
  1447. }
  1448. case FILEMGMT_SESSION:
  1449. case FILEMGMT_RESOURCE:
  1450. ASSERT(FALSE);
  1451. return E_UNEXPECTED;
  1452. case FILEMGMT_SERVICE:
  1453. if (CCT_RESULT != dataobjecttype)
  1454. {
  1455. ASSERT(FALSE);
  1456. return E_UNEXPECTED;
  1457. }
  1458. if (!QueryComponentDataRef().Service_FInsertPropertyPages(OUT pCallBack, IN pDataObject, handle))
  1459. {
  1460. // Unable to open the service and query service info
  1461. return S_FALSE;
  1462. }
  1463. return S_OK;
  1464. default:
  1465. break;
  1466. }
  1467. ASSERT(FALSE);
  1468. return S_FALSE;
  1469. MFC_CATCH;
  1470. }
  1471. STDMETHODIMP CFileMgmtComponent::Compare(
  1472. LPARAM /*lUserParam*/, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int* pnResult)
  1473. {
  1474. ASSERT(NULL != pnResult);
  1475. // WARNING cookie cast
  1476. CCookie* pBaseCookieA = reinterpret_cast<CCookie*>(cookieA);
  1477. CCookie* pBaseCookieB = reinterpret_cast<CCookie*>(cookieB);
  1478. ASSERT( NULL != pBaseCookieA && NULL != pBaseCookieB );
  1479. CFileMgmtCookie* pCookieA = QueryComponentDataRef().ActiveCookie(
  1480. (CFileMgmtCookie*)pBaseCookieA);
  1481. CFileMgmtCookie* pCookieB = QueryComponentDataRef().ActiveCookie(
  1482. (CFileMgmtCookie*)pBaseCookieB);
  1483. ASSERT( NULL != pCookieA && NULL != pCookieB );
  1484. FileMgmtObjectType objecttypeA = pCookieA->QueryObjectType();
  1485. FileMgmtObjectType objecttypeB = pCookieB->QueryObjectType();
  1486. ASSERT( IsValidObjectType(objecttypeA) && IsValidObjectType(objecttypeB) );
  1487. if (objecttypeA != objecttypeB)
  1488. {
  1489. // assign an arbitrary ordering to cookies with different nodetypes
  1490. *pnResult = ((int)objecttypeA) - ((int)objecttypeB);
  1491. return S_OK;
  1492. }
  1493. return pCookieA->CompareSimilarCookies( pBaseCookieB, pnResult);
  1494. }
  1495. STDMETHODIMP CFileMgmtComponent::GetProperty(
  1496. /* [in] */ LPDATAOBJECT pDataObject,
  1497. /* [in] */ BSTR szPropertyName,
  1498. /* [out] */ BSTR* pbstrProperty)
  1499. {
  1500. if ( IsBadReadPtr(pDataObject,sizeof(*pDataObject))
  1501. || IsBadStringPtr(szPropertyName,0x7FFFFFFF)
  1502. || IsBadWritePtr(pbstrProperty,sizeof(*pbstrProperty))
  1503. )
  1504. {
  1505. ASSERT(FALSE);
  1506. return E_POINTER;
  1507. }
  1508. CCookie* pbasecookie = NULL;
  1509. HRESULT hr = ExtractBaseCookie( pDataObject, &pbasecookie );
  1510. RETURN_HR_IF_FAIL;
  1511. ASSERT(NULL != pbasecookie);
  1512. CFileMgmtCookie* pcookie = (CFileMgmtCookie*)pbasecookie;
  1513. CString strProperty;
  1514. if (!_wcsicmp(L"CCF_HTML_DETAILS",szPropertyName))
  1515. {
  1516. if (FILEMGMT_SERVICE != pcookie->QueryObjectType())
  1517. return S_FALSE;
  1518. if (NULL == QueryComponentDataRef().m_hScManager)
  1519. {
  1520. ASSERT(FALSE);
  1521. return S_FALSE;
  1522. }
  1523. CString strServiceName;
  1524. if (!QueryComponentDataRef().Service_FGetServiceInfoFromIDataObject(
  1525. pDataObject,
  1526. NULL,
  1527. OUT &strServiceName,
  1528. NULL))
  1529. {
  1530. ASSERT(FALSE);
  1531. return S_FALSE;
  1532. }
  1533. BOOL rgfMenuFlags[iServiceActionMax];
  1534. ::ZeroMemory(rgfMenuFlags,sizeof(rgfMenuFlags));
  1535. AFX_MANAGE_STATE(AfxGetStaticModuleState()); // required for CWaitCursor
  1536. CWaitCursor wait;
  1537. if (!Service_FGetServiceButtonStatus( // this will report errors itself
  1538. QueryComponentDataRef().m_hScManager,
  1539. strServiceName,
  1540. OUT rgfMenuFlags,
  1541. NULL, // pdwCurrentState
  1542. TRUE)) // fSilentError
  1543. {
  1544. return S_FALSE;
  1545. }
  1546. for (INT i = 0; i < iServiceActionMax; i++)
  1547. {
  1548. if (rgfMenuFlags[i])
  1549. {
  1550. CString strTemp;
  1551. VERIFY(strTemp.LoadString(IDS_HTML_DETAILS_START+i));
  1552. strProperty += strTemp;
  1553. }
  1554. }
  1555. }
  1556. else if (!_wcsicmp(L"CCF_DESCRIPTION",szPropertyName))
  1557. {
  1558. hr = pcookie->GetExplorerViewDescription( strProperty );
  1559. }
  1560. else
  1561. {
  1562. return S_FALSE; // unknown strPropertyName
  1563. }
  1564. *pbstrProperty = ::SysAllocString(strProperty);
  1565. return S_OK;
  1566. }
  1567. /////////////////////////////////////////////////////////////////////
  1568. // Virtual function called by CComponent::IComponent::Notify(MMCN_COLUMN_CLICK)
  1569. HRESULT CFileMgmtComponent::OnNotifyColumnClick( LPDATAOBJECT /*lpDataObject*/, LPARAM iColumn, LPARAM uFlags )
  1570. {
  1571. m_iSortColumn = (int)iColumn;
  1572. m_dwSortFlags = (DWORD) uFlags;
  1573. return m_pResultData->Sort ((int)iColumn, (DWORD)uFlags, 0);
  1574. }
  1575. HRESULT CFileMgmtComponent::OnNotifySnapinHelp (LPDATAOBJECT /*pDataObject*/)
  1576. {
  1577. return ShowHelpTopic( IsServiceSnapin()
  1578. ? L"sys_srv_overview.htm"
  1579. : L"file_srv_overview.htm" );
  1580. }