有人问,前面的博文,分别列出了USB xHCI, USB3 HUB, UCX01000的符号有什么用?
答案是,虽然我们不能看到MICROSOFT 的源代码,但通过这些符号,可以帮助我们调试USB子系统。
下面给出一例:
做USB设备驱动这些年,用过Cypress的USB3.0驱动,改过Philips USB1.1, Cypress USB2.0的驱动代码, 开发了基于Microsoft USBSamp的USB IP测试软件包。
最近,又借助WinUSB来完成一个音视频设备项目。
使用WinUSB的优点是显而易见的,可以将设备驱动软件开发的时间与精力专注于产品的特色处(例如这个项目中的视频方面),而由WinUSB提供了稳定的USB相关功能。
先列出WinUSB的符号:
0: kd> lm vm winusb
start end module name
fffff800`caab5000 fffff800`caace000 WinUSB (pdb symbols) c:\e\symcache\winusb.pdb\661781CAB404408B9E1DAE81C370764D1\winusb.pdb
Loaded symbol image file: WinUSB.sys
Image path: WinUSB.sys
Image name: WinUSB.sys
Timestamp: Thu Aug 22 19:37:55 2013 (5215F813)
CheckSum: 0001CA4C
ImageSize: 00019000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
0: kd> x winusb!*
fffff800`caac3f40 WinUSB!WdfDriverGlobals = <no type information>
fffff800`caab6b10 WinUSB!WPP_RECORDER_SF_did (<no parameter info>)
fffff800`caac20c0 WinUSB!_imp_ExAcquireFastMutexUnsafe = <no type information>
fffff800`caaca320 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caab65dc WinUSB!WppClassicProviderCallback (<no parameter info>)
fffff800`caaca490 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caab84b0 WinUSB!WinUsb_GetPipePolicy (<no parameter info>)
fffff800`caac9e70 WinUSB!WinUSB_SelectConfiguration (<no parameter info>)
fffff800`caab6a44 WinUSB!WPP_RECORDER_SF_di (<no parameter info>)
fffff800`caaba0e4 WinUSB!WinUSB_IncrementKeepAliveCount (<no parameter info>)
fffff800`caac3008 WinUSB!_security_cookie_complement = <no type information>
fffff800`caac60f8 WinUSB!WppTraceCallback (<no parameter info>)
fffff800`caac2038 WinUSB!_imp_WdfVersionUnbindClass = <no type information>
fffff800`caab9a70 WinUSB!WinUSB_ExchangeVersion (<no parameter info>)
fffff800`caabfa94 WinUSB!WinUSB_ChildIsochTransferComplete (<no parameter info>)
fffff800`caabe05c WinUSB!WinUSB_EvtWriteIoResume (<no parameter info>)
fffff800`caac2170 WinUSB!_imp_RtlInitUnicodeString = <no type information>
fffff800`caac01d0 WinUSB!WinUSB_IsochPurgeComplete (<no parameter info>)
fffff800`caac14d4 WinUSB!WinUSB_SetupIsochUrb (<no parameter info>)
fffff800`caabbb04 WinUSB!WinUSB_ReadPipeCompletion (<no parameter info>)
fffff800`caac88e8 WinUSB!WinUSB_SetDeviceInterfaceProperties (<no parameter info>)
fffff800`caac3170 WinUSB!__KMDF_TYPE_INIT_END = <no type information>
fffff800`caac1ec0 WinUSB! ?? ::FNODOBFM::`string‘ (<no parameter info>)
fffff800`caac7e20 WinUSB!WinUSB_PrepareHardware (<no parameter info>)
fffff800`caaba194 WinUSB!WPP_RECORDER_SF_dDdd (<no parameter info>)
fffff800`caacb3c8 WinUSB!_IMPORT_DESCRIPTOR_HAL = <no type information>
fffff800`caab98f4 WinUSB!WinUSB_QueryDeviceInformation (<no parameter info>)
fffff800`caac23b0 WinUSB!WPP_272e0b4692370df708b7a2b9a6c27a83_Traceguids = <no type information>
fffff800`caabd510 WinUSB!WinUSB_WritePipeCompletion (<no parameter info>)
fffff800`caac1f00 WinUSB! ?? ::FNODOBFM::`string‘ (<no parameter info>)
fffff800`caac20a8 WinUSB!_imp__wcsnicmp = <no type information>
fffff800`caac2070 WinUSB!WppRecorder_NULL_THUNK_DATA = <no type information>
fffff800`caac1784 WinUSB!FxStubDriverMiniportUnload (<no parameter info>)
fffff800`caabc5a8 WinUSB!WinUSB_RawIoRead (<no parameter info>)
fffff800`caac2160 WinUSB!_imp_MmGetSystemRoutineAddress = <no type information>
fffff800`caacb404 WinUSB!_IMPORT_DESCRIPTOR_WDFLDR = <no type information>
fffff800`caac7274 WinUSB!WinUSB_Create (<no parameter info>)
fffff800`caac2110 WinUSB!_imp_KeInitializeSpinLock = <no type information>
fffff800`caabab88 WinUSB!WinUSB_SetInterface (<no parameter info>)
fffff800`caac23c0 WinUSB!WPP_7e587b8b4c5e1652d25e8f85ef570329_Traceguids = <no type information>
fffff800`caac22c8 WinUSB!DEVPKEY_Winusb_Device_VID = <no type information>
fffff800`caabcbc4 WinUSB!WinUSB_SubmitRead (<no parameter info>)
fffff800`caac2020 WinUSB!_imp_USBD_ParseDescriptors = <no type information>
fffff800`caac8840 WinUSB!WinUSB_QueryStop (<no parameter info>)
fffff800`caac20c8 WinUSB!_imp_KeWaitForSingleObject = <no type information>
fffff800`caac2168 WinUSB!_imp_KeReleaseSpinLock = <no type information>
fffff800`caaba5bc WinUSB!WinUSB_InitPipe (<no parameter info>)
fffff800`caac22b0 WinUSB!DEVPKEY_Winusb_Device_PID = <no type information>
fffff800`caabdfa8 WinUSB!WinUSB_EvtWriteIoStop (<no parameter info>)
fffff800`caaca2a0 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac8130 WinUSB!WinUSB_SelfManagedIoInit (<no parameter info>)
fffff800`caac41d0 WinUSB!g_pIoSetActivityIdIrp = <no type information>
fffff800`caac0d10 WinUSB!WinUSB_InitializeParentRequest (<no parameter info>)
fffff800`caac2018 WinUSB!_imp_USBD_ParseConfigurationDescriptorEx = <no type information>
fffff800`caabe2cc WinUSB!WinUSB_InitIsochPipe (<no parameter info>)
fffff800`caaca240 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac2390 WinUSB!WPP_d8eea9561f2d10664565e8078ca0c91c_Traceguids = <no type information>
fffff800`caac1a80 WinUSB!memcpy (<no parameter info>)
fffff800`caab6d4c WinUSB!WinUSB_DeviceControl (<no parameter info>)
fffff800`caab6ccc WinUSB!WinUSB_QueueStateChangeComplete (<no parameter info>)
fffff800`caab9144 WinUSB!WinUSB_SetPowerPolicy (<no parameter info>)
fffff800`caac77b4 WinUSB!WinUSB_GetRegParams (<no parameter info>)
fffff800`caac3190 WinUSB!pfnWppGetVersion = <no type information>
fffff800`caaca570 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac1f30 WinUSB! ?? ::FNODOBFM::`string‘ (<no parameter info>)
fffff800`caaba434 WinUSB!WinUSB_FreePipe (<no parameter info>)
fffff800`caac9098 WinUSB!WinUSB_ResetPipe (<no parameter info>)
fffff800`caac1a80 WinUSB!memmove (<no parameter info>)
fffff800`caabe474 WinUSB!WinUSB_IsochBufferDeviceControl (<no parameter info>)
fffff800`caabc2ec WinUSB!WinUSB_ReadPipe (<no parameter info>)
fffff800`caabd2d0 WinUSB!WinUSB_CancelRead (<no parameter info>)
fffff800`caac2148 WinUSB!_imp_RtlCopyUnicodeString = <no type information>
fffff800`caaca2d0 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac19f8 WinUSB!_GSHandlerCheckCommon (<no parameter info>)
fffff800`caabe5bc WinUSB!WinUSB_FreeIsochPipe (<no parameter info>)
fffff800`caac9d0c WinUSB!WinUSB_GetConfigurationDescriptor (<no parameter info>)
fffff800`caac4180 WinUSB!WPP_MAIN_CB = <no type information>
fffff800`caacb2e0 WinUSB! ?? ::PBOPGDP::`string‘ (<no parameter info>)
fffff800`caab8050 WinUSB!WinUSB_SetPipePolicy (<no parameter info>)
fffff800`caac0e74 WinUSB!WinUSB_SubmitChildIsochTransfer (<no parameter info>)
fffff800`caac2050 WinUSB!WDFLDR_NULL_THUNK_DATA = <no type information>
fffff800`caac2140 WinUSB!_imp_ExReleaseFastMutexUnsafe = <no type information>
fffff800`caac64f8 WinUSB!WinUSB_AddDevice (<no parameter info>)
fffff800`caac9868 WinUSB!WinUSB_ResetPort (<no parameter info>)
fffff800`caac8e7c WinUSB!WinUsb_IsUpperFilterPresent (<no parameter info>)
fffff800`caac3140 WinUSB!__KMDF_CLASS_BIND_START = <no type information>
fffff800`caac2078 WinUSB!_imp_ExAllocatePoolWithTag = <no type information>
fffff800`caaca4e0 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac20d8 WinUSB!_imp_IoBuildPartialMdl = <no type information>
fffff800`caac31b0 WinUSB!pfnWppQueryTraceInformation = <no type information>
fffff800`caac1308 WinUSB!WinUSB_SubmitIsochTransfer (<no parameter info>)
fffff800`caacb3f0 WinUSB!_IMPORT_DESCRIPTOR_WppRecorder = <no type information>
fffff800`caac2258 WinUSB!DEVPKEY_Device_Service = <no type information>
fffff800`caac17b8 WinUSB!FxDriverEntryWorker (<no parameter info>)
fffff800`caabc9fc WinUSB!WinUSB_CreateActivityIdSubRequest (<no parameter info>)
fffff800`caab7bd8 WinUSB!WinUSB_SelectAltSetting (<no parameter info>)
fffff800`caac2128 WinUSB!_imp_ExFreePool = <no type information>
fffff800`caac9a84 WinUSB!WinUSB_CyclePort (<no parameter info>)
fffff800`caac2130 WinUSB!_imp_KeLeaveCriticalRegion = <no type information>
fffff800`caaca380 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac19d8 WinUSB!_GSHandlerCheck (<no parameter info>)
fffff800`caaca0b0 WinUSB!WinUSB_ResetDevice (<no parameter info>)
fffff800`caac2138 WinUSB!_imp_IoAllocateMdl = <no type information>
fffff800`caac30d8 WinUSB!WDF_WORKITEM_CONTEXT_TYPE_INFO = <no type information>
fffff800`caac22e0 WinUSB!DEVPKEY_Winusb_Device_SubClass = <no type information>
fffff800`caac3010 WinUSB!WDF_ISOCH_REQUEST_CONTEXT_TYPE_INFO = <no type information>
fffff800`caac3198 WinUSB!pfnEtwRegisterClassicProvider = <no type information>
fffff800`caac2310 WinUSB!DEVPKEY_Winusb_Device_Class = <no type information>
fffff800`caac2120 WinUSB!_imp_RtlGetVersion = <no type information>
fffff800`caac41f8 WinUSB!__PchSym_ = <no type information>
fffff800`caabf450 WinUSB!WinUSB_IsochQueueReadyNotification (<no parameter info>)
fffff800`caac2370 WinUSB!WPP_01fecbf68877b6edf8ae50552383ce55_Traceguids = <no type information>
fffff800`caac41d8 WinUSB!g_pIoGetActivityIdIrp = <no type information>
fffff800`caac2028 WinUSB!USBD_NULL_THUNK_DATA = <no type information>
fffff800`caab9424 WinUSB!WinUsb_GetPowerPolicy (<no parameter info>)
fffff800`caac41f0 WinUSB!g_pIoDecrementKeepAliveCount = <no type information>
fffff800`caaca300 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac31a0 WinUSB!pfnEtwUnregister = <no type information>
fffff800`caac2340 WinUSB!TestGuid = <no type information>
fffff800`caab660c WinUSB!RtlStringCbPrintfW (<no parameter info>)
fffff800`caab7e90 WinUSB!WinUsb_GetAltSetting (<no parameter info>)
fffff800`caac2040 WinUSB!_imp_WdfVersionUnbind = <no type information>
fffff800`caabe914 WinUSB!WinUSB_RegisterIsochBuffer (<no parameter info>)
fffff800`caaca1a0 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac2088 WinUSB!_imp_IoGetDevicePropertyData = <no type information>
fffff800`caaca590 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac2000 WinUSB!_guard_check_icall_fptr = <no type information>
fffff800`caaba350 WinUSB!WPP_RECORDER_SF_dqq (<no parameter info>)
fffff800`caac22f8 WinUSB!DEVPKEY_Winusb_Device_Custom_Interface_GUIDs = <no type information>
fffff800`caac80c0 WinUSB!WinUSB_ReleaseHardware (<no parameter info>)
fffff800`caab64c4 WinUSB!WPP_RECORDER_SF_qq (<no parameter info>)
fffff800`caac2030 WinUSB!_imp_WdfVersionBind = <no type information>
fffff800`caac74bc WinUSB!WinUSB_Cleanup (<no parameter info>)
fffff800`caaba290 WinUSB!WPP_RECORDER_SF_dq (<no parameter info>)
fffff800`caabae54 WinUSB!WinUSB_IsInterruptOrBulkInPipe (<no parameter info>)
fffff800`caabdbf0 WinUSB!WinUSB_SubmitWrite (<no parameter info>)
fffff800`caaca3c0 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caabf114 WinUSB!WinUSB_AllocateIsochChildRequests (<no parameter info>)
fffff800`caabe1a4 WinUSB!WPP_RECORDER_SF_qlldd (<no parameter info>)
fffff800`caacb310 WinUSB! ?? ::PBOPGDP::`string‘ (<no parameter info>)
fffff800`caac3100 WinUSB!WPP_GLOBAL_Control = <no type information>
fffff800`caac30b0 WinUSB!WDF_ISOCH_REQUEST_WITH_CHILD_CONTEXT_TYPE_INFO = <no type information>
fffff800`caac20d0 WinUSB!_imp_IoSetDeviceInterfacePropertyData = <no type information>
fffff800`caabf35c WinUSB!WinUSB_DispatchIsochRequests (<no parameter info>)
fffff800`caac7cd8 WinUSB!WinUSB_UpdateSqmInfo (<no parameter info>)
fffff800`caab7808 WinUSB!WinUSB_GetDescriptor (<no parameter info>)
fffff800`caab8bb8 WinUSB!WinUSB_ControlTransfer (<no parameter info>)
fffff800`caab6000 WinUSB!WPP_RECORDER_SF_ (<no parameter info>)
fffff800`caac23a0 WinUSB!WPP_665a2041265c71ae73ac0046da341ef0_Traceguids = <no type information>
fffff800`caabf7bc WinUSB!WinUSB_ParentIsochRequestCancel (<no parameter info>)
fffff800`caabe7c4 WinUSB!WinUSB_RegisterIsochBufferCancel (<no parameter info>)
fffff800`caac19b0 WinUSB!_security_check_cookie (<no parameter info>)
fffff800`caab62b8 WinUSB!WPP_RECORDER_SF_q (<no parameter info>)
fffff800`caab61c8 WinUSB!WPP_RECORDER_SF_l (<no parameter info>)
fffff800`caab61c8 WinUSB!WPP_RECORDER_SF_D (<no parameter info>)
fffff800`caab61c8 WinUSB!WPP_RECORDER_SF_d (<no parameter info>)
fffff800`caac31c0 WinUSB!WdfFunctions = <no type information>
fffff800`caac20e8 WinUSB!_imp_ExInterlockedInsertTailList = <no type information>
fffff800`caacb3b4 WinUSB!_IMPORT_DESCRIPTOR_ntoskrnl = <no type information>
fffff800`caac646c WinUSB!WinUSB_Unload (<no parameter info>)
fffff800`caac2328 WinUSB!DEVPKEY_DeviceInterface_Restricted = <no type information>
fffff800`caab7694 WinUSB!WinUSB_SerialDeviceControl (<no parameter info>)
fffff800`caacb340 WinUSB! ?? ::PBOPGDP::`string‘ (<no parameter info>)
fffff800`caac2058 WinUSB!_imp_WppAutoLogStart = <no type information>
fffff800`caab9e70 WinUSB!WinUSB_StartDeviceControlQueues (<no parameter info>)
fffff800`caac63e0 WinUSB!WppCleanupKm (<no parameter info>)
fffff800`caabef94 WinUSB!WinUSB_UnmapIsochBuffer (<no parameter info>)
fffff800`caac3038 WinUSB!WDF_ISOCH_BUFFER_CONTEXT_TYPE_INFO = <no type information>
fffff800`caac2068 WinUSB!_imp_WppAutoLogStop = <no type information>
fffff800`caaca160 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac23f0 WinUSB!load_config_used = <no type information>
fffff800`caac175c WinUSB!FxStubDriverUnload (<no parameter info>)
fffff800`caac3184 WinUSB!ExDefaultNonPagedPoolType = <no type information>
fffff800`caac1f60 WinUSB! ?? ::FNODOBFM::`string‘ (<no parameter info>)
fffff800`caabf8a0 WinUSB!WinUSB_IsochTransferComplete (<no parameter info>)
fffff800`caac3150 WinUSB!__KMDF_CLASS_BIND_END = <no type information>
fffff800`caabfe10 WinUSB!WinUSB_ForwardIsochRequest (<no parameter info>)
fffff800`caabafb4 WinUSB!WinUSB_ErrorWorkItem (<no parameter info>)
fffff800`caac8280 WinUSB!WinUSB_DeviceCleanup (<no parameter info>)
fffff800`caac86c0 WinUSB!WinUSB_D0Exit (<no parameter info>)
fffff800`caaca560 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac2350 WinUSB!WPP_9e5919c5a70c38eced6e3b7996693684_Traceguids = <no type information>
fffff800`caac41e8 WinUSB!g_pIoIncrementKeepAliveCount = <no type information>
fffff800`caac7414 WinUSB!WinUSB_Close (<no parameter info>)
fffff800`caac2280 WinUSB!DEVPKEY_Winusb_Device_Protocol = <no type information>
fffff800`caac2118 WinUSB!_imp_KeInitializeEvent = <no type information>
fffff800`caaca1e0 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caaca460 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac1a60 WinUSB!guard_check_icall_nop (<no parameter info>)
fffff800`caac2298 WinUSB!DEVPKEY_Device_UpperFilters = <no type information>
fffff800`caac9c24 WinUSB!WinUSB_GetDeviceDescriptor (<no parameter info>)
fffff800`caac2108 WinUSB!_imp_RtlGUIDFromString = <no type information>
fffff800`caab9ba8 WinUSB!WinUSB_InternalDeviceControl (<no parameter info>)
fffff800`caac6000 WinUSB!WppLoadTracingSupport (<no parameter info>)
fffff800`caac2150 WinUSB!_imp_IoWMIRegistrationControl = <no type information>
fffff800`caac16cc WinUSB!FxStubDriverUnloadCommon (<no parameter info>)
fffff800`caac3060 WinUSB!WDF_DEVICE_EXTENSION_TYPE_INFO = <no type information>
fffff800`caab8a7c WinUSB!WinUSB_ControlTransferCompletion (<no parameter info>)
fffff800`caabb90c WinUSB!WinUSB_RawIoReadCompletion (<no parameter info>)
fffff800`caaca400 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caabb3d8 WinUSB!WinUSB_HandlePipeError (<no parameter info>)
fffff800`caac3160 WinUSB!__KMDF_TYPE_INIT_START = <no type information>
fffff800`caac20b8 WinUSB!_imp_KeAcquireSpinLockRaiseToDpc = <no type information>
fffff800`caac2008 WinUSB!_imp_KeQueryPerformanceCounter = <no type information>
fffff800`caab9684 WinUSB!WinUSB_ResetDefaults (<no parameter info>)
fffff800`caaca430 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac178c WinUSB!FxDriverEntry (<no parameter info>)
fffff800`caac2360 WinUSB!WPP_ThisDir_CTLGUID_WinUSB = <no type information>
fffff800`caac3000 WinUSB!_security_cookie = <no type information>
fffff800`caabe0c0 WinUSB!WPP_RECORDER_SF_qDD (<no parameter info>)
fffff800`caac20f8 WinUSB!_imp_ExInterlockedInsertHeadList = <no type information>
fffff800`caabb6f4 WinUSB!WPP_RECORDER_SF_dDd (<no parameter info>)
fffff800`caab6688 WinUSB!WPP_RECORDER_SF_DDD (<no parameter info>)
fffff800`caab6764 WinUSB!WPP_RECORDER_SF_DDd (<no parameter info>)
fffff800`caab695c WinUSB!WPP_RECORDER_SF_ddd (<no parameter info>)
fffff800`caacb380 WinUSB! ?? ::PBOPGDP::`string‘ (<no parameter info>)
fffff800`caabb82c WinUSB!WPP_RECORDER_SF_dDi (<no parameter info>)
fffff800`caac0c5c WinUSB!WinUSB_FreeChildIsochRequest (<no parameter info>)
fffff800`caaca180 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac2158 WinUSB!_imp_RtlCompareMemory = <no type information>
fffff800`caac41e0 WinUSB!g_pIoGetInitiatorProcess = <no type information>
fffff800`caab60c0 WinUSB!WPP_RECORDER_SF_Sd (<no parameter info>)
fffff800`caab63a8 WinUSB!WPP_RECORDER_SF_qd (<no parameter info>)
fffff800`caab6848 WinUSB!WPP_RECORDER_SF_dD (<no parameter info>)
fffff800`caab6848 WinUSB!WPP_RECORDER_SF_Dd (<no parameter info>)
fffff800`caab6848 WinUSB!WPP_RECORDER_SF_dd (<no parameter info>)
fffff800`caab6c04 WinUSB!WPP_RECORDER_SF_id (<no parameter info>)
fffff800`caac20f0 WinUSB!_imp_ExInterlockedRemoveHeadList = <no type information>
fffff800`caaba13c WinUSB!WinUSB_DecrementKeepAliveCount (<no parameter info>)
fffff800`caac20a0 WinUSB!_imp_RtlQueryRegistryValues = <no type information>
fffff800`caac3088 WinUSB!WDF_TRANSFER_CONTEXT_TYPE_INFO = <no type information>
fffff800`caac2098 WinUSB!_imp__vsnwprintf = <no type information>
fffff800`caac20e0 WinUSB!_imp_IoFreeMdl = <no type information>
fffff800`caacb27c WinUSB!_security_init_cookie (<no parameter info>)
fffff800`caabf4c8 WinUSB!WinUSB_CancelChildRequests (<no parameter info>)
fffff800`caac83c8 WinUSB!WinUSB_D0Entry (<no parameter info>)
fffff800`caac3188 WinUSB!WPPTraceSuite = <no type information>
fffff800`caac20b0 WinUSB!_imp_KeSetEvent = <no type information>
fffff800`caacb2b0 WinUSB! ?? ::PBOPGDP::`string‘ (<no parameter info>)
fffff800`caac9388 WinUSB!WinUSB_AbortPipe (<no parameter info>)
fffff800`caabd45c WinUSB!WinUSB_EvtRawIoStop (<no parameter info>)
fffff800`caac3180 WinUSB!ExDefaultMdlProtection = <no type information>
fffff800`caac19d0 WinUSB!_report_gsfailure (<no parameter info>)
fffff800`caabb5f4 WinUSB!WinUsb_GetCurrentFrameNumber (<no parameter info>)
fffff800`caac2060 WinUSB!_imp_WppAutoLogTrace = <no type information>
fffff800`caab9f58 WinUSB!WinUSB_StopDeviceControlQueues (<no parameter info>)
fffff800`caac2048 WinUSB!_imp_WdfVersionBindClass = <no type information>
fffff800`caac2178 WinUSB!ntoskrnl_NULL_THUNK_DATA = <no type information>
fffff800`caac2080 WinUSB!_imp_ExFreePoolWithTag = <no type information>
fffff800`caac96ac WinUSB!WinUSB_FlushPipe (<no parameter info>)
fffff800`caac2100 WinUSB!_imp_KeEnterCriticalRegion = <no type information>
fffff800`caac0248 WinUSB!WinUSB_SubmitIsochRequests (<no parameter info>)
fffff800`caabaf04 WinUSB!WinUSB_IsInterruptOrBulkOutPipe (<no parameter info>)
fffff800`caac0b78 WinUSB!WinUSB_GetFreeChildIsochRequest (<no parameter info>)
fffff800`caaca270 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac2380 WinUSB!WPP_2087dac655485f81d1477b0c81a5b792_Traceguids = <no type information>
fffff800`caacb000 WinUSB!DriverEntry (<no parameter info>)
fffff800`caabda04 WinUSB!WinUSB_WritePipe (<no parameter info>)
fffff800`caaca350 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caac31a8 WinUSB!pfnWppTraceMessage = <no type information>
fffff800`caac8d3c WinUSB!WinUsb_MarkInterfaceRestricted (<no parameter info>)
fffff800`caac6334 WinUSB!WppInitKm (<no parameter info>)
fffff800`caabecb0 WinUSB!WinUSB_MapIsochTransfer (<no parameter info>)
fffff800`caac2270 WinUSB!GUID_DEVINTERFACE_WINUSB_WINRT = <no type information>
fffff800`caac2010 WinUSB!HAL_NULL_THUNK_DATA = <no type information>
fffff800`caabb4ec WinUSB!WinUsb_GetMaxBytesPerInterval (<no parameter info>)
fffff800`caac1dc0 WinUSB!memset (<no parameter info>)
fffff800`caacb418 WinUSB!_NULL_IMPORT_DESCRIPTOR = <no type information>
fffff800`caaca220 WinUSB! ?? ::NNGAKEGL::`string‘ (<no parameter info>)
fffff800`caacb3dc WinUSB!_IMPORT_DESCRIPTOR_USBD = <no type information>
fffff800`caac2090 WinUSB!_imp_IoGetDeviceProperty = <no type information>
项目中,碰到的实际问题是:有的时候,系统软件发出的数据,与USB设备接收到的数据,数据内容不匹配(一块数据,前面部分丢失的情况)。
首先怀疑是设备这端没有做好接受数据工作,但经过Lecory T3 USB Analyzer的实时数据抓取,发现设备这边并没有数据丢失的情况发生。
转而怀疑是系统软件与WinUSB之间存在的交互的问题,导致了数据的丢失情况。
于是,在私有视频驱动准备数据处,与WinUSB的发送数据处,分别设一个断点:
bp WinUSB!WinUSB_WritePipe
观察是不是系统软件每次都将完整的数据包交给了WinUSB.
如果是,那说明两者之间的交互是正确的,问题在于WinUSB后面的数据传输过程,例如,是USB xHCI/USB3 HUB/UCX01000系统USB3.0主控驱动软件导致, 也有可能是USB3.0的HOST出了硬件逻辑本身就有问题,从而导致数据丢失的问题, 需要进一步对USB HOST驱动设断点,进行观察与排除怀疑点,缩小问题根源的范围。
下面是笔者设定bp WinUSB!WinUSB_WritePipe断点后,断点HIT时的寄存器上线文与栈回溯(NET双机内核调试):(以下栈帧中,将其中一些私有驱动名称改为xxmgr)
0: kd> g
Breakpoint 1 hit
rax=0000000000000000 rbx=ffffe00192f57080 rcx=ffffe0019085fe60
rdx=ffffe001908bdcb4 rsi=00001ffe6d0a8f78 rdi=ffffe0019085fe60
rip=fffff800caabda04 rsp=ffffd000234c63d8 rbp=ffffd000234c6430
r8=00001ffe6d0a8f78 r9=ffffd000234c6420 r10=000000000000001c
r11=ffffe001908bd080 r12=0000000000000000 r13=00001ffe6fd9e3d8
r14=fffff800caac2380 r15=0000000000000002
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000286
WinUSB!WinUSB_WritePipe:
fffff800`caabda04 488bc4 mov rax,rsp
0: kd> kvn
# Child-SP RetAddr : Args to Child : Call Site
00 ffffd000`234c63d8 fffff800`caab70f1 : ffffe001`92f57080 ffffd000`234c6430 00001ffe`6d0a8f78 00000000`00000000 : WinUSB!WinUSB_WritePipe
01 ffffd000`234c63e0 fffff800`c88f69ce : ffffe001`92f57080 00001ffe`6d0a8f78 00000000`03508021 fffff800`c896b748 : WinUSB!WinUSB_DeviceControl+0x3a5
02 ffffd000`234c6460 fffff800`c88f6123 : ffffe001`90261c00 ffffd000`234c6500 ffffe001`9490ce00 00000000`00000001 : Wdf01000!FxIoQueue::DispatchRequestToDriver+0x1be
03 ffffd000`234c6530 fffff800`c8902279 : ffffe001`90261c20 ffffe001`92f57000 00000000`00000000 ffffd000`234c66d9 : Wdf01000!FxIoQueue::DispatchEvents+0x363
04 ffffd000`234c65f0 fffff800`c88fad93 : ffffcf80`26e38700 ffffe001`92f57080 ffffcf80`26e38750 ffffcf80`26e38750 : Wdf01000!FxIoQueue::QueueRequest+0x8d
05 ffffd000`234c6660 fffff800`c86cc832 : 00000000`00020000 ffffd000`234c6700 ffffe001`9085fb70 fffff800`c88fa240 : Wdf01000!FxDevice::DispatchWithLock+0xb51
06 ffffd000`234c6740 fffff802`33b03911 : ffffcf80`26e38750 00000000`00000002 ffffe001`94267860 00000000`00000000 : VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xfe
07 ffffd000`234c67a0 fffff802`33b1fec9 : ffffcf80`26e38750 ffffe001`901819f0 00000000`00000002 ffffe001`93e8e7c0 : nt!IovCallDriver+0x3cd
08 ffffd000`234c67f0 fffff802`33b03911 : ffffe001`90181b40 ffffcf80`26e38750 ffffe001`901819f0 00000000`00000001 : nt!ViFilterDispatchGeneric+0xd1
09 ffffd000`234c6830 fffff802`3385115f : 00000000`00000000 ffffd000`234c6b80 ffffcf80`26e38750 ffffe001`947eca60 : nt!IovCallDriver+0x3cd
0a ffffd000`234c6880 fffff802`33852a76 : 00000000`00000000 00000000`03b830f4 00000000`00000000 00000000`00ef3110 : nt!IopXxxControlFile+0xa4f
0b ffffd000`234c6a20 fffff802`335e79b3 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtDeviceIoControlFile+0x56
0c ffffd000`234c6a90 00007ffb`1ecf16ea : 00007ffb`1c3db805 00000000`000003e5 00000000`026bbb90 00000000`0377f614 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd000`234c6b00)
0d 00000000`0377f5e8 00007ffb`1c3db805 : 00000000`000003e5 00000000`026bbb90 00000000`0377f614 00000000`00000000 : ntdll!NtDeviceIoControlFile+0xa
0e 00000000`0377f5f0 00007ffb`1cef2470 : 00000000`03508021 00007ffb`00000103 00000000`00ef0000 00000000`0000000a : KERNELBASE!DeviceIoControl+0x103
0f 00000000`0377f660 00007ffb`16572cbd : 00000000`0038dc30 00007ffb`1c3d4f4f 00000000`0377f7b0 00000000`00000000 : KERNEL32!DeviceIoControlImplementation+0x74
10 00000000`0377f6b0 00000000`00cc45d6 : 00000000`00ef0200 00000000`0377f702 00000000`00ef2ec0 00000000`038830b8 : WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d
11 00000000`0377f730 00000000`00cc4c1f : 00000000`00000000 00000003`03000400 0000c299`caf3775a 00000000`00ef2ec0 : xxmgr+0x145d6
12 00000000`0377f7f0 00000000`00cd0e45 : 00000000`026bb4d0 00000000`00000000 00000000`00000001 00000000`00000000 : xxmgr+0x14c1f
13 00000000`0377f850 00000000`00cce23d : 00000000`00ef14c0 00000000`0377f919 00000000`00020d00 00000000`0038a0cc : xxmgr+0x20e45
14 00000000`0377f890 00000000`00cd28c7 : 00000000`00000300 00000000`00000020 00000000`00000004 00000000`026bb398 : xxmgr+0x1e23d
15 00000000`0377f980 00000000`00ccf42f : 00000000`00000000 00000000`00ef2dd0 00000000`00000000 00000000`00ef14c0 : xxmgr+0x228c7
16 00000000`0377f9e0 00000000`00ccc72b : 00000000`026bbc80 00000000`00000000 00000000`00000000 00000000`00000000 : xxmgr+0x1f42f
17 00000000`0377fa40 00000000`00cc2744 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : xxmgr+0x1c72b
18 00000000`0377fa80 00007ffb`1cef16ad : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : xxmgr+0x12744
19 00000000`0377fac0 00007ffb`1ecb4409 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0xd
1a 00000000`0377faf0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
这里注意,栈帧0和10都有WinUSB_WritePipe的字样,但到底是哪一个呢:
从这两处栈帧的EBP情况看,0帧是处于内核态的(事实上,就是WinUSB.sys), 10帧是处于用户态的(WinUSB.dll).
笔者发现,在视频驱动准备数据处的断点HIT时,数据BUFFER的指针为:00000000`038830b8
而10号栈帧,第四个参数也是00000000`038830b8, 这就说明,私有驱动在这一次断点(bp WinUSB!WinUSB_WritePipe)HIT时,将数据包交给了WinUSB, 并没有改变视频数据BUFFER的起始地址(这是一次正确的情况)。
有了这样的调试方法,后面可以深入追踪这个问题的根源(可能会涉及到对xHCI USB3.0驱动设断点,参考前三篇博文的符号列表)。
当然,设定WinUSB_WritePipe是最基本的,之后的问题追踪,需要更多的WinDbg内核调试技巧。
其中有一点疑惑的是:
MSDN查找WinUSB_WritePipe的文档
http://msdn.microsoft.com/zh-cn/library/ff540322(v=vs.85).aspx
BOOL __stdcall WinUsb_WritePipe( _In_ WINUSB_INTERFACE_HANDLE InterfaceHandle, _In_ UCHAR PipeID, _In_ PUCHAR Buffer, _In_ ULONG BufferLength, _Out_opt_ PULONG LengthTransferred, _In_opt_ LPOVERLAPPED Overlapped );
第三个参数是视频BUFFER的指针,(视频数据包的长度为0x300040)
而栈帧10中, (00000000`038830b8 视频数据BUFFER指针)却是第四个参数(其实,这里是以x86函数调用的方式来思考问题,得出BUFFER指针为第四个参数的错误结论)。
# Child-SP RetAddr : Args to Child : Call Site
10 00000000`0377f6b0 00000000`00cc45d6 : 00000000`00ef0200 00000000`0377f702 00000000`00ef2ec0 00000000`038830b8 : WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d
一时间,对这个问题没有太好的解答,后来突然一想,目标机是X64的平台,会不会函数调用方式与X86有不同之处呢?
查找WinDbg文档发现:
Calling Conventions
Unlike the x86, the C/C++ compiler only supports one calling convention on x64. This calling convention takes advantage of the increased number of registers available on x64:
- The first four integer or pointer parameters are passed in the rcx,
rdx, r8, and r9 registers. - The first four floating-point parameters are passed in the first four SSE registers,
xmm0-xmm3. - The caller reserves space on the stack for arguments passed in registers. The called function can use this space to spill the contents of registers to the stack.
- Any additional arguments are passed on the stack.
- An integer or pointer return value is returned in the rax register, while a floating-point return value is returned in
xmm0. - rax, rcx, rdx, r8-r11 are volatile.
- rbx, rbp, rdi, rsi,
r12-r15 are nonvolatile.
The calling convention for C++ is very similar: the this pointer is passed as an implicit first parameter. The next three parameters are passed in registers, while the rest are passed on the stack.
确实,与X86有很大的不同,X64统一了一种函数调用方式,从以上文档可以看出,前四个参数,是以寄存器rcx, rdx, r8, and r9来传递的。
于是,切换到10栈帧,看当时的寄存器情况:
3: kd> .frame /r 0x10
10 00000000`0377f6b0 00000000`00cc45d6 WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d
rax=0000000000000000 rbx=000000000038dc30 rcx=ffffe0019085fe60
rdx=ffffe001908bdf84 rsi=0000000000000000 rdi=0000000000ef3110
rip=00007ffb16572cbd rsp=000000000377f6b0 rbp=000000000377f7b0
r8=00001ffe6ca109a8 r9=ffffd000234c6420 r10=000000000000001c
r11=ffffe001908bd080 r12=0000000000300040 r13=00000000038830b8
r14=000000000377f764 r15=0000000000380580
iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000286
WinUsb_7ffb16570000!WinUsb_WritePipe+0x10d:
00007ffb`16572cbd 8bd8 mov ebx,eax
我们看到视频数据BUFFER指针与长度分别由以下寄存器传递:
r13=00000000038830b8
r12=0000000000300040
而
rcx=ffffe0019085fe60
rdx=ffffe001908bdf84
r8=00001ffe6ca109a8
r9=ffffd000234c6420
这四个寄存中,既没有看到正确的长度值,也没有BUFFER指针。
笔者得出结论,可能X64的函数调用方式,在新型的计算机中,使用了别的寄存器,取代了rcx, rdx, r8, and r9。
列出X86的函数调用方式:
Calling Conventions
The x86 architecture has several different calling conventions. Fortunately, they all follow the same register preservation and function return rules:
- Functions must preserve all registers, except for eax,
ecx, and edx, which can be changed across a function call, and
esp, which must be updated according to the calling convention. - The eax register receives function return values if the result is 32 bits or smaller. If the result is 64 bits, then the result is stored in the
edx:eax pair.
The following is a list of calling conventions used on the x86 architecture:
- Win32 (__stdcall)
Function parameters are passed on the stack, pushed right to left, and the callee cleans the stack.
- Native C++ method call (also known as thiscall)
Function parameters are passed on the stack, pushed right to left, the "this" pointer is passed in the
ecx register, and the callee cleans the stack. - COM (__stdcall for C++ method calls)
Function parameters are passed on the stack, pushed right to left, then the "this" pointer is pushed on the stack, and then the function is called. The callee cleans the stack.
- __fastcall
The first two DWORD-or-smaller arguments are passed in the ecx and
edx registers. The remaining parameters are passed on the stack, pushed right to left. The callee cleans the stack. - __cdecl
Function parameters are passed on the stack, pushed right to left, and the caller cleans the stack. The
__cdecl calling convention is used for all functions with variable-length parameters.