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.
 
 
 
 
 
 

353 lines
12 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 2002.
//
// File : SMem.hxx
//
// Contents : Shared memory (named + file based)
//
// Classes : CNamedSharedMem
//
// History: 22-Mar-94 t-joshh Created
//
//----------------------------------------------------------------------------
#pragma once
#include <secutil.hxx>
//+---------------------------------------------------------------------------
//
// Class: CNamedSharedMem
//
// Purpose: Named shared memory
//
// History: 22-Mar-94 t-joshh Created
//
//----------------------------------------------------------------------------
class CNamedSharedMem
{
public:
inline CNamedSharedMem( WCHAR const * pwszName, ULONG cb, SECURITY_DESCRIPTOR * psd = 0, BOOL fWrite = TRUE );
CNamedSharedMem()
: _hMap( 0 ),
_pb( 0 )
{
}
enum eNameType { AppendPid };
CNamedSharedMem( WCHAR const * pwszName, eNameType eNT, ULONG cb )
: _hMap( 0 ),
_pb( 0 )
{
Win4Assert( eNT == CNamedSharedMem::AppendPid );
unsigned ccName = wcslen( pwszName );
WCHAR wcsNewName[MAX_PATH];
RtlCopyMemory( wcsNewName, pwszName, ccName * sizeof(WCHAR) );
_itow( GetCurrentProcessId(), wcsNewName + ccName, 16 );
Init( wcsNewName, cb, 0 );
}
~CNamedSharedMem()
{
if ( 0 != _pb )
UnmapViewOfFile( _pb );
if ( 0 != _hMap )
CloseHandle( _hMap );
}
BYTE * GetPointer() { return _pb; }
BYTE * Get() { return _pb; }
BOOL Ok() { return ( 0 != _pb ); }
inline void Init( WCHAR const * pwszName, ULONG cb, SECURITY_DESCRIPTOR * psd = 0, BOOL fWrite = TRUE );
void CreateForWriteFromRegKey( WCHAR const * pwszName,
ULONG cb,
WCHAR const * pwcRegKey )
{
Win4Assert( 0 == _hMap );
Win4Assert( 0 == _pb );
Win4Assert( 0 != pwcRegKey );
_hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
0, // Security attributes
PAGE_READWRITE, // Page-level protection
0, // Size high
cb, // size low
pwszName ); // Name
if ( 0 == _hMap )
THROW( CException() );
DWORD dwErr = CopyNamedDacls( pwszName, pwcRegKey );
if ( NO_ERROR != dwErr )
THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
_pb = (BYTE *) MapViewOfFile( _hMap, // Handle to map
FILE_MAP_WRITE, // Access
0, // Offset (high)
0, // Offset (low)
0 ); // Map all
if ( 0 == _pb )
{
DWORD dwErr = GetLastError();
CloseHandle( _hMap );
_hMap = 0;
THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
}
}
void CreateForWriteFromSA( WCHAR const * pwszName,
ULONG cb,
SECURITY_ATTRIBUTES & sa )
{
Win4Assert( 0 == _hMap );
Win4Assert( 0 == _pb );
_hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
&sa, // Security attributes
PAGE_READWRITE, // Page-level protection
0, // Size high
cb, // size low
pwszName ); // Name
if ( 0 == _hMap )
THROW( CException() );
_pb = (BYTE *) MapViewOfFile( _hMap, // Handle to map
FILE_MAP_WRITE, // Access
0, // Offset (high)
0, // Offset (low)
0 ); // Map all
if ( 0 == _pb )
{
DWORD dwErr = GetLastError();
CloseHandle( _hMap );
_hMap = 0;
THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
}
}
BOOL OpenForRead( WCHAR const * pwszName )
{
Win4Assert( 0 == _hMap );
Win4Assert( 0 == _pb );
//
// Note: you have to ask for PAGE_READWRITE even though we only want
// PAGE_READ, otherwise you get ERROR_ACCESS_DENIED. I don't know
// why, but since only a limited # of contexts have write access,
// it should be OK.
//
_hMap = OpenFileMapping( PAGE_READWRITE, // Access
FALSE, // Inherit
pwszName ); // Name
if ( 0 == _hMap )
{
if ( ERROR_FILE_NOT_FOUND == GetLastError() )
return FALSE;
THROW( CException() );
}
_pb = (BYTE *) MapViewOfFile( _hMap,
FILE_MAP_READ, // Access
0, // Offset (high)
0, // Offset (low)
0 ); // Map all
if ( 0 == _pb )
{
DWORD dwErr = GetLastError();
CloseHandle( _hMap );
_hMap = 0;
THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
}
return TRUE;
}
private:
HANDLE _hMap;
BYTE * _pb;
};
//+---------------------------------------------------------------------------
//
// Member: CNamedSharedMem::CNamedSharedMem, public
//
// Synopsis: Create/Open named shared memory
//
// Arguments: [pwszName] -- Name of shared memory region
// [cb] -- Size of shared memory region
// [psd] -- Security
// [fWrite] -- TRUE if write-access is required
//
// History: 06-Oct-1999 KyleP Heavily modified
//
//----------------------------------------------------------------------------
inline CNamedSharedMem::CNamedSharedMem( WCHAR const * pwszName,
ULONG cb,
SECURITY_DESCRIPTOR * psd,
BOOL fWrite )
: _hMap( 0 ),
_pb( 0 )
{
//
// Create null security descriptor, if needed
//
struct
{
SECURITY_DESCRIPTOR _sdMaxAccess;
BYTE _sdExtra[SECURITY_DESCRIPTOR_MIN_LENGTH];
} sd;
if ( 0 == psd )
{
if ( !InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ) )
{
THROW( CException() );
}
if ( !SetSecurityDescriptorDacl( &sd._sdMaxAccess,// Security descriptor
TRUE, // Discretionary ACL
0, // The null ACL (all access)
FALSE ) ) // Not a default disc. ACL
{
THROW( CException() );
}
psd = &sd._sdMaxAccess;
}
Init( pwszName, cb, psd, fWrite );
}
//+---------------------------------------------------------------------------
//
// Member: CNamedSharedMem::Init, public
//
// Synopsis: Create/Open named shared memory
//
// Arguments: [pwszName] -- Name of shared memory region
// [cb] -- Size of shared memory region
// [psd] -- Security
// [fWrite] -- TRUE if write-access is required
//
// History: 06-Oct-1999 KyleP Heavily modified
//
//----------------------------------------------------------------------------
void CNamedSharedMem::Init( WCHAR const * pwszName,
ULONG cb,
SECURITY_DESCRIPTOR * psd,
BOOL fWrite )
{
Win4Assert( 0 == _hMap );
Win4Assert( 0 == _pb );
//Win4Assert( 0 == psd ); // Handy assert to enable to analyze security problems.
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES),
psd,
FALSE };
//
// Set up flags
//
DWORD dwCFMMode;
DWORD dwMVoFMode;
if ( fWrite )
{
dwCFMMode = PAGE_READWRITE;
dwMVoFMode = FILE_MAP_WRITE;
}
else
{
dwCFMMode = PAGE_READWRITE; // make it so that others can map for write
dwMVoFMode = FILE_MAP_READ;
}
_hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
&sa, // Security attributes
dwCFMMode, // Page-level protection
0, // Size high
cb, // size low
pwszName ); // Name
#if 0
if ( 0 != psd )
{
BYTE ab[1000];
DWORD dwl;
BOOL fOk = GetKernelObjectSecurity( _hMap, // handle to object
FILE_MAP_WRITEDACL_SECURITY_INFORMATION, // request
(SECURITY_DESCRIPTOR *)&ab[0], // SD
sizeof(ab), // size of SD
&dwl ); // required size of buffer
Win4Assert( fOk );
Win4Assert( !fOk );
ciDebugOut(( DEB_ERROR, "pb = 0x%x\n", &ab[0] ));
Win4Assert( !fOk );
//HANDLE hTemp = OpenFileMapping( PAGE_READONLY, // Access
// FALSE, // Inherit
// pwszName ); // Name
HANDLE hTemp = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
&sa, // Security attributes
PAGE_READONLY, // Page-level protection
0, // Size high
cb, // size low
pwszName ); // Name
Win4Assert( 0 != hTemp );
BYTE * pbTemp = (BYTE *) MapViewOfFile( hTemp, // Handle to map
FILE_MAP_READ, // Access
0, // Offset (high)
0, // Offset (low)
0 ); // Map all
Win4Assert( 0 != pbTemp );
UnmapViewOfFile( pbTemp );
CloseHandle( hTemp );
}
#endif
if ( 0 != _hMap )
_pb = (BYTE *) MapViewOfFile( _hMap, // Handle to map
dwMVoFMode, // Access
0, // Offset (high)
0, // Offset (low)
0 ); // Map all
}