//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1994. // // File: smblock.cxx // // Contents: Shared memory block code // // Classes: // // Functions: // // History: 24-Mar-94 PhilipLa Created // //---------------------------------------------------------------------------- #include <ole2int.h> #include <smblock.hxx> #include <smcreate.hxx> #if DBG == 1 DECLARE_INFOLEVEL(mem); #endif //+--------------------------------------------------------------------------- // // Member: CSharedMemoryBlock::~CSharedMemoryBlock, public // // Synopsis: Destructor // // Returns: Appropriate status code // // History: 25-Apr-94 PhilipLa Created // //---------------------------------------------------------------------------- CSharedMemoryBlock::~CSharedMemoryBlock() { CloseSharedFileMapping(_hMem, _pbBase); } //+------------------------------------------------------------------------- // // Member: CSharedMemoryBlock::Init // // Synopsis: Create/get address of shared memory block. // // Arguments: [pszName] - name of block to allocate // [culSize] - size of block to allocate // // Algorithm: Attempts to open the block first. If this fails then // this creates the block of memory. It then puts the // address of the block as the first bytes of the block. // If the block already exists, the memory is mapped // and then the address is read. The memory is then mapped // to the address. // // History: 03-Nov-93 Ricksa Created // 07-Jan-94 AlexT No security for CHICAGO // // Notes: Counts on some outside synchronization to prevent // a race in the creation of the memory. // //-------------------------------------------------------------------------- SCODE CSharedMemoryBlock::Init( LPWSTR pszName, ULONG culSize, ULONG culCommitSize, void *pvBase, PSECURITY_DESCRIPTOR lpSecDes, BOOL fOKToCreate) { SCODE sc = S_OK; memAssert((_hMem == NULL) && "Attempt to Init CSharedMemoryBlock twice."); //We store a header on the shared memory - this should be // transparent to clients. culSize = culSize + sizeof(CSharedMemHeader); if (fOKToCreate) { // try to create the shared file mapping // creates or opens it for Read/Write access. _fReadWrite = TRUE; _hMem = CreateSharedFileMapping(pszName, culSize, // size of shared mem 0, // map size pvBase, // base addr lpSecDes, // security desc PAGE_READWRITE | SEC_RESERVE, (void **)&_pbBase, // returned base ptr &_fCreated); // created or not } else { // try to open the shared file mapping. // opens it for read only access, base address unspecified. _fReadWrite = FALSE; _fCreated = FALSE; _hMem = OpenSharedFileMapping(pszName, 0, // map size (void **)&_pbBase); // returned base ptr } if (_hMem == NULL) { return HRESULT_FROM_WIN32(GetLastError()); } #if DBG == 1 MEMORY_BASIC_INFORMATION meminf; ULONG cbReal; cbReal = VirtualQuery(_pbBase, &meminf, sizeof(MEMORY_BASIC_INFORMATION)); memDebugOut((DEB_ITRACE, "cbReal == %lu, Mem Info: Base Address %p, Allocation Base %p, AllocationProtect %lx, Region Size %lu, State %lx, Protect %lx, Type %lx\n", cbReal, meminf.BaseAddress, meminf.AllocationBase, meminf.AllocationProtect, meminf.RegionSize, meminf.State, meminf.Protect, meminf.Type)); #endif // Commit the first page void *pvResult; pvResult = VirtualAlloc(_pbBase, culCommitSize, MEM_COMMIT, (_fReadWrite) ? PAGE_READWRITE : PAGE_READONLY); if (pvResult == NULL) { sc = GetScode(HRESULT_FROM_WIN32(GetLastError())); memDebugOut((DEB_ERROR, "CSharedMemoryBlock::Commit of %lu bytes" " failed with %lx\n", culCommitSize, sc)); return sc; } #if DBG == 1 cbReal = VirtualQuery(_pbBase, &meminf, sizeof(MEMORY_BASIC_INFORMATION)); memDebugOut((DEB_ITRACE, "cbReal == %lu, Mem Info: Base Address %p, Allocation Base %p, AllocationProtect %lx, Region Size %lu, State %lx, Protect %lx, Type %lx\n", cbReal, meminf.BaseAddress, meminf.AllocationBase, meminf.AllocationProtect, meminf.RegionSize, meminf.State, meminf.Protect, meminf.Type)); #endif _culCommitSize = culCommitSize; _culInitCommitSize = culCommitSize; //If we created the block, mark the size in the header. if (_fCreated) { ((CSharedMemHeader *)_pbBase)->SetSize(_culCommitSize); } else { sc = Sync(); } return sc; } #ifdef RESETOK //+--------------------------------------------------------------------------- // // Member: CSharedMemoryBlock::Reset, public // // Synopsis: Reset the shared memory block to its original empty state // // Arguments: None. // // Returns: Appropriate status code // // History: 04-Apr-94 PhilipLa Created // //---------------------------------------------------------------------------- SCODE CSharedMemoryBlock::Reset(void) { #if DBG == 1 BOOL b; #endif void *pv; memDebugOut((DEB_ITRACE, "In CSharedMemoryBlock::Reset:%p()\n", this)); #if DBG == 1 b = #endif VirtualFree(_pbBase, _culCommitSize, MEM_DECOMMIT); memAssert(b && "VirtualFree failed."); #if DBG == 1 if (b == NULL) { memDebugOut((DEB_ERROR, "VirtualFree failed with %lx\n", GetLastError())); } #endif pv = VirtualAlloc(_pbBase, , _culInitCommitSize, MEM_COMMIT, (_fReadWrite) ? PAGE_READWRITE : PAGE_READONLY); if (pv == NULL) { SCODE sc = GetScode(HRESULT_FROM_WIN32(GetLastError())); memDebugOut((DEB_ERROR, "CSharedMemoryBlock::Commit of %lu bytes" " failed with %lx\n", _culInitCommitSize, sc)); return sc; } _culCommitSize = _culInitCommitSize; ((CSharedMemHeader *)_pbBase)->SetSize(_culCommitSize); memDebugOut((DEB_ITRACE, "Out CSharedMemoryBlock::Reset\n")); return S_OK; } #endif //RESETOK //+--------------------------------------------------------------------------- // // Member: CSharedMemoryBlock::Commit, public // // Synopsis: Commit the given number of bytes within the block // // Arguments: [culNewSize] -- Number of bytes to commit // // Returns: Appropriate status code // // History: 29-Mar-94 PhilipLa Created // //---------------------------------------------------------------------------- SCODE CSharedMemoryBlock::Commit(ULONG culNewSize) { SCODE sc = S_OK; culNewSize = culNewSize + sizeof(CSharedMemHeader); memAssert((culNewSize >= _culCommitSize) && "Attempted to shrink shared memory heap."); if (culNewSize == _culCommitSize) { return sc; } void *pb; pb = VirtualAlloc(_pbBase, culNewSize, MEM_COMMIT, (_fReadWrite) ? PAGE_READWRITE : PAGE_READONLY); if (pb == NULL) { sc = GetScode(HRESULT_FROM_WIN32(GetLastError())); memDebugOut((DEB_ERROR, "CSharedMemoryBlock::Commit of %lu bytes failed with %lx\n", culNewSize, sc)); } else { _culCommitSize = culNewSize; //If the new size is greater than the maximum committed size, // update the maximum committed size. CSharedMemHeader *psmh = (CSharedMemHeader *)_pbBase; if (_culCommitSize > psmh->GetSize()) { psmh->SetSize(_culCommitSize); } } #if DBG == 1 MEMORY_BASIC_INFORMATION meminf; ULONG cbReal; cbReal = VirtualQuery(_pbBase, &meminf, sizeof(MEMORY_BASIC_INFORMATION)); memDebugOut((DEB_ITRACE, "Commit size == %lu, cbReal == %lu, Mem Info: Base Address %p, Allocation Base %p, AllocationProtect %lx, Region Size %lu, State %lx, Protect %lx, Type %lx\n", _culCommitSize, cbReal, meminf.BaseAddress, meminf.AllocationBase, meminf.AllocationProtect, meminf.RegionSize, meminf.State, meminf.Protect, meminf.Type)); if (cbReal != sizeof(MEMORY_BASIC_INFORMATION)) { memDebugOut((DEB_ERROR, "Virtual Query error: %lx\n", GetLastError())); } #endif return sc; } //+--------------------------------------------------------------------------- // // Member: CSharedMemoryBlock::Sync, public // // Synopsis: Match committed view to largest committed view // // Arguments: None. // // Returns: Appropriate status code // // History: 29-Mar-94 PhilipLa Created // //---------------------------------------------------------------------------- SCODE CSharedMemoryBlock::Sync(void) { CSharedMemHeader *psmh = (CSharedMemHeader *)_pbBase; ULONG culSize = psmh->GetSize(); if (culSize != _culCommitSize) { return Commit(culSize - sizeof(CSharedMemHeader)); } return S_OK; }