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.

668 lines
18 KiB

  1. /**************************************************************************************************
  2. FILENAME: DataIo.cpp
  3. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  4. */
  5. #define INC_OLE2
  6. #include "stdafx.h"
  7. #ifndef SNAPIN
  8. #include <windows.h>
  9. #endif
  10. //#include <objbase.h>
  11. #include <initguid.h>
  12. #include "DataIo.h"
  13. #include "DataIoCl.h"
  14. #include "Message.h"
  15. #include "ErrMacro.h"
  16. // If we use DataIo with a console application, then we cannot use
  17. // the Windows message pump PostMessage() routine as there is No
  18. // window to post the message to, so we will use a locally created
  19. // PostMessageLocal() routine instead.
  20. #ifdef ESI_POST_MESSAGE
  21. #pragma message ("Information: ESI_POST_MESSAGE defined.")
  22. #include "PostMsgC.h"
  23. #endif
  24. /**************************************************************************************************
  25. Globals
  26. */
  27. int vcObjects = 0;
  28. CClassFactory g_ClassFactory;
  29. extern HWND hwndMain;
  30. /**************************************************************************************************
  31. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  32. ROUTINE DESCRIPTION:
  33. CClassFactory::QueryInterface implementation.
  34. GLOBAL VARIABLES:
  35. None.
  36. ARGUMENTS:
  37. IN REFIID riid - reference IID of the ClassFactory Interface.
  38. OUT void** ppv.- receives a pointer to the interface pointer of the object.
  39. RETURN:
  40. HRESULT - zero = success.
  41. HRESULT - non zero = error code.
  42. */
  43. STDMETHODIMP
  44. CClassFactory::QueryInterface(REFIID riid, void** ppv)
  45. {
  46. // Check for valid argunment - ppv should be NULL.
  47. if (ppv == NULL) {
  48. // Message(TEXT("CClassFactory::QueryInterface"), E_INVALIDARG, NULL);
  49. return E_INVALIDARG;
  50. }
  51. // Make sure we are being asked for a ClassFactory or Unknown interface.
  52. if (riid == IID_IClassFactory || riid == IID_IUnknown) {
  53. // If so return a pointer to this interface.
  54. *ppv = (IClassFactory*) this;
  55. AddRef();
  56. // Message(TEXT("CClassFactory::QueryInterface"), S_OK, NULL);
  57. return S_OK;
  58. }
  59. // No interface.
  60. *ppv = NULL;
  61. // Message(TEXT("CClassFactory::QueryInterface"), E_NOINTERFACE, NULL);
  62. return E_NOINTERFACE;
  63. }
  64. /**************************************************************************************************
  65. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  66. ROUTINE DESCRIPTION:
  67. CClassFactory::CreateInstance implementation of the ESI Data Object.
  68. GLOBAL VARIABLES:
  69. None.
  70. ARGUMENTS:
  71. IN LPUNKNOWN punkOuter - aggregate pointer - must be NULL as we don't support aggregation.
  72. IN REFIID riid - reference IID of the ClassFactory Interface.
  73. OUT void** ppv.- receives a pointer to the interface pointer of the object.
  74. RETURN:
  75. HRESULT - zero = success.
  76. HRESULT - non zero = error code.
  77. */
  78. STDMETHODIMP
  79. CClassFactory::CreateInstance(LPUNKNOWN punkOuter, REFIID riid, void** ppv)
  80. {
  81. LPUNKNOWN punk;
  82. HRESULT hr;
  83. *ppv = NULL;
  84. // Check for aggregation - we don't support it..
  85. if (punkOuter != NULL) {
  86. // Message(TEXT("CClassFactory::CreateInstance"), CLASS_E_NOAGGREGATION, NULL);
  87. return CLASS_E_NOAGGREGATION;
  88. }
  89. // Create the ESI Data Object.
  90. // Message(TEXT("CClassFactory::CreateInstance"), S_OK, NULL);
  91. punk = new EsiDataObject;
  92. // If we didn't get a pointer then we are out of memory.
  93. if (punk == NULL) {
  94. // Message(TEXT("CClassFactory::CreateInstance"), E_OUTOFMEMORY, NULL);
  95. return E_OUTOFMEMORY;
  96. }
  97. // Get a pointer to the ESI Data Object interface.
  98. hr = punk->QueryInterface(riid, ppv);
  99. // Release the pointer to the ESI Data Object.
  100. punk->Release();
  101. return hr;
  102. }
  103. /**************************************************************************************************
  104. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  105. ROUTINE DESCRIPTION:
  106. EsiDataObject::EsiDataObject constructor.
  107. GLOBAL VARIABLES:
  108. None.
  109. ARGUMENTS:
  110. None.
  111. RETURN:
  112. None.
  113. */
  114. EsiDataObject::EsiDataObject(void)
  115. {
  116. m_cRef = 1;
  117. hDataOut = NULL;
  118. hDataIn = NULL;
  119. // Message(TEXT("EsiDataObject::EsiDataObject"), S_OK, NULL);
  120. }
  121. /**************************************************************************************************
  122. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  123. ROUTINE DESCRIPTION:
  124. EsiDataObject::EsiDataObject destructor.
  125. GLOBAL VARIABLES:
  126. None.
  127. ARGUMENTS:
  128. None.
  129. RETURN:
  130. None.
  131. */
  132. EsiDataObject::~EsiDataObject(void)
  133. {
  134. // Message(TEXT("EsiDataObject::~EsiDataObject"), S_OK, NULL);
  135. }
  136. /**************************************************************************************************
  137. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  138. ROUTINE DESCRIPTION:
  139. EsiDataObject::QueryInterface
  140. GLOBAL VARIABLES:
  141. None.
  142. ARGUMENTS:
  143. IN REFIID riid - reference IID of the EsiDataObject interfavce.
  144. OUT void** ppv.- receives a pointer to the interface pointer of the object.
  145. RETURN:
  146. HRESULT - zero = success.
  147. HRESULT - non zero = error code.
  148. */
  149. STDMETHODIMP
  150. EsiDataObject::QueryInterface(REFIID riid, void** ppv)
  151. {
  152. // Check for valid argunment - ppv should be NULL.
  153. if (ppv == NULL) {
  154. // Message(TEXT("EsiDataObject::QueryInterface"), E_INVALIDARG, NULL);
  155. return E_INVALIDARG;
  156. }
  157. // Make sure we are being asked for a DataObject interface.
  158. if (riid == IID_IUnknown || riid == IID_IDataObject) {
  159. // If so return a pointer to this interface.
  160. *ppv = (IUnknown *) this;
  161. AddRef();
  162. // Message(TEXT("EsiDataObject::QueryInterface"), S_OK, NULL);
  163. return S_OK;
  164. }
  165. // No interface.
  166. *ppv = NULL;
  167. // Message(TEXT("EsiDataObject::QueryInterface"), E_NOINTERFACE, NULL);
  168. return E_NOINTERFACE;
  169. }
  170. /**************************************************************************************************
  171. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  172. ROUTINE DESCRIPTION:
  173. Decrements the reference count and when zero deletes the interface object and post a
  174. WM_CLOSE message to terminate the program.
  175. GLOBAL VARIABLES:
  176. None.
  177. ARGUMENTS:
  178. IN REFIID riid - reference IID of the EsiDataObject interfavce.
  179. OUT void** ppv.- receives a pointer to the interface pointer of the object.
  180. RETURN:
  181. ULONG - m_cRef
  182. */
  183. STDMETHODIMP_(ULONG)
  184. EsiDataObject::Release(void)
  185. {
  186. if (InterlockedDecrement(&m_cRef) == 0) {
  187. delete this;
  188. return 0;
  189. }
  190. return m_cRef;
  191. }
  192. /**************************************************************************************************
  193. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  194. ROUTINE DESCRIPTION:
  195. EsiDataObject::GetData only supports CF_TEXT
  196. GLOBAL VARIABLES:
  197. None.
  198. ARGUMENTS:
  199. IN LPFORMATETC
  200. IN LPSTGMEDIUM
  201. RETURN:
  202. HRESULT - zero = success.
  203. HRESULT - non zero = error code.
  204. */
  205. STDMETHODIMP
  206. EsiDataObject::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
  207. {
  208. char FAR* pstrDest;
  209. char FAR* pDataOut = NULL;
  210. // char FAR* pstrSrc;
  211. if (!(pformatetcIn->dwAspect & DVASPECT_CONTENT))
  212. return DATA_E_FORMATETC;
  213. switch (pformatetcIn->cfFormat) {
  214. case CF_TEXT:
  215. if (!(pformatetcIn->tymed & TYMED_HGLOBAL))
  216. return DATA_E_FORMATETC;
  217. pmedium->tymed = TYMED_HGLOBAL;
  218. pmedium->pUnkForRelease = NULL;
  219. pmedium->hGlobal = GlobalAlloc(GHND,GlobalSize(hDataOut));
  220. EE_ASSERT(pmedium->hGlobal);
  221. pstrDest = (char FAR *)GlobalLock(pmedium->hGlobal);
  222. EE_ASSERT(pstrDest);
  223. pDataOut = (char FAR *)GlobalLock(hDataOut);
  224. EE_ASSERT(pDataOut);
  225. memcpy(pstrDest,pDataOut,(ULONG)GlobalSize(hDataOut));
  226. GlobalUnlock(hDataOut);
  227. GlobalUnlock(pmedium->hGlobal);
  228. break;
  229. default:
  230. return DATA_E_FORMATETC;
  231. }
  232. return S_OK;
  233. }
  234. // ------------------------------------------------------------------------------------------------
  235. // %%Function: EsiDataObject::GetData
  236. // ------------------------------------------------------------------------------------------------
  237. // GetData only supports CF_TEXT
  238. /*
  239. STDMETHODIMP
  240. EsiDataObject::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
  241. {
  242. char FAR *pstrDest;
  243. char FAR *pstrSrc;
  244. if (!(pformatetcIn->dwAspect & DVASPECT_CONTENT))
  245. return DATA_E_FORMATETC;
  246. switch (pformatetcIn->cfFormat) {
  247. case CF_TEXT:
  248. if (!(pformatetcIn->tymed & TYMED_HGLOBAL))
  249. return DATA_E_FORMATETC;
  250. pmedium->tymed = TYMED_HGLOBAL;
  251. pmedium->hGlobal = GlobalAlloc(GHND,GlobalSize(hGuid));
  252. pmedium->pUnkForRelease = NULL;
  253. pstrDest = (char FAR *)GlobalLock(pmedium->hGlobal);
  254. pstrSrc = (char FAR *)GlobalLock(hGuid);
  255. memcpy(pstrDest,pstrSrc,GlobalSize(hGuid));
  256. GlobalUnlock(hGuid);
  257. GlobalUnlock(pmedium->hGlobal);
  258. break;
  259. default:
  260. return DATA_E_FORMATETC;
  261. }
  262. return S_OK;
  263. }
  264. /**************************************************************************************************
  265. EsiDataObject::GetDataHere - NOT IMPLEMENTED.
  266. */
  267. STDMETHODIMP
  268. EsiDataObject::GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
  269. {
  270. // Message(TEXT("EsiDataObject::GetDataHere"), E_NOTIMPL, NULL);
  271. return E_NOTIMPL;
  272. }
  273. /**************************************************************************************************
  274. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  275. ROUTINE DESCRIPTION:
  276. This routine tells the caller that we support only CF_TEXT and TYMED_HGLOBAL formats.
  277. GLOBAL VARIABLES:
  278. None.
  279. ARGUMENTS:
  280. IN LPFORMATETC
  281. RETURN:
  282. HRESULT - zero = success.
  283. HRESULT - non zero = error code.
  284. */
  285. STDMETHODIMP
  286. EsiDataObject::QueryGetData(LPFORMATETC pformatetc)
  287. {
  288. // Check for DVASPECT_CONTENT.
  289. if (!(DVASPECT_CONTENT & pformatetc->dwAspect)) {
  290. // Message(TEXT("EsiDataObject::QueryGetData"), DATA_E_FORMATETC, NULL);
  291. return DATA_E_FORMATETC;
  292. }
  293. // Check for CF_TEXT.
  294. if (pformatetc->cfFormat != CF_TEXT) {
  295. // Message(TEXT("EsiDataObject::QueryGetData"), DATA_E_FORMATETC, NULL);
  296. return DATA_E_FORMATETC;
  297. }
  298. // Check for TYMED_HGLOBAL.
  299. if (!(TYMED_HGLOBAL & pformatetc->tymed)) {
  300. // Message(TEXT("EsiDataObject::QueryGetData"), DV_E_TYMED, NULL);
  301. return DV_E_TYMED;
  302. }
  303. // Message(TEXT("EsiDataObject::QueryGetData"), S_OK, NULL);
  304. return S_OK;
  305. }
  306. /*
  307. /**************************************************************************************************
  308. EsiDataObject::GetCanonicalFormatEtc - NOT IMPLEMENTED.
  309. */
  310. STDMETHODIMP
  311. EsiDataObject::GetCanonicalFormatEtc(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut)
  312. {
  313. // Message(TEXT("EsiDataObject::GetCanonicalFormatEtc"), DATA_S_SAMEFORMATETC, NULL);
  314. return DATA_S_SAMEFORMATETC;
  315. }
  316. /**************************************************************************************************
  317. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  318. ROUTINE DESCRIPTION:
  319. EsiDataObject::GetData only supports CF_TEXT
  320. GLOBAL VARIABLES:
  321. None.
  322. ARGUMENTS:
  323. IN LPFORMATETC
  324. IN LPSTGMEDIUM
  325. IN BOOL fRelease
  326. RETURN:
  327. HRESULT - zero = success.
  328. HRESULT - non zero = error code.
  329. typedef struct {
  330. WORD dwID; // ESI data structre ID always = 0x4553 'ES'
  331. WORD dwType; // Type of data structure
  332. WORD dwVersion; // Version number
  333. WORD dwCompatibilty;// Compatibilty number
  334. ULONG ulDataSize; // Data size
  335. WPARAM wparam; // LOWORD(wparam) = Command
  336. char cData; // Void pointer to the data - NULL = no data
  337. } DATA_IO, *PDATA_IO;
  338. */
  339. STDMETHODIMP EsiDataObject::SetData(LPFORMATETC pformatetc,
  340. STGMEDIUM FAR * pmedium,
  341. BOOL fRelease)
  342. {
  343. WPARAM wpPostCommand;
  344. // We only support CF_TEXT
  345. if (pformatetc->cfFormat != CF_TEXT) {
  346. // Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
  347. return E_FAIL;
  348. }
  349. // We want memory only.
  350. if (pformatetc->tymed != TYMED_HGLOBAL) {
  351. // Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
  352. return E_FAIL;
  353. }
  354. DWORD dwGlobalSize;
  355. char FAR* pstrSrc;
  356. PCHAR pDataIn;
  357. // Check for valid memory handle.
  358. if(pmedium->hGlobal == NULL) {
  359. // Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
  360. return E_FAIL;
  361. }
  362. // Get the size of the incoming data.
  363. dwGlobalSize = (DWORD)GlobalSize(pmedium->hGlobal);
  364. // Allocate enough memory for the incoming data.
  365. hDataIn = GlobalAlloc(GHND,dwGlobalSize);
  366. EE_ASSERT(hDataIn);
  367. // Lock and get pointers to the data.
  368. pDataIn = (PCHAR)GlobalLock(hDataIn);
  369. EE_ASSERT(pDataIn);
  370. pstrSrc = (char FAR*)GlobalLock(pmedium->hGlobal);
  371. EE_ASSERT(pstrSrc);
  372. // Copy the data to this processes memory.
  373. CopyMemory(pDataIn, pstrSrc, dwGlobalSize);
  374. // Unlock and release the pointer to the source memory.
  375. GlobalUnlock(pmedium->hGlobal);
  376. // Release the memory if requested by the caller.
  377. if (fRelease) {
  378. ReleaseStgMedium(pmedium);
  379. }
  380. DATA_IO* pDataIo = (DATA_IO*)pDataIn;
  381. // Extract the Post Command message
  382. wpPostCommand = pDataIo->wparam;
  383. // Cehck ESI data structre ID which is always = 0x4553 'ES'
  384. if(pDataIo->dwID != ESI_DATA_STRUCTURE) {
  385. // Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
  386. return FALSE;
  387. }
  388. // Cehck the data structure type.
  389. if(pDataIo->dwType != FR_COMMAND_BUFFER) {
  390. // Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
  391. return FALSE;
  392. }
  393. // Check for data structure compatibility.
  394. if(pDataIo->dwCompatibilty != FR_COMMAND_BUFFER_ONE) {
  395. // Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
  396. return FALSE;
  397. }
  398. // Unlock the memory.
  399. GlobalUnlock(hDataIn);
  400. // Check for any data.
  401. if(pDataIo->ulDataSize == 0) {
  402. // Unlock the memory since there is no data other than the command.
  403. EH_ASSERT(GlobalFree(hDataIn) == NULL);
  404. hDataIn = NULL;
  405. }
  406. // Send the data to the message pump.
  407. // NOTE THAT THE MEMORY MUST FREED BY THE PROCESSING FUNCTION.
  408. // If we use DataIo with a console application, then we cannot use the WNT
  409. // PostMessage() routine as there is No window to post the message to, so
  410. // we will use a locally created PostMessageConsole() routine instead.
  411. #ifdef ESI_POST_MESSAGE
  412. #ifndef DKMS
  413. PostMessageLocal(NULL, WM_COMMAND, wpPostCommand, (LPARAM)hDataIn);
  414. #endif
  415. #else
  416. PostMessage(hwndMain, WM_COMMAND, wpPostCommand, (LPARAM)hDataIn);
  417. #endif
  418. // Message(TEXT("EsiDataObject::SetData"), S_OK, NULL);
  419. return S_OK;
  420. }
  421. /**************************************************************************************************
  422. EsiDataObject::EnumFormatEtc - NOT IMPLEMENTED.
  423. */
  424. STDMETHODIMP
  425. EsiDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
  426. {
  427. // Message(TEXT("EsiDataObject::DAdvise"), E_NOTIMPL, NULL);
  428. return E_NOTIMPL ;
  429. }
  430. /**************************************************************************************************
  431. EsiDataObject::DAdvise - NOT SUPPORTED.
  432. */
  433. STDMETHODIMP
  434. EsiDataObject::DAdvise(FORMATETC FAR* pFormatetc,
  435. DWORD advf,
  436. LPADVISESINK pAdvSink,
  437. DWORD FAR* pdwConnection)
  438. {
  439. // Message(TEXT("EsiDataObject::DAdvise"), OLE_E_ADVISENOTSUPPORTED, NULL);
  440. return OLE_E_ADVISENOTSUPPORTED;
  441. }
  442. /**************************************************************************************************
  443. EsiDataObject::DUnadvise - NOT SUPPORTED.
  444. */
  445. STDMETHODIMP
  446. EsiDataObject::DUnadvise(DWORD dwConnection)
  447. {
  448. // Message(TEXT("EsiDataObject::DUnadvise"), OLE_E_ADVISENOTSUPPORTED, NULL);
  449. return OLE_E_ADVISENOTSUPPORTED;
  450. }
  451. /**************************************************************************************************
  452. EsiDataObject::DUnadvise - NOT SUPPORTED.
  453. */
  454. STDMETHODIMP
  455. EsiDataObject::EnumDAdvise(LPENUMSTATDATA FAR* ppenumAdvise)
  456. {
  457. // Message(TEXT("EsiDataObject::EnumDAdvise"), OLE_E_ADVISENOTSUPPORTED, NULL);
  458. return OLE_E_ADVISENOTSUPPORTED;
  459. }
  460. /**************************************************************************************************
  461. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  462. ROUTINE DESCRIPTION:
  463. This is the WinMain function for the Diskeeper Gui.
  464. GLOBAL VARIABLES:
  465. None.
  466. INPUT:
  467. hInstance - The handle to this instance.
  468. hPrevInstance - The handle to the previous instance.
  469. lpCmdLine - The command line which was passed in.
  470. nCmdShow - Whether the window should be minimized or not.
  471. RETURN:
  472. TRUE - Success.
  473. FALSE - Failure to initilize.
  474. */
  475. DWORD
  476. InitializeDataIo(
  477. IN REFCLSID refCLSID,
  478. DWORD dwRegCls
  479. )
  480. {
  481. HRESULT hr;
  482. DWORD dwRegister;
  483. // initialize COM for free-threading.
  484. // DO NOT want this for controls that are derived from ATL. Bad Mojo
  485. #ifndef ESI_DFRGUI
  486. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  487. #endif
  488. // Register the class-object with OLE.
  489. hr = CoRegisterClassObject(refCLSID,
  490. &g_ClassFactory,
  491. CLSCTX_SERVER,
  492. dwRegCls,
  493. &dwRegister);
  494. if (FAILED(hr)) {
  495. return 0;
  496. }
  497. return( dwRegister );
  498. }
  499. /**************************************************************************************************
  500. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  501. ROUTINE DESCRIPTION:
  502. Exit routine for DataIo
  503. GLOBAL VARIABLES:
  504. None.
  505. INPUT:
  506. None
  507. RETURN:
  508. TRUE - Success.
  509. FALSE - Failure.
  510. */
  511. BOOL
  512. ExitDataIo(
  513. )
  514. {
  515. #ifndef ESI_DFRGUI
  516. // DO NOT want this for controls that are derived from ATL. Bad Mojo
  517. CoUninitialize();
  518. #endif
  519. return TRUE;
  520. }