用C ++编程的USB编程 [英] USB Programming in C++

查看:85
本文介绍了用C ++编程的USB编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好。我正在尝试构建一个关于USB设备的DLL,包括其他DLL,如setupapi.dll,user32.dll,MPUSBAPI.dll。我似乎无法获得我的函数指针来指出它们的一些功能。这是我的代码的相关部分:



Hello. I''m trying to construct a DLL about USB devices including other DLLs such as "setupapi.dll", "user32.dll", "MPUSBAPI.dll". I can''t seem to get my function pointers to point some of their functions though. Here''s the relevant parts of my code:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>	//Definitions for various common and not so common types like DWORD, PCHAR, HANDLE, etc.
#include <Dbt.h>		//Need this for definitions of WM_DEVICECHANGE messages
#include <setupapi.h>	
#include <string>

using namespace std;

#define Cihaz_ID  "Vid_a0a1&Pid_4147"	 
#define __YAZI__ "Esetron USB Kart V1.0"

typedef HDEVINFO (*SetupDiGetClassDevsUMPTR)(LPGUID, PCTSTR, HWND, DWORD);
typedef WINSETUPAPI BOOL (*SetupDiEnumDeviceInterfacesUMPTR)(HDEVINFO, PSP_DEVINFO_DATA, LPGUID, DWORD, PSP_DEVICE_INTERFACE_DATA);
typedef WINSETUPAPI BOOL (*SetupDiDestroyDeviceInfoListUMPTR)(HDEVINFO);
typedef WINSETUPAPI BOOL (*SetupDiEnumDeviceInfoUMPTR)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
typedef WINSETUPAPI BOOL (*SetupDiGetDeviceRegistryPropertyUMPTR)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);
typedef WINSETUPAPI BOOL (*SetupDiSetDeviceRegistryPropertyUMPTR)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE*, DWORD);
typedef BOOL (*SetupDiGetDeviceInterfaceDetailUMPTR)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA);
typedef HDEVNOTIFY (*RegisterDeviceNotificationUMPTR)(HANDLE, LPVOID, DWORD);

typedef DWORD (*MPUSBGetDLLVersionPTR)(void);
typedef DWORD (*MPUSBGetDeviceCountPTR)(PCHAR);
typedef HANDLE (*MPUSBOpenPTR)(DWORD, PCHAR, PCHAR, DWORD, DWORD);
typedef BOOL (*MPUSBClosePTR)(HANDLE);
typedef DWORD (*MPUSBReadPTR)(HANDLE, PVOID, DWORD, PDWORD, DWORD);
typedef DWORD (*MPUSBWritePTR)(HANDLE, PVOID, DWORD, PDWORD, DWORD);
typedef DWORD (*MPUSBReadIntPTR)(HANDLE, PVOID, DWORD, PDWORD, DWORD);
typedef HDEVNOTIFY (*RegisterDeviceNotificationUMPTR)(HANDLE, LPVOID, DWORD);

//Globally Unique Identifier (GUID) for HID class devices.  Windows uses GUIDs to identify things.
GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}; 

//USB variables
BOOL AttachedState = false;		
BOOL AttachedButBroken = false;					
PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP_DEVICE_INTERFACE_DETAIL_DATA;
HANDLE WriteHandleToUSBDevice = INVALID_HANDLE_VALUE;
HANDLE ReadHandleToUSBDevice = INVALID_HANDLE_VALUE;

unsigned char LED_durum = 0;
HANDLE  EP1INHandle = INVALID_HANDLE_VALUE;
HANDLE  EP1OUTHandle = INVALID_HANDLE_VALUE;
bool durum = false;

class USBdll 
{
public:		
		SetupDiGetClassDevsUMPTR _SetupDiGetClassDevsUMPTR;
		SetupDiEnumDeviceInterfacesUMPTR _SetupDiEnumDeviceInterfacesUMPTR;
		SetupDiDestroyDeviceInfoListUMPTR _SetupDiDestroyDeviceInfoListUMPTR;
		SetupDiEnumDeviceInfoUMPTR _SetupDiEnumDeviceInfoUMPTR;
		SetupDiGetDeviceRegistryPropertyUMPTR _SetupDiGetDeviceRegistryPropertyUMPTR;
		SetupDiSetDeviceRegistryPropertyUMPTR _SetupDiSetDeviceRegistryPropertyUMPTR;
		SetupDiGetDeviceInterfaceDetailUMPTR _SetupDiGetDeviceInterfaceDetailUMPTR;
		RegisterDeviceNotificationUMPTR _RegisterDeviceNotificationUMPTR;

		MPUSBGetDLLVersionPTR _MPUSBGetDLLVersionPTR;
		MPUSBGetDeviceCountPTR _MPUSBGetDeviceCountPTR;
		MPUSBOpenPTR _MPUSBOpenPTR;
		MPUSBClosePTR _MPUSBClosePTR;
		MPUSBReadPTR _MPUSBReadPTR;
		MPUSBWritePTR _MPUSBWritePTR;
		MPUSBReadIntPTR _MPUSBReadIntPTR;

		DWORD ErrorStatusWrite;
		DWORD ErrorStatusRead;

		//Explicit Linking
		HINSTANCE hSetUpApi; 
		HINSTANCE hUser32;
		HINSTANCE hMPUSBAPI;
...//Other stuff that hasn't got relevance
                USBdll();
...
};

USBdll::USBdll(){
	hSetUpApi = LoadLibrary("setupapi.dll");
	hUser32 = LoadLibrary("user32.dll");
	hMPUSBAPI = LoadLibrary("MPUSBAPI.dll");

	_SetupDiGetClassDevsUMPTR = (SetupDiGetClassDevsUMPTR)GetProcAddress(hSetUpApi, "SetupDiGetClassDevsA"); 
	_SetupDiEnumDeviceInterfacesUMPTR = (SetupDiEnumDeviceInterfacesUMPTR)GetProcAddress(hSetUpApi, "SetupDiEnumDeviceInterfaces");
	_SetupDiDestroyDeviceInfoListUMPTR = (SetupDiDestroyDeviceInfoListUMPTR)GetProcAddress(hSetUpApi, "SetupDiDestroyDeviceInfoList");
	_SetupDiEnumDeviceInfoUMPTR = (SetupDiEnumDeviceInfoUMPTR)GetProcAddress(hSetUpApi, "SetupDiEnumDeviceInfo");
	_SetupDiGetDeviceRegistryPropertyUMPTR = (SetupDiGetDeviceRegistryPropertyUMPTR)GetProcAddress(hSetUpApi, "SetupDiGetDeviceRegistryPropertyA"); 
	_SetupDiSetDeviceRegistryPropertyUMPTR = (SetupDiSetDeviceRegistryPropertyUMPTR)GetProcAddress(hSetUpApi, "SetupDiSetDeviceRegistryPropertyA");  
	_SetupDiGetDeviceInterfaceDetailUMPTR = (SetupDiGetDeviceInterfaceDetailUMPTR)GetProcAddress(hSetUpApi, "SetupDiGetDeviceInterfaceDetailA");  

	_MPUSBGetDLLVersionPTR = (MPUSBGetDLLVersionPTR)GetProcAddress(hMPUSBAPI, "_MPUSBGetDLLVersion");  // Problematic part, pointer is null instead of pointing the imported function 
	_MPUSBGetDeviceCountPTR = (MPUSBGetDeviceCountPTR)GetProcAddress(hMPUSBAPI, "_MPUSBGetDeviceCount");  // Problematic part, pointer is null instead of pointing the imported function 
	_MPUSBOpenPTR = (MPUSBOpenPTR)GetProcAddress(hMPUSBAPI, "_MPUSBOpen");  // Problematic part, pointer is null instead of pointing the imported function 
	_MPUSBClosePTR = (MPUSBClosePTR)GetProcAddress(hMPUSBAPI, "_MPUSBClose");  // Problematic part, pointer is null instead of pointing the imported function 
	_MPUSBReadPTR = (MPUSBReadPTR)GetProcAddress(hMPUSBAPI, "_MPUSBRead");  // Problematic part, pointer is null instead of pointing the imported function 
	_MPUSBWritePTR = (MPUSBWritePTR)GetProcAddress(hMPUSBAPI, "_MPUSBWrite");  // Problematic part, pointer is null instead of pointing the imported function 
	_MPUSBReadIntPTR = (MPUSBReadIntPTR)GetProcAddress(hMPUSBAPI, "_MPUSBReadInt");  // Problematic part, pointer is null instead of pointing the imported function 

	DEV_BROADCAST_DEVICEINTERFACE MyDeviceBroadcastHeader;// = new DEV_BROADCAST_HDR;
	MyDeviceBroadcastHeader.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	MyDeviceBroadcastHeader.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	MyDeviceBroadcastHeader.dbcc_reserved = 0;	//Reserved says not to use...
	MyDeviceBroadcastHeader.dbcc_classguid = InterfaceClassGuid;
...
}





如果有帮助,我正在使用多字节字符集。感谢您对长代码的关注和道歉。



编辑:正如Arndt先生要求我为有问题的函数链接添加了''A''后缀,现在函数指针已经正确的函数地址(MPUSABI.dll仍为NULL)。但现在我得到一个运行时检查错误0使用此功能而不是访问冲突异常我曾经得到相同的功能:





I''m using multi byte character set if it helps. Thanks for your attention and apologies for long code.

As Mr Arndt requested i have added ''A'' suffix to problematic function linkings, now function pointers have proper function addresses (MPUSABI.dll ones still remain NULL). But now i''m getting a Run Time Check Error 0 with this function instead of Access Violation Exception i used to get at the same function:

DeviceInfoTable = _SetupDiGetClassDevsUMPTR(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);





编辑2:Faithfull先生可以你给出了解决方案的语法示例吗?我以为我包含了适当的库并将其链接到正确的句柄。



Mr. Faithfull can you give a syntax example for your solution please? I thought i included proper library and linked it to proper handle.

推荐答案

1。只要你直接加载它就应该完全指定函数 GetProcAddress(hSetUpApi,SetupDiGetClassDevsW); for unicode as function SetupDiGetClassDevs 在setup api dll中不存在。除此之外,你应该将unicode结构声明传递给函数(最后用W)。



2.你的函数类型声明不正确:

1. you should specify function fully as long you are loading them directly GetProcAddress(hSetUpApi, "SetupDiGetClassDevsW"); for unicode as function "SetupDiGetClassDevs" does not exists in setup api dll. Along with it you should passing unicode structure declaration into functions (with "W" at the end).

2. Your function type declarations are not correct:
// Example
typedef HDEVINFO (WINAPI * FNSetupDiGetClassDevsW)(CONST GUID *ClassGuid,PCWSTR Enumerator,HWND hwndParent,DWORD Flags);
// Initializing
FNSetupDiGetClassDevsW pfn = (FNSetupDiGetClassDevsW)GetProcAddress(hSetUpApi, "SetupDiGetClassDevsW");



问候,

Maxim。


Regards,
Maxim.


这里有一大堆问题,主要的一点是你不需要做大部分工作。例如,使用 SetupDiGetClassDevs 只需 #include< setupapi.h> < /setupapi.h> 并链接到 Setupapi.lib 。你会发现 SetupDiGetClassDevs 然后是全局命名空间中的普通函数,你可以使用它。

这将解决你的大多数问题,但可能不是全部。您需要检查返回的句柄,以确保实际找到并加载DLL。您还可以使用 Dependency walker [ ^ ]检查dll本身,看看他们确实输出了什么名称。

如果你还有问题,请回来更新问题或发布另一个问题,因为它用更少的东西来查看错误会更容易。
There are a raft of problem here, the main one is that you don''t need to do most of this. For example to use SetupDiGetClassDevs just #include <setupapi.h> </setupapi.h> and link to Setupapi.lib. You will find SetupDiGetClassDevs is then an ordinary function in the global namespace and you can just use it.
This will solve most of your issues but probably not all. You need to check the returned handles to ensure that the DLLs are actually being found and loaded. You can also use Dependency walker[^] to examine the dlls themselves to see exactly what names they do export.
If you still have issues come back and update the questions or post another as it will be much easier to spot whats wrong with less to look at.


当使用 GetProcAddress()时,你必须指定的函数名称是存在于DLL中。当DLL支持Unicode和多字节时,存在字符或字符串参数时有两个函数。然后将字母A或W附加到函数名称中。因此,当使用多字节构建时,使用''A''(ANSI)终止名称:

When using GetProcAddress() you must specify function names that are present in the DLL. When a DLL supports Unicode and multi byte, there are two functions when character or string parameters are present. Then the letters ''A'' or ''W'' are appended to the function names. So when using multi byte builds, use the ''A'' (ANSI) terminated names:
_SetupDiGetClassDevsUMPTR = (SetupDiGetClassDevsUMPTR)GetProcAddress(hSetUpApi, "SetupDiGetClassDevsA"); 



当有ANSI和宽版本时,以相同的方式更改所有其他功能的代码。对于不使用 SetupDiEnumDeviceInfo 等字符串的函数,只有一个版本。


Change your code for all other functions in the same way when there are ANSI and wide versions. With functions that did not use strings like SetupDiEnumDeviceInfo, there is only one version.


这篇关于用C ++编程的USB编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆