|
|
/****************************************************************************
FILE: actestp.c
PURPOSE: FUNCTIONS: COMMENTS:
****************************************************************************/
#include <windows.h>
#include <ole2.h>
#include <oleext.h> // IAccessControl interface definition
#include <wchar.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include "oactest.h" // header file generated by MIDL compiler
void DecrementLockCount(); void IncrementLockCount(); void ObjectCreated(); void ObjectDestroyed();
const CLSID CLSID_COAccessControl_DCOM = {0x52c0e9e1,0xc0c0,0x11cf,{0xae,0xec,0x00,0xaa,0x00,0x44,0xfb,0x89}};
extern "C" const CLSID CLSID_COAccessControlTest; extern ULONG g_ulFrequency; DWORD g_dwRegister; long g_fClassRegistered = FALSE;
// IAccessControlTest implementation class
class CAccessControlTest : public IAccessControlTest { private: IUnknown *m_pIUnknown; IPersistStream *m_pIPersistStream; IAccessControl *m_pIAccessControl; ULONG m_cRef; BOOL m_bInitialized;
// destructor
~CAccessControlTest() { DecrementLockCount(); ObjectDestroyed(); }
public: // contructor
CAccessControlTest() { m_cRef = 0; m_bInitialized = FALSE; ObjectCreated(); IncrementLockCount(); }
STDMETHODIMP_(HRESULT) QueryInterface ( REFIID iid, void **ppv );
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP_(HRESULT) TestServer ( LPSTR pszTestString );
STDMETHODIMP_(HRESULT) GetClassID ( CLSID *pClassID, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) InitNewACL ( DOUBLE*pdMillisec );
STDMETHODIMP_(HRESULT) LoadACL ( LPCSTR pszFilename, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) SaveACL ( LPCSTR pszFilename, BOOL fClearDirty, ULONG *pulBytesWritten, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) GetSizeMax ( ULONG *pcdSize, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) IsDirty ( DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) GrantAccessRights ( ULONG cCount, E_ACCESS_REQUEST *pAccessRequestList, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) DenyAccessRights ( ULONG cCount, E_ACCESS_REQUEST pAccessRequestList[], DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) SetAccessRights ( ULONG cCount, E_ACCESS_REQUEST pAccessRequestList[], DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) ReplaceAllAccessRights ( ULONG cCount, E_EXPLICIT_ACCESS pExplicitAccessList[], DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) RevokeExplicitAccessRights ( ULONG cCount, E_TRUSTEE pTrustee[], DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) IsAccessPermitted ( E_TRUSTEE *pTrustee, DWORD grfAccessPermissions, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) GetEffectiveAccessRights ( E_TRUSTEE *pTrustee, DWORD *pdwRights, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) GetExplicitAccessRights ( ULONG *pcCount, PE_EXPLICIT_ACCESS *ppExplicitAccessList, DOUBLE *pdMillisec );
STDMETHODIMP_(HRESULT) RevertAccessRights ( );
STDMETHODIMP_(HRESULT) CommitAccessRights ( DWORD grfCommitFlags );
}; // CAccessControlTest
//+-------------------------------------------------------------------------
//
// Method: CAccessControlTest::AddRef, public
//
// Synopsis: Increment reference count
//
// See Also: IUnknown::AddRef
//
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAccessControlTest::AddRef() { InterlockedIncrement((long *) &m_cRef); return m_cRef; }
//+-------------------------------------------------------------------------
//
// Method: CAccessControlTest::Release, public
//
// Synopsis: Decrement DLL reference count
//
// Notes: After the m_cRef is decremented, the object may be
// deleted by another thread. In order to make this code safe
// for multiple threads, we have to access the object state
// before decrementing m_cRef.
//
// See Also: IUnknown::Release.
//
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAccessControlTest::Release() { unsigned long count; count = m_cRef - 1;
if(InterlockedDecrement((long *) &m_cRef) == 0) { count = 0; if(m_bInitialized) { m_pIUnknown->Release(); m_pIPersistStream->Release(); m_pIAccessControl->Release(); } delete this; }
return count; }
//+-------------------------------------------------------------------------
//
// Method: CAccessControlTest::QueryInterface, public
//
// Synopsis: Query for an interface on the class factory.
//
// See Also: IUnknown:QueryInterface
//
//--------------------------------------------------------------------------
STDMETHODIMP_(HRESULT) CAccessControlTest::QueryInterface ( REFIID iid, void **ppv ) { HRESULT hr;
if (!m_bInitialized) { hr = CoCreateInstance( CLSID_COAccessControl_DCOM , NULL , CLSCTX_INPROC_SERVER , IID_IUnknown , (void **)&m_pIUnknown); if(FAILED(hr)) { printf("Failed to create an instance of COAccessControl\n."); return hr; }
hr = m_pIUnknown->QueryInterface(IID_IPersistStream, (void **)&m_pIPersistStream);
if(FAILED(hr)) { printf("Failed to query for the IPersistStream Interface.\n"); return hr; } hr = m_pIUnknown->QueryInterface(IID_IAccessControl, (void **)&m_pIAccessControl);
if(FAILED(hr)) { printf("Failed to query for the IAccessControl interface.\n"); return hr; } m_bInitialized = TRUE; }
if ( IsEqualGUID( iid, IID_IUnknown ) ) { *ppv = (IUnknown *) this; ((IUnknown *)(*ppv))->AddRef(); hr = S_OK; } else if (IsEqualGUID( iid, IID_IAccessControlTest)) { *ppv = (IUnknown *)(IAccessControlTest *)this; ((IAccessControlTest *)(*ppv))->AddRef(); hr = S_OK; } else { *ppv = 0; hr = E_NOINTERFACE; }
return hr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::TestServer ( LPSTR pszTestString ) { printf("The test string is: %s\n", pszTestString);
return S_OK; }
STDMETHODIMP_(HRESULT) CAccessControlTest::GetClassID ( CLSID *pClassID, DOUBLE *pdMillisec ) { HRESULT localhr; CLSID clsid;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIPersistStream->GetClassID(&clsid); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pClassID = clsid; *pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::InitNewACL ( DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIPersistStream->Load(NULL); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr;
}
STDMETHODIMP_(HRESULT) CAccessControlTest::LoadACL ( LPCSTR pszFilename, DOUBLE *pdMillisec ) { HRESULT localhr; IStream *pIStream = NULL; HANDLE FileHandle; DWORD dwFileSize; void *pvBuffer;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
// Open the file specified by the client
FileHandle = CreateFileA( pszFilename , GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
if( FileHandle == INVALID_HANDLE_VALUE ) { printf("Cannot open file %s.\n", pszFilename); *pdMillisec = 0; return HRESULT_FROM_WIN32(GetLastError()); }
// Get the size of the file
dwFileSize = GetFileSize(FileHandle, NULL);
// Create a buffer to hold the data in the file
pvBuffer = CoTaskMemAlloc(dwFileSize);
DWORD dwBytesRead; // Read the data of the opened file into a buffer
if(!ReadFile( FileHandle , pvBuffer , dwFileSize , &dwBytesRead , NULL )) { return HRESULT_FROM_WIN32(GetLastError()); }
// Once we have read the file data into a buffer, we can
// close the file handle
CloseHandle( FileHandle);
// Create a stream on the the buffer
localhr = CreateStreamOnHGlobal(NULL, TRUE, &pIStream);
if (FAILED(localhr)) { printf("Cannot create stream object.\n"); CoTaskMemFree(pvBuffer); *pdMillisec = 0; return localhr; }
// Load the data in the buffer into the IStream object
localhr = pIStream->Write(pvBuffer, dwFileSize, NULL);
// Release the local buffer
CoTaskMemFree(pvBuffer);
if (FAILED(localhr)) { printf("Failed to load data into stream object.\n"); *pdMillisec = 0; return localhr; }
// Rewind the stream pointer the starting position
LARGE_INTEGER li; li.LowPart = 0; li.HighPart = 0; localhr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
if (FAILED(localhr)) { printf("Failed to set the stream pointer to the starting position.\n"); *pdMillisec = 0; return localhr; }
QueryPerformanceCounter(&liCount1); localhr = m_pIPersistStream->Load(pIStream); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0;
// Release the local stream pointer
pIStream->Release();
return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::SaveACL ( LPCSTR pszFilename, BOOL fClearDirty, ULONG *pulNumOfBytesWritten, DOUBLE *pdMillisec ) { HRESULT localhr; IStream *pIStream = NULL; HANDLE FileHandle; DWORD dwFileSize; void *pvBuffer; STATSTG StreamInfo;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
// Create a stream on the the buffer
localhr = CreateStreamOnHGlobal(NULL, TRUE, &pIStream);
if (FAILED(localhr)) { printf("Cannot create stream object.\n"); *pdMillisec = 0; return localhr; }
QueryPerformanceCounter(&liCount1); localhr = m_pIPersistStream->Save(pIStream, fClearDirty); QueryPerformanceCounter(&liCount2);
if(FAILED(localhr)) { *pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
// Get the number of bytes written to the stream
localhr = pIStream->Stat(&StreamInfo, STATFLAG_NONAME); if (FAILED(localhr)) { printf("Unable to get information about the local stream.\n"); *pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
dwFileSize = StreamInfo.cbSize.LowPart;
LARGE_INTEGER liOffset;
liOffset.QuadPart = Int32x32To64(dwFileSize, -1); pIStream->Seek(liOffset,STREAM_SEEK_CUR, NULL);
// Allocate a buffer to store the data in the stream
pvBuffer = CoTaskMemAlloc(dwFileSize);
// Write the stream
localhr = pIStream->Read(pvBuffer, dwFileSize, NULL);
if(FAILED(localhr)) { printf("Unable to write data from stream to buffer.\n"); CoTaskMemFree(pvBuffer); *pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
// Open the file specified by the client
FileHandle = CreateFileA( pszFilename , GENERIC_WRITE | GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL );
if( FileHandle == INVALID_HANDLE_VALUE ) { printf("Cannot open file %s.\n", pszFilename); CoTaskMemFree(pvBuffer); *pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return HRESULT_FROM_WIN32(GetLastError()); }
// Read the data of the opened file into a buffer
if(!WriteFile( FileHandle , pvBuffer , dwFileSize , pulNumOfBytesWritten , NULL )) { DWORD dwLastError; dwLastError = GetLastError(); printf("Write failed with error code %x.", dwLastError); }
// Flush the file buffers
FlushFileBuffers(FileHandle);
// Close the file handle
CloseHandle(FileHandle);
CoTaskMemFree(pvBuffer);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; *pulNumOfBytesWritten = dwFileSize;
// Release the local stream pointer
pIStream->Release();
return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::GetSizeMax ( ULONG *pcdSize, DOUBLE *pdMillisec ) { ULARGE_INTEGER uliSize; HRESULT localhr; LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIPersistStream->GetSizeMax(&uliSize); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pcdSize = uliSize.LowPart; *pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::IsDirty ( DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIPersistStream->IsDirty(); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0;
return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::GrantAccessRights ( ULONG cCount, E_ACCESS_REQUEST pAccessRequestList[], DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->GrantAccessRights(cCount, (ACCESS_REQUEST_W *)pAccessRequestList); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::SetAccessRights ( ULONG cCount, E_ACCESS_REQUEST pAccessRequestList[], DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->SetAccessRights(cCount, (ACCESS_REQUEST_W *)pAccessRequestList); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::DenyAccessRights ( ULONG cCount, E_ACCESS_REQUEST pAccessRequestList[], DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->DenyAccessRights(cCount, (ACCESS_REQUEST_W *)pAccessRequestList); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::ReplaceAllAccessRights ( ULONG cCount, E_EXPLICIT_ACCESS pExplicitAccessList[], DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->ReplaceAllAccessRights(cCount, (EXPLICIT_ACCESS_W *)pExplicitAccessList); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::RevokeExplicitAccessRights ( ULONG cCount, E_TRUSTEE pTrustee[], DOUBLE *pdMillisec ) { char *pszClientName; RPC_STATUS status; HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->RevokeExplicitAccessRights(cCount, (TRUSTEE_W *)pTrustee); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::IsAccessPermitted ( E_TRUSTEE *pTrustee, DWORD grfAccessPermissions, DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->IsAccessPermitted((TRUSTEE_W *)pTrustee, grfAccessPermissions); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::GetEffectiveAccessRights ( E_TRUSTEE *pTrustee, DWORD *pdwRights, DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->GetEffectiveAccessRights((TRUSTEE_W *)pTrustee, pdwRights); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::GetExplicitAccessRights ( ULONG *pcCount, PE_EXPLICIT_ACCESS *ppExplicitAccessList, DOUBLE *pdMillisec ) { HRESULT localhr;
LARGE_INTEGER liCount1; LARGE_INTEGER liCount2;
QueryPerformanceCounter(&liCount1); localhr = m_pIAccessControl->GetExplicitAccessRights(pcCount, (PEXPLICIT_ACCESS_W *)ppExplicitAccessList); QueryPerformanceCounter(&liCount2);
// Assign calues to the out parameters
*pdMillisec = ((DOUBLE)(liCount2.LowPart) - (DOUBLE)(liCount1.LowPart)) / (DOUBLE)(g_ulFrequency) * 1000.0; return localhr; }
STDMETHODIMP_(HRESULT) CAccessControlTest::RevertAccessRights ( ) { return m_pIAccessControl->RevertAccessRights();
}
STDMETHODIMP_(HRESULT) CAccessControlTest::CommitAccessRights ( DWORD grfCommitFlags ) { return m_pIAccessControl->CommitAccessRights(grfCommitFlags); }
class CACTestClassFactory : public IClassFactory { private: unsigned long m_cRef;
//destructor
~CACTestClassFactory() { ObjectDestroyed(); }
public: //constructor
CACTestClassFactory() { m_cRef = 0; ObjectCreated(); }
HRESULT STDMETHODCALLTYPE QueryInterface( REFIID iid, void **ppv); ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown *punkOuter, REFIID riid, void **ppv);
HRESULT STDMETHODCALLTYPE LockServer( BOOL fLock );
};
//+-------------------------------------------------------------------------
//
// Method: CACTestClassFactory::AddRef, public
//
// Synopsis: Increment DLL reference counts
//
// See Also: IUnknown::AddRef
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE CACTestClassFactory::AddRef() { InterlockedIncrement((long *) &m_cRef); return m_cRef; }
//+-------------------------------------------------------------------------
//
// Method: CACTestClassFactory::CreateInstance, public
//
// Synopsis: Create an instance of CAccessControlTest.
//
// See Also: IClassFactory::CreateInstance
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CACTestClassFactory::CreateInstance ( IUnknown *punkOuter, REFIID riid, void **ppv ) { HRESULT hr; CAccessControlTest *pACTest;
if(punkOuter != 0) { //The CAccessControlTest class doesn't support aggregation.
return CLASS_E_NOAGGREGATION; }
pACTest = new CAccessControlTest(); if(pACTest != 0) { hr = pACTest->QueryInterface(riid, ppv); } else { hr = E_OUTOFMEMORY; *ppv = 0; }
return hr; }
//+-------------------------------------------------------------------------
//
// Method: CACTestClassFactory::LockServer, public
//
// Synopsis: Lock the server in memory (by adding an extra reference)
//
// Notes: The class factory will be revoked when the lock count
// is decremented to zero. LockServer(TRUE) will increment the
// lock count and ensure that the class factory will
// not be revoked.
//
// See Also: IClassFactory::LockServer
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CACTestClassFactory::LockServer( BOOL fLock ) { if (fLock == TRUE) IncrementLockCount(); else DecrementLockCount();
return S_OK; }
//+-------------------------------------------------------------------------
//
// Method: CACTestClassFactory::QueryInterface, public
//
// Synopsis: Query for an interface on the class factory.
//
// See Also: IUnknown::QueryInterface
//
//--------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CACTestClassFactory::QueryInterface ( REFIID iid, void **ppv ) { HRESULT hr;
if ( IsEqualGUID( iid, IID_IUnknown) || IsEqualGUID( iid, IID_IClassFactory ) ) { *ppv = this; ((IUnknown *)(*ppv))->AddRef(); hr = S_OK; } else { *ppv = 0; hr = E_NOINTERFACE; }
return hr; } //+-------------------------------------------------------------------------
//
// Method: CACTestClassFactory::Release, public
//
// Synopsis: Decrement DLL reference count
//
// See Also: IUnknown::Release
//
//--------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE CACTestClassFactory::Release() { unsigned long count; count = m_cRef - 1;
if(InterlockedDecrement((long *) &m_cRef) == 0) { count = 0; delete this; } return count; }
//+-------------------------------------------------------------------------
//
// Function: RegisterClassFactory.
//
// Synopsis: Register the class factory if it is not currently registered.
//
//--------------------------------------------------------------------------
HRESULT RegisterClassFactory() { HRESULT hr; CACTestClassFactory *pClassFactory;
if(InterlockedExchange(&g_fClassRegistered, TRUE) == FALSE) { pClassFactory = new CACTestClassFactory; if(pClassFactory != 0) { hr = CoRegisterClassObject(CLSID_COAccessControlTest, (IUnknown *) pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &g_dwRegister); } else { hr = E_OUTOFMEMORY; } } else { hr = S_OK; } return hr; }
//+-------------------------------------------------------------------------
//
// Function: RevokeClassFactory.
//
// Synopsis: Revoke the registered class factories if they have not
// already been revoked.
//
//--------------------------------------------------------------------------
HRESULT RevokeClassFactory() { HRESULT hr;
if(InterlockedExchange(&g_fClassRegistered, FALSE) == TRUE) { hr = CoRevokeClassObject(g_dwRegister); } else { hr = S_OK; } return hr; }
|