229 lines
5.2 KiB
C++
229 lines
5.2 KiB
C++
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
sharemem.cxx
|
|
|
|
Abstract:
|
|
|
|
Shared memory implementation.
|
|
|
|
Author:
|
|
|
|
Albert Ting (AlbertT) 17-Dec-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "sharemem.hxx"
|
|
|
|
#ifdef COUNTOF
|
|
#undef COUNTOF
|
|
#endif
|
|
#define COUNTOF(x) (sizeof(x)/sizeof(*x))
|
|
|
|
LPCTSTR szPrefixFile = TEXT( "_ShrMemF" );
|
|
LPCTSTR szPrefixMutex = TEXT( "_ShrMemM" );
|
|
|
|
TShareMem::
|
|
TShareMem(
|
|
IN UINT uSize,
|
|
IN LPCTSTR pszName,
|
|
IN UINT uFlags,
|
|
IN PSECURITY_ATTRIBUTES psa, OPTIONAL
|
|
OUT PUINT puSizeDisposition OPTIONAL
|
|
) : m_hFile( NULL ), m_hMutex( NULL ), m_pvBase( NULL ),
|
|
m_pvUserData( NULL )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create a shared memory access object.
|
|
|
|
Arguments:
|
|
|
|
uSize - Size of the buffer requested.
|
|
|
|
pszName - Name of shared memory object.
|
|
|
|
uFlags - Options
|
|
|
|
kCreate - Create a new file mapping. If the mapping already
|
|
exists, it will be used (see puSizeDisposition). If
|
|
not specified, an existing one will be opened.
|
|
kReadWrite - Open with ReadWrite access. If not specified,
|
|
Read only access is used.
|
|
|
|
psa - Pointer to security attributes. Used only if kCreate specified.
|
|
|
|
puSizeDisposition - If the object already exists, returns its
|
|
size. If the object did not exist, returns zero.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
UINT cchName;
|
|
|
|
//
|
|
// Validate input and determine the size of the name.
|
|
//
|
|
if( !uSize || !pszName || !pszName[0] ||
|
|
( cchName = lstrlen( pszName )) >= MAX_PATH )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
return;
|
|
}
|
|
|
|
DWORD dwAccess = ( uFlags & kReadWrite ) ?
|
|
FILE_MAP_READ | FILE_MAP_WRITE :
|
|
FILE_MAP_READ;
|
|
|
|
//
|
|
// Pre-initialize output variables.
|
|
//
|
|
|
|
UINT uSizeDispositionDiscard;
|
|
|
|
if( !puSizeDisposition )
|
|
{
|
|
puSizeDisposition = &uSizeDispositionDiscard;
|
|
}
|
|
*puSizeDisposition = 0;
|
|
|
|
//
|
|
// Create or shared mutex that will protect the data. Create
|
|
// the new name. This needs to be created first to protect
|
|
// against multiple people trying to create the file mapping
|
|
// simultaneously.
|
|
//
|
|
TCHAR szFullName[MAX_PATH + max( COUNTOF( szPrefixFile ),
|
|
COUNTOF( szPrefixMutex ))];
|
|
lstrcpy( szFullName, pszName );
|
|
lstrcpy( &szFullName[cchName], szPrefixMutex );
|
|
m_hMutex = CreateMutex( psa,
|
|
FALSE,
|
|
szFullName );
|
|
|
|
if( !m_hMutex )
|
|
{
|
|
return;
|
|
}
|
|
|
|
{
|
|
//
|
|
// Acquire the mutex for use while we're grabbing the resource.
|
|
//
|
|
WaitForSingleObject( m_hMutex, INFINITE );
|
|
|
|
BOOL bFileExists = TRUE;
|
|
|
|
//
|
|
// Create the name of the mapped file.
|
|
//
|
|
lstrcpy( &szFullName[cchName], szPrefixFile );
|
|
|
|
//
|
|
// Either open or create the map file handle.
|
|
//
|
|
if( uFlags & kCreate )
|
|
{
|
|
//
|
|
// Create a new map.
|
|
//
|
|
m_hFile = CreateFileMapping( INVALID_HANDLE_VALUE,
|
|
psa,
|
|
( uFlags & kReadWrite ) ?
|
|
PAGE_READWRITE :
|
|
PAGE_READONLY,
|
|
0,
|
|
uSize,
|
|
szFullName );
|
|
|
|
//
|
|
// See if it already exists.
|
|
//
|
|
if( GetLastError() != ERROR_ALREADY_EXISTS )
|
|
{
|
|
bFileExists = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Open existing map.
|
|
//
|
|
m_hFile = OpenFileMapping( dwAccess,
|
|
FALSE,
|
|
szFullName );
|
|
}
|
|
|
|
if( m_hFile )
|
|
{
|
|
|
|
//
|
|
// Map the file into our address space.
|
|
//
|
|
m_pvBase = MapViewOfFile( m_hFile,
|
|
dwAccess,
|
|
0,
|
|
0,
|
|
0 );
|
|
|
|
if( m_pvBase )
|
|
{
|
|
if( bFileExists )
|
|
{
|
|
*puSizeDisposition = GetHeader().uSize;
|
|
}
|
|
else
|
|
{
|
|
GetHeader().uHeaderSize = sizeof( HEADER );
|
|
GetHeader().uSize = uSize;
|
|
}
|
|
|
|
m_pvUserData = reinterpret_cast<PBYTE>( m_pvBase ) +
|
|
GetHeader().uHeaderSize;
|
|
}
|
|
}
|
|
|
|
ReleaseMutex( m_hMutex );
|
|
}
|
|
|
|
//
|
|
// m_pvUserData is our valid check. If this variable is NULL
|
|
// then the object wasn't created correctly.
|
|
//
|
|
}
|
|
|
|
TShareMem::
|
|
~TShareMem(
|
|
VOID
|
|
)
|
|
{
|
|
if( m_hMutex )
|
|
{
|
|
CloseHandle( m_hMutex );
|
|
}
|
|
|
|
if( m_pvBase )
|
|
{
|
|
UnmapViewOfFile( m_pvBase );
|
|
}
|
|
|
|
if( m_hFile )
|
|
{
|
|
CloseHandle( m_hFile );
|
|
}
|
|
}
|
|
|