/*++ Copyright (c) 1998 - 1999 Microsoft Corporation Module Name: hidgame.c Abstract: Human Interface Device (HID) Gameport driver Environment: Kernel mode @@BEGIN_DDKSPLIT Author: Eliyas Yakub (Mar, 10, 1997) Revision History: Updated by Eliyas on Feb 5 1998 OmSharma ( April 12, 1998 ) MarcAnd 02-Jul-98 Quick tidy for DDK @@END_DDKSPLIT --*/ #include "hidgame.h" #ifdef ALLOC_PRAGMA #pragma alloc_text( INIT, DriverEntry ) #pragma alloc_text( PAGE, HGM_CreateClose) #pragma alloc_text( PAGE, HGM_AddDevice) #pragma alloc_text( PAGE, HGM_Unload) #pragma alloc_text( PAGE, HGM_SystemControl) #endif /* ALLOC_PRAGMA */ HIDGAME_GLOBAL Global; ULONG debugLevel; /***************************************************************************** * * @doc EXTERNAL * * @func NTSTATUS | DriverEntry | * * Installable driver initialization entry point. * This entry point is called directly by the I/O system. * * @parm IN PDRIVER_OBJECT | DriverObject | * * Pointer to the driver object * * @parm IN PUNICODE_STRING | RegistryPath | * * Pointer to a unicode string representing the path, * to driver-specific key in the registry. * * @rvalue STATUS_SUCCESS | success * @rvalue ??? | returned HidRegisterMinidriver() * *****************************************************************************/ NTSTATUS EXTERNAL DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS ntStatus; HID_MINIDRIVER_REGISTRATION hidMinidriverRegistration; debugLevel = HGM_DEFAULT_DEBUGLEVEL; HGM_DBGPRINT(FILE_HIDGAME| HGM_WARN, \ ("Hidgame.sys: Built %s at %s\n", __DATE__, __TIME__)); HGM_DBGPRINT( FILE_HIDGAME | HGM_FENTRY, ("DriverEntry(DriverObject=0x%x,RegistryPath=0x%x)", DriverObject, RegistryPath) ); C_ASSERT(sizeof( OEMDATA[2] ) == sizeof(GAMEENUM_OEM_DATA) ); ntStatus = HGM_DriverInit(); if( NT_SUCCESS(ntStatus) ) { DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = HGM_CreateClose; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HGM_InternalIoctl; DriverObject->MajorFunction[IRP_MJ_PNP] = HGM_PnP; DriverObject->MajorFunction[IRP_MJ_POWER] = HGM_Power; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HGM_SystemControl; DriverObject->DriverUnload = HGM_Unload; DriverObject->DriverExtension->AddDevice = HGM_AddDevice; /* * Register with HID.SYS module */ RtlZeroMemory(&hidMinidriverRegistration, sizeof(hidMinidriverRegistration)); hidMinidriverRegistration.Revision = HID_REVISION; hidMinidriverRegistration.DriverObject = DriverObject; hidMinidriverRegistration.RegistryPath = RegistryPath; hidMinidriverRegistration.DeviceExtensionSize = sizeof(DEVICE_EXTENSION); hidMinidriverRegistration.DevicesArePolled = TRUE; HGM_DBGPRINT( FILE_HIDGAME | HGM_BABBLE2, ("DeviceExtensionSize = %d", hidMinidriverRegistration.DeviceExtensionSize) ); ntStatus = HidRegisterMinidriver(&hidMinidriverRegistration); HGM_DBGPRINT(FILE_HIDGAME | HGM_BABBLE2, ("Registered with HID.SYS, returnCode=%x", ntStatus) ); if( NT_SUCCESS(ntStatus) ) { /* * Protect the list with a Mutex */ ExInitializeFastMutex (&Global.Mutex); /* * Initialize the device list head */ InitializeListHead(&Global.DeviceListHead); /* * Initialize gameport access spinlock */ KeInitializeSpinLock(&Global.SpinLock); } else { HGM_DBGPRINT(FILE_HIDGAME | HGM_ERROR, ("Failed to registered with HID.SYS, returnCode=%x", ntStatus) ); } } else { HGM_DBGPRINT(FILE_HIDGAME | HGM_ERROR, ("Failed to initialize a timer") ); } HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK , "DriverEntry", ntStatus); return ntStatus; } /* DriverEntry */ /***************************************************************************** * * @doc EXTERNAL * * @func NTSTATUS | HGM_CreateClose | * * Process the create and close IRPs sent to this device. * * @parm IN PDEVICE_OBJECT | DeviceObject | * * Pointer to the device object * * @parm IN PIRP | Irp | * * Pointer to an I/O Request Packet. * * @rvalue STATUS_SUCCESS | success * @rvalue STATUS_INVALID_PARAMETER | Irp not handled * *****************************************************************************/ NTSTATUS EXTERNAL HGM_CreateClose ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION IrpStack; NTSTATUS ntStatus = STATUS_SUCCESS; PAGED_CODE (); HGM_DBGPRINT(FILE_HIDGAME | HGM_FENTRY, ("HGM_CreateClose(DeviceObject=0x%x,Irp=0x%x)", DeviceObject, Irp) ); /* * Get a pointer to the current location in the Irp. */ IrpStack = IoGetCurrentIrpStackLocation(Irp); switch(IrpStack->MajorFunction) { case IRP_MJ_CREATE: HGM_DBGPRINT(FILE_HIDGAME | HGM_BABBLE, ("HGM_CreateClose:IRP_MJ_CREATE") ); Irp->IoStatus.Information = 0; break; case IRP_MJ_CLOSE: HGM_DBGPRINT(FILE_HIDGAME | HGM_BABBLE, ("HGM_CreateClose:IRP_MJ_CLOSE") ); Irp->IoStatus.Information = 0; break; default: HGM_DBGPRINT(FILE_HIDGAME | HGM_WARN, ("HGM_CreateClose:Not handled IrpStack->MajorFunction 0x%x", IrpStack->MajorFunction) ); ntStatus = STATUS_INVALID_PARAMETER; break; } /* * Save Status for return and complete Irp */ Irp->IoStatus.Status = ntStatus; IoCompleteRequest(Irp, IO_NO_INCREMENT); HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK, "HGM_CreateClose", ntStatus); return ntStatus; } /* HGM_CreateClose */ /***************************************************************************** * * @doc EXTERNAL * * @func NTSTATUS | HGM_AddDevice | * * Called by hidclass, allows us to initialize our device extensions. * * @parm IN PDRIVER_OBJECT | DriverObject | * * Pointer to the driver object * * @parm IN PDEVICE_OBJECT | FunctionalDeviceObject | * * Pointer to a functional device object created by hidclass. * * @rvalue STATUS_SUCCESS | success * *****************************************************************************/ NTSTATUS EXTERNAL HGM_AddDevice ( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT FunctionalDeviceObject ) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_OBJECT DeviceObject; PDEVICE_EXTENSION DeviceExtension; PAGED_CODE (); HGM_DBGPRINT( FILE_HIDGAME | HGM_FENTRY, ("HGM_AddDevice(DriverObject=0x%x,FunctionalDeviceObject=0x%x)", DriverObject, FunctionalDeviceObject) ); ASSERTMSG("HGM_AddDevice:", FunctionalDeviceObject != NULL); DeviceObject = FunctionalDeviceObject; /* * Initialize the device extension. */ DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject); DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; /* * Initialize the list */ InitializeListHead(&DeviceExtension->Link); /* * Acquire mutex before modifying the Global Linked list of devices */ ExAcquireFastMutex (&Global.Mutex); /* * Add this device to the linked list of devices */ InsertTailList(&Global.DeviceListHead, &DeviceExtension->Link); /* * Release the mutex */ ExReleaseFastMutex (&Global.Mutex); /* * Initialize the remove lock */ DeviceExtension->RequestCount = 1; KeInitializeEvent(&DeviceExtension->RemoveEvent, SynchronizationEvent, FALSE); HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK, "HGM_AddDevice", ntStatus); return ntStatus; } /* HGM_AddDevice */ /***************************************************************************** * * @doc EXTERNAL * * @func NTSTATUS | HGM_SystemControl | * * Process the WMI IRPs sent to this device. * * @parm IN PDEVICE_OBJECT | DeviceObject | * * Pointer to the device object * * @parm IN PIRP | Irp | * * Pointer to an I/O Request Packet. * * @rvalue STATUS_SUCCESS | success * @rvalue STATUS_INVALID_PARAMETER | Irp not handled * *****************************************************************************/ NTSTATUS EXTERNAL HGM_SystemControl ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PAGED_CODE (); HGM_DBGPRINT(FILE_HIDGAME | HGM_FENTRY, ("HGM_SystemControl(DeviceObject=0x%x,Irp=0x%x)", DeviceObject, Irp) ); IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp); } /* HGM_SystemControl */ /***************************************************************************** * * @doc EXTERNAL * * @func void | HGM_Unload | * * Free all the allocated resources, etc. * * @parm IN PDRIVER_OBJECT | DeviceObject | * * Pointer to the driver object * * *****************************************************************************/ VOID EXTERNAL HGM_Unload ( IN PDRIVER_OBJECT DriverObject ) { PAGED_CODE(); HGM_DBGPRINT(FILE_HIDGAME | HGM_FENTRY, ("HGM_Unload Enter")); /* * All the device objects should be gone */ ASSERT ( NULL == DriverObject->DeviceObject); HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK, "HGM_Unload:", STATUS_SUCCESS ); return; } /* HGM_Unload */