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

📄 usbmsc.c

📁 cayman提供的PXA270 wince下的bsp源码包
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Load the USB Disk Driver based on the bInterfaceSubClass code.
        // The USB Disk Driver is named by convention USBDISKxx.DLL, 
        // where 'xx' is a valid bInterfaceSubClass code.
        //
        // To override the default disk driver stuff the replacement driver subkey in the registry.
        // If the named subkey does not exist then retry with SCSI as the default driver.
        //
        bInterfaceSubClass = pUsbDevice->pUsbInterface->Descriptor.bInterfaceSubClass;
        ASSERT( (bInterfaceSubClass >= USBMSC_SUBCLASS_RBC) && 
                (bInterfaceSubClass <= USBMSC_SUBCLASS_SCSI) );

_retryDefault:
        swprintf( &wsSubClassRegKey[index], TEXT("\\%d"), bInterfaceSubClass ); 
        
        RegVal[0].Name = DLL_SZ;
        RegVal[0].Type = REG_SZ;
        RegVal[0].Size = MAX_DLL_LEN;
        RegVal[0].Data = (PUCHAR)wsDriverName;

        if ( !GetSetKeyValues( wsSubClassRegKey,
                               &RegVal[0],
                               GET, 
                               FALSE ) ) {

            if (0xFF == bTempInterfaceSubClass) {
                // retry using SCSI
                DEBUGMSG( ZONE_WARN, (TEXT("Retry SubClass:0x%x with 0x%x\n"), bInterfaceSubClass, USBMSC_SUBCLASS_SCSI));
                bTempInterfaceSubClass = bInterfaceSubClass;
                bInterfaceSubClass = USBMSC_SUBCLASS_SCSI;
                goto _retryDefault;
            } else {
                DEBUGMSG( ZONE_ERR, (TEXT("GetSetKeyValues failed!\n")));
                bRc = FALSE;
                break;
            }
        }

        if (0xFF != bTempInterfaceSubClass) {
            bInterfaceSubClass = bTempInterfaceSubClass;
        }

        pUsbDevice->hDiskDriver = LoadDriver( wsDriverName );
        if ( !pUsbDevice->hDiskDriver ) {
            DEBUGMSG( ZONE_ERR, (TEXT("LoadDriver error:%d on %s\n"), GetLastError(), wsDriverName ));
            bRc = FALSE;
            break;
        }
        pUsbDevice->Index = InterlockedIncrement(&g_NumDevices);

        //
        // get DiskAttach
        //
        DiskAttach = (PUSBDISK_ATTACH)GetProcAddress( pUsbDevice->hDiskDriver, TEXT("UsbDiskAttach") );
        if ( !DiskAttach ) {
            DEBUGMSG( ZONE_ERR, (TEXT("GetProcAddress error:%d on %s\n"), GetLastError(), wsDriverName ));
            bRc = FALSE;
            break;
        }

        //
        // Save DiskDetach callback & Context to call when we get the device Notify
        //
        pUsbDevice->DiskDetach = (PUSBDISK_DETACH)GetProcAddress( pUsbDevice->hDiskDriver, TEXT("UsbDiskDetach") );
        if ( !pUsbDevice->DiskDetach ) {
            DEBUGMSG( ZONE_ERR, (TEXT("GetProcAddress error:%d on %s\n"), GetLastError(), wsDriverName ));
            bRc = FALSE;
            break;
        }

        //
        // register for USB callbacks
        //
        bRc = UsbFuncs->lpRegisterNotificationRoutine( hDevice,
                                                       UsbDeviceNotify,
                                                       pUsbDevice );
        if ( !bRc ) {
            DEBUGMSG( ZONE_ERR, (TEXT("RegisterNotificationRoutine error:%d\n"), GetLastError() ));
            break;
        }

        // signal we can take I/O
        pUsbDevice->Flags.AcceptIo = TRUE;

        //
        // Call the driver's DiskAttach.
        // DiskAttach returns non-null Context on success, else null.
        //
       __try {
            pUsbDevice->DiskContext = DiskAttach((HANDLE)pUsbDevice, 
                                                 wsSubClassRegKey, 
                                                 bInterfaceSubClass );
            if ( !pUsbDevice->DiskContext ) {
                DEBUGMSG( ZONE_ERR, (TEXT("DiskAttach error:%d on %s\n"), GetLastError(), wsDriverName ));
                bRc = FALSE;
                break;
            }
        } __except ( EXCEPTION_EXECUTE_HANDLER ) {
            DEBUGMSG(ZONE_ERR,(TEXT("USBMSC::DiskAttach:EXCEPTION:0x%x\n"), GetExceptionCode()));
            TEST_TRAP();
            bRc = FALSE;
        }

    } while(0);

    if (!bRc) {
        //
        // If not our device, or error, then clean up
        //
        RemoveDeviceContext( pUsbDevice );

    } else {

        *AcceptControl = TRUE;

        UsbDeviceTest( pUsbDevice );

    }

    DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC<USBDeviceAttach:%d\n"), *AcceptControl ));

    return bRc;
}


//
// Warning: do not assume that the USB stack will call this routine immediately after the device is unplugged.
// It could take some time for it to cleanup and get back to us. 
//
BOOL WINAPI 
UsbDeviceNotify(
   LPVOID lpvNotifyParameter,
   DWORD dwCode,
   LPDWORD * dwInfo1,
   LPDWORD * dwInfo2,
   LPDWORD * dwInfo3,
   LPDWORD * dwInfo4
   )
{
   PUSBMSC_DEVICE pUsbDevice = (PUSBMSC_DEVICE)lpvNotifyParameter;

   UNREFERENCED_PARAMETER(dwInfo1);
   UNREFERENCED_PARAMETER(dwInfo2);
   UNREFERENCED_PARAMETER(dwInfo3);
   UNREFERENCED_PARAMETER(dwInfo4);

   DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC>UsbDeviceNotify\n")));

   if ( !VALID_CONTEXT( pUsbDevice ) ) {
      DEBUGMSG( ZONE_ERR, (TEXT("Invalid Context!\n")));
      TEST_TRAP();
      return FALSE;
   }

   switch(dwCode) {

      case USB_CLOSE_DEVICE:
        DEBUGMSG( ZONE_USB_INIT, (TEXT("USB_CLOSE_DEVICE\n")));
        if (pUsbDevice->Flags.AcceptIo) {
           //
           // set state that we are being removed
           // and no longer accepting I/O
           // 
           EnterCriticalSection( &pUsbDevice->Lock );
           pUsbDevice->Flags.AcceptIo = FALSE;
           pUsbDevice->Flags.DeviceRemoved = TRUE;
           LeaveCriticalSection( &pUsbDevice->Lock );
           
           //
           // cancel any outstanding I/O
           // ...


           //
           // call the Disk's DiskDetach callback. DiskDetach should be able to cope with NULL Context.
           //
           __try {
                if ( pUsbDevice->DiskDetach && !pUsbDevice->DiskDetach(pUsbDevice->DiskContext) ) {
                    DEBUGMSG( ZONE_ERR, (TEXT("DiskDetach error:%d\n"), GetLastError() ));
                }
            } __except ( EXCEPTION_EXECUTE_HANDLER ) {
                DEBUGMSG(ZONE_ERR,(TEXT("USBMSC::DiskDetach:EXCEPTION:0x%x\n"), GetExceptionCode()));
                TEST_TRAP();
            }
            
            if (0 == InterlockedDecrement(&g_NumDevices) ) {
                if ( pUsbDevice->hDiskDriver && !FreeLibrary( pUsbDevice->hDiskDriver) ) {
                   DEBUGMSG( ZONE_ERR, (TEXT("FreeLibrary error:%d\n"), GetLastError() ));
                } 
                else 
                    pUsbDevice->hDiskDriver=NULL;
            }
            ASSERT(g_NumDevices >= 0);

        } else {
            ASSERT(0);
        }

        //
        // finally, cleanup this device context
        //
        RemoveDeviceContext( pUsbDevice );

        return TRUE;

      default:
         DEBUGMSG( ZONE_ERR, (TEXT("Unhandled code:%d\n"), dwCode));
         TEST_TRAP();
         break;
    }
   
   DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC<UsbDeviceNotify\n")));
   
   return FALSE;
}


LPCUSB_INTERFACE
ParseUsbDescriptors(
   USB_HANDLE       hUsbDevice,
   LPCUSB_FUNCS     UsbFuncs,
   LPCUSB_INTERFACE CurInterface,
   LPUSHORT         ConfigIndex
   )
{
    LPCUSB_DEVICE      pDevice;
    LPCUSB_INTERFACE   pUsbInterface;
    LPCUSB_INTERFACE   pDesiredInterface = NULL;

    DWORD dwNumInterfaces;
    DWORD dwIndex;

    DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC>ParseUsbDescriptors\n")));

    if ( !hUsbDevice || !UsbFuncs || !CurInterface || !ConfigIndex) {
        DEBUGMSG( ZONE_ERR, (TEXT("Invalid parameter\n")));
        return NULL;
    }

    //
    // get the descriptors
    //
    pDevice = UsbFuncs->lpGetDeviceInfo( hUsbDevice );
    if ( !pDevice ) {
        DEBUGMSG( ZONE_ERR, (TEXT("GetDeviceInfo error:%d\n"), GetLastError() ));
        return NULL;
    }

    DUMP_USB_DEVICE_DESCRIPTOR( pDevice->Descriptor );
    DUMP_USB_CONFIGURATION_DESCRIPTOR( pDevice->lpActiveConfig->Descriptor );  

    // get config index
    for ( *ConfigIndex = 0; *ConfigIndex < (USHORT)pDevice->Descriptor.bNumConfigurations; *ConfigIndex++) {
        if (pDevice->lpActiveConfig == (pDevice->lpConfigs + *ConfigIndex)) {
            DEBUGMSG( ZONE_USB_INIT, (TEXT("ConfigIndex:%d\n"), *ConfigIndex));
         break;
      }
    }

    pUsbInterface   = pDevice->lpActiveConfig->lpInterfaces;
    dwNumInterfaces = pDevice->lpActiveConfig->dwNumInterfaces;

    // walk the interfaces searching for best fit
    for ( dwIndex = 0; dwIndex < dwNumInterfaces; pUsbInterface++, dwIndex++) 
    {
        DUMP_USB_INTERFACE_DESCRIPTOR( pUsbInterface->Descriptor, dwIndex );
        if ( pUsbInterface->Descriptor.bInterfaceNumber == CurInterface->Descriptor.bInterfaceNumber ) 
        {
            if (  pUsbInterface->Descriptor.bInterfaceClass == USBMSC_INTERFACE_CLASS &&
                 (pUsbInterface->Descriptor.bInterfaceSubClass >= USBMSC_SUBCLASS_RBC && pUsbInterface->Descriptor.bInterfaceSubClass <= USBMSC_SUBCLASS_SCSI) &&
                 (pUsbInterface->Descriptor.bInterfaceProtocol == USBMSC_INTERFACE_PROTOCOL_CBIT || pUsbInterface->Descriptor.bInterfaceProtocol == USBMSC_INTERFACE_PROTOCOL_CBT || pUsbInterface->Descriptor.bInterfaceProtocol == USBMSC_INTERFACE_PROTOCOL_BOT) )
            {
                //
                // if we do not already have an interface, or the selected Protocol is not Bulk-Only
                // (I personally prefer Bulk-Only since it is well defined) 
                //
                if ( !pDesiredInterface || pDesiredInterface->Descriptor.bInterfaceProtocol != USBMSC_INTERFACE_PROTOCOL_BOT)
                {
                    pDesiredInterface = pUsbInterface;
                    DEBUGMSG( ZONE_USB_INIT, (TEXT("*** Found interface @ index: %d ***\n"), dwIndex));
                }
            }
        }
    }
  
   DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC<ParseUsbDescriptors:0x%x\n"), pDesiredInterface ));

   return pDesiredInterface;
}


BOOL
SetUsbInterface(
   PUSBMSC_DEVICE   pUsbDevice
   )
{
   USB_TRANSFER hTransfer;
   BOOL bRc = FALSE;
   DWORD dwIndex;

   DEBUGMSG( ZONE_USB_INIT, (TEXT("USBMSC>SetUsbInterface\n")));

   if ( !VALID_CONTEXT( pUsbDevice ) || !pUsbDevice->pUsbInterface ) {
      DEBUGMSG( ZONE_ERR, (TEXT("Invalid parameter\n")));
      return FALSE;
   }

   hTransfer = pUsbDevice->UsbFuncs->lpSetInterface( pUsbDevice->hUsbDevice,
                                                     NULL,
                                                     NULL,
                                                     0, // Flags
                                                     pUsbDevice->pUsbInterface->Descriptor.bInterfaceNumber,
                                                     pUsbDevice->pUsbInterface->Descriptor.bAlternateSetting );

   if ( !hTransfer ) {
      DEBUGMSG( ZONE_ERR, (TEXT("SetUsbInterface error:%d\n"), GetLastError() ));
      return FALSE;
   }

    //
    // now parse the endpoints
    //
    for ( dwIndex = 0; dwIndex < pUsbDevice->pUsbInterface->Descriptor.bNumEndpoints; dwIndex++) 
    {
        LPCUSB_ENDPOINT pEndpoint;
        pEndpoint = pUsbDevice->pUsbInterface->lpEndpoints + dwIndex;

        DUMP_USB_ENDPOINT_DESCRIPTOR( pEndpoint->Descriptor );

        // 
        // Mass Storage Class supports 1 mandatory Bulk OUT, 1 mandatory Bulk IN, and 1 optional INTERRUPT
        // 
        if ( USB_ENDPOINT_DIRECTION_OUT( pEndpoint->Descriptor.bEndpointAddress ) ) {
            if ( NULL == pUsbDevice->BulkOut.hPipe &&
                (pEndpoint->Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) 
            {
                //
                // create the Bulk OUT pipe
                //
                pUsbDevice->BulkOut.hPipe = pUsbDevice->UsbFuncs->lpOpenPipe( pUsbDevice->hUsbDevice,
                                                                              &pEndpoint->Descriptor );
                if ( !pUsbDevice->BulkOut.hPipe ) {
                    DEBUGMSG( ZONE_ERR, (TEXT("OpenPipe error:%d\n"), GetLastError() ));
                    bRc = FALSE;
                    TEST_TRAP();
                    break;
                }

                //
                // setup any endpoint specific timers, buffers, context, etc.
                //
                pUsbDevice->BulkOut.hEvent = CreateEvent( NULL, MANUAL_RESET_EVENT, FALSE, NULL);
                if ( !pUsbDevice->BulkOut.hEvent ) {
                    DEBUGMSG( ZONE_ERR, (TEXT("CreateEvent error:%d\n"), GetLastError() ));
                    bRc = FALSE;
                    TEST_TRAP();
                    break;
                }

                pUsbDevice->BulkOut.bIndex         = pEndpoint->Descriptor.bEndpointAddress;
                pUsbDevice->BulkOut.wMaxPacketSize = pEndpoint->Descriptor.wMaxPacketSize;
            }

        } else if (USB_ENDPOINT_DIRECTION_IN( pEndpoint->Descriptor.bEndpointAddress ) ) {
            if ( NULL == pUsbDevice->BulkIn.hPipe && 
                (pEndpoint->Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) 
            {
                //
                // create the Bulk IN pipe
                //
                pUsbDevice->BulkIn.hPipe = pUsbDevice->UsbFuncs->lpOpenPipe( pUsbDevice->hUsbDevice,
                                                                            &pEndpoint->Descriptor );
                if ( !pUsbDevice->BulkIn.hPipe ) {
                    DEBUGMSG( ZONE_ERR, (TEXT("OpenPipe error: %d\n"), GetLastError() ));
                    bRc = FALSE;
                    TEST_TRAP();
                    break;
                }

                //
                // setup any endpoint specific timers, buffers, context, etc.
                //
                pUsbDevice->BulkIn.hEvent = CreateEvent( NULL, MANUAL_RESET_EVENT, FALSE, NULL);
                if ( !pUsbDevice->BulkIn.hEvent ) {
                    DEBUGMSG( ZONE_ERR, (TEXT("CreateEvent error:%d\n"), GetLastError() ));
                    bRc = FALSE;
                    TEST_TRAP();
                    break;
                }

                pUsbDevice->BulkIn.bIndex         = pEndpoint->Descriptor.bEndpointAddress;
                pUsbDevice->BulkIn.wMaxPacketSize = pEndpoint->Descriptor.wMaxPacketSize;
            
            } else if ( NULL == pUsbDevice->Interrupt.hPipe &&

⌨️ 快捷键说明

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