Click here to Skip to main content
15,892,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:

C++
#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;
...
}


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

Edit: 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:

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


Edit2: Mr. Faithfull can you give a syntax example for your solution please? I thought i included proper library and linked it to proper handle.
Posted
Updated 12-Feb-13 22:52pm
v4
Comments
Jochen Arndt 13-Feb-13 5:14am    
Regarding the MPUSBAPI.dll:
Did the function names exported by the library really begin with a underscore? I don't think so.
Jochen Arndt 13-Feb-13 5:21am    
You should add comments to answers (like this one to your question). Then the author of the answer gets an email notification and may answer. When only editing your question, the adressed persons may not see it.

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:
C++
// Example
typedef HDEVINFO (WINAPI * FNSetupDiGetClassDevsW)(CONST GUID *ClassGuid,PCWSTR Enumerator,HWND hwndParent,DWORD Flags);
// Initializing
FNSetupDiGetClassDevsW pfn = (FNSetupDiGetClassDevsW)GetProcAddress(hSetUpApi, "SetupDiGetClassDevsW");

Regards,
Maxim.
 
Share this answer
 
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.
 
Share this answer
 
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"); 

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.
 
Share this answer
 
Comments
YourAverageCoder 13-Feb-13 5:43am    
Weird but it does start with an underscore, from C# example:
<pre lang="c#">
#pragma region DLL imports
//mpusbapi.dll içindeki USB fonksiyonları import ediliyor
[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBGetDLLVersion")]
extern "C" DWORD MPUSBGetDLLVersion(void);
[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBGetDeviceCount")]
extern "C" DWORD MPUSBGetDeviceCount(PCHAR pVID_PID);
[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBOpen")]
extern "C" HANDLE MPUSBOpen(DWORD instance, // Input
PCHAR pVID_PID, // Input
PCHAR pEP, // Input
DWORD dwDir, // Input
DWORD dwReserved);// Input

[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBClose")]
extern "C" BOOL MPUSBClose(HANDLE handle); //Input
[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBRead")]
extern "C" DWORD MPUSBRead(HANDLE handle, // Input
PVOID pData, // Output
DWORD dwLen, // Input
PDWORD pLength, // Output
DWORD dwMilliseconds);// Input

[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBWrite")]
extern "C" DWORD MPUSBWrite(HANDLE handle, // Input
PVOID pData, // Output
DWORD dwLen, // Input
PDWORD pLength, // Output
DWORD dwMilliseconds);// Input
[DllImport("MPUSBAPI.dll" , EntryPoint="_MPUSBReadInt")]
extern "C" DWORD MPUSBReadInt(HANDLE handle, // Input
PVOID pData, // Output
DWORD dwLen, // Input
PDWORD pLength, // Output
DWORD dwMilliseconds);// Input
</pre>
Jochen Arndt 13-Feb-13 6:40am    
Weird is that I did not get an email notification for your comment.

I don't know C# very well, but with the import of DLLs there may be name mangling depending on the calling convention of the exported function.

So ignore the example and use the function names exported by the DLL. To get the names, use the command line utility dumpbin, the Dependancy Walker, or just a hex editor.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900