⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbclient.c

📁 Xcale270Bsp包,wince平台
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: 

    usbclient.c

Abstract:

    Common USB Client Driver Interface

Issues:
    
    No isoch support yet

--*/

#include "usbclient.h"

#if 0
#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("USBCLIENT"), {
    TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),   TEXT("Undefined")  
    TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),   TEXT("Undefined")  
    TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),   TEXT("Undefined")  
    TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),   TEXT("Undefined")  
    },
     0x0003 // ZONE_WRN|ZONE_ERR
};
#endif  // DEBUG

BOOL 
DllEntry(
   HANDLE hDllHandle, 
   DWORD  dwReason,
   LPVOID lpreserved
   ) 
{
    UNREFERENCED_PARAMETER(lpreserved);
    switch (dwReason) {

      case DLL_PROCESS_ATTACH:
           DEBUGREGISTER((HINSTANCE)hDllHandle);
           break;

      case DLL_PROCESS_DETACH:
           break;

      default:
        break;
    }
    return TRUE;
}
#endif 0

__inline
DWORD
_ResetEvent(
    HANDLE hEvent
    )
{
   DWORD dwErr = ERROR_SUCCESS;

    if ( !ResetEvent(hEvent) ) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_USBCLIENT, (TEXT("*** ResetEvent ERROR:%d ***\n"), dwErr));
        // ASSERT(0);
        return dwErr;
    }

    return TRUE;
}


BOOL
AbortTransfer(
    LPCUSB_FUNCS   pUsbFuncs,
    USB_TRANSFER   hTransfer,
    DWORD          dwFlags
    )
{
    BOOL bRc = TRUE;

    // AbortTransfer checks if the transfer has already completed
    if ( !pUsbFuncs->lpAbortTransfer(hTransfer, dwFlags) ) {
        DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** AbortTransfer ERROR:%d ***\n"), GetLastError())); 
        bRc = FALSE;
    }

    return bRc;
}


BOOL
CloseTransferHandle(
    LPCUSB_FUNCS   pUsbFuncs,
    USB_TRANSFER   hTransfer
    )
{
    BOOL bRc = TRUE;

    // This assert may fail on suprise remove,
    // but should pass during normal I/O.
    // ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) ); 

    // CloseTransfer aborts any pending transfers
    if ( !pUsbFuncs->lpCloseTransfer(hTransfer) ) {
        DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** CloseTransfer ERROR:%d ***\n"), GetLastError())); 
        bRc = FALSE;
    }

    return bRc;
}


//
// Returns: 
//  Win32 error
//    
// Note: 
//    a synchronous ClearOrSetFeature call can take quite some time.
//
DWORD
ClearOrSetFeature(
    LPCUSB_FUNCS              pUsbFuncs,
    HANDLE                    hUsbDevice,
    LPTRANSFER_NOTIFY_ROUTINE NotifyRoutine,     // CallbackRoutine: signals a completion event.
    PVOID                     NotifyContext,     // CallbackContext: handle to a BulkXxx Completion Event
    DWORD                     dwFlags,           // see ClearOrSetFeature doc
    WORD                      wFeature,          // one of USB_FEATURE_*
    UCHAR                     bIndex,
    DWORD                     dwTimeout,         // Timeout in msec
    BOOL                      bSet               // TRUE to Set, FALSE to Clear
    )
{
    DWORD dwErr    = ERROR_SUCCESS;
    DWORD dwUsbErr = USB_NO_ERROR;
    DWORD dwWaitReturn;
    
    USB_TRANSFER hTransfer;

    if (NotifyContext && NotifyRoutine && dwTimeout) {

        _ResetEvent(NotifyContext); // NotifyContext *must* be an EVENT
    
    }
  
    //
    // reset endpoint on device
    //
    if (bSet)
        hTransfer = pUsbFuncs->lpSetFeature( hUsbDevice,
                                             NotifyRoutine,                  
                                             NotifyContext,
                                             dwFlags,
                                             wFeature,
                                             bIndex );
    else 
        hTransfer = pUsbFuncs->lpClearFeature( hUsbDevice,
                                               NotifyRoutine,                  
                                               NotifyContext,
                                               dwFlags,
                                               wFeature,
                                               bIndex );

    if ( hTransfer ) {
            //
            // Asynch call completed.
            // Get transfer status & number of bytes transferred
            //
            if (NotifyContext && NotifyRoutine) {

                if (!dwTimeout) {
                    return (DWORD)hTransfer;
                }

                //
                // sync the transfer completion / timer
                //
                dwWaitReturn = WaitForSingleObject( NotifyContext,
                                                    dwTimeout );

                switch (dwWaitReturn) {

                   case WAIT_OBJECT_0:
                      //
                      // The completion event was signalled by the callback.
                      // determine if it was actually cleared on the device
                      //
                      // ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );

                      GetTransferStatus(pUsbFuncs, hTransfer, NULL, &dwUsbErr);
                        
                      if ( USB_NO_ERROR != dwUsbErr)
                          dwErr = ERROR_GEN_FAILURE;
                      break;

                    case WAIT_TIMEOUT:
                      //
                      // The transfer reqest timed out.
                      //
                      DEBUGMSG( ZONE_USBCLIENT, (TEXT("ClearOrSetFeature:WAIT_TIMEOUT on bIndex:0x%x\n"), bIndex ));

                      GetTransferStatus(pUsbFuncs, hTransfer, NULL, &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.
                // determine if it was actually cleared on the device
                //
                // ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) );

                GetTransferStatus(pUsbFuncs, hTransfer, NULL, &dwUsbErr);

                if ( USB_NO_ERROR != dwUsbErr)
                    dwErr = ERROR_GEN_FAILURE;
            }
        
            CloseTransferHandle(pUsbFuncs, hTransfer);

    } else {
        dwErr = GetLastError();
        DEBUGMSG( ZONE_USBCLIENT, (TEXT("*** ClearOrSetFeature on endpoint:0x%x ERROR:%d ***\n"), bIndex, dwErr ));
    }

    return dwErr;
}


//
// Generic DefaultTransferComplete callback routine.
// Simply signals the hEvent passed in when USB signals a transfer is done.
// If you prematurely close/abort a transfer then this routine will still run.
//
DWORD
DefaultTransferComplete(
   PVOID    Context
   )
{
   HANDLE hEvent = (HANDLE)Context;
   DWORD  dwErr  = ERROR_SUCCESS;

   if ( hEvent ) {
      //
      // The current operation completed, signal the event
      //
       if ( !SetEvent( hEvent) ) {
          dwErr = GetLastError();
          //SetLastError(dwErr);
          DEBUGMSG(ZONE_USBCLIENT,(TEXT("*** SetEvent ERROR:%d ***\n"), dwErr));
          // ASSERT(0);
       }

   } else {
      dwErr = ERROR_INVALID_HANDLE;
      SetLastError(dwErr);
      DEBUGMSG( ZONE_USBCLIENT,(TEXT("*** DefaultTransferComplete ERROR:%d ***\n"), dwErr));
      // ASSERT(0);
   }

   return dwErr;
}


//
// returns Win32 error
//
// Note: 
//    a synchronous GetStatus call can take quite some time.
//
DWORD
GetStatus(
    LPCUSB_FUNCS              pUsbFuncs,
    HANDLE                    hUsbDevice,
    LPTRANSFER_NOTIFY_ROUTINE NotifyRoutine,     // CallbackRoutine: signals a completion event.
    PVOID                     NotifyContext,     // CallbackContext: handle to a BulkXxx Completion Event
    DWORD                     dwFlags,
    UCHAR                     bIndex,
    LPWORD                    lpwStatus,
    DWORD                     dwTimeout         // Timeout in msec
    )
{
    DWORD dwErr    = ERROR_SUCCESS;
    DWORD dwUsbErr = USB_NO_ERROR;
    DWORD dwWaitReturn;
    DWORD dwBytesTransferred;
    USB_TRANSFER hTransfer;


    if (NotifyContext && NotifyRoutine && dwTimeout) {

        _ResetEvent(NotifyContext); // NotifyContext *must* be an EVENT

    }

    hTransfer = pUsbFuncs->lpGetStatus( hUsbDevice,
                                        NotifyRoutine,
                                        NotifyContext,
                                        dwFlags,
                                        bIndex,
                                        lpwStatus );

    if ( hTransfer ) {
            //
            // Asynch call completed.
            // Get transfer status & number of bytes transferred
            //
            if (NotifyContext && NotifyRoutine) {

                if (!dwTimeout) {
                    return (DWORD)hTransfer;
                }

                //
                // 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, &dwBytesTransferred, &dwUsbErr);
                      break;

                    case WAIT_TIMEOUT:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -