WindowsXP-SP1/windows/oleacc/oleacc/memchk.cpp
2020-09-30 16:53:49 +02:00

361 lines
9.7 KiB
C++

// Copyright (c) 1996-2000 Microsoft Corporation
// --------------------------------------------------------------------------
//
// MEMCHK.CPP
//
// Simple new/delete counting error checking library
//
// --------------------------------------------------------------------------
#include "oleacc_p.h"
#include "default.h"
#include "w95trace.h"
#include "memchk.h"
#ifdef _DEBUG
struct MemInfo
{
LONG m_NumAlloc;
LONG m_NumFree;
};
// Two MemInfo structures - one for allocations through new/delete,
// one for allocations through SharedAlloc/SharedFree
MemInfo g_MemInfo;
MemInfo g_SharedMemInfo;
#endif // _DEBUG
#ifndef _DEBUG
// Non-_DEBUG new/delete call-through to LocalAlloc/Free...
// --------------------------------------------------------------------------
//
// new()
//
// We implement this ourself to avoid pulling in the C++ runtime.
//
// --------------------------------------------------------------------------
void * __cdecl operator new(size_t nSize)
{
// Zero init just to save some headaches
return (void *)LocalAlloc(LPTR, nSize);
}
// --------------------------------------------------------------------------
//
// delete()
//
// We implement this ourself to avoid pulling in the C++ runtime.
//
// --------------------------------------------------------------------------
void __cdecl operator delete(void *pv)
{
LocalFree((HLOCAL)pv);
}
// --------------------------------------------------------------------------
//
// SharedAlloc()
//
// This allocates out of the shared heap on Win '95. On NT, we need to
// use VirtualAllocEx to allocate memory in the other process. The caller
// of SharedAlloc will need to then use ReadProcessMemory to read the data
// from the VirtualAlloc'ed memory. What I am going to do is create 2 new
// functions - SharedRead and SharedWrite, that will read and write shared
// memory. On Win95, they will just use CopyMemory, but on NT they will use
// ReadProcessMemory and WriteProcessMemory.
//
// Parameters:
// UINT cbSize Size of the memory block required
// HWND hwnd Window handle in the process to allocate
// the shared memory in.
// HANDLE* pProcHandle Pointer to a handle that has the process
// handle filled in on return. This must be saved
// for use in calls to SharedRead, SharedWrite,
// and SharedFree.
//
// Returns:
// Pointer to the allocated memory, or NULL if it fails. Access to the
// memory must be done using SharedRead and SharedWrite. On success,
// pProcHandle is filled in as well.
//
// --------------------------------------------------------------------------
LPVOID SharedAlloc(UINT cbSize,HWND hwnd,HANDLE *pProcessHandle)
{
#ifndef NTONLYBUILD
if (fWindows95)
return(HeapAlloc(hheapShared, HEAP_ZERO_MEMORY, cbSize));
else
#endif // NTONLYBUILD
{
DWORD dwProcessId;
if( ! GetWindowThreadProcessId( hwnd, & dwProcessId ) )
return NULL;
HANDLE hProcess = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
FALSE,dwProcessId );
if( ! hProcess )
return NULL;
LPVOID pv = MyVirtualAllocEx( hProcess, NULL, cbSize, MEM_COMMIT, PAGE_READWRITE );
if( ! pv )
{
CloseHandle( hProcess );
return NULL;
}
if( pProcessHandle )
*pProcessHandle = hProcess;
return pv;
}
}
// --------------------------------------------------------------------------
//
// SharedFree()
//
// This frees shared memory.
//
// --------------------------------------------------------------------------
VOID SharedFree(LPVOID lpv,HANDLE hProcess)
{
#ifndef NTONLYBUILD
if (fWindows95)
HeapFree(hheapShared, 0, lpv);
else
#endif // NTONLYBUILD
{
MyVirtualFreeEx(hProcess,lpv,0,MEM_RELEASE);
CloseHandle (hProcess);
}
}
// 'Empty' functions to keep compiler/linker happy in case client
// calls these in non _DEBUG code...
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
void InitMemChk()
{
// Do nothing
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
void UninitMemChk()
{
// Do nothing
}
#else // _DEBUG #############################################################
// --------------------------------------------------------------------------
// DEBUG new - increments new count, calls through to LocalAlloc...
// --------------------------------------------------------------------------
void * __cdecl operator new(unsigned int nSize)
{
// Zero init just to save some headaches
void * pv = (void *)LocalAlloc(LPTR, nSize);
if( ! pv )
{
return NULL;
}
// Update statistics...
InterlockedIncrement( & g_MemInfo.m_NumAlloc );
// return pointer to alloc'd space...
return pv;
}
// --------------------------------------------------------------------------
// DEBUG delete - increments delete count, calls through to LocalFree...
// --------------------------------------------------------------------------
void __cdecl operator delete(void *pv)
{
// C++ allows 'delete NULL'...
if( pv == NULL )
return;
// Update statistics...
InterlockedIncrement( & g_MemInfo.m_NumFree );
LocalFree((HLOCAL)pv);
}
// --------------------------------------------------------------------------
//
// DEBUG SharedAlloc()
//
// Does alloc, updates count.
// --------------------------------------------------------------------------
LPVOID SharedAlloc(UINT cbSize,HWND hwnd,HANDLE *pProcessHandle)
{
#ifndef NTONLYBUILD
if (fWindows95)
{
// Update statistics...
InterlockedIncrement( & g_SharedMemInfo.m_NumAlloc );
return(HeapAlloc(hheapShared, HEAP_ZERO_MEMORY, cbSize));
}
else
#endif // NTONLYBUILD
{
DWORD dwProcessId;
if( ! GetWindowThreadProcessId( hwnd, & dwProcessId ) )
return NULL;
HANDLE hProcess = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
FALSE,dwProcessId );
if( ! hProcess )
return NULL;
LPVOID pv = MyVirtualAllocEx( hProcess, NULL, cbSize, MEM_COMMIT, PAGE_READWRITE );
if( ! pv )
{
CloseHandle( hProcess );
return NULL;
}
// Update statistics...
InterlockedIncrement( & g_SharedMemInfo.m_NumAlloc );
if( pProcessHandle )
*pProcessHandle = hProcess;
return pv;
}
}
// --------------------------------------------------------------------------
//
// DEBUG SharedFree()
//
// frees shared memory, updates free count.
//
// --------------------------------------------------------------------------
VOID SharedFree(LPVOID lpv,HANDLE hProcess)
{
// Update statistics...
InterlockedIncrement( & g_SharedMemInfo.m_NumFree );
#ifndef NTONLYBUILD
if (fWindows95)
HeapFree(hheapShared, 0, lpv);
else
#endif // NTONLYBUILD
{
MyVirtualFreeEx(hProcess,lpv,0,MEM_RELEASE);
CloseHandle (hProcess);
}
}
// --------------------------------------------------------------------------
// InitMemChk - sets alloc/free counts to zero.
// --------------------------------------------------------------------------
void InitMemChk()
{
g_MemInfo.m_NumAlloc = 0;
g_MemInfo.m_NumFree = 0;
g_SharedMemInfo.m_NumAlloc = 0;
g_SharedMemInfo.m_NumFree = 0;
}
// --------------------------------------------------------------------------
// UninitMemChk - outputs stats including number of unfree'd objects...
//
// Note that Shared memory is often allocated from one process and free'd
// from another, so when a process detatches the numbers may not match up.
// At some point in time it might be more useful to keep this as a global
// across all instances of the DLL.
// --------------------------------------------------------------------------
void UninitMemChk()
{
DBPRINTF( TEXT("Total objects: %d, unfreed: %d\n"),
g_MemInfo.m_NumAlloc,
g_MemInfo.m_NumAlloc - g_MemInfo.m_NumFree );
DBPRINTF( TEXT("Total Shared objects: %d, unfreed: %d\n"),
g_SharedMemInfo.m_NumAlloc,
g_SharedMemInfo.m_NumAlloc - g_SharedMemInfo.m_NumFree );
}
#endif // _DEBUG
// --------------------------------------------------------------------------
//
// SharedRead
//
// This reads shared memory.
//
// --------------------------------------------------------------------------
BOOL SharedRead(LPVOID lpvSharedSource,LPVOID lpvDest,DWORD cbSize,HANDLE hProcess)
{
#ifdef _X86_
if (fWindows95)
{
CopyMemory (lpvDest,lpvSharedSource,cbSize);
return TRUE;
}
else
#endif // _X86_
{
return (ReadProcessMemory (hProcess,lpvSharedSource,lpvDest,cbSize,NULL));
}
}
// --------------------------------------------------------------------------
//
// SharedWrite
//
// This writes into shared memory.
//
// --------------------------------------------------------------------------
BOOL SharedWrite(LPVOID lpvSource,LPVOID lpvSharedDest,DWORD cbSize,HANDLE hProcess)
{
#ifdef _X86_
if (fWindows95)
{
CopyMemory(lpvSharedDest,lpvSource,cbSize);
return TRUE;
}
else
#endif // _X86_
{
return (WriteProcessMemory (hProcess,lpvSharedDest,lpvSource,cbSize,NULL));
}
}