⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpmemlock9x.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 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 + -