?? usbclient.c
字號:
//
// The transfer reqest timed out.
// Get transfer status & number of bytes transferred
//
DEBUGMSG( ZONE_USBCLIENT, (TEXT("GetStatus:WAIT_TIMEOUT on bIndex:0x%x\n"), bIndex ));
GetTransferStatus(pUsbFuncs, hTransfer, &dwBytesTransferred, &dwUsbErr);
//
// let caller know it timed out
//
dwErr = ERROR_TIMEOUT;
break;
default:
dwErr = ERROR_GEN_FAILURE;
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** Unhandled WaitReason:%d ***\n"), dwWaitReturn));
break;
}
} else {
//
// Synch call completed.
// Get transfer status & number of bytes transferred
//
// ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );
GetTransferStatus(pUsbFuncs, hTransfer, &dwBytesTransferred, &dwUsbErr);
// ASSERT( USB_NO_ERROR == dwUsbErr);
}
CloseTransferHandle(pUsbFuncs, hTransfer);
} else {
dwErr = GetLastError();
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** GetStatus on endpoint:0x%x failed with ERROR:%d ***\n"), bIndex, dwErr ));
}
if ( USB_NO_ERROR != dwUsbErr && ERROR_SUCCESS != dwErr ) {
dwErr = ERROR_GEN_FAILURE;
}
if ( ERROR_SUCCESS != dwErr ) {
SetLastError(dwErr);
}
return dwErr;
}
// returns TRUE if successful
BOOL
GetTransferStatus(
LPCUSB_FUNCS pUsbFuncs,
USB_TRANSFER hTransfer,
LPDWORD pBytesTransferred, // OPTIONAL returns number of bytes transferred
PUSB_ERROR pUsbError // returns USB error code
)
{
BOOL bRc = TRUE;
if ( pUsbFuncs->lpGetTransferStatus(hTransfer, pBytesTransferred, pUsbError) ) {
if ( USB_NO_ERROR != *pUsbError ) {
DEBUGMSG( ZONE_USBCLIENT, (TEXT("GetTransferStatus (BytesTransferred:%d, UsbError:0x%x)\n"), pBytesTransferred?*pBytesTransferred:-1, pUsbError?*pUsbError:-1 ));
}
} else {
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** GetTransferStatus ERROR:%d ***\n"), GetLastError()));
*pUsbError = USB_CANCELED_ERROR;
bRc = FALSE;
}
return bRc;
}
/* ++
IssueBulkTransfer: generic USB bulk transfer handler.
If NotifyRoutine and NotifyContext are NULL, then the call is made synchronously.
If NotifyRoutine and NotifyContext are not NULL, then the call is made asynchronously
with the following restrictions:
If dwTimeout not zero, then IssueBulkTransfer waits for either the NotifyContext,
which is must be an initialized EVENT, or the timeout duration.
If dwTimeout is zero, then IssueBulkTransfer returns immediately.
The Transfer handle is returned in the pUsbError parameter.
It is up to the caller to check transfer status, close the transfer handle, etc.
Notes:
It's up to the caller to determine if the correct number of bytes were transferred.
It's up to the caller to determine any Win32 or USB error codes.
It's up to the caller to handle any USB errors.
Return:
Number of bytes transferred by USB, Win32 error code, and either USB_ERROR or USB_TRANSFER.
-- */
DWORD
IssueBulkTransfer(
LPCUSB_FUNCS pUsbFuncs,
USB_PIPE hPipe,
LPTRANSFER_NOTIFY_ROUTINE NotifyRoutine, // Transfer completion routine.
PVOID NotifyContext, // Single argument passed to the completion routine
DWORD Flags, // USB_XXX flags describing the transfer
LPVOID pBuffer, // Pointer to transfer buffer
ULONG PhysAddr, // Specifies the physical address, which may be NULL, of the data buffer
DWORD BufferLength, // Length of transfer buffer in bytes
LPDWORD pBytesTransferred, // Returns number of bytes transferred by USB
DWORD dwTimeout, // Timeout in msec
PUSB_ERROR pUsbRc // Returns USB_ERROR or USB_TRANSFER
)
{
USB_TRANSFER hTransfer = NULL;
DWORD dwWaitReturn = 0;
BOOL bRc = FALSE;
DWORD dwErr = ERROR_SUCCESS;
if ( pUsbFuncs && hPipe && pBytesTransferred && pUsbRc ) {
*pBytesTransferred = 0;
*pUsbRc = USB_NO_ERROR;
if (NotifyContext && NotifyRoutine && dwTimeout) {
_ResetEvent(NotifyContext); // NotifyContext *must* be an EVENT
}
hTransfer = pUsbFuncs->lpIssueBulkTransfer( hPipe,
NotifyRoutine,
NotifyContext,
Flags,
BufferLength,
pBuffer,
PhysAddr );
if ( hTransfer ) {
//
// Asynch call succeeded.
// Get transfer status & number of bytes transferred
//
if (NotifyContext && NotifyRoutine) {
if (!dwTimeout) {
*pUsbRc = (USB_ERROR)hTransfer;
return dwErr;
}
//
// sync the transfer completion / timer
//
dwWaitReturn = WaitForSingleObject( NotifyContext,
dwTimeout );
switch (dwWaitReturn) {
case WAIT_OBJECT_0:
//
// The completion event was signalled by the callback.
// Get transfer status & number of bytes transferred
//
// ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );
GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
break;
case WAIT_TIMEOUT:
//
// The transfer reqest timed out.
// Get transfer status & number of bytes transferred
//
DEBUGMSG( ZONE_USBCLIENT, (TEXT("%s:WAIT_TIMEOUT on hT:0x%x\n"), (Flags & USB_IN_TRANSFER) ? TEXT("IN") : TEXT("OUT"), hTransfer ));
GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
//
// let caller know it timed out
//
dwErr = ERROR_TIMEOUT;
break;
default:
dwErr = ERROR_GEN_FAILURE;
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** Unhandled WaitReason:%d ***\n"), dwWaitReturn, hTransfer ));
break;
}
} else {
//
// Synch call completed.
// Get transfer status & number of bytes transferred
//
// ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );
GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
}
CloseTransferHandle(pUsbFuncs, hTransfer);
} else {
dwErr = GetLastError();
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** IssueBulkTransfer ERROR(3, %d) ***\n"), dwErr ));
}
} else {
dwErr = ERROR_INVALID_PARAMETER;
}
if ( pUsbRc && USB_NO_ERROR != *pUsbRc && ERROR_SUCCESS == dwErr) {
dwErr = ERROR_GEN_FAILURE;
}
if ( ERROR_SUCCESS != dwErr ) {
SetLastError(dwErr);
DEBUGMSG( ZONE_USBCLIENT, (TEXT("IssueBulkTransfer ERROR(5, BytesTransferred:%d, Win32Err:%d, UsbError:0x%x)\n"), pBytesTransferred?*pBytesTransferred:-1, dwErr, pUsbRc?*pUsbRc:-1 ));
}
return dwErr;
}
/* ++
IssueInterruptTransfer: generic USB interrupt transfer handler.
If NotifyRoutine and NotifyContext are NULL, then the call is made synchronously.
If NotifyRoutine and NotifyContext are not NULL, then the call is made asynchronously
with the following restrictions:
If dwTimeout not zero, then IssueBulkTransfer waits for either the NotifyContext,
which is must be an initialized EVENT, or the timeout duration.
If dwTimeout is zero, then IssueBulkTransfer returns immediately.
The Transfer handle is returned in the pUsbError parameter.
It is up to the caller to check transfer status, close the transfer handle, etc.
Notes:
It's up to the caller to determine if the correct number of bytes were transferred.
It's up to the caller to determine any Win32 or USB error codes.
It's up to the caller to handle any USB errors.
Return:
Number of bytes transferred by USB, Win32 error code, and either USB_ERROR or USB_TRANSFER.
-- */
DWORD
IssueInterruptTransfer(
LPCUSB_FUNCS pUsbFuncs,
USB_PIPE hPipe,
LPTRANSFER_NOTIFY_ROUTINE NotifyRoutine, // Transfer completion routine.
PVOID NotifyContext, // Single argument passed to the completion routine
DWORD Flags, // USB_XXX flags describing the transfer
LPVOID pBuffer, // Ppointer to transfer buffer
ULONG PhysAddr, // Specifies the physical address, which may be NULL, of the data buffer
DWORD BufferLength, // Length of transfer buffer in bytes
LPDWORD pBytesTransferred, // Number of bytes transferred by USB
DWORD dwTimeout, // Timeout in msec
PUSB_ERROR pUsbRc // Returns USB_ERROR or USB_TRANSFER
)
{
USB_TRANSFER hTransfer = NULL;
DWORD dwWaitReturn = 0;
BOOL bRc = FALSE;
DWORD dwErr = ERROR_SUCCESS;
if ( pUsbFuncs && hPipe && pBytesTransferred && pUsbRc ) {
*pBytesTransferred = 0;
*pUsbRc = USB_NO_ERROR;
if (NotifyContext && NotifyRoutine && dwTimeout) {
_ResetEvent(NotifyContext); // NotifyContext *must* be an EVENT
}
hTransfer = pUsbFuncs->lpIssueInterruptTransfer( hPipe,
NotifyRoutine,
NotifyContext,
Flags,
BufferLength,
pBuffer,
PhysAddr );
if ( hTransfer ) {
//
// Asynch call succeeded.
// Get transfer status & number of bytes transferred
//
if (NotifyContext && NotifyRoutine) {
if (!dwTimeout) {
*pUsbRc = (USB_ERROR)hTransfer;
return dwErr;
}
//
// sync the transfer completion / timer
//
dwWaitReturn = WaitForSingleObject( NotifyContext,
dwTimeout );
switch (dwWaitReturn) {
case WAIT_OBJECT_0:
//
// The completion event was signalled by the callback.
// Get transfer status & number of bytes transferred
//
// ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );
GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
break;
case WAIT_TIMEOUT:
//
// The transfer reqest timed out.
// Get transfer status & number of bytes transferred
//
DEBUGMSG( ZONE_USBCLIENT, (TEXT("%s:WAIT_TIMEOUT on hT:0x%x\n"), (Flags & USB_IN_TRANSFER) ? TEXT("IN") : TEXT("OUT"), hTransfer ));
GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
//
// let caller know it timed out
//
dwErr = ERROR_TIMEOUT;
break;
default:
dwErr = ERROR_GEN_FAILURE;
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** Unhandled WaitReason:%d ***\n"), dwWaitReturn, hTransfer ));
break;
}
} else {
//
// Synch call completed.
// Get transfer status & number of bytes transferred
//
// ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );
GetTransferStatus(pUsbFuncs, hTransfer, pBytesTransferred, pUsbRc);
}
CloseTransferHandle(pUsbFuncs, hTransfer);
} else {
dwErr = ERROR_GEN_FAILURE;
DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** IssueInterruptTransfer ERROR(3, %d) ***\n"), dwErr ));
}
} else {
dwErr = ERROR_INVALID_PARAMETER;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -