Leaked source code of windows server 2003
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.
 
 
 
 
 
 

585 lines
14 KiB

/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// mem.c - memory functions
////
#include "winlocal.h"
#include <string.h>
#include "mem.h"
#include "sys.h"
#include "trace.h"
////
// private definitions
////
#ifndef NOTRACE
// mem control struct
//
typedef struct MEM
{
DWORD dwVersion;
HINSTANCE hInst;
HTASK hTask;
long nBlocks;
long sizBlocks;
} MEM, FAR *LPMEM;
// shared mem engine handle
//
static LPMEM lpMemShare = NULL;
static int cShareUsage = 0;
// helper functions
//
static LPMEM MemGetPtr(HMEM hMem);
static HMEM MemGetHandle(LPMEM lpMem);
////
// public functions
////
// MemInit - initialize mem engine
// <dwVersion> (i) must be MEM_VERSION
// <hInst> (i) instance handle of calling module
// return handle (NULL if error)
//
HMEM DLLEXPORT WINAPI MemInit(DWORD dwVersion, HINSTANCE hInst)
{
BOOL fSuccess = TRUE;
LPMEM lpMem = NULL;
BOOL fShare = TRUE;
if (dwVersion != MEM_VERSION)
fSuccess = FALSE;
else if (hInst == NULL)
fSuccess = FALSE;
// if a shared mem engine already exists,
// use it rather than create another one
//
else if (fShare && cShareUsage > 0 && lpMemShare != NULL)
lpMem = lpMemShare;
// memory is allocated such that the client app owns it
// unless we are sharing the mem handle among several apps
//
#ifdef _WIN32
else if ((lpMem = (LPMEM) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(MEM))) == NULL)
#else
else if ((lpMem = (LPMEM) GlobalAllocPtr(GMEM_MOVEABLE |
GMEM_ZEROINIT, sizeof(MEM))) == NULL)
#endif
fSuccess = FALSE;
else
{
lpMem->dwVersion = dwVersion;
lpMem->hInst = hInst;
lpMem->hTask = GetCurrentTask();
lpMem->nBlocks = 0;
lpMem->sizBlocks = 0;
}
if (!fSuccess)
{
MemTerm(MemGetHandle(lpMem));
lpMem = NULL;
}
// keep track of total modules sharing a mem engine handle
//
if (fSuccess && fShare)
{
if (++cShareUsage == 1)
lpMemShare = lpMem;
}
return fSuccess ? MemGetHandle(lpMem) : NULL;
}
// MemTerm - shut down mem engine
// <hMem> (i) handle returned from MemInit or NULL
// return 0 if success
//
int DLLEXPORT WINAPI MemTerm(HMEM hMem)
{
BOOL fSuccess = TRUE;
LPMEM lpMem;
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
// only shut down mem engine if handle
// is not shared (or is no longer being shared)
//
else if (lpMem != lpMemShare || --cShareUsage <= 0)
{
// shared mem engine handle no longer valid
//
if (cShareUsage <= 0)
lpMemShare = NULL;
#ifdef _WIN32
if (!HeapFree(GetProcessHeap(), 0, lpMem))
#else
if (GlobalFreePtr(lpMem) != 0)
#endif
fSuccess = FALSE;
}
return fSuccess ? 0 : -1;
}
// MemAlloc - allocate memory block
// <hMem> (i) handle returned from MemInit or NULL
// <sizBlock> (i) size of block, in bytes
// <dwFlags> (i) control flags
// MEM_NOZEROINIT do not initialize block
// return pointer to block, NULL if error
//
LPVOID DLLEXPORT WINAPI MemAllocEx(HMEM hMem, long sizBlock, DWORD dwFlags,
LPCTSTR lpszFileName, unsigned uLineNumber)
{
BOOL fSuccess = TRUE;
LPMEM lpMem;
LPVOID lpBlock;
#ifdef _WIN32
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
else if ((lpBlock = HeapAlloc(GetProcessHeap(),
(dwFlags & MEM_NOZEROINIT) ? 0 : HEAP_ZERO_MEMORY,
sizBlock)) == NULL)
fSuccess = FALSE;
#else
UINT wFlags = 0;
wFlags |= GMEM_MOVEABLE;
if (!(dwFlags & MEM_NOZEROINIT))
wFlags |= GMEM_ZEROINIT;
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
else if ((lpBlock = GlobalAllocPtr(wFlags, sizBlock)) == NULL)
fSuccess = FALSE;
#endif
// keep track of total blocks allocated, total size of all blocks
//
else if (++lpMem->nBlocks, lpMem->sizBlocks += sizBlock, FALSE)
;
else if (TraceGetLevel(NULL) >= 9)
{
TracePrintf_7(NULL, 9, TEXT("%s(%u) : %08X = MemAllocEx(%p, %08X) (%ld, %ld)\n"),
(LPTSTR) lpszFileName,
(unsigned) uLineNumber,
lpBlock,
(long) sizBlock,
(unsigned long) dwFlags,
lpMem->nBlocks,
lpMem->sizBlocks);
}
return fSuccess ? lpBlock : NULL;
}
// MemReAlloc - reallocate memory block
// <hMem> (i) handle returned from MemInit or NULL
// <lpBlock> (i) pointer returned from MemAlloc
// <sizBlock> (i) new size of block, in bytes
// <dwFlags> (i) control flags
// MEM_NOZEROINIT do not initialize block
// return pointer to block, NULL if error
//
LPVOID DLLEXPORT WINAPI MemReAllocEx(HMEM hMem, LPVOID lpBlock, long sizBlock,
DWORD dwFlags, LPCTSTR lpszFileName, unsigned uLineNumber)
{
BOOL fSuccess = TRUE;
LPMEM lpMem;
LPVOID lpBlockOld = lpBlock;
long sizBlockOld;
#ifdef _WIN32
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
else if ((sizBlockOld = MemSize(hMem, lpBlock)) <= 0)
fSuccess = FALSE;
else if ((lpBlock = HeapReAlloc(GetProcessHeap(),
(dwFlags & MEM_NOZEROINIT) ? 0 : HEAP_ZERO_MEMORY,
lpBlockOld, sizBlock)) == NULL)
fSuccess = FALSE;
#else
UINT wFlags = 0;
wFlags |= GMEM_MOVEABLE;
if (!(dwFlags & MEM_NOZEROINIT))
wFlags |= GMEM_ZEROINIT;
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
else if ((sizBlockOld = MemSize(hMem, lpBlock)) <= 0)
fSuccess = FALSE;
else if ((lpBlock = GlobalReAllocPtr(lpBlockOld, sizBlock, wFlags)) == NULL)
fSuccess = FALSE;
#endif
// keep track of total blocks allocated, total size of all blocks
//
else if (lpMem->sizBlocks -= sizBlockOld, lpMem->sizBlocks += sizBlock, FALSE)
;
else if (TraceGetLevel(NULL) >= 9)
{
TracePrintf_8(NULL, 9, TEXT("%s(%u) : %p = MemReAllocEx(%p, %ld, %08X) (%ld, %ld)\n"),
(LPTSTR) lpszFileName,
(unsigned) uLineNumber,
lpBlock,
lpBlockOld,
(long) sizBlock,
(unsigned long) dwFlags,
lpMem->nBlocks,
lpMem->sizBlocks);
}
return fSuccess ? lpBlock : NULL;
}
// MemFree - free memory block
// <hMem> (i) handle returned from MemInit or NULL
// <lpBlock> (i) pointer returned from MemAlloc
// return NULL if success, lpBlock if error
//
// NOTE: the return value of this function is designed to allow the
// user of this function to easily assign NULL to a freed pointer,
// as the following example demonstrates:
//
// if ((p = MemFree(hMem, p)) != NULL)
// ; // error
//
LPVOID DLLEXPORT WINAPI MemFreeEx(HMEM hMem, LPVOID lpBlock,
LPCTSTR lpszFileName, unsigned uLineNumber)
{
BOOL fSuccess = TRUE;
LPMEM lpMem;
long sizBlock;
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
else if ((sizBlock = MemSize(hMem, lpBlock)) <= 0)
fSuccess = FALSE;
#ifdef _WIN32
else if (!HeapFree(GetProcessHeap(), 0, lpBlock))
#else
else if (GlobalFreePtr(lpBlock) != 0)
#endif
fSuccess = FALSE;
// keep track of total blocks allocated, total size of all blocks
//
else if (--lpMem->nBlocks, lpMem->sizBlocks -= sizBlock, FALSE)
;
else if (TraceGetLevel(NULL) >= 9)
{
TracePrintf_5(NULL, 9, TEXT("%s(%u) : MemFreeEx(%p) (%ld, %ld)\n"),
(LPTSTR) lpszFileName,
(unsigned) uLineNumber,
lpBlock,
lpMem->nBlocks,
lpMem->sizBlocks);
}
return fSuccess ? NULL : lpBlock;
}
// MemSize - get size of memory block
// <hMem> (i) handle returned from MemInit or NULL
// <lpBlock> (i) pointer returned from MemAlloc
// return size of block if success, 0 if error
//
long DLLEXPORT WINAPI MemSize(HMEM hMem, LPVOID lpBlock)
{
BOOL fSuccess = TRUE;
LPMEM lpMem;
long sizBlock;
if ((lpMem = MemGetPtr(hMem)) == NULL)
fSuccess = FALSE;
#ifdef _WIN32
else if ((sizBlock = (long) HeapSize(GetProcessHeap(), 0, lpBlock)) <= 0)
#else
else if ((sizBlock = (long) GlobalSize(GlobalPtrHandle(lpBlock))) <= 0)
#endif
fSuccess = FALSE;
return fSuccess ? sizBlock : 0;
}
#endif // #ifndef NOTRACE
#ifndef _WIN32
static void hmemmove(void _huge *d, const void _huge *s, long len);
#ifndef SIZE_T_MAX
#define SIZE_T_MAX (~((size_t) 0))
#endif
void _huge* DLLEXPORT MemCCpyEx(void _huge* dest, const void _huge* src, int c, long count)
{
if (count <= SIZE_T_MAX)
return _fmemccpy(dest, src, c, (size_t) count);
else
return NULL; //$FIXUP - need to handle large count
}
void _huge* DLLEXPORT MemChrEx(void _huge* buf, int c, long count)
{
if (count <= SIZE_T_MAX)
return _fmemchr(buf, c, (size_t) count);
else
return NULL; //$FIXUP - need to handle large count
}
int DLLEXPORT MemCmpEx(const void _huge* buf1, void _huge* buf2, long count)
{
if (count <= SIZE_T_MAX)
return _fmemcmp(buf1, buf2, (size_t) count);
else
return NULL; //$FIXUP - need to handle large count
}
void _huge* DLLEXPORT MemCpyEx(void _huge* dest, const void _huge* src, long count)
{
if (count <= SIZE_T_MAX)
return _fmemcpy(dest, src, (size_t) count);
else
{
hmemcpy(dest, src, count);
return dest;
}
}
int DLLEXPORT MemICmpEx(const void _huge* buf1, void _huge* buf2, long count)
{
if (count <= SIZE_T_MAX)
return _fmemicmp(buf1, buf2, (size_t) count);
else
return NULL; //$FIXUP - need to handle large count
}
void _huge* DLLEXPORT MemMoveEx(void _huge* dest, const void _huge* src, long count)
{
if (count <= SIZE_T_MAX)
return _fmemmove(dest, src, (size_t) count);
else
{
hmemmove(dest, src, count);
return dest;
}
}
void _huge* DLLEXPORT MemSet(void _huge* dest, int c, long count)
{
if (count <= SIZE_T_MAX)
return _fmemset(dest, c, (size_t) count);
else
{
BYTE _huge* destTemp = dest;
long countTemp = count;
while (countTemp > 0)
{
size_t cb = (size_t) min(SIZE_T_MAX, countTemp);
_fmemset(destTemp, c, cb);
destTemp += cb;
countTemp -= cb;
}
return dest;
}
}
#endif // #ifndef _WIN32
////
// helper functions
////
#ifndef NOTRACE
// MemGetPtr - verify that mem handle is valid,
// <hMem> (i) handle returned from MemInit
// return corresponding mem pointer (NULL if error)
//
static LPMEM MemGetPtr(HMEM hMem)
{
BOOL fSuccess = TRUE;
LPMEM lpMem;
// use shared mem handle if no other supplied
//
if (hMem == NULL && lpMemShare != NULL)
lpMem = lpMemShare;
// create shared mem handle if no other supplied
//
else if (hMem == NULL && lpMemShare == NULL &&
(hMem = MemInit(MEM_VERSION, SysGetTaskInstance(NULL))) == NULL)
fSuccess = FALSE;
else if ((lpMem = (LPMEM) hMem) == NULL)
fSuccess = FALSE;
// note: check for good pointer made only if not using lpMemShare
//
else if (lpMem != lpMemShare &&
IsBadWritePtr(lpMem, sizeof(MEM)))
fSuccess = FALSE;
#ifdef CHECKTASK
// make sure current task owns the mem handle
// except when shared mem handle is used
//
if (fSuccess && lpMem != lpMemShare &&
lpMem->hTask != GetCurrentTask())
fSuccess = FALSE;
#endif
return fSuccess ? lpMem : NULL;
}
// MemGetHandle - verify that mem pointer is valid,
// <lpMem> (i) pointer to MEM struct
// return corresponding mem handle (NULL if error)
//
static HMEM MemGetHandle(LPMEM lpMem)
{
BOOL fSuccess = TRUE;
HMEM hMem;
if ((hMem = (HMEM) lpMem) == NULL)
fSuccess = FALSE;
return fSuccess ? hMem : NULL;
}
#endif // #ifndef NOTRACE
#ifndef _WIN32
// from Microsoft Windows SDK KnowledgeBase PSS ID Number: Q117743
//
static void hmemmove(void _huge *d, const void _huge *s, long len)
{
register long i;
long safesize, times;
// There are four cases to consider
// case 1: source and destination are the same
// case 2: source and destination do not overlap
// case 3: source starts at a location before destination in
// linear memory
// case 4: source starts at a location after destination in
// linear memory
// detect case 1 and handle it
if (d == s)
return;
// determine the amount of overlap
if (d > s) // get the absolute difference
safesize = ((unsigned long)d - (unsigned long)s);
else
safesize = ((unsigned long)s - (unsigned long)d);
// detect case 2
if (safesize >= len)
{
hmemcpy(d, s, len); // no overlap
return;
}
times = len/safesize;
// detect case 3 and handle it
if ((s < d) && ((unsigned long)s+len-1) >(unsigned long)d)
{
// copy bytes from the end of source to the end of
// destination in safesize quantum.
for (i = 1; i <= times; i++)
hmemcpy((void _huge *)((unsigned long) d+len-i*safesize),
(void _huge *)((unsigned long)s+len-i*safesize),
safesize);
// copy the bytes remaining to be copied after
// times*safesize bytes have been copied.
if (times*safesize < len)
hmemcpy(d, s, len - times*safesize);
}
else // this is case 4. handle it
{
// ASSERT (s > d) && ((d+len-1) > s))
// copy bytes from the beginning of source to the
// beginning of destination in safesize quantum
for (i = 0; i < times; i++)
hmemcpy((void _huge *)((unsigned long)d+i*safesize),
(void _huge *)((unsigned long)s+i*safesize),
safesize);
// copy the bytes remaining to be copied after
// times*safesize bytes have been copied.
if (times*safesize < len)
hmemcpy((void _huge*)((unsigned long)d+times*safesize),
(void _huge*)((unsigned long)s+times*safesize),
len - times*safesize);
}
return;
}
#endif // #ifndef _WIN32