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.

277 lines
8.7 KiB

  1. /*++
  2. Copyright (C) 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. return ::InterlockedIncrement(&m_Ref);
  28. }
  29. ULONG
  30. CDataObject::Release()
  31. {
  32. ASSERT( 0 != m_Ref );
  33. ULONG cRef = ::InterlockedDecrement(&m_Ref);
  34. if ( 0 == cRef )
  35. {
  36. delete this;
  37. }
  38. return cRef;
  39. }
  40. STDMETHODIMP
  41. CDataObject::QueryInterface(
  42. REFIID riid,
  43. void** ppv
  44. )
  45. {
  46. if (!ppv) {
  47. return E_INVALIDARG;
  48. }
  49. HRESULT hr = S_OK;
  50. if (IsEqualIID(riid, IID_IUnknown)) {
  51. *ppv = (IUnknown*)this;
  52. } else if (IsEqualIID(riid, IID_IDataObject)) {
  53. *ppv = this;
  54. } else {
  55. hr = E_NOINTERFACE;
  56. }
  57. if (SUCCEEDED(hr)) {
  58. AddRef();
  59. } else {
  60. *ppv = NULL;
  61. }
  62. return hr;
  63. }
  64. HRESULT
  65. CDataObject::Initialize(
  66. DATA_OBJECT_TYPES Type,
  67. COOKIE_TYPE ct,
  68. CCookie* pCookie,
  69. String& strMachineName
  70. )
  71. {
  72. try {
  73. m_strMachineName = strMachineName;
  74. m_pCookie = pCookie;
  75. m_Type = Type;
  76. m_ct = ct;
  77. } catch (CMemoryException* e) {
  78. e->Delete();
  79. return E_OUTOFMEMORY;
  80. }
  81. return S_OK;
  82. }
  83. STDMETHODIMP
  84. CDataObject::GetDataHere(
  85. LPFORMATETC lpFormatetc,
  86. LPSTGMEDIUM lpMedium
  87. )
  88. {
  89. HRESULT hr = S_OK;
  90. try {
  91. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  92. hr = DV_E_FORMATETC;
  93. SafeInterfacePtr<IStream> StreamPtr;
  94. if (TYMED_HGLOBAL == lpMedium->tymed) {
  95. ULONG ulWritten;
  96. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &StreamPtr);
  97. if (S_OK == hr) {
  98. const NODEINFO* pni = &NodeInfo[m_ct];
  99. ASSERT(pni->ct == m_ct);
  100. if (cf == m_cfNodeType) {
  101. const GUID* pGuid = &pni->Guid;
  102. hr = StreamPtr->Write(pGuid, sizeof(GUID), &ulWritten);
  103. } else if (cf == m_cfNodeTypeString) {
  104. const TCHAR *pszGuid = pni->GuidString;
  105. hr = StreamPtr->Write(pszGuid,
  106. (ULONG)(wcslen(pszGuid) + 1) * sizeof(TCHAR),
  107. &ulWritten
  108. );
  109. } else if (cf == m_cfDisplayName) {
  110. if (pni->idsFormat) {
  111. String strDisplayName;
  112. TCHAR Format[LINE_LEN];
  113. TCHAR LocalMachine[LINE_LEN];
  114. ::LoadString(g_hInstance, pni->idsFormat, Format, ARRAYLEN(Format));
  115. LPCTSTR MachineName = m_strMachineName;
  116. if (m_strMachineName.IsEmpty()) {
  117. ::LoadString(g_hInstance, IDS_LOCAL_MACHINE, LocalMachine,
  118. ARRAYLEN(LocalMachine));
  119. MachineName = LocalMachine;
  120. }
  121. strDisplayName.Format(Format, MachineName);
  122. hr = StreamPtr->Write(strDisplayName,
  123. (strDisplayName.GetLength() + 1) * sizeof(TCHAR),
  124. &ulWritten
  125. );
  126. }
  127. } else if (cf == m_cfSnapinInternal) {
  128. INTERNAL_DATA tID;
  129. tID.ct = m_ct;
  130. tID.dot = m_Type;
  131. tID.cookie = (MMC_COOKIE)m_pCookie;
  132. hr = StreamPtr->Write(&tID,
  133. sizeof(INTERNAL_DATA),
  134. &ulWritten
  135. );
  136. } else if (cf == m_cfCoClass) {
  137. hr = StreamPtr->Write(&CLSID_DEVMGR,
  138. sizeof(CLSID),
  139. &ulWritten
  140. );
  141. } else if (cf == m_cfMachineName) {
  142. if (!m_strMachineName.IsEmpty()) {
  143. hr = StreamPtr->Write((LPCTSTR)m_strMachineName,
  144. (m_strMachineName.GetLength()+1) * sizeof(TCHAR),
  145. NULL);
  146. } else {
  147. TCHAR Nothing[1];
  148. Nothing[0] = _T('\0');
  149. hr = StreamPtr->Write(Nothing, sizeof(Nothing), NULL);
  150. }
  151. } else if (cf == m_cfClassGuid) {
  152. if (COOKIE_TYPE_RESULTITEM_CLASS == m_pCookie->GetType()) {
  153. CClass* pClass = (CClass*)m_pCookie->GetResultItem();
  154. ASSERT(pClass);
  155. LPGUID pClassGuid = *pClass;
  156. hr = StreamPtr->Write(pClassGuid, sizeof(GUID), NULL);
  157. }
  158. } else if (cf == m_cfDeviceID) {
  159. if (COOKIE_TYPE_RESULTITEM_DEVICE == m_pCookie->GetType()) {
  160. CDevice* pDevice = (CDevice*)m_pCookie->GetResultItem();
  161. ASSERT(pDevice);
  162. LPCTSTR DeviceID = pDevice->GetDeviceID();
  163. hr = StreamPtr->Write(DeviceID,
  164. (ULONG)(wcslen(DeviceID) + 1) * sizeof(TCHAR),
  165. NULL
  166. );
  167. }
  168. } else {
  169. hr = DV_E_FORMATETC;
  170. }
  171. }
  172. }
  173. } catch (CMemoryException* e) {
  174. e->Delete();
  175. hr = E_OUTOFMEMORY;
  176. }
  177. return hr;
  178. }
  179. STDMETHODIMP
  180. CDataObject::GetData(
  181. LPFORMATETC lpFormatetc,
  182. LPSTGMEDIUM lpMedium
  183. )
  184. {
  185. UNREFERENCED_PARAMETER(lpFormatetc);
  186. UNREFERENCED_PARAMETER(lpMedium);
  187. return E_NOTIMPL;
  188. }
  189. STDMETHODIMP
  190. CDataObject::EnumFormatEtc(
  191. DWORD dwDirection,
  192. LPENUMFORMATETC* ppEnumFormatEtc
  193. )
  194. {
  195. UNREFERENCED_PARAMETER(dwDirection);
  196. UNREFERENCED_PARAMETER(ppEnumFormatEtc);
  197. return E_NOTIMPL;
  198. }
  199. HRESULT ExtractData(
  200. IDataObject* pIDataObject,
  201. unsigned int cfClipFormat,
  202. BYTE* pBuffer,
  203. DWORD cbBuffer
  204. )
  205. {
  206. if ((NULL == pIDataObject) || (NULL == pBuffer)) {
  207. return E_POINTER;
  208. }
  209. HRESULT hr = S_OK;
  210. FORMATETC FormatEtc = {(CLIPFORMAT)cfClipFormat, NULL, DVASPECT_CONTENT, -1 , TYMED_HGLOBAL};
  211. STGMEDIUM StgMedium = {TYMED_HGLOBAL, NULL};
  212. StgMedium.hGlobal = ::GlobalAlloc(GMEM_SHARE, cbBuffer);
  213. if (NULL == StgMedium.hGlobal) {
  214. ASSERT(FALSE);
  215. hr = E_OUTOFMEMORY;
  216. } else {
  217. hr = pIDataObject->GetDataHere(&FormatEtc, &StgMedium);
  218. if (SUCCEEDED(hr)) {
  219. BYTE* pData = reinterpret_cast<BYTE*>(::GlobalLock(StgMedium.hGlobal));
  220. if (NULL == pData) {
  221. ASSERT(FALSE);
  222. hr = E_UNEXPECTED;
  223. } else {
  224. ::memcpy(pBuffer, pData, cbBuffer);
  225. ::GlobalUnlock(StgMedium.hGlobal);
  226. }
  227. }
  228. ::GlobalFree(StgMedium.hGlobal);
  229. }
  230. return hr;
  231. }