windows-nt/Source/XPSP1/NT/com/oleutest/channel/hook/hook.cxx
2020-09-26 16:20:57 +08:00

491 lines
13 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//--------------------------------------------------------------
//
// File: hook.cxx
//
// Contents: Test channel hooks
//
//---------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <io.h>
#include <malloc.h>
#include <ole2.h>
#include <coguid.h>
#include "hook.h"
class CWhichHook : public IWhichHook
{
public:
// Constructor/Destructor
CWhichHook();
~CWhichHook() {};
// IUnknown
STDMETHOD (QueryInterface) (REFIID iid, void FAR * FAR * ppv);
STDMETHOD_(ULONG,AddRef) ( void );
STDMETHOD_(ULONG,Release) ( void );
// IWhichHook
STDMETHOD (Me) ( REFIID riid );
STDMETHOD (Hooked)( REFIID riid );
STDMETHOD (Clear) ();
private:
DWORD _iRef;
static BOOL _f1;
static BOOL _f2;
};
class CDllHook : public IChannelHook
{
public:
CDllHook( REFGUID );
~CDllHook() {};
STDMETHOD (QueryInterface) ( REFIID riid, LPVOID FAR* ppvObj);
STDMETHOD_(ULONG,AddRef) ( void );
STDMETHOD_(ULONG,Release) ( void );
STDMETHOD_(void,ClientGetSize) ( REFGUID, REFIID, ULONG *DataSize );
STDMETHOD_(void,ClientFillBuffer)( REFGUID, REFIID, ULONG *DataSize, void *DataBuffer );
STDMETHOD_(void,ClientNotify) ( REFGUID, REFIID, ULONG DataSize, void *DataBuffer,
DWORD DataRep, HRESULT );
STDMETHOD_(void,ServerNotify) ( REFGUID, REFIID, ULONG DataSize, void *DataBuffer,
DWORD DataRep );
STDMETHOD_(void,ServerGetSize) ( REFGUID, REFIID, HRESULT, ULONG *DataSize );
STDMETHOD_(void,ServerFillBuffer)( REFGUID, REFIID, ULONG *DataSize, void *DataBuffer, HRESULT );
private:
ULONG _iRef;
GUID _extent;
CWhichHook _cWhich;
};
class CHookCF: public IClassFactory
{
public:
// Constructor/Destructor
CHookCF( CLSID );
~CHookCF() {};
// IUnknown
STDMETHOD (QueryInterface) (REFIID iid, void FAR * FAR * ppv);
STDMETHOD_(ULONG,AddRef) ( void );
STDMETHOD_(ULONG,Release) ( void );
// IClassFactory
STDMETHODIMP CreateInstance(
IUnknown FAR* pUnkOuter,
REFIID iidInterface,
void FAR* FAR* ppv);
STDMETHODIMP LockServer(BOOL fLock);
private:
ULONG _iRef;
CLSID _class;
};
const CLSID CLSID_Hook1 = {0x60000400, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
const CLSID CLSID_Hook2 = {0x60000401, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
const CLSID CLSID_WhichHook = {0x60000402, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
const IID IID_IWhichHook = {0x60000403, 0x76d7, 0x11cf, {0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4}};
BOOL CWhichHook::_f1 = FALSE;
BOOL CWhichHook::_f2 = FALSE;
//+-------------------------------------------------------------------------
//
// Function: DllCanUnloadNow
//
// Synopsis: Dll entry point
//
//--------------------------------------------------------------------------
STDAPI DllCanUnloadNow()
{
return S_FALSE;
}
//+-------------------------------------------------------------------------
//
// Function: DllGetClassObject
//
// Synopsis: Dll entry point
//
//--------------------------------------------------------------------------
STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv)
{
CHookCF *pFactory;
// Check for IPSFactoryBuffer
if ((clsid == CLSID_Hook1 || clsid == CLSID_Hook2 || clsid == CLSID_WhichHook)
&& iid == IID_IClassFactory)
{
pFactory = new CHookCF( clsid );
*ppv = pFactory;
if (pFactory == NULL)
return E_OUTOFMEMORY;
else
return S_OK;
}
return E_NOTIMPL;
}
//+-------------------------------------------------------------------
//
// Member: CHookCF::AddRef, public
//
// Synopsis: Adds a reference to an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CHookCF::AddRef()
{
InterlockedIncrement( (long *) &_iRef );
return _iRef;
}
//+-------------------------------------------------------------------
//
// Member: CHookCF::CHookCF
//
// Synopsis: Constructor
//
//--------------------------------------------------------------------
CHookCF::CHookCF( CLSID clsid )
{
_iRef = 1;
_class = clsid;
}
//+-------------------------------------------------------------------
//
// Member: CHookCF::CreateInstance, public
//
// Synopsis: Create an instance of the requested class
//
//--------------------------------------------------------------------
STDMETHODIMP CHookCF::CreateInstance(
IUnknown FAR* pUnkOuter,
REFIID iidInterface,
void FAR* FAR* ppv)
{
IUnknown *pUnk;
HRESULT hr;
*ppv = NULL;
if (pUnkOuter != NULL)
{
printf( "Create instance failed, attempted agregation.\n" );
return E_FAIL;
}
// Create the right class.
if (_class == CLSID_WhichHook)
pUnk = new CWhichHook();
else
pUnk = new CDllHook( _class );
// Query for the requested interface.
hr = pUnk->QueryInterface( iidInterface, ppv );
pUnk->Release();
return hr;
}
//+-------------------------------------------------------------------
//
// Member: CHookCF::LockServer, public
//
//--------------------------------------------------------------------
STDMETHODIMP CHookCF::LockServer(BOOL fLock)
{
return E_FAIL;
}
//+-------------------------------------------------------------------
//
// Member: CHookCF::QueryInterface, public
//
// Synopsis: Returns a pointer to the requested interface.
//
//--------------------------------------------------------------------
STDMETHODIMP CHookCF::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IClassFactory))
*ppvObj = (IClassFactory *) this;
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
//+-------------------------------------------------------------------
//
// Member: CHookCF::Release, public
//
// Synopsis: Releases an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CHookCF::Release()
{
ULONG lRef = _iRef - 1;
if (InterlockedDecrement( (long*) &_iRef ) == 0)
{
delete this;
return 0;
}
else
return lRef;
}
//+-------------------------------------------------------------------
//
// Member: CDllHook::AddRef, public
//
// Synopsis: Adds a reference to an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CDllHook::AddRef()
{
InterlockedIncrement( (long *) &_iRef );
return _iRef;
}
//+-------------------------------------------------------------------
//
// Member: CDllHook::CDllHook, public
//
// Synopsis: Constructor
//
//--------------------------------------------------------------------
CDllHook::CDllHook( REFGUID rExtent )
{
_iRef = 1;
_extent = rExtent;
}
//+-------------------------------------------------------------------
//
// Member: CDllHook::QueryInterface, public
//
// Synopsis: Returns a pointer to the requested interface.
//
//--------------------------------------------------------------------
STDMETHODIMP CDllHook::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IChannelHook))
*ppvObj = (IChannelHook *) this;
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
//+-------------------------------------------------------------------
//
// Member: CDllHook::Release, public
//
// Synopsis: Releases an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CDllHook::Release()
{
ULONG lRef = _iRef - 1;
if (InterlockedDecrement( (long*) &_iRef ) == 0)
{
delete this;
return 0;
}
else
return lRef;
}
/***************************************************************************/
STDMETHODIMP_(void) CDllHook::ClientGetSize( REFGUID ext, REFIID riid,
ULONG *size )
{
_cWhich.Me( _extent );
*size = sizeof(DWORD);
}
/***************************************************************************/
STDMETHODIMP_(void) CDllHook::ClientFillBuffer( REFGUID ext, REFIID riid,
ULONG *max, void *buffer )
{
_cWhich.Me( _extent );
*max = sizeof(DWORD);
if (_extent == CLSID_Hook1)
*((DWORD *) buffer) = 'Blue';
else
*((DWORD *) buffer) = 'Grn';
}
/***************************************************************************/
STDMETHODIMP_(void) CDllHook::ClientNotify( REFGUID ext, REFIID riid,
ULONG size, void *buffer,
DWORD data_rep, HRESULT result )
{
_cWhich.Me( _extent );
}
/***************************************************************************/
STDMETHODIMP_(void) CDllHook::ServerNotify( REFGUID ext, REFIID riid,
ULONG size, void *buffer,
DWORD data_rep )
{
_cWhich.Me( _extent );
}
/***************************************************************************/
STDMETHODIMP_(void) CDllHook::ServerGetSize( REFGUID ext, REFIID riid, HRESULT hr,
ULONG *size )
{
_cWhich.Me( _extent );
*size = sizeof(DWORD);
}
/***************************************************************************/
STDMETHODIMP_(void) CDllHook::ServerFillBuffer( REFGUID ext, REFIID riid,
ULONG *max, void *buffer, HRESULT hr )
{
_cWhich.Me( _extent );
*max = sizeof(DWORD);
if (_extent == CLSID_Hook1)
*((DWORD *) buffer) = 'Blue';
else
*((DWORD *) buffer) = 'Grn';
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::AddRef, public
//
// Synopsis: Adds a reference to an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWhichHook::AddRef()
{
InterlockedIncrement( (long *) &_iRef );
return _iRef;
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::CWhichHook, public
//
// Synopsis: Constructor
//
//--------------------------------------------------------------------
CWhichHook::CWhichHook()
{
_iRef = 1;
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::QueryInterface, public
//
// Synopsis: Returns a pointer to the requested interface.
//
//--------------------------------------------------------------------
STDMETHODIMP CWhichHook::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IWhichHook))
*ppvObj = (IWhichHook *) this;
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::Release, public
//
// Synopsis: Releases an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWhichHook::Release()
{
ULONG lRef = _iRef - 1;
if (InterlockedDecrement( (long*) &_iRef ) == 0)
{
delete this;
return 0;
}
else
return lRef;
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::Me, public
//
// Synopsis: Flags a hook as used.
//
//--------------------------------------------------------------------
STDMETHODIMP CWhichHook::Me( REFIID riid )
{
if (riid == CLSID_Hook1)
_f1 = TRUE;
else if (riid == CLSID_Hook2)
_f2 = TRUE;
return S_OK;
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::Hooked, public
//
// Synopsis: Succeeds if the specified hook has been used.
//
//--------------------------------------------------------------------
STDMETHODIMP CWhichHook::Hooked( REFIID riid )
{
if (riid == CLSID_Hook1)
return _f1 ? S_OK : E_FAIL;
else if (riid == CLSID_Hook2)
return _f2 ? S_OK : E_FAIL;
return E_INVALIDARG;
}
//+-------------------------------------------------------------------
//
// Member: CWhichHook::Clear, public
//
// Synopsis: Clears the used flags.
//
//--------------------------------------------------------------------
STDMETHODIMP CWhichHook::Clear()
{
_f1 = FALSE;
_f2 = FALSE;
return S_OK;
}