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.
 
 
 
 
 
 

513 lines
15 KiB

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