Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1049 lines
25 KiB

/****************************************************************************
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;
}