📄 pgpmemlock9x.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
pgpMemLock.c - main C routines for PGPmemlock VxD (Win95)
$Id: pgpMemLock9x.c,v 1.3 2002/08/06 20:11:20 dallen Exp $
____________________________________________________________________________*/
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <vtd.h>
#include <vwin32.h>
#include <vxdwraps.h>
#include <debug.h>
#include <winerror.h>
#include <memory.h>
#include "PGPsdkDriver.h"
#include "pgpMemLock9x.h"
#include "pgpMisc.h"
#pragma intrinsic (memset)
// ______________________________________________________
//
// internal item allocation routines
VOID
sHeapBlockInit (
PPGPMEMLOCKBLOCK pmlb)
{
ULONG i = 0;
PPGPMEMLOCKITEM pmli = NULL;
pmlb->pblockNext = NULL;
pmli = &(pmlb->item[0]);
for (i=1; i<NUMITEMSPERBLOCK; i++)
{
pmli->pitemNext = &(pmlb->item[i]);
pmli = pmli->pitemNext;
}
pmli->pitemNext = NULL;
}
static BOOL
sHeapInit (
PPGPMEMLOCK ppml)
{
ppml->pblockHeap = pgpDriverSecureAlloc (sizeof(PGPMEMLOCKBLOCK));
if (ppml->pblockHeap)
{
sHeapBlockInit (ppml->pblockHeap);
ppml->pitemFreeList = &(ppml->pblockHeap->item[0]);
return TRUE;
}
else
return FALSE;
}
static VOID
sHeapDestroy (
PPGPMEMLOCK ppml)
{
PPGPMEMLOCKBLOCK pmlb = NULL;
PPGPMEMLOCKBLOCK pmlbNext = NULL;
pmlb = ppml->pblockHeap;
while (pmlb)
{
pmlbNext = pmlb->pblockNext;
pgpDriverSecureFree (pmlb);
pmlb = pmlbNext;
}
ppml->pblockHeap = NULL;
ppml->pitemFreeList = NULL;
}
static PPGPMEMLOCKITEM
sAllocateItem (
PPGPMEMLOCK ppml)
{
PPGPMEMLOCKITEM pmli = NULL;
PPGPMEMLOCKBLOCK pmlbNew = NULL;
// there is an item available
if (ppml->pitemFreeList)
{
// remove item from free list
pmli = ppml->pitemFreeList;
ppml->pitemFreeList = ppml->pitemFreeList->pitemNext;
return pmli;
}
// free list is empty, allocate more memory
pmlbNew = pgpDriverSecureAlloc (sizeof(PGPMEMLOCKBLOCK));
if (pmlbNew)
{
// insert block into linked list of blocks
pmlbNew->pblockNext = ppml->pblockHeap;
ppml->pblockHeap = pmlbNew;
// link new items into a list
sHeapBlockInit (pmlbNew);
// first item will be returned to caller
pmli = &(pmlbNew->item[0]);
// add rest of new items to free list
ppml->pitemFreeList = &(pmlbNew->item[1]);
return pmli;
}
// couldn't get an item
return NULL;
}
static VOID
sFreeItem (
PPGPMEMLOCK ppml,
PPGPMEMLOCKITEM pmli)
{
// add item to list of free items
pmli->pitemNext = ppml->pitemFreeList;
ppml->pitemFreeList = pmli;
}
// ______________________________________________________
//
// wipe the specified memory block
static VOID
sWipeBlock (
ULONG ulPage,
ULONG ulNumPages)
{
PVOID pmem;
ULONG ulBytes;
pmem = (PVOID)(ulPage << WIN32PAGESIZE);
ulBytes = ulNumPages << WIN32PAGESIZE;
memset (pmem, 0, ulBytes);
}
// ______________________________________________________
//
// add the specified memory block to list of locked blocks
static BOOL
sAddBlockToList (
PPGPMEMLOCK ppml,
PVOID pCriticalSection,
DWORD dwHandle,
ULONG ulPage,
ULONG ulNumPages)
{
HANDLE hProc = NULL;
PPGPMEMLOCKITEM pmli = NULL;
BOOL bReturn = FALSE;
pgpDriverEnterCriticalSection (pCriticalSection, MUTEX);
// allocate new item
pmli = sAllocateItem (ppml);
if (pmli)
{
// get process handle of current process
VxDCall (VWIN32_GetCurrentProcessHandle)
_asm mov hProc, eax
// insert block information into item
pmli->hProcess = hProc;
pmli->dwHandle = dwHandle;
pmli->ulPage = ulPage;
pmli->ulNumPages = ulNumPages;
// insert item into list
pmli->pitemNext = ppml->pitemLockedList;
ppml->pitemLockedList = pmli;
bReturn = TRUE;
}
pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);
return bReturn;
}
// ______________________________________________________
//
// remove the specified memory block from list of locked blocks
static BOOL
sRemoveBlockFromList (
PPGPMEMLOCK ppml,
PVOID pCriticalSection,
DWORD dwHandle,
ULONG ulPage,
ULONG ulNumPages)
{
HANDLE hProc = NULL;
PPGPMEMLOCKITEM pmli = NULL;
PPGPMEMLOCKITEM pPrev = NULL;
// get process handle of current process
VxDCall (VWIN32_GetCurrentProcessHandle)
_asm mov hProc, eax
pgpDriverEnterCriticalSection (pCriticalSection, MUTEX);
// search list for specified block
pPrev = NULL;
pmli = ppml->pitemLockedList;
while (pmli)
{
if ((pmli->hProcess == hProc) &&
(pmli->dwHandle == dwHandle))
{
if ((pmli->ulPage == ulPage) &&
(pmli->ulNumPages == ulNumPages))
{
if (pPrev)
{
pPrev->pitemNext = pmli->pitemNext;
}
else
{
ppml->pitemLockedList = pmli->pitemNext;
}
sWipeBlock (ulPage, ulNumPages);
sFreeItem (ppml, pmli);
pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);
return TRUE;
}
}
pPrev = pmli;
pmli = pmli->pitemNext;
}
pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);
// didn't find specified block, return error
return FALSE;
}
// ______________________________________________________
//
// unlock and remove all memory blocks belonging to this handle
static BOOL
sUnlockHandleBlocks (
PPGPMEMLOCK ppml,
DWORD dwHandle)
{
HANDLE hProc = NULL;
PPGPMEMLOCKITEM pmli = NULL;
PPGPMEMLOCKITEM pPrev = NULL;
PPGPMEMLOCKITEM pNext = NULL;
// get process handle of current process
VxDCall (VWIN32_GetCurrentProcessHandle)
_asm mov hProc, eax
// search list for block belonging to this process
pPrev = NULL;
pmli = ppml->pitemLockedList;
while (pmli)
{
if ((pmli->hProcess == hProc) &&
(pmli->dwHandle == dwHandle))
{
if (pPrev)
{
pPrev->pitemNext = pmli->pitemNext;
}
else
{
ppml->pitemLockedList = pmli->pitemNext;
}
pNext = pmli->pitemNext;
sWipeBlock (pmli->ulPage, pmli->ulNumPages);
_LinPageUnLock (pmli->ulPage, pmli->ulNumPages, 0);
sFreeItem (ppml, pmli);
pmli = pNext;
}
else
{
pPrev = pmli;
pmli = pmli->pitemNext;
}
}
return TRUE;
}
// ______________________________________________________
//
// unlock and remove all blocks in the list
static BOOL
sUnlockAllBlocks (
PPGPMEMLOCK ppml)
{
PPGPMEMLOCKITEM pmli = NULL;
PPGPMEMLOCKITEM pNext = NULL;
pmli = ppml->pitemLockedList;
while (pmli)
{
pNext = pmli->pitemNext;
sWipeBlock (pmli->ulPage, pmli->ulNumPages);
_LinPageUnLock (pmli->ulPage, pmli->ulNumPages, 0);
sFreeItem (ppml, pmli);
pmli = pNext;
}
ppml->pitemLockedList = NULL;
return TRUE;
}
// ______________________________________________________
//
// lock the page(s) specified by structure
static DWORD
sLockTheMemory (
PPGPMEMLOCK ppml,
PPGPMEMLOCKSTRUCT ppmls,
DWORD dwHandle,
PVOID pCriticalSection)
{
ULONG ulPage = 0;
ULONG ulNumPages = 0;
ULONG ulError = 0;
PGPdbgVerbosePrint (("PGPutil: sLockTheMemory.\n"));
// assume no error
ppmls->ulError = 0;
// calculate page numbers
ulPage = ((ULONG)(ppmls->pMem)) >> WIN32PAGESIZE;
ulNumPages = (((ppmls->ulNumBytes)-1) >> WIN32PAGESIZE ) +1;
PGPdbgVerbosePrint (("PGPutil: locking page(s) %x - %x.\n",
ulPage, ulPage+ulNumPages-1));
// add the block to the list of locked pages
if (sAddBlockToList (ppml, pCriticalSection, dwHandle, ulPage, ulNumPages))
{
// actually lock the page(s)
ulError = _LinPageLock (ulPage, ulNumPages, 0);
if (ulError == 0) // error
{
PGPdbgPrint (("PGPutil: Err: _LinPageLock error.\n"));
ppmls->ulError = kPGPUDError_MemLockError;
sRemoveBlockFromList (
ppml, pCriticalSection, dwHandle, ulPage, ulNumPages);
}
else
{
PGPdbgVerbosePrint (("PGPutil: successfully locked memory.\n"));
}
}
else
{
PGPdbgPrint (("PGPutil: Err: sAddBlockToList error.\n"));
ppmls->ulError = kPGPUDError_LockListError;
}
return 0;
}
// ______________________________________________________
//
// unlock the page(s) specified by structure
static DWORD
sUnlockTheMemory (
PPGPMEMLOCK ppml,
PPGPMEMLOCKSTRUCT ppmls,
DWORD dwHandle,
PVOID pCriticalSection)
{
ULONG ulPage;
ULONG ulNumPages;
ULONG ulError;
PGPdbgVerbosePrint (("PGPutil: sUnlockTheMemory.\n"));
// assume no error
ppmls->ulError = 0;
// calculate page numbers
ulPage = ((ULONG)(ppmls->pMem)) >> WIN32PAGESIZE;
ulNumPages = (((ppmls->ulNumBytes)-1) >> WIN32PAGESIZE ) +1;
PGPdbgVerbosePrint (("PGPutil: unlocking page(s) %x - %x.\n",
ulPage, ulPage+ulNumPages-1));
// remove the pages from the list of locked pages
if (sRemoveBlockFromList (
ppml, pCriticalSection, dwHandle, ulPage, ulNumPages))
{
// actually unlock the page(s)
ulError = _LinPageUnLock (ulPage, ulNumPages, 0);
if (ulError == 0) // error
{
PGPdbgPrint (("PGPmemlock: Err: _LinPageUnLock error.\n"));
ppmls->ulError = kPGPUDError_MemUnlockError;
}
else
{
PGPdbgVerbosePrint (("PGPmemlock: successfully unlocked memory.\n"));
}
}
else
{
PGPdbgPrint (("PGPmemlock: Err: PGPmlRemoveBlockFromList error.\n"));
ppmls->ulError = kPGPUDError_LockListError;
}
return 0;
}
// ______________________________________________________
//
// process the DeviceIOControl message from the attached application
VOID
pgpMemlockProcessOperation (
PPGPMEMLOCK ppml,
PPGPMEMLOCKSTRUCT ppmls,
DWORD dwHandle,
ULONG ulStatusFlags,
PVOID pCriticalSection)
{
if (!(ulStatusFlags & kPGPUDFlag_MemlockInitialized))
{
ppmls->ulError = kPGPUDError_DriverUninitialized;
return;
}
switch (ppmls->ulOperation) {
case kPGPUDOperation_LockMemory :
if (sLockTheMemory (ppml, ppmls, dwHandle, pCriticalSection))
PGPdbgVerbosePrint (("PGPutil: memory successfully locked.\n"));
else
PGPdbgPrint (("PGPutil: Err: memory lock failed.\n"));
break;
case kPGPUDOperation_UnlockMemory:
if (sUnlockTheMemory (ppml, ppmls, dwHandle, pCriticalSection))
PGPdbgVerbosePrint (("PGPutil: memory successfully unlocked.\n"));
else
PGPdbgPrint (("PGPutil: Err: memory unlock failed.\n"));
break;
default :
ppmls->ulError = kPGPUDError_UndefinedOperation;
break;
}
}
// ______________________________________________________
//
// initialize the memlock routines
ULONG
pgpMemlockInit (
PPGPMEMLOCK ppml)
{
ppml->pitemLockedList = NULL;
return sHeapInit (ppml);
}
// ______________________________________________________
//
// remove all of this handle's memory blocks from
// list of blocks and unlock the memory
VOID
pgpMemlockCleanupHandle (
PPGPMEMLOCK ppml,
DWORD dwHandle,
PVOID pCriticalSection)
{
PPGPMEMLOCKITEM pmli = NULL;
PPGPMEMLOCKITEM pitemNext = NULL;
PPGPMEMLOCKITEM pitemPrev = NULL;
HANDLE hProc = NULL;
// get process handle of current process
VxDCall (VWIN32_GetCurrentProcessHandle)
_asm mov hProc, eax
// first wipe any blocks belonging to this handle
pmli = ppml->pitemLockedList;
while (pmli)
{
if ((pmli->hProcess == hProc) &&
(pmli->dwHandle == dwHandle))
{
sWipeBlock (pmli->ulPage, pmli->ulNumPages);
}
pmli = pmli->pitemNext;
}
pgpDriverEnterCriticalSection (pCriticalSection, MUTEX);
// search list for items belonging to this handle
// and unlock/free them
pitemPrev = NULL;
pmli = ppml->pitemLockedList;
while (pmli)
{
if ((pmli->hProcess == hProc) &&
(pmli->dwHandle == dwHandle))
{
if (pitemPrev)
{
pitemPrev->pitemNext = pmli->pitemNext;
}
else
{
ppml->pitemLockedList = pmli->pitemNext;
}
pitemNext = pmli->pitemNext;
_LinPageUnLock (pmli->ulPage, pmli->ulNumPages, 0);
sFreeItem (ppml, pmli);
pmli = pitemNext;
}
else
{
pitemPrev = pmli;
pmli = pmli->pitemNext;
}
}
pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);
}
// ______________________________________________________
//
// remove all locked memory blocks from
// list of blocks and unlock the memory
VOID
pgpMemlockCleanup (
PPGPMEMLOCK ppml,
PVOID pCriticalSection)
{
PPGPMEMLOCKITEM pmli = NULL;
PPGPMEMLOCKITEM pitemNext = NULL;
// first wipe all blocks
pmli = ppml->pitemLockedList;
while (pmli)
{
sWipeBlock (pmli->ulPage, pmli->ulNumPages);
pmli = pmli->pitemNext;
}
pgpDriverEnterCriticalSection (pCriticalSection, MUTEX);
// now unlock blocks and destroy list
pmli = ppml->pitemLockedList;
while (pmli)
{
pitemNext = pmli->pitemNext;
_LinPageUnLock (pmli->ulPage, pmli->ulNumPages, 0);
sFreeItem (ppml, pmli);
pmli = pitemNext;
}
ppml->pitemLockedList = NULL;
pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);
sHeapDestroy (ppml);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -