windows-nt/Source/XPSP1/NT/base/fs/utils/dfrg/dataio.cpp
2020-09-26 16:20:57 +08:00

669 lines
18 KiB
C++

/**************************************************************************************************
FILENAME: DataIo.cpp
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
*/
#define INC_OLE2
#include "stdafx.h"
#ifndef SNAPIN
#include <windows.h>
#endif
//#include <objbase.h>
#include <initguid.h>
#include "DataIo.h"
#include "DataIoCl.h"
#include "Message.h"
#include "ErrMacro.h"
// If we use DataIo with a console application, then we cannot use
// the Windows message pump PostMessage() routine as there is No
// window to post the message to, so we will use a locally created
// PostMessageLocal() routine instead.
#ifdef ESI_POST_MESSAGE
#pragma message ("Information: ESI_POST_MESSAGE defined.")
#include "PostMsgC.h"
#endif
/**************************************************************************************************
Globals
*/
int vcObjects = 0;
CClassFactory g_ClassFactory;
extern HWND hwndMain;
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
CClassFactory::QueryInterface implementation.
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN REFIID riid - reference IID of the ClassFactory Interface.
OUT void** ppv.- receives a pointer to the interface pointer of the object.
RETURN:
HRESULT - zero = success.
HRESULT - non zero = error code.
*/
STDMETHODIMP
CClassFactory::QueryInterface(REFIID riid, void** ppv)
{
// Check for valid argunment - ppv should be NULL.
if (ppv == NULL) {
// Message(TEXT("CClassFactory::QueryInterface"), E_INVALIDARG, NULL);
return E_INVALIDARG;
}
// Make sure we are being asked for a ClassFactory or Unknown interface.
if (riid == IID_IClassFactory || riid == IID_IUnknown) {
// If so return a pointer to this interface.
*ppv = (IClassFactory*) this;
AddRef();
// Message(TEXT("CClassFactory::QueryInterface"), S_OK, NULL);
return S_OK;
}
// No interface.
*ppv = NULL;
// Message(TEXT("CClassFactory::QueryInterface"), E_NOINTERFACE, NULL);
return E_NOINTERFACE;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
CClassFactory::CreateInstance implementation of the ESI Data Object.
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN LPUNKNOWN punkOuter - aggregate pointer - must be NULL as we don't support aggregation.
IN REFIID riid - reference IID of the ClassFactory Interface.
OUT void** ppv.- receives a pointer to the interface pointer of the object.
RETURN:
HRESULT - zero = success.
HRESULT - non zero = error code.
*/
STDMETHODIMP
CClassFactory::CreateInstance(LPUNKNOWN punkOuter, REFIID riid, void** ppv)
{
LPUNKNOWN punk;
HRESULT hr;
*ppv = NULL;
// Check for aggregation - we don't support it..
if (punkOuter != NULL) {
// Message(TEXT("CClassFactory::CreateInstance"), CLASS_E_NOAGGREGATION, NULL);
return CLASS_E_NOAGGREGATION;
}
// Create the ESI Data Object.
// Message(TEXT("CClassFactory::CreateInstance"), S_OK, NULL);
punk = new EsiDataObject;
// If we didn't get a pointer then we are out of memory.
if (punk == NULL) {
// Message(TEXT("CClassFactory::CreateInstance"), E_OUTOFMEMORY, NULL);
return E_OUTOFMEMORY;
}
// Get a pointer to the ESI Data Object interface.
hr = punk->QueryInterface(riid, ppv);
// Release the pointer to the ESI Data Object.
punk->Release();
return hr;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
EsiDataObject::EsiDataObject constructor.
GLOBAL VARIABLES:
None.
ARGUMENTS:
None.
RETURN:
None.
*/
EsiDataObject::EsiDataObject(void)
{
m_cRef = 1;
hDataOut = NULL;
hDataIn = NULL;
// Message(TEXT("EsiDataObject::EsiDataObject"), S_OK, NULL);
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
EsiDataObject::EsiDataObject destructor.
GLOBAL VARIABLES:
None.
ARGUMENTS:
None.
RETURN:
None.
*/
EsiDataObject::~EsiDataObject(void)
{
// Message(TEXT("EsiDataObject::~EsiDataObject"), S_OK, NULL);
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
EsiDataObject::QueryInterface
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN REFIID riid - reference IID of the EsiDataObject interfavce.
OUT void** ppv.- receives a pointer to the interface pointer of the object.
RETURN:
HRESULT - zero = success.
HRESULT - non zero = error code.
*/
STDMETHODIMP
EsiDataObject::QueryInterface(REFIID riid, void** ppv)
{
// Check for valid argunment - ppv should be NULL.
if (ppv == NULL) {
// Message(TEXT("EsiDataObject::QueryInterface"), E_INVALIDARG, NULL);
return E_INVALIDARG;
}
// Make sure we are being asked for a DataObject interface.
if (riid == IID_IUnknown || riid == IID_IDataObject) {
// If so return a pointer to this interface.
*ppv = (IUnknown *) this;
AddRef();
// Message(TEXT("EsiDataObject::QueryInterface"), S_OK, NULL);
return S_OK;
}
// No interface.
*ppv = NULL;
// Message(TEXT("EsiDataObject::QueryInterface"), E_NOINTERFACE, NULL);
return E_NOINTERFACE;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
Decrements the reference count and when zero deletes the interface object and post a
WM_CLOSE message to terminate the program.
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN REFIID riid - reference IID of the EsiDataObject interfavce.
OUT void** ppv.- receives a pointer to the interface pointer of the object.
RETURN:
ULONG - m_cRef
*/
STDMETHODIMP_(ULONG)
EsiDataObject::Release(void)
{
if (InterlockedDecrement(&m_cRef) == 0) {
delete this;
return 0;
}
return m_cRef;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
EsiDataObject::GetData only supports CF_TEXT
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN LPFORMATETC
IN LPSTGMEDIUM
RETURN:
HRESULT - zero = success.
HRESULT - non zero = error code.
*/
STDMETHODIMP
EsiDataObject::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
{
char FAR* pstrDest;
char FAR* pDataOut = NULL;
// char FAR* pstrSrc;
if (!(pformatetcIn->dwAspect & DVASPECT_CONTENT))
return DATA_E_FORMATETC;
switch (pformatetcIn->cfFormat) {
case CF_TEXT:
if (!(pformatetcIn->tymed & TYMED_HGLOBAL))
return DATA_E_FORMATETC;
pmedium->tymed = TYMED_HGLOBAL;
pmedium->pUnkForRelease = NULL;
pmedium->hGlobal = GlobalAlloc(GHND,GlobalSize(hDataOut));
EE_ASSERT(pmedium->hGlobal);
pstrDest = (char FAR *)GlobalLock(pmedium->hGlobal);
EE_ASSERT(pstrDest);
pDataOut = (char FAR *)GlobalLock(hDataOut);
EE_ASSERT(pDataOut);
memcpy(pstrDest,pDataOut,(ULONG)GlobalSize(hDataOut));
GlobalUnlock(hDataOut);
GlobalUnlock(pmedium->hGlobal);
break;
default:
return DATA_E_FORMATETC;
}
return S_OK;
}
// ------------------------------------------------------------------------------------------------
// %%Function: EsiDataObject::GetData
// ------------------------------------------------------------------------------------------------
// GetData only supports CF_TEXT
/*
STDMETHODIMP
EsiDataObject::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
{
char FAR *pstrDest;
char FAR *pstrSrc;
if (!(pformatetcIn->dwAspect & DVASPECT_CONTENT))
return DATA_E_FORMATETC;
switch (pformatetcIn->cfFormat) {
case CF_TEXT:
if (!(pformatetcIn->tymed & TYMED_HGLOBAL))
return DATA_E_FORMATETC;
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = GlobalAlloc(GHND,GlobalSize(hGuid));
pmedium->pUnkForRelease = NULL;
pstrDest = (char FAR *)GlobalLock(pmedium->hGlobal);
pstrSrc = (char FAR *)GlobalLock(hGuid);
memcpy(pstrDest,pstrSrc,GlobalSize(hGuid));
GlobalUnlock(hGuid);
GlobalUnlock(pmedium->hGlobal);
break;
default:
return DATA_E_FORMATETC;
}
return S_OK;
}
/**************************************************************************************************
EsiDataObject::GetDataHere - NOT IMPLEMENTED.
*/
STDMETHODIMP
EsiDataObject::GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
{
// Message(TEXT("EsiDataObject::GetDataHere"), E_NOTIMPL, NULL);
return E_NOTIMPL;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
This routine tells the caller that we support only CF_TEXT and TYMED_HGLOBAL formats.
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN LPFORMATETC
RETURN:
HRESULT - zero = success.
HRESULT - non zero = error code.
*/
STDMETHODIMP
EsiDataObject::QueryGetData(LPFORMATETC pformatetc)
{
// Check for DVASPECT_CONTENT.
if (!(DVASPECT_CONTENT & pformatetc->dwAspect)) {
// Message(TEXT("EsiDataObject::QueryGetData"), DATA_E_FORMATETC, NULL);
return DATA_E_FORMATETC;
}
// Check for CF_TEXT.
if (pformatetc->cfFormat != CF_TEXT) {
// Message(TEXT("EsiDataObject::QueryGetData"), DATA_E_FORMATETC, NULL);
return DATA_E_FORMATETC;
}
// Check for TYMED_HGLOBAL.
if (!(TYMED_HGLOBAL & pformatetc->tymed)) {
// Message(TEXT("EsiDataObject::QueryGetData"), DV_E_TYMED, NULL);
return DV_E_TYMED;
}
// Message(TEXT("EsiDataObject::QueryGetData"), S_OK, NULL);
return S_OK;
}
/*
/**************************************************************************************************
EsiDataObject::GetCanonicalFormatEtc - NOT IMPLEMENTED.
*/
STDMETHODIMP
EsiDataObject::GetCanonicalFormatEtc(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut)
{
// Message(TEXT("EsiDataObject::GetCanonicalFormatEtc"), DATA_S_SAMEFORMATETC, NULL);
return DATA_S_SAMEFORMATETC;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
EsiDataObject::GetData only supports CF_TEXT
GLOBAL VARIABLES:
None.
ARGUMENTS:
IN LPFORMATETC
IN LPSTGMEDIUM
IN BOOL fRelease
RETURN:
HRESULT - zero = success.
HRESULT - non zero = error code.
typedef struct {
WORD dwID; // ESI data structre ID always = 0x4553 'ES'
WORD dwType; // Type of data structure
WORD dwVersion; // Version number
WORD dwCompatibilty;// Compatibilty number
ULONG ulDataSize; // Data size
WPARAM wparam; // LOWORD(wparam) = Command
char cData; // Void pointer to the data - NULL = no data
} DATA_IO, *PDATA_IO;
*/
STDMETHODIMP EsiDataObject::SetData(LPFORMATETC pformatetc,
STGMEDIUM FAR * pmedium,
BOOL fRelease)
{
WPARAM wpPostCommand;
// We only support CF_TEXT
if (pformatetc->cfFormat != CF_TEXT) {
// Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
return E_FAIL;
}
// We want memory only.
if (pformatetc->tymed != TYMED_HGLOBAL) {
// Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
return E_FAIL;
}
DWORD dwGlobalSize;
char FAR* pstrSrc;
PCHAR pDataIn;
// Check for valid memory handle.
if(pmedium->hGlobal == NULL) {
// Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
return E_FAIL;
}
// Get the size of the incoming data.
dwGlobalSize = (DWORD)GlobalSize(pmedium->hGlobal);
// Allocate enough memory for the incoming data.
hDataIn = GlobalAlloc(GHND,dwGlobalSize);
EE_ASSERT(hDataIn);
// Lock and get pointers to the data.
pDataIn = (PCHAR)GlobalLock(hDataIn);
EE_ASSERT(pDataIn);
pstrSrc = (char FAR*)GlobalLock(pmedium->hGlobal);
EE_ASSERT(pstrSrc);
// Copy the data to this processes memory.
CopyMemory(pDataIn, pstrSrc, dwGlobalSize);
// Unlock and release the pointer to the source memory.
GlobalUnlock(pmedium->hGlobal);
// Release the memory if requested by the caller.
if (fRelease) {
ReleaseStgMedium(pmedium);
}
DATA_IO* pDataIo = (DATA_IO*)pDataIn;
// Extract the Post Command message
wpPostCommand = pDataIo->wparam;
// Cehck ESI data structre ID which is always = 0x4553 'ES'
if(pDataIo->dwID != ESI_DATA_STRUCTURE) {
// Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
return FALSE;
}
// Cehck the data structure type.
if(pDataIo->dwType != FR_COMMAND_BUFFER) {
// Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
return FALSE;
}
// Check for data structure compatibility.
if(pDataIo->dwCompatibilty != FR_COMMAND_BUFFER_ONE) {
// Message(TEXT("EsiDataObject::SetData"), E_FAIL, NULL);
return FALSE;
}
// Unlock the memory.
GlobalUnlock(hDataIn);
// Check for any data.
if(pDataIo->ulDataSize == 0) {
// Unlock the memory since there is no data other than the command.
EH_ASSERT(GlobalFree(hDataIn) == NULL);
hDataIn = NULL;
}
// Send the data to the message pump.
// NOTE THAT THE MEMORY MUST FREED BY THE PROCESSING FUNCTION.
// If we use DataIo with a console application, then we cannot use the WNT
// PostMessage() routine as there is No window to post the message to, so
// we will use a locally created PostMessageConsole() routine instead.
#ifdef ESI_POST_MESSAGE
#ifndef DKMS
PostMessageLocal(NULL, WM_COMMAND, wpPostCommand, (LPARAM)hDataIn);
#endif
#else
PostMessage(hwndMain, WM_COMMAND, wpPostCommand, (LPARAM)hDataIn);
#endif
// Message(TEXT("EsiDataObject::SetData"), S_OK, NULL);
return S_OK;
}
/**************************************************************************************************
EsiDataObject::EnumFormatEtc - NOT IMPLEMENTED.
*/
STDMETHODIMP
EsiDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
// Message(TEXT("EsiDataObject::DAdvise"), E_NOTIMPL, NULL);
return E_NOTIMPL ;
}
/**************************************************************************************************
EsiDataObject::DAdvise - NOT SUPPORTED.
*/
STDMETHODIMP
EsiDataObject::DAdvise(FORMATETC FAR* pFormatetc,
DWORD advf,
LPADVISESINK pAdvSink,
DWORD FAR* pdwConnection)
{
// Message(TEXT("EsiDataObject::DAdvise"), OLE_E_ADVISENOTSUPPORTED, NULL);
return OLE_E_ADVISENOTSUPPORTED;
}
/**************************************************************************************************
EsiDataObject::DUnadvise - NOT SUPPORTED.
*/
STDMETHODIMP
EsiDataObject::DUnadvise(DWORD dwConnection)
{
// Message(TEXT("EsiDataObject::DUnadvise"), OLE_E_ADVISENOTSUPPORTED, NULL);
return OLE_E_ADVISENOTSUPPORTED;
}
/**************************************************************************************************
EsiDataObject::DUnadvise - NOT SUPPORTED.
*/
STDMETHODIMP
EsiDataObject::EnumDAdvise(LPENUMSTATDATA FAR* ppenumAdvise)
{
// Message(TEXT("EsiDataObject::EnumDAdvise"), OLE_E_ADVISENOTSUPPORTED, NULL);
return OLE_E_ADVISENOTSUPPORTED;
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
This is the WinMain function for the Diskeeper Gui.
GLOBAL VARIABLES:
None.
INPUT:
hInstance - The handle to this instance.
hPrevInstance - The handle to the previous instance.
lpCmdLine - The command line which was passed in.
nCmdShow - Whether the window should be minimized or not.
RETURN:
TRUE - Success.
FALSE - Failure to initilize.
*/
DWORD
InitializeDataIo(
IN REFCLSID refCLSID,
DWORD dwRegCls
)
{
HRESULT hr;
DWORD dwRegister;
// initialize COM for free-threading.
// DO NOT want this for controls that are derived from ATL. Bad Mojo
#ifndef ESI_DFRGUI
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif
// Register the class-object with OLE.
hr = CoRegisterClassObject(refCLSID,
&g_ClassFactory,
CLSCTX_SERVER,
dwRegCls,
&dwRegister);
if (FAILED(hr)) {
return 0;
}
return( dwRegister );
}
/**************************************************************************************************
COPYRIGHT© 2001 Microsoft Corporation and Executive Software International, Inc.
ROUTINE DESCRIPTION:
Exit routine for DataIo
GLOBAL VARIABLES:
None.
INPUT:
None
RETURN:
TRUE - Success.
FALSE - Failure.
*/
BOOL
ExitDataIo(
)
{
#ifndef ESI_DFRGUI
// DO NOT want this for controls that are derived from ATL. Bad Mojo
CoUninitialize();
#endif
return TRUE;
}