参考:
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
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