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.

376 lines
8.1 KiB

  1. //
  2. // Copyright 1997 - Microsoft
  3. //
  4. //
  5. // DATAOBJ.CPP - A data object
  6. //
  7. #include "pch.h"
  8. #include "dataobj.h"
  9. DEFINE_MODULE("IMADMUI")
  10. DEFINE_THISCLASS("CDsPropDataObj")
  11. #define THISCLASS CDsPropDataObj
  12. #define LPTHISCLASS CDsPropDataObj*
  13. //
  14. // CreateInstance( )
  15. //
  16. LPVOID
  17. CDsPropDataObj_CreateInstance(
  18. HWND hwndParent,
  19. IDataObject * pido,
  20. GUID * pClassGUID,
  21. BOOL fReadOnly,
  22. LPWSTR pszObjPath,
  23. LPWSTR bstrClass )
  24. {
  25. TraceFunc( "CDsPropDataObj_CreateInstance( ... )\n" );
  26. LPTHISCLASS lpcc = new THISCLASS( hwndParent, pido, pClassGUID, fReadOnly);
  27. if (!lpcc)
  28. RETURN(lpcc);
  29. HRESULT hr = THR( lpcc->Init( pszObjPath, bstrClass ) );
  30. if ( hr )
  31. {
  32. delete lpcc;
  33. RETURN(NULL);
  34. }
  35. RETURN((LPVOID) lpcc);
  36. }
  37. //
  38. // Constructor
  39. //
  40. THISCLASS::THISCLASS(
  41. HWND hwndParent,
  42. IDataObject * pido,
  43. GUID * pClassGUID,
  44. BOOL fReadOnly) :
  45. m_fReadOnly(fReadOnly),
  46. m_pwszObjName(NULL),
  47. m_pwszObjClass(NULL),
  48. m_hwnd(hwndParent),
  49. m_pPage(pido),
  50. m_ClassGUID(*pClassGUID),
  51. _cRef(0)
  52. {
  53. TraceClsFunc( "CDsPropDataObj( )\n" );
  54. if (m_pPage) {
  55. m_pPage->AddRef();
  56. }
  57. TraceFuncExit( );
  58. }
  59. //
  60. // Destructor
  61. //
  62. THISCLASS::~THISCLASS(void)
  63. {
  64. TraceClsFunc( "~CDsPropDataObj( )\n" );
  65. if (m_pPage) {
  66. m_pPage->Release();
  67. }
  68. if (m_pwszObjName) {
  69. TraceFree(m_pwszObjName);
  70. }
  71. if (m_pwszObjClass) {
  72. TraceFree(m_pwszObjClass);
  73. }
  74. TraceFuncExit( );
  75. }
  76. //
  77. // Init( )
  78. //
  79. HRESULT
  80. THISCLASS::Init(
  81. LPWSTR pwszObjName,
  82. LPWSTR pwszClass )
  83. {
  84. TraceClsFunc( "Init( ... )\n" );
  85. HRESULT hr = S_OK;
  86. // IUnknown stuff
  87. BEGIN_QITABLE_IMP( CDsPropDataObj, IDataObject );
  88. QITABLE_IMP( IDataObject );
  89. END_QITABLE_IMP( CDsPropDataObj );
  90. Assert( _cRef == 0);
  91. AddRef( );
  92. if (!pwszObjName || *pwszObjName == L'\0')
  93. {
  94. HRETURN(E_INVALIDARG);
  95. }
  96. if (!pwszClass || *pwszClass == L'\0')
  97. {
  98. HRETURN(E_INVALIDARG);
  99. }
  100. m_pwszObjName = (LPWSTR) TraceStrDup( pwszObjName );
  101. if ( !m_pwszObjName ) {
  102. hr = THR(E_OUTOFMEMORY);
  103. goto Error;
  104. }
  105. m_pwszObjClass = (LPWSTR) TraceStrDup( pwszClass );
  106. if ( !m_pwszObjClass ) {
  107. hr = THR(E_OUTOFMEMORY);
  108. goto Error;
  109. }
  110. Cleanup:
  111. HRETURN(hr);
  112. Error:
  113. if ( m_pwszObjName ) {
  114. TraceFree( m_pwszObjName );
  115. m_pwszObjName = NULL;
  116. }
  117. if ( m_pwszObjClass ) {
  118. TraceFree( m_pwszObjClass );
  119. m_pwszObjClass = NULL;
  120. }
  121. MessageBoxFromHResult( m_hwnd, IDC_ERROR_CREATINGACCOUNT_TITLE, hr );
  122. goto Cleanup;
  123. }
  124. // ************************************************************************
  125. //
  126. // IUnknown
  127. //
  128. // ************************************************************************
  129. //
  130. // QueryInterface()
  131. //
  132. STDMETHODIMP
  133. THISCLASS::QueryInterface(
  134. REFIID riid,
  135. LPVOID *ppv )
  136. {
  137. TraceClsFunc( "" );
  138. HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
  139. QIRETURN( hr, riid );
  140. }
  141. //
  142. // AddRef()
  143. //
  144. STDMETHODIMP_(ULONG)
  145. THISCLASS::AddRef( void )
  146. {
  147. TraceClsFunc( "[IUnknown] AddRef( )\n" );
  148. InterlockIncrement( _cRef );
  149. RETURN(_cRef);
  150. }
  151. //
  152. // Release()
  153. //
  154. STDMETHODIMP_(ULONG)
  155. THISCLASS::Release( void )
  156. {
  157. TraceClsFunc( "[IUnknown] Release( )\n" );
  158. InterlockDecrement( _cRef );
  159. if ( _cRef )
  160. RETURN(_cRef);
  161. TraceDo( delete this );
  162. RETURN(0);
  163. }
  164. // ************************************************************************
  165. //
  166. // IDataObject
  167. //
  168. // ************************************************************************
  169. //
  170. // GetData( )
  171. //
  172. STDMETHODIMP
  173. THISCLASS::GetData(
  174. FORMATETC * pFormatEtc,
  175. STGMEDIUM * pMedium)
  176. {
  177. TraceClsFunc( "[IDataObject] GetData( ... )\n" );
  178. if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) {
  179. HRETURN(E_INVALIDARG);
  180. }
  181. if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) {
  182. HRETURN(DV_E_TYMED);
  183. }
  184. HRESULT hr = S_OK;
  185. if (pFormatEtc->cfFormat == g_cfDsObjectNames)
  186. {
  187. // return the object name and class.
  188. //
  189. if (!m_pwszObjName || !m_pwszObjClass) {
  190. HRETURN(E_INVALIDARG);
  191. }
  192. INT cbPath = sizeof(WCHAR) * (wcslen(m_pwszObjName) + 1);
  193. INT cbClass = sizeof(WCHAR) * (wcslen(m_pwszObjClass) + 1);
  194. INT cbStruct = sizeof(DSOBJECTNAMES);
  195. LPDSOBJECTNAMES pDSObj;
  196. pDSObj = (LPDSOBJECTNAMES)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  197. cbStruct + cbPath + cbClass);
  198. if (pDSObj == NULL) {
  199. hr = THR(STG_E_MEDIUMFULL);
  200. goto Exit;
  201. }
  202. ZeroMemory(pDSObj, sizeof(DSOBJECTNAMES));
  203. pDSObj->clsidNamespace = CLSID_MicrosoftDS;
  204. pDSObj->cItems = 1;
  205. pDSObj->aObjects[0].offsetName = cbStruct;
  206. pDSObj->aObjects[0].offsetClass = cbStruct + cbPath;
  207. if (m_fReadOnly)
  208. {
  209. pDSObj->aObjects[0].dwFlags = DSOBJECT_READONLYPAGES;
  210. }
  211. wcscpy((PWSTR)((BYTE *)pDSObj + cbStruct), m_pwszObjName);
  212. wcscpy((PWSTR)((BYTE *)pDSObj + cbStruct + cbPath), m_pwszObjClass);
  213. pMedium->hGlobal = (HGLOBAL)pDSObj;
  214. }
  215. else if (pFormatEtc->cfFormat == g_cfDsPropCfg)
  216. {
  217. // return the property sheet notification info. In this case, it is
  218. // the invokding sheet's hwnd.
  219. //
  220. PPROPSHEETCFG pSheetCfg;
  221. pSheetCfg = (PPROPSHEETCFG)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  222. sizeof(PROPSHEETCFG));
  223. if (pSheetCfg == NULL) {
  224. hr = THR(STG_E_MEDIUMFULL);
  225. goto Exit;
  226. }
  227. ZeroMemory(pSheetCfg, sizeof(PROPSHEETCFG));
  228. pSheetCfg->hwndParentSheet = m_hwnd;
  229. pMedium->hGlobal = (HGLOBAL)pSheetCfg;
  230. }
  231. else
  232. {
  233. // Pass call on to "parent" object's data obj.
  234. if (m_pPage ) {
  235. hr = m_pPage->GetData( pFormatEtc, pMedium );
  236. #ifdef DEBUG
  237. if (hr != DV_E_FORMATETC ) {
  238. THR(hr);
  239. }
  240. #endif
  241. goto Exit;
  242. } else {
  243. hr = THR(E_FAIL);
  244. goto Exit;
  245. }
  246. }
  247. pMedium->tymed = TYMED_HGLOBAL;
  248. pMedium->pUnkForRelease = NULL;
  249. Exit:
  250. HRETURN(hr);
  251. }
  252. //
  253. // GetDataHere( )
  254. //
  255. STDMETHODIMP
  256. THISCLASS::GetDataHere(
  257. LPFORMATETC pFormatEtc,
  258. LPSTGMEDIUM pMedium)
  259. {
  260. TraceClsFunc( "[IDataObject] GetDataHere( ... )\n" );
  261. HRESULT hr;
  262. if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) {
  263. HRETURN(E_INVALIDARG);
  264. }
  265. if (pFormatEtc->cfFormat == g_cfMMCGetNodeType)
  266. {
  267. if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) {
  268. hr = THR(DV_E_TYMED);
  269. goto Error;
  270. }
  271. LPSTREAM lpStream;
  272. ULONG written;
  273. // Create the stream on the hGlobal passed in.
  274. //
  275. hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &lpStream);
  276. if (hr)
  277. goto Error;
  278. hr = lpStream->Write(&m_ClassGUID, sizeof(m_ClassGUID), &written);
  279. // Because we told CreateStreamOnHGlobal with 'FALSE', only the
  280. // stream is released here.
  281. lpStream->Release();
  282. } else if (m_pPage ) {
  283. // Pass call on to "parent" object's data obj.
  284. hr = THR( m_pPage->GetDataHere( pFormatEtc, pMedium ) );
  285. } else {
  286. hr = THR(E_FAIL);
  287. }
  288. Cleanup:
  289. HRETURN(hr);
  290. Error:
  291. goto Cleanup;
  292. }
  293. //
  294. // EnumFormatEtc( )
  295. //
  296. STDMETHODIMP
  297. THISCLASS::EnumFormatEtc(
  298. DWORD dwDirection,
  299. LPENUMFORMATETC * ppEnumFormatEtc)
  300. {
  301. TraceClsFunc( "[IDataObject] EnumFormatEtc( ... )\n" );
  302. //
  303. // Pass call on to "parent" object's data obj.
  304. //
  305. if (m_pPage )
  306. {
  307. HRETURN(m_pPage->EnumFormatEtc(dwDirection, ppEnumFormatEtc));
  308. }
  309. else
  310. {
  311. HRETURN(E_FAIL);
  312. }
  313. }