306 lines
5.5 KiB
C++
306 lines
5.5 KiB
C++
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
sharedat.cxx
|
|
|
|
Abstract:
|
|
|
|
Shared data implementation.
|
|
|
|
Author:
|
|
|
|
Albert Ting (AlbertT) 5-Oct-1997
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "spllibp.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "sharedat.hxx"
|
|
|
|
LPCTSTR szSuffixFile = SZ_SUFFIX_FILE;
|
|
|
|
|
|
/********************************************************************
|
|
|
|
TShareData::TBase
|
|
|
|
Base functionality common to both TReadWrite and TRead.
|
|
|
|
********************************************************************/
|
|
|
|
TShareData::
|
|
TBase::
|
|
TBase(
|
|
VOID
|
|
) : m_hMap( NULL ), m_pData( NULL )
|
|
{
|
|
}
|
|
|
|
VOID
|
|
TShareData::
|
|
TBase::
|
|
vCleanup(
|
|
VOID
|
|
)
|
|
{
|
|
if( m_pData )
|
|
{
|
|
UnmapViewOfFile( m_pData );
|
|
m_pData = NULL;
|
|
}
|
|
|
|
if( m_hMap )
|
|
{
|
|
CloseHandle( m_hMap );
|
|
m_hMap = NULL;
|
|
}
|
|
}
|
|
|
|
TShareData::
|
|
TBase::
|
|
~TBase(
|
|
VOID
|
|
)
|
|
{
|
|
vCleanup();
|
|
}
|
|
|
|
BOOL
|
|
TShareData::
|
|
TBase::
|
|
bGetFullName(
|
|
LPCTSTR pszName,
|
|
LPTSTR pszFullName
|
|
)
|
|
{
|
|
UINT cchName;
|
|
//
|
|
// Validate input and determine the size of the name.
|
|
//
|
|
if( !pszName || !pszName[0] || ( cchName = lstrlen( pszName )) >= MAX_PATH )
|
|
{
|
|
SetLastError( ERROR_INVALID_NAME );
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Create shared file object.
|
|
//
|
|
lstrcpy( pszFullName, pszName );
|
|
lstrcpy( &pszFullName[cchName], szSuffixFile );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
TShareData::TReadWrite
|
|
|
|
Class that allows user to read and write a shared data object.
|
|
Since there is only one valid writer, the vWriteBegin and
|
|
vWriteEnd functions are rolled up together here.
|
|
|
|
********************************************************************/
|
|
|
|
TShareData::
|
|
TReadWrite::
|
|
TReadWrite(
|
|
IN LPCTSTR pszName,
|
|
IN DWORD cbSize,
|
|
IN PSECURITY_ATTRIBUTES pSA
|
|
) : TBase()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create a shared data access object.
|
|
|
|
Arguments:
|
|
|
|
pszName - Name of shared memory object.
|
|
|
|
pSA - Security attributes.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR szFullName[kNameBufferMax];
|
|
|
|
if( bGetFullName( pszName, szFullName ))
|
|
{
|
|
m_hMap = CreateFileMapping( INVALID_HANDLE_VALUE,
|
|
pSA,
|
|
PAGE_READWRITE,
|
|
0,
|
|
sizeof( TData ) + cbSize,
|
|
szFullName );
|
|
|
|
if( m_hMap )
|
|
{
|
|
m_pData = (pTData)MapViewOfFile( m_hMap,
|
|
FILE_MAP_WRITE,
|
|
0,
|
|
0,
|
|
0 );
|
|
m_pData->cbSize = cbSize;
|
|
|
|
//
|
|
// Put ourselves in an inconsistent state so that clients won't
|
|
// read bad data. The callee must call vWriteFirst() after
|
|
// the first initialization.
|
|
//
|
|
m_pData->lCount2 = m_pData->lCount1 + 1;
|
|
}
|
|
}
|
|
|
|
//
|
|
// m_pData is our valid check. If this variable is NULL
|
|
// then the object wasn't created correctly.
|
|
//
|
|
}
|
|
|
|
VOID
|
|
TShareData::
|
|
TReadWrite::
|
|
vWriteFirst(
|
|
VOID
|
|
)
|
|
{
|
|
m_pData->lCount1 = m_pData->lCount2 = 0;
|
|
}
|
|
|
|
VOID
|
|
TShareData::
|
|
TReadWrite::
|
|
vWriteBegin(
|
|
VOID
|
|
)
|
|
{
|
|
InterlockedIncrement( &m_pData->lCount2 );
|
|
}
|
|
|
|
VOID
|
|
TShareData::
|
|
TReadWrite::
|
|
vWriteEnd(
|
|
VOID
|
|
)
|
|
{
|
|
InterlockedIncrement( &m_pData->lCount1 );
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
|
TShareData::TRead
|
|
|
|
Read-only class. Since there can be multiple readers, the
|
|
reader instance is separated out into a TReadSync class.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
TShareData::
|
|
TRead::
|
|
TRead(
|
|
IN LPCTSTR pszName,
|
|
IN DWORD cbSize
|
|
) : TBase()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create a shared data access object.
|
|
|
|
Arguments:
|
|
|
|
pszName - Name of shared memory object.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR szFullName[kNameBufferMax];
|
|
|
|
if( bGetFullName( pszName, szFullName ))
|
|
{
|
|
m_hMap = OpenFileMapping( FILE_MAP_READ,
|
|
FALSE,
|
|
szFullName );
|
|
|
|
if( m_hMap )
|
|
{
|
|
m_pData = (pTData)MapViewOfFile( m_hMap,
|
|
FILE_MAP_READ,
|
|
0,
|
|
0,
|
|
0 );
|
|
if( m_pData )
|
|
{
|
|
if( m_pData->cbSize < cbSize )
|
|
{
|
|
vCleanup();
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// m_pData is our valid check. If this variable is NULL
|
|
// then the object wasn't created correctly.
|
|
//
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
|
TShareData::TReadSync
|
|
|
|
Synchronizes a read instance from a TShareData::Read object.
|
|
There can be multiple TReadSyncs running concurrently for a
|
|
given TShareData::Read object.
|
|
|
|
********************************************************************/
|
|
|
|
TShareData::
|
|
TReadSync::
|
|
TReadSync(
|
|
TRead& Read
|
|
) : m_Read( Read )
|
|
{
|
|
}
|
|
|
|
VOID
|
|
TShareData::
|
|
TReadSync::
|
|
vReadBegin(
|
|
VOID
|
|
)
|
|
{
|
|
m_lCount = m_Read.m_pData->lCount1;
|
|
}
|
|
|
|
BOOL
|
|
TShareData::
|
|
TReadSync::
|
|
bReadEnd(
|
|
VOID
|
|
)
|
|
{
|
|
return m_Read.m_pData->lCount2 == m_lCount;
|
|
}
|
|
|