rwiso.c
上传用户:leituo004
上传日期:2014-11-03
资源大小:159k
文件大小:31k
源码类别:

驱动编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1997-1998  Microsoft Corporation
  3. Module Name:
  4.     RwIso.c
  5. Abstract:
  6.     Console test app for IsoUsb.sys driver
  7. Environment:
  8.     user mode only
  9. Notes:
  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.   Copyright (c) 1997-1998 Microsoft Corporation.  All Rights Reserved.
  15. Revision History:
  16.         11/17/97: created
  17. --*/
  18. #include <windows.h>
  19. #include <conio.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <assert.h>
  23. #include <time.h>
  24. #include "devioctl.h"
  25. #include <setupapi.h>
  26. #include <basetyps.h>
  27. #include "IsoUsr.h"
  28. #include "usbdi.h"
  29. #define NOISY(_x_) printf _x_ ;
  30. char inPipe[32] = "PIPE04";     // pipe name for iso input pipe on our test board
  31. char outPipe[32] = "PIPE05";    // pipe name for iso output pipe on our test board
  32. char completeDeviceName[256] = "";  //generated from the GUID registered by the driver itself
  33. BOOL fDumpUsbConfig = FALSE;    // flags set in response to console command line switches
  34. BOOL fDumpReadData = FALSE;
  35. BOOL fRead = FALSE;
  36. BOOL fWrite = FALSE;
  37. PVOID gpStreamObj;
  38. char gbuf[256];
  39. BOOL fIsoStreamStarted = FALSE;
  40. HANDLE ghStreamDev = NULL;
  41. int gMS = 10000; // default to 10 secs stream test
  42. int gDebugLevel = 1;      // higher == more verbose, default is 1, 0 turns off all
  43. ULONG IterationCount = 1; // count of iterations of the test we are to perform
  44. int WriteLen = 0;         // #bytes to write
  45. int ReadLen = 0;          // #bytes to read
  46. void StartIsoStream( void );
  47. void StopIsoStream( void );
  48. // functions
  49. HANDLE
  50. OpenOneDevice (
  51.     IN       HDEVINFO                    HardwareDeviceInfo,
  52.     IN       PSP_DEVICE_INTERFACE_DATA   DeviceInfoData,
  53.         IN               char *devName
  54.     )
  55. /*++
  56. Routine Description:
  57.     Given the HardwareDeviceInfo, representing a handle to the plug and
  58.     play information, and deviceInfoData, representing a specific usb device,
  59.     open that device and fill in all the relevant information in the given
  60.     USB_DEVICE_DESCRIPTOR structure.
  61. Arguments:
  62.     HardwareDeviceInfo:  handle to info obtained from Pnp mgr via SetupDiGetClassDevs()
  63.     DeviceInfoData:      ptr to info obtained via SetupDiEnumDeviceInterfaces()
  64. Return Value:
  65.     return HANDLE if the open and initialization was successfull,
  66.         else INVLAID_HANDLE_VALUE.
  67. --*/
  68. {
  69.     PSP_DEVICE_INTERFACE_DETAIL_DATA     functionClassDeviceData = NULL;
  70.     ULONG                                predictedLength = 0;
  71.     ULONG                                requiredLength = 0;
  72.         HANDLE                                                           hOut = INVALID_HANDLE_VALUE;
  73.     //
  74.     // allocate a function class device data structure to receive the
  75.     // goods about this particular device.
  76.     //
  77.     SetupDiGetDeviceInterfaceDetail (
  78.             HardwareDeviceInfo,
  79.             DeviceInfoData,
  80.             NULL, // probing so no output buffer yet
  81.             0, // probing so output buffer length of zero
  82.             &requiredLength,
  83.             NULL); // not interested in the specific dev-node
  84.     predictedLength = requiredLength;
  85.     // sizeof (SP_FNCLASS_DEVICE_DATA) + 512;
  86.     functionClassDeviceData = malloc (predictedLength);
  87.     functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
  88.     //
  89.     // Retrieve the information from Plug and Play.
  90.     //
  91.     if (! SetupDiGetDeviceInterfaceDetail (
  92.                HardwareDeviceInfo,
  93.                DeviceInfoData,
  94.                functionClassDeviceData,
  95.                predictedLength,
  96.                &requiredLength,
  97.                NULL)) {
  98.                 free( functionClassDeviceData );
  99.         return INVALID_HANDLE_VALUE;
  100.     }
  101.         strcpy( devName,functionClassDeviceData->DevicePath) ;
  102.         printf( "Attempting to open %sn", devName );
  103.     hOut = CreateFile (
  104.                   functionClassDeviceData->DevicePath,
  105.                   GENERIC_READ | GENERIC_WRITE,
  106.                   FILE_SHARE_READ | FILE_SHARE_WRITE,
  107.                   NULL, // no SECURITY_ATTRIBUTES structure
  108.                   OPEN_EXISTING, // No special create flags
  109.                   0, // No special attributes
  110.                   NULL); // No template file
  111.     if (INVALID_HANDLE_VALUE == hOut) {
  112.                 printf( "FAILED to open %sn", devName );
  113.     }
  114.         free( functionClassDeviceData );
  115.         return hOut;
  116. }
  117. HANDLE
  118. OpenUsbDevice( LPGUID  pGuid, char *outNameBuf)
  119. /*++
  120. Routine Description:
  121.    Do the required PnP things in order to find
  122.    the next available proper device in the system at this time.
  123. Arguments:
  124.     pGuid:      ptr to GUID registered by the driver itself
  125.     outNameBuf: the generated name for this device
  126. Return Value:
  127.     return HANDLE if the open and initialization was successful,
  128.         else INVLAID_HANDLE_VALUE.
  129. --*/
  130. {
  131.    ULONG NumberDevices;
  132.    HANDLE hOut = INVALID_HANDLE_VALUE;
  133.    HDEVINFO                 hardwareDeviceInfo;
  134.    SP_DEVICE_INTERFACE_DATA deviceInfoData;
  135.    ULONG                    i;
  136.    BOOLEAN                  done;
  137.    PUSB_DEVICE_DESCRIPTOR   usbDeviceInst;
  138.    PUSB_DEVICE_DESCRIPTOR       *UsbDevices = &usbDeviceInst;
  139.    *UsbDevices = NULL;
  140.    NumberDevices = 0;
  141.    //
  142.    // Open a handle to the plug and play dev node.
  143.    // SetupDiGetClassDevs() returns a device information set that contains info on all
  144.    // installed devices of a specified class.
  145.    //
  146.    hardwareDeviceInfo = SetupDiGetClassDevs (
  147.                            pGuid,
  148.                            NULL, // Define no enumerator (global)
  149.                            NULL, // Define no
  150.                            (DIGCF_PRESENT | // Only Devices present
  151.                             DIGCF_DEVICEINTERFACE)); // Function class devices.
  152.    //
  153.    // Take a wild guess at the number of devices we have;
  154.    // Be prepared to realloc and retry if there are more than we guessed
  155.    //
  156.    NumberDevices = 4;
  157.    done = FALSE;
  158.    deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
  159.    i=0;
  160.    while (!done) {
  161.       NumberDevices *= 2;
  162.       if (*UsbDevices) {
  163.          *UsbDevices =
  164.                realloc (*UsbDevices, (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR)));
  165.       } else {
  166.          *UsbDevices = calloc (NumberDevices, sizeof (USB_DEVICE_DESCRIPTOR));
  167.       }
  168.       if (NULL == *UsbDevices) {
  169.          // SetupDiDestroyDeviceInfoList destroys a device information set
  170.          // and frees all associated memory.
  171.          SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
  172.          return INVALID_HANDLE_VALUE;
  173.       }
  174.       usbDeviceInst = *UsbDevices + i;
  175.       for (; i < NumberDevices; i++) {
  176.          // SetupDiEnumDeviceInterfaces() returns information about device interfaces
  177.          // exposed by one or more devices. Each call returns information about one interface;
  178.          // the routine can be called repeatedly to get information about several interfaces
  179.          // exposed by one or more devices.
  180.          if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
  181.                                          0, // We don't care about specific PDOs
  182.                                                                                  pGuid,
  183.                                          i,
  184.                                          &deviceInfoData)) {
  185.             hOut = OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, outNameBuf);
  186.                         if ( hOut != INVALID_HANDLE_VALUE ) {
  187.                done = TRUE;
  188.                break;
  189.                         }
  190.          } else {
  191.             if (ERROR_NO_MORE_ITEMS == GetLastError()) {
  192.                done = TRUE;
  193.                break;
  194.             }
  195.          }
  196.       }
  197.    }
  198.    NumberDevices = i;
  199.    // SetupDiDestroyDeviceInfoList() destroys a device information set
  200.    // and frees all associated memory.
  201.    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
  202.    free ( *UsbDevices );
  203.    return hOut;
  204. }
  205. BOOL
  206. GetUsbDeviceFileName( LPGUID  pGuid, char *outNameBuf)
  207. /*++
  208. Routine Description:
  209.     Given a ptr to a driver-registered GUID, give us a string with the device name
  210.     that can be used in a CreateFile() call.
  211.     Actually briefly opens and closes the device and sets outBuf if successfull;
  212.     returns FALSE if not
  213. Arguments:
  214.     pGuid:      ptr to GUID registered by the driver itself
  215.     outNameBuf: the generated zero-terminated name for this device
  216. Return Value:
  217.     TRUE on success else FALSE
  218. --*/
  219. {
  220.         HANDLE hDev = OpenUsbDevice( pGuid, outNameBuf );
  221.         if ( hDev != INVALID_HANDLE_VALUE )
  222.         {
  223.                 CloseHandle( hDev );
  224.                 return TRUE;
  225.         }
  226.         return FALSE;
  227. }
  228. HANDLE
  229. open_dev()
  230. /*++
  231. Routine Description:
  232.     Called by dumpUsbConfig() to open an instance of our device
  233. Arguments:
  234.     None
  235. Return Value:
  236.     Device handle on success else NULL
  237. --*/
  238. {
  239.         HANDLE hDEV = OpenUsbDevice( (LPGUID)&GUID_CLASS_I82930_ISO, completeDeviceName);
  240.         if (hDEV == INVALID_HANDLE_VALUE) {
  241.                 printf("Failed to open (%s) = %d", completeDeviceName, GetLastError());
  242.         } else {
  243.                 printf("DeviceName = (%s)n", completeDeviceName);
  244.     }           
  245.         return hDEV;
  246. }
  247. HANDLE
  248. open_file( char *filename)
  249. /*++
  250. Routine Description:
  251.     Called by main() to open an instance of our device after obtaining its name
  252. Arguments:
  253.     None
  254. Return Value:
  255.     Device handle on success else NULL
  256. --*/
  257. {
  258.         int success = 1;
  259.         HANDLE h;
  260.         if ( !GetUsbDeviceFileName(
  261.                 (LPGUID) &GUID_CLASS_I82930_ISO,
  262.                 completeDeviceName) )
  263.         {
  264.                 NOISY(("Failed to GetUsbDeviceFileNamen", GetLastError()));
  265.                 return  INVALID_HANDLE_VALUE;
  266.         }
  267.     strcat (completeDeviceName,
  268.                         "\"
  269.                         );                      
  270.     strcat (completeDeviceName,
  271.                         filename
  272.                         );                                      
  273.         printf("completeDeviceName = (%s)n", completeDeviceName);
  274.         h = CreateFile(completeDeviceName,
  275.                 GENERIC_WRITE | GENERIC_READ,
  276.                 FILE_SHARE_WRITE | FILE_SHARE_READ,
  277.                 NULL,
  278.                 OPEN_EXISTING,
  279.                 0,
  280.                 NULL);
  281.         if (h == INVALID_HANDLE_VALUE) {
  282.                 NOISY(("Failed to open (%s) = %d", completeDeviceName, GetLastError()));
  283.                 success = 0;
  284.         } else {
  285.                         NOISY(("Opened successfully.n"));
  286.     }           
  287.         return h;
  288. }
  289. void
  290. usage()
  291. /*++
  292. Routine Description:
  293.     Called by main() to dump usage info to the console when
  294.     the app is called with no parms or with an invalid parm
  295. Arguments:
  296.     None
  297. Return Value:
  298.     None
  299. --*/
  300. {
  301.     printf("Usage for Read/Write test:n");
  302.     printf("-r [n] where n is number of bytes to readn");
  303.     printf("-w [n] where n is number of bytes to writen");
  304.     printf("-c [n] where n is number of iterations (default = 1)n");
  305.     printf("-i [s] where s is the input pipen");
  306.     printf("-o [s] where s is the output pipen");
  307.     printf("-v verbose -- dumps read datan");
  308.     printf("nUsage for USB and Endpoint info:n");
  309.     printf("-u to dump USB configuration and pipe info n");
  310.     printf("-g [s] Run Isochronous test stream for 's' seconds n");
  311. }
  312. void
  313. parse(
  314.     int argc,
  315.     char *argv[] )
  316. /*++
  317. Routine Description:
  318.     Called by main() to parse command line parms
  319. Arguments:
  320.     argc and argv that was passed to main()
  321. Return Value:
  322.     Sets global flags as per user function request
  323. --*/
  324. {
  325.     int i;
  326.         if ( argc < 2 ) // give usage if invoked with no parms
  327.                 usage();
  328.     for (i=0; i<argc; i++) {
  329.         if (argv[i][0] == '-' ||
  330.             argv[i][0] == '/') {
  331.             switch(argv[i][1]) {
  332.             case 'r':
  333.             case 'R':
  334.                 ReadLen = atoi(&argv[i+1][0]);
  335.                                 fRead = TRUE;
  336.                 i++;
  337.                 break;
  338.             case 'w':
  339.             case 'W':
  340.                 WriteLen = atoi(&argv[i+1][0]);
  341.                                 fWrite = TRUE;
  342.                 i++;
  343.                 break;
  344.             case 'c':
  345.             case 'C':
  346.                 IterationCount = atoi(&argv[i+1][0]);
  347.                 i++;
  348.                 break;
  349.             case 'i':
  350.             case 'I':
  351.                 strcpy(inPipe, &argv[i+1][0]);
  352.                 i++;
  353.                 break;
  354.             case 'u':
  355.             case 'U':
  356.                 fDumpUsbConfig = TRUE;
  357.                                 i++;
  358.                 break;
  359.             case 'v':
  360.             case 'V':
  361.                 fDumpReadData = TRUE;
  362.                                 i++;
  363.                 break;
  364.                          case 'o':
  365.              case 'O':
  366.                 strcpy(outPipe, &argv[i+1][0]);
  367.                 i++;
  368.                 break;
  369.                          case 'g':
  370.              case 'G':
  371.                  gMS = 1000 * atoi(&argv[i+1][0]);
  372.                                  StartIsoStream();
  373.                 break;
  374.                          case 'x':
  375.              case 'X':
  376.                                  StopIsoStream();
  377.                 break;
  378.             default:
  379.                 usage();
  380.             }
  381.         }
  382.     }
  383. }
  384. BOOL
  385. compare_buffs(char *buff1, char *buff2, int length)
  386. /*++
  387. Routine Description:
  388.     Called to verify read and write buffers match for loopback test
  389. Arguments:
  390.     buffers to compare and length
  391. Return Value:
  392.     TRUE if buffers match, else FALSE
  393. --*/
  394. {
  395.     int ok = 1;
  396.         if (memcmp(buff1, buff2, length )) {
  397.                 // Edi, and Esi point to the mismatching char and ecx indicates the
  398.                 // remaining length.
  399.                 ok = 0;
  400.         }
  401.     return ok;
  402. }
  403. #define NPERLN 8
  404. void
  405. dump(
  406.    UCHAR *b,
  407.    int len
  408. )
  409. /*++
  410. Routine Description:
  411.     Called to do formatted ascii dump to console of the io buffer
  412. Arguments:
  413.     buffer and length
  414. Return Value:
  415.     none
  416. --*/
  417. {
  418.     ULONG i;
  419.         ULONG longLen = (ULONG)len / sizeof( ULONG );
  420.         PULONG pBuf = (PULONG) b;
  421.         // dump an ordinal ULONG for each sizeof(ULONG)'th byte
  422.     printf("n****** BEGIN DUMP LEN decimal %d, 0x%xn", len,len);
  423.     for (i=0; i<longLen; i++) {
  424.         printf("%04X ", *pBuf++);
  425.         if (i % NPERLN == (NPERLN - 1)) {
  426.             printf("n");
  427.         }
  428.     }
  429.     if (i % NPERLN != 0) {
  430.         printf("n");
  431.     }
  432.     printf("n****** END DUMP LEN decimal %d, 0x%xn", len,len);
  433. }
  434. // Begin, routines for USB configuration dump (Cmdline "rwiso -u" )
  435. char
  436. *usbDescriptorTypeString(UCHAR bDescriptorType )
  437. /*++
  438. Routine Description:
  439.     Called to get ascii string of USB descriptor
  440. Arguments:
  441.         PUSB_ENDPOINT_DESCRIPTOR->bDescriptorType or
  442.         PUSB_DEVICE_DESCRIPTOR->bDescriptorType or
  443.         PUSB_INTERFACE_DESCRIPTOR->bDescriptorType or
  444.         PUSB_STRING_DESCRIPTOR->bDescriptorType or
  445.         PUSB_POWER_DESCRIPTOR->bDescriptorType or
  446.         PUSB_CONFIGURATION_DESCRIPTOR->bDescriptorType
  447. Return Value:
  448.     ptr to string
  449. --*/{
  450.         switch(bDescriptorType) {
  451.         case USB_DEVICE_DESCRIPTOR_TYPE:
  452.                 return "USB_DEVICE_DESCRIPTOR_TYPE";
  453.         case USB_CONFIGURATION_DESCRIPTOR_TYPE:
  454.                 return "USB_CONFIGURATION_DESCRIPTOR_TYPE";
  455.                 
  456.         case USB_STRING_DESCRIPTOR_TYPE:
  457.                 return "USB_STRING_DESCRIPTOR_TYPE";
  458.                 
  459.         case USB_INTERFACE_DESCRIPTOR_TYPE:
  460.                 return "USB_INTERFACE_DESCRIPTOR_TYPE";
  461.                 
  462.         case USB_ENDPOINT_DESCRIPTOR_TYPE:
  463.                 return "USB_ENDPOINT_DESCRIPTOR_TYPE";
  464.                 
  465. #ifdef USB_POWER_DESCRIPTOR_TYPE // this is the older definintion which is actually obsolete
  466.     // workaround for temporary bug in 98ddk, older USB100.h file
  467.         case USB_POWER_DESCRIPTOR_TYPE:
  468.                 return "USB_POWER_DESCRIPTOR_TYPE";
  469. #endif
  470.                 
  471. #ifdef USB_RESERVED_DESCRIPTOR_TYPE  // this is the current version of USB100.h as in NT5DDK
  472.         case USB_RESERVED_DESCRIPTOR_TYPE:
  473.                 return "USB_RESERVED_DESCRIPTOR_TYPE";
  474.         case USB_CONFIG_POWER_DESCRIPTOR_TYPE:
  475.                 return "USB_CONFIG_POWER_DESCRIPTOR_TYPE";
  476.         case USB_INTERFACE_POWER_DESCRIPTOR_TYPE:
  477.                 return "USB_INTERFACE_POWER_DESCRIPTOR_TYPE";
  478. #endif // for current nt5ddk version of USB100.h
  479.                 
  480.         default:
  481.                 return "??? UNKNOWN!!"; 
  482.         }
  483. }
  484. char
  485. *usbEndPointTypeString(UCHAR bmAttributes)
  486. /*++
  487. Routine Description:
  488.     Called to get ascii string of endpt descriptor type
  489. Arguments:
  490.         PUSB_ENDPOINT_DESCRIPTOR->bmAttributes
  491. Return Value:
  492.     ptr to string
  493. --*/
  494. {
  495.         UINT typ = bmAttributes & USB_ENDPOINT_TYPE_MASK;
  496.         switch( typ) {
  497.         case USB_ENDPOINT_TYPE_INTERRUPT:
  498.                 return "USB_ENDPOINT_TYPE_INTERRUPT";
  499.         case USB_ENDPOINT_TYPE_BULK:
  500.                 return "USB_ENDPOINT_TYPE_BULK";        
  501.         case USB_ENDPOINT_TYPE_ISOCHRONOUS:
  502.                 return "USB_ENDPOINT_TYPE_ISOCHRONOUS"; 
  503.                 
  504.         case USB_ENDPOINT_TYPE_CONTROL:
  505.                 return "USB_ENDPOINT_TYPE_CONTROL";     
  506.                 
  507.         default:
  508.                 return "??? UNKNOWN!!"; 
  509.         }
  510. }
  511. char
  512. *usbConfigAttributesString(UCHAR bmAttributes)
  513. /*++
  514. Routine Description:
  515.     Called to get ascii string of USB_CONFIGURATION_DESCRIPTOR attributes
  516. Arguments:
  517.         PUSB_CONFIGURATION_DESCRIPTOR->bmAttributes
  518. Return Value:
  519.     ptr to string
  520. --*/
  521. {
  522.         UINT typ = bmAttributes & USB_CONFIG_POWERED_MASK;
  523.         switch( typ) {
  524.         case USB_CONFIG_BUS_POWERED:
  525.                 return "USB_CONFIG_BUS_POWERED";
  526.         case USB_CONFIG_SELF_POWERED:
  527.                 return "USB_CONFIG_SELF_POWERED";
  528.                 
  529.         case USB_CONFIG_REMOTE_WAKEUP:
  530.                 return "USB_CONFIG_REMOTE_WAKEUP";
  531.                 
  532.         default:
  533.                 return "??? UNKNOWN!!"; 
  534.         }
  535. }
  536. void
  537. print_USB_CONFIGURATION_DESCRIPTOR(PUSB_CONFIGURATION_DESCRIPTOR cd)
  538. /*++
  539. Routine Description:
  540.     Called to do formatted ascii dump to console of a USB config descriptor
  541. Arguments:
  542.     ptr to USB configuration descriptor
  543. Return Value:
  544.     none
  545. --*/
  546. {
  547.     printf("n===================nUSB_CONFIGURATION_DESCRIPTORn");
  548.     printf(
  549.     "bLength = 0x%x, decimal %dn", cd->bLength, cd->bLength
  550.     );
  551.     printf(
  552.     "bDescriptorType = 0x%x ( %s )n", cd->bDescriptorType, usbDescriptorTypeString( cd->bDescriptorType )
  553.     );
  554.     printf(
  555.     "wTotalLength = 0x%x, decimal %dn", cd->wTotalLength, cd->wTotalLength
  556.     );
  557.     printf(
  558.     "bNumInterfaces = 0x%x, decimal %dn", cd->bNumInterfaces, cd->bNumInterfaces
  559.     );
  560.     printf(
  561.     "bConfigurationValue = 0x%x, decimal %dn", cd->bConfigurationValue, cd->bConfigurationValue
  562.     );
  563.     printf(
  564.     "iConfiguration = 0x%x, decimal %dn", cd->iConfiguration, cd->iConfiguration
  565.     );
  566.     printf(
  567.     "bmAttributes = 0x%x ( %s )n", cd->bmAttributes, usbConfigAttributesString( cd->bmAttributes )
  568.     );
  569.     printf(
  570.     "MaxPower = 0x%x, decimal %dn", cd->MaxPower, cd->MaxPower
  571.     );
  572. }
  573. void
  574. print_USB_INTERFACE_DESCRIPTOR(PUSB_INTERFACE_DESCRIPTOR id, UINT ix)
  575. /*++
  576. Routine Description:
  577.     Called to do formatted ascii dump to console of a USB interface descriptor
  578. Arguments:
  579.     ptr to USB interface descriptor
  580. Return Value:
  581.     none
  582. --*/
  583. {
  584.     printf("n-----------------------------nUSB_INTERFACE_DESCRIPTOR #%dn", ix);
  585.     printf(
  586.     "bLength = 0x%xn", id->bLength
  587.     );
  588.     printf(
  589.     "bDescriptorType = 0x%x ( %s )n", id->bDescriptorType, usbDescriptorTypeString( id->bDescriptorType )
  590.     );
  591.     printf(
  592.     "bInterfaceNumber = 0x%xn", id->bInterfaceNumber
  593.     );
  594.     printf(
  595.     "bAlternateSetting = 0x%xn", id->bAlternateSetting
  596.     );
  597.     printf(
  598.     "bNumEndpoints = 0x%xn", id->bNumEndpoints
  599.     );
  600.     printf(
  601.     "bInterfaceClass = 0x%xn", id->bInterfaceClass
  602.     );
  603.     printf(
  604.     "bInterfaceSubClass = 0x%xn", id->bInterfaceSubClass
  605.     );
  606.     printf(
  607.     "bInterfaceProtocol = 0x%xn", id->bInterfaceProtocol
  608.     );
  609.     printf(
  610.     "bInterface = 0x%xn", id->iInterface
  611.     );
  612. }
  613. void
  614. print_USB_ENDPOINT_DESCRIPTOR(PUSB_ENDPOINT_DESCRIPTOR ed, int i)
  615. /*++
  616. Routine Description:
  617.     Called to do formatted ascii dump to console of a USB endpoint descriptor
  618. Arguments:
  619.     ptr to USB endpoint descriptor,
  620.         index of this endpt in interface desc
  621. Return Value:
  622.     none
  623. --*/
  624. {
  625.     printf(
  626.         "------------------------------nUSB_ENDPOINT_DESCRIPTOR for Pipe%02dn", i
  627.         );
  628.     printf(
  629.     "bLength = 0x%xn", ed->bLength
  630.     );
  631.     printf(
  632.     "bDescriptorType = 0x%x ( %s )n", ed->bDescriptorType, usbDescriptorTypeString( ed->bDescriptorType )
  633.     );
  634.         if ( USB_ENDPOINT_DIRECTION_IN( ed->bEndpointAddress ) ) {
  635.                 printf(
  636.                 "bEndpointAddress= 0x%x ( INPUT )n", ed->bEndpointAddress
  637.                 );
  638.         } else {
  639.                 printf(
  640.                 "bEndpointAddress= 0x%x ( OUTPUT )n", ed->bEndpointAddress
  641.                 );
  642.         }
  643.     printf(
  644.     "bmAttributes= 0x%x ( %s )n", ed->bmAttributes, usbEndPointTypeString ( ed->bmAttributes )
  645.     );
  646.     printf(
  647.     "wMaxPacketSize= 0x%x, decimal %dn", ed->wMaxPacketSize, ed->wMaxPacketSize
  648.     );
  649.     printf(
  650.     "bInterval = 0x%x, decimal %dn", ed->bInterval, ed->bInterval
  651.     );
  652. }
  653. void
  654. rw_dev( HANDLE hDEV )
  655. /*++
  656. Routine Description:
  657.     Called to do formatted ascii dump to console of  USB
  658.     configuration, interface, and endpoint descriptors
  659.     (Cmdline "rwiso -u" )
  660. Arguments:
  661.     handle to device
  662. Return Value:
  663.     none
  664. --*/
  665. {
  666.         ULONG success;
  667.         int siz, nBytes;
  668.         char buf[256];
  669.     PUSB_CONFIGURATION_DESCRIPTOR cd;
  670.     PUSB_INTERFACE_DESCRIPTOR id;
  671.     PUSB_ENDPOINT_DESCRIPTOR ed;
  672.         siz = sizeof(buf);
  673.         if (hDEV == INVALID_HANDLE_VALUE) {
  674.                 NOISY(("DEV not open"));
  675.                 return;
  676.         }
  677.         
  678.         success = DeviceIoControl(hDEV,
  679.                         IOCTL_ISOUSB_GET_CONFIG_DESCRIPTOR,
  680.                         buf,
  681.                         siz,
  682.                         buf,
  683.                         siz,
  684.                         &nBytes,
  685.                         NULL);
  686.         NOISY(("request complete, success = %d nBytes = %dn", success, nBytes));
  687.         
  688.         if (success) {
  689.         ULONG i;
  690.                 UINT  j, n;
  691.         char *pch;
  692.         pch = buf;
  693.                 n = 0;
  694.         cd = (PUSB_CONFIGURATION_DESCRIPTOR) pch;
  695.         print_USB_CONFIGURATION_DESCRIPTOR( cd );
  696.         pch += cd->bLength;
  697.         do {
  698.             id = (PUSB_INTERFACE_DESCRIPTOR) pch;
  699.             print_USB_INTERFACE_DESCRIPTOR(id, n++);
  700.             pch += id->bLength;
  701.             for (j=0; j<id->bNumEndpoints; j++) {
  702.                 ed = (PUSB_ENDPOINT_DESCRIPTOR) pch;
  703.                 print_USB_ENDPOINT_DESCRIPTOR(ed,j);
  704.                 pch += ed->bLength;
  705.             }
  706.             i = (ULONG)(pch - buf);
  707.         } while (i<cd->wTotalLength);
  708.         }
  709.         
  710.         return;
  711. }
  712. int  dumpUsbConfig()
  713. /*++
  714. Routine Description:
  715.     Called to do formatted ascii dump to console of  USB
  716.     configuration, interface, and endpoint descriptors
  717.     (Cmdline "rwiso -u" )
  718. Arguments:
  719.     none
  720. Return Value:
  721.     none
  722. --*/
  723. {
  724.         HANDLE hDEV = open_dev();
  725.         if ( hDEV )
  726.         {
  727.                 rw_dev( hDEV );
  728.                 CloseHandle(hDEV);
  729.         }
  730.         return 0;
  731. }
  732. //  End, routines for USB configuration and pipe info dump  (Cmdline "rwiso -u" )
  733. // Begin, routines for Iso Streaming
  734. void
  735. IsoStream( HANDLE hDEV, BOOL fStop )
  736. /*++
  737. Routine Description:
  738.     Called to start or stop an iso stream
  739.     (Cmdline "RwIso -g" )
  740. Arguments:
  741.     handle to device
  742. Return Value:
  743.     none
  744. --*/
  745. {
  746.         ULONG success;
  747.         int nBytes;
  748.         DWORD ioctl;
  749.         char i;
  750.         if ( fStop )
  751.         {
  752.                 ioctl = IOCTL_ISOUSB_STOP_ISO_STREAM;
  753.                 
  754.                 for ( i = 0; i < sizeof( gbuf ); i ++ )
  755.                         gbuf[ i ] = 0; // init outbuf to 0's to make sure read was good
  756.                 success = DeviceIoControl(hDEV,
  757.                                 ioctl,
  758.                                 &gpStreamObj, //pointer to stream object initted when stream was started
  759.                                 sizeof( PVOID),
  760.                                 gbuf, // output buffer gets back from kernel mode
  761.                                 sizeof(gbuf),
  762.                                 &nBytes,
  763.                                 NULL);
  764.                 NOISY(("DeviceIoControl STOP_ISO_STREAM complete, success = %dn", success));
  765.         }
  766.         else
  767.         {
  768.                 ioctl = IOCTL_ISOUSB_START_ISO_STREAM;
  769.                 //input is our 256-byte buffer, binary char 0-255
  770.                 for ( i = 0; i < sizeof( gbuf ); i ++ )
  771.                         gbuf[ i ] = i;
  772.                 success = DeviceIoControl(hDEV,
  773.                                 ioctl,
  774.                                 gbuf,
  775.                                 sizeof(gbuf),
  776.                                 &gpStreamObj, // will receive pointer to stream object
  777.                                 sizeof( PVOID),
  778.                                 &nBytes,
  779.                                 NULL);
  780.                 NOISY(("DeviceIoControl START_ISO_STREAM complete, success = %dn", success));
  781.         }
  782.         if (hDEV == INVALID_HANDLE_VALUE) {
  783.                 NOISY(("DEV not open"));
  784.                 return;
  785.         }
  786.         
  787.         
  788. }
  789. void StartIsoStream( void )
  790. {
  791.         if ( !ghStreamDev ) {
  792.                 ghStreamDev = open_dev();
  793.                 if ( ghStreamDev != INVALID_HANDLE_VALUE ) {
  794.                         IsoStream(  ghStreamDev , FALSE );
  795.                         Sleep( gMS );
  796.                         StopIsoStream();
  797.                 }
  798.         }
  799. }
  800. void StopIsoStream( void )
  801. {
  802.         if ( ghStreamDev ) {
  803.                 IsoStream(  ghStreamDev , TRUE );
  804.                 ghStreamDev = NULL;
  805.         }
  806. }
  807. // End, routines for Iso Streaming
  808. int _cdecl main(
  809.     int argc,
  810.         char *argv[])
  811. /*++
  812. Routine Description:
  813.     Entry point to RwIso.exe
  814.     Parses cmdline, performs user-requested tests
  815. Arguments:
  816.     argc, argv  standard console  'c' app arguments
  817. Return Value:
  818.     Zero
  819. --*/
  820. {
  821.     char *pinBuf = NULL, *poutBuf = NULL;
  822.     ULONG nBytesRead, nBytesWrite, nBytes;
  823.         ULONG i, j;
  824.     int ok;
  825.     ULONG success;
  826.     HANDLE hRead = INVALID_HANDLE_VALUE, hWrite = INVALID_HANDLE_VALUE;
  827.         char buf[1024];
  828.         clock_t start, finish;
  829.         ULONG totalBytes = 0L;
  830.         double seconds;
  831.         ULONG fail = 0L;
  832.     parse(argc, argv );
  833.         // dump USB configuation and pipe info
  834.         if( fDumpUsbConfig ) {
  835.                 dumpUsbConfig();
  836.         }
  837.         // doing a read, write, or both test
  838.         if ((fRead) || (fWrite)) {
  839.             if (fRead) {
  840.             //
  841.             // open the output file
  842.             //
  843.                         if ( fDumpReadData ) { // round size to sizeof ULONG for readable dumping
  844.                                 while( ReadLen % sizeof( ULONG ) )
  845.                                                 ReadLen++;
  846.                         }
  847.             hRead = open_file( inPipe);
  848.         
  849.                 pinBuf = malloc(ReadLen);
  850.             }
  851.             if (fWrite) {
  852.                         if ( fDumpReadData ) { // round size to sizeof ULONG for readable dumping
  853.                                 while( WriteLen % sizeof( ULONG ) )
  854.                                                 WriteLen++;
  855.                         }
  856.                 hWrite = open_file( outPipe);
  857.                 poutBuf = malloc(WriteLen);
  858.             }
  859.         for (i=0; i<IterationCount; i++) {
  860.             if (fWrite && poutBuf && hWrite != INVALID_HANDLE_VALUE) {
  861.                                 PULONG pOut = (PULONG) poutBuf;
  862.                                 ULONG  numLongs = WriteLen / sizeof( ULONG );
  863.                 //
  864.                 // put some data in the output buffer
  865.                 //
  866.                 for (j=0; j<numLongs; j++) {
  867.                     *(pOut+j) = j;
  868.                 }
  869.                 //
  870.                 // send the write
  871.                 //
  872.                     WriteFile(hWrite,
  873.                               poutBuf,
  874.                               WriteLen,
  875.                               &nBytesWrite,
  876.                               NULL);
  877.                     printf("<%s> W (%04.4d) : request %06.6d bytes -- %06.6d bytes writtenn",
  878.                             outPipe, i, WriteLen, nBytesWrite);
  879.                 assert(nBytesWrite == WriteLen);
  880.                 }
  881.                 if (fRead && pinBuf) {
  882.                     success = ReadFile(hRead,
  883.                                   pinBuf,
  884.                               ReadLen,
  885.                                   &nBytesRead,
  886.                                   NULL);
  887.                     printf("<%s> R (%04.4d) : request %06.6d bytes -- %06.6d bytes readn",
  888.                         inPipe, i, ReadLen, nBytesRead);
  889.                 if (fWrite) {
  890.                     //
  891.                     // validate the input buffer against what
  892.                     // we sent to the 82930 (loopback test)
  893.                     //
  894.                     ok = compare_buffs(pinBuf, poutBuf,  nBytesRead);
  895.                                         if( fDumpReadData ) {
  896.                                                 printf("Dumping read buffern");
  897.                                                 dump( pinBuf, nBytesRead );     
  898.                                                 printf("Dumping write buffern");
  899.                                                 dump( poutBuf, nBytesRead );
  900.                                         }
  901.                     assert(ok);
  902.                                         if(ok != 1)
  903.                                                 fail++;
  904.                     assert(ReadLen == WriteLen);
  905.                     assert(nBytesRead == ReadLen);
  906.                     assert(nBytesWrite == WriteLen);
  907.                 }
  908.                 }
  909.         
  910.         }
  911.         if (pinBuf) {
  912.             free(pinBuf);
  913.         }
  914.         if (poutBuf) {
  915.             free(poutBuf);
  916.         }
  917.                 // close devices if needed
  918.                 if(hRead != INVALID_HANDLE_VALUE)
  919.                         CloseHandle(hRead);
  920.                 if(hWrite != INVALID_HANDLE_VALUE)
  921.                         CloseHandle(hWrite);
  922.     }
  923.         
  924.         StopIsoStream(); // stop iso stream if we started one
  925.         return 0;
  926. }