2025-04-27 07:49:33 -04:00

375 lines
8.6 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
HIDMON.c
Abstract
Driver for the HID Descriptor tool. Provides an interface to
Input.sys so that the tool may register and send data as a
HID device.
Author:
John Piece
Environment:
Kernel mode
Revision History:
--*/
#include <NTDDK.H>
#include <HIDCLASS.H>
#include <hidmon.h>
#ifdef DEBUG
#pragma message("Debug Defined")
#endif
typedef unsigned short WORD;
//
// Specify pagable functions
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
//#pragma alloc_text(INIT,CreateNewDevice)
#endif
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING RegistryPath;
ULONG gDeviceID;
ULONG gDeviceObj;
/*++
Routine Description:
Installable driver initialization entry point.
Arguments:
DriverObject - pointer to driver object.
registrypath - pointer to unicode string pointer registery entry.
Return Value:
STATUS_SUCCESS, STATUS_UNSUCCESSFUL.
--*/
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT driverObject,
IN PUNICODE_STRING registryPath )
{
PDEVICE_OBJECT deviceObject = NULL;
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING HidmonDeviceName;
UNICODE_STRING HidmonDosDeviceName;
DbgPrint("HIDMON.SYS: DriverEntry Enter\n");
//
// Create NULL terminated registry path
//
// RegistryPath.Length = registryPath->Length;
// RegistryPath.MaximumLength = RegistryPath.Length + sizeof(UNICODE_NULL) + sizeof(L"\\Parameters\\Test");
// RegistryPath.Buffer = ExAllocatePool(PagedPool, RegistryPath.MaximumLength);
// if(!RegistryPath.Buffer)
// return STATUS_UNSUCCESSFUL;
// RtlZeroMemory(RegistryPath.Buffer, RegistryPath.MaximumLength);
// RtlMoveMemory(RegistryPath.Buffer, registryPath->Buffer, RegistryPath.Length);
//
// Save the driver object
//
DriverObject = driverObject;
//
// Create a named control device, so that we get IRPs.
//
RtlInitUnicodeString( &HidmonDeviceName, HIDMON_DEVICE_NAME );
ntStatus = IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
&HidmonDeviceName,
FILE_DEVICE_TEST,
0,
FALSE,
&deviceObject);
//
// Create a symbolic link that Win32 apps can specify to gain access
// to this driver
//
RtlInitUnicodeString(&HidmonDosDeviceName,HIDMON_LINK_NAME);
ntStatus = IoCreateSymbolicLink(&HidmonDosDeviceName, &HidmonDeviceName );
//
// Create dispatch points
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = HIDMONCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = HIDMONCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HIDMONControl;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HIDMONControl;
DriverObject->DriverUnload = HIDMONDestructor;
DbgPrint("HIDMON.SYS: DriverEntry Exit\n");
return STATUS_SUCCESS;
}
/*++
Routine Description:
handles create and close irps.
Arguments:
DriverObject - pointer to driver object.
Irp - pointer to Interrupt Request Packet.
Return Value:
STATUS_SUCCESS, STATUS_UNSUCCESSFUL.
--*/
NTSTATUS
HIDMONCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
NTSTATUS ntStatus;
//
// Get a pointer to the current location in the Irp.
//
irpStack = IoGetCurrentIrpStackLocation(Irp);
switch(irpStack->MajorFunction)
{
case IRP_MJ_CREATE:
//Irp->IoStatus.Information = 0;
ntStatus = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
//Irp->IoStatus.Information = 0;
ntStatus = STATUS_SUCCESS;
break;
default:
ntStatus = STATUS_INVALID_PARAMETER;
break;
}
//
// Save Status for return and complete irp
//
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
/*****************************************************************++
Routine Description:
Process the IRPs sent to this device.
Arguments:
DriverObject - pointer to driver object.
Irp - pointer to Interrupt Request Packet.
Return Value:
NT status code.
****************************************************************--*/
NTSTATUS
HIDMONControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack;
PWSTR pDevice,*ppDeviceList;
PWSTR ptmp;
//
// Get a pointer to the current location in the Irp
//
IrpStack = IoGetCurrentIrpStackLocation(Irp);
//
// Get a pointer to the device extension
//
DeviceExtension = DeviceObject->DeviceExtension;
switch(IrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_GET_DEVICE_CLASS_ASSOC:
{
ULONG size=0;
GUID MyGUID;
MyGUID.Data1 = 0x4D1E55B2L;
MyGUID.Data2 = 0xF16F;
MyGUID.Data3 = 0x11CF;
MyGUID.Data4[0]= 0x88;
MyGUID.Data4[1]= 0xCB;
MyGUID.Data4[2]= 0x00;
MyGUID.Data4[3]= 0x11;
MyGUID.Data4[4]= 0x11;
MyGUID.Data4[5]= 0x00;
MyGUID.Data4[6]= 0x00;
MyGUID.Data4[7]= 0x30;
DbgPrint("HIDMON.SYS: Enter IOCTL_GET_DEVICE_CLASS_ASSOC\n");
//
// Make the call to get the list of devices
//
ntStatus = IoGetDeviceClassAssociations(&MyGUID,ppDeviceList);
if( (ntStatus == STATUS_SUCCESS) && *ppDeviceList)
{
ptmp = *ppDeviceList;
while( **ppDeviceList != UNICODE_NULL )
{
pDevice = *ppDeviceList;
while(*pDevice++ != UNICODE_NULL)
size ++;
size += sizeof(UNICODE_NULL);
*ppDeviceList += size;
}
//TESTING!!
//size+=128;
size += sizeof(UNICODE_NULL)*2; // include the NULL
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,ptmp,size*2);
Irp->IoStatus.Information = size*2;
}
else
ntStatus = STATUS_NO_MORE_FILES;
DbgPrint("HIDMON.SYS: Leave IOCTL_GET_DEVICE_CLASS_ASSOC\n");
}
break;
default:
ntStatus = STATUS_INVALID_PARAMETER;
break;
}
//
// Save Status for return and complete irp
//
Irp->IoStatus.Status = ntStatus;
if(ntStatus == STATUS_PENDING)
{
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, (PULONG) NULL, NULL);
}
else
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to driver object.
Return Value:
STATUS_SUCCESS, STATUS_UNSUCCESSFUL. STATUS_SHARING_VIOLATION, STATUS_INVALID_PARAMETER.
--*/
VOID
HIDMONDestructor(
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
UNICODE_STRING deviceLinkUnicodeString;
DbgPrint("HIDMON.SYS: HIDMONDestructor() Entry\n");
//
// Walk the DriverObject->DeviceObject list freeing as we go
//
while( DeviceObject )
{
IoDeleteDevice(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
RtlInitUnicodeString(&deviceLinkUnicodeString,HIDMON_LINK_NAME);
IoDeleteSymbolicLink(&deviceLinkUnicodeString);
IoDeleteDevice(DeviceObject);
DbgPrint("HIDMON.SYS: DeviceObject: %08X deleted\n",DeviceObject);
DbgPrint("HIDMON.SYS: HIDMONDestructor() Exit\n");
}