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.

1303 lines
34 KiB

  1. /*++
  2. Module Name:
  3. RW.C
  4. Abstract:
  5. This source file contains routines for exercising reads and writes
  6. to a USB device through the I82930.SYS test driver.
  7. Environment:
  8. user mode
  9. Copyright (c) 1996-1998 Microsoft Corporation. All Rights Reserved.
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. --*/
  15. //*****************************************************************************
  16. // I N C L U D E S
  17. //*****************************************************************************
  18. #include <windows.h>
  19. #include <basetyps.h>
  20. #include <setupapi.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <devioctl.h>
  24. #include <string.h>
  25. #include <initguid.h>
  26. #include "ioctl.h"
  27. #pragma intrinsic(strlen, strcpy, memcmp)
  28. //*****************************************************************************
  29. // D E F I N E S
  30. //*****************************************************************************
  31. #define NOISY(_x_) printf _x_ ;
  32. #define RW_SUCCESS 0
  33. #define RW_FAILED 1
  34. #define RW_ABORTED 2
  35. #define RW_NODEVICE 3
  36. #define RW_BADARGS 4
  37. //*****************************************************************************
  38. // T Y P E D E F S
  39. //*****************************************************************************
  40. typedef struct _DEVICENODE
  41. {
  42. struct _DEVICENODE *Next;
  43. CHAR DevicePath[0];
  44. } DEVICENODE, *PDEVICENODE;
  45. //*****************************************************************************
  46. // G L O B A L S
  47. //*****************************************************************************
  48. ULONG DevInstance = 1; // set with -# option
  49. ULONG InPipeNum = 0; // set with -i option
  50. ULONG OutPipeNum = 1; // set with -o option
  51. BOOL TestMode = 0; // set with -t option
  52. ULONG Count = 1; // set with -c option
  53. ULONG WriteLen = 0; // set with -w option
  54. LONG WriteOffset = 0; // set with -wo option
  55. BOOL WriteReset = 0; // set with -W option
  56. BOOL WriteZero = 0;
  57. ULONG ReadLen = 0; // set with -r option
  58. LONG ReadOffset = 0; // set with -ro option
  59. BOOL ReadReset = 0; // set with -R option
  60. BOOL ReadZero = 0;
  61. BOOL DumpFlag = 0; // set with -d option
  62. BOOL Verbose = 0; // set with -v option
  63. DWORD Offset = 0; // set with -f option
  64. DWORD OffsetHigh = 0; //
  65. BOOL StallIn = 0; // set with -S option
  66. BOOL StallOut = 0; // set with -S option
  67. BOOL SelectAlt = FALSE; // set with -A option
  68. UCHAR Alternate = 0;
  69. BOOL Reset = FALSE; // set with -Z option
  70. BOOL Abort = FALSE; // set by CtrlHandlerRoutine
  71. BOOL Cancel = FALSE; // set by CtrlHandlerRoutine
  72. //*****************************************************************************
  73. // F U N C T I O N P R O T O T Y P E S
  74. //*****************************************************************************
  75. ULONG
  76. DoReadWriteTest (
  77. PUCHAR pinBuf,
  78. HANDLE hRead,
  79. PUCHAR poutBuf,
  80. HANDLE hWrite
  81. );
  82. BOOL
  83. ParseArgs (
  84. int argc,
  85. char *argv[]
  86. );
  87. PDEVICENODE
  88. EnumDevices (
  89. LPGUID Guid
  90. );
  91. HANDLE
  92. OpenDevice (
  93. PDEVICENODE DeviceNode
  94. );
  95. HANDLE
  96. OpenDevicePipe (
  97. PDEVICENODE DeviceNode,
  98. ULONG PipeNum
  99. );
  100. BOOL
  101. CompareBuffs (
  102. PUCHAR buff1,
  103. PUCHAR buff2,
  104. ULONG length
  105. );
  106. VOID
  107. DumpBuff (
  108. PUCHAR b,
  109. ULONG len
  110. );
  111. BOOL
  112. ResetPipe (
  113. HANDLE hPipe
  114. );
  115. BOOL
  116. StallPipe(
  117. HANDLE hPipe
  118. );
  119. BOOL
  120. AbortPipe(
  121. HANDLE hPipe
  122. );
  123. BOOL
  124. SelectAlternate(
  125. HANDLE hDevice,
  126. UCHAR AlternateSetting
  127. );
  128. BOOL
  129. ResetDevice(
  130. HANDLE hDevice
  131. );
  132. BOOL WINAPI
  133. CtrlHandlerRoutine (
  134. DWORD dwCtrlType
  135. );
  136. //*****************************************************************************
  137. //
  138. // main()
  139. //
  140. //*****************************************************************************
  141. int _cdecl
  142. main(
  143. int argc,
  144. char *argv[]
  145. )
  146. {
  147. PDEVICENODE deviceNode;
  148. PUCHAR pinBuf = NULL;
  149. PUCHAR poutBuf = NULL;
  150. HANDLE hDevice = INVALID_HANDLE_VALUE;
  151. HANDLE hRead = INVALID_HANDLE_VALUE;
  152. HANDLE hWrite = INVALID_HANDLE_VALUE;
  153. ULONG fail = 0;
  154. BOOL success;
  155. // Parse the command line args
  156. //
  157. if (!ParseArgs(argc, argv))
  158. {
  159. return RW_BADARGS;
  160. }
  161. // Find devices
  162. //
  163. deviceNode = EnumDevices((LPGUID)&GUID_CLASS_I82930);
  164. if (deviceNode == NULL)
  165. {
  166. printf("No devices found!\n");
  167. return RW_NODEVICE;
  168. }
  169. while (deviceNode && --DevInstance)
  170. {
  171. deviceNode = deviceNode->Next;
  172. }
  173. if (deviceNode == NULL)
  174. {
  175. printf("Devices instance not found!\n");
  176. return RW_NODEVICE;
  177. }
  178. // Reset the device if desired
  179. //
  180. if (Reset || SelectAlt)
  181. {
  182. hDevice = OpenDevice(deviceNode);
  183. if (hDevice != INVALID_HANDLE_VALUE)
  184. {
  185. if (Reset)
  186. {
  187. success = ResetDevice(hDevice);
  188. if (!success)
  189. {
  190. printf("Reset device failed\n");
  191. fail++;
  192. }
  193. }
  194. if (SelectAlt)
  195. {
  196. success = SelectAlternate(hDevice, Alternate);
  197. if (!success)
  198. {
  199. printf("Select Alternate Interface failed\n");
  200. fail++;
  201. }
  202. }
  203. }
  204. }
  205. // Set a CTRL-C / CTRL-BREAK handler
  206. //
  207. SetConsoleCtrlHandler(CtrlHandlerRoutine, TRUE);
  208. // Allocate a page aligned write buffer if we're going to do a write.
  209. //
  210. if (WriteLen)
  211. {
  212. poutBuf = VirtualAlloc(NULL,
  213. WriteLen + WriteOffset,
  214. MEM_COMMIT,
  215. PAGE_READWRITE);
  216. }
  217. // Allocate a page aligned read buffer if we're going to do a read.
  218. //
  219. if (ReadLen)
  220. {
  221. pinBuf = VirtualAlloc(NULL,
  222. ReadLen + ReadOffset,
  223. MEM_COMMIT,
  224. PAGE_READWRITE);
  225. }
  226. // Open the output pipe if we're going to do a write or a reset.
  227. //
  228. if (poutBuf || WriteReset || WriteZero || StallOut)
  229. {
  230. hWrite = OpenDevicePipe(deviceNode, OutPipeNum);
  231. // STALL the output pipe if desired
  232. //
  233. if ((hWrite != INVALID_HANDLE_VALUE) && StallOut)
  234. {
  235. success = StallPipe(hWrite);
  236. if (!success)
  237. {
  238. printf("Output pipe STALL failed\n");
  239. fail++;
  240. }
  241. }
  242. // Reset the output pipe if desired
  243. //
  244. if ((hWrite != INVALID_HANDLE_VALUE) && WriteReset)
  245. {
  246. success = ResetPipe(hWrite);
  247. if (!success)
  248. {
  249. printf("Output pipe ResetPipe failed\n");
  250. fail++;
  251. }
  252. }
  253. }
  254. // Open the input pipe if we're going to do a read or a reset.
  255. //
  256. if (pinBuf || ReadReset || ReadZero || StallIn)
  257. {
  258. hRead = OpenDevicePipe(deviceNode, InPipeNum);
  259. // STALL the input pipe if desired
  260. //
  261. if ((hRead != INVALID_HANDLE_VALUE) && StallIn)
  262. {
  263. success = StallPipe(hRead);
  264. if (!success)
  265. {
  266. printf("Input pipe STALL failed\n");
  267. fail++;
  268. }
  269. }
  270. // Reset the input pipe if desired
  271. //
  272. if ((hRead != INVALID_HANDLE_VALUE) && ReadReset)
  273. {
  274. success = ResetPipe(hRead);
  275. if (!success)
  276. {
  277. printf("Input pipe ResetPipe failed\n");
  278. fail++;
  279. }
  280. }
  281. }
  282. if (WriteLen && (!poutBuf || (hWrite == INVALID_HANDLE_VALUE)))
  283. {
  284. printf("Failed allocating write buffer and/or opening write pipe\n");
  285. fail++;
  286. }
  287. if (ReadLen && (!pinBuf || (hRead == INVALID_HANDLE_VALUE)))
  288. {
  289. printf("Failed allocating read buffer and/or opening read pipe\n");
  290. fail++;
  291. }
  292. //
  293. // NOW DO THE REAL WRITE/READ TEST
  294. //
  295. if (!fail)
  296. {
  297. fail = DoReadWriteTest(pinBuf + ReadOffset,
  298. hRead,
  299. poutBuf + WriteOffset,
  300. hWrite);
  301. }
  302. if (TestMode)
  303. {
  304. if (fail)
  305. {
  306. printf("Test failed\n");
  307. }
  308. else
  309. {
  310. printf("Test passed\n");
  311. }
  312. }
  313. // Close devices if needed
  314. //
  315. if (hDevice != INVALID_HANDLE_VALUE)
  316. {
  317. CloseHandle(hDevice);
  318. hRead = INVALID_HANDLE_VALUE;
  319. }
  320. if (hRead != INVALID_HANDLE_VALUE)
  321. {
  322. CloseHandle(hRead);
  323. hRead = INVALID_HANDLE_VALUE;
  324. }
  325. if (hWrite != INVALID_HANDLE_VALUE)
  326. {
  327. CloseHandle(hWrite);
  328. hWrite = INVALID_HANDLE_VALUE;
  329. }
  330. // Free read/write buffers if needed
  331. //
  332. if (pinBuf)
  333. {
  334. VirtualFree(pinBuf,
  335. 0,
  336. MEM_RELEASE);
  337. }
  338. if (poutBuf)
  339. {
  340. VirtualFree(poutBuf,
  341. 0,
  342. MEM_RELEASE);
  343. }
  344. if (Abort)
  345. {
  346. return RW_ABORTED;
  347. }
  348. else if (fail)
  349. {
  350. return RW_FAILED;
  351. }
  352. else
  353. {
  354. return RW_SUCCESS;
  355. }
  356. }
  357. //*****************************************************************************
  358. //
  359. // DoReadWriteTest()
  360. //
  361. // pinBuf - Buffer to read data into from input pipe
  362. //
  363. // hRead - Handle of input pipe
  364. //
  365. // poutBuf - Buffer to write data from to output pipe
  366. //
  367. // hWrite - Handle of output pipe
  368. //
  369. // return value - zero if success, non-zero if failure
  370. //
  371. //*****************************************************************************
  372. ULONG
  373. DoReadWriteTest (
  374. PUCHAR pinBuf,
  375. HANDLE hRead,
  376. PUCHAR poutBuf,
  377. HANDLE hWrite
  378. )
  379. {
  380. ULONG nBytesRead;
  381. ULONG nBytesWrite;
  382. ULONG i;
  383. ULONG nBytes;
  384. BOOL ok;
  385. BOOL success;
  386. ULONG fail = 0;
  387. HANDLE hConsole;
  388. HANDLE hEvent;
  389. HANDLE waitHandles[2];
  390. OVERLAPPED overlapped;
  391. DWORD dwRet;
  392. DWORD lastError;
  393. // Create an event for the overlapped struct
  394. //
  395. hEvent = CreateEvent(
  396. NULL, // pEventAttributes
  397. FALSE, // bManualReset
  398. FALSE, // bInitialState
  399. NULL // lpName
  400. );
  401. overlapped.hEvent = hEvent;
  402. // Set the command line specified or default offset in the
  403. // overlapped struct
  404. //
  405. overlapped.Offset = Offset;
  406. overlapped.OffsetHigh = OffsetHigh;
  407. // The handles that we'll wait on during the overlapped I/O
  408. //
  409. hConsole = GetStdHandle(STD_INPUT_HANDLE);
  410. waitHandles[0] = hConsole;
  411. waitHandles[1] = hEvent;
  412. if (poutBuf)
  413. {
  414. // Put some data in the output buffer
  415. //
  416. //
  417. for (i=0; i<WriteLen/sizeof(USHORT); i++)
  418. {
  419. ((PUSHORT)poutBuf)[i] = (USHORT)i;
  420. }
  421. }
  422. // Start of main Write/Read loop
  423. //
  424. for (i=0; i<Count && !Abort && !fail; i++)
  425. {
  426. // Write to the output pipe if we have an output buffer
  427. // and we've opened the output pipe.
  428. //
  429. if ((poutBuf || WriteZero) && hWrite != INVALID_HANDLE_VALUE)
  430. {
  431. //
  432. // send the write
  433. //
  434. success = WriteFile(hWrite,
  435. poutBuf,
  436. WriteLen,
  437. &nBytesWrite,
  438. &overlapped);
  439. if (!success)
  440. {
  441. lastError = GetLastError();
  442. if (lastError != ERROR_IO_PENDING)
  443. {
  444. printf("WriteFile failed, LastError 0x%08X\n",
  445. lastError);
  446. fail++;
  447. break;
  448. }
  449. }
  450. // Wait for either the write to complete or a cancel by the user
  451. //
  452. while (TRUE)
  453. {
  454. dwRet = WaitForMultipleObjects(
  455. 2,
  456. waitHandles,
  457. FALSE,
  458. INFINITE
  459. );
  460. if (dwRet == WAIT_OBJECT_0)
  461. {
  462. FlushConsoleInputBuffer(hConsole);
  463. if (Abort)
  464. {
  465. if (Cancel)
  466. {
  467. printf("Cancelling Write!\n");
  468. success = CancelIo(hWrite);
  469. break;
  470. }
  471. else
  472. {
  473. printf("Aborting Write!\n");
  474. success = AbortPipe(hWrite);
  475. break;
  476. }
  477. }
  478. }
  479. else
  480. {
  481. break; // Write is complete
  482. }
  483. }
  484. success = GetOverlappedResult(hWrite,
  485. &overlapped,
  486. &nBytesWrite,
  487. FALSE);
  488. // Do screen I/O if we aren't in perf mode
  489. //
  490. if (!TestMode)
  491. {
  492. printf("<PIPE%02d> W (%04.4d) : request %06.6d bytes -- %06.6d bytes written\n",
  493. OutPipeNum, i, WriteLen, nBytesWrite);
  494. }
  495. }
  496. // Read from the input pipe if we have an input buffer
  497. // and we've opened the input pipe.
  498. //
  499. if ((pinBuf || ReadZero) && hRead != INVALID_HANDLE_VALUE)
  500. {
  501. success = ReadFile(hRead,
  502. pinBuf,
  503. ReadLen,
  504. &nBytesRead,
  505. &overlapped);
  506. if (!success)
  507. {
  508. lastError = GetLastError();
  509. if (lastError != ERROR_IO_PENDING)
  510. {
  511. printf("ReadFile failed, LastError 0x%08X\n",
  512. lastError);
  513. fail++;
  514. break;
  515. }
  516. }
  517. // Wait for either the read to complete or a cancel by the user
  518. //
  519. while (TRUE)
  520. {
  521. dwRet = WaitForMultipleObjects(
  522. 2,
  523. waitHandles,
  524. FALSE,
  525. INFINITE
  526. );
  527. if (dwRet == WAIT_OBJECT_0)
  528. {
  529. FlushConsoleInputBuffer(hConsole);
  530. if (Abort)
  531. {
  532. if (Cancel)
  533. {
  534. printf("Cancelling Read!\n");
  535. success = CancelIo(hRead);
  536. break;
  537. }
  538. else
  539. {
  540. printf("Aborting Read!\n");
  541. success = AbortPipe(hRead);
  542. break;
  543. }
  544. }
  545. }
  546. else
  547. {
  548. break; // Read is complete
  549. }
  550. }
  551. success = GetOverlappedResult(hRead,
  552. &overlapped,
  553. &nBytesRead,
  554. FALSE);
  555. // Do screen I/O if we aren't in perf mode
  556. //
  557. if (!TestMode)
  558. {
  559. printf("<PIPE%02d> R (%04.4d) : request %06.6d bytes -- %06.6d bytes read\n",
  560. InPipeNum, i, ReadLen, nBytesRead);
  561. }
  562. // Dump the read data if desired
  563. //
  564. if (DumpFlag)
  565. {
  566. DumpBuff(pinBuf, nBytesRead);
  567. }
  568. if (poutBuf)
  569. {
  570. //
  571. // validate the input buffer against what
  572. // we sent to the 82930 (loopback test)
  573. //
  574. ok = CompareBuffs(pinBuf, poutBuf, nBytesRead);
  575. if (ok != 1)
  576. {
  577. fail++;
  578. }
  579. }
  580. }
  581. }
  582. //
  583. // End of main Write/Read loop
  584. return fail;
  585. }
  586. //*****************************************************************************
  587. //
  588. // Usage()
  589. //
  590. //*****************************************************************************
  591. void
  592. Usage ()
  593. {
  594. printf("RW.EXE\n");
  595. printf("usage:\n");
  596. printf("-# [n] where n is the device instance to open\n");
  597. printf("-r [n] where n is number of bytes to read\n");
  598. printf("-ro [n] where n is offset from page boundary for read buffer\n");
  599. printf("-R reset the input pipe\n");
  600. printf("-w [n] where n is number of bytes to write\n");
  601. printf("-wo [n] where n is offset from page boundary for write buffer\n");
  602. printf("-W reset the output pipe\n");
  603. printf("-c [n] where n is number of iterations (default = 1)\n");
  604. printf("-f [n] where n is offset from current ISO frame\n");
  605. printf("-i [s] where s is the input pipe (default PIPE00)\n");
  606. printf("-o [s] where s is the output pipe (default PIPE01)\n");
  607. printf("-t test mode - less screen I/O with pass/fail at end of test\n");
  608. printf("-d dump read data\n");
  609. printf("-S STALL pipe(s) specified by -i and/or -o\n");
  610. printf("-A [n] Select Alternate Interface");
  611. printf("-Z Reset Device");
  612. }
  613. //*****************************************************************************
  614. //
  615. // ParseArgs()
  616. //
  617. //*****************************************************************************
  618. BOOL
  619. ParseArgs (
  620. int argc,
  621. char *argv[]
  622. )
  623. {
  624. int i, j;
  625. BOOL in, out, stall;
  626. in = FALSE;
  627. out = FALSE;
  628. stall = FALSE;
  629. if (argc < 2)
  630. {
  631. Usage();
  632. return FALSE;
  633. }
  634. for (i=1; i<argc; i++) {
  635. if (argv[i][0] == '-' ||
  636. argv[i][0] == '/') {
  637. switch(argv[i][1]) {
  638. case '#':
  639. if (++i == argc) {
  640. Usage();
  641. return FALSE;
  642. }
  643. else {
  644. DevInstance = atoi(argv[i]);
  645. }
  646. break;
  647. case 'R':
  648. ReadReset = TRUE;
  649. break;
  650. case 'r':
  651. if (i+1 == argc) {
  652. Usage();
  653. return FALSE;
  654. }
  655. else {
  656. switch(argv[i][2])
  657. {
  658. case 0:
  659. ReadLen = atoi(argv[++i]);
  660. if (!ReadLen)
  661. {
  662. ReadZero = TRUE;
  663. }
  664. break;
  665. case 'o':
  666. ReadOffset = atoi(argv[++i]) & 0x00000FFF;
  667. break;
  668. default:
  669. Usage();
  670. return FALSE;
  671. }
  672. }
  673. break;
  674. case 'W':
  675. WriteReset = TRUE;
  676. break;
  677. case 'w':
  678. if (i+1 == argc) {
  679. Usage();
  680. return FALSE;
  681. }
  682. else {
  683. switch(argv[i][2])
  684. {
  685. case 0:
  686. WriteLen = atoi(argv[++i]);
  687. if (!WriteLen) {
  688. WriteZero = TRUE;
  689. }
  690. break;
  691. case 'o':
  692. WriteOffset = atoi(argv[++i]) & 0x00000FFF;
  693. break;
  694. default:
  695. Usage();
  696. return FALSE;
  697. }
  698. }
  699. break;
  700. case 'c':
  701. if (++i == argc) {
  702. Usage();
  703. return FALSE;
  704. }
  705. else {
  706. Count = atoi(argv[i]);
  707. }
  708. break;
  709. case 'f':
  710. if (++i == argc) {
  711. Usage();
  712. return FALSE;
  713. }
  714. else {
  715. Offset = atoi(argv[i]);
  716. OffsetHigh = 1;
  717. }
  718. break;
  719. case 't':
  720. TestMode = TRUE;
  721. break;
  722. case 'i':
  723. if (++i == argc) {
  724. Usage();
  725. return FALSE;
  726. }
  727. else {
  728. for (j=0; argv[i][j] && !isdigit(argv[i][j]); j++) {
  729. }
  730. if (argv[i][j])
  731. {
  732. InPipeNum = atoi(&argv[i][j]);
  733. in = TRUE;
  734. }
  735. }
  736. break;
  737. case 'o':
  738. if (++i == argc) {
  739. Usage();
  740. return FALSE;
  741. }
  742. else {
  743. for (j=0; argv[i][j] && !isdigit(argv[i][j]); j++) {
  744. }
  745. if (argv[i][j])
  746. {
  747. OutPipeNum = atoi(&argv[i][j]);
  748. out = TRUE;
  749. }
  750. }
  751. break;
  752. case 'd':
  753. DumpFlag = TRUE;
  754. break;
  755. case 'S':
  756. stall = TRUE;
  757. break;
  758. case 'A':
  759. if (++i == argc) {
  760. Usage();
  761. return FALSE;
  762. }
  763. else {
  764. SelectAlt = TRUE;
  765. Alternate = (UCHAR)atoi(argv[i]);
  766. }
  767. break;
  768. case 'Z':
  769. Reset = TRUE;
  770. break;
  771. case 'v':
  772. Verbose = TRUE;
  773. break;
  774. default:
  775. Usage();
  776. return FALSE;
  777. }
  778. }
  779. }
  780. if (ReadZero) {
  781. ReadOffset = 0;
  782. }
  783. if (WriteZero) {
  784. WriteOffset = 0;
  785. }
  786. if (stall && in) {
  787. StallIn = TRUE;
  788. }
  789. if (stall && out) {
  790. StallOut = TRUE;
  791. }
  792. // Dump parsed args if desired for debug
  793. //
  794. if (Verbose)
  795. {
  796. printf("DevInstance: %d\n", DevInstance);
  797. printf("TestMode: %d\n", TestMode);
  798. printf("inPipe: PIPE%02d\n", InPipeNum);
  799. printf("outPipe: PIPE%02d\n", OutPipeNum);
  800. printf("TestMode: %d\n", TestMode);
  801. printf("Count: %d\n", Count);
  802. printf("WriteLen: %d\n", WriteLen);
  803. printf("WriteOffset: %d\n", WriteOffset);
  804. printf("WriteReset: %d\n", WriteReset);
  805. printf("WriteZero: %d\n", WriteZero);
  806. printf("ReadLen: %d\n", ReadLen);
  807. printf("ReadOffset: %d\n", ReadOffset);
  808. printf("ReadReset: %d\n", ReadReset);
  809. printf("ReadZero: %d\n", ReadZero);
  810. printf("DumpFlag: %d\n", DumpFlag);
  811. printf("Verbose: %d\n", Verbose);
  812. printf("Offset: %d\n", Offset);
  813. printf("OffsetHigh: %d\n", OffsetHigh);
  814. printf("StallIn: %d\n", StallIn);
  815. printf("StallOut: %d\n", StallOut);
  816. }
  817. return TRUE;
  818. }
  819. //*****************************************************************************
  820. //
  821. // EnumDevices()
  822. //
  823. //*****************************************************************************
  824. PDEVICENODE
  825. EnumDevices (
  826. LPGUID Guid
  827. )
  828. {
  829. HDEVINFO deviceInfo;
  830. SP_DEVICE_INTERFACE_DATA deviceInfoData;
  831. PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData;
  832. ULONG index;
  833. ULONG requiredLength;
  834. PDEVICENODE deviceNode;
  835. PDEVICENODE deviceNodeHead;
  836. deviceNodeHead = NULL;
  837. deviceInfo = SetupDiGetClassDevs(Guid,
  838. NULL,
  839. NULL,
  840. (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
  841. deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  842. for (index=0;
  843. SetupDiEnumDeviceInterfaces(deviceInfo,
  844. 0,
  845. Guid,
  846. index,
  847. &deviceInfoData);
  848. index++)
  849. {
  850. SetupDiGetDeviceInterfaceDetail(deviceInfo,
  851. &deviceInfoData,
  852. NULL,
  853. 0,
  854. &requiredLength,
  855. NULL);
  856. deviceDetailData = GlobalAlloc(GPTR, requiredLength);
  857. deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  858. SetupDiGetDeviceInterfaceDetail(deviceInfo,
  859. &deviceInfoData,
  860. deviceDetailData,
  861. requiredLength,
  862. &requiredLength,
  863. NULL);
  864. requiredLength = sizeof(DEVICENODE) +
  865. strlen(deviceDetailData->DevicePath) + 1;
  866. deviceNode = GlobalAlloc(GPTR, requiredLength);
  867. strcpy(deviceNode->DevicePath, deviceDetailData->DevicePath);
  868. deviceNode->Next = deviceNodeHead;
  869. deviceNodeHead = deviceNode;
  870. GlobalFree(deviceDetailData);
  871. }
  872. SetupDiDestroyDeviceInfoList(deviceInfo);
  873. return deviceNodeHead;
  874. }
  875. //*****************************************************************************
  876. //
  877. // OpenDevice()
  878. //
  879. //*****************************************************************************
  880. HANDLE
  881. OpenDevice (
  882. PDEVICENODE DeviceNode
  883. )
  884. {
  885. HANDLE devHandle;
  886. devHandle = INVALID_HANDLE_VALUE;
  887. devHandle = CreateFile(DeviceNode->DevicePath,
  888. GENERIC_WRITE | GENERIC_READ,
  889. FILE_SHARE_WRITE | FILE_SHARE_READ,
  890. NULL,
  891. OPEN_EXISTING,
  892. 0,
  893. NULL);
  894. if (devHandle == INVALID_HANDLE_VALUE)
  895. {
  896. NOISY(("Failed to open (%s) = %d\n",
  897. DeviceNode->DevicePath, GetLastError()));
  898. }
  899. return devHandle;
  900. }
  901. //*****************************************************************************
  902. //
  903. // OpenDevicePipe()
  904. //
  905. //*****************************************************************************
  906. HANDLE
  907. OpenDevicePipe (
  908. PDEVICENODE DeviceNode,
  909. ULONG PipeNum
  910. )
  911. {
  912. PCHAR devName;
  913. HANDLE devHandle;
  914. devHandle = INVALID_HANDLE_VALUE;
  915. if (PipeNum <= 99)
  916. {
  917. devName = GlobalAlloc(GPTR,
  918. strlen(DeviceNode->DevicePath)+sizeof("\\00"));
  919. if (devName)
  920. {
  921. sprintf(devName, "%s\\%02d", DeviceNode->DevicePath, PipeNum);
  922. if (!TestMode)
  923. {
  924. printf("DevicePath = (%s)\n", devName);
  925. }
  926. devHandle = CreateFile(devName,
  927. GENERIC_WRITE | GENERIC_READ,
  928. FILE_SHARE_WRITE | FILE_SHARE_READ,
  929. NULL,
  930. OPEN_EXISTING,
  931. FILE_FLAG_OVERLAPPED,
  932. NULL);
  933. if (devHandle == INVALID_HANDLE_VALUE)
  934. {
  935. NOISY(("Failed to open (%s) = %d\n",
  936. devName, GetLastError()));
  937. }
  938. else
  939. {
  940. if (!TestMode)
  941. {
  942. NOISY(("Opened successfully.\n"));
  943. }
  944. }
  945. GlobalFree(devName);
  946. }
  947. }
  948. return devHandle;
  949. }
  950. //*****************************************************************************
  951. //
  952. // CompareBuffs()
  953. //
  954. //*****************************************************************************
  955. BOOL
  956. CompareBuffs (
  957. PUCHAR buff1,
  958. PUCHAR buff2,
  959. ULONG length
  960. )
  961. {
  962. BOOL ok = TRUE;
  963. if (memcmp(buff1, buff2, length))
  964. {
  965. ok = FALSE;
  966. }
  967. return ok;
  968. }
  969. //*****************************************************************************
  970. //
  971. // DumpBuff()
  972. //
  973. //*****************************************************************************
  974. void
  975. DumpBuff (
  976. PUCHAR b,
  977. ULONG len
  978. )
  979. {
  980. ULONG i;
  981. for (i=0; i<len; i++) {
  982. printf("%02X ", *b++);
  983. if (i % 16 == 15) {
  984. printf("\n");
  985. }
  986. }
  987. if (i % 16 != 0) {
  988. printf("\n");
  989. }
  990. }
  991. //*****************************************************************************
  992. //
  993. // ResetPipe()
  994. //
  995. //*****************************************************************************
  996. BOOL
  997. ResetPipe(
  998. HANDLE hPipe
  999. )
  1000. {
  1001. int nBytes;
  1002. return DeviceIoControl(hPipe,
  1003. IOCTL_I82930_RESET_PIPE,
  1004. NULL,
  1005. 0,
  1006. NULL,
  1007. 0,
  1008. &nBytes,
  1009. NULL);
  1010. }
  1011. //*****************************************************************************
  1012. //
  1013. // StallPipe()
  1014. //
  1015. //*****************************************************************************
  1016. BOOL
  1017. StallPipe(
  1018. HANDLE hPipe
  1019. )
  1020. {
  1021. int nBytes;
  1022. return DeviceIoControl(hPipe,
  1023. IOCTL_I82930_STALL_PIPE,
  1024. NULL,
  1025. 0,
  1026. NULL,
  1027. 0,
  1028. &nBytes,
  1029. NULL);
  1030. }
  1031. //*****************************************************************************
  1032. //
  1033. // AbortPipe()
  1034. //
  1035. //*****************************************************************************
  1036. BOOL
  1037. AbortPipe(
  1038. HANDLE hPipe
  1039. )
  1040. {
  1041. int nBytes;
  1042. return DeviceIoControl(hPipe,
  1043. IOCTL_I82930_ABORT_PIPE,
  1044. NULL,
  1045. 0,
  1046. NULL,
  1047. 0,
  1048. &nBytes,
  1049. NULL);
  1050. }
  1051. //*****************************************************************************
  1052. //
  1053. // SelectAlternate()
  1054. //
  1055. //*****************************************************************************
  1056. BOOL
  1057. SelectAlternate(
  1058. HANDLE hDevice,
  1059. UCHAR AlternateSetting
  1060. )
  1061. {
  1062. int nBytes;
  1063. return DeviceIoControl(hDevice,
  1064. IOCTL_I82930_SELECT_ALTERNATE_INTERFACE,
  1065. &AlternateSetting,
  1066. sizeof(UCHAR),
  1067. NULL,
  1068. 0,
  1069. &nBytes,
  1070. NULL);
  1071. }
  1072. //*****************************************************************************
  1073. //
  1074. // ResetDevice()
  1075. //
  1076. //*****************************************************************************
  1077. BOOL
  1078. ResetDevice(
  1079. HANDLE hDevice
  1080. )
  1081. {
  1082. int nBytes;
  1083. return DeviceIoControl(hDevice,
  1084. IOCTL_I82930_RESET_DEVICE,
  1085. NULL,
  1086. 0,
  1087. NULL,
  1088. 0,
  1089. &nBytes,
  1090. NULL);
  1091. }
  1092. //*****************************************************************************
  1093. //
  1094. // CtrlHandlerRoutine()
  1095. //
  1096. //*****************************************************************************
  1097. BOOL WINAPI
  1098. CtrlHandlerRoutine (
  1099. DWORD dwCtrlType
  1100. )
  1101. {
  1102. BOOL handled;
  1103. switch (dwCtrlType)
  1104. {
  1105. case CTRL_C_EVENT:
  1106. Cancel = TRUE;
  1107. case CTRL_BREAK_EVENT:
  1108. Abort = TRUE;
  1109. handled = TRUE;
  1110. break;
  1111. default:
  1112. handled = FALSE;
  1113. break;
  1114. }
  1115. return handled;
  1116. }