|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999.
//
// File: namesem.hxx
//
// Contents: Classes to manage InterProcess Synchronization and shared
// memory.
//
// Classes: CIPMutexSem, CSharedMemory, CIPLock
//
// History: 1-30-96 srikants Created
//
//----------------------------------------------------------------------------
#pragma once
//
// No longer needed. Originally I thought it might be needed.
//
//+---------------------------------------------------------------------------
//
// Class: CNamedEventSem
//
// Purpose:
//
// History: 1-30-96 srikants Created
//
//----------------------------------------------------------------------------
class CNamedEventSem {
public:
inline CNamedEventSem( DWORD dwMustBeZero, WCHAR const * pwszName, DWORD dwAccess = EVENT_ALL_ACCESS | EVENT_MODIFY_STATE | SYNCHRONIZE );
inline CNamedEventSem( WCHAR const * pwszName, BOOL fInitState = FALSE, const LPSECURITY_ATTRIBUTES lpsa = NULL );
enum eNameType { AppendPid };
inline CNamedEventSem( WCHAR const * pwszName, eNameType eNT, BOOL fInitState = FALSE, const LPSECURITY_ATTRIBUTES lpsa = NULL );
inline ~CNamedEventSem();
HANDLE AcquireHandle() { HANDLE hVal = _hEvent; _hEvent = 0; return hVal; }
HANDLE GetHandle() const { return _hEvent; }
private:
inline void Init( WCHAR const * pwszName, BOOL fInitState, const LPSECURITY_ATTRIBUTES lpsa );
HANDLE _hEvent;
};
inline CNamedEventSem::CNamedEventSem( DWORD dwMustBeZero, WCHAR const * pwszName, DWORD dwAccess ) { Win4Assert( 0 == dwMustBeZero && 0 != pwszName ); //ciDebugOut(( DEB_ITRACE, "Opening a named event (%ws)\n", pwszName ));
_hEvent = OpenEvent( dwAccess, TRUE, pwszName ); if ( 0 == _hEvent ) { //ciDebugOut(( DEB_ERROR, "Error while opening named event (%ws). Error - 0x%X\n",
// pwszName, GetLastError() ));
THROW( CException() ); } }
inline CNamedEventSem::CNamedEventSem( WCHAR const * pwszName, BOOL fInitState, const LPSECURITY_ATTRIBUTES lpsa ) { Init( pwszName, fInitState, lpsa ); }
inline CNamedEventSem::CNamedEventSem( WCHAR const * pwszName, CNamedEventSem::eNameType eNT, BOOL fInitState, const LPSECURITY_ATTRIBUTES lpsa ) { Win4Assert( eNT == CNamedEventSem::AppendPid );
unsigned ccName = wcslen( pwszName ); WCHAR wcsNewName[MAX_PATH];
RtlCopyMemory( wcsNewName, pwszName, ccName * sizeof(WCHAR) ); _itow( GetCurrentProcessId(), wcsNewName + ccName, 16 );
Init( wcsNewName, fInitState, lpsa ); }
inline CNamedEventSem::~CNamedEventSem() { if ( 0 != _hEvent && !CloseHandle (_hEvent) ) { THROW ( CException() ); } }
inline void CNamedEventSem::Init( WCHAR const * pwszName, BOOL fInitState, const LPSECURITY_ATTRIBUTES lpsa ) { //ciDebugOut(( DEB_ITRACE, "Creating a named event (%ws)\n", pwszName ));
_hEvent = CreateEvent ( lpsa, TRUE, fInitState, pwszName ); if ( _hEvent == 0 ) { //ciDebugOut(( DEB_ERROR, "Error while creating named event (%ws). Error - 0x%X\n",
// pwszName, GetLastError() ));
THROW ( CException() ); } }
//+---------------------------------------------------------------------------
//
// Class: CIPMutexSem
//
// Purpose: Mutex useful for inter-process synchronization. It can be
// named or un-named.
//
// History: 1-30-96 srikants Created
//
//----------------------------------------------------------------------------
class CIPMutexSem {
public:
inline CIPMutexSem( WCHAR const * pwszName, BOOL bInitialOwner = FALSE, const LPSECURITY_ATTRIBUTES lpsa=0 );
inline CIPMutexSem( DWORD dwMustBeZero, WCHAR const * pwszName );
inline CIPMutexSem( HANDLE hMutex ) : _hMutex(hMutex) {}
enum eNameType { AppendPid };
inline CIPMutexSem( WCHAR const * pwszName, eNameType eNT, BOOL bInitialOwner = FALSE, const LPSECURITY_ATTRIBUTES lpsa = 0 );
inline ~CIPMutexSem();
void Request( DWORD dwMilliSeconds = INFINITE );
void Release();
HANDLE GetHandle() const { return _hMutex; }
private:
inline void Init( WCHAR const * pwszName, BOOL bInitialOwner, const LPSECURITY_ATTRIBUTES lpsa );
HANDLE _hMutex;
};
//+---------------------------------------------------------------------------
//
// Member: CIPMutexSem::CIPMutexSem
//
// Synopsis: Constructor for the "opening" of the mutex in a child process.
// The mutex must already have been created by the parent
// process.
//
// Arguments: [dwMustBeZero] - Just to distinguish two constructors.
// [pwszName] - Name of the mutext. MUST NOT BE NULL.
//
// History: 2-02-96 srikants Created
//
//----------------------------------------------------------------------------
inline CIPMutexSem::CIPMutexSem( DWORD dwMustBeZero, WCHAR const * pwszName ) { Win4Assert( 0 != pwszName ); //ciDebugOut(( DEB_ITRACE, "Opening a named (%ws) mutex \n", pwszName ));
_hMutex = OpenMutex( MUTEX_ALL_ACCESS, TRUE, pwszName ); if ( 0 == _hMutex ) { //ciDebugOut(( DEB_ERROR,
// "Failed to open named mutex (%ws). Error 0x%X\n",
// pwszName, GetLastError() ));
THROW( CException() );
} }
//+---------------------------------------------------------------------------
//
// Member: CIPMutexSem::CIPMutexSem
//
// Synopsis: Constructor to "create" a mutex object.
//
// Arguments: [pwszName] - Name of the mutex object. Can be NULL.
// [bInitialOwner] - Set to TRUE if the mutex object is owned
// by the creator immediately after creation.
// [lpsa] - Pointer to the security object. It should
// be a valid pointer to a SECURITY_ATTRIBUTES structure if the
// the mutex handle must be inherited by a child process.
//
// History: 2-02-96 srikants Created
//
//----------------------------------------------------------------------------
inline CIPMutexSem::CIPMutexSem( WCHAR const * pwszName, BOOL bInitialOwner, const LPSECURITY_ATTRIBUTES lpsa ) { Init( pwszName, bInitialOwner, lpsa ); }
//+---------------------------------------------------------------------------
//
// Member: CIPMutexSem::CIPMutexSem
//
// Synopsis: Constructor to "create" a mutex object.
//
// Arguments: [eNt] - Distinguishes from other variants
// [pwszName] - Name of the mutex object. Can be NULL.
// [bInitialOwner] - Set to TRUE if the mutex object is owned
// by the creator immediately after creation.
// [lpsa] - Pointer to the security object. It should
// be a valid pointer to a SECURITY_ATTRIBUTES structure if the
// the mutex handle must be inherited by a child process.
//
// History: 2-02-96 srikants Created
//
//----------------------------------------------------------------------------
inline CIPMutexSem::CIPMutexSem( WCHAR const * pwszName, CIPMutexSem::eNameType eNT, BOOL bInitialOwner, const LPSECURITY_ATTRIBUTES lpsa ) { Win4Assert( eNT == CIPMutexSem::AppendPid );
unsigned ccName = wcslen( pwszName ); WCHAR wcsNewName[MAX_PATH];
RtlCopyMemory( wcsNewName, pwszName, ccName * sizeof(WCHAR) ); _itow( GetCurrentProcessId(), wcsNewName + ccName, 16 );
Init( wcsNewName, bInitialOwner, lpsa ); }
//+---------------------------------------------------------------------------
//
// Member: CIPMutexSem::~CIPMutexSem
//
// Synopsis: Destructor of the CIPMutexSem object.
//
// History: 2-02-96 srikants Created
//
//----------------------------------------------------------------------------
inline CIPMutexSem::~CIPMutexSem() { if ( !CloseHandle(_hMutex) ) { THROW ( CException() ); } }
inline void CIPMutexSem::Request( DWORD dwMilliseconds) { WaitForSingleObject( _hMutex, dwMilliseconds ); }
inline void CIPMutexSem::Release() { if ( !ReleaseMutex( _hMutex ) ) { THROW ( CException() ); } }
inline void CIPMutexSem::Init( WCHAR const * pwszName, BOOL bInitialOwner, const LPSECURITY_ATTRIBUTES lpsa ) { #if CIDBG==1
if ( 0 != pwszName ) { //ciDebugOut(( DEB_ITRACE, "Creating a named (%ws) mutex \n", pwszName ));
} #endif // CIDBG==1
_hMutex = CreateMutex( lpsa, bInitialOwner, pwszName );
if ( 0 == _hMutex ) { //ciDebugOut(( DEB_ERROR,
// "Failed to create a named mutex (%ws). Error 0x%X\n",
// pwszName, GetLastError() ));
THROW( CException() ); } }
//+---------------------------------------------------------------------------
//
// Class: CIPLock
//
// Purpose: An unwindable lock object for the CIPMutexSem object.
//
// History: 1-30-96 srikants Created
//
//----------------------------------------------------------------------------
class CIPLock { public:
CIPLock( CIPMutexSem & mxs ) : _mxs(mxs) { _mxs.Request(); }
~CIPLock() { _mxs.Release(); }
private:
CIPMutexSem & _mxs;
};
//+---------------------------------------------------------------------------
//
// Class: CLocalSystemSharedMemory
//
// Purpose: A class to contruct either a named or un-named shared memory
// to a paging file.
//
// History: 1-30-96 srikants Created
//
// Notes: This class is hard-wide to allow only SYSTEM account access.
//
//----------------------------------------------------------------------------
class CLocalSystemSharedMemory { public:
CLocalSystemSharedMemory( WCHAR const * pwszName = 0, DWORD dwMaxSizeLow = 1024 );
~CLocalSystemSharedMemory() { if (_pBuf) { UnmapViewOfFile( _pBuf ); _pBuf = 0; }
CloseHandle( _hMap ); }
BYTE * Map() { _pBuf = (BYTE *) MapViewOfFile( _hMap, FILE_MAP_ALL_ACCESS, 0, 0, _dwMaxSizeLow ); if ( 0 == _pBuf ) { ciDebugOut(( DEB_ERROR, "Failed to map file. Error 0x%X\n", GetLastError() )); THROW( CException() ); }
return _pBuf; }
BYTE * GetBuf() { return _pBuf; }
DWORD SizeLow() const { return _dwMaxSizeLow; }
HANDLE GetMapHandle() const { return _hMap; }
private:
HANDLE _hMap; // Handle of the shared memory map
DWORD _dwMaxSizeLow; // Maximum size of the region
BYTE * _pBuf; // Pointer to the mapped region
};
//+---------------------------------------------------------------------------
//
// Member: CLocalSystemSharedMemory::CLocalSystemSharedMemory
//
// Synopsis: Constructor for "creating" a shared memory.
//
// Arguments: [pwszName] - Name of the shared memory region. If NULL,
// an unnamed shared memory region will be created.
// [dwMaxSizeLow] - Maximum size of the shared memory region.
//
// History: 2-02-96 srikants Created
// 07-Oct-1999 KyleP Wired to Local SYSTEM account
//
//----------------------------------------------------------------------------
inline CLocalSystemSharedMemory::CLocalSystemSharedMemory( WCHAR const * pwszName, DWORD dwMaxSizeLow ) {
#if CIDBG==1
if ( pwszName ) { ciDebugOut(( DEB_ITRACE, "Creating named shared memory (%ws) \n", pwszName )); } #endif // CIDBG==1
//
// Build a security descriptor for the local system account
//
static SID sidLocalSystem = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID };
int const cbSD = sizeof(SECURITY_DESCRIPTOR) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidLocalSystem);
BYTE abSD[cbSD];
ACL * pAcl = (PACL)(((SECURITY_DESCRIPTOR *)&abSD[0]) + 1); SECURITY_DESCRIPTOR * psd = (SECURITY_DESCRIPTOR *)&abSD[0];
BOOL bRetVal = InitializeAcl( pAcl, // Pointer to the ACL
cbSD - sizeof(SECURITY_DESCRIPTOR), // Size of ACL
ACL_REVISION ); // Revision level of ACL
if (FALSE == bRetVal) { THROW( CException() ); }
bRetVal = AddAccessAllowedAce( pAcl, // Pointer to the ACL
ACL_REVISION, // ACL revision level
FILE_MAP_READ | FILE_MAP_WRITE | GENERIC_ALL | STANDARD_RIGHTS_ALL, // Access Mask
&sidLocalSystem );
if (FALSE == bRetVal) { THROW( CException() ); }
bRetVal = InitializeSecurityDescriptor( psd, // Pointer to SD
SECURITY_DESCRIPTOR_REVISION ); // SD revision
if (FALSE == bRetVal) { THROW( CException() ) }
bRetVal = SetSecurityDescriptorDacl( psd, // Security Descriptor
TRUE, // Dacl present
pAcl, // The Dacl
FALSE ); // Not defaulted
if (FALSE == bRetVal) { THROW( CException() ); }
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), psd, FALSE };
//
// Create file map
//
_hMap = CreateFileMapping( INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, dwMaxSizeLow, pwszName );
if ( 0 == _hMap ) { ciDebugOut(( DEB_ERROR, "Failed to create a mapping. Error - 0x%X\n", GetLastError() )); THROW( CException() ); }
_dwMaxSizeLow = dwMaxSizeLow; _pBuf = 0; }
|