| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3593 人关注过本帖
标题:在VF6.0中如何实现获取新插入U盘的序列号?
只看楼主 加入收藏
wangbaoping
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2017-7-1
结帖率:0
收藏
已结贴  问题点数:20 回复次数:9 
在VF6.0中如何实现获取新插入U盘的序列号?
在VF6.0中如何实现获取新插入U盘的序列号和生产厂商?要编程实现对外接U盘的有效控制。

[此贴子已经被作者于2017-7-1 13:38编辑过]

搜索更多相关主题的帖子: 获取 插入 序列号 编程 控制 
2017-07-01 13:36
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10609
专家分:43210
注 册:2014-5-20
收藏
得分:4 
参考:
图片附件: 游客没有浏览图片的权限,请 登录注册

WIN10+VFP9调试,有些函数或命令VFP6不支持,要自己写相应的功能函数。

**
** 枚举USB设备获取USB序列号
**
CLEAR

#DEFINE GENERIC_WRITE       0x40000000
#DEFINE FILE_SHARE_WRITE    0x00000002
#DEFINE OPEN_EXISTING       3

#DEFINE INVALID_HANDLE_VALUE    -1
#DEFINE BUFFER_SIZE             2048

#DEFINE FILE_DEVICE_USB                            0x00000022
#DEFINE HCD_GET_DRIVERKEY_NAME                     265
#DEFINE HCD_GET_ROOT_HUB_NAME                      258
#DEFINE USB_GET_NODE_INFORMATION                   258
#DEFINE USB_GET_NODE_CONNECTION_INFORMATION        259
#DEFINE USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION    260
#DEFINE USB_GET_NODE_CONNECTION_NAME               261
#DEFINE METHOD_BUFFERED                            0
#DEFINE FILE_ANY_ACCESS                            0

#DEFINE IOCTL_GET_HCD_DRIVERKEY_NAME                     CTL_CODE(FILE_DEVICE_USB,;
                                                                  HCD_GET_DRIVERKEY_NAME,;
                                                                  METHOD_BUFFERED,;
                                                                  FILE_ANY_ACCESS)

#DEFINE IOCTL_USB_GET_ROOT_HUB_NAME                      CTL_CODE(FILE_DEVICE_USB,;
                                                                  HCD_GET_ROOT_HUB_NAME,;
                                                                  METHOD_BUFFERED,;
                                                                  FILE_ANY_ACCESS)

#DEFINE IOCTL_USB_GET_NODE_INFORMATION                   CTL_CODE(FILE_DEVICE_USB,;
                                                                  USB_GET_NODE_INFORMATION,;
                                                                  METHOD_BUFFERED,;
                                                                  FILE_ANY_ACCESS)

#DEFINE IOCTL_USB_GET_NODE_CONNECTION_INFORMATION        CTL_CODE(FILE_DEVICE_USB,;
                                                                  USB_GET_NODE_CONNECTION_INFORMATION,;
                                                                  METHOD_BUFFERED,;
                                                                  FILE_ANY_ACCESS)

#DEFINE IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION    CTL_CODE(FILE_DEVICE_USB,;
                                                                  USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,;
                                                                  METHOD_BUFFERED,;
                                                                  FILE_ANY_ACCESS)

#DEFINE IOCTL_USB_GET_NODE_CONNECTION_NAME               CTL_CODE(FILE_DEVICE_USB,;
                                                                  USB_GET_NODE_CONNECTION_NAME,;
                                                                  METHOD_BUFFERED,;
                                                                  FILE_ANY_ACCESS)

#DEFINE USB_STRING_DESCRIPTOR_TYPE    0x03

DECLARE LONG CreateFile             IN Kernel32 STRING@, LONG, LONG, STRING@, LONG, LONG, LONG
DECLARE LONG CloseHandle            IN Kernel32 LONG
DECLARE LONG DeviceIoControl        IN Kernel32 LONG, LONG, STRING@, LONG, STRING@, LONG, LONG@, LONG
DECLARE LONG GetSystemDefaultLangID IN Kernel32

CREATE CURSOR dt (Property C(10), Value C(50))

EnumUsbDevice()
GO TOP
BROWSE
CLEAR DLLS
RETURN

FUNCTION CTL_CODE(DeviceType, Function, Method, Access)
    * #define CTL_CODE(DeviceType, Function, Method, Access) (
    *     ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
    * )
    RETURN BITOR(BITLSHIFT(DeviceType, 16), BITLSHIFT(Access, 14), BITLSHIFT(Function, 2), Method)
ENDFUNC

FUNCTION EnumUsbDevice()
    LOCAL i, hHCD, szHCDPath, szHUBName
   
    FOR i = 0 TO 9            && 假定最多有10个主控
        szHCDPath = "\\.\HCD" + TRANSFORM(i)

        hHCD = CreateFile(@szHCDPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0)
            
        IF hHCD == INVALID_HANDLE_VALUE
            EXIT
        ENDIF
        
        szHUBName = GetHUBName(hHCD)
            
        IF !ISNULL(szHUBName)
            GetHUB(szHUBName)    && 取集线器数据
        ENDIF

        CloseHandle(hHCD)
    ENDFOR
ENDFUNC
            
FUNCTION GetHUB(szHUBName)
    LOCAL i, hHUB, szHUBPath, szBuffer, dwReturnedSize, dbPorts
   
    szHUBPath = "\\.\" + szHUBName
    hHUB      = CreateFile(@szHUBPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0)
               
    IF hHUB != INVALID_HANDLE_VALUE
        szBuffer       = REPLICATE(0h00, BUFFER_SIZE)
        dwReturnedSize = 0

        IF DeviceIoControl(hHUB,;
                           IOCTL_USB_GET_NODE_INFORMATION,;
                           @szBuffer, BUFFER_SIZE,;
                           @szBuffer, BUFFER_SIZE,;
                           @dwReturnedSize,;
                           0) != 0
                           
                * USB_NODE_INFORMATION 结构
                * 端口数,dbPports = szBuffer->u.HubInformation.HubDescriptor.bNumberOfPorts
            dbPorts = CTOBIN(SUBSTR(szBuffer, 7, 1), "1RS")
            
            FOR i = 1 TO dbPorts
                GetHUBPort(hHUB, i)    && 取各端口数据
            ENDFOR
        ENDIF
                           
        CloseHandle(hHUB)
    ENDIF
ENDFUNC

FUNCTION GetHUBPort(hHUB, dbPortIndex)
    LOCAL szBuffer, dwReturnedSize, ddConnectionIndex
    LOCAL iManufacturer, iProduct, iSerialNumber, idVendor, idProduct, bcdDevice
    LOCAL DeviceIsHub, ConnectionStatus

        * USB_NODE_CONNECTION_INFORMATION 结构
        * 端口号,szBuffer->ConnectionIndex = dbPortIndex
    szBuffer       = BINTOC(dbPortIndex, "4RS") + REPLICATE(0h00, BUFFER_SIZE - 4)
    dwReturnedSize = 0
                        
    IF DeviceIoControl(hHUB,;
                       IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,;
                       @szBuffer, BUFFER_SIZE,;
                       @szBuffer, BUFFER_SIZE,;
                       @dwReturnedSize,;
                       0) != 0
                       
        ddConnectionIndex = CTOBIN(LEFT(szBuffer, 4), "4RS")
                           
        IF ddConnectionIndex > 0
                * 集线器标志,szBuffer->DeviceIsHub
            DeviceIsHub = CTOBIN(SUBSTR(szBuffer, 25, 1), "1RS")
        
            IF DeviceIsHub == 1    && 是集线器
                szBuffer       = BINTOC(dbPortIndex, "4RS") + REPLICATE(0h00, BUFFER_SIZE - 4)
                dwReturnedSize = 0

                IF DeviceIoControl(hHUB,;
                                   IOCTL_USB_GET_NODE_CONNECTION_NAME,;
                                   @szBuffer, BUFFER_SIZE,;
                                   @szBuffer, BUFFER_SIZE,;
                                   @dwReturnedSize,;
                                   0) != 0

                    szBuffer = RTRIM(STRCONV(SUBSTR(szBuffer, 9, dwReturnedSize - 8), 6), 0h00, " ")
                    GetHUB(szBuffer)    && 遍历集线器
                ENDIF
            ELSE
                    * szBuffer->ConnectionStatus
                ConnectionStatus = CTOBIN(SUBSTR(szBuffer, 32, 1), "1RS")

                IF ConnectionStatus == 1
                        * USB_NODE_CONNECTION_INFORMATION 结构
                    idVendor  = CTOBIN(SUBSTR(szBuffer, 13, 2) + 0h0000, "4RS")
                    idProduct = CTOBIN(SUBSTR(szBuffer, 15, 2) + 0h0000, "4RS")
                    bcdDevice = CTOBIN(SUBSTR(szBuffer, 17, 2) + 0h0000, "4RS")
               
                    INSERT INTO dt VALUES ("供应商ID", IIF(idVendor  > 0, TRANSFORM(idVendor), "NULL"))
                    INSERT INTO dt VALUES ("  产品ID", IIF(idProduct > 0, TRANSFORM(idProduct), "NULL"))
                    INSERT INTO dt VALUES ("设备编码", IIF(bcdDevice > 0, TRANSFORM(bcdDevice), "NULL"))
                                
                        * iManufacturer、iProduct 和 iSerialNumber 域指向一个串描述符,
                        * 该串描述符用人类可读的语言描述设备生产厂商、产品和序列号。
                    iManufacturer = CTOBIN(SUBSTR(szBuffer, 19, 1), "1RS")
                    iProduct      = CTOBIN(SUBSTR(szBuffer, 20, 1), "1RS")
                    iSerialNumber = CTOBIN(SUBSTR(szBuffer, 21, 1), "1RS")
                    INSERT INTO dt VALUES ("厂商描述", GetStringDescriptor(hHUB, ddConnectionIndex, iManufacturer))
                    INSERT INTO dt VALUES ("产品描述", GetStringDescriptor(hHUB, ddConnectionIndex, iProduct))
                    INSERT INTO dt VALUES ("  序列号", GetStringDescriptor(hHUB, ddConnectionIndex, iSerialNumber))
                    INSERT INTO dt VALUES ("", "")
                ENDIF
            ENDIF
        ENDIF
    ENDIF
ENDFUNC

FUNCTION GetHCDDriverKeyName(hHCD)
    LOCAL szBuffer, dwReturnedSize
    szBuffer       = REPLICATE(0h00, BUFFER_SIZE)
    dwReturnedSize = 0

    IF DeviceIoControl(hHCD,;
                       IOCTL_GET_HCD_DRIVERKEY_NAME,;
                       @szBuffer, BUFFER_SIZE,;
                       @szBuffer, BUFFER_SIZE,;
                       @dwReturnedSize,;
                       0) != 0
        
        szBuffer = STRCONV(SUBSTR(szBuffer, 5, dwReturnedSize - 4), 6)
        RETURN RTRIM(szBuffer, 0h00, " ")
    ENDIF

    RETURN NULL
ENDFUNC

FUNCTION GetHUBName(hHostController)
    LOCAL szBuffer, dwReturnedSize
    szBuffer       = REPLICATE(0h00, BUFFER_SIZE)
    dwReturnedSize = 0

    IF DeviceIoControl(hHostController,;
                       IOCTL_USB_GET_ROOT_HUB_NAME,;
                       @szBuffer, BUFFER_SIZE,;
                       @szBuffer, BUFFER_SIZE,;
                       @dwReturnedSize,;
                       0) != 0
        
        szBuffer = STRCONV(SUBSTR(szBuffer, 5, dwReturnedSize - 4), 6)
        RETURN RTRIM(szBuffer, 0h00, " ")
    ENDIF

    RETURN NULL
ENDFUNC

FUNCTION GetStringDescriptor(hHUB, dbConnectionIndex, dbDescriptorIndex)
    LOCAL szBuffer, dwReturnedSize, dbLength, dbDescriptorType
   
    IF (dbConnectionIndex < 1) OR (dbDescriptorIndex < 1)
        RETURN "NULL"
    ENDIF
        * szBuffer->ConnectionIndex     = ConnectionIndex
        * szBuffer->SetupPacket.wValue  = (USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex
        * szBuffer->SetupPacket.wIndex  = GetSystemDefaultLangID()
        * szBuffer->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST))
        * sizeof(USB_DESCRIPTOR_REQUEST) = 12
    szBuffer = BINTOC(dbConnectionIndex, "4RS") + 0h0000;
             + BINTOC(BITOR(BITLSHIFT(USB_STRING_DESCRIPTOR_TYPE, 8), dbDescriptorIndex), "2RS");
             + BINTOC(0, "2RS");
             + BINTOC(BUFFER_SIZE - 12, "2RS") + REPLICATE(0h00, BUFFER_SIZE - 12)
            
    dwReturnedSize = 0

    IF DeviceIoControl(hHUB,;
                       IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,;
                       @szBuffer, BUFFER_SIZE,;
                       @szBuffer, BUFFER_SIZE,;
                       @dwReturnedSize,;
                       0) != 0
                       
            * USB_STRING_DESCRIPTOR 结构
        dbLength         = CTOBIN(SUBSTR(szBuffer, 13, 1), "1RS")
        dbDescriptorType = CTOBIN(SUBSTR(szBuffer, 14, 1), "1RS")
        
        IF (dwReturnedSize > 1) AND (dbLength == dwReturnedSize - 12);
                                AND (dbDescriptorType == USB_STRING_DESCRIPTOR_TYPE);
                                AND (dbLength % 2 == 0)
        
            RETURN RTRIM(STRCONV(SUBSTR(szBuffer, 15, dbLength), 6), 0h00, " ")
        ELSE
            RETURN "NULL"
        ENDIF
    ENDIF

    RETURN "NULL"
ENDFUNC
   
2017-07-01 14:13
wangbaoping
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2017-7-1
收藏
得分:0 
回复 楼主 wangbaoping
谢谢!可是目前的环境是WIN XP+VFP 6.0暂时无法改变,又想实现获取新插入U盘的序列号和厂家,具体如何实现呢?
2017-07-01 14:25
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10609
专家分:43210
注 册:2014-5-20
收藏
得分:0 
以下是引用wangbaoping在2017-7-1 14:25:11的发言:

谢谢!可是目前的环境是WIN XP+VFP 6.0暂时无法改变,又想实现获取新插入U盘的序列号和厂家,具体如何实现呢?

主要是调用WinAPI,用到的API应该也兼容XP。
有个别VFP9函数或命令VFP6无的,但VFP6可以写出相同功能的函数,参考一下VFP9帮助说明自己动动手就OK。
参考代码是枚举当前使用中的所有USB设备,你要的那个USB设备信息要自己去作出选择。
2017-07-01 21:17
hyswcyh
Rank: 8Rank: 8
等 级:贵宾
威 望:20
帖 子:391
专家分:896
注 册:2004-11-23
收藏
得分:4 
吹版威武!学习中...
2017-07-02 08:28
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1790
专家分:3409
注 册:2012-2-29
收藏
得分:4 
学习,谢谢吹版主!
2017-07-02 08:35
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:995
专家分:4966
注 册:2013-2-16
收藏
得分:4 
是要做USB版本的加密狗吗
2017-07-03 19:20
hyswcyh
Rank: 8Rank: 8
等 级:贵宾
威 望:20
帖 子:391
专家分:896
注 册:2004-11-23
收藏
得分:0 
看起来是的
2017-07-04 07:56
n73wxb
Rank: 1
等 级:新手上路
帖 子:5
专家分:9
注 册:2012-6-7
收藏
得分:4 
好东西,学习
2017-07-04 21:23
井绳
Rank: 2
等 级:论坛游民
帖 子:97
专家分:69
注 册:2010-6-29
收藏
得分:0 
吹版确实高人
2018-09-12 19:16
快速回复:在VF6.0中如何实现获取新插入U盘的序列号?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.045263 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved