windows-nt/Source/XPSP1/NT/drivers/wdm/input/legacy/hidgame/hidgame.c
2020-09-26 16:20:57 +08:00

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 */