Witam serdecznie,
próbuję skompilować listing z książki “USB praktyczne programowanie w Windows API”.
Listing wygląda tak:
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#pragma argsused
#pragma hdrstop
#define searchMaxDevices 10
// maksymalna liczba inteifejsow urzadzen
using namespace std;
// --------------------------------------------------------
template
inline void releaseMemory(T &x)
{
assert(x != NULL);
delete x;
x = NULL;
};
// --------------------------------------------------------
typedef USHORT USAGE, *PUSAGE;
typedef struct _HIDP_PREPARSED_DATA *PHIDP_PREPARSED_DATA;
//--------------------------------------------------------
typedef struct _HIDP_CAPS {//1
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberlinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
} HIDP_CAPS, *PHIDP_CAPS;
//---------------------------------------------------------
typedef struct _DEVICE_DATA {//1
TCHAR *HardwareId;
TCHAR *Path;
DWORD DeviceInstance;
HANDLE hidDeviceObject;
BYTE *inputReportBuffer;
USHORT inputReportByteLength;
USHORT outputReportByteLength;
USHORT featureReportByteLength;
PHIDP_PREPARSED_DATA preparsedData;
HIDP_CAPS capabilities;
} DEVICE_DATA, *PDEVICE_DATA;
// -------------------------------------------------------
class TUSBDevice {//1
private:
UINT fMemberIndex;
void displayError(const char* msg);
public:
PDEVICE_DATA deviceList;
BOOL getHidDeviceCapabilities(UINT memberIndex);
UINT setGetHidDeviceData();
HANDLE openHidUSBDevice(UINT memberIndex);
BOOL readUSBReport(UINT memberIndex);
BOOL closeHidUSBDevice(HANDLE devHandle);
TUSBDevice(UINT memberIndex);
~TUSBDevice();
};//0
//---------------------------------------------------------
TUSBDevice::TUSBDevice(UINT memberIndex){//1
fMemberIndex = memberIndex;
deviceList = (PDEVICE_DATA) new DEVICE_DATA[((fMemberIndex+1)*sizeof(DEVICE_DATA))];
};//0
//--------------------------------------------------------
TUSBDevice::~TUSBDevice()
{//1
releaseMemory(deviceList);
system(“PAUSE”);
};//0
//---------------------------------------------------------
void TUSBDevice::displayError(const char* msg)
{//1
cout << msg << endl;
system(“PAUSE”);
exit(0);
};//0
//--------------------------------------------------------
BOOL TUSBDevice::getHidDeviceCapabilities(UINT memberIndex)
{//1
HMODULE hHidLib;
bool status;
long (__stdcall* HidP_GetCaps)(IN PHIDP_PREPARSED_DATA PreparsedData, OUT PHIDP_CAPS Capabilities);
bool (__stdcall* HidD_GetPreparsedData)(IN HANDLE HidDeviceObject, OUT PHIDP_PREPARSED_DATA *PreparsedData);
bool (__stdcall* HidD_FreePreparsedData)(IN PHIDP_PREPARSED_DATA PreparsedData);
hHidLib = LoadLibrary(“HID.DLL”);
if(!hHidLib)
displayError(“Blad dolaczenia biblioteki HID.DLL.”);
(FARPROC&) HidP_GetCaps=GetProcAddress(hHidLib, “HidP_GetCaps”);
(FARPROC&) HidD_GetPreparsedData=GetProcAddress(hHidLib, “HidD_GetPreparsedData”);
(FARPROC&) HidD_FreePreparsedData=GetProcAddress(hHidLib, “HidD_FreePreparsedData”);
if (!HidP_GetCaps || !HidD_GetPreparsedData || !HidD_FreePreparsedData)
{//2
FreeLibrary(hHidLib);
displayError(“Nie znaleziono jednej lub wiecej funkcji eksportowych .\n”);
};//1
status=HidD_GetPreparsedData(deviceList[memberIndex].hidDeviceObject,
&deviceList->preparsedData);
if(status){//2
HidP_GetCaps(deviceList->preparsedData, &deviceList->capabilities);
deviceList[memberIndex].inputReportByteLength = deviceList->capabilities.InputReportByteLength;
deviceList[memberIndex].outputReportByteLength = deviceList->capabilities.OutputReportByteLength;
deviceList[memberIndex].featureReportByteLength = deviceList->capabilities.FeatureReportByteLength;
HidD_FreePreparsedData(deviceList->preparsedData);
}//1
FreeLibrary(hHidLib);
return status;
};//0
// ---------------------------------------------------------
UINT TUSBDevice::setGetHidDeviceData()
{//1
DWORD propertyBufferSize = 0;
char *propertyBuffer = NULL;
HMODULE hHidLib;
SP_DEVINFO_DATA deviceInfoData;
HDEVINFO deviceInfoSet;
SP_INTERFACE_DEVICE_DATA deviceInterfaceData;
fMemberIndex = 0;
GUID classGuid;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
DWORD requiredSize = 0;
DWORD deviceInterfaceDetailDataSize = 0;
DWORD maxDevice = searchMaxDevices;
bool done = false;
void (__stdcall *HidD_GetHidGuid)(OUT LPGUID HidGuid);
hHidLib = LoadLibrary(“HID.DLL”);
if (!hHidLib)
displayError(“Blad dolaczenia biblioteki HID.DLL.”);
(FARPROC&) HidD_GetHidGuid = GetProcAddress(hHidLib,“HidD_GetHidGuid”);
if (!HidD_GetHidGuid)
{//2
FreeLibrary(hHidLib);
displayError(“Nie znaleziono identyfikatora GUID.”);
};//1
HidD_GetHidGuid (&classGuid);
deviceInfoSet = SetupDiGetClassDevs(&classGuid, NULL, NULL,
(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
while(!done)
{//2
for(; fMemberIndex < maxDevice; fMemberIndex++)
{//3
if(SetupDiEnumDeviceInterfaces(deviceInfoSet,0,&classGuid,
fMemberIndex,&deviceInterfaceData))
{//4
SetupDiGetDeviceInterfaceDetail(deviceInfoSet,&deviceInterfaceData, NULL,0,&deviceInterfaceDetailDataSize, NULL);
requiredSize = deviceInterfaceDetailDataSize;
deviceInterfaceDetailData =(PSP_DEVICE_INTERFACE_DETAIL_DATA) new DWORD[deviceInterfaceDetailDataSize];
if(deviceInterfaceDetailData)
{//5
deviceInterfaceDetailData->cbSize= sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
}//4
else {//5
SetupDiDestroyDeviceInfoList(deviceInfoSet);
releaseMemory(deviceInterfaceDetailData);
return 0;
}//4
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if(!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, deviceInterfaceDetailData, deviceInterfaceDetailDataSize, &requiredSize, &deviceInfoData))
{//5
SetupDiDestroyDeviceInfoList(deviceInfoSet);
releaseMemory(deviceInterfaceDetailData);
return 0;
}//4
size_t nLen = strlen(deviceInterfaceDetailData->DevicePath) + 1;
deviceList[fMemberIndex].Path = new TCHAR[(nLen*sizeof(TCHAR))];
StrLCopy(deviceList[fMemberIndex].Path, deviceInterfaceDetailData->DevicePath, nLen);
deviceList[fMemberIndex].DeviceInstance = deviceInfoData.DevInst;
SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID, NULL, NULL, 0, &propertyBufferSize);
// allokowanie pamieci dla bufora danych
propertyBuffer = new char[(propertyBufferSize*sizeof(TCHAR))];
SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID, NULL, propertyBuffer, propertyBufferSize, NULL);
deviceList[fMemberIndex].HardwareId = propertyBuffer;
cout<<"\nDeviceList["<
releaseMemory(deviceInterfaceDetailData);
releaseMemory(propertyBuffer);
}//3
else {//4
if(ERROR_NO_MORE_ITEMS == GetLastError()){//5
done = TRUE;
break;
}//4
}//3
}//2
}//1
SetupDiDestroyDeviceInfoList(deviceInfoSet);
FreeLibrary(hHidLib);
return fMemberIndex;
}//0
//---------------------------------------------------------
HANDLE TUSBDevice::openHidUSBDevice(UINT memberIndex)
{//1
deviceList[memberIndex].hidDeviceObject == INVALID_HANDLE_VALUE;
deviceList[memberIndex].hidDeviceObject = CreateFile(deviceList[memberIndex].Path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);
if(deviceList[memberIndex].hidDeviceObject != INVALID_HANDLE_VALUE)
return deviceList[memberIndex].hidDeviceObject;
else
return INVALID_HANDLE_VALUE;
}//0
// ---------------------------------------------------------
BOOL TUSBDevice::closeHidUSBDevice(HANDLE devHandle)
{//1
if((devHandle == 0) ||(devHandle == INVALID_HANDLE_VALUE))
{//2
return false;
}//1
else
return Win32Check(CloseHandle(devHandle));
};//0
//---------------------------------------------------------
BOOL TUSBDevice::readUSBReport(UINT memberIndex)
{//1
DWORD result = 0;
DWORD numberOfBytesRead = 0;
OVERLAPPED *overlapped = NULL;
if(overlapped == NULL){//2
overlapped = new OVERLAPPED;
overlapped->hEvent = CreateEvent(NULL, TRUE, TRUE, “”);
overlapped->Offset = 0;
overlapped->OffsetHigh = 0;
}//1
memset(deviceList[memberIndex].inputReportBuffer, 0x00,
deviceList[memberIndex].inputReportByteLength);
if(!ReadFile(deviceList[memberIndex].hidDeviceObject,
deviceList[memberIndex].inputReportBuffer,
deviceList[memberIndex].inputReportByteLength,
&numberOfBytesRead, overlapped)) {//2
if(GetLastError() == ERROR_IO_PENDING) {//3
result = WaitForSingleObject(overlapped->hEvent, 100);
if(result == WAIT_TIMEOUT) {//4
CancelIo(deviceList[memberIndex].hidDeviceObject);
return false;
}//3
else
if(result == WAIT_FAILED){//4
displayError(“Blad Odczytu danych.”);
return false;
}//3
GetOverlappedResult(deviceList[memberIndex].hidDeviceObject,
overlapped, &numberOfBytesRead, FALSE);
}//2
else
displayError(“Blad odczytu danych.”);
}//1
ResetEvent(overlapped->hEvent);
if(numberOfBytesRead == (UINT)deviceList[memberIndex].inputReportByteLength){//2
for(USHORT i=0; i
printf("%d ", deviceList[memberIndex].inputReportBuffer_);_
printf("\n");
}//1
else {//2
printf (“Bledna liczba bajtow odebranych. \n” , numberOfBytesRead);
}//1
releaseMemory(overlapped);
return true;
}//0
//---------------------------------------------------------
int main() {//1
UINT interfaceIndex = 3; // numer istniejacego
//interfejsu urzadzenia HID
// stworzenie obiektu klasy TUSBDevice
TUSBDevice *usbDevice = new TUSBDevice(interfaceIndex);
// enumeracja aktualnie podlaczonych urzadzen klasy HiD
usbDevice->setGetHidDeviceData();
cout << “\nDeviceList[”<
usbDevice->deviceList[interfaceIndex].Path << endl;
// otwarcie portu USB
usbDevice->openHidUSBDevice(interfaceIndex);
// odczyt wlasciwosci urzadzenia
if (usbDevice->getHidDeviceCapabilities(interfaceIndex)) {//2
_usbDevice->deviceList[interfaceIndex].inputReportBuffer = new _
BYTE[usbDevice->deviceList[interfaceIndex].inputReportByteLength];
while(true) { //3 cykliczny odczyt raportu wejsciowego
usbDevice->readUSBReport(interfaceIndex);
if(usbDevice->deviceList[interfaceIndex].inputReportBuffer[6]==64)
break;
}//2
_usbDevice->closeHidUSBDevice(usbDevice->deviceList[interfaceIndex]._
hidDeviceObject);
}//1
releaseMemory(usbDevice->deviceList[interfaceIndex].Path);
releaseMemory(usbDevice->deviceList[interfaceIndex].inputReportBuffer);
// wywolanie destruktora klasy TUSBDevice
releaseMemory(usbDevice);
return 0;
}//0
//---------------------------------------------------------------------------
Przy kompilacji otrzymuję błędy:
[Linker Error] Error: Unresolved external ‘__fastcall Sysutils::StrLCopy(char *, const char *, unsigned int)’ referenced from D:\MOJE DOKUMENTY\BORLAND STUDIO PROJECTS\LISTING_7_2\LISTING_7_2.OBJ
[Linker Error] Error: Unresolved external ‘__fastcall Sysutils::Win32Check(int)’ referenced from D:\MOJE DOKUMENTY\BORLAND STUDIO PROJECTS\LISTING_7_2\LISTING_7_2.OBJ
Wyszykałem podobnych problemów w necie i przypuszczam (może to za dużo powiedziane), że problem leży w odpowiednim zainicjowaniu obu funkcji.
Niestety nie umiem tego zrobić.
Po usunięciu odwołania do pliku sysutils.hpp kompilator zwraca błędy o nieznalezieniu funkcji.
Dziękuję za radę