Article ID: 968204 - Last Review: February 20, 2009 - Revision: 1.0 Windows CE USB Serial Host Driver (Wceusbsh.sys) Not Available On Windows VistaSource: Microsoft Support RAPID PUBLISHINGRAPID PUBLISHING ARTICLES PROVIDE INFORMATION DIRECTLY FROM WITHIN THE MICROSOFT SUPPORT ORGANIZATION. THE INFORMATION CONTAINED HEREIN IS CREATED IN RESPONSE TO EMERGING OR UNIQUE TOPICS, OR IS INTENDED SUPPLEMENT OTHER KNOWLEDGE BASE INFORMATION. SymptomApplications which depend on functionality provided by Wceusbsh.sys to communicate with Windows CE or Windows Mobile devices do not work on Windows Vista. Microsoft recommends that application developers use the APIs provided by WinUSB for communication with Windows Mobile devices from computers running Windows Vista. CauseThe Windows CE USB Serial Host Driver (Wceusbsh.sys) provides a simulated Serial interface that is used by Microsoft ActiveSync to communicate with Windows CE or Windows Mobile devices over a USB connection from a computer running Microsoft Windows XP. Wceusbsh.sys was provided for Windows XP, for use by ActiveSync to communicate with Windows CE or Windows Mobile devices. Any other use of Wceusbsh.sys (for example, by an application or service other than ActiveSync) is strictly unsupported. Windows Vista includes Windows Mobile Device Center (WMDC) to communicate with Windows CE or Windows Mobile devices. Windows Mobile Device Center uses the USB interface provided by WinUSB to communicate with Windows CE or Windows Mobile devices over a USB connection. Wceusbsh.sys is not included in Windows Vista. ResolutionMicrosoft recommends that application developers use the APIs provided by WinUSB for communication with Windows CE or Windows Mobile devices from computers running Windows Vista. The WinUSB interface is provided by WinUSB.dll and WinUSB.sys, which are components of Microsoft Windows Vista. More InformationThe 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) (http://msdn.microsoft.com/en-us/library/aa476426.aspx (http://msdn.microsoft.com/en-us/library/aa476426.aspx) ) DISCLAIMERMICROSOFT AND/OR ITS SUPPLIERS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY, RELIABILITY OR ACCURACY OF THE INFORMATION CONTAINED IN THE DOCUMENTS AND RELATED GRAPHICS PUBLISHED ON THIS WEBSITE (THE “MATERIALS”) FOR ANY PURPOSE. THE MATERIALS MAY INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS AND MAY BE REVISED AT ANY TIME WITHOUT NOTICE.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND/OR ITS SUPPLIERS DISCLAIM AND EXCLUDE ALL REPRESENTATIONS, WARRANTIES, AND CONDITIONS WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO REPRESENTATIONS, WARRANTIES, OR CONDITIONS OF TITLE, NON INFRINGEMENT, SATISFACTORY CONDITION OR QUALITY, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE MATERIALS. APPLIES TO
|
|
Back to the top
