windows-nt/Source/XPSP1/NT/printscan/ui/uicommon/shmemsec.h
2020-09-26 16:20:57 +08:00

227 lines
6 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 1998
*
* TITLE: SHMEMSEC.H
*
* VERSION: 1.0
*
* AUTHOR: ShaunIv
*
* DATE: 9/30/1999
*
* DESCRIPTION: Simple shared memory section template. Don't use it for classes!
* Basically, simple objects only. structs are ok. Nothing with a
* vtable.
*
*******************************************************************************/
#ifndef __SHMEMSEC_H_INCLUDED
#define __SHMEMSEC_H_INCLUDED
#include <windows.h>
#include <simstr.h>
#include <miscutil.h>
template <class T>
class CSharedMemorySection
{
public:
enum COpenResult
{
SmsFailed,
SmsCreated,
SmsOpened
};
private:
HANDLE m_hMutex;
HANDLE m_hFileMapping;
T *m_pMappedSection;
private:
//
// Not implemented
//
CSharedMemorySection( const CSharedMemorySection & );
CSharedMemorySection &operator=( const CSharedMemorySection & );
public:
CSharedMemorySection( LPCTSTR pszName=NULL, bool bAllowCreate=true )
: m_hFileMapping(NULL),
m_pMappedSection(NULL),
m_hMutex(NULL)
{
WIA_PUSHFUNCTION(TEXT("CSharedMemorySection::CSharedMemorySection"));
Open(pszName,bAllowCreate);
}
~CSharedMemorySection(void)
{
WIA_PUSHFUNCTION(TEXT("CSharedMemorySection::~CSharedMemorySection"));
Close();
}
bool OK(void)
{
return(m_pMappedSection != NULL);
}
T *Lock(void)
{
T *pResult = NULL;
if (OK())
{
if (WiaUiUtil::MsgWaitForSingleObject( m_hMutex, INFINITE ))
{
pResult = m_pMappedSection;
}
}
return pResult;
}
void Release(void)
{
if (OK())
{
ReleaseMutex(m_hMutex);
}
}
COpenResult Open( LPCTSTR pszName, bool bAllowCreate=true )
{
//
// Close any previous instances
//
Close();
//
// Assume failure
//
COpenResult orResult = SmsFailed;
//
// Make sure we have a valid name
//
if (pszName && *pszName)
{
//
// Save the name
//
CSimpleString strSectionName = pszName;
//
// Replace any invalid characters
//
for (int i=0;i<(int)strSectionName.Length();i++)
{
if (strSectionName[i] == TEXT('\\'))
{
strSectionName[i] = TEXT('-');
}
}
//
// Create the mutex name
//
CSimpleString strMutex(strSectionName);
strMutex += TEXT("-Mutex");
//
// Try to create the mutex
//
m_hMutex = CreateMutex( NULL, FALSE, strMutex );
if (m_hMutex)
{
//
// Take ownership of the mutex
//
if (WiaUiUtil::MsgWaitForSingleObject( m_hMutex, INFINITE ))
{
//
// If this file mapping already exists, open it.
//
m_hFileMapping = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, strSectionName );
if (m_hFileMapping)
{
m_pMappedSection = reinterpret_cast<T*>(MapViewOfFile( m_hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(T) ));
orResult = SmsOpened;
}
else if (bAllowCreate)
{
//
// Create the file mapping
//
m_hFileMapping = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(T), strSectionName );
if (m_hFileMapping)
{
//
// Try to acquire the file mapping
//
m_pMappedSection = reinterpret_cast<T*>(MapViewOfFile( m_hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(T) ));
if (m_pMappedSection)
{
//
// Initialize the data
//
ZeroMemory( m_pMappedSection, sizeof(T) );
orResult = SmsCreated;
}
}
}
//
// Release the mutex
//
ReleaseMutex(m_hMutex);
}
}
}
//
// If we weren't able to map the file mapping section, we need to clean up
//
if (!m_pMappedSection)
{
Close();
}
return(orResult);
}
void Close(void)
{
//
// First, try to delete it safely.
//
if (m_hMutex)
{
if (WiaUiUtil::MsgWaitForSingleObject( m_hMutex, INFINITE ))
{
if (m_pMappedSection)
{
UnmapViewOfFile(m_pMappedSection);
m_pMappedSection = NULL;
}
if (m_hFileMapping)
{
CloseHandle(m_hFileMapping);
m_hFileMapping = NULL;
}
ReleaseMutex(m_hMutex);
}
}
//
// Then, just clean up
//
if (m_pMappedSection)
{
UnmapViewOfFile(m_pMappedSection);
m_pMappedSection = NULL;
}
if (m_hFileMapping)
{
CloseHandle(m_hFileMapping);
m_hFileMapping = NULL;
}
if (m_hMutex)
{
CloseHandle(m_hMutex);
m_hMutex = NULL;
}
}
};
#endif