问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何用C++ builder编写usbxpress

发布网友 发布时间:2022-04-26 14:44

我来回答

1个回答

热心网友 时间:2022-06-29 08:38

C++ Builder 访问 USB 口的方法
编译环境: Borland C++ Builder 6.0, Windows Server 2003 DDK

运行环境: Win98/2000/XP/2003

下面是访问 USB 口必备的函数:

#include <vcl.h>

#include <dir.h>

#include <setupapi.h>

#include "C:/WINDDK/3790/inc/ddk/w2k/usbdi.h"

#include "C:/WINDDK/3790/inc/ddk/w2k/devioctl.h"

#include <initguid.h>

//---------------------------------------------------------------------------

// 下面必须为驱动程序的 GUID 值, 这里我乱写的数

DEFINE_GUID(USB_DRIVER_GUID, 0x12345678,0xabcd,0x1122,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00);

//---------------------------------------------------------------------------

HANDLE OpenONeDevice(HDEVINFO hDvcInfo, PSP_INTERFACE_DEVICE_DATA DvcInfoData, char *sDevNameBuf)

{

HANDLE hOut = INVALID_HANDLE_VALUE;

ULONG iReqLen = 0;

SetupDiGeTInterfaceDeviceDetail(hDvcInfo, DvcInfoData, NULL, 0, &iReqLen, NULL);

ULONG iDevDataLen = iReqLen; //sizeof(SP_FNCLASS_DEVICE_DATA) + 512;

PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iDevDataLen);

pDevData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

if(SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL))

{

STrcpy(sDevNameBuf, pDevData->DevicePath);

hOut = CreateFile(pDevData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

}

free(pDevData);

return hOut;

}

//---------------------------------------------------------------------------

HANDLE OpenUsbDevice(const GUID *pGuid, char *sDevNameBuf)

{

HANDLE hOut = INVALID_HANDLE_VALUE;

HDEVINFO hDevInfo = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

SP_INTERFACE_DEVICE_DATA deviceInfoData;

deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

ULONG nGuessCount = MAXLONG;

for(ULONG iDevIndex=0; iDevIndex<nGuessCount; iDevIndex++)

{

if(SetupDiEnumDeviceInterfaces(hDevInfo, 0, pGuid, iDevIndex, &deviceInfoData))

{

if((hOut=OpenOneDevice(hDevInfo, &deviceInfoData, sDevNameBuf)) != INVALID_HANDLE_VALUE)

break;

}

else if(GetLastError() == ERROR_NO_MORE_ITEMS) //No more items

{

break;

}

}

SetupDiDestroyDeviceInfoList(hDevInfo);

return hOut;

}

//---------------------------------------------------------------------------

bool GetUsbDeviceFileName(const GUID *pGuid, char *sDevNameBuf)

{

HANDLE hDev = OpenUsbDevice(pGuid, sDevNameBuf);

if(hDev != INVALID_HANDLE_VALUE)

{

CloseHandle(hDev);

return true;

}

return false;

}

//---------------------------------------------------------------------------

HANDLE OpenMyDevice()

{

char DeviceName[MAXPATH] = "";

return OpenUsbDevice(&USB_DRIVER_GUID, DeviceName);

}

//---------------------------------------------------------------------------

HANDLE OpenMyDevPipe(const char *PipeName)

{

char DeviceName[MAXPATH] = "";

if(GetUsbDeviceFileName(&USB_DRIVER_GUID, DeviceName))

{

strcat(DeviceName,"\\");

strcat(DeviceName,PipeName);

return CreateFile(DeviceName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

}

return INVALID_HANDLE_VALUE;

}

//---------------------------------------------------------------------------

有了上面的函数就可以访问 USB 口了:

//打开 USB 口读写, 由驱动程序的 Pipe 名确定

HANDLE hPipe = OpenMyDevPipe("MyPipe1"); //驱动程序里面的 Pipe 名, 对应访问某个端点的 I/O, 这里我乱写的, 需要与驱动一致

if(hPipe != INVALID_HANDLE_VALUE) //打开 Pipe 成功

{

ReadFile(hPipe, Buffer, BufSize, &nBytesRead, NULL); //从 hPipe 里读取数据到 Buffer 里

//WriteFile(hPipe, Buffer, BytesToWrite, &nBytesWritten, NULL); //把 Buffer 里面的 BytesToWrite 字节写入 hPipe

CloseHandle(hPipe);

}

//使用 DeviceIoControl 访问 USB 设备

HANDLE hDevice = OpenMyDevice();

if(hDevice != INVALID_HANDLE_VALUE) //打开设备成功

{

//这些 DeviceIoControl 功能都是由设备定义的, 具体看设备和驱动的资料

if(DeviceIoControl(hDevice, IOCTL_READ_xxxx, &IOBlock, sizeof(IOBLOCK), &c, 1, &nBytes, NULL))

{

//成功

}

CloseHandle(hDevice);

}

USB 设备、USB 驱动、USB 应用程序

1.USB 设备硬件部分

a.这个硬件的标识是用的 Vender ID 和 Proct ID, 即“厂家标识”和“产品标识”

b.这个硬件规定了各个 End Point (端点) 的性质, 读/写 及 类型 (Control/Interrupt/Bulk/Isochronous)

c.这个硬件的固件里面有 DeviceIoControl 的实现部分, 规定了这个函数的具体参数和动作

2.USB 设备驱动

①硬件接口

a.需要识别 Vender ID 和 Proct ID

b.对每个 EndPoint 的每个 I/O 分配一个 Pipe, 并且起一个名字作为软件接口

c.做 DeviceIoControl 的接口

②软件接口

a.GUID, 驱动程序的标识, 每个驱动程序使用不同的 GUID, GUID 是识别驱动的, 与硬件无关 (驱动程序升级版本 GUID 不能修改)

b.硬件接口里面的 b: Pipe 名字是软件接口, 这个 Pipe 名字纯粹由驱动定义的, 和硬件无关, 升级驱动不能改 Pipe 的名字

c.硬件接口里面的 c 的各个参数也是软件的接口, 这些参数是由硬件带来的, 不是驱动规定的, 当然也可以在驱动里面转义, 隐藏设备的真实情况

③这个驱动程序是用 WinDDK 编译的, 可以用文本编辑器或其他开发工具的编辑器编程序代码, 然后调用 WinDDK 编译

3.读写 USB 口的程序

①与驱动的接口

a.利用驱动程序里面的 GUID 找出设备的文件名, 用 CreateFile 函数打开设备。我前面的程序里面的 OpenUsbDevice 就是这个作用

b.通过 a.得到的设备文件名和驱动程序里面的 Pipe 名打开 Pipe, 访问这个 Pipe 对应的 USB 端点 (读写数据)

c.使用 a.的 CreateFile 得到的句柄, 通过 DeviceIoControl 实现设备规定的动作

②有关需要的资料

a.Vender ID, Proct ID 和 GUID 一般在驱动程序的 .inf 文件里面能看到, 如果找不到就需要和厂家联系

b.Pipe 的名字是驱动程序规定的, 需要有驱动程序的资料才能知道

c.DeviceIoControl 的参数需要有驱动程序的资料或者硬件资料才能知道

③这个程序一般用 C/C++ 直接编写, 如果使用其他语言(VB/PB等)需要调用 C/C++ 编的 DLL

其他相关内容:

USB 驱动程序可以到注册表里面找到:

"HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Enum\\USB\\Vid_厂家标识&Pid_产品标识\\驱动程序"

里面的 ClassGUID 就是驱动程序的 GUID 标识, 例如 {36FC9E60-C465-11CF-805*44553540000}

相当于程序的: DEFINE_GUID(USB_DRIVER_GUID, 0x36FC9E60,0xC465,0x11CF,0x80,0x56,0x44,0x45,0x53,0x54,0x00,0x00);

另外在这个注册表键里面还可找到有关设备的其他描述, 例如 DeviceDesc = "USB Mass Storage Device" 等
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...时间会发作,很痛的,请问是这样吗?会痛多久? ...已经坏了,如今全身浮肿,尿排不出,医生说就这 我爷爷得了肝癌晚期,腹水,不能手术.听说氩氦超冷刀技术能治.哪里有... 父亲59岁得了肝癌晚期,医生说最多半年时间了,上面还有80多岁的爷爷... 长春跑大连的列车员,怎么区分正式分和临时工呢? 员工刚怀孕就被开除,开除负责人拒不认错,你如何看待该公司的态度?_百 ... 员工在职期间怀孕,老板可以无故迟退吗? 老板开除怀孕女员工违法吗 如何选购蚊帐 什么样的蚊帐最好 合肥什么地方能给电脑增加内存,价格是多少? 合肥哪卖内存条?? 谁有c++builder帮助文件的中文解释 Borland C++ Builder 6.0的详细说明 如何进行C++ Builder中的文件读写操作 编程语言的C++ Builder 学习C++builder最好的书籍有哪些,拜托高手帮帮忙?有好的电子书更好。 最近想学C++ Builder。请大神推荐几本好书。书中必须带有一些例子。 推荐几本C++Builder的好书 手机屏幕按键失灵了怎样修复 c++ builder如何编写c语言的程序 paonoca空调遥控器上的模式显示是太阳是什么模式? oppo锁屏键失灵修复方法 paonoca空调没有遥控器怎么开 按键失灵,屏幕破损这种情况还能修吗?大概多少钱? 东松空调故障e1什么意思? 电脑显示屏按键坏了维修得多少钱 东松空调一个小时要多少电? 浙江宁波东松空调厂厂址在哪里? paonoca KFR-35w/CSX-33属于定频空调还是变频空调? 如何用C++ builder调试程序 合肥在哪可以换内存 我的是iphone5s c++builder6.0中怎样让c语言编程界面化 Builder C++ 编程, Visual C++的区别 ,C++编程,API编程,Windos编程,与MFC编程的异同 现在新的512M内存条大概多少钱? C,C#,C+,C++,C++Builder,JAVA这几种语言有何相同点和不同点,哪一种好学? 刚才说我的宏基D525可换DDR2 800 4G内存条,可我淘宝合肥实体店商家说只有DDR2 2G的 c++ builder 6.0 中如何将按钮和输入的属性与C语言代码对应? 尔必达内存怎么才能买到? 金士顿和尔必达内存条 合肥沛顿是央企吗 我想在合肥买个2500左右的电脑,希望配置能好点,谁给出出注意? 如何把加密光盘内容复制到电脑硬盘上。 2G的内存条120元,可以买吗? 如何复制加密光盘里的内容 在合肥买组装电脑,请高手进~~ 如何复制加密光盘中的内容,比如各种视频文件 去哪买内存条最好~ 有版权的光盘,可能是加密了,我怎么复制,或是用什么软件复制?紧急! 如何把加密光盘文件复制到电脑里面?