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

📄 pgpmemlocknt.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	pgpMemLockNT.c - PGPmemlock kernel mode device driver for locking memory


	$Id: pgpMemLockNT.c,v 1.3 2002/08/06 20:11:20 dallen Exp $
____________________________________________________________________________*/

#include "ntddk.h"
#include "stdarg.h"

#include "PGPsdkDriver.h"
#include "pgpMemLockNT.h"
#include "pgpMisc.h"

//	______________________________________________________
//
//  internal memory allocation routines

static VOID
sHeapBlockInit (
	IN 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 ULONG
sHeapInit (
    IN PPGPMEMLOCK	ppml)
{
	ULONG				i		= 0;
	PPGPMEMLOCKITEM		pmli	= NULL;

	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 (
    IN 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 (
	IN 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 (
	IN PPGPMEMLOCK		ppml,
	IN PPGPMEMLOCKITEM	pmli)
{
	// add item to list of free items
	pmli->pitemNext = ppml->pitemFreeList;
	ppml->pitemFreeList = pmli;
}


//	______________________________________________________
//
//  wipe the specified memory block

static VOID
sWipeBlock (
	IN ULONG			ulPage,
	IN 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 blocks

static ULONG
sAddBlockToList (
    IN PPGPMEMLOCK		ppml,
    IN PFILE_OBJECT 	pfo,
	IN PVOID			pCriticalSection,
	IN ULONG			ulPage,
	IN ULONG			ulNumPages,
	IN PMDL				pmdl)
{
	PPGPMEMLOCKITEM		pmli		= NULL;
	PEPROCESS			peProcess	= NULL;
	ULONG				bReturn		= FALSE;

	peProcess = PsGetCurrentProcess ();
	pgpDriverEnterCriticalSection (pCriticalSection, MUTEX);

	// allocate new item
	pmli = sAllocateItem (ppml);
	if (pmli)
	{
		// insert block information into item
		pmli->peProcess = peProcess;
		pmli->pfo = pfo;
		pmli->ulPage = ulPage;
		pmli->ulNumPages = ulNumPages;
		pmli->pmdl = pmdl;

		// insert item into list
		pmli->pitemNext = ppml->pitemLockedList;
		ppml->pitemLockedList = pmli;

		bReturn = TRUE;
	}

	pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);

	return bReturn;
}


//	______________________________________________________
//
//  remove the specified memory page(s) from list of
//	locked blocks and unlock the memory

static ULONG
sUnlockPage (
    IN PPGPMEMLOCK		ppml,
    IN PFILE_OBJECT 	pfo,
	IN PVOID			pCriticalSection,
	IN ULONG			ulPage,
	IN ULONG			ulNumPages,
	IN ULONG			bUnlock)
{
	PMDL				pmdl		= NULL;
	PEPROCESS			peProcess	= NULL;
	PPGPMEMLOCKITEM		pmli		= NULL;
	PPGPMEMLOCKITEM		pitemPrev	= NULL;
	ULONG				bReturn		= FALSE;

	peProcess = PsGetCurrentProcess ();
	pgpDriverEnterCriticalSection (pCriticalSection, MUTEX);

	// search list for specified block
	pitemPrev = NULL;
	pmli = ppml->pitemLockedList;
	while (pmli)
	{
		if ((pmli->peProcess == peProcess) &&
			(pmli->pfo == pfo))
		{
			if ((pmli->ulPage == ulPage)  &&
				(pmli->ulNumPages == ulNumPages))
			{
				if (pitemPrev)
				{
					pitemPrev->pitemNext = pmli->pitemNext;
				}
				else
				{
					ppml->pitemLockedList = pmli->pitemNext;
				}
				pmdl = pmli->pmdl;
				sFreeItem (ppml, pmli);
				bReturn = TRUE;
				break;
			}
		}
		pitemPrev = pmli;
		pmli = pmli->pitemNext;
	}

	pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);

	// unlock pages and discard MDL
	if (bUnlock && pmdl)
	{
		sWipeBlock (ulPage, ulNumPages);
		MmUnlockPages (pmdl);
		IoFreeMdl (pmdl);
	}

	return bReturn;
}


//	______________________________________________________
//
//  lock the pages in the specified virtual address range

static ULONG
sLockTheMemory(
    IN PPGPMEMLOCK			ppml,
    IN PPGPMEMLOCKSTRUCT	ppmls,
    IN PFILE_OBJECT			pfo,
	IN PVOID				pCriticalSection)
{
	PMDL			pmdl			= NULL;
	ULONG			ulPage			= 0;
	ULONG			ulNumPages		= 0;

	PGPdbgVerbosePrint (("PGPutil: sLockTheMemory.\n"));

	// assume no error
	ppmls->ulError = kPGPUDError_NoErr;

	// allocate and initialize a Memory Descriptor List
	pmdl = IoAllocateMdl(ppmls->pMem, ppmls->ulNumBytes, FALSE, FALSE, NULL);
	if (pmdl == NULL)
	{
		PGPdbgPrint (("PGPutil: Err: IoAllocateMdl failed.\n"));
		ppmls->ulError = kPGPUDError_MemAllocError;
		goto done;
	}

	// 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 this block to the array of locked blocks
	if (!sAddBlockToList (ppml, pfo, pCriticalSection, ulPage, ulNumPages, pmdl))
	{
		// we couldn't allocate a new list item
		PGPdbgPrint (("PGPutil: Err: sAddBlockToList failed.\n"));
		ppmls->ulError = kPGPUDError_LockListError;

		// free the mdl we allocated,
		IoFreeMdl(pmdl);
		goto done;
	}

	// try to lock down the client's area
	__try {
		MmProbeAndLockPages (pmdl, UserMode, IoModifyAccess);
	} __except(EXCEPTION_EXECUTE_HANDLER) {
		// client must have passed a bad address, or it exceeded its quota
		PGPdbgPrint (("PGPutil: Err: MmProbeAndLockPages failed.\n"));
		ppmls->ulError = kPGPUDError_MemLockError;

		// remove block from array and free the MDL we allocated,
		sUnlockPage (ppml, pfo, pCriticalSection, ulPage, ulNumPages, FALSE);
		IoFreeMdl (pmdl);
		goto done;
	}

	return TRUE;

done:
    return FALSE;
}


//	______________________________________________________
//
//  unlock the pages in the specified virtual address range

static ULONG
sUnlockTheMemory(
    IN PPGPMEMLOCK			ppml,
    IN PPGPMEMLOCKSTRUCT	ppmls,
    IN PFILE_OBJECT			pfo,
	IN PVOID				pCriticalSection)
{
	ULONG				ulPage			= 0;
	ULONG				ulNumPages		= 0;

	PGPdbgVerbosePrint (("PGPutil: sUnlockTheMemory.\n"));

	// assume no error
	ppmls->ulError = kPGPUDError_NoErr;

	// 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));

	// unlock the pages
	if (!sUnlockPage (ppml, pfo, pCriticalSection, ulPage, ulNumPages, TRUE))
	{
		// we couldn't unlock the memory
		PGPdbgPrint (("PGPutil: Err: sUnlockPage failed.\n"));
		ppmls->ulError = kPGPUDError_MemUnlockError;
		return FALSE;
	}

	return TRUE;
}


//	______________________________________________________
//
//  process the DeviceIOControl message from the attached application

VOID
pgpMemlockProcessOperation (
	IN PPGPMEMLOCK			ppml,
    IN PPGPMEMLOCKSTRUCT	ppmls,
    IN PFILE_OBJECT			pfo,
	IN ULONG				ulStatusFlags,
	IN PVOID				pCriticalSection)
{
	if (!(ulStatusFlags & kPGPUDFlag_MemlockInitialized))
	{
		ppmls->ulError = kPGPUDError_DriverUninitialized;
		return;
	}

	switch (ppmls->ulOperation) {
	case kPGPUDOperation_LockMemory :
		if (sLockTheMemory (ppml, ppmls, pfo, pCriticalSection))
			PGPdbgVerbosePrint (("PGPutil: memory successfully locked.\n"));
		else
			PGPdbgPrint (("PGPutil: Err: memory lock failed.\n"));
		break;

	case kPGPUDOperation_UnlockMemory:
		if (sUnlockTheMemory (ppml, ppmls, pfo, 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 (
    IN 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 (
    IN PPGPMEMLOCK		ppml,
    IN PFILE_OBJECT 	pfo,
	IN PVOID			pCriticalSection)
{
	PEPROCESS			peProcess	= NULL;
	PPGPMEMLOCKITEM		pmli		= NULL;
	PPGPMEMLOCKITEM		pitemNext	= NULL;
	PPGPMEMLOCKITEM		pitemPrev	= NULL;

	peProcess = PsGetCurrentProcess ();

	// first wipe any blocks belonging to this handle
	pmli = ppml->pitemLockedList;
	while (pmli)
	{
		if ((pmli->peProcess == peProcess) &&
			(pmli->pfo == pfo))
		{
			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->peProcess == peProcess) &&
			(pmli->pfo == pfo))
		{
			if (pitemPrev)
			{
				pitemPrev->pitemNext = pmli->pitemNext;
			}
			else
			{
				ppml->pitemLockedList = pmli->pitemNext;
			}
			pitemNext = pmli->pitemNext;
			MmUnlockPages (pmli->pmdl);
			IoFreeMdl (pmli->pmdl);
			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 (
    IN PPGPMEMLOCK	ppml,
	IN 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;
		MmUnlockPages (pmli->pmdl);
		IoFreeMdl (pmli->pmdl);
		sFreeItem (ppml, pmli);
		pmli = pitemNext;
	}
	ppml->pitemLockedList = NULL;

	pgpDriverLeaveCriticalSection (pCriticalSection, MUTEX);

	sHeapDestroy (ppml);
}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -