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.

673 lines
22 KiB

  1. // DataObj.cpp : Implementation of data object classes
  2. #include "stdafx.h"
  3. #include "compdata.h"
  4. #include "safetemp.h"
  5. #include "macros.h"
  6. USE_HANDLE_MACROS("FILEMGMT(dataobj.cpp)")
  7. #include "FileSvc.h" // FileServiceProvider
  8. #include "dataobj.h"
  9. #include "smb.h"
  10. #include "fpnw.h"
  11. #include "sfm.h"
  12. #include "cmponent.h" // for COLNUM_SESSIONS_COMPUTERNAME
  13. #define DONT_WANT_SHELLDEBUG
  14. #include "shlobjp.h" // ILFree, ILGetSize, ILClone, etc.
  15. #include <comstrm.h>
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #include "stddtobj.cpp"
  22. // IDataObject interface implementation
  23. HRESULT CFileMgmtDataObject::GetDataHere(
  24. FORMATETC __RPC_FAR *pFormatEtcIn,
  25. STGMEDIUM __RPC_FAR *pMedium)
  26. {
  27. MFC_TRY;
  28. const CLIPFORMAT cf=pFormatEtcIn->cfFormat;
  29. if (cf == m_CFInternal)
  30. {
  31. CFileMgmtDataObject *pThis = this;
  32. stream_ptr s(pMedium);
  33. return s.Write(&pThis, sizeof(CFileMgmtDataObject*));
  34. }
  35. else if (cf == m_CFSnapInCLSID)
  36. {
  37. stream_ptr s(pMedium);
  38. return s.Write(&m_SnapInCLSID, sizeof(GUID));
  39. }
  40. if (!m_MultiSelectObjList.empty())
  41. {
  42. //
  43. // this is the multiselect data object, we don't support other clipformats in GetDataHere().
  44. //
  45. return DV_E_FORMATETC;
  46. }
  47. if (cf == m_CFNodeType)
  48. {
  49. const GUID* pguid = GetObjectTypeGUID( m_objecttype );
  50. stream_ptr s(pMedium);
  51. return s.Write(pguid, sizeof(GUID));
  52. }
  53. else if (cf == m_CFNodeTypeString)
  54. {
  55. const BSTR strGUID = GetObjectTypeString( m_objecttype );
  56. stream_ptr s(pMedium);
  57. return s.Write(strGUID);
  58. }
  59. else if (cf == m_CFDisplayName)
  60. {
  61. return PutDisplayName(pMedium);
  62. }
  63. else if (cf == m_CFDataObjectType)
  64. {
  65. stream_ptr s(pMedium);
  66. return s.Write(&m_dataobjecttype, sizeof(m_dataobjecttype));
  67. }
  68. else if (cf == m_CFMachineName)
  69. {
  70. stream_ptr s(pMedium);
  71. return s.Write(m_strMachineName);
  72. }
  73. else if (cf == m_CFTransport)
  74. {
  75. FILEMGMT_TRANSPORT transport = FILEMGMT_OTHER;
  76. HRESULT hr = m_pcookie->GetTransport( &transport );
  77. if ( FAILED(hr) )
  78. return hr;
  79. stream_ptr s(pMedium);
  80. return s.Write(&transport, sizeof(DWORD));
  81. }
  82. else if (cf == m_CFShareName)
  83. {
  84. ASSERT( NULL != m_pcookie );
  85. CString strShareName;
  86. HRESULT hr = m_pcookie->GetShareName( strShareName );
  87. if ( FAILED(hr) )
  88. return hr;
  89. stream_ptr s(pMedium);
  90. return s.Write(strShareName);
  91. }
  92. else if (cf == m_CFSessionClientName)
  93. {
  94. ASSERT( NULL != m_pcookie );
  95. CString strSessionClientName;
  96. HRESULT hr = m_pcookie->GetSessionClientName( strSessionClientName );
  97. if ( FAILED(hr) )
  98. return hr;
  99. stream_ptr s(pMedium);
  100. return s.Write(strSessionClientName);
  101. }
  102. else if (cf == m_CFSessionUserName)
  103. {
  104. ASSERT( NULL != m_pcookie );
  105. CString strSessionUserName;
  106. HRESULT hr = m_pcookie->GetSessionUserName( strSessionUserName );
  107. if ( FAILED(hr) )
  108. return hr;
  109. stream_ptr s(pMedium);
  110. return s.Write(strSessionUserName);
  111. }
  112. else if (cf == m_CFSessionID)
  113. {
  114. DWORD dwSessionID = 0;
  115. HRESULT hr = m_pcookie->GetSessionID( &dwSessionID );
  116. if ( FAILED(hr) )
  117. return hr;
  118. stream_ptr s(pMedium);
  119. return s.Write(&dwSessionID, sizeof(DWORD));
  120. }
  121. else if (cf == m_CFFileID)
  122. {
  123. DWORD dwFileID = 0;
  124. HRESULT hr = m_pcookie->GetFileID( &dwFileID );
  125. if ( FAILED(hr) )
  126. return hr;
  127. stream_ptr s(pMedium);
  128. return s.Write(&dwFileID, sizeof(DWORD));
  129. }
  130. else if (cf == m_CFServiceName)
  131. {
  132. ASSERT( NULL != m_pcookie );
  133. CString strServiceName;
  134. HRESULT hr = m_pcookie->GetServiceName( strServiceName );
  135. if ( FAILED(hr) )
  136. return hr;
  137. stream_ptr s(pMedium);
  138. return s.Write(strServiceName);
  139. }
  140. else if (cf == m_CFServiceDisplayName)
  141. {
  142. ASSERT( NULL != m_pcookie );
  143. CString strServiceDisplayName;
  144. HRESULT hr = m_pcookie->GetServiceDisplayName( strServiceDisplayName );
  145. if ( FAILED(hr) )
  146. return hr;
  147. stream_ptr s(pMedium);
  148. return s.Write(strServiceDisplayName);
  149. }
  150. else if (cf == m_CFRawCookie)
  151. {
  152. stream_ptr s(pMedium);
  153. return s.Write((PBYTE)&m_pcookie, sizeof(m_pcookie));
  154. }
  155. else if (cf == m_CFSnapinPreloads) // added JonN 01/19/00
  156. {
  157. stream_ptr s(pMedium);
  158. BOOL bPreload = TRUE;
  159. return s.Write((PBYTE)&bPreload, sizeof(BOOL));
  160. }
  161. return DV_E_FORMATETC;
  162. MFC_CATCH;
  163. }
  164. HRESULT CFileMgmtDataObject::Initialize( CFileMgmtCookie* pcookie,
  165. CFileMgmtComponentData& refComponentData,
  166. DATA_OBJECT_TYPES type )
  167. {
  168. if (NULL == pcookie)
  169. {
  170. ASSERT(FALSE);
  171. return E_UNEXPECTED;
  172. }
  173. m_pComponentData = &refComponentData;
  174. ((IComponentData*) m_pComponentData)->AddRef ();
  175. m_objecttype = pcookie->QueryObjectType();
  176. m_fAllowOverrideMachineName = refComponentData.m_fAllowOverrideMachineName;
  177. #ifdef SNAPIN_PROTOTYPER
  178. if (m_objecttype != FILEMGMT_PROTOTYPER_LEAF)
  179. m_strMachineName = pcookie->QueryTargetServer();
  180. #else
  181. m_strMachineName = pcookie->QueryTargetServer();
  182. #endif
  183. m_dataobjecttype = type;
  184. m_pcookie = pcookie;
  185. m_pcookie->AddRefCookie();
  186. VERIFY( SUCCEEDED(refComponentData.GetClassID(&m_SnapInCLSID)) );
  187. return S_OK;
  188. }
  189. CFileMgmtDataObject::~CFileMgmtDataObject()
  190. {
  191. FreeMultiSelectObjList();
  192. if (NULL != m_pcookie)
  193. {
  194. m_pcookie->ReleaseCookie();
  195. }
  196. if ( m_pComponentData )
  197. ((IComponentData*) m_pComponentData)->Release ();
  198. }
  199. /////////////////////////////////////////////////////////////////////
  200. // CFileMgmtDataObject::IDataObject::GetData()
  201. //
  202. // Write data into the storage medium.
  203. // The data will be retrieved by the Send Console Message snapin.
  204. //
  205. //
  206. HRESULT CFileMgmtDataObject::GetData(
  207. FORMATETC __RPC_FAR * pFormatEtcIn,
  208. STGMEDIUM __RPC_FAR * pMedium)
  209. {
  210. ASSERT(pFormatEtcIn != NULL);
  211. ASSERT(pMedium != NULL);
  212. HRESULT hResult = S_OK;
  213. const CLIPFORMAT cf = pFormatEtcIn->cfFormat;
  214. if (!m_MultiSelectObjList.empty())
  215. {
  216. //
  217. // This is the multiselect dataobject.
  218. //
  219. if (cf == m_CFObjectTypesInMultiSelect)
  220. {
  221. //
  222. // We will provide the list of object types of all the currently selected items here.
  223. // MMC will use this format to determine extensions snapins
  224. //
  225. UINT nMultiSelectedObjects = m_MultiSelectObjList.size();
  226. // Calculate the size of SMMCObjectTypes.
  227. int cb = sizeof(DWORD) + sizeof(SMMCObjectTypes) * nMultiSelectedObjects;
  228. //Fill out parameters
  229. pMedium->tymed = TYMED_HGLOBAL;
  230. pMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, cb);
  231. if (pMedium->hGlobal == NULL)
  232. return STG_E_MEDIUMFULL;
  233. SMMCObjectTypes* pMMCDO = reinterpret_cast<SMMCObjectTypes*>(::GlobalLock(pMedium->hGlobal));
  234. pMMCDO->count = 0;
  235. GUID *pMMCDOGuid = pMMCDO->guid;
  236. for (CDataObjectList::iterator i = m_MultiSelectObjList.begin(); i != m_MultiSelectObjList.end(); i++)
  237. {
  238. CCookie* pbasecookie = NULL;
  239. hResult = ExtractData(*i, CFileMgmtDataObject::m_CFRawCookie, &pbasecookie, sizeof(pbasecookie));
  240. if (FAILED(hResult))
  241. break;
  242. pbasecookie = m_pComponentData->ActiveBaseCookie( pbasecookie );
  243. CFileMgmtCookie* pUseThisCookie = dynamic_cast<CFileMgmtCookie*>(pbasecookie);
  244. FileMgmtObjectType objecttype = pUseThisCookie->QueryObjectType();
  245. const GUID* pguid = GetObjectTypeGUID(objecttype);
  246. memcpy(pMMCDOGuid++, pguid, sizeof(GUID));
  247. pMMCDO->count++;
  248. }
  249. ::GlobalUnlock(pMedium->hGlobal);
  250. if (FAILED(hResult))
  251. {
  252. ::GlobalFree(pMedium->hGlobal);
  253. pMedium->hGlobal = NULL;
  254. }
  255. } else
  256. hResult = DV_E_FORMATETC;
  257. return hResult;
  258. }
  259. if (cf == m_cfSendConsoleMessageRecipients)
  260. {
  261. ASSERT (m_pComponentData);
  262. if ( m_pComponentData )
  263. {
  264. // I suppose it doesn't matter what type this cookie is because we
  265. // are just using to hang enumerated session cookies off of, as long
  266. // as it's not an abstract class.
  267. BOOL fContinue = TRUE;
  268. HRESULT hr = S_OK;
  269. CSmbSessionCookie* pCookie = new CSmbSessionCookie[1];
  270. if ( pCookie )
  271. {
  272. CSmbCookieBlock cookieBlock (pCookie, 1, (LPCTSTR) m_strMachineName, 0);
  273. CBaseCookieBlock* pCookieBlock = 0;
  274. //
  275. // JonN 6/28/01 426224
  276. // Shared Folder: Send Message access denied error title needs to be changed for localization
  277. //
  278. AFX_MANAGE_STATE(AfxGetStaticModuleState()); // required for CWaitCursor
  279. // Enumerate all the session cookies
  280. for (INT iTransport = FILEMGMT_FIRST_TRANSPORT;
  281. fContinue && iTransport < FILEMGMT_NUM_TRANSPORTS;
  282. iTransport++ )
  283. {
  284. hr = m_pComponentData->GetFileServiceProvider(iTransport)->EnumerateSessions(
  285. NULL, &pCookie[0], false);
  286. fContinue = SUCCEEDED(hr);
  287. }
  288. // Enumerate all the computer names from the session cookies and store them in
  289. // the computerList
  290. CStringList computerList;
  291. size_t len = 0; // number of WCHARS
  292. while ( !pCookie[0].m_listResultCookieBlocks.IsEmpty () )
  293. {
  294. pCookieBlock = pCookie[0].m_listResultCookieBlocks.RemoveHead ();
  295. ASSERT (pCookieBlock);
  296. if ( !pCookieBlock )
  297. break;
  298. int nCookies = pCookieBlock->QueryNumCookies ();
  299. while (nCookies--)
  300. {
  301. CCookie* pBaseCookie = pCookieBlock->QueryBaseCookie (nCookies);
  302. ASSERT (pBaseCookie);
  303. if ( pBaseCookie )
  304. {
  305. CFileMgmtCookie* pFMCookie = dynamic_cast <CFileMgmtCookie*> (pBaseCookie);
  306. ASSERT (pFMCookie);
  307. if ( pFMCookie )
  308. {
  309. computerList.AddHead (pFMCookie->QueryResultColumnText (
  310. COLNUM_SESSIONS_COMPUTERNAME, *m_pComponentData));
  311. len += computerList.GetHead ().GetLength () + 1; // to account for NULL
  312. }
  313. }
  314. }
  315. pCookieBlock->Release ();
  316. }
  317. if ( !m_strMachineName.IsEmpty () )
  318. {
  319. computerList.AddHead (m_strMachineName);
  320. len += computerList.GetHead ().GetLength () + 1; // to account for NULL
  321. }
  322. // Run through all the computer names in computerList and add them to the output buffer
  323. //
  324. // Write the list of recipients to the storage medium.
  325. // - The list of recipients is a group of UNICODE strings
  326. // terminated by TWO null characters.c
  327. // - Allocated memory must include BOTH null characters.
  328. //
  329. len += 1; // to account for extra NULL at end.
  330. WCHAR* pgrszRecipients = new WCHAR[len];
  331. WCHAR* ptr = pgrszRecipients;
  332. CString computerName;
  333. if ( pgrszRecipients )
  334. {
  335. ::ZeroMemory (pgrszRecipients, len * sizeof (WCHAR));
  336. while ( !computerList.IsEmpty () )
  337. {
  338. computerName = computerList.RemoveHead ();
  339. // append computer name
  340. wcscpy (ptr, (LPCTSTR) computerName);
  341. // skip past computer name and terminating NULL
  342. ptr += computerName.GetLength () + 1;
  343. }
  344. // Add the name of this computer
  345. HGLOBAL hGlobal = ::GlobalAlloc (GMEM_FIXED, len * sizeof (WCHAR));
  346. if ( hGlobal )
  347. {
  348. memcpy (OUT hGlobal, pgrszRecipients, len * sizeof (WCHAR));
  349. pMedium->hGlobal = hGlobal;
  350. }
  351. else
  352. hResult = E_OUTOFMEMORY;
  353. delete [] pgrszRecipients;
  354. }
  355. else
  356. hResult = E_OUTOFMEMORY;
  357. // pCookie deleted in destructor of cookieBlock
  358. }
  359. else
  360. hResult = E_OUTOFMEMORY;
  361. }
  362. else
  363. hResult = E_UNEXPECTED;
  364. }
  365. else if (cf == m_CFIDList)
  366. {
  367. LPITEMIDLIST pidl = NULL, pidlR = NULL;
  368. hResult = m_pcookie->GetSharePIDList( &pidl );
  369. if (SUCCEEDED(hResult))
  370. {
  371. pidlR = ILClone(ILFindLastID(pidl)); // relative IDList
  372. ILRemoveLastID(pidl); // folder IDList
  373. int cidl = 1;
  374. UINT offset = sizeof(CIDA) + sizeof(UINT)*cidl;
  375. UINT cbFolder = ILGetSize(pidl);
  376. UINT cbRelative = ILGetSize(pidlR);
  377. UINT cbTotal = offset + cbFolder + cbRelative;
  378. HGLOBAL hGlobal = ::GlobalAlloc (GPTR, cbTotal);
  379. if ( hGlobal )
  380. {
  381. LPIDA pida = (LPIDA)hGlobal;
  382. pida->cidl = cidl;
  383. pida->aoffset[0] = offset;
  384. MoveMemory(((LPBYTE)hGlobal+offset), pidl, cbFolder);
  385. offset += cbFolder;
  386. pida->aoffset[1] = offset;
  387. MoveMemory(((LPBYTE)hGlobal+offset), pidlR, cbRelative);
  388. pMedium->hGlobal = hGlobal;
  389. }
  390. else
  391. hResult = E_OUTOFMEMORY;
  392. // free pidl & pidlR
  393. if (pidl)
  394. ILFree(pidl);
  395. if (pidlR)
  396. ILFree(pidlR);
  397. } else
  398. hResult = DV_E_FORMATETC;
  399. } else
  400. hResult = DV_E_FORMATETC; // Invalid/unknown clipboard format
  401. return hResult;
  402. } // CMyComputerDataObject::GetData()
  403. HRESULT CFileMgmtDataObject::PutDisplayName(STGMEDIUM* pMedium)
  404. // Writes the "friendly name" to the provided storage medium
  405. // Returns the result of the write operation
  406. {
  407. if ( !IsAutonomousObjectType(m_objecttype) )
  408. {
  409. ASSERT(FALSE);
  410. return DV_E_FORMATETC;
  411. }
  412. CString strDisplayName;
  413. BOOL fStaticNode = ( NULL != m_pComponentData
  414. && !m_pComponentData->IsExtensionSnapin()
  415. && m_pComponentData->QueryRootCookie().QueryObjectType()
  416. == m_objecttype);
  417. // will only succeed for scope cookies
  418. m_pcookie->GetDisplayName( strDisplayName, fStaticNode );
  419. // LoadStringPrintf(nStringId, OUT &strDisplayName, (LPCTSTR)m_strMachineName);
  420. stream_ptr s(pMedium);
  421. return s.Write(strDisplayName);
  422. }
  423. void CFileMgmtDataObject::FreeMultiSelectObjList()
  424. {
  425. if (!m_MultiSelectObjList.empty())
  426. {
  427. for (CDataObjectList::iterator i = m_MultiSelectObjList.begin(); i != m_MultiSelectObjList.end(); i++)
  428. delete (*i);
  429. m_MultiSelectObjList.clear();
  430. }
  431. }
  432. HRESULT CFileMgmtDataObject::InitMultiSelectDataObjects(CFileMgmtComponentData& refComponentData)
  433. {
  434. FreeMultiSelectObjList();
  435. ASSERT(!m_pComponentData);
  436. m_pComponentData = &refComponentData;
  437. ((IComponentData*) m_pComponentData)->AddRef ();
  438. VERIFY( SUCCEEDED(refComponentData.GetClassID(&m_SnapInCLSID)) );
  439. return S_OK;
  440. }
  441. HRESULT CFileMgmtDataObject::AddMultiSelectDataObjects(CFileMgmtCookie* pCookie, DATA_OBJECT_TYPES type)
  442. {
  443. HRESULT hr = S_OK;
  444. CComObject<CFileMgmtDataObject>* pDataObject = NULL;
  445. hr = CComObject<CFileMgmtDataObject>::CreateInstance(&pDataObject);
  446. if (SUCCEEDED(hr))
  447. hr = pDataObject->Initialize(pCookie, *m_pComponentData, type );
  448. IDataObject *piDataObject = NULL;
  449. if (SUCCEEDED(hr))
  450. hr = pDataObject->QueryInterface(IID_IDataObject, reinterpret_cast<void**>(&piDataObject));
  451. if (SUCCEEDED(hr))
  452. {
  453. m_MultiSelectObjList.push_back(piDataObject);
  454. } else
  455. {
  456. delete pDataObject;
  457. }
  458. return hr;
  459. }
  460. // Register the clipboard formats
  461. CLIPFORMAT CFileMgmtDataObject::m_CFSnapinPreloads =
  462. (CLIPFORMAT)RegisterClipboardFormat(CCF_SNAPIN_PRELOADS);
  463. CLIPFORMAT CFileMgmtDataObject::m_CFDisplayName =
  464. (CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
  465. CLIPFORMAT CFileMgmtDataObject::m_CFTransport =
  466. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_TRANSPORT");
  467. CLIPFORMAT CFileMgmtDataObject::m_CFMachineName =
  468. (CLIPFORMAT)RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  469. CLIPFORMAT CFileMgmtDataObject::m_CFShareName =
  470. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SHARE_NAME");
  471. CLIPFORMAT CFileMgmtDataObject::m_CFSessionClientName =
  472. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SESSION_CLIENT_NAME");
  473. CLIPFORMAT CFileMgmtDataObject::m_CFSessionUserName =
  474. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SESSION_USER_NAME");
  475. CLIPFORMAT CFileMgmtDataObject::m_CFSessionID =
  476. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SESSION_ID");
  477. CLIPFORMAT CFileMgmtDataObject::m_CFFileID =
  478. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_FILE_ID");
  479. CLIPFORMAT CFileMgmtDataObject::m_CFServiceName =
  480. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_NAME");
  481. CLIPFORMAT CFileMgmtDataObject::m_CFServiceDisplayName =
  482. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME");
  483. CLIPFORMAT CDataObject::m_CFRawCookie =
  484. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_RAW_COOKIE");
  485. // Additional clipboard formats for the Send Console Message snapin
  486. CLIPFORMAT CFileMgmtDataObject::m_cfSendConsoleMessageRecipients =
  487. (CLIPFORMAT)RegisterClipboardFormat(_T("mmc.sendcmsg.MessageRecipients"));
  488. // Additional clipboard formats for the Security Page
  489. CLIPFORMAT CFileMgmtDataObject::m_CFIDList =
  490. (CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  491. CLIPFORMAT CFileMgmtDataObject::m_CFObjectTypesInMultiSelect =
  492. (CLIPFORMAT)RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  493. CLIPFORMAT CFileMgmtDataObject::m_CFMultiSelectDataObject =
  494. (CLIPFORMAT)RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
  495. CLIPFORMAT CFileMgmtDataObject::m_CFMultiSelectSnapins =
  496. (CLIPFORMAT)RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
  497. CLIPFORMAT CFileMgmtDataObject::m_CFInternal =
  498. (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_INTERNAL");
  499. STDMETHODIMP CFileMgmtComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  500. {
  501. MFC_TRY;
  502. // WARNING cookie cast
  503. CCookie* pbasecookie = reinterpret_cast<CCookie*>(cookie);
  504. CFileMgmtCookie* pUseThisCookie = ActiveCookie((CFileMgmtCookie*)pbasecookie);
  505. ASSERT( IsValidObjectType(pUseThisCookie->QueryObjectType()) );
  506. CComObject<CFileMgmtDataObject>* pDataObject = NULL;
  507. HRESULT hRes = CComObject<CFileMgmtDataObject>::CreateInstance(&pDataObject);
  508. if ( FAILED(hRes) )
  509. return hRes;
  510. HRESULT hr = pDataObject->Initialize( pUseThisCookie, *this, type );
  511. if ( SUCCEEDED(hr) )
  512. {
  513. hr = pDataObject->QueryInterface(IID_IDataObject,
  514. reinterpret_cast<void**>(ppDataObject));
  515. }
  516. if ( FAILED(hr) )
  517. {
  518. delete pDataObject;
  519. return hr;
  520. }
  521. return hr;
  522. MFC_CATCH;
  523. }
  524. /////////////////////////////////////////////////////////////////////
  525. // FileMgmtObjectTypeFromIDataObject()
  526. //
  527. // Find the objecttype of a IDataObject pointer. The purpose
  528. // of this routine is to combine ExtractObjectTypeGUID() and
  529. // CheckObjectTypeGUID() into a single function.
  530. //
  531. // Return the FILEMGMT_* node type (enum FileMgmtObjectType).
  532. //
  533. // HISTORY
  534. // 30-Jul-97 t-danm Creation.
  535. //
  536. FileMgmtObjectType
  537. FileMgmtObjectTypeFromIDataObject(IN LPDATAOBJECT lpDataObject)
  538. {
  539. ASSERT(lpDataObject != NULL);
  540. GUID guidObjectType = GUID_NULL; // JonN 11/21/00 PREFIX 226042
  541. HRESULT hr = ExtractObjectTypeGUID( IN lpDataObject, OUT &guidObjectType );
  542. ASSERT( SUCCEEDED(hr) );
  543. return (FileMgmtObjectType)CheckObjectTypeGUID(IN &guidObjectType );
  544. } // FileMgmtObjectTypeFromIDataObject()
  545. HRESULT ExtractBaseCookie(
  546. IN LPDATAOBJECT piDataObject,
  547. OUT CCookie** ppcookie,
  548. OUT FileMgmtObjectType* pobjecttype )
  549. {
  550. HRESULT hr = ExtractData( piDataObject,
  551. CFileMgmtDataObject::m_CFRawCookie,
  552. (PBYTE)ppcookie,
  553. sizeof(CCookie*) );
  554. if ( SUCCEEDED(hr) && NULL != pobjecttype )
  555. {
  556. *pobjecttype = FileMgmtObjectTypeFromIDataObject(piDataObject);
  557. }
  558. return hr;
  559. }
  560. BOOL IsMultiSelectObject(LPDATAOBJECT piDataObject)
  561. {
  562. BOOL bMultiSelectObject = FALSE;
  563. if (piDataObject)
  564. {
  565. //
  566. // return TRUE if piDataObject is the composite data object (MMC_MS_DO) created by MMC.
  567. //
  568. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL};
  569. FORMATETC formatetc = {CFileMgmtDataObject::m_CFMultiSelectDataObject,
  570. NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  571. HRESULT hr = piDataObject->GetData(&formatetc, &stgmedium);
  572. if (S_OK == hr && stgmedium.hGlobal)
  573. {
  574. DWORD* pdwData = reinterpret_cast<DWORD*>(::GlobalLock(stgmedium.hGlobal));
  575. bMultiSelectObject = (1 == *pdwData);
  576. ::GlobalUnlock(stgmedium.hGlobal);
  577. ::GlobalFree(stgmedium.hGlobal);
  578. }
  579. }
  580. return bMultiSelectObject;
  581. }