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.

403 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. locate.c
  5. Abstract:
  6. This module contains the code
  7. for finding, adding, removing, and identifying hid devices.
  8. Environment:
  9. Kernel & user mode
  10. Revision History:
  11. Nov-96 : Created by Kenneth D. Ray
  12. --*/
  13. #include <basetyps.h>
  14. #include <stdlib.h>
  15. #include <wtypes.h>
  16. #include <cfgmgr32.h>
  17. #include <initguid.h>
  18. #include <stdio.h>
  19. #include <winioctl.h>
  20. #include "dock.h"
  21. #define USAGE "Usage: dock [-e] [-v] [-f]\n" \
  22. "\t -e eject dock\n" \
  23. "\t -v verbose\n" \
  24. "\t -f force\n"
  25. VOID
  26. DockStartEject (
  27. BOOLEAN Verbose,
  28. BOOLEAN Force
  29. );
  30. __cdecl
  31. main (
  32. ULONG argc,
  33. CHAR *argv[]
  34. )
  35. /*++
  36. ++*/
  37. {
  38. BOOLEAN eject = FALSE;
  39. BOOLEAN verbose = FALSE;
  40. BOOLEAN force = FALSE;
  41. BOOLEAN error = FALSE;
  42. ULONG i;
  43. char * parameter = NULL;
  44. //
  45. // parameter parsing follows:
  46. //
  47. try {
  48. if (argc < 2) {
  49. leave;
  50. }
  51. for (i = 1; i < argc; i++) {
  52. parameter = argv[i];
  53. if ('-' == *(parameter ++)) {
  54. switch (*parameter) {
  55. case 'e':
  56. eject = TRUE;
  57. break;
  58. case 'v':
  59. verbose = TRUE;
  60. break;
  61. case 'f':
  62. force = TRUE;
  63. break;
  64. default:
  65. error = TRUE;
  66. leave;
  67. }
  68. } else {
  69. error = TRUE;
  70. leave;
  71. }
  72. }
  73. } finally {
  74. if (error || ((!eject) && (!verbose))) {
  75. printf (USAGE);
  76. exit (1);
  77. }
  78. if (verbose) {
  79. printf ("Verbose Mode Requested \n");
  80. }
  81. if (eject) {
  82. printf ("Eject Requested \n");
  83. DockStartEject (verbose, force);
  84. }
  85. }
  86. printf("Done\n");
  87. return 0;
  88. }
  89. VOID
  90. DockStartEject (
  91. BOOLEAN Verbose,
  92. BOOLEAN Force
  93. )
  94. /*++
  95. --*/
  96. {
  97. CONFIGRET status;
  98. BOOL present;
  99. if (Verbose) {
  100. printf("Checking if Dock Present\n");
  101. }
  102. status = CM_Is_Dock_Station_Present (&present);
  103. if (Verbose) {
  104. printf("ret 0x%x, Present %s\n",
  105. status,
  106. (present ? "TRUE" : "FALSE"));
  107. }
  108. if (Force || present) {
  109. if (Verbose) {
  110. printf("Calling eject\n");
  111. }
  112. status = CM_Request_Eject_PC ();
  113. if (Verbose) {
  114. printf("ret 0x%x\n", status);
  115. }
  116. } else {
  117. printf("Skipping eject call\n");
  118. }
  119. }
  120. #if 0
  121. BOOLEAN
  122. OpenGamePort (
  123. IN HDEVINFO HardwareDeviceInfo,
  124. IN PSP_INTERFACE_DEVICE_DATA DeviceInfoData,
  125. IN OUT PGAME_PORT GamePort
  126. );
  127. BOOLEAN
  128. FindKnownGamePorts (
  129. OUT PGAME_PORT * GamePorts, // A array of struct _GAME_PORT.
  130. OUT PULONG NumberDevices // the length in elements of this array.
  131. )
  132. /*++
  133. Routine Description:
  134. Do the required PnP things in order to find, the all the HID devices in
  135. the system at this time.
  136. --*/
  137. {
  138. HDEVINFO hardwareDeviceInfo;
  139. SP_INTERFACE_DEVICE_DATA deviceInfoData;
  140. ULONG i;
  141. BOOLEAN done;
  142. PGAME_PORT gamePortInst;
  143. LPGUID gamePortGuid;
  144. gamePortGuid = (LPGUID) &GUID_GAMEENUM_BUS_ENUMERATOR;
  145. *GamePorts = NULL;
  146. *NumberDevices = 0;
  147. //
  148. // Open a handle to the plug and play dev node.
  149. //
  150. hardwareDeviceInfo = SetupDiGetClassDevs (
  151. gamePortGuid,
  152. NULL, // Define no enumerator (global)
  153. NULL, // Define no
  154. (DIGCF_PRESENT | // Only Devices present
  155. DIGCF_INTERFACEDEVICE)); // Function class devices.
  156. //
  157. // Take a wild guess to start
  158. //
  159. *NumberDevices = 4;
  160. done = FALSE;
  161. deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
  162. i=0;
  163. while (!done) {
  164. *NumberDevices *= 2;
  165. if (*GamePorts) {
  166. *GamePorts =
  167. realloc (*GamePorts, (*NumberDevices * sizeof (GAME_PORT)));
  168. } else {
  169. *GamePorts = calloc (*NumberDevices, sizeof (GAME_PORT));
  170. }
  171. if (NULL == *GamePorts) {
  172. SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
  173. return FALSE;
  174. }
  175. gamePortInst = *GamePorts + i;
  176. for (; i < *NumberDevices; i++, gamePortInst++) {
  177. if (SetupDiEnumInterfaceDevice (hardwareDeviceInfo,
  178. 0, // No care about specific PDOs
  179. gamePortGuid,
  180. i,
  181. &deviceInfoData)) {
  182. if( !OpenGamePort (hardwareDeviceInfo, &deviceInfoData, gamePortInst) )
  183. printf("Error: OpenGamePort returned FALSE\n");
  184. } else {
  185. if (ERROR_NO_MORE_ITEMS == GetLastError()) {
  186. done = TRUE;
  187. break;
  188. }
  189. }
  190. }
  191. }
  192. *NumberDevices = i;
  193. SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
  194. return TRUE;
  195. }
  196. BOOLEAN
  197. OpenGamePort (
  198. IN HDEVINFO HardwareDeviceInfo,
  199. IN PSP_INTERFACE_DEVICE_DATA DeviceInfoData,
  200. IN OUT PGAME_PORT GamePort
  201. )
  202. /*++
  203. RoutineDescription:
  204. Given the HardwareDeviceInfo, representing a handle to the plug and
  205. play information, and deviceInfoData, representing a specific hid device,
  206. open that device and fill in all the relivant information in the given
  207. HID_DEVICE structure.
  208. return if the open and initialization was successfull or not.
  209. --*/
  210. {
  211. PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = NULL;
  212. ULONG predictedLength = 0;
  213. ULONG requiredLength = 0;
  214. ULONG i, bytes;
  215. GAMEENUM_REMOVE_HARDWARE remove;
  216. //
  217. // allocate a function class device data structure to receive the
  218. // goods about this particular device.
  219. //
  220. SetupDiGetInterfaceDeviceDetail (
  221. HardwareDeviceInfo,
  222. DeviceInfoData,
  223. NULL, // probing so no output buffer yet
  224. 0, // probing so output buffer length of zero
  225. &requiredLength,
  226. NULL); // not interested in the specific dev-node
  227. predictedLength = requiredLength;
  228. // sizeof (SP_FNCLASS_DEVICE_DATA) + 512;
  229. functionClassDeviceData = malloc (predictedLength);
  230. functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
  231. //
  232. // Retrieve the information from Plug and Play.
  233. //
  234. if (! SetupDiGetInterfaceDeviceDetail (
  235. HardwareDeviceInfo,
  236. DeviceInfoData,
  237. functionClassDeviceData,
  238. predictedLength,
  239. &requiredLength,
  240. NULL)) {
  241. printf("Error in SetupDiGetInterfaceDeviceDetail\n");
  242. free (functionClassDeviceData);
  243. return FALSE;
  244. }
  245. printf("Opening %s\n", functionClassDeviceData->DevicePath);
  246. GamePort->File = CreateFile (
  247. functionClassDeviceData->DevicePath,
  248. GENERIC_READ | GENERIC_WRITE,
  249. 0, // FILE_SHARE_READ | FILE_SHARE_WRITE
  250. NULL, // no SECURITY_ATTRIBUTES structure
  251. OPEN_EXISTING, // No special create flags
  252. 0, // No special attributes
  253. NULL); // No template file
  254. if (INVALID_HANDLE_VALUE == GamePort->File) {
  255. printf("Error in CreateFile: %x", GetLastError());
  256. free (functionClassDeviceData);
  257. return FALSE;
  258. }
  259. printf("File Opened!!!\n");
  260. GamePort->Desc.Size = sizeof (GamePort->Desc);
  261. if (!DeviceIoControl (GamePort->File,
  262. IOCTL_GAMEENUM_PORT_DESC,
  263. &GamePort->Desc, sizeof (GamePort->Desc),
  264. &GamePort->Desc, sizeof (GamePort->Desc),
  265. &bytes, NULL)) {
  266. printf("Error in DeviceIoctl IOCTL_GAMEENUM_PORT_DESC: %x", GetLastError());
  267. free (functionClassDeviceData);
  268. return FALSE;
  269. }
  270. printf("Description: Size (%d), Handle (0x%x), Address (0x%x) \n",
  271. GamePort->Desc.Size,
  272. GamePort->Desc.PortHandle,
  273. GamePort->Desc.PortAddress);
  274. //
  275. // Set the port up
  276. //
  277. if(bExpose) {
  278. printf("\nThis handle is not valid for remove!!!\n\nExposing port\n");
  279. GamePort->Hardware = malloc (bytes = (sizeof (GAMEENUM_EXPOSE_HARDWARE) +
  280. GAME_HARDWARE_IDS_LENGTH));
  281. GamePort->Hardware->Size = sizeof (GAMEENUM_EXPOSE_HARDWARE);
  282. GamePort->Hardware->PortHandle = GamePort->Desc.PortHandle;
  283. printf("Enter Number of Joysticks:");
  284. scanf("%d",&GamePort->Hardware->NumberJoysticks);
  285. printf("Enter Number of Buttons:");
  286. scanf("%d", &GamePort->Hardware->NumberButtons);
  287. printf("Enter Number of Axes:");
  288. scanf("%d", &GamePort->Hardware->NumberAxis);
  289. memcpy (GamePort->Hardware->HardwareIDs,
  290. GAME_HARDWARE_IDS,
  291. GAME_HARDWARE_IDS_LENGTH);
  292. if (!DeviceIoControl (GamePort->File,
  293. IOCTL_GAMEENUM_EXPOSE_HARDWARE,
  294. GamePort->Hardware, bytes,
  295. GamePort->Hardware, bytes,
  296. &bytes, NULL)) {
  297. free (functionClassDeviceData);
  298. free (GamePort->Hardware);
  299. GamePort->Hardware = NULL;
  300. printf("Error in DeviceIoctl IOCTL_GAMEENUM_EXPOSE_HARDWARE: 0x%x\n", GetLastError());
  301. return FALSE;
  302. }
  303. printf("Hardware handle 0x%x <----- Save this handle!!!\n",GamePort->Hardware->HardwareHandle);
  304. printf("\t\tGameEnum -r will not be able retrieve it for you.\n");
  305. free (GamePort->Hardware);
  306. GamePort->Hardware = NULL;
  307. }
  308. if(bRemove) {
  309. printf("Removing port\n");
  310. remove.Size = bytes = sizeof (remove);
  311. printf("Enter hardware handle: ");
  312. scanf("%x",&remove.HardwareHandle);
  313. printf("Entered Handle: %x", remove.HardwareHandle);
  314. if (!DeviceIoControl (GamePort->File,
  315. IOCTL_GAMEENUM_REMOVE_HARDWARE,
  316. &remove, bytes,
  317. &remove, bytes,
  318. &bytes, NULL)) {
  319. printf("Error in DeviceIoctl IOCTL_GAMEENUM_REMOVE_HARDWARE: 0x%x\n", GetLastError());
  320. return FALSE;
  321. }
  322. }
  323. free (functionClassDeviceData);
  324. return TRUE;
  325. }
  326. #endif