線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:9716
推到 Plurk!
推到 Facebook!

偵測USB裝置插入哪一個USB Port插槽

 
blk5743
高階會員


發表:34
回覆:371
積分:236
註冊:2003-11-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-05 15:40:00 IP:61.66.xxx.xxx 未訂閱
這個程式已經得到作者的允許,如果要在轉載至其他網站,請先經過作者同意 此程式是用VC寫的,不過稍加修改一下就可以在BCB執行    作者說會有The USBView.exe sample program does not enumerate devices on pre-Windows XP SP1-based computers的問題 http://support.microsoft.com/default.aspx?scid=kb;en-us;838100 但是我在XP SP1,SP2都沒發現有什麼大問題 但是程式碼中的sizeof(NodeInformation)的長度會算錯 (正確為76,但是我的兩台電腦均為73) 同時在NodeInformation.HubDescriptor會塞進三個Byte "0",因此所有結構的內容都會Offset 3 bytes.因此會得到錯誤的bNumberOfPorts 以上錯誤不知為何會出現,不過用小技巧避開後即可正常執行,也希望能有高手可以解答我這個問題
 
// This version of DisplayUSB.cpp was derived from an example program first
// published by John Hyde in his book
// USB Design by Example, 2nd Edition
// A Practical Guide to Building I/O Devices
//
// It is Copyright (C) 2004,  John Hyde and published with his permission
//
// Permission is hereby granted to merge this program code with other program 
// material to create a derivative work.  This derivative work may be distributed
// in compiled object form only. Any other publication of this program, in any form,
// without the explicit permission of the copyright holder is prohibited.
//
// Send questions and comments to John@USB-By-Example.com    #include "stdafx.h"
#include "objbase.h"
#include "winioctl.h"
#include "usbioctl.h"
#include "stdio.h"
#include "stdlib.h"    bool DEBUG; // Set to true to enable DEBUG messages 
SECURITY_ATTRIBUTES SA;  // Needed for Win2000    const char ClassName[] [20] = {
        "Reserved",                        "Audio",                                "Communications",                "Human Interface",
        "Monitor",                        "Physical Interface",        "Power",                                "Printer",
        "Storage",                        "Hub",                                        "Vendor Specific",                "*ILLEGAL VALUE*"
        };    const char ConnectionStatus[] [30] = {
        "No device connected",                        "Device connected",                                        "Device FAILED enumeration",
        "Device general FAILURE",                "Device caused overcurrent",                "Not enough power for device"
        };    // Define all stuctures using UCHAR or BOOLEAN so that the variables are not 'aligned' by the compiler
typedef struct DESCRIPTOR_REQUEST {
    ULONG ConnectionIndex;
    struct {UCHAR bmRequest; UCHAR bRequest; UCHAR wValue[2]; UCHAR wIndex[2]; UCHAR wLength[2];} SetupPacket;
    UCHAR Data[2048];
        };            typedef struct DEVICE_DESCRIPTOR {
    UCHAR bLength;                                        UCHAR bDescriptorType;                                UCHAR bcdUSB[2];
    UCHAR bDeviceClass;                                UCHAR bDeviceSubClass;                                UCHAR bDeviceProtocol;
    UCHAR bMaxPacketSize0;                        UCHAR idVendor[2];                                        UCHAR idProduct[2];
    UCHAR bcdDevice[2];                                UCHAR iManufacturer;                                UCHAR iProduct;
    UCHAR iSerialNumber;                        UCHAR bNumConfigurations;
        };    typedef struct HUB_DESCRIPTOR {
    UCHAR bDescriptorLength;                UCHAR bDescriptorType;                                UCHAR bNumberOfPorts;
        UCHAR wHubCharacteristics[2];        UCHAR bPowerOnToPowerGood;                        UCHAR bHubControlCurrent;
    UCHAR bRemoveAndPowerMask[64];      
        };    typedef struct NODE_INFORMATION {
    USB_HUB_NODE NodeType;                        HUB_DESCRIPTOR HubDescriptor;                BOOLEAN HubIsBusPowered;
        };     typedef struct NODE_CONNECTION_INFORMATION {
    ULONG ConnectionIndex;                        DEVICE_DESCRIPTOR DeviceDescriptor;        UCHAR CurrentConfigurationValue;
    BOOLEAN LowSpeed;                                BOOLEAN DeviceIsHub;                                UCHAR DeviceAddress[2];
    UCHAR NumberOfOpenPipes[4];                UCHAR ConnectionStatus[4];                        USB_PIPE_INFO PipeList[32];
        };    USHORT DisplayStringDescriptor (HANDLE HubHandle, ULONG PortIndex, USHORT LanguageID, UCHAR Index) {
        if (DEBUG) printf("\nIn DisplayStringDescriptor with HubHandle = %x, PortIndex = %x, LanguageID = %x, Index = %x\n",
                HubHandle, PortIndex, LanguageID, Index);
        DESCRIPTOR_REQUEST Packet;
        DWORD BytesReturned;
        bool Success;
        if (LanguageID == 0) {                        // Get the language ID
                memset(&Packet, 0, sizeof(Packet));
                Packet.ConnectionIndex = PortIndex;
                Packet.SetupPacket.bmRequest = 0x80;
                Packet.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
                Packet.SetupPacket.wValue[1] = USB_STRING_DESCRIPTOR_TYPE;
                Packet.SetupPacket.wLength[0] = 4;
                Success = DeviceIoControl(HubHandle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &Packet,
                        sizeof(Packet), &Packet, sizeof(Packet), &BytesReturned, NULL);
                if (!Success) printf(" *** ERROR *** String Descriptor 0 not returned, ErrorCode = %d\n", GetLastError());
                LanguageID = Packet.Data[2]   (Packet.Data[3] << 8);
                }
        memset(&Packet, 0, sizeof(Packet));
        Packet.ConnectionIndex = PortIndex;
        Packet.SetupPacket.bmRequest = 0x80;
        Packet.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
        Packet.SetupPacket.wValue[1] = USB_STRING_DESCRIPTOR_TYPE;
        Packet.SetupPacket.wValue[0] = Index;
        Packet.SetupPacket.wIndex[0] = LanguageID & 0xFF;
        Packet.SetupPacket.wIndex[1] = (LanguageID >> 8) & 0xFF;
        Packet.SetupPacket.wLength[0] = 255;
        Success = DeviceIoControl(HubHandle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &Packet,
                sizeof(Packet), &Packet, sizeof(Packet), &BytesReturned, NULL);
        if (!Success) printf(" *** ERROR *** String Descriptor %d not returned. ErrorCode = %d\n", Index, GetLastError());
        printf(" = %ws", &Packet.Data[2]);
        return LanguageID;
        }    USHORT DisplayDeviceDescriptor (HANDLE HubHandle, ULONG PortIndex, USHORT LanguageID, PUCHAR BufferPtr) {
        if (DEBUG) printf("In DisplayDeviceDescriptor with HubHandle = %x, PortIndex = %x, LanguageID = %x\n", HubHandle, PortIndex, LanguageID);
        UCHAR LowByte;
        printf("Device Descriptor");
        BufferPtr--;  // Backup pointer to prepare for pre-increment
        printf("\n  bLength             %2.2x", *  BufferPtr);
        printf("\n  bDescriptorType     %2.2x", *  BufferPtr);
        LowByte = *  BufferPtr;
        printf("\n  bcdUSB            %4.4x", LowByte   (*  BufferPtr << 8));
        printf("\n  bDeviceClass        %2.2x", *  BufferPtr);
        printf("\n  bDeviceSubClass     %2.2x", *  BufferPtr);
        printf("\n  bDeviceProtocol     %2.2x", *  BufferPtr);
        printf("\n  bMaxEP0Size         %2.2x", *  BufferPtr);
        LowByte = *  BufferPtr;
        printf("\n  wVendorID         %4.4x", LowByte   (*  BufferPtr << 8));
        LowByte = *  BufferPtr;
        printf("\n  wProductID        %4.4x", LowByte   (*  BufferPtr << 8));
        LowByte = *  BufferPtr;
        printf("\n  wDeviceID         %4.4x", LowByte   (*  BufferPtr << 8));
        printf("\n  iManufacturer       %2.2x", *  BufferPtr);
        if (*BufferPtr != 0) LanguageID = DisplayStringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr);
        printf("\n  iProduct            %2.2x", *  BufferPtr);
        if (*BufferPtr != 0) LanguageID = DisplayStringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr);
        printf("\n  iSerialNumber       %2.2x", *  BufferPtr);
        if (*BufferPtr != 0) LanguageID = DisplayStringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr);
        printf("\n  bNumConfigurations  %2.2x\n", *  BufferPtr);
        return LanguageID;
        }    USHORT DisplayConfigurationDescriptor(HANDLE HubHandle, ULONG PortIndex, USHORT LanguageID) {
        if (DEBUG) printf("In DisplayConfigurationDescriptor with HubHandle = %x, PortIndex = %x, LanguageID = %x\n", HubHandle, PortIndex, LanguageID);
        DWORD BytesReturned;
        bool Success;
        UCHAR LowByte;
        DESCRIPTOR_REQUEST Packet;
        int i;
        printf("\nConfiguration Descriptor");
//  First need to get the configuration descriptor
        memset(&Packet, 0, sizeof(Packet));
        Packet.ConnectionIndex = PortIndex;
        Packet.SetupPacket.bmRequest = 0x80;
        Packet.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
        Packet.SetupPacket.wValue[1] = USB_CONFIGURATION_DESCRIPTOR_TYPE;
        Packet.SetupPacket.wLength[1] = 1;        // Using a 2K buffer
        Success = DeviceIoControl(HubHandle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &Packet,
                sizeof(Packet), &Packet, sizeof(Packet), &BytesReturned, NULL);
        if (!Success) printf(" *** ERROR *** Configuration Descriptor not returned. ErrorCode = %d\n", GetLastError());
        PUCHAR BufferPtr = &Packet.Data[0];
        UCHAR Length = *BufferPtr;
        while (Length != 0) {
                UCHAR Type = *  BufferPtr;
                switch (Type) {
                case 2:
                        printf("\n  bLength             %2.2x", Length);
                        printf("\n  bDescriptorType     %2.2x = Configuration Header", Type);
                        LowByte = *  BufferPtr;
                        printf("\n  wTotalLength      %4.4x", LowByte   (*  BufferPtr << 8));
                        printf("\n  bNumInterfaces      %2.2x", *  BufferPtr);
                        printf("\n  bConfigValue        %2.2x", *  BufferPtr);
                        printf("\n  iConfiguration      %2.2x", *  BufferPtr);
                        if (*BufferPtr != 0) LanguageID = DisplayStringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr);
                        printf("\n  bmAttributes        %2.2x", *  BufferPtr);
                        LowByte = *  BufferPtr;
                        printf("\n  bMaxPower           %2.2x = %d mA", LowByte, (LowByte << 1));
                        break;
                case 4:
                        printf("\n  bLength             %2.2x", Length);
                        printf("\n  bDescriptorType     %2.2x = Interface Descriptor", Type);
                        printf("\n  bInterfaceNum       %2.2x", *  BufferPtr);
                        printf("\n  bAlternateSetting   %2.2x", *  BufferPtr);
                        printf("\n  bNumEndpoints       %2.2x", *  BufferPtr);
                        LowByte = *  BufferPtr;
                        if ((LowByte > 9) & (LowByte < 255)) LowByte = 11;
                        if (LowByte == 255) LowByte = 10;
                        printf("\n  bInterfaceClass     %2.2x = %s", *BufferPtr, ClassName[LowByte]);
                        printf("\n  bSubClass           %2.2x", *  BufferPtr);
                        printf("\n  bProtocol           %2.2x", *  BufferPtr);
                        printf("\n  iInterface          %2.2x", *  BufferPtr);
                        if (*BufferPtr != 0) LanguageID = DisplayStringDescriptor(HubHandle, PortIndex, LanguageID, *BufferPtr);
                        break;
                case 5:
                        printf("\n  bLength             %2.2x", Length);
                        printf("\n  bDescriptorType     %2.2x = Endpoint Descriptor", Type);
                        printf("\n  bEndpointAddress    %2.2x", *  BufferPtr);
                        printf("\n  bmAttributes        %2.2x", *  BufferPtr);
                        LowByte = *  BufferPtr;
                        printf("\n  wMaxPacketSize    %4.4x", LowByte   (*  BufferPtr << 8));
                        printf("\n  bInterval           %2.2x", *  BufferPtr);
                        break;                
                case 0x21:
                        printf("\n  bLength             %2.2x", Length);
                        printf("\n  bDescriptorType     %2.2x = HID Descriptor", Type);
                        LowByte = *  BufferPtr;
                        printf("\n  wHIDversion       %4.4x", LowByte   (*  BufferPtr << 8));
                        printf("\n  bCountryCode        %2.2x", *  BufferPtr);
                        printf("\n  bHIDDescriptorCount %2.2x", *  BufferPtr);
                        printf("\n  bHIDReportType      %2.2x", *  BufferPtr);
                        LowByte = *  BufferPtr;
                        printf("\n  wHIDReportLength  %4.4x", LowByte   (*  BufferPtr << 8));
                        break;
                default:
                        printf("\nUnknown descriptor with Length = %2.2xH and Type = %2.2xH", Length, Type);
                        BufferPtr-=2;  // Back up to start of descriptor
                        for (i = 0; i < Length; i  ) {
                                if ((i % 16) == 0) printf("\n");
                                printf("%2.2x ", *  BufferPtr);
                                }
                        break;
                        }
                Length = *  BufferPtr;
                printf("\n");
                }
        return LanguageID;
        }    void GetPortData(HANDLE HubHandle, UCHAR PortCount, int HubDepth) {
        if (DEBUG) printf("In GetPortData with HubHandle = %x, PortCount = %x, HubDepth = %x\n", HubHandle, PortCount, HubDepth);
        DWORD BytesReturned;
        bool Success;
        int i;
        ULONG PortIndex;
        USHORT LanguageID;
        UCHAR ThisDevice, PortStatus;
        char ConnectedHubName[256] = "\\\\.\\";
        HANDLE ConnectedHubHandle;
        NODE_INFORMATION NodeInformation;
        NODE_CONNECTION_INFORMATION ConnectionInformation;
        struct {ULONG ConnectionIndex; ULONG ActualLength; WCHAR Name[256];} ConnectedHub;    // Iterate over the ports to discover what is connected to each one
        for (PortIndex = 1; PortIndex < (ULONG)PortCount   1; PortIndex  ) {
                LanguageID = 0;  // Reset for each port
                ConnectionInformation.ConnectionIndex = PortIndex;
                Success = DeviceIoControl(HubHandle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, &ConnectionInformation,
                        sizeof(ConnectionInformation), &ConnectionInformation, sizeof(ConnectionInformation), &BytesReturned, NULL);
                if (!Success) printf(" *** ERROR *** Node connection information not returned\n");
        
                PortStatus = ConnectionInformation.ConnectionStatus[0];  // Save some typing!
                ThisDevice = (PortStatus == DeviceConnected) ? ConnectionInformation.DeviceAddress[0] : 0;    // Create an indented display so that hubs and their connections are more easily seen
//   First the common header
//                printf("%2.2x", ThisDevice);
                for (i=0; i     
        
附加檔案:59211_DUSBVC.zip
ctx62
一般會員


發表:4
回覆:28
積分:6
註冊:2002-12-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-09 09:47:24 IP:218.12.xxx.xxx 未訂閱
那位高手能把它翻譯成delphi
st
一般會員


發表:11
回覆:21
積分:11
註冊:2004-07-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-12 16:48:54 IP:211.75.xxx.xxx 未訂閱
請參考拙作 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=57122 寫程式與攝影一樣重要
jemin121
一般會員


發表:2
回覆:4
積分:1
註冊:2005-01-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-01-21 16:07:26 IP:210.243.xxx.xxx 未訂閱
BCB長度算錯的問題可依下列方式設定 Project->Options->Compiler->將Treat enum types as ints打勾即可
tccman
一般會員


發表:0
回覆:11
積分:2
註冊:2005-02-17

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-02-20 03:16:29 IP:218.172.xxx.xxx 未訂閱
◥██◣ ╭╭╮謝謝你的分享! 田︱田田| ╰-------------- ╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
blk5743
高階會員


發表:34
回覆:371
積分:236
註冊:2003-11-17

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-01 09:03:34 IP:61.66.xxx.xxx 未訂閱
有人寫信問我在哪找到這CODE 請參考    http://www.intel.com/intelpress/usb/examples/download.htm
blk5743
高階會員


發表:34
回覆:371
積分:236
註冊:2003-11-17

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-04-01 09:32:36 IP:61.66.xxx.xxx 未訂閱
引言: 但是程式碼中的sizeof(NodeInformation)的長度會算錯 (正確為76,但是我的兩台電腦均為73) 同時在NodeInformation.HubDescriptor會塞進三個Byte "0",因此所有結構的內容都會Offset 3 bytes.因此會得到錯誤的bNumberOfPorts 以上錯誤不知為何會出現,不過用小技巧避開後即可正常執行,也希望能有高手可以解答我這個問題
到Project->Option->Advanced Compiler->Data Alignment 選擇Byte 這是因為Compiler最佳化的緣故 因為我們的OS大部份都是32位元的 所以他會用四個Bytes(32bits)為一個單位 如果是一個Byte,為了快數存取,也會當作4Bytes 所以用sizeof時會算錯
系統時間:2024-05-04 9:20:49
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!