|
|
/*++
Copyright (c) 1996,1997 Microsoft Corporation
Module Name:
hidir.c
Abstract: Human Input Device (HID) minidriver that creates an example device.
--*/ #include "pch.h"
VOID HidIrCheckIfMediaCenter();
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(INIT,HidIrCheckIfMediaCenter)
#endif
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath ) /*++
Routine Description:
Installable driver initialization entry point. This entry point is called directly by the I/O system.
Arguments:
DriverObject - pointer to the driver object
registryPath - pointer to a unicode string representing the path, to driver-specific key in the registry.
Return Value:
STATUS_SUCCESS if successful, STATUS_UNSUCCESSFUL otherwise
--*/ { NTSTATUS status = STATUS_SUCCESS; HID_MINIDRIVER_REGISTRATION HidIrdriverRegistration;
HidIrKdPrint((3, "DriverEntry Enter"));
HidIrKdPrint((3, "DriverObject (%lx)", DriverObject));
//
// Create dispatch points
//
// All of the other dispatch routines are handled by HIDCLASS, except for
// IRP_MJ_POWER, which isn't implemented yet.
//
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HidIrIoctl; DriverObject->MajorFunction[IRP_MJ_PNP] = HidIrPnP; DriverObject->MajorFunction[IRP_MJ_POWER] = HidIrPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidIrSystemControl; DriverObject->DriverExtension->AddDevice = HidIrAddDevice; DriverObject->DriverUnload = HidIrUnload;
//
// Register Sample layer with HIDCLASS.SYS module
//
HidIrdriverRegistration.Revision = HID_REVISION; HidIrdriverRegistration.DriverObject = DriverObject; HidIrdriverRegistration.RegistryPath = registryPath; HidIrdriverRegistration.DeviceExtensionSize = sizeof(HIDIR_EXTENSION);
// HIDIR does not need to be polled.
HidIrdriverRegistration.DevicesArePolled = FALSE;
HidIrKdPrint((3, "DeviceExtensionSize = %x", HidIrdriverRegistration.DeviceExtensionSize));
HidIrKdPrint((3, "Registering with HIDCLASS.SYS"));
HidIrCheckIfMediaCenter();
//
// After registering with HIDCLASS, it takes over control of the device, and sends
// things our way if they need device specific processing.
//
status = HidRegisterMinidriver(&HidIrdriverRegistration);
HidIrKdPrint((3, "DriverEntry Exit = %x", status));
return status; }
ULONG RunningMediaCenter;
VOID HidIrCheckIfMediaCenter() { OBJECT_ATTRIBUTES attributes; HANDLE skuRegKey; NTSTATUS status; ULONG resultLength; UNICODE_STRING regString; UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( ULONG )];
PAGED_CODE(); RunningMediaCenter = 0;
//
// Open the MediaCenter SKU registry key
//
RtlInitUnicodeString( ®String, L"\\REGISTRY\\MACHINE\\SYSTEM\\WPA\\MediaCenter" ); InitializeObjectAttributes( &attributes, ®String, OBJ_CASE_INSENSITIVE, NULL, NULL );
status = ZwOpenKey( &skuRegKey, KEY_READ, &attributes );
if (!NT_SUCCESS( status )) { return; }
//
// Read the Installed value from the registry.
//
RtlInitUnicodeString( ®String, L"Installed" );
status = ZwQueryValueKey( skuRegKey, ®String, KeyValuePartialInformation, buffer, sizeof(buffer), &resultLength );
if (NT_SUCCESS( status )) { PKEY_VALUE_PARTIAL_INFORMATION info = (PKEY_VALUE_PARTIAL_INFORMATION) buffer; if (info->DataLength == sizeof(ULONG)) { RunningMediaCenter = *((ULONG*) &((info)->Data)); } }
//
// Close the registry entry
//
ZwClose(skuRegKey); }
NTSTATUS HidIrAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject ) /*++
Routine Description:
Process AddDevice. Provides the opportunity to initialize the DeviceObject or the DriverObject.
Arguments:
DriverObject - pointer to the driver object.
DeviceObject - pointer to a device object.
Return Value:
NT status code.
--*/ { NTSTATUS status = STATUS_SUCCESS; PHIDIR_EXTENSION deviceExtension; LARGE_INTEGER timeout; timeout.HighPart = -1; timeout.LowPart = -1;
HidIrKdPrint((3, "HidIrAddDevice Entry"));
deviceExtension = GET_MINIDRIVER_HIDIR_EXTENSION( DeviceObject );
deviceExtension->NumPendingRequests = 0; KeInitializeEvent( &deviceExtension->AllRequestsCompleteEvent, NotificationEvent, FALSE);
deviceExtension->DeviceState = DEVICE_STATE_NONE; deviceExtension->DeviceObject = DeviceObject; deviceExtension->VersionNumber = 0x110; // deviceExtension->VendorID = 0x045e;
// deviceExtension->ProductID = 0x006d;
// Predispose timer to signalled.
KeInitializeTimer(&deviceExtension->IgnoreStandbyTimer); KeSetTimer(&deviceExtension->IgnoreStandbyTimer, timeout, NULL);
HidIrKdPrint((3, "HidIrAddDevice Exit = %x", status));
return status; }
VOID HidIrUnload( IN PDRIVER_OBJECT DriverObject ) /*++
Routine Description:
Free all the allocated resources, etc. in anticipation of this driver being unloaded.
Arguments:
DriverObject - pointer to the driver object.
Return Value:
VOID.
--*/ { HidIrKdPrint((3, "HidIrUnload Enter"));
HidIrKdPrint((3, "Unloading DriverObject = %x", DriverObject));
HidIrKdPrint((3, "Unloading Exit = VOID")); }
NTSTATUS HidIrSynchronousCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { UNREFERENCED_PARAMETER (DeviceObject);
KeSetEvent ((PKEVENT) Context, 1, FALSE); // No special priority
// No Wait
return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP
}
NTSTATUS HidIrCallDriverSynchronous( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { KEVENT event; NTSTATUS status;
// Set next stack location
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, HidIrSynchronousCompletion, &event, // context
TRUE, TRUE, TRUE ); status = IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);
if (status == STATUS_PENDING) { // wait for it...
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = Irp->IoStatus.Status; }
return status; }
|