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.
648 lines
19 KiB
648 lines
19 KiB
// @doc
|
|
/**********************************************************************
|
|
*
|
|
* @module GckShell.c |
|
|
*
|
|
* Basic driver entry points for GcKernel.sys
|
|
*
|
|
* History
|
|
* ----------------------------------------------------------
|
|
* Mitchell S. Dernis Original
|
|
*
|
|
* (c) 1986-1998 Microsoft Corporation. All right reserved.
|
|
*
|
|
* @topic GckShell |
|
|
* Contains the most basic driver entry points (that any NT\WDM driver
|
|
* would have) for GcKernel.sys.
|
|
*
|
|
**********************************************************************/
|
|
#define __DEBUG_MODULE_IN_USE__ GCK_GCKSHELL_C
|
|
|
|
#include <wdm.h>
|
|
#include "Debug.h"
|
|
#include "GckShell.h"
|
|
#include "vmmid.h"
|
|
|
|
#ifdef BUILD_98
|
|
extern void* KeyBoardHook(void);
|
|
#endif
|
|
|
|
//
|
|
// Mark the pageable routines as such
|
|
//
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text (INIT, DriverEntry)
|
|
#pragma alloc_text (PAGE, GCK_Create)
|
|
#pragma alloc_text (PAGE, GCK_Close)
|
|
#pragma alloc_text (PAGE, GCK_Unload)
|
|
#endif
|
|
|
|
//
|
|
// Allow debug output for this moduel, and set the intial level
|
|
//
|
|
DECLARE_MODULE_DEBUG_LEVEL((DBG_WARN|DBG_ERROR|DBG_CRITICAL));
|
|
|
|
//
|
|
// Instance the global variables
|
|
//
|
|
GCK_GLOBALS Globals;
|
|
ULONG ulWaitTime = 30;
|
|
|
|
#ifdef BUILD_98
|
|
|
|
#pragma data_seg("_LDATA", "LCODE")
|
|
LONG g_lHookRefCount = 0;
|
|
ULONG g_rgdwKeyEvents[50] = { 0 };
|
|
ULONG g_pPreviousKeyhook = 0;
|
|
UCHAR g_ucWriteIndex = 0;
|
|
UCHAR g_ucReadIndex = 0;
|
|
#pragma data_seg()
|
|
|
|
#pragma code_seg("_LTEXT", "LCODE")
|
|
#endif BUILD_98
|
|
|
|
void KeyHookC(ULONG dwScanCode)
|
|
{
|
|
#ifdef BUILD_98
|
|
g_rgdwKeyEvents[g_ucWriteIndex++] = dwScanCode;
|
|
if (g_ucWriteIndex >= 50)
|
|
{
|
|
g_ucWriteIndex = 0;
|
|
}
|
|
#else !BUILD_98
|
|
UNREFERENCED_PARAMETER (dwScanCode);
|
|
#endif BUILD_98
|
|
}
|
|
|
|
#ifdef BUILD_98
|
|
//-----------------------------------------------------------------------------
|
|
// InitHook - Sets up the keyboard hook
|
|
//-----------------------------------------------------------------------------
|
|
BOOLEAN HookKeyboard(void)
|
|
{
|
|
volatile ULONG dwHook = (ULONG)KeyBoardHook;
|
|
|
|
RtlZeroMemory((void*)g_rgdwKeyEvents, sizeof(ULONG) * 50);
|
|
g_ucWriteIndex = 0;
|
|
g_ucReadIndex = 0;
|
|
// GetVxDServiceOrdinal eax, VKD_Filter_Keyboard_Input
|
|
__asm mov eax, __VKD_Filter_Keyboard_Input
|
|
|
|
__asm mov esi, dwHook
|
|
VxDCall(__Hook_Device_Service)
|
|
__asm jc initfail
|
|
__asm mov [g_pPreviousKeyhook], esi // Since we are using C we can't use the funky callback
|
|
return TRUE;
|
|
initfail:
|
|
return FALSE;
|
|
};
|
|
#pragma code_seg()
|
|
|
|
|
|
void UnHookKeyboard()
|
|
{
|
|
volatile ULONG dwHook = (ULONG)KeyBoardHook;
|
|
|
|
// GetVxDServiceOrdinal eax, VKD_Filter_Keyboard_Input
|
|
__asm mov eax, __VKD_Filter_Keyboard_Input
|
|
__asm mov esi, dwHook
|
|
VxDCall(__Unhook_Device_Service)
|
|
__asm clc
|
|
}
|
|
#endif BUILD_98
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath )
|
|
**
|
|
** @func Standard DriverEntry routine
|
|
**
|
|
** @rdesc STATUS_SUCCESS or various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS DriverEntry
|
|
(
|
|
IN PDRIVER_OBJECT pDriverObject, // @parm Driver Object
|
|
IN PUNICODE_STRING puniRegistryPath // @parm Path to driver specific registry section.
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SUCCESS;
|
|
int i;
|
|
|
|
UNREFERENCED_PARAMETER (puniRegistryPath);
|
|
|
|
PAGED_CODE();
|
|
GCK_DBG_CRITICAL_PRINT(("Built %s at %s\n", __DATE__, __TIME__));
|
|
GCK_DBG_CRITICAL_PRINT(("Entering DriverEntry, pDriverObject = 0x%0.8x, puniRegistryPath = %s\n", pDriverObject, puniRegistryPath));
|
|
|
|
// Allow Control Device module to initialize itself
|
|
NtStatus = GCK_CTRL_DriverEntry(pDriverObject, puniRegistryPath);
|
|
if( NT_ERROR(NtStatus) )
|
|
{
|
|
return NtStatus;
|
|
}
|
|
|
|
// Allow Filter Device module to initialize itself
|
|
NtStatus = GCK_FLTR_DriverEntry(pDriverObject, puniRegistryPath);
|
|
if( NT_ERROR(NtStatus) )
|
|
{
|
|
return NtStatus;
|
|
}
|
|
|
|
// Allow SideWinder Virtual Bus module to initialize itself
|
|
NtStatus = GCK_SWVB_DriverEntry(pDriverObject, puniRegistryPath);
|
|
if( NT_ERROR(NtStatus) )
|
|
{
|
|
return NtStatus;
|
|
}
|
|
|
|
// Allow SideWinder Virtual Keyboard module to initialize itself
|
|
NtStatus = GCK_VKBD_DriverEntry(pDriverObject, puniRegistryPath);
|
|
if( NT_ERROR(NtStatus) )
|
|
{
|
|
return NtStatus;
|
|
}
|
|
|
|
// Hook all IRPs so we can pass them on.
|
|
GCK_DBG_TRACE_PRINT(("Filling out entry point structure\n"));
|
|
for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
|
{
|
|
pDriverObject->MajorFunction[i] = GCK_Pass;
|
|
}
|
|
|
|
// Initialize any shared global data
|
|
#ifdef BUILD_98
|
|
g_lHookRefCount = 0;
|
|
#endif
|
|
|
|
// Define entries for IRPs we expect to handle
|
|
pDriverObject->MajorFunction[IRP_MJ_CREATE] = GCK_Create;
|
|
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = GCK_Close;
|
|
pDriverObject->MajorFunction[IRP_MJ_READ] = GCK_Read;
|
|
pDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
|
|
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GCK_Ioctl;
|
|
pDriverObject->MajorFunction[IRP_MJ_PNP] = GCK_PnP;
|
|
pDriverObject->MajorFunction[IRP_MJ_POWER] = GCK_Power;
|
|
pDriverObject->DriverExtension->AddDevice = GCK_FLTR_AddDevice; //only the filter has an add device
|
|
pDriverObject->DriverUnload = GCK_Unload;
|
|
|
|
GCK_DBG_EXIT_PRINT (("Normal exit of DriverEntry: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** VOID GCK_Unload(IN PDRIVER_OBJECT pDriverObject )
|
|
**
|
|
** @func Called to unload driver, delete Control Device here
|
|
**
|
|
*************************************************************************************/
|
|
VOID GCK_Unload
|
|
(
|
|
IN PDRIVER_OBJECT pDriverObject // @parm Driver Object for our driver
|
|
)
|
|
{
|
|
PAGED_CODE ();
|
|
|
|
GCK_DBG_ENTRY_PRINT(("Entering GCK_Unload, pDriverObject = 0x%0.8x\n", pDriverObject));
|
|
|
|
UNREFERENCED_PARAMETER(pDriverObject);
|
|
|
|
GCK_SWVB_UnLoad();
|
|
|
|
//
|
|
// We should not be unloaded until all the PDOs have been removed from
|
|
// our queue. The control device object should be the only thing left.
|
|
//
|
|
ASSERT (NULL == pDriverObject->DeviceObject);
|
|
ASSERT (NULL == Globals.pControlObject);
|
|
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Unload\n"));
|
|
return;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_Create ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
|
|
**
|
|
** @func Handles the IRP_MJ_CREATE - Generated by Win32 CreateFile or OpenFile
|
|
**
|
|
** @rdesc STATUS_SUCCESS, or various error codes
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_Create (
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object for context of IRP
|
|
IN PIRP pIrp // @parm pointer to IRP
|
|
)
|
|
{
|
|
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType;
|
|
|
|
PAGED_CODE ();
|
|
|
|
GCK_DBG_ENTRY_PRINT (("GCK_Create, pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
KdPrint(("GCK_Create, pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_CONTROL:
|
|
KdPrint((" -- GCK_DO_TYPE_CONTROL\n"));
|
|
NtStatus = GCK_CTRL_Create(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_FILTER:
|
|
KdPrint((" -- GCK_DO_TYPE_FILTER\n"));
|
|
NtStatus = GCK_FLTR_Create(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_SWVB:
|
|
KdPrint((" -- GCK_DO_TYPE_SWVB\n"));
|
|
NtStatus = GCK_SWVB_Create(pDeviceObject, pIrp);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
}
|
|
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Create. Status: 0x%0.8x\n", NtStatus));
|
|
KdPrint(("Exiting GCK_Create. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_Close ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
|
|
**
|
|
** @func Handles IRP_MJ_CLOSE - Generated by Win32 CloseFile
|
|
**
|
|
** @rdesc STATUS_SUCCESS or various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_Close (
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm pointer DeviceObject for context
|
|
IN PIRP pIrp // @parm pointer to IRP to handle
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
|
|
PAGED_CODE ();
|
|
|
|
GCK_DBG_ENTRY_PRINT (("GCK_Close, pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_CONTROL:
|
|
NtStatus = GCK_CTRL_Close(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_FILTER:
|
|
NtStatus = GCK_FLTR_Close(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_SWVB:
|
|
NtStatus = GCK_SWVB_Close(pDeviceObject, pIrp);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
}
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Close. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_Read (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
|
|
**
|
|
** @func Handles IRP_MJ_READ - Generated by Win32 ReadFile
|
|
**
|
|
** @rdesc STATUS_SUCCESS, or various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_Read
|
|
(
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object as our context
|
|
IN PIRP pIrp // @parm IRP to handle
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType;
|
|
|
|
GCK_DBG_RT_ENTRY_PRINT(("Entering GCK_Read. pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_CONTROL:
|
|
NtStatus = STATUS_NOT_SUPPORTED;
|
|
//Assert as we shouldn't get read on the control device
|
|
ASSERT( NT_SUCCESS(NtStatus) );
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
break;
|
|
case GCK_DO_TYPE_FILTER:
|
|
NtStatus = GCK_FLTR_Read(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_SWVB:
|
|
NtStatus = GCK_SWVB_Read(pDeviceObject, pIrp);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Read. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_Power (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
|
|
**
|
|
** @func Handles IRP_MJ_POWER
|
|
**
|
|
** @rdesc STATUS_SUCCESS, or various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_Power
|
|
(
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object for our context
|
|
IN PIRP pIrp // @parm IRP to handle
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType;
|
|
|
|
GCK_DBG_ENTRY_PRINT(("Entering GCK_Power. pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_CONTROL:
|
|
NtStatus = STATUS_NOT_SUPPORTED;
|
|
//Assert as we shouldn't get power on the control device
|
|
ASSERT( NT_SUCCESS(NtStatus) );
|
|
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
|
|
break;
|
|
case GCK_DO_TYPE_FILTER:
|
|
NtStatus = GCK_FLTR_Power(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_SWVB:
|
|
NtStatus = GCK_SWVB_Power(pDeviceObject, pIrp);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Power. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_PnP (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
|
|
**
|
|
** @func Handles IRP_MJ_PnP
|
|
**
|
|
** @rdesc STATUS_SUCCESS, or various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_PnP
|
|
(
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object for our context
|
|
IN PIRP pIrp // @parm IRP to handle
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType;
|
|
|
|
GCK_DBG_ENTRY_PRINT(("Entering GCK_PnP. pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_CONTROL:
|
|
NtStatus = STATUS_NOT_SUPPORTED;
|
|
//Assert as we shouldn't get PnP on the control device
|
|
ASSERT( NT_SUCCESS(NtStatus) );
|
|
pIrp->IoStatus.Status = NtStatus;
|
|
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
|
|
break;
|
|
case GCK_DO_TYPE_FILTER:
|
|
NtStatus = GCK_FLTR_PnP(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_SWVB:
|
|
NtStatus = GCK_SWVB_PnP(pDeviceObject, pIrp);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_PnP. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_Ioctl (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
|
|
**
|
|
** @func Handles IRP_MJ_IOCTL and IRP_MJ_INTERNAL_IOCTL
|
|
**
|
|
** @rdesc STATUS_SUCCES, or various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_Ioctl
|
|
(
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm pointer to Device Object
|
|
IN PIRP pIrp // @parm pointer to IRP
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType;
|
|
ULONG uIoctl;
|
|
|
|
PIO_STACK_LOCATION pIrpStack;
|
|
|
|
|
|
GCK_DBG_ENTRY_PRINT(("Entering GCK_Ioctl. pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
|
|
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
|
|
uIoctl = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
|
|
if (uIoctl == IOCTL_GCK_ENABLE_KEYHOOK)
|
|
{ // Special case IOCTL, device independant
|
|
#ifdef BUILD_WIN2K
|
|
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
#else !BUILD_WIN2K
|
|
if (InterlockedIncrement(&g_lHookRefCount) == 1)
|
|
{ // Not already hooked
|
|
HookKeyboard();
|
|
}
|
|
pIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
#endif BUILD_WIN2K
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
if (uIoctl == IOCTL_GCK_DISABLE_KEYHOOK)
|
|
{ // Special case also device independant
|
|
#ifdef BUILD_WIN2K
|
|
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
#else !BUILD_WIN2K
|
|
if (InterlockedDecrement(&g_lHookRefCount) < 1)
|
|
{ // Last hooker is going away
|
|
UnHookKeyboard();
|
|
g_lHookRefCount = 0;
|
|
}
|
|
pIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
#endif BUILD_WIN2K
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
if (uIoctl == IOCTL_GCK_GET_KEYHOOK_DATA)
|
|
{
|
|
#ifdef BUILD_WIN2K
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
#else !BUILD_WIN2K
|
|
ULONG uOutLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
|
|
if (uOutLength < sizeof(ULONG))
|
|
{
|
|
NtStatus = STATUS_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
ULONG* pulIoBuffer = (ULONG*)(pIrp->AssociatedIrp.SystemBuffer);
|
|
*pulIoBuffer = 0;
|
|
pIrp->IoStatus.Information = sizeof(ULONG);
|
|
NtStatus = STATUS_SUCCESS;
|
|
|
|
if (g_lHookRefCount > 0)
|
|
{ // There is a hook
|
|
if (g_ucWriteIndex != g_ucReadIndex)
|
|
{ // We have data in the Queue
|
|
*pulIoBuffer = g_rgdwKeyEvents[g_ucReadIndex++];
|
|
if (g_ucReadIndex >= 50)
|
|
{
|
|
g_ucReadIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif BUILD_WIN2K
|
|
pIrp->IoStatus.Status = NtStatus;
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
return NtStatus;
|
|
}
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_CONTROL:
|
|
NtStatus = GCK_CTRL_Ioctl(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_FILTER:
|
|
NtStatus = GCK_FLTR_Ioctl(pDeviceObject, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_SWVB:
|
|
NtStatus = GCK_SWVB_Ioctl(pDeviceObject, pIrp);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Ioctl. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|
|
/***********************************************************************************
|
|
**
|
|
** NTSTATUS GCK_Pass ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
|
|
**
|
|
** @func Passes on unhandled IRPs to lower drivers DEBUG version trace out info
|
|
** Cannot be pageable since we have no idea what IRPs we're getting.
|
|
**
|
|
** @rdesc STATUS_SUCCESS, various errors
|
|
**
|
|
*************************************************************************************/
|
|
NTSTATUS GCK_Pass (
|
|
IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object as our context
|
|
IN PIRP pIrp // @parm IRP to pass on
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG ulGckDevObjType;
|
|
PGCK_FILTER_EXT pFilterExt;
|
|
|
|
// Debug version want IRP stack for traceouts.
|
|
#if (DBG==1)
|
|
PIO_STACK_LOCATION pIrpStack;
|
|
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
|
|
#endif
|
|
|
|
GCK_DBG_ENTRY_PRINT(("Entering GCK_Pass. pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
|
|
GCK_DBG_TRACE_PRINT(
|
|
(
|
|
"GCK_Pass called with Irp MajorFunction = 0x%0.8x, MinorFunction = 0x%0.8x\n",
|
|
pIrpStack->MajorFunction, pIrpStack->MinorFunction)
|
|
);
|
|
|
|
ulGckDevObjType = *(PULONG)pDeviceObject->DeviceExtension;
|
|
switch(ulGckDevObjType)
|
|
{
|
|
case GCK_DO_TYPE_FILTER:
|
|
GCK_DBG_TRACE_PRINT(( "Passing IRP to lower driver\n"));
|
|
pFilterExt = (PGCK_FILTER_EXT)pDeviceObject->DeviceExtension;
|
|
IoSkipCurrentIrpStackLocation (pIrp);
|
|
NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
|
|
break;
|
|
case GCK_DO_TYPE_CONTROL:
|
|
case GCK_DO_TYPE_SWVB:
|
|
// No one to pass to, so return default status
|
|
NtStatus = pIrp->IoStatus.Status;
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
break;
|
|
default:
|
|
//
|
|
// If this assertion is hit, this Device Object was never properly initialized
|
|
// by GcKernel, or it has been trashed.
|
|
//
|
|
ASSERT(FALSE);
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
|
|
};
|
|
|
|
//return
|
|
GCK_DBG_EXIT_PRINT(("Exiting GCK_Pass. Status: 0x%0.8x\n", NtStatus));
|
|
return NtStatus;
|
|
}
|
|
|