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

📄 usbmsc.c

📁 Windows CE 5.0下的U盘驱动源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
        
        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.
        //
        for (uiIndex=0;uiIndex<MAX_LUN;uiIndex++)
           pUsbDevice->DiskContext[uiIndex]=NULL;
        // Get Max LUN.
        if (GetMaxLUN(pUsbDevice, &uMaxLun)!=ERROR_SUCCESS)
            uMaxLun=1;// Using 1 as default;
        pUsbDevice->dwMaxLun= uMaxLun;
        ASSERT(pUsbDevice->dwMaxLun>=1);
        for (uiIndex=0;uiIndex<uMaxLun;uiIndex++) {
           __try {
                pUsbDevice->DiskContext[uiIndex]= DiskAttach((HANDLE)pUsbDevice, 
                                                     wsSubClassRegKey,
                                                     (DWORD)uiIndex,
                                                     bInterfaceSubClass);
                if ( !pUsbDevice->DiskContext[uiIndex] ) {
                    DEBUGMSG( ZONE_ERR, (TEXT("DiskAttach error:%d on %s\n"), GetLastError(), wsDriverName ));
                    pUsbDevice->Flags.AcceptIo = FALSE;
                    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 ) {
                    DWORD dwIndex;
                    for (dwIndex=0;dwIndex<pUsbDevice->dwMaxLun;dwIndex++)
                        if (pUsbDevice->DiskContext[dwIndex]==NULL ||
                                !pUsbDevice->DiskDetach(pUsbDevice->DiskContext[dwIndex]) ) {
                            DEBUGMSG( ZONE_ERR, (TEXT("DiskDetach(Lun=%d) error:%d\n"),dwIndex, 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.bInterfaceSubClass == USBMSC_SUBCLASS_RESERVED) &&
                 (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,
   LPCWSTR          UniqueDriverId   
   )
{
   USB_TRANSFER hTransfer = 0;
   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;
   }

   if (pUsbDevice->pUsbInterface->Descriptor.bAlternateSetting != 0) {
      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;
                }
                //
                // Set Async Content
                pUsbDevice->BulkOut.pAsyncContent = CreateBulkTransferMgr(
                        pUsbDevice->UsbFuncs,pUsbDevice->BulkOut.hPipe,&pEndpoint->Descriptor,UniqueDriverId
                        );
                
                if (!pUsbDevice->BulkOut.pAsyncContent)  {
                    DEBUGMSG( ZONE_ERR, (TEXT("CreateBulkTransferMgr 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;
                }
                //
                // Set Async Content
                pUsbDevice->BulkIn.pAsyncContent = CreateBulkTransferMgr(
                        pUsbDevice->UsbFuncs,pUsbDevice->BulkIn.hPipe,&pEndpoint->Descriptor,UniqueDriverId
                        );
                if (!pUsbDevice->BulkIn.pAsyncContent)  {
                    DEBUGMSG( ZONE_ERR, (TEXT("CreateBulkTransferMgr 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;

⌨️ 快捷键说明

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