396 lines
10 KiB
C
396 lines
10 KiB
C
|
|
/*++
|
|
|
|
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.
|
|
* <nl>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 */
|
|
|