• AVR Freaks

Using WinUSB

Page: 1234 > Showing page 1 of 4
Author
mzoran
Super Member
  • Total Posts : 683
  • Reward points : 0
  • Status: offline
2007/06/25 01:44:46 (permalink)
5 (1)

Using WinUSB

    I sometimes wish technical forums had more informational posts rather then just people begging for help.  So I'm going to give a shot at something informational.  Here is some information I've collected.
 
    Microchip provides a generic driver called MCHPUSB.sys that allows most of the device controlling functionality to be in the application.  Unfortunatly, this driver isn't signed and it isn't supported in Vista.   I also found it to be alittle querky.  A common option is to implement a CDC class device.  The disadvantage of CDC is that the application doesn't have a good way to find the com port of the device and it creates alittle more work for the framework code.  My understanding is that most apps that use CDC require the user to configure the port, do port banging to see if anything interesting happens, or search the registry in an unsupported way. 
 
    Vista includes a generic USB driver called WinUSB which is very similar to MCHPUSB.sys.  It's installed out of the box in Vista, and a redistributable package for XP is included in the Vista WDK.  WinUSB allows each device to specify a device GUID in the INF so that all of your devices of a given type can be easily found from the SetupAPIs.  MCHPUSB.sys has a hardcoded GUID for all devices so to use MCHPUSB.sys you need to restrict the search farther perhaps by quering the VID/PID from the device descriptor.
 
    The Vista WDK is available at:(I had alot of trouble finding it myself)
    http://connect.microsoft.com
 
    To actually get the WDK you need to:
    1. Create a Windows Live account
    2. sign in using the Live account
    3. Click "Available Connections"
    4. Do a find for "WDK".  You won't see this if you arn't signed in.
    5. Signup for the WDK connection.
    6. Goto downloads in the connection and select "Windows Driver Kit RTM (Vista)"
    7. The download is a raw DVD ISO file so you either need to burn a DVD or use Daemon tools to mount the image to a virtual drive.
 
    WinUSB is documented in the following sections.
    Windows Driver Kit\Device and Driver Technologies\Buses and Ports\Buses\USB\
        Design Guide\System-Supplied USB Drivers\WinUSB (The general architure documentation )
        Reference\WinUSB User-Mode Client Support Routines ( The user mode application interface )
 
    The inc section of the DDK contains the only required inc winusb.h.  I simply added the inc directories to the search path in the DDK and the one include was compatible with SDK headers.   You also need to link to winusb.lib.
 
    Windows or the redist does not include device INFs.  You need to make one yourself.  The INF is tricky because it needs to install WinUSB and the documentation that actually is available for doing this is very poor and scattered.  I found a template INF on the web that only needed minimal modifications for the PID/VID and strings.
 
    http://www.osronline.com/showthread.cfm?link=109991
 
    You need to copy the redist files from the WDK in the redist\wdf and redist\winusb directories to the amd64 and x86 directories where the INF file will be found.(Driver install disk for example)
 
    The API is very straightforward.  One usefull feature WinUSB has is the ability to set endpoint timeouts with the WinUsb_SetPipePolicy API.  This removed several complications in my own code. With the Microchip driver I had to use asynchronous IO to manually implement timeouts.
 
    One area that I would like help in is getting asynchronous IO to work with WinUSB.  When doing async the read and write function don't fill in the return value for bytes transmitted.  In normal Win32 you can use the GetOverlappedResult api to get this, but it requires a file or device handle so I'm not exactly sure which handle to pass in.  With WinUSB you start with a device handle and use it to open a WinUSB handle through WinUsb_Initialize.
 
 
 
 
#1

65 Replies Related Threads

    mzoran
    Super Member
    • Total Posts : 683
    • Reward points : 0
    • Status: offline
    RE: Using WinUSB 2007/06/25 01:46:47 (permalink)
    0
    Forgot to mention I've converted several homebrew devices and application to WinUSB from the Microchip driver and it was a very straightforward conversion.  It only took a few hours.
     
    Also wanted to mention that I've tested WinUSB on XP and it works great.
    #2
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Using WinUSB 2007/06/25 01:51:14 (permalink)
    0
    Hi, this sounds great Smile

    I'll try to take a look ASAP. Thank you.

    GENOVA :D :D ! GODO
    #3
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Using WinUSB 2007/06/26 15:30:29 (permalink)
    0
    ORIGINAL: mzoran

    Forgot to mention I've converted several homebrew devices and application to WinUSB from the Microchip driver and it was a very straightforward conversion.  It only took a few hours.

    Also wanted to mention that I've tested WinUSB on XP and it works great.

     
    Good to hear that. Somehow the samples for WinUSB is scarce in the web.
     
    Before WinUSB, there is the libusb-win32. The latest version of libusb-win32 will have three backend (the original libusb-win32, HID and WinUSB). It is not finished though. The partially finished code is here:
     
    http://libusb-win32.svn.sourceforge.net/viewvc/libusb-win32/trunk/libusb1/
     
     
    #4
    mzoran
    Super Member
    • Total Posts : 683
    • Reward points : 0
    • Status: offline
    RE: Using WinUSB 2007/06/28 12:31:36 (permalink)
    0
    I can give alittle information on WinUSB, but the document on the API in the WDK is very clear.  The INF is the problem which has very very poor documentation.  I had to find an example for that on the web.
     
    http://www.osronline.com/showthread.cfm?link=109991
     
    The client API looks like this:
     
    1.  You find your device through SetupAPI and create a handle to the device with CreateFile.  You need to use the FILE_FLAG_OVERLAPPED option for the library to work.  This step is essentually idential to what you do with the Microchip driver.
     
    2.  Call WinUsb_Initialize and pass in the device handle.  The API returns a WinUSB opaque handle.
     
    3.  You call either WinUsb_ReadPipe or WinUsb_WritePipe to read and write from the endpoints of the device. Here is the prototype of WinUsb_ReadPipe and WinUsb_WritePipe
     
    BOOL __stdcall
      WinUsb_ReadPipe (
        IN WINUSB_INTERFACE_HANDLE  InterfaceHandle,
        IN UCHAR  PipeID,
        IN PUCHAR  Buffer,
        IN ULONG  BufferLength,
        OUT PULONG  LengthTransferred,
        IN LPOVERLAPPED  Overlapped
      );
     
    BOOL __stdcall
      WinUsb_WritePipe (
        IN WINUSB_INTERFACE_HANDLE  InterfaceHandle,
        IN UCHAR  PipeID,
        IN PUCHAR  Buffer,
        IN ULONG  BufferLength,
        OUT PULONG  LengthTransferred,
        IN LPOVERLAPPED  Overlapped
      );
     
    They are essentually a drop in replacement for the ReadFile/WriteFile calls on the endpoint handles in the Microchip driver.  The PipeId is the endpoint ID and are same numbers that are used in the endpoint descriptor.   Noitce that WinUSB only uses a handle to the device and you pass in the endpoint ID on each call.  This is different from the Microchip driver where you open a handle for each endpoint.
     
    4.  If needed, you can call SetPipePolicy to set timeouts and buffering policy of the endpoint.  Buffering options are essentually raw mode where each read and write is mapped directly to a single endpoint operation or buffered mode where it's possible to do things like read 256 bytes from a 64 byte endpoint or read 16 bytes when the device sends 64 and the driver will use multiple operations and buffering of partial data as appropriate.
     
    5. When done, the application calls WinUsb_Free to close the WinUSB handle and then CloseFile to close the device handle.
     
    As I said, for me the conversion process was a few hours.  Most of the time was retesting the device.  
     
    Now that WinUSB is freely available and is such a direct replace for the Microchip driver, it wouldn't surprise me if Microchip simply pulled support for their driver.  I suspect the Microchip driver was mostly meant to be a demo and prototyping tool rather then something that was ment for large scale production.
     
    #5
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Using WinUSB 2007/06/28 13:40:28 (permalink)
    0
    ORIGINAL: mzoran

    Now that WinUSB is freely available and is such a direct replace for the Microchip driver, it wouldn't surprise me if Microchip simply pulled support for their driver.  I suspect the Microchip driver was mostly meant to be a demo and prototyping tool rather then something that was ment for large scale production.


     
    I could be wrong here. 
     
    I think WinUSB does not support ISOC transfer. I believe that Microchip's driver does. And WinUSB is not supported under Windows 2000 and not officially supported under XP (should work).
     
    Therefore I think Microchip driver should still be supported. I think it is writen by the famous driver developer Walter Oney (just look at the version property of the driver).
    #6
    mayur05_damania
    Junior Member
    • Total Posts : 96
    • Reward points : 0
    • Joined: 2007/07/19 02:50:33
    • Location: 0
    • Status: offline
    Using WinUSB 2007/07/27 06:32:38 (permalink)
    0
    hi there,
     
        i am new to WinUSB. I am trying to download the file you mentioned for WinUSB. I am using VISTA and PICUSBFS demo board for usb communication. Can you tell me how this WinUSB.dll file communicates with microcontroller. And how do I access microcontroller in VB using winusb.dll file.
     
    help please
    #7
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 00:17:42 (permalink)
    0
    ORIGINAL: mzoran

    I can give alittle information on WinUSB, but the document on the API in the WDK is very clear.  The INF is the problem which has very very poor documentation.  I had to find an example for that on the web.

    http://www.osronline.com/showthread.cfm?link=109991

    The client API looks like this:

    1.  You find your device through SetupAPI and create a handle to the device with CreateFile.  You need to use the FILE_FLAG_OVERLAPPED option for the library to work.  This step is essentually idential to what you do with the Microchip driver.

    2.  Call WinUsb_Initialize and pass in the device handle.  The API returns a WinUSB opaque handle.

    3.  You call either WinUsb_ReadPipe or WinUsb_WritePipe to read and write from the endpoints of the device. Here is the prototype of WinUsb_ReadPipe and WinUsb_WritePipe

    BOOL __stdcall
     WinUsb_ReadPipe (
       IN WINUSB_INTERFACE_HANDLE  InterfaceHandle,
       IN UCHAR  PipeID,
       IN PUCHAR  Buffer,
       IN ULONG  BufferLength,
       OUT PULONG  LengthTransferred,
       IN LPOVERLAPPED  Overlapped
     );

    BOOL __stdcall
     WinUsb_WritePipe (
       IN WINUSB_INTERFACE_HANDLE  InterfaceHandle,
       IN UCHAR  PipeID,
       IN PUCHAR  Buffer,
       IN ULONG  BufferLength,
       OUT PULONG  LengthTransferred,
       IN LPOVERLAPPED  Overlapped
     );

    They are essentually a drop in replacement for the ReadFile/WriteFile calls on the endpoint handles in the Microchip driver.  The PipeId is the endpoint ID and are same numbers that are used in the endpoint descriptor.   Noitce that WinUSB only uses a handle to the device and you pass in the endpoint ID on each call.  This is different from the Microchip driver where you open a handle for each endpoint.

    4.  If needed, you can call SetPipePolicy to set timeouts and buffering policy of the endpoint.  Buffering options are essentually raw mode where each read and write is mapped directly to a single endpoint operation or buffered mode where it's possible to do things like read 256 bytes from a 64 byte endpoint or read 16 bytes when the device sends 64 and the driver will use multiple operations and buffering of partial data as appropriate.

    5. When done, the application calls WinUsb_Free to close the WinUSB handle and then CloseFile to close the device handle.

    As I said, for me the conversion process was a few hours.  Most of the time was retesting the device.  

    Now that WinUSB is freely available and is such a direct replace for the Microchip driver, it wouldn't surprise me if Microchip simply pulled support for their driver.  I suspect the Microchip driver was mostly meant to be a demo and prototyping tool rather then something that was ment for large scale production.



    You say the API is very clear... Where can I find this? I am trying to get it working in C#, and all my googling has only lead me to this post. lol. I have the full WinDDK iso from Microsoft, and I have successfully created my inf file. I just need to figure out how to interface with winusb through C#. Am I correct that I cannot use THIS because I am using C# so no header files?

    Any help would be greatly appreciated. Thankyou.
    #8
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Using WinUSB 2007/08/13 01:54:21 (permalink)
    0
    The API is really very clear.
    WinUSB User-Mode Client Support Routines:
    http://msdn2.microsoft.com/en-us/library/aa476437.aspx
     
    If you are using VB.Net or C#, then you need to write a wrapper for the user mode dll (winusb.dll). I think this will be relatively easy if you are proficent in VB.Net or Visual C# programming. I think it should be similar to what you have done with the Microchip provided driver/dll.
     
    Unfortunately I do not know much about Windows programming in general so that I can not help you more.
     
    #9
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 12:57:24 (permalink)
    0
    ORIGINAL: xiaofan

    The API is really very clear.
    WinUSB User-Mode Client Support Routines:
    http://msdn2.microsoft.com/en-us/library/aa476437.aspx

    If you are using VB.Net or C#, then you need to write a wrapper for the user mode dll (winusb.dll). I think this will be relatively easy if you are proficent in VB.Net or Visual C# programming. I think it should be similar to what you have done with the Microchip provided driver/dll.

    Unfortunately I do not know much about Windows programming in general so that I can not help you more.



    Well I am not good with those msdn articles. They never make sense to me. I would really prefer to see examples, and their examples are no where close to c#.

    I know what I need to do, but I cannot figure out how to find the device handle given a specific GUID. Everyone says to use SetupAPI or to use SetupDiGetClassDevs to pass in the GUID to look for and it returns the handle I need. However, there is no such mention of either of those in the link, and none of those functions take in a GUID or any that I can see... It is just the basic getting the handle that seems to be the problem. Once you have the handle, it seems to be relatively straightforward, but I cant seem to find the missing key. Examples in C# would be the best, but any help anyone can provide would be awesome.
    #10
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 16:19:22 (permalink)
    0
    Ok, this is pretty difficult for me.

    Anyways, I was able to call "SetupDiGetClassDevs" and it does return a handle when I pass it my GUID.

    I think the article is fine in theory from that point on, but I am unable to get anywhere...

    I then tried to do the "SetupDiEnumDeviceInterfaces" and go through starting at 0, but right away without even trying once, it returned false. So I used the Last Win32 Error thing, and found that it was error 259 and "No other data available" was the description, so some googling and I find that means that there is no more data. So obviously it is looking right over my device. Yes it is plugged in and powered... What is the best way to debug this sort of thing? Can anyone with some windows side programming chime in on what my problem may be?
    #11
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Using WinUSB 2007/08/13 16:20:51 (permalink)
    0
    I know that example is the best, especially to someone like me who know only a little about Windows programming but is able to do minor modifications to the existing codes. Unfortunately WinUSB is so new and it is only for Vista (XP as well but with some tweaks) so there are no C# or VB.Net examples right now. In fact, I have searched them to no avail. The answer from the Microsoft guy is that it is just another DLL and write your own wrapper...
     
    Anyway, you can refer to the HID.dll wrapper in the excellent USB Central HID page. It is not the same but the step should be very similar. You can buy her book as well. C# and VB.net examples are provided.
    http://www.lvr.com/hidpage.htm
    #12
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Using WinUSB 2007/08/13 16:27:44 (permalink)
    0
    Ok the latest Google for (WinUSB C# Example) comes out the following.
    http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-interop/8132/WinUsb-WinUsb-ControlTransfer
     
    At least the author is able to get the SetUpAPI part working.
    #13
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: Using WinUSB 2007/08/13 16:32:57 (permalink)
    0
    Ah you did make some progress. For others to help, you can post the code and I am sure there are some Windows programming experts out here.
     
     
    #14
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 17:44:09 (permalink)
    0
    Ok, well I got another step further... I FOUND MY DEVICE! :)

    Now I am going to read on the next steps, but I was able to iterate through until one with my specific vid/pid was found.

    The thing is... I dont get why it worked. I changed the GUID from the one in my driver, to a generic Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED") and it iterated through and found it. Now I assume that this GUID is for the USB hub, so everything attached to it, will show up. How come I could not use the GUID in my driver file that was generated by that microsoft unique guid program? It shows up as an installed device in the device manager, and I can look through the driver details and find where it has the GUID and it is the one in the driver obviously, not this generic one... So is there a way to make it iterate through not all of them on the hub, but just those under my custom class with a completely different GUID? I thought it would work if I entered my GUID inplace of the generic one, but again, it never iterates as if there are no devices with that connected. Is there something blatently obvious that I am missing?

    And thankyou very much for the help so far! It has been key to me getting this far. :)

    EDIT: I should add that I am grateful that it works. I however like to know why something works or how something works rather than just accepting that it does... So if you know why this GUID worked over my own, then please I would like to know. Thanks.
    post edited by NVergunst - 2007/08/13 17:49:10
    #15
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 20:58:12 (permalink)
    0
    Ok, I think I am at the point where I can start to use the Write/Read Pipe. However, I cannot find any C# code examples that wrap them.

    The one that I made keeps erroring out with a memory exception problem. Anyone have a wrapper for it? Also perhaps a more detailed explanation of what the PipeID is...

    Thanks
    #16
    mzoran
    Super Member
    • Total Posts : 683
    • Reward points : 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 22:17:05 (permalink)
    0
    Here is some of my code for opening the device.  It is an except from a library I wrote for myself so it isn't stand alone but it should be enough to get the idea.  The GUID GUID_DEVINTERFACE_WINUSB is a GUID you made up yourself with guidgen and you use in the INF for creating the DeviceInterfaceGUIDs value in the registry.  The PipeID for ReadPipe/WritePipe is simply the USB endpoint ID.
     
    I don't know that much about VB and C# but I've heard a very easy way to write write wrappers in to write a layer of glue code writting in Managed C++ and you call from C#.  The managed C++ wrappers can take .NET types and convert things into something closer to what you pass back and forth between the USB device.
     

     
    UsbDrvCliDevice *
    UsbDrvCliPrivate::OpenDevice(
       unsigned short VID,
       unsigned short PID,
       WCHAR * Serial )
    {
       SP_DEVICE_INTERFACE_DATA   devInfoData;
       bool        LastDevice = FALSE;
       int         MemberIndex = 0;
       LONG        Result; 
       GUID ClassGuid = GUID_DEVINTERFACE_WINUSB;
       HDEVINFO hDevInfo = NULL;
       BOOL FoundDevice = FALSE;
       DWORD Length = 0;
       DWORD Required = 0;
       PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
     
       UsbDrvCliDevicePrivate * Device = NULL;
       hDevInfo=SetupDiGetClassDevs 
           (&ClassGuid,
            NULL,
            NULL,
            DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
      
      if (!hDevInfo)
      {
         UsbDrvCliPrivate::DoErrorCallback( ErrorCallback, L"Unable to initialize setupapi\n");
         return NULL;
      }
      
      devInfoData.cbSize = sizeof(devInfoData);
      MemberIndex = 0;
      LastDevice = FALSE;
     
      while(1)
      {
         Result=SetupDiEnumDeviceInterfaces
            (hDevInfo, 
            0, 
            &ClassGuid,
            MemberIndex,
            &devInfoData);
      
         if (!Result)
         {
             UsbDrvCliPrivate::DoErrorCallback( ErrorCallback, L"Unable to find device");
             SetupDiDestroyDeviceInfoList(hDevInfo);
             return NULL;
         }
       Result = SetupDiGetDeviceInterfaceDetail
          (hDevInfo,
          &devInfoData,
          NULL,
          0,
          &Length,
          NULL);
      
       detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)alloca(Length);
       detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
       Result = SetupDiGetDeviceInterfaceDetail
          (hDevInfo,
          &devInfoData,
          detailData,
          Length,
          &Required,
          NULL);
      
       if (!Result)
       {
          UsbDrvCliPrivate::DoErrorCallback( ErrorCallback, L"SetupDiGetDeviceInterfaceDetail failed, error %u\n" ,GetLastError() );
          MemberIndex = MemberIndex + 1;
          continue;
       }
       
       Device = new UsbDrvCliDevicePrivate( detailData->DevicePath );
       if (!Device)
       {
          MemberIndex = MemberIndex + 1;
          continue;
      }
      
      if ( !Device->OpenDevice() )
      {
         delete Device;
         Device = NULL;
         MemberIndex = MemberIndex + 1;
         continue;
      }
      
      if ( Device->VID != VID ||
           Device->PID != PID )
      {
         delete Device;
         Device = NULL;
         MemberIndex = MemberIndex + 1;
         continue;
      }
      
       if ( Serial )
       {
         if ( wcscmp( Device->Serial, Serial ) != 0 )
         {
            delete Device;
            Device = NULL;
            MemberIndex = MemberIndex + 1;
            continue;
         }
       }
      
       SetupDiDestroyDeviceInfoList(hDevInfo);
       return Device;
       }
    }
     
    bool
    UsbDrvCliDevicePrivate::OpenDevice(void)
    {
       DeviceHandle=CreateFile(
          DevicePath,
          GENERIC_READ|GENERIC_WRITE,
          0,
          (LPSECURITY_ATTRIBUTES)NULL,
          OPEN_EXISTING,
          FILE_FLAG_OVERLAPPED,
          NULL);
     
       if ( DeviceHandle == INVALID_HANDLE_VALUE )
       {
          DWORD Error = GetLastError();
             return false;
       }
     
       if (!WinUsb_Initialize( DeviceHandle, &WinUsbDeviceHandle) )
       {
           return false;
       }
        Sleep(50);
     
       USB_DEV_DSC DeviceInfo;
       DWORD dwBytesReturned = 0;
     
       BOOL Result = 
          WinUsb_GetDescriptor (
          WinUsbDeviceHandle,
          USB_DEVICE_DESCRIPTOR_TYPE,
          0,
          0x0409,
          (PUCHAR)&DeviceInfo,
          sizeof(DeviceInfo),
          &dwBytesReturned );
     
       if (!Result)
         return false;
     
       VID = DeviceInfo.idVendor;
       PID = DeviceInfo.idProduct;
       Sleep(50);
     
       static unsigned char ManufactureName[1024];
       unsigned char ManufactureNameLength;
       USB_STR_DSC * ManufactureNameStringDsc = (USB_STR_DSC*)ManufactureName;
     
       Result = 
          WinUsb_GetDescriptor (
             WinUsbDeviceHandle,
             USB_STRING_DESCRIPTOR_TYPE,
             DeviceInfo.iMFR,
             0x0409,
             ManufactureName,
             sizeof(ManufactureName),
            &dwBytesReturned );
     
       if (!Result)
          return false;
       Sleep(50);
     
       ManufactureNameLength = ( ManufactureNameStringDsc->bLength - 2 ) / 2;
       memcpy( Manufacture, ManufactureNameStringDsc->string, sizeof(WCHAR) * ManufactureNameLength );
       Manufacture[ ManufactureNameLength ] = 0;
       static unsigned char ProductName[1024];
       unsigned char ProductNameLength;
       USB_STR_DSC * ProductNameStringDsc = (USB_STR_DSC*)ProductName;
     
       Result = 
          WinUsb_GetDescriptor (
              WinUsbDeviceHandle,
              USB_STRING_DESCRIPTOR_TYPE,
              DeviceInfo.iProduct,
              0x0409,
              ProductName,
              sizeof(ProductName),
              &dwBytesReturned );
     
        if (!Result)
           return false;
        Sleep(50);
        ProductNameLength = ( ProductNameStringDsc->bLength - 2 ) / 2;
        memcpy( FriendlyName, ProductNameStringDsc->string, sizeof(WCHAR) * ProductNameLength );
        FriendlyName[ ProductNameLength ] = 0;
        static unsigned char SerialNumber[1024];
        unsigned char SerialNumberLength;
        USB_STR_DSC * SerialNumberStringDsc = (USB_STR_DSC*)SerialNumber;
      
        Result =
           WinUsb_GetDescriptor (
              WinUsbDeviceHandle,
              USB_STRING_DESCRIPTOR_TYPE,
              DeviceInfo.iSerialNum,
              0x0409,
              SerialNumber,
              sizeof(SerialNumber),
              &dwBytesReturned );
     
        if (!Result)
            return false;
     
        SerialNumberLength = ( SerialNumberStringDsc->bLength - 2 ) / 2;
        memcpy( Serial, SerialNumberStringDsc->string, sizeof(WCHAR) * SerialNumberLength );
        Serial[ SerialNumberLength ] = 0;
        Sleep(50);
        return true;
    }

     


    #17
    mzoran
    Super Member
    • Total Posts : 683
    • Reward points : 0
    • Status: offline
    RE: Using WinUSB 2007/08/13 22:25:25 (permalink)
    0
    Just one more thing, the book "USB Complete" was very usefull to me in the beginning.   It not only explains the basic USB information, but it also covers topics such as tricks and tips of Device Manager, basics of a USB INF, and how to use SetupAPI to find devices.   It includes an example with sample code for creating a HID device but using HID as a generic library has some problems in my opinion.
    #18
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/14 00:22:49 (permalink)
    0
    ORIGINAL: mzoran

    Just one more thing, the book "USB Complete" was very usefull to me in the beginning.   It not only explains the basic USB information, but it also covers topics such as tricks and tips of Device Manager, basics of a USB INF, and how to use SetupAPI to find devices.   It includes an example with sample code for creating a HID device but using HID as a generic library has some problems in my opinion.


    Thankyou for the example. I am not very proficient with C++, but as far as I can tell that is just to find the handle of the USB device correct? I did not see any code that to me suggested actual writing to or reading from the device. I could just be blind. Like I said, I am not too good with C++...

    I have been able to (from what I can tell at least), find the device and get the handle. I copy/pasted some code from a HID device example I found and tweaked it a little bit. I am pretty much lost at this point.

    This is the exception I am getting along with the code snipped that is generating it.



    Also what types should I be using for the read/write pipes? Does the data field return a pointer to some memory block of the length input, or will it return an array, or what? What type should the end point be?

    This is what I am using and obviously it is incorrect as it continues to give me memory errors.


    [DllImport("winusb.dll")]
    public static extern bool WinUsb_ReadPipe(IntPtr WinUSBHandle, string PipeID, byte[] datain, uint length, uint received_length);

    [DllImport("winusb.dll")]
    public static extern bool WinUsb_WritePipe(IntPtr WinUSBHandle, string PipeID, byte[] dataout, uint length, uint sent_length);


    At this point I am willing to ask for help with compensation. I have working code that works with the generic Microchip dll. I need code that will work with winusb. I am willing to pay for some clear guidance with this issue as I am working on a bit of a time crunch.
    #19
    NVergunst
    Super Member
    • Total Posts : 390
    • Reward points : 0
    • Joined: 2007/02/11 19:58:16
    • Location: 0
    • Status: offline
    RE: Using WinUSB 2007/08/15 13:04:40 (permalink)
    0
    Well I am still having no luck with this. Is there a way to debug this sort of thing?

    Like to double check that the handle's for both the device and for the createfile file are correct? Is there a way to check if the file has been created successfully other than making sure the function returns true?

    It seems as if up to the actual read/write, the functions return true, which means that they work.

    I am pretty surprised that even microsoft doesnt have C# examples for something like this seeing as how it is their language...

    Well I have never imported C++ code into C#, but I am told it can be done. So perhaps I should look into just trying to get the header files from the developement kit to work with C#...
    #20
    Page: 1234 > Showing page 1 of 4
    Jump to:
    © 2020 APG vNext Commercial Version 4.5