Leaked source code of windows server 2003
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.

736 lines
18 KiB

  1. /*++
  2. Copyright (c) 1998 - 1999 Microsoft Corporation
  3. Module Name:
  4. hidgame.h
  5. Abstract: Contains definitions of all constants and
  6. data types for the joystick driver.
  7. Environment:
  8. Kernel mode
  9. @@BEGIN_DDKSPLIT
  10. Author:
  11. Eliyas Yakub (Mar, 10, 1997)
  12. Revision History:
  13. Updated by Eliyas on Feb 5 1998
  14. OmSharma ( April 12, 1998)
  15. MarcAnd 02-Jul-98 Quick tidy for DDK
  16. @@END_DDKSPLIT
  17. --*/
  18. /*****************************************************************************
  19. * @doc EXTERNAL
  20. *
  21. * @module HidGame | Analog WDM/HID Joystick driver.
  22. *
  23. * HidGame is the HID minidriver for analog joysticks.
  24. * This driver registers with the HID class driver and
  25. * responds to IRPs put out by HIDclass. It informs HIDClass
  26. * about the capabilities of the joystick and polls the joystick
  27. * in response to a read IOCTL.
  28. *
  29. * This driver is loaded in reponse to a "New hardware Found"
  30. * PnP event, and consequently must have an entry in an inf file
  31. * that binds a PnP hardware ID to this driver.
  32. *
  33. * Gameport joysticks are not true PnP devices, so the user has to
  34. * inform the system about the joystick that was added to the
  35. * gameport by using the Game Controllers CPL "Add" a joystick.
  36. * An example of how a new joystick type can be created is provided
  37. * in the accompanying inf file.
  38. *
  39. * Once a user selects a joystick and gameport, the GameCPL passes
  40. * this information to DirectInput which sends an IOCTL to the
  41. * gameport bus driver (GameEnum), specifying the number of axes,
  42. * buttons and a PnPHardware ID for the joystick. The Gameport Bus
  43. * informs PnP of a new device arrival. PnP searches the system for
  44. * a match for the hardwareID and loads the appropriate driver.
  45. *
  46. *
  47. * The following files are part of this driver.
  48. *
  49. * <nl>HidGame.c
  50. * <nl>DriverEntry, CreateClose, AddDevice and Unload Routines.
  51. * This code performs functions required for any device driver
  52. * and so can probably be used without changes for any game
  53. * other game device.
  54. *
  55. * <nl>PnP.c
  56. * <nl>Support routines for PnP IOCTLs.
  57. *
  58. * <nl>Ioctl.c
  59. * <nl>Support routines for Non PnP IOCTLs
  60. * These deal with all the HID IOCTLs required for an ordinary
  61. * game device and so could be used without change as there is
  62. * no analog specific funtionality in these routines.
  63. * Drivers for some devices may need to add code to support more
  64. * complex devices.
  65. *
  66. * <nl>HidJoy.c
  67. * <nl>Support routines to translate legacy joystick flags and
  68. * data into HID descriptors. The majority of this code is
  69. * needed to support the wide variety of analog joysticks
  70. * available so is not relevant to drivers written for specific
  71. * devices.
  72. *
  73. * <nl>Poll.c
  74. * <nl>Support routines to read analog joystick data from a
  75. * gameport. These functions are likely to be of little use
  76. * in a digital joystick driver.
  77. *
  78. * <nl>i386\timing.c
  79. * <nl>Support routines to use x86 Time Stamp Counter.
  80. * Includes code to check for the presence of, calibrate and
  81. * read the high speed CPU timer.
  82. *
  83. * <nl>Hidgame.h
  84. * <nl>Common include file.
  85. * The general definitions are likely to be of use in most
  86. * drivers for game devices but some customization will be needed.
  87. *
  88. * <nl>Debug.h
  89. * <nl>Definitions to aid debugging.
  90. * This contains the tag for the driver name used in debug output
  91. * which must be changed.
  92. *
  93. * <nl>Analog.h
  94. * <nl>Specific include file.
  95. * Definitions specific to analog joystick devices.
  96. *
  97. * <nl>OemSetup.inf
  98. * <nl>Sample inf file.
  99. * See comments in this file for how to install devices.
  100. *
  101. * <nl>Source
  102. * <nl> Source file for the NT build utility
  103. *
  104. * <nl>Makefile
  105. * <nl> Used as part of the build process
  106. *
  107. *****************************************************************************/
  108. #ifndef __HIDGAME_H__
  109. #define __HIDGAME_H__
  110. /* @@BEGIN_DDKSPLIT
  111. *
  112. * Only define CHANGE_DEVICE in DDK sample
  113. */
  114. #if 0
  115. /* @@END_DDKSPLIT */
  116. /*
  117. * When CHANGE_DEVICE is defined it turns on code to use expose sibling and
  118. * remove self to allow the driver to change its capabilities on-the-fly.
  119. * This code is not used in the retail version of HIDGame.
  120. */
  121. #define CHANGE_DEVICE
  122. /* @@BEGIN_DDKSPLIT */
  123. #endif
  124. /* @@END_DDKSPLIT */
  125. /* @@BEGIN_DDKSPLIT Disable common benign warnings for W4 testing */
  126. #pragma warning( disable:4514 ) /* unreferenced inline function has been removed */
  127. #pragma warning( disable:4214 ) /* nonstandard extension used : bit field types other than int */
  128. /* @@END_DDKSPLIT */
  129. /*
  130. * Include Files
  131. */
  132. #include "wdm.h"
  133. #include "hidtoken.h"
  134. #include "hidusage.h"
  135. #include "hidport.h"
  136. #include "gameport.h"
  137. #include "debug.h"
  138. #include "analog.h"
  139. /*
  140. * A value guaranteed to be considered a timeout
  141. */
  142. #define AXIS_TIMEOUT ( 0xffffffffL )
  143. /*
  144. * Define a tag to mark memory allocations made by this driver
  145. * so they can be recognized. This is for illustration only as
  146. * this driver does not make any explicite memory allocations.
  147. */
  148. #define HGM_POOL_TAG ('maGH')
  149. #define ExAllocPool( Type, Size ) \
  150. ExAllocatePoolWithTag( Type, Size, HGM_POOL_TAG )
  151. /*
  152. * Defines for hidgame
  153. */
  154. #define HIDGAME_VERSION_NUMBER ((USHORT) 1)
  155. #define JOY_START_TIMERS ( 0 )
  156. #define MAXBYTES_GAME_REPORT ( 256 )
  157. #define BUTTON_1 0x10
  158. #define BUTTON_2 0x20
  159. #define BUTTON_3 0x40
  160. #define BUTTON_4 0x80
  161. #define AXIS_X 0x01
  162. #define AXIS_Y 0x02
  163. #define AXIS_R 0x04
  164. #define AXIS_Z 0x08
  165. #define BUTTON_BIT 0
  166. #define BUTTON_ON ( 1 << BUTTON_BIT )
  167. /*
  168. * Function type used for timing.
  169. * MUST be compatible with KeQueryPerformanceCounter
  170. */
  171. typedef
  172. LARGE_INTEGER
  173. (*COUNTER_FUNCTION) (
  174. PLARGE_INTEGER pDummy
  175. );
  176. /*
  177. * Typedef the structs we need
  178. */
  179. /*****************************************************************************
  180. *
  181. * @doc EXTERNAL
  182. *
  183. * @struct HIDGAME_GLOBAL |
  184. *
  185. * Global struct to store driver wide data.
  186. * Stuff we need to share across multiple instances of this driver.
  187. *
  188. * @field FAST_MUTEX | Mutex |
  189. *
  190. * Mutex to synchronize access to the following list entry
  191. *
  192. * @field LIST_ENTRY | DeviceListHead |
  193. *
  194. * Keeps a list of all devices.
  195. *
  196. * @field KSPIN_LOCK | SpinLock |
  197. *
  198. * Spinlock used to stop multiple processors polling gameports at
  199. * once. It would be better to keep a list of spinlocks, one for
  200. * each gameport but then processors could contend for IO access
  201. * and we'd have to maintain another list.
  202. *
  203. * @field COUNTER_FUNCTION | ReadCounter |
  204. *
  205. * Function to retrieve clock time
  206. *
  207. * @field ULONG | CounterScale |
  208. *
  209. * The scale to be used.
  210. *
  211. *****************************************************************************/
  212. typedef struct _HIDGAME_GLOBAL
  213. {
  214. FAST_MUTEX Mutex; /* A syncronization for access to list */
  215. LIST_ENTRY DeviceListHead; /* Keeps list of all the devices */
  216. KSPIN_LOCK SpinLock; /* Lock so that only one port is accessed */
  217. COUNTER_FUNCTION ReadCounter; /* Function to retrieve clock time */
  218. ULONG CounterScale; /* Clock scale factor */
  219. } HIDGAME_GLOBAL;
  220. /*****************************************************************************
  221. *
  222. * @doc EXTERNAL
  223. *
  224. * @struct DEVICE_EXTENSION |
  225. *
  226. * Device specific data.
  227. *
  228. * @field PGAMEENUM_READPORT | ReadAccessor |
  229. *
  230. * Read Accessor function for the gameport. Obtained in the return from
  231. * IOCTL to the gameport.
  232. *
  233. * @field PGAMEENUM_WRITEPORT | WriteAccessor |
  234. *
  235. * Write Accessor function for the gameport. Obtained in the return from
  236. * IOCTL to the gameport.
  237. *
  238. * @field PGAMEENUM_READPORT_DIGITAL | ReadAccessorDigital |
  239. *
  240. * Digital read accessor for the gameport. Obtained as part of return from
  241. * IOCTL to the gameport
  242. *
  243. * @field PGAMEENUM_ACQUIRE_PORT | AcquirePort |
  244. *
  245. * Function to call before reading/writing to the port. Obtained as
  246. * part of return from IOCTL to the gameport
  247. *
  248. * @field PGAMEENUM_RELEASE_PORT | ReleasePort |
  249. *
  250. * Function to call when done reading/writing to the port. Obtained as
  251. * part of return from IOCTL to the gameport
  252. *
  253. * @field PVOID | GameContext |
  254. *
  255. * Token to read this game port. Obtained as part of the return from
  256. * IOCTL to the gameport.
  257. *
  258. * @field PVOID | PortContext |
  259. *
  260. * Context to pass to AcquirePort and ReleasePort. Obtained as part
  261. * of the return from IOCTL to the gameport.
  262. *
  263. * @field LIST_ENTRY | Link |
  264. *
  265. * Link to other hidgame devices on the system.
  266. *
  267. * @field KEVENT | RemoveEvent |
  268. *
  269. * The remove plugplay request must use this event to make sure all
  270. * other requests have completed before it deletes the device object.
  271. *
  272. * @field LONG | RequestCount |
  273. *
  274. * Number of IRPs underway.
  275. *
  276. * @field PDEVICE_OBJECT | NextDeviceObject |
  277. *
  278. * NOTE: Only present if CHANGE_DEVICE is defined
  279. *
  280. * DeviceObject to send self created IRPs down to
  281. *
  282. * @field ANALOG_DEVICE | unnamed structure see ANALOG_DEVICE |
  283. *
  284. * Structure containing analog device specific information.
  285. *
  286. * NOTE: this structure is placed after the DWORD aligned elements.
  287. *
  288. * @xref <t ANALOG_DEVICE>.
  289. *
  290. * @field BOOLEAN | fRemoved |
  291. *
  292. * Set to true if the device has been removed => all requests should be failed
  293. *
  294. * @field BOOLEAN | fStarted |
  295. *
  296. * Set to true is device has started.
  297. *
  298. * @field BOOLEAN | fSurpriseRemoved |
  299. *
  300. * Set to true if the device has been surprise removed by PnPs device has started.
  301. *
  302. *****************************************************************************/
  303. typedef struct _DEVICE_EXTENSION
  304. {
  305. /*
  306. * read accessor for the game port
  307. */
  308. PGAMEENUM_READPORT ReadAccessor;
  309. /*
  310. * write the game port
  311. */
  312. PGAMEENUM_WRITEPORT WriteAccessor;
  313. /*
  314. * Digital read accessor for the gameport
  315. */
  316. PGAMEENUM_READPORT_DIGITAL ReadAccessorDigital;
  317. /*
  318. * Function to call before reading/writing to the port
  319. */
  320. PGAMEENUM_ACQUIRE_PORT AcquirePort;
  321. /*
  322. * Function to call when done reading/writing to the port
  323. */
  324. PGAMEENUM_RELEASE_PORT ReleasePort;
  325. /*
  326. * token to read this game port
  327. */
  328. PVOID GameContext;
  329. /*
  330. * Context to pass to AcquirePort and ReleasePort
  331. */
  332. PVOID PortContext;
  333. /*
  334. * List of other joystick devices
  335. */
  336. LIST_ENTRY Link;
  337. /*
  338. * The remove plugplay request must use this event to make sure all
  339. * other requests have completed before it deletes the device object.
  340. */
  341. KEVENT RemoveEvent;
  342. /*
  343. * Number of IRPs underway.
  344. */
  345. LONG RequestCount;
  346. #ifdef CHANGE_DEVICE
  347. /*
  348. * DeviceObject to send self created IRPs down to.
  349. */
  350. PDEVICE_OBJECT NextDeviceObject;
  351. #endif /* CHANGE_DEVICE */
  352. /*
  353. * Structure containing analog device specific information.
  354. */
  355. ANALOG_DEVICE;
  356. /*
  357. * Set to true if the device has been removed => all requests should be failed
  358. */
  359. BOOLEAN fRemoved;
  360. /*
  361. * Set to true if the device has started
  362. */
  363. BOOLEAN fStarted;
  364. /*
  365. * Set to true if the device has been surprise removed by PnPs device has started.
  366. */
  367. BOOLEAN fSurpriseRemoved;
  368. #ifdef CHANGE_DEVICE
  369. /*
  370. * Indicates that a replacement sibling is being started
  371. */
  372. BOOLEAN fReplaced;
  373. #endif /* CHANGE_DEVICE */
  374. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  375. #define GET_MINIDRIVER_DEVICE_EXTENSION(DO) \
  376. ((PDEVICE_EXTENSION) (((PHID_DEVICE_EXTENSION)(DO)->DeviceExtension)->MiniDeviceExtension))
  377. #define GET_NEXT_DEVICE_OBJECT(DO) \
  378. (((PHID_DEVICE_EXTENSION)(DO)->DeviceExtension)->NextDeviceObject)
  379. /*
  380. * Globals
  381. */
  382. extern HIDGAME_GLOBAL Global;
  383. /*
  384. * Function prototypes
  385. */
  386. #define INTERNAL /* Called only within a translation unit */
  387. #define EXTERNAL /* Called from other translation units */
  388. /*
  389. * hidgame.c
  390. */
  391. NTSTATUS EXTERNAL
  392. DriverEntry
  393. (
  394. IN PDRIVER_OBJECT DriverObject,
  395. IN PUNICODE_STRING registryPath
  396. );
  397. NTSTATUS EXTERNAL
  398. HGM_CreateClose
  399. (
  400. IN PDEVICE_OBJECT DeviceObject,
  401. IN PIRP Irp
  402. );
  403. NTSTATUS EXTERNAL
  404. HGM_SystemControl
  405. (
  406. IN PDEVICE_OBJECT DeviceObject,
  407. IN PIRP Irp
  408. );
  409. NTSTATUS EXTERNAL
  410. HGM_AddDevice
  411. (
  412. IN PDRIVER_OBJECT DriverObject,
  413. IN PDEVICE_OBJECT FunctionalDeviceObject
  414. );
  415. VOID EXTERNAL
  416. HGM_Unload
  417. (
  418. IN PDRIVER_OBJECT DriverObject
  419. );
  420. /*
  421. * ioctl.c
  422. */
  423. NTSTATUS EXTERNAL
  424. HGM_InternalIoctl
  425. (
  426. IN PDEVICE_OBJECT DeviceObject,
  427. IN PIRP Irp
  428. );
  429. NTSTATUS EXTERNAL
  430. HGM_GetDeviceDescriptor
  431. (
  432. IN PDEVICE_OBJECT DeviceObject,
  433. IN PIRP Irp
  434. );
  435. NTSTATUS INTERNAL
  436. HGM_GetReportDescriptor
  437. (
  438. IN PDEVICE_OBJECT DeviceObject,
  439. IN PIRP Irp
  440. );
  441. NTSTATUS INTERNAL
  442. HGM_ReadReport
  443. (
  444. IN PDEVICE_OBJECT DeviceObject,
  445. IN PIRP Irp
  446. );
  447. NTSTATUS INTERNAL
  448. HGM_GetAttributes
  449. (
  450. PDEVICE_OBJECT DeviceObject,
  451. PIRP Irp
  452. );
  453. /*
  454. * pnp.c
  455. */
  456. NTSTATUS INTERNAL
  457. HGM_IncRequestCount
  458. (
  459. PDEVICE_EXTENSION DeviceExtension
  460. );
  461. VOID INTERNAL
  462. HGM_DecRequestCount
  463. (
  464. PDEVICE_EXTENSION DeviceExtension
  465. );
  466. VOID INTERNAL
  467. HGM_RemoveDevice
  468. (
  469. PDEVICE_EXTENSION DeviceExtension
  470. );
  471. NTSTATUS EXTERNAL
  472. HGM_PnP
  473. (
  474. IN PDEVICE_OBJECT DeviceObject,
  475. IN PIRP Irp
  476. );
  477. NTSTATUS INTERNAL
  478. HGM_InitDevice
  479. (
  480. IN PDEVICE_OBJECT DeviceObject,
  481. IN PIRP Irp
  482. );
  483. NTSTATUS INTERNAL
  484. HGM_Power
  485. (
  486. IN PDEVICE_OBJECT DeviceObject,
  487. IN PIRP pIrp
  488. );
  489. NTSTATUS INTERNAL
  490. HGM_GetResources
  491. (
  492. IN PDEVICE_OBJECT DeviceObject,
  493. IN PIRP Irp
  494. );
  495. NTSTATUS INTERNAL
  496. HGM_PnPComplete
  497. (
  498. IN PDEVICE_OBJECT DeviceObject,
  499. IN PIRP Irp,
  500. IN PVOID Context
  501. );
  502. /*
  503. * hidjoy.c
  504. */
  505. NTSTATUS EXTERNAL
  506. HGM_DriverInit
  507. (
  508. VOID
  509. );
  510. NTSTATUS INTERNAL
  511. HGM_SetupButtons
  512. (
  513. IN OUT PDEVICE_EXTENSION DeviceExtension
  514. );
  515. NTSTATUS INTERNAL
  516. HGM_MapAxesFromDevExt
  517. (
  518. IN OUT PDEVICE_EXTENSION DeviceExtension
  519. );
  520. NTSTATUS INTERNAL
  521. HGM_GenerateReport
  522. (
  523. IN PDEVICE_OBJECT DeviceObject,
  524. OUT UCHAR rgGameReport[MAXBYTES_GAME_REPORT],
  525. OUT PUSHORT pCbReport
  526. );
  527. NTSTATUS INTERNAL
  528. HGM_JoystickConfig
  529. (
  530. IN PDEVICE_OBJECT DeviceObject
  531. );
  532. NTSTATUS EXTERNAL
  533. HGM_InitAnalog
  534. (
  535. IN PDEVICE_OBJECT DeviceObject
  536. );
  537. /*
  538. * Sample only code for changing the device
  539. */
  540. #ifdef CHANGE_DEVICE
  541. VOID
  542. HGM_ChangeHandler
  543. (
  544. IN PDEVICE_OBJECT DeviceObject,
  545. PIO_WORKITEM WorkItem
  546. );
  547. VOID
  548. HGM_DeviceChanged
  549. (
  550. IN PDEVICE_OBJECT DeviceObject,
  551. IN OUT PDEVICE_EXTENSION DeviceExtension
  552. );
  553. VOID
  554. HGM_Game2HID
  555. (
  556. IN PDEVICE_OBJECT DeviceObject,
  557. IN PDEVICE_EXTENSION DeviceExtension,
  558. IN OUT PUHIDGAME_INPUT_DATA pHIDData
  559. );
  560. #else
  561. VOID
  562. HGM_Game2HID
  563. (
  564. IN PDEVICE_EXTENSION DeviceExtension,
  565. IN OUT PUHIDGAME_INPUT_DATA pHIDData
  566. );
  567. #endif /* CHANGE_DEVICE */
  568. /*
  569. * poll.c
  570. */
  571. NTSTATUS INTERNAL
  572. HGM_AnalogPoll
  573. (
  574. IN PDEVICE_EXTENSION DeviceExtension,
  575. IN UCHAR resistiveInputMask,
  576. IN BOOLEAN bApproximate,
  577. IN OUT ULONG Axis[MAX_AXES],
  578. OUT UCHAR Buttons[PORT_BUTTONS]
  579. );
  580. NTSTATUS
  581. HGM_UpdateLatestPollData
  582. (
  583. IN OUT PDEVICE_EXTENSION DeviceExtension
  584. );
  585. /*
  586. * <CPU>\timing.c (or macro equivalents for external functions)
  587. */
  588. #ifdef _X86_
  589. BOOLEAN INTERNAL
  590. HGM_x86IsClockAvailable
  591. (
  592. VOID
  593. );
  594. LARGE_INTEGER INTERNAL
  595. HGM_x86ReadCounter
  596. (
  597. IN PLARGE_INTEGER Dummy
  598. );
  599. VOID INTERNAL
  600. HGM_x86SampleClocks
  601. (
  602. OUT PULONGLONG pTSC,
  603. OUT PULONGLONG pQPC
  604. );
  605. BOOLEAN EXTERNAL
  606. HGM_x86CounterInit();
  607. #define HGM_CPUCounterInit HGM_x86CounterInit
  608. #else
  609. /*
  610. * For all other processors a value to cause the default timing to be used
  611. */
  612. #define HGM_CPUCounterInit() FALSE
  613. #endif /* _X86_ */
  614. #endif /* __HIDGAME_H__ */