Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

395 lines
10 KiB

  1. /*++
  2. Copyright (c) 1998 - 1999 Microsoft Corporation
  3. Module Name:
  4. hidgame.c
  5. Abstract: Human Interface Device (HID) Gameport driver
  6. Environment:
  7. Kernel mode
  8. @@BEGIN_DDKSPLIT
  9. Author:
  10. Eliyas Yakub (Mar, 10, 1997)
  11. Revision History:
  12. Updated by Eliyas on Feb 5 1998
  13. OmSharma ( April 12, 1998 )
  14. MarcAnd 02-Jul-98 Quick tidy for DDK
  15. @@END_DDKSPLIT
  16. --*/
  17. #include "hidgame.h"
  18. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text( INIT, DriverEntry )
  20. #pragma alloc_text( PAGE, HGM_CreateClose)
  21. #pragma alloc_text( PAGE, HGM_AddDevice)
  22. #pragma alloc_text( PAGE, HGM_Unload)
  23. #pragma alloc_text( PAGE, HGM_SystemControl)
  24. #endif /* ALLOC_PRAGMA */
  25. HIDGAME_GLOBAL Global;
  26. ULONG debugLevel;
  27. /*****************************************************************************
  28. *
  29. * @doc EXTERNAL
  30. *
  31. * @func NTSTATUS | DriverEntry |
  32. *
  33. * Installable driver initialization entry point.
  34. * <nl>This entry point is called directly by the I/O system.
  35. *
  36. * @parm IN PDRIVER_OBJECT | DriverObject |
  37. *
  38. * Pointer to the driver object
  39. *
  40. * @parm IN PUNICODE_STRING | RegistryPath |
  41. *
  42. * Pointer to a unicode string representing the path,
  43. * to driver-specific key in the registry.
  44. *
  45. * @rvalue STATUS_SUCCESS | success
  46. * @rvalue ??? | returned HidRegisterMinidriver()
  47. *
  48. *****************************************************************************/
  49. NTSTATUS EXTERNAL
  50. DriverEntry
  51. (
  52. IN PDRIVER_OBJECT DriverObject,
  53. IN PUNICODE_STRING RegistryPath
  54. )
  55. {
  56. NTSTATUS ntStatus;
  57. HID_MINIDRIVER_REGISTRATION hidMinidriverRegistration;
  58. debugLevel = HGM_DEFAULT_DEBUGLEVEL;
  59. HGM_DBGPRINT(FILE_HIDGAME| HGM_WARN, \
  60. ("Hidgame.sys: Built %s at %s\n", __DATE__, __TIME__));
  61. HGM_DBGPRINT( FILE_HIDGAME | HGM_FENTRY,
  62. ("DriverEntry(DriverObject=0x%x,RegistryPath=0x%x)",
  63. DriverObject, RegistryPath)
  64. );
  65. C_ASSERT(sizeof( OEMDATA[2] ) == sizeof(GAMEENUM_OEM_DATA) );
  66. ntStatus = HGM_DriverInit();
  67. if( NT_SUCCESS(ntStatus) )
  68. {
  69. DriverObject->MajorFunction[IRP_MJ_CREATE] =
  70. DriverObject->MajorFunction[IRP_MJ_CLOSE] = HGM_CreateClose;
  71. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
  72. HGM_InternalIoctl;
  73. DriverObject->MajorFunction[IRP_MJ_PNP] = HGM_PnP;
  74. DriverObject->MajorFunction[IRP_MJ_POWER] = HGM_Power;
  75. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HGM_SystemControl;
  76. DriverObject->DriverUnload = HGM_Unload;
  77. DriverObject->DriverExtension->AddDevice = HGM_AddDevice;
  78. /*
  79. * Register with HID.SYS module
  80. */
  81. RtlZeroMemory(&hidMinidriverRegistration, sizeof(hidMinidriverRegistration));
  82. hidMinidriverRegistration.Revision = HID_REVISION;
  83. hidMinidriverRegistration.DriverObject = DriverObject;
  84. hidMinidriverRegistration.RegistryPath = RegistryPath;
  85. hidMinidriverRegistration.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
  86. hidMinidriverRegistration.DevicesArePolled = TRUE;
  87. HGM_DBGPRINT( FILE_HIDGAME | HGM_BABBLE2,
  88. ("DeviceExtensionSize = %d",
  89. hidMinidriverRegistration.DeviceExtensionSize)
  90. );
  91. ntStatus = HidRegisterMinidriver(&hidMinidriverRegistration);
  92. HGM_DBGPRINT(FILE_HIDGAME | HGM_BABBLE2,
  93. ("Registered with HID.SYS, returnCode=%x",
  94. ntStatus)
  95. );
  96. if( NT_SUCCESS(ntStatus) )
  97. {
  98. /*
  99. * Protect the list with a Mutex
  100. */
  101. ExInitializeFastMutex (&Global.Mutex);
  102. /*
  103. * Initialize the device list head
  104. */
  105. InitializeListHead(&Global.DeviceListHead);
  106. /*
  107. * Initialize gameport access spinlock
  108. */
  109. KeInitializeSpinLock(&Global.SpinLock);
  110. }
  111. else
  112. {
  113. HGM_DBGPRINT(FILE_HIDGAME | HGM_ERROR,
  114. ("Failed to registered with HID.SYS, returnCode=%x",
  115. ntStatus)
  116. );
  117. }
  118. }
  119. else
  120. {
  121. HGM_DBGPRINT(FILE_HIDGAME | HGM_ERROR,
  122. ("Failed to initialize a timer")
  123. );
  124. }
  125. HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK , "DriverEntry", ntStatus);
  126. return ntStatus;
  127. } /* DriverEntry */
  128. /*****************************************************************************
  129. *
  130. * @doc EXTERNAL
  131. *
  132. * @func NTSTATUS | HGM_CreateClose |
  133. *
  134. * Process the create and close IRPs sent to this device.
  135. *
  136. * @parm IN PDEVICE_OBJECT | DeviceObject |
  137. *
  138. * Pointer to the device object
  139. *
  140. * @parm IN PIRP | Irp |
  141. *
  142. * Pointer to an I/O Request Packet.
  143. *
  144. * @rvalue STATUS_SUCCESS | success
  145. * @rvalue STATUS_INVALID_PARAMETER | Irp not handled
  146. *
  147. *****************************************************************************/
  148. NTSTATUS EXTERNAL
  149. HGM_CreateClose
  150. (
  151. IN PDEVICE_OBJECT DeviceObject,
  152. IN PIRP Irp
  153. )
  154. {
  155. PIO_STACK_LOCATION IrpStack;
  156. NTSTATUS ntStatus = STATUS_SUCCESS;
  157. PAGED_CODE ();
  158. HGM_DBGPRINT(FILE_HIDGAME | HGM_FENTRY,
  159. ("HGM_CreateClose(DeviceObject=0x%x,Irp=0x%x)",
  160. DeviceObject, Irp) );
  161. /*
  162. * Get a pointer to the current location in the Irp.
  163. */
  164. IrpStack = IoGetCurrentIrpStackLocation(Irp);
  165. switch(IrpStack->MajorFunction)
  166. {
  167. case IRP_MJ_CREATE:
  168. HGM_DBGPRINT(FILE_HIDGAME | HGM_BABBLE,
  169. ("HGM_CreateClose:IRP_MJ_CREATE") );
  170. Irp->IoStatus.Information = 0;
  171. break;
  172. case IRP_MJ_CLOSE:
  173. HGM_DBGPRINT(FILE_HIDGAME | HGM_BABBLE,
  174. ("HGM_CreateClose:IRP_MJ_CLOSE") );
  175. Irp->IoStatus.Information = 0;
  176. break;
  177. default:
  178. HGM_DBGPRINT(FILE_HIDGAME | HGM_WARN,
  179. ("HGM_CreateClose:Not handled IrpStack->MajorFunction 0x%x",
  180. IrpStack->MajorFunction) );
  181. ntStatus = STATUS_INVALID_PARAMETER;
  182. break;
  183. }
  184. /*
  185. * Save Status for return and complete Irp
  186. */
  187. Irp->IoStatus.Status = ntStatus;
  188. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  189. HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK, "HGM_CreateClose", ntStatus);
  190. return ntStatus;
  191. } /* HGM_CreateClose */
  192. /*****************************************************************************
  193. *
  194. * @doc EXTERNAL
  195. *
  196. * @func NTSTATUS | HGM_AddDevice |
  197. *
  198. * Called by hidclass, allows us to initialize our device extensions.
  199. *
  200. * @parm IN PDRIVER_OBJECT | DriverObject |
  201. *
  202. * Pointer to the driver object
  203. *
  204. * @parm IN PDEVICE_OBJECT | FunctionalDeviceObject |
  205. *
  206. * Pointer to a functional device object created by hidclass.
  207. *
  208. * @rvalue STATUS_SUCCESS | success
  209. *
  210. *****************************************************************************/
  211. NTSTATUS EXTERNAL
  212. HGM_AddDevice
  213. (
  214. IN PDRIVER_OBJECT DriverObject,
  215. IN PDEVICE_OBJECT FunctionalDeviceObject
  216. )
  217. {
  218. NTSTATUS ntStatus = STATUS_SUCCESS;
  219. PDEVICE_OBJECT DeviceObject;
  220. PDEVICE_EXTENSION DeviceExtension;
  221. PAGED_CODE ();
  222. HGM_DBGPRINT( FILE_HIDGAME | HGM_FENTRY,
  223. ("HGM_AddDevice(DriverObject=0x%x,FunctionalDeviceObject=0x%x)",
  224. DriverObject, FunctionalDeviceObject) );
  225. ASSERTMSG("HGM_AddDevice:", FunctionalDeviceObject != NULL);
  226. DeviceObject = FunctionalDeviceObject;
  227. /*
  228. * Initialize the device extension.
  229. */
  230. DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);
  231. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  232. /*
  233. * Initialize the list
  234. */
  235. InitializeListHead(&DeviceExtension->Link);
  236. /*
  237. * Acquire mutex before modifying the Global Linked list of devices
  238. */
  239. ExAcquireFastMutex (&Global.Mutex);
  240. /*
  241. * Add this device to the linked list of devices
  242. */
  243. InsertTailList(&Global.DeviceListHead, &DeviceExtension->Link);
  244. /*
  245. * Release the mutex
  246. */
  247. ExReleaseFastMutex (&Global.Mutex);
  248. /*
  249. * Initialize the remove lock
  250. */
  251. DeviceExtension->RequestCount = 1;
  252. KeInitializeEvent(&DeviceExtension->RemoveEvent,
  253. SynchronizationEvent,
  254. FALSE);
  255. HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK, "HGM_AddDevice", ntStatus);
  256. return ntStatus;
  257. } /* HGM_AddDevice */
  258. /*****************************************************************************
  259. *
  260. * @doc EXTERNAL
  261. *
  262. * @func NTSTATUS | HGM_SystemControl |
  263. *
  264. * Process the WMI IRPs sent to this device.
  265. *
  266. * @parm IN PDEVICE_OBJECT | DeviceObject |
  267. *
  268. * Pointer to the device object
  269. *
  270. * @parm IN PIRP | Irp |
  271. *
  272. * Pointer to an I/O Request Packet.
  273. *
  274. * @rvalue STATUS_SUCCESS | success
  275. * @rvalue STATUS_INVALID_PARAMETER | Irp not handled
  276. *
  277. *****************************************************************************/
  278. NTSTATUS EXTERNAL
  279. HGM_SystemControl
  280. (
  281. IN PDEVICE_OBJECT DeviceObject,
  282. IN PIRP Irp
  283. )
  284. {
  285. PAGED_CODE ();
  286. HGM_DBGPRINT(FILE_HIDGAME | HGM_FENTRY,
  287. ("HGM_SystemControl(DeviceObject=0x%x,Irp=0x%x)",
  288. DeviceObject, Irp) );
  289. IoSkipCurrentIrpStackLocation(Irp);
  290. return IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);
  291. } /* HGM_SystemControl */
  292. /*****************************************************************************
  293. *
  294. * @doc EXTERNAL
  295. *
  296. * @func void | HGM_Unload |
  297. *
  298. * Free all the allocated resources, etc.
  299. *
  300. * @parm IN PDRIVER_OBJECT | DeviceObject |
  301. *
  302. * Pointer to the driver object
  303. *
  304. *
  305. *****************************************************************************/
  306. VOID EXTERNAL
  307. HGM_Unload
  308. (
  309. IN PDRIVER_OBJECT DriverObject
  310. )
  311. {
  312. PAGED_CODE();
  313. HGM_DBGPRINT(FILE_HIDGAME | HGM_FENTRY,
  314. ("HGM_Unload Enter"));
  315. /*
  316. * All the device objects should be gone
  317. */
  318. ASSERT ( NULL == DriverObject->DeviceObject);
  319. HGM_EXITPROC(FILE_HIDGAME | HGM_FEXIT_STATUSOK, "HGM_Unload:", STATUS_SUCCESS );
  320. return;
  321. } /* HGM_Unload */