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.

351 lines
10 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. dataobj.cpp
  5. Abstract:
  6. header file defines CDataObject class
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "devmgr.h"
  12. #include "DataObj.h"
  13. unsigned int CDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  14. unsigned int CDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  15. unsigned int CDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  16. unsigned int CDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  17. unsigned int CDataObject::m_cfSnapinInternal = RegisterClipboardFormat(SNAPIN_INTERNAL);
  18. unsigned int CDataObject::m_cfMachineName = RegisterClipboardFormat(MMC_SNAPIN_MACHINE_NAME);
  19. unsigned int CDataObject::m_cfClassGuid = RegisterClipboardFormat(DEVMGR_SNAPIN_CLASS_GUID);
  20. unsigned int CDataObject::m_cfDeviceID = RegisterClipboardFormat(DEVMGR_SNAPIN_DEVICE_ID);
  21. //
  22. // IUnknown interface implementation
  23. //
  24. ULONG
  25. CDataObject::AddRef()
  26. {
  27. ::InterlockedIncrement((LONG*)&m_Ref);
  28. return m_Ref;
  29. }
  30. ULONG
  31. CDataObject::Release()
  32. {
  33. ::InterlockedDecrement((LONG*)&m_Ref);
  34. if (!m_Ref) {
  35. delete this;
  36. return 0;
  37. }
  38. return m_Ref;
  39. }
  40. STDMETHODIMP
  41. CDataObject::QueryInterface(
  42. REFIID riid,
  43. void** ppv
  44. )
  45. {
  46. if (!ppv)
  47. return E_INVALIDARG;
  48. HRESULT hr = S_OK;
  49. if (IsEqualIID(riid, IID_IUnknown))
  50. *ppv = (IUnknown*)this;
  51. else if (IsEqualIID(riid, IID_IDataObject)) {
  52. *ppv = this;
  53. } else {
  54. hr = E_NOINTERFACE;
  55. }
  56. if (SUCCEEDED(hr))
  57. AddRef();
  58. else
  59. *ppv = NULL;
  60. return hr;
  61. }
  62. HRESULT
  63. CDataObject::Initialize(
  64. DATA_OBJECT_TYPES Type,
  65. COOKIE_TYPE ct,
  66. CCookie* pCookie,
  67. String& strMachineName
  68. )
  69. {
  70. try {
  71. m_strMachineName = strMachineName;
  72. m_pCookie = pCookie;
  73. m_Type = Type;
  74. m_ct = ct;
  75. } catch (CMemoryException* e) {
  76. e->Delete();
  77. return E_OUTOFMEMORY;
  78. }
  79. return S_OK;
  80. }
  81. STDMETHODIMP
  82. CDataObject::GetDataHere(
  83. LPFORMATETC lpFormatetc,
  84. LPSTGMEDIUM lpMedium
  85. )
  86. {
  87. HRESULT hr = S_OK;
  88. try {
  89. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  90. hr = DV_E_FORMATETC;
  91. SafeInterfacePtr<IStream> StreamPtr;
  92. if (TYMED_HGLOBAL == lpMedium->tymed) {
  93. ULONG ulWritten;
  94. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &StreamPtr);
  95. if (S_OK == hr) {
  96. const NODEINFO* pni = &NodeInfo[m_ct];
  97. ASSERT(pni->ct == m_ct);
  98. if (cf == m_cfNodeType) {
  99. const GUID* pGuid = &pni->Guid;
  100. hr = StreamPtr->Write(pGuid, sizeof(GUID), &ulWritten);
  101. } else if (cf == m_cfNodeTypeString) {
  102. const TCHAR *pszGuid = pni->GuidString;
  103. hr = StreamPtr->Write(pszGuid,
  104. (wcslen(pszGuid) + 1) * sizeof(TCHAR),
  105. &ulWritten
  106. );
  107. } else if (cf == m_cfDisplayName) {
  108. if (pni->idsFormat) {
  109. String strDisplayName;
  110. TCHAR Format[LINE_LEN];
  111. TCHAR LocalMachine[LINE_LEN];
  112. ::LoadString(g_hInstance, pni->idsFormat, Format, sizeof(Format)/sizeof(TCHAR));
  113. LPCTSTR MachineName = m_strMachineName;
  114. if (m_strMachineName.IsEmpty()) {
  115. ::LoadString(g_hInstance, IDS_LOCAL_MACHINE, LocalMachine,
  116. sizeof(LocalMachine) / sizeof(TCHAR));
  117. MachineName = LocalMachine;
  118. }
  119. strDisplayName.Format(Format, MachineName);
  120. hr = StreamPtr->Write(strDisplayName,
  121. (strDisplayName.GetLength() + 1) * sizeof(TCHAR),
  122. &ulWritten
  123. );
  124. }
  125. } else if (cf == m_cfSnapinInternal) {
  126. INTERNAL_DATA tID;
  127. tID.ct = m_ct;
  128. tID.dot = m_Type;
  129. tID.cookie = (MMC_COOKIE)m_pCookie;
  130. hr = StreamPtr->Write(&tID,
  131. sizeof(INTERNAL_DATA),
  132. &ulWritten
  133. );
  134. } else if (cf == m_cfCoClass) {
  135. hr = StreamPtr->Write(&CLSID_DEVMGR,
  136. sizeof(CLSID),
  137. &ulWritten
  138. );
  139. } else if (cf == m_cfMachineName) {
  140. if (!m_strMachineName.IsEmpty()) {
  141. hr = StreamPtr->Write((LPCTSTR)m_strMachineName,
  142. (m_strMachineName.GetLength()+1) * sizeof(TCHAR),
  143. NULL);
  144. } else {
  145. TCHAR Nothing[1];
  146. Nothing[0] = _T('\0');
  147. hr = StreamPtr->Write(Nothing, sizeof(Nothing), NULL);
  148. }
  149. } else if (cf == m_cfClassGuid) {
  150. if (COOKIE_TYPE_RESULTITEM_CLASS == m_pCookie->GetType()) {
  151. CClass* pClass = (CClass*)m_pCookie->GetResultItem();
  152. ASSERT(pClass);
  153. LPGUID pClassGuid = *pClass;
  154. hr = StreamPtr->Write(pClassGuid, sizeof(GUID), NULL);
  155. }
  156. } else if (cf == m_cfDeviceID) {
  157. if (COOKIE_TYPE_RESULTITEM_DEVICE == m_pCookie->GetType()) {
  158. CDevice* pDevice = (CDevice*)m_pCookie->GetResultItem();
  159. ASSERT(pDevice);
  160. LPCTSTR DeviceID = pDevice->GetDeviceID();
  161. hr = StreamPtr->Write(DeviceID,
  162. (wcslen(DeviceID) + 1) * sizeof(TCHAR),
  163. NULL
  164. );
  165. }
  166. } else {
  167. hr = DV_E_FORMATETC;
  168. }
  169. }
  170. }
  171. } catch (CMemoryException* e) {
  172. e->Delete();
  173. hr = E_OUTOFMEMORY;
  174. }
  175. return hr;
  176. }
  177. STDMETHODIMP
  178. CDataObject::GetData(
  179. LPFORMATETC lpFormatetc,
  180. LPSTGMEDIUM lpMedium
  181. )
  182. {
  183. return E_NOTIMPL;
  184. }
  185. STDMETHODIMP
  186. CDataObject::EnumFormatEtc(
  187. DWORD dwDirection,
  188. LPENUMFORMATETC* ppEnumFormatEtc
  189. )
  190. {
  191. return E_NOTIMPL;
  192. }
  193. HRESULT ExtractData(
  194. IDataObject* pIDataObject,
  195. unsigned int cfClipFormat,
  196. BYTE* pBuffer,
  197. DWORD cbBuffer
  198. )
  199. {
  200. if (NULL == pIDataObject || NULL == pBuffer)
  201. return E_POINTER;
  202. HRESULT hr = S_OK;
  203. FORMATETC FormatEtc = {(CLIPFORMAT)cfClipFormat, NULL, DVASPECT_CONTENT, -1 , TYMED_HGLOBAL};
  204. STGMEDIUM StgMedium = {TYMED_HGLOBAL, NULL};
  205. StgMedium.hGlobal = ::GlobalAlloc(GMEM_SHARE, cbBuffer);
  206. if (NULL == StgMedium.hGlobal) {
  207. ASSERT(FALSE);
  208. hr = E_OUTOFMEMORY;
  209. } else {
  210. hr = pIDataObject->GetDataHere(&FormatEtc, &StgMedium);
  211. if (SUCCEEDED(hr)) {
  212. BYTE* pData = reinterpret_cast<BYTE*>(::GlobalLock(StgMedium.hGlobal));
  213. if (NULL == pData) {
  214. ASSERT(FALSE);
  215. hr = E_UNEXPECTED;
  216. } else {
  217. ::memcpy(pBuffer, pData, cbBuffer);
  218. ::GlobalUnlock(StgMedium.hGlobal);
  219. }
  220. }
  221. ::GlobalFree(StgMedium.hGlobal);
  222. }
  223. return hr;
  224. }
  225. #if 0
  226. /////////////////////////////////////////////////////////////////////
  227. ////
  228. /// Helper functions to extact data from the given IDataObject
  229. ///
  230. HRESULT ExtractData(IDataObject* piDataObject,
  231. unsigned int cfClipFormat,
  232. BYTE* pBuffer,
  233. DWORD cbBuffer
  234. );
  235. HRESULT ExtractString(IDataObject* piDataObject,
  236. unsigned int cfClipFormat,
  237. String* pstr,
  238. DWORD cchMax
  239. );
  240. HRESULT
  241. ExtractData(
  242. IDataObject* piDataObject,
  243. unsigned int cfClipFormat,
  244. BYTE* pBuffer,
  245. DWORD cbBuffer
  246. )
  247. {
  248. HRESULT hr = S_OK;
  249. FORMATETC Formatetc = {cfClipFormat, NULL, DVASPET_CONTENT, -1, TYMED_HGLOBAL};
  250. STGMEDIUM Stgmedium = {TYMED_HGLOBAL, NULL};
  251. Stgmedium.hGlobal = ::GlobalAlloc(GMEM_SHARE, cbBuffer);
  252. if (NULL == Stgmedium.hGlobal) {
  253. ASSERT(FASLE);
  254. AfxThrowMemoryException();
  255. hr = E_OUTOFMEMORY;
  256. return hr;
  257. }
  258. hr = piDataObject->GetDataHere(&Formatetc, &Stgmedium);
  259. if (FAILED(hr)) {
  260. ASSERT(FALSE);
  261. return hr;
  262. }
  263. BYTE* pData = reinterpret_cast<BYTE*>(::GlobalLock(Stgmedium.hGlobal));
  264. if (NULL == pData) {
  265. ASSERT(FALSE);
  266. hr = E_UNEXPECTED;
  267. }
  268. ::memcpy(pBuffer, pData, cbBuffer);
  269. return hr;
  270. }
  271. HRESULT
  272. ExtractString(
  273. IDataObject* piDataObject,
  274. unsigned int cfClipFormat,
  275. String* pstr
  276. DWORD cbMax
  277. )
  278. {
  279. FORMATETC Formatetc = {cfClipFormat, NULL, DVASPET_CONTENT, -1, TYMED_HGLOBAL};
  280. STGMEDIUM Stgmedium = {TYMED_HGLOBAL, NULL};
  281. Stgmedium.hGlobal = ::GlobalAlloc(GMEM_SHARE, cbBuffer);
  282. if (NULL == Stgmedium.hGlobal) {
  283. ASSERT(FASLE);
  284. AfxThrowMemoryException();
  285. hr = E_OUTOFMEMORY;
  286. return hr;
  287. }
  288. HRESULT hr = piDataObject->GetDataHere(&Formatetc, &Stgmedium);
  289. if (FAILED(hr)) {
  290. ASSERT(FALSE);
  291. return hr;
  292. }
  293. LPTSTR pszData = reinterpret_cast<LPTSTR>(::GlobalLock(Stgmedium.hGlobal));
  294. if (NULL == pszData) {
  295. ASSERT(FALSE);
  296. return E_UNEXPECTTED;
  297. }
  298. USES_CONVERSION;
  299. *pstr = OLE2T(pszData);
  300. return S_OK;
  301. }
  302. #endif