#include <stdio.h> // for fprintf()
#include <CoreFoundation/CoreFoundation.h>
#include "ServerModule.h"
#include "ServerModuleLib.h"
#include "CDSServerModule.h"
#include "DirServicesTypes.h"
using namespace DSServerPlugin;
#ifndef _HRESULT_TYPEDEF_
#define _HRESULT_TYPEDEF_(x) x
#endif
extern "C" {
extern CFUUIDRef ModuleFactoryUUID;
extern void *ModuleFactory( CFAllocatorRef, CFUUIDRef );
}
typedef struct _tagModuleType : public ModuleFtbl
{
UInt32 mRefCount;
CDSServerModule *mInstance;
} _ModuleType;
static _ModuleType *_VTablePrototype = NULL;
#pragma mark **** COM Support functions ****
static HRESULT _COMQueryInterface ( void *thisp, REFIID iid, LPVOID *ppv )
{
CFUUIDRef uuidInterface = ::CFUUIDCreateFromUUIDBytes ( NULL, iid );
if ( ::CFEqual ( uuidInterface, kModuleInterfaceUUID ) ||
::CFEqual ( uuidInterface, IUnknownUUID ) )
{
((IUnknownVTbl *)thisp)->AddRef(thisp);
*ppv = thisp;
::CFRelease( uuidInterface );
return( S_OK );
}
::CFRelease( uuidInterface );
*ppv = NULL;
return( E_NOINTERFACE );
}
static ULONG _COMAddRef ( void *thisp )
{
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs ( "Bad cast to _ModuleType!\n", stderr );
return( (ULONG)-1 );
}
return( ++(opThis->mRefCount) );
}
static ULONG _COMRelease ( void *thisp )
{
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs ( "Bad cast to _ModuleType in Release!\n", stderr );
return( (ULONG)-1 );
}
if ( --(opThis->mRefCount) )
{
return( opThis->mRefCount );
}
#if DEBUG
::puts ( "_COMRelease: deallocating...\n" );
#endif
delete( opThis );
::CFPlugInRemoveInstanceForFactory ( ModuleFactoryUUID );
return( 0 );
}
#pragma mark **** ModuleInterface functions ****
static SInt32 _Validate ( void *thisp, const char *inVersionStr, const UInt32 inSignature )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs ("Bad cast to _ModuleType in Validate!\n", stderr);
return( -1 );
}
try {
nResult = opThis->mInstance->Validate( inVersionStr, inSignature );
}
catch( SInt32 err )
{
nResult = err;
}
catch( SInt16 err )
{
nResult = err;
}
catch( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static SInt32 _Initialize ( void *thisp )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs ("Bad cast to _ModuleType in Initialize!\n", stderr);
return( -1 );
}
try {
nResult = opThis->mInstance->Initialize();
}
catch( SInt32 err )
{
nResult = err;
}
catch( SInt16 err )
{
nResult = err;
}
catch( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static SInt32 _Configure ( void *thisp )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs ("Bad cast to _ModuleType in Configure!\n", stderr);
return( -1 );
}
try {
nResult = opThis->mInstance->Configure();
}
catch( SInt32 err )
{
nResult = err;
}
catch( SInt16 err )
{
nResult = err;
}
catch( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static SInt32 _ProcessRequest ( void *thisp, void *inData )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs ( "Bad cast to _ModuleType in ProcessRequest!\n", stderr );
return( -1 );
}
try {
nResult = opThis->mInstance->ProcessRequest( inData );
}
catch ( SInt32 err )
{
nResult = err;
}
catch ( SInt16 err )
{
nResult = err;
}
catch ( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static SInt32 _SetPluginState ( void *thisp, const UInt32 inState )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs( "Bad cast to _ModuleType in SetPluginState!\n", stderr );
return( -1 );
}
try {
nResult = opThis->mInstance->SetPluginState( inState );
}
catch( SInt32 err )
{
nResult = err;
}
catch( SInt16 err )
{
nResult = err;
}
catch( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static SInt32 _PeriodicTask ( void *thisp )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs( "Bad cast to _ModuleType in PeriodicTask!\n", stderr );
return( -1 );
}
try {
nResult = opThis->mInstance->PeriodicTask();
}
catch( SInt32 err )
{
nResult = err;
}
catch( SInt16 err )
{
nResult = err;
}
catch( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static SInt32 _Shutdown ( void *thisp )
{
SInt32 nResult = eDSNoErr;
_ModuleType *opThis = static_cast<_ModuleType *> (thisp);
if ( opThis == NULL )
{
::fputs( "Bad cast to _ModuleType in Shutdown!\n", stderr );
return( -1 );
}
try {
nResult = opThis->mInstance->Shutdown();
}
catch( SInt32 err )
{
nResult = err;
}
catch( SInt16 err )
{
nResult = err;
}
catch( ... )
{
nResult = eParameterError;
}
return( nResult );
}
static void _LinkLibFtbl ( void *thisp, SvrLibFtbl *inLinkBack )
{
::SetupLinkTable( inLinkBack );
}
static void _InitializeModule ( void )
{
_VTablePrototype = new _ModuleType;
if ( _VTablePrototype != nil )
{
_VTablePrototype->QueryInterface = _COMQueryInterface;
_VTablePrototype->AddRef = _COMAddRef;
_VTablePrototype->Release = _COMRelease;
_VTablePrototype->validate = _Validate;
_VTablePrototype->initialize = _Initialize;
_VTablePrototype->configure = _Configure;
_VTablePrototype->processRequest = _ProcessRequest;
_VTablePrototype->setPluginState = _SetPluginState;
_VTablePrototype->periodicTask = _PeriodicTask;
_VTablePrototype->shutdown = _Shutdown;
_VTablePrototype->linkLibFtbl = _LinkLibFtbl;
_VTablePrototype->mInstance = 0;
_VTablePrototype->mRefCount = 1;
}
else
{
::fputs ( "Serious memory allocation error!\n", stderr );
}
}
void *ModuleFactory ( CFAllocatorRef allocator, CFUUIDRef typeID )
{
if ( _VTablePrototype == nil )
{
_InitializeModule();
}
#if DEBUG
::puts( "ModuleFactory: loaded and called!\n" );
::fflush( stdout );
#endif
if ( ::CFEqual( typeID, kModuleTypeUUID ) )
{
_ModuleType *opNew = new _ModuleType;
*opNew = *_VTablePrototype;
opNew->mInstance = CDSServerModule::Instance();
::CFPlugInAddInstanceForFactory( ModuleFactoryUUID );
return( opNew );
}
else
{
return( NULL );
}
}