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.

377 lines
7.7 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(S_OK);
  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. switch (hr) {
  122. case S_OK:
  123. break;
  124. default:
  125. MessageBoxFromHResult( m_hwnd, IDC_ERROR_CREATINGACCOUNT_TITLE, hr );
  126. break;
  127. }
  128. goto Cleanup;
  129. }
  130. // ************************************************************************
  131. //
  132. // IUnknown
  133. //
  134. // ************************************************************************
  135. //
  136. // QueryInterface()
  137. //
  138. STDMETHODIMP
  139. THISCLASS::QueryInterface(
  140. REFIID riid,
  141. LPVOID *ppv )
  142. {
  143. TraceClsFunc( "" );
  144. HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
  145. QIRETURN( hr, riid );
  146. }
  147. //
  148. // AddRef()
  149. //
  150. STDMETHODIMP_(ULONG)
  151. THISCLASS::AddRef( void )
  152. {
  153. TraceClsFunc( "[IUnknown] AddRef( )\n" );
  154. InterlockIncrement( _cRef );
  155. RETURN(_cRef);
  156. }
  157. //
  158. // Release()
  159. //
  160. STDMETHODIMP_(ULONG)
  161. THISCLASS::Release( void )
  162. {
  163. TraceClsFunc( "[IUnknown] Release( )\n" );
  164. InterlockDecrement( _cRef );
  165. if ( _cRef )
  166. RETURN(_cRef);
  167. TraceDo( delete this );
  168. RETURN(0);
  169. }
  170. // ************************************************************************
  171. //
  172. // IDataObject
  173. //
  174. // ************************************************************************
  175. //
  176. // GetData( )
  177. //
  178. STDMETHODIMP
  179. THISCLASS::GetData(
  180. FORMATETC * pFormatEtc,
  181. STGMEDIUM * pMedium)
  182. {
  183. TraceClsFunc( "[IDataObject] GetData( ... )\n" );
  184. if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) {
  185. HRETURN(E_INVALIDARG);
  186. }
  187. if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) {
  188. HRETURN(DV_E_TYMED);
  189. }
  190. HRESULT hr = S_OK;
  191. if (pFormatEtc->cfFormat == g_cfDsObjectNames)
  192. {
  193. // return the object name and class.
  194. //
  195. INT cbPath = sizeof(WCHAR) * (wcslen(m_pwszObjName) + 1);
  196. INT cbClass = sizeof(WCHAR) * (wcslen(m_pwszObjClass) + 1);
  197. INT cbStruct = sizeof(DSOBJECTNAMES);
  198. LPDSOBJECTNAMES pDSObj;
  199. pDSObj = (LPDSOBJECTNAMES)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  200. cbStruct + cbPath + cbClass);
  201. if (pDSObj == NULL) {
  202. hr = THR(STG_E_MEDIUMFULL);
  203. goto Error;
  204. }
  205. pDSObj->clsidNamespace = CLSID_MicrosoftDS;
  206. pDSObj->cItems = 1;
  207. pDSObj->aObjects[0].offsetName = cbStruct;
  208. pDSObj->aObjects[0].offsetClass = cbStruct + cbPath;
  209. if (m_fReadOnly)
  210. {
  211. pDSObj->aObjects[0].dwFlags = DSOBJECT_READONLYPAGES;
  212. }
  213. wcscpy((PWSTR)((BYTE *)pDSObj + cbStruct), m_pwszObjName);
  214. wcscpy((PWSTR)((BYTE *)pDSObj + cbStruct + cbPath), m_pwszObjClass);
  215. pMedium->hGlobal = (HGLOBAL)pDSObj;
  216. }
  217. else if (pFormatEtc->cfFormat == g_cfDsPropCfg)
  218. {
  219. // return the property sheet notification info. In this case, it is
  220. // the invokding sheet's hwnd.
  221. //
  222. PPROPSHEETCFG pSheetCfg;
  223. pSheetCfg = (PPROPSHEETCFG)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  224. sizeof(PROPSHEETCFG));
  225. if (pSheetCfg == NULL) {
  226. hr = THR(STG_E_MEDIUMFULL);
  227. goto Error;
  228. }
  229. ZeroMemory(pSheetCfg, sizeof(PROPSHEETCFG));
  230. pSheetCfg->hwndParentSheet = m_hwnd;
  231. pMedium->hGlobal = (HGLOBAL)pSheetCfg;
  232. }
  233. else
  234. {
  235. // Pass call on to "parent" object's data obj.
  236. if (m_pPage ) {
  237. hr = m_pPage->GetData( pFormatEtc, pMedium );
  238. #ifdef DEBUG
  239. if (hr != DV_E_FORMATETC )
  240. THR(hr);
  241. #endif
  242. goto Error; // not really, but we don't want to clean up
  243. } else {
  244. hr = THR(E_FAIL);
  245. goto Error;
  246. }
  247. }
  248. pMedium->tymed = TYMED_HGLOBAL;
  249. pMedium->pUnkForRelease = NULL;
  250. Error:
  251. HRETURN(hr);
  252. }
  253. //
  254. // GetDataHere( )
  255. //
  256. STDMETHODIMP
  257. THISCLASS::GetDataHere(
  258. LPFORMATETC pFormatEtc,
  259. LPSTGMEDIUM pMedium)
  260. {
  261. TraceClsFunc( "[IDataObject] GetDataHere( ... )\n" );
  262. HRESULT hr;
  263. if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) {
  264. HRETURN(E_INVALIDARG);
  265. }
  266. if (pFormatEtc->cfFormat == g_cfMMCGetNodeType)
  267. {
  268. if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) {
  269. hr = THR(DV_E_TYMED);
  270. goto Error;
  271. }
  272. LPSTREAM lpStream;
  273. ULONG written;
  274. // Create the stream on the hGlobal passed in.
  275. //
  276. hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &lpStream);
  277. if (hr)
  278. goto Error;
  279. hr = lpStream->Write(&m_ClassGUID, sizeof(m_ClassGUID), &written);
  280. // Because we told CreateStreamOnHGlobal with 'FALSE', only the
  281. // stream is released here.
  282. lpStream->Release();
  283. } else if (m_pPage ) {
  284. // Pass call on to "parent" object's data obj.
  285. hr = THR( m_pPage->GetDataHere( pFormatEtc, pMedium ) );
  286. } else {
  287. hr = THR(E_FAIL);
  288. }
  289. Cleanup:
  290. HRETURN(hr);
  291. Error:
  292. goto Cleanup;
  293. }
  294. //
  295. // EnumFormatEtc( )
  296. //
  297. STDMETHODIMP
  298. THISCLASS::EnumFormatEtc(
  299. DWORD dwDirection,
  300. LPENUMFORMATETC * ppEnumFormatEtc)
  301. {
  302. TraceClsFunc( "[IDataObject] EnumFormatEtc( ... )\n" );
  303. //
  304. // Pass call on to "parent" object's data obj.
  305. //
  306. if (m_pPage )
  307. {
  308. HRETURN(m_pPage->EnumFormatEtc(dwDirection, ppEnumFormatEtc));
  309. }
  310. else
  311. {
  312. HRETURN(E_FAIL);
  313. }
  314. }