📄 pgpdrivernt.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
pgpDriverNT.c - kernel mode device driver for PGP utility functions
$Id: pgpDriverNT.c,v 1.16 2002/08/06 20:11:20 dallen Exp $
____________________________________________________________________________*/
#include "ntddk.h"
#include "stdarg.h"
#ifndef PGP_EROS
#define PGP_EROS 0
#endif // PGP_EROS
#if !PGP_EROS
#include "ntddkbd.h"
#include "ntddmou.h"
#endif // !PGP_EROS
#include "PGPsdkDriver.h"
#include "pgpDriverNT.h"
#include "pgpMemlockNT.h"
#include "pgpGeneric.h"
#include "pgpMisc.h"
#if !PGP_EROS
#include "pgpWipeDeleteNT.h"
#include "pgpEntropy.h"
static WCHAR keyboardGuid[] = L"{4D36E96B-E325-11CE-BFC1-08002BE10318}";
static WCHAR mouseGuid[] = L"{4D36E96F-E325-11CE-BFC1-08002BE10318}";
#endif // !PGP_EROS
static WCHAR deviceNameBuffer[] = L"\\Device\\PGPsdkDriver";
static WCHAR deviceLinkBuffer[] = L"\\DosDevices\\PGPsdkDriver";
#if !PGP_EROS
// ______________________________________________________
//
// I/O Completion routine for mouse read requests
//
// this routine is called after the system has retrieved the
// mouse position and button information from the lower level driver.
//
// if a mouse button has been pressed, we need to reset the inactivity
// timers. Also, if count is reached, we pass timing information into
// the entropy hashing functions
static NTSTATUS
sMouseReadCompletion (
IN PDEVICE_OBJECT pdevo,
IN PIRP pirp,
IN PVOID context)
{
PDEVEXTENSION pdeveFilter = pdevo->DeviceExtension;
PDRVEXTENSION pdrve = pdeveFilter->pdrve;
PGPdbgVerbosePrint(( "PGPutil: sReadCompletion: IRP: %x\n", pirp));
// if appropriate, send this IRP to the entropy store driver
if (NT_SUCCESS(pirp->IoStatus.Status))
{
PMOUSE_INPUT_DATA pmid;
ULONG ulForceAdd;
// hash the x, y coordinates into the entropy buffer
pmid = (PMOUSE_INPUT_DATA)(pirp->AssociatedIrp.SystemBuffer);
// flag that the hook seems to be working
pdrve->ulStatusFlags |= kPGPUDFlag_MouseHookCalled;
if (pdeveFilter->ulSkipCount == 0)
{
pdeveFilter->ulSkipCount = MOUSE_SKIP;
ulForceAdd = TRUE;
}
else
{
pdeveFilter->ulSkipCount--;
ulForceAdd = FALSE;
}
// add entropy to pool
// (leave as SPINLOCK we could be > dispatch level)
if (pgpDriverTryToEnterCriticalSection (&pdrve->csEntropy,
SPINLOCK))
{
pgpEntropyAddMouseEvent (ulForceAdd);
pgpDriverLeaveCriticalSection (&pdrve->csEntropy, SPINLOCK);
}
if (pmid->Buttons != 0)
{
pgpProcessActivityEvent (&pdrve->inactivity,
&pdrve->csInactivity);
}
}
if (pirp->PendingReturned)
{
IoMarkIrpPending (pirp);
}
return STATUS_SUCCESS;
}
// ______________________________________________________
//
// process the IRPs sent to the mouse device.
//
// this function simply passes a request on to the lower driver,
// attaching a completion routine pointer to the "read" requests.
static NTSTATUS
sMouseEntropyDispatch (
IN PDEVICE_OBJECT pdevo,
IN PIRP pirp)
{
PDEVEXTENSION pdeveFilter = pdevo->DeviceExtension;
PIO_STACK_LOCATION pirpsCurrent = IoGetCurrentIrpStackLocation (pirp);
PGPdbgVerbosePrint (("PGPutil: sKbdEntropyDispatch: IRP: %8x; "
"MajorFunction: %d\n", pirp,
pirpsCurrent->MajorFunction));
switch (pirpsCurrent->MajorFunction) {
case IRP_MJ_READ :
// Copy args to next level
IoCopyCurrentIrpStackLocationToNext(pirp);
// Set up Completion routine to handle marking the IRP pending.
IoSetCompletionRoutine (pirp, sMouseReadCompletion,
NULL, TRUE, TRUE, TRUE);
// Pass the IRP to the target driver
return IoCallDriver (pdeveFilter->pdevoNext, pirp);
#if (_WIN32_WINNT >= 0x0500)
case IRP_MJ_PNP:
switch (pirpsCurrent->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
// target device is going away, so do we
IoSkipCurrentIrpStackLocation(pirp);
IoCallDriver(pdeveFilter->pdevoNext, pirp);
IoDetachDevice(pdeveFilter->pdevoNext);
IoDeleteDevice(pdevo);
return STATUS_SUCCESS;
default:
// Pass the IRP to the target
IoSkipCurrentIrpStackLocation(pirp);
return IoCallDriver (pdeveFilter->pdevoNext, pirp);
}
case IRP_MJ_POWER:
// must use special calls to pass down power IRPs
PoStartNextPowerIrp(pirp);
IoSkipCurrentIrpStackLocation(pirp);
return PoCallDriver(pdeveFilter->pdevoNext, pirp);
#endif // _WIN32_WINNT >= 0x5000
default :
// Pass the IRP to the target
IoSkipCurrentIrpStackLocation(pirp);
return IoCallDriver (pdeveFilter->pdevoNext, pirp);
}
}
// ______________________________________________________
//
// I/O Completion routine for keyboard read requests
//
// this routine is called after the system has retrieved the
// keypress information from the lower level driver.
//
// we need to reset the inactivity timers, and if count is
// reached, pass keypress into the entropy hashing functions
static NTSTATUS
sKbdReadCompletion (
IN PDEVICE_OBJECT pdevo,
IN PIRP pirp,
IN PVOID context)
{
PDEVEXTENSION pdeveFilter = pdevo->DeviceExtension;
PDRVEXTENSION pdrve = pdeveFilter->pdrve;
PGPdbgVerbosePrint(( "PGPutil: sReadCompletion: IRP: %x\n", pirp));
// if appropriate, send this IRP to the entropy store driver
if (NT_SUCCESS(pirp->IoStatus.Status))
{
PKEYBOARD_INPUT_DATA pkid;
// put the scancode in the structure to pass to the
// Entropy driver callback function
pkid = (PKEYBOARD_INPUT_DATA)(pirp->AssociatedIrp.SystemBuffer);
// only take key presses
if (pkid->Flags == KEY_MAKE)
{
ULONG ulForceAdd;
// flag that the hook seems to be working
pdrve->ulStatusFlags |= kPGPUDFlag_KeyboardHookCalled;
if (pdeveFilter->ulSkipCount == 0)
{
pdeveFilter->ulSkipCount = KEYBOARD_SKIP;
ulForceAdd = TRUE;
}
else
{
pdeveFilter->ulSkipCount--;
ulForceAdd = FALSE;
}
// hash the keycode into the entropy buffer
// (leave as SPINLOCK we could be > dispatch level)
if (pgpDriverTryToEnterCriticalSection (&pdrve->csEntropy,
SPINLOCK))
{
pgpEntropyAddKeystrokeEvent (ulForceAdd, pkid->MakeCode);
pgpDriverLeaveCriticalSection (&pdrve->csEntropy,
SPINLOCK);
}
pgpProcessActivityEvent (&pdrve->inactivity,
&pdrve->csInactivity);
}
}
if (pirp->PendingReturned)
{
IoMarkIrpPending (pirp);
}
return STATUS_SUCCESS;
}
// ______________________________________________________
//
// process the IRPs sent to the keyboard device.
//
// this function simply passes a request on to the lower driver,
// attaching a completion routine pointer to the "read" requests.
static NTSTATUS
sKbdEntropyDispatch (
IN PDEVICE_OBJECT pdevo,
IN PIRP pirp)
{
PDEVEXTENSION pdeveFilter = pdevo->DeviceExtension;
PIO_STACK_LOCATION pirpsCurrent = IoGetCurrentIrpStackLocation (pirp);
PGPdbgVerbosePrint (("PGPutil: sKbdEntropyDispatch: IRP: %8x; "
"MajorFunction: %d\n", pirp,
pirpsCurrent->MajorFunction));
switch (pirpsCurrent->MajorFunction) {
case IRP_MJ_READ :
IoCopyCurrentIrpStackLocationToNext(pirp);
// Set up Completion routine to handle marking the IRP pending.
IoSetCompletionRoutine (pirp, sKbdReadCompletion,
NULL, TRUE, TRUE, TRUE);
// Pass the IRP to the target driver
return IoCallDriver (pdeveFilter->pdevoNext, pirp);
#if (_WIN32_WINNT >= 0x0500)
case IRP_MJ_PNP:
switch (pirpsCurrent->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
// target device is going away, so do we
IoSkipCurrentIrpStackLocation(pirp);
IoCallDriver(pdeveFilter->pdevoNext, pirp);
IoDetachDevice(pdeveFilter->pdevoNext);
IoDeleteDevice(pdevo);
return STATUS_SUCCESS;
default:
// Pass the IRP to the target
IoSkipCurrentIrpStackLocation(pirp);
return IoCallDriver (pdeveFilter->pdevoNext, pirp);
}
case IRP_MJ_POWER:
// must use special calls to pass down power IRPs
PoStartNextPowerIrp(pirp);
IoSkipCurrentIrpStackLocation(pirp);
return PoCallDriver(pdeveFilter->pdevoNext, pirp);
#endif // _WIN32_WINNT >= 0x5000
default :
// Pass the IRP to the target
IoSkipCurrentIrpStackLocation(pirp);
return IoCallDriver (pdeveFilter->pdevoNext, pirp);
}
}
#endif // !PGP_EROS
// ______________________________________________________
//
// just make sure that the buffer is big enough to hold the data
static ULONG
sValidateDeviceIOBuffer (
IN PIRP pirp,
IN PIO_STACK_LOCATION pIrpStack,
IN ULONG ulStructSize)
{
ULONG ulBufLenIn = 0;
ULONG ulBufLenOut = 0;
ulBufLenIn = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ulBufLenOut = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
pirp->IoStatus.Status = STATUS_INVALID_PARAMETER;
pirp->IoStatus.Information = 0;
if (ulBufLenIn < ulStructSize)
{
PGPdbgPrint (("PGPutil: sDispatchDeviceControl: "
"invalid input buffer length.\n"));
return FALSE;
}
if (pirp->AssociatedIrp.SystemBuffer == NULL)
{
PGPdbgPrint (("PGPutil: sDispatchDeviceControl: "
"invalid buffer address.\n"));
return FALSE;
}
pirp->IoStatus.Status = STATUS_SUCCESS;
pirp->IoStatus.Information = ulBufLenOut;
return TRUE;
}
// ______________________________________________________
//
// process the IRPs sent to the "main" device (as opposed to
// the keyboard and mouse "filter" devices.
static NTSTATUS
sPGPUtilDispatch (
IN PDEVICE_OBJECT pdevo,
IN PIRP pirp)
{
PIO_STACK_LOCATION pIrpStack = NULL;
NTSTATUS ntStatus = STATUS_SUCCESS;
PVOID pStruct = NULL;
PDEVEXTENSION pdeve = pdevo->DeviceExtension;
PDRVEXTENSION pdrve = pdeve->pdrve;
// Init to default settings
pirp->IoStatus.Status = STATUS_SUCCESS;
pirp->IoStatus.Information = 0;
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
pIrpStack = IoGetCurrentIrpStackLocation (pirp);
switch (pIrpStack->MajorFunction) {
// called when user app calls CreateFile
case IRP_MJ_CREATE:
PGPdbgVerbosePrint (("PGPutil: IRP_MJ_CREATE\n"));
break;
// called when user app closes handle to driver --
// make sure all locked memory belonging to this handle gets unlocked
case IRP_MJ_CLOSE:
PGPdbgVerbosePrint (("PGPutil: IRP_MJ_CLOSE\n"));
if (KeGetCurrentIrql () < DISPATCH_LEVEL)
{
pgpMemlockCleanupHandle (&pdrve->memlock,
pIrpStack->FileObject, &pdrve->csMemlock);
}
break;
#if !PGP_EROS
// called when other driver sends IRP
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
PGPdbgVerbosePrint (("PGPutil: IRP_MJ_INTERNAL_DEVICE_CONTROL\n"));
pStruct = pirp->AssociatedIrp.SystemBuffer;
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_PGPUTIL_INACTIVITY :
if (sValidateDeviceIOBuffer (
pirp, pIrpStack, sizeof(PGPINACTIVITYSTRUCT)))
{
pgpInactivityProcessOperation (
&pdrve->inactivity,
(PPGPINACTIVITYSTRUCT)pStruct,
&pdrve->csInactivity);
}
break;
default:
pirp->IoStatus.Status = STATUS_INVALID_PARAMETER;
PGPdbgPrint (
("PGPutil: Err: unknown IRP_MJ_INTERNAL_DEVICE_CONTROL.\n"));
break;
}
break;
#endif // !PGP_EROS
// called when user apps call DeviceIoControl
case IRP_MJ_DEVICE_CONTROL:
PGPdbgVerbosePrint (("PGPutil: IRP_MJ_DEVICE_CONTROL\n"));
pStruct = pirp->AssociatedIrp.SystemBuffer;
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_PGPUTIL_GENERIC :
if (sValidateDeviceIOBuffer (
pirp, pIrpStack, sizeof(PPGPGENERICSTRUCT)))
{
pgpGenericProcessOperation (
(PPGPGENERICSTRUCT)pStruct, pdrve->ulStatusFlags);
}
break;
case IOCTL_PGPUTIL_MEMLOCK :
if (sValidateDeviceIOBuffer (
pirp, pIrpStack, sizeof(PGPMEMLOCKSTRUCT)))
{
pgpMemlockProcessOperation (
&pdrve->memlock,
(PPGPMEMLOCKSTRUCT)pStruct,
pIrpStack->FileObject,
pdrve->ulStatusFlags,
&pdrve->csMemlock);
}
break;
#if !PGP_EROS
case IOCTL_PGPUTIL_ENTROPY :
if (sValidateDeviceIOBuffer (
pirp, pIrpStack, sizeof(PGPENTROPYSTRUCT)))
{
pgpEntropyProcessOperation (
(PPGPENTROPYSTRUCT)pStruct, &pdrve->csEntropy);
}
break;
case IOCTL_PGPUTIL_CACHE :
if (sValidateDeviceIOBuffer (
pirp, pIrpStack, sizeof(PGPCACHESTRUCT)))
{
PPGPCACHE ppc = NULL;
switch (((PPGPCACHESTRUCT)pStruct)->ulCache) {
case kPGPUDCache_Signing :
ppc = &pdrve->cacheSign;
break;
case kPGPUDCache_Decryption :
ppc = &pdrve->cacheDecrypt;
break;
default :
((PPGPCACHESTRUCT)pStruct)->ulError =
kPGPUDError_BadParams;
break;
}
if (ppc)
{
pgpCacheProcessOperation (
ppc,
(PPGPCACHESTRUCT)pStruct,
&pdrve->csCache);
}
}
break;
case IOCTL_PGPUTIL_WIPEDELETE :
if (sValidateDeviceIOBuffer (
pirp, pIrpStack, sizeof(PGPWIPEDELETESTRUCT)))
{
pgpWipeDeleteProcessOperation (
(PPGPWIPEDELETESTRUCT)pStruct, pdrve->ulStatusFlags);
}
break;
#endif // !PGP_EROS
default:
pirp->IoStatus.Status = STATUS_INVALID_PARAMETER;
PGPdbgPrint (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -