lixxu

如何得知 USB设备接在哪个端口?

网上抄的, 话说 不懂 mfc的人压力很大啊
 
import struct
import win32file
import win32api
import win32con
import pywintypes


IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424
IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408
IOCTL_USB_GET_NODE_INFORMATION = 0x220408
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION = 0x22040C
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME = 0x220420
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0x220410
USB_STRING_DESCRIPTOR_TYPE = 3
MAXIMUM_USB_STRING_LENGTH = 255
NoDeviceConnected = 0
DeviceConnected = 1


def getRootHubName(handle):
    buffer = win32file.DeviceIoControl(
            handle,
            IOCTL_USB_GET_ROOT_HUB_NAME,
            None,
            6,
            None)
    #print len(buffer), type(buffer), [ord(i) for i in buffer]
    actualLength, t = struct.unpack(\'LH\', buffer)


    buffer = win32file.DeviceIoControl(
            handle,
            IOCTL_USB_GET_ROOT_HUB_NAME,
            None,
            actualLength,
            None)
    #print len(buffer), type(buffer), [ord(i) for i in buffer]
    return buffer[4:].decode(\'utf-16le\')


def getHCDDriverKeyName(handle):
    buffer = win32file.DeviceIoControl(
            handle,
            IOCTL_GET_HCD_DRIVERKEY_NAME,
            None,
            6,
            None)
    actualLength, t = struct.unpack(\'LH\', buffer)
    buffer = win32file.DeviceIoControl(
            handle,
            IOCTL_GET_HCD_DRIVERKEY_NAME,
            None,
            actualLength,
            None)
    return buffer[4:].decode(\'utf-16le\')


def getDriverKeyName(handle, index):
    driverKeyName = chr(index)+\'\0\'*9
    try:
        buffer = win32file.DeviceIoControl(
                handle,
                IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
                driverKeyName,
                10,
                None)
    except pywintypes.error as e:
        print e.strerror, index
        raw_input(\'Press Enter...\')
        exit(1)


    connectIndex, actualLength, t = struct.unpack(\'LLH\', buffer)
    buffer = win32file.DeviceIoControl(
            handle,
            IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
            driverKeyName,
            actualLength,
            None)
    return buffer[8:].decode(\'utf-16le\')




def openDevice(deviceName):
    try:
        handle = win32file.CreateFile( deviceName,
                win32file.GENERIC_WRITE,
                win32file.FILE_SHARE_WRITE,
                None,
                win32file.OPEN_EXISTING,
                0,
                None)
    except pywintypes.error as e:
        #print e.strerror, name
        raw_input(\'Press Enter...\')
        exit(1)
    return handle


def getStringDescriptor(handle, connectionIndex, serialNumber):
    stringDescReq = struct.pack(\'LBBHHH\',
            connectionIndex,
            0,
            0,
            (USB_STRING_DESCRIPTOR_TYPE<<8)|serialNumber,
            win32api.GetSystemDefaultLangID(),
            12
            )
    try:
        buffer = win32file.DeviceIoControl(
                handle,
                IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
                stringDescReq,
                12+MAXIMUM_USB_STRING_LENGTH,
                None)




        if len(buffer)>16:
            print buffer[14:]#.decode(\'utf-16le\')
    except pywintypes.error as e:
        print e.strerror
    #print len(buffer[12:]), \'len\'
    #print [ord(i) for i in buffer[12:]]


for i in range(10):
    name = r"\\.\HCD{}".format(i)
    try:
        handle = win32file.CreateFile( name,
                win32file.GENERIC_WRITE,
                win32file.FILE_SHARE_WRITE,
                None,
                win32file.OPEN_EXISTING,
                0,
                None)
    except pywintypes.error as e:
        #print e.strerror, name
        break
    print \'\nDriverKey:\', getHCDDriverKeyName(handle)
    rootHubName = getRootHubName(handle)
    print \'\n    RootHub\n\'
    print \'    {}\n\'.format(rootHubName)
    deviceName = r\'\\.\{}\'.format(rootHubName)
    deviceHandle = openDevice(deviceName)
    buffer = win32file.DeviceIoControl(
            deviceHandle,
            IOCTL_USB_GET_NODE_INFORMATION,
            None,
            76, # sizeof USB_NODE_INFORMATION
            None)
    numberOfPorts = ord(buffer[6])
    #print numberOfPorts
    for index in range(1, numberOfPorts+1):
        connectionInfo = chr(index)+\'\0\'*34
        try:
            buffer = win32file.DeviceIoControl(
                    deviceHandle,
                    IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
                    connectionInfo,
                    34+11*30, #note
                    None)
        except pywintypes.error as e:
            print e.winerror, e.funcname, e.strerror
            #exit()
        #print [ord(i) for i in buffer]
        if ord(buffer[31]) == NoDeviceConnected: ##why
            print \'    [Port{}]{}\'.format(index, \'NoDeviceConnected\')


        if ord(buffer[31]) == DeviceConnected:
            print \'    [Port{}]{}\'.format(index, getDriverKeyName(deviceHandle, index))
            serialNumber = ord(buffer[20])
            getStringDescriptor(deviceHandle, index, serialNumber)


    deviceHandle.close()
    handle.close()


raw_input(\'Press Enter...\')





分类:

技术点:

相关文章: