The following sample code provides an unsupported example of how to use the APIs exported by Winusb.sys to communicate with Windows Mobile devices over a USB connection:
#include <winusb.h>
typedef struct WINUSB_DEVICE_CONTEXT
{
BSTR bszPath;
WINUSB_INTERFACE_HANDLE Dev;
UCHAR BulkOutPipe;
ULONG BulkOutMaxPacket;
UCHAR BulkInPipe;
ULONG BulkInMaxPacket;
} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
void ReadData(HANDLE hDriver, DEVICE_CONTEXT winusbContext, OVERLAPPED readOverlapped);
void WriteData(HANDLE hDriver, DEVICE_CONTEXT winusbContext, OVERLAPPED writeOverlapped);
TCHAR * GetDevicePnpPath();
void ReadWriteWinusb()
{
HANDLE hDriver = INVALID_HANDLE_VALUE;
OVERLAPPED readOverlapped = {0};
OVERLAPPED writeOverlapped = {0};
DEVICE_CONTEXT winusbContext = {0};
WINUSB_PIPE_INFORMATION pipe = {UsbdPipeTypeControl};
WINUSB_INTERFACE_HANDLE hInt = NULL;
USB_INTERFACE_DESCRIPTOR usbDescriptor = {0};
DWORD iEndpoint = 0;
hDriver = CreateFile(GetDevicePnpPath, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
if (hDriver == INVALID_HANDLE_VALUE)
goto Error;
//
// Open the driver with WinUSB
//
if (!WinUsb_Initialize(hDriver, &(winusbContext.Dev)))
{
goto Error;
}
//
// We should have exactly one interface
//
if (!WinUsb_QueryInterfaceSettings(winusbContext.Dev,
0,
&usbDescriptor))
{
goto Error;
}
//
// Get the read and write pipes to the device
//
for (iEndpoint = 0; iEndpoint < usbDescriptor.bNumEndpoints; iEndpoint++)
{
if (!WinUsb_QueryPipe(winusbContext.Dev,
0,
(UCHAR)iEndpoint,
&pipe))
{
goto Error;
}
if ((pipe.PipeType == UsbdPipeTypeBulk) && (USB_ENDPOINT_DIRECTION_OUT(pipe.PipeId)))
{
winusbContext.BulkOutPipe = pipe.PipeId;
winusbContext.BulkOutMaxPacket = pipe.MaximumPacketSize;
}
else if (pipe.PipeType == UsbdPipeTypeBulk)
{
winusbContext.BulkInPipe = pipe.PipeId;
winusbContext.BulkInMaxPacket = pipe.MaximumPacketSize;
}
}
//
// Create an event to block while waiting on a read overlapped I/O to complete.
//
readOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (readOverlapped.hEvent == NULL)
goto Error;
//
// Create an event to block while waiting on a write overlapped I/O to complete.
//
writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (writeOverlapped.hEvent == NULL)
goto Error;
//
// Read some data from the device
//
ReadData(hDriver, readOverlapped);
//
// Write Some data to the device
//
WriteData(hDriver, writeOverlapped);
//
// Close the device
//
Error:
if (winusbContext.Dev)
{
if (!WinUsb_Free(winusbContext.Dev))
{
DSYSERR("-WinUsb_Free failed");
}
winusbContext.Dev = NULL;
}
CloseHandle(hDriver);
//
// Release the overlapped I/O event handle.
//
if (readOverlapped.hEvent)
{
CloseHandle(readOverlapped.hEvent);
readOverlapped.hEvent = NULL;
}
if (writeOverlapped.hEvent)
{
CloseHandle(writeOverlapped.hEvent);
writeOverlapped.hEvent = NULL;
}
}
void ReadData(HANDLE hDriver, DEVICE_CONTEXT winusbContext, OVERLAPPED readOverlapped)
{
const UINT cbBuffer = 4096;
BYTE *paBuffer = NULL;
ULONG cBytes = 0;
BOOL fResult = FALSE;
if (4096 <= winusbContext.BulkInMaxPacket)
{
goto Error;
}
paBuffer = new BYTE[cbBuffer];
if (!paBuffer)
{
goto Error;
}
fResult = WinUsb_ReadPipe(winusbContext.Dev,
winusbContext.BulkInPipe,
paBuffer,
cbBuffer,
&cBytes,
&readOverlapped);
if (!fResult)
{
if (GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(readOverlapped.hEvent, INFINITE);
fResult = GetOverlappedResult(hDriver, &readOverlapped, &cBytes, FALSE);
if (!fResult)
{
goto Error;
}
}
else
{
goto Error;
}
}
Error:
//
// Example code - not going to return what we read or even errors
//
return;
}
void WriteData(HANDLE hDriver, DEVICE_CONTEXT winusbContext, OVERLAPPED writeOverlapped)
{
char data[] = "CLIENTSERVER";
BYTE * pbData;
ULONG cbWritten = 0;
ULONG cData;
ULONG cbWrite;
ULONG cbTotalWritten = 0;
BOOL fResult = FALSE;
pbData = (BYTE *)data;
cData = sizeof(data);
//
// In case the data is bigger than the max packet, write in a loop
//
while (cData)
{
if (cData > winusbContext.BulkOutMaxPacket)
{
cbWrite = winusbContext.BulkOutMaxPacket;
}
else
{
cbWrite = cData;
}
fResult = WinUsb_WritePipe(winusbContext.Dev,
winusbContext.BulkOutPipe,
pbData,
cbWrite,
&cbWritten,
&writeOverlapped);
if (!fResult)
{
if (GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(writeOverlapped.hEvent, INFINITE);
fResult = GetOverlappedResult(hDriver, &writeOverlapped, &cbWritten, FALSE);
if (!fResult)
{
goto Error;
}
}
else
{
goto Error;
}
}
//
// Update our stats.
//
cData -= cbWritten;
pbData += cbWritten;
cbTotalWritten += cbWritten;
}
Error:
//
// Example code - not going to return errors
//
return;
}
//
// DeviceInterface GUID for CE USB serial devices
//
GUID IID_CEUSBDEVICE = {0x25dbce51,0x6c8f,0x4a72,0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35};
TCHAR * GetDevicePnpPath()
{
HRESULT hr = E_FAIL;
DWORD dwError;
DWORD iInterface = 0;
HDEVINFO hdevClassInfo = NULL;
SP_INTERFACE_DEVICE_DATA InterfaceDeviceData = {0};
PSP_INTERFACE_DEVICE_DETAIL_DATA pDeviceDetailData = {0};
//initialize variables
InterfaceDeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
//
// Open the device for serial communications.
//
hdevClassInfo = SetupDiGetClassDevs(&IID_CEUSBDEVICE,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if (hdevClassInfo == INVALID_HANDLE_VALUE) {
goto Error;
}
while (SetupDiEnumDeviceInterfaces(hdevClassInfo,
NULL,
(LPGUID)&IID_CEUSBDEVICE,
iInterface,
&InterfaceDeviceData))
{
DWORD DetailSize = 0;
ULONG ulStatus = 0;
ULONG ulProblem = 0;
SP_DEVINFO_DATA DeviceInfoData = {0};
CONFIGRET cfgRet = CR_SUCCESS;
SetupDiGetDeviceInterfaceDetail(hdevClassInfo,
&InterfaceDeviceData,
NULL,
0,
&DetailSize,
NULL);
//Allocate memory for the Device Detail Data
if ((pDeviceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)
malloc(DetailSize)) == NULL)
{
goto Error;
}
// Initialize the device detail data structure
pDeviceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
// Get the Device Detail Data
// This gives us the path that we can open with CreateFile
if (SetupDiGetDeviceInterfaceDetail(hdevClassInfo,
&InterfaceDeviceData,
pDeviceDetailData,
DetailSize,
NULL,
&DeviceInfoData))
{
// !!
//
// Example code - don't return from the middle here
// This will skip the cleanup code and leak memory
//
// !!
return (pDeviceDetailData->DevicePath);
}
else
{
dwError = GetLastError();
}
iInterface++;
free(pDeviceDetailData);
pDeviceDetailData = NULL;
}
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_ITEMS)
{
goto Error;
}
Error:
if(pDeviceDetailData)
{
free(pDeviceDetailData);
}
if(hdevClassInfo)
{
SetupDiDestroyDeviceInfoList(hdevClassInfo);
}
return NULL;
} The WDK (Windows Driver Kit) is necessary for compiling this code.
Additional information about WinUSB is available in the Microsoft Windows Driver Kit (WDK) documentation, under the following topic:
WinUSB (
http://msdn.microsoft.com/en-us/library/aa476426.aspx)