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.

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