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.

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