491 lines
13 KiB
C++
491 lines
13 KiB
C++
//--------------------------------------------------------------
|
||
//
|
||
// 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;
|
||
}
|
||
|