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.

206 lines
6.0 KiB

  1. #include "main.h"
  2. #include <initguid.h>
  3. #include "dataobj.h"
  4. unsigned int CDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  5. unsigned int CDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  6. unsigned int CDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  7. unsigned int CDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  8. ///////////////////////////////////////////////////////////////////////////////
  9. // //
  10. // CDataObject implementation //
  11. // //
  12. ///////////////////////////////////////////////////////////////////////////////
  13. CDataObject::CDataObject(CComponentData *pComponent)
  14. {
  15. m_cRef = 1;
  16. InterlockedIncrement(&g_cRefThisDll);
  17. m_pcd = pComponent;
  18. m_type = CCT_UNINITIALIZED;
  19. m_cookie = -1;
  20. }
  21. CDataObject::~CDataObject()
  22. {
  23. InterlockedDecrement(&g_cRefThisDll);
  24. }
  25. ///////////////////////////////////////////////////////////////////////////////
  26. // //
  27. // CDataObject object implementation (IUnknown) //
  28. // //
  29. ///////////////////////////////////////////////////////////////////////////////
  30. HRESULT CDataObject::QueryInterface (REFIID riid, void **ppv)
  31. {
  32. if (IsEqualIID(riid, IID_IGPTDataObject))
  33. {
  34. *ppv = (LPGPTDATAOBJECT)this;
  35. m_cRef++;
  36. return S_OK;
  37. }
  38. else if (IsEqualIID(riid, IID_IDataObject) ||
  39. IsEqualIID(riid, IID_IUnknown))
  40. {
  41. *ppv = (LPDATAOBJECT)this;
  42. m_cRef++;
  43. return S_OK;
  44. }
  45. else
  46. {
  47. *ppv = NULL;
  48. return E_NOINTERFACE;
  49. }
  50. }
  51. ULONG CDataObject::AddRef (void)
  52. {
  53. return ++m_cRef;
  54. }
  55. ULONG CDataObject::Release (void)
  56. {
  57. if (--m_cRef == 0) {
  58. delete this;
  59. return 0;
  60. }
  61. return m_cRef;
  62. }
  63. ///////////////////////////////////////////////////////////////////////////////
  64. // //
  65. // CDataObject object implementation (IDataObject) //
  66. // //
  67. ///////////////////////////////////////////////////////////////////////////////
  68. STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  69. {
  70. HRESULT hr = DV_E_CLIPFORMAT;
  71. // Based on the CLIPFORMAT write data to the stream
  72. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  73. if(cf == m_cfNodeType)
  74. {
  75. hr = CreateNodeTypeData(lpMedium);
  76. }
  77. else if(cf == m_cfNodeTypeString)
  78. {
  79. hr = CreateNodeTypeStringData(lpMedium);
  80. }
  81. else if (cf == m_cfDisplayName)
  82. {
  83. hr = CreateDisplayName(lpMedium);
  84. }
  85. else if (cf == m_cfCoClass)
  86. {
  87. hr = CreateCoClassID(lpMedium);
  88. }
  89. return hr;
  90. }
  91. ///////////////////////////////////////////////////////////////////////////////
  92. // //
  93. // CDataObject object implementation (Internal functions) //
  94. // //
  95. ///////////////////////////////////////////////////////////////////////////////
  96. HRESULT CDataObject::Create(LPVOID pBuffer, INT len, LPSTGMEDIUM lpMedium)
  97. {
  98. HRESULT hr = DV_E_TYMED;
  99. // Do some simple validation
  100. if (pBuffer == NULL || lpMedium == NULL)
  101. return E_POINTER;
  102. // Make sure the type medium is HGLOBAL
  103. if (lpMedium->tymed == TYMED_HGLOBAL)
  104. {
  105. // Create the stream on the hGlobal passed in
  106. LPSTREAM lpStream;
  107. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  108. if (SUCCEEDED(hr))
  109. {
  110. // Write to the stream the number of bytes
  111. unsigned long written;
  112. hr = lpStream->Write(pBuffer, len, &written);
  113. // Because we told CreateStreamOnHGlobal with 'FALSE',
  114. // only the stream is released here.
  115. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  116. // at the correct time. This is according to the IDataObject specification.
  117. lpStream->Release();
  118. }
  119. }
  120. return hr;
  121. }
  122. HRESULT CDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  123. {
  124. const GUID * pGUID;
  125. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  126. if (m_cookie == -1)
  127. return E_UNEXPECTED;
  128. if (m_type == CCT_RESULT)
  129. pGUID = g_NameSpace[lpResultItem->dwNameSpaceItem].pNodeID;
  130. else
  131. pGUID = g_NameSpace[m_cookie].pNodeID;
  132. // Create the node type object in GUID format
  133. return Create((LPVOID)pGUID, sizeof(GUID), lpMedium);
  134. }
  135. HRESULT CDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  136. {
  137. const GUID * pGUID;
  138. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  139. TCHAR szNodeType[50];
  140. if (m_cookie == -1)
  141. return E_UNEXPECTED;
  142. if (m_type == CCT_RESULT)
  143. pGUID = g_NameSpace[lpResultItem->dwNameSpaceItem].pNodeID;
  144. else
  145. pGUID = g_NameSpace[m_cookie].pNodeID;
  146. szNodeType[0] = TEXT('\0');
  147. StringFromGUID2 (*pGUID, szNodeType, 50);
  148. // Create the node type object in GUID string format
  149. return Create((LPVOID)szNodeType, ((lstrlenW(szNodeType)+1) * sizeof(WCHAR)), lpMedium);
  150. }
  151. HRESULT CDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  152. {
  153. WCHAR szDispName[50];
  154. WCHAR szDisplayName[100];
  155. LoadStringW (g_hInstance, IDS_SNAPIN_NAME, szDisplayName, 100);
  156. return Create((LPVOID)szDisplayName, (lstrlenW(szDisplayName) + 1) * sizeof(WCHAR), lpMedium);
  157. }
  158. HRESULT CDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  159. {
  160. // Create the CoClass information
  161. return Create((LPVOID)&CLSID_GPTDemoSnapIn, sizeof(CLSID), lpMedium);
  162. }