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.

371 lines
11 KiB

  1. #include "main.h"
  2. #include <initguid.h>
  3. #include "dataobj.h"
  4. #include "rsopdobj.h"
  5. unsigned int CRSOPDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  6. unsigned int CRSOPDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  7. unsigned int CRSOPDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  8. unsigned int CRSOPDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  9. unsigned int CRSOPDataObject::m_cfPreloads = RegisterClipboardFormat(CCF_SNAPIN_PRELOADS);
  10. unsigned int CRSOPDataObject::m_cfNodeID = RegisterClipboardFormat(CCF_NODEID);
  11. unsigned int CRSOPDataObject::m_cfDescription = RegisterClipboardFormat(L"CCF_DESCRIPTION");
  12. unsigned int CRSOPDataObject::m_cfHTMLDetails = RegisterClipboardFormat(L"CCF_HTML_DETAILS");
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // //
  15. // CRSOPDataObject implementation //
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. CRSOPDataObject::CRSOPDataObject(CRSOPComponentData *pComponent)
  19. {
  20. m_cRef = 1;
  21. InterlockedIncrement(&g_cRefThisDll);
  22. m_pcd = pComponent;
  23. m_pcd->AddRef();
  24. m_type = CCT_UNINITIALIZED;
  25. m_cookie = -1;
  26. }
  27. CRSOPDataObject::~CRSOPDataObject()
  28. {
  29. m_pcd->Release();
  30. InterlockedDecrement(&g_cRefThisDll);
  31. }
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // //
  34. // CRSOPDataObject object implementation (IUnknown) //
  35. // //
  36. ///////////////////////////////////////////////////////////////////////////////
  37. HRESULT CRSOPDataObject::QueryInterface (REFIID riid, void **ppv)
  38. {
  39. if (IsEqualIID(riid, IID_IRSOPInformation))
  40. {
  41. *ppv = (LPRSOPINFORMATION)this;
  42. m_cRef++;
  43. return S_OK;
  44. }
  45. else if (IsEqualIID(riid, IID_IRSOPDataObject))
  46. {
  47. *ppv = (LPRSOPDATAOBJECT)this;
  48. m_cRef++;
  49. return S_OK;
  50. }
  51. else if (IsEqualIID(riid, IID_IDataObject) ||
  52. IsEqualIID(riid, IID_IUnknown))
  53. {
  54. *ppv = (LPDATAOBJECT)this;
  55. m_cRef++;
  56. return S_OK;
  57. }
  58. else
  59. {
  60. *ppv = NULL;
  61. return E_NOINTERFACE;
  62. }
  63. }
  64. ULONG CRSOPDataObject::AddRef (void)
  65. {
  66. return ++m_cRef;
  67. }
  68. ULONG CRSOPDataObject::Release (void)
  69. {
  70. if (--m_cRef == 0) {
  71. delete this;
  72. return 0;
  73. }
  74. return m_cRef;
  75. }
  76. ///////////////////////////////////////////////////////////////////////////////
  77. // //
  78. // CRSOPDataObject object implementation (IDataObject) //
  79. // //
  80. ///////////////////////////////////////////////////////////////////////////////
  81. STDMETHODIMP CRSOPDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  82. {
  83. HRESULT hr = DV_E_CLIPFORMAT;
  84. // Based on the CLIPFORMAT write data to the stream
  85. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  86. if(cf == m_cfNodeType)
  87. {
  88. hr = CreateNodeTypeData(lpMedium);
  89. }
  90. else if(cf == m_cfNodeTypeString)
  91. {
  92. hr = CreateNodeTypeStringData(lpMedium);
  93. }
  94. else if (cf == m_cfDisplayName)
  95. {
  96. hr = CreateDisplayName(lpMedium);
  97. }
  98. else if (cf == m_cfCoClass)
  99. {
  100. hr = CreateCoClassID(lpMedium);
  101. }
  102. else if (cf == m_cfPreloads)
  103. {
  104. hr = CreatePreloadsData(lpMedium);
  105. }
  106. else if (cf == m_cfDescription)
  107. {
  108. hr = DV_E_TYMED;
  109. if (lpMedium->tymed == TYMED_ISTREAM)
  110. {
  111. ULONG ulWritten;
  112. TCHAR szDesc[300];
  113. IStream *lpStream = lpMedium->pstm;
  114. if(lpStream)
  115. {
  116. LoadString (g_hInstance, g_RsopNameSpace[m_cookie].iStringDescID, szDesc, ARRAYSIZE(szDesc));
  117. hr = lpStream->Write(szDesc, lstrlen(szDesc) * sizeof(TCHAR), &ulWritten);
  118. if (SUCCEEDED(hr))
  119. {
  120. if ((m_cookie == 0) && (m_pcd->m_bComputerCSEError || m_pcd->m_bUserCSEError))
  121. {
  122. LoadString (g_hInstance, IDS_CSEFAILURE2_DESC, szDesc, ARRAYSIZE(szDesc));
  123. hr = lpStream->Write(szDesc, lstrlen(szDesc) * sizeof(TCHAR), &ulWritten);
  124. }
  125. if (((m_cookie == 1) && m_pcd->m_bComputerCSEError) ||
  126. ((m_cookie == 2) && m_pcd->m_bUserCSEError))
  127. {
  128. LoadString (g_hInstance, IDS_CSEFAILURE_DESC, szDesc, ARRAYSIZE(szDesc));
  129. hr = lpStream->Write(szDesc, lstrlen(szDesc) * sizeof(TCHAR), &ulWritten);
  130. }
  131. }
  132. }
  133. }
  134. }
  135. else if (cf == m_cfHTMLDetails)
  136. {
  137. hr = DV_E_TYMED;
  138. if (lpMedium->tymed == TYMED_ISTREAM)
  139. {
  140. ULONG ulWritten;
  141. if ((m_cookie == 0) || (m_cookie == 1) || (m_cookie == 2))
  142. {
  143. IStream *lpStream = lpMedium->pstm;
  144. if(lpStream)
  145. {
  146. hr = lpStream->Write(g_szDisplayProperties, lstrlen(g_szDisplayProperties) * sizeof(TCHAR), &ulWritten);
  147. }
  148. }
  149. }
  150. }
  151. return hr;
  152. }
  153. STDMETHODIMP CRSOPDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  154. {
  155. HRESULT hr = DV_E_CLIPFORMAT;
  156. // Based on the CLIPFORMAT write data to the stream
  157. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  158. if (cf == m_cfNodeID)
  159. {
  160. hr = CreateNodeIDData(lpMedium);
  161. }
  162. return hr;
  163. }
  164. ///////////////////////////////////////////////////////////////////////////////
  165. // //
  166. // CRSOPDataObject object implementation (IROSPInformation) //
  167. // //
  168. ///////////////////////////////////////////////////////////////////////////////
  169. STDMETHODIMP CRSOPDataObject::GetNamespace (DWORD dwSection, LPOLESTR pszName, int cchMaxLength)
  170. {
  171. return m_pcd->GetNamespace(dwSection, pszName, cchMaxLength);
  172. }
  173. STDMETHODIMP CRSOPDataObject::GetFlags (DWORD * pdwFlags)
  174. {
  175. return m_pcd->GetFlags(pdwFlags);
  176. }
  177. STDMETHODIMP CRSOPDataObject::GetEventLogEntryText (LPOLESTR pszEventSource, LPOLESTR pszEventLogName,
  178. LPOLESTR pszEventTime, DWORD dwEventID,
  179. LPOLESTR *ppszText)
  180. {
  181. return m_pcd->GetEventLogEntryText(pszEventSource, pszEventLogName, pszEventTime, dwEventID, ppszText);
  182. }
  183. ///////////////////////////////////////////////////////////////////////////////
  184. // //
  185. // CRSOPDataObject object implementation (Internal functions) //
  186. // //
  187. ///////////////////////////////////////////////////////////////////////////////
  188. HRESULT CRSOPDataObject::Create(LPVOID pBuffer, INT len, LPSTGMEDIUM lpMedium)
  189. {
  190. HRESULT hr = DV_E_TYMED;
  191. // Do some simple validation
  192. if (pBuffer == NULL || lpMedium == NULL)
  193. return E_POINTER;
  194. // Make sure the type medium is HGLOBAL
  195. if (lpMedium->tymed == TYMED_HGLOBAL)
  196. {
  197. // Create the stream on the hGlobal passed in
  198. LPSTREAM lpStream;
  199. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  200. if (SUCCEEDED(hr))
  201. {
  202. // Write to the stream the number of bytes
  203. unsigned long written;
  204. hr = lpStream->Write(pBuffer, len, &written);
  205. // Because we told CreateStreamOnHGlobal with 'FALSE',
  206. // only the stream is released here.
  207. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  208. // at the correct time. This is according to the IDataObject specification.
  209. lpStream->Release();
  210. }
  211. }
  212. return hr;
  213. }
  214. HRESULT CRSOPDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  215. {
  216. const GUID * pGUID;
  217. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  218. if (m_cookie == -1)
  219. return E_UNEXPECTED;
  220. if (m_type == CCT_RESULT)
  221. pGUID = g_RsopNameSpace[lpResultItem->dwNameSpaceItem].pNodeID;
  222. else
  223. pGUID = g_RsopNameSpace[m_cookie].pNodeID;
  224. // Create the node type object in GUID format
  225. return Create((LPVOID)pGUID, sizeof(GUID), lpMedium);
  226. }
  227. HRESULT CRSOPDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  228. {
  229. const GUID * pGUID;
  230. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  231. TCHAR szNodeType[50];
  232. if (m_cookie == -1)
  233. return E_UNEXPECTED;
  234. if (m_type == CCT_RESULT)
  235. pGUID = g_RsopNameSpace[lpResultItem->dwNameSpaceItem].pNodeID;
  236. else
  237. pGUID = g_RsopNameSpace[m_cookie].pNodeID;
  238. szNodeType[0] = TEXT('\0');
  239. StringFromGUID2 (*pGUID, szNodeType, 50);
  240. // Create the node type object in GUID string format
  241. return Create((LPVOID)szNodeType, ((lstrlenW(szNodeType)+1) * sizeof(WCHAR)), lpMedium);
  242. }
  243. HRESULT CRSOPDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  244. {
  245. WCHAR szDisplayName[300];
  246. //
  247. // This is the display named used in the scope pane and snap-in manager
  248. //
  249. szDisplayName[0] = TEXT('\0');
  250. if (m_pcd->m_pDisplayName)
  251. //if (m_pcd->m_pGPO && m_pcd->m_pDisplayName)
  252. {
  253. lstrcpy (szDisplayName, m_pcd->m_pDisplayName);
  254. }
  255. else
  256. {
  257. LoadStringW (g_hInstance, IDS_RSOP_SNAPIN_NAME, szDisplayName, ARRAYSIZE(szDisplayName));
  258. }
  259. return Create((LPVOID)szDisplayName, (lstrlenW(szDisplayName) + 1) * sizeof(WCHAR), lpMedium);
  260. }
  261. HRESULT CRSOPDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  262. {
  263. // Create the CoClass information
  264. return Create((LPVOID)&CLSID_GPESnapIn, sizeof(CLSID), lpMedium);
  265. }
  266. HRESULT CRSOPDataObject::CreatePreloadsData(LPSTGMEDIUM lpMedium)
  267. {
  268. BOOL bPreload = TRUE;
  269. return Create((LPVOID)&bPreload, sizeof(bPreload), lpMedium);
  270. }
  271. HRESULT CRSOPDataObject::CreateNodeIDData(LPSTGMEDIUM lpMedium)
  272. {
  273. const GUID * pGUID;
  274. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  275. TCHAR szNodeType[50];
  276. SNodeID * psNode;
  277. if (m_cookie == -1)
  278. return E_UNEXPECTED;
  279. if (m_type == CCT_RESULT)
  280. pGUID = g_RsopNameSpace[lpResultItem->dwNameSpaceItem].pNodeID;
  281. else
  282. pGUID = g_RsopNameSpace[m_cookie].pNodeID;
  283. szNodeType[0] = TEXT('\0');
  284. StringFromGUID2 (*pGUID, szNodeType, 50);
  285. lpMedium->hGlobal = GlobalAlloc (GMEM_SHARE | GMEM_MOVEABLE, (lstrlen(szNodeType) * sizeof(TCHAR)) + sizeof(SNodeID));
  286. if (!lpMedium->hGlobal)
  287. {
  288. return (STG_E_MEDIUMFULL);
  289. }
  290. psNode = (SNodeID *) GlobalLock (lpMedium->hGlobal);
  291. psNode->cBytes = lstrlen(szNodeType) * sizeof(TCHAR);
  292. CopyMemory (psNode->id, szNodeType, psNode->cBytes);
  293. GlobalUnlock (lpMedium->hGlobal);
  294. return S_OK;
  295. }