#include "stdafx.h"
#include "usbhidioc.h"
#include "usbhidiocDlg.h"
#include <wtypes.h>
#include <initguid.h>
#define MAX_LOADSTRING 256
extern "C" {
#include "hidsdi.h"
#include <setupapi.h>
#include <dbt.h>
}
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL DeviceNameMatch(LPARAM lParam);
bool FindTheHID();
LRESULT Main_OnDeviceChange(WPARAM wParam, LPARAM lParam);
void CloseHandles();
void DisplayCurrentTime();
void DisplayData(CString cstrDataToDisplay);
void DisplayFeatureReport();
void DisplayInputReport();
void DisplayLastError(CString Operation);
void DisplayReceivedData(char ReceivedByte);
void GetDeviceCapabilities();
void PrepareForOverlappedTransfer();
void ScrollToBottomOfListBox(USHORT idx);
void ReadAndWriteToDevice();
void ReadFeatureReport();
void ReadInputReport();
void RegisterForDeviceNotifications();
void WriteFeatureReport();
void WriteOutputReport();
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
CUsbhidiocDlg::CUsbhidiocDlg(CWnd* pParent )
: CDialog(CUsbhidiocDlg::IDD, pParent)
{
m_AutoIncrement = FALSE;
m_ResultsString = _T("");
m_strBytesReceived = _T("");
m_strByteToSend0 = _T("");
m_strByteToSend1 = _T("");
m_ReportType = 0;
m_UseControlTransfersOnly = FALSE;
m_ProductIDString = _T("6001");
m_VendorIDString = _T("0403");
m_InputReportBufferSize = _T("32");
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
DWORD ActualBytesRead;
DWORD BytesRead;
HIDP_CAPS Capabilities;
DWORD cbBytesRead;
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
HANDLE DeviceHandle;
DWORD dwError;
char FeatureReport[256];
HANDLE hEventObject;
HANDLE hDevInfo;
GUID HidGuid;
OVERLAPPED HIDOverlapped;
char InputReport[256];
ULONG Length;
LPOVERLAPPED lpOverLap;
bool MyDeviceDetected = FALSE;
CString MyDevicePathName;
DWORD NumberOfBytesRead;
char OutputReport[256];
HANDLE ReadHandle;
DWORD ReportType;
ULONG Required;
CString ValueToDisplay;
HANDLE WriteHandle;
int VendorID = 0x0925;
int ProductID = 0x1299;
void CUsbhidiocDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_txtVendorID, m_VendorID);
DDX_Control(pDX, IDC_txtProductID, m_ProductID);
DDX_Control(pDX, IDC_Continuous, m_Continuous);
DDX_Control(pDX, IDC_AutoIncrement, m_cbutAutoIncrement);
DDX_Control(pDX, IDC_cboByteToSend1, m_cboByteToSend1);
DDX_Control(pDX, IDC_cboByteToSend0, m_cboByteToSend0);
DDX_Control(pDX, IDC_lstBytesReceived, m_BytesReceived);
DDX_Control(pDX, IDC_LIST2, m_ResultsList);
DDX_Control(pDX, IDC_Once, m_Once);
DDX_Check(pDX, IDC_AutoIncrement, m_AutoIncrement);
DDX_LBString(pDX, IDC_LIST2, m_ResultsString);
DDX_LBString(pDX, IDC_lstBytesReceived, m_strBytesReceived);
DDX_CBString(pDX, IDC_cboByteToSend0, m_strByteToSend0);
DDX_CBString(pDX, IDC_cboByteToSend1, m_strByteToSend1);
DDX_Radio(pDX, IDC_optExchangeInputAndOutputReports, m_ReportType);
DDX_Check(pDX, IDC_chkUseControlTransfersOnly, m_UseControlTransfersOnly);
DDX_Text(pDX, IDC_txtProductID, m_ProductIDString);
DDX_Text(pDX, IDC_txtVendorID, m_VendorIDString);
DDX_Text(pDX, IDC_txtInputReportBufferSize, m_InputReportBufferSize);
}
BEGIN_MESSAGE_MAP(CUsbhidiocDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_Once, OnOnce)
ON_EN_CHANGE(IDC_Results, OnChangeResults)
ON_BN_CLICKED(IDC_Continuous, OnContinuous)
ON_WM_TIMER()
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_cmdFindMyDevice, On_cmdFindMyDevice)
ON_EN_CHANGE(IDC_txtVendorID, OnChange_txtVendorID)
ON_EN_CHANGE(IDC_txtProductID, OnChange_txtProductID)
ON_BN_CLICKED(IDC_optExchangeInputAndOutputReports, On_optExchangeInputAndOutputReports)
ON_BN_CLICKED(IDC_optExchangeFeatureReports, On_optExchangeFeatureReports)
ON_BN_CLICKED(IDC_chkUseControlTransfersOnly, On_chkUseControlTransfersOnly)
ON_EN_CHANGE(IDC_txtInputReportBufferSize, OnChange_txtInputReportBufferSize)
ON_BN_CLICKED(IDC_cmdInputReportBufferSize, On_cmdInputReportBufferSize)
ON_MESSAGE(WM_DEVICECHANGE, Main_OnDeviceChange)
ON_BN_CLICKED(IDC_BUTTON1, &CUsbhidiocDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
BOOL CUsbhidiocDlg::OnInitDialog()
{
CDialog::OnInitDialog();
int ByteToSend = 0;
CString strByteToSend = "";
CString strComboBoxText="";
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);
MyDeviceDetected=FALSE;
for (ByteToSend=0; ByteToSend < 256; ByteToSend++)
{
strByteToSend.Format("%.2X",ByteToSend);
m_cboByteToSend0.AddString(strByteToSend);
m_cboByteToSend1.AddString(strByteToSend);
}
m_cboByteToSend0.SetCurSel(0);
m_cboByteToSend1.SetCurSel(128);
m_cbutAutoIncrement.SetCheck(1);
m_Continuous.SetWindowText("Continuous");
return TRUE; }
void CUsbhidiocDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CUsbhidiocDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CUsbhidiocDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CUsbhidiocDlg::CloseHandles()
{
if (DeviceHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(DeviceHandle);
}
if (ReadHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(ReadHandle);
}
if (WriteHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(WriteHandle);
}
}
BOOL CUsbhidiocDlg::DeviceNameMatch(LPARAM lParam)
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
DisplayData("MyDevicePathName = " + MyDevicePathName);
if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE lpdbi = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
CString DeviceNameString;
DeviceNameString = lpdbi->dbcc_name;
DisplayData("DeviceNameString = " + DeviceNameString);
if ((DeviceNameString.CompareNoCase(MyDevicePathName)) == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
void CUsbhidiocDlg::DisplayCurrentTime()
{
CTime curTime = CTime::GetCurrentTime();
CString CurrentTime = curTime.Format( "%H:%M:%S, %B %d, %Y" );
DisplayData(CurrentTime);
}
void CUsbhidiocDlg::DisplayData(CString cstrDataToDisplay)
{
USHORT Index;
Index=m_ResultsList.InsertString(-1, (LPCTSTR)cstrDataToDisplay);
ScrollToBottomOfListBox(Index);
}
void CUsbhidiocDlg::DisplayFeatureReport()
{
USHORT ByteNumber;
CHAR ReceivedByte;
m_BytesReceived.ResetContent();
for (ByteNumber=0; ByteNumber < Capabilities.FeatureReportByteLength; ByteNumber++)
{
ReceivedByte = FeatureReport[ByteNumber];
DisplayReceivedData(ReceivedByte);
}
}
void CUsbhidiocDlg::DisplayInputReport()
{
USHORT ByteNumber;
CHAR ReceivedByte;
m_BytesReceived.ResetContent();
for (ByteNumber=0; ByteNumber < Capabilities.InputReportByteLength; ByteNumber++)
{
ReceivedByte = InputReport[ByteNumber];
DisplayReceivedData(ReceivedByte);
}
}
void CUsbhidiocDlg::DisplayLastError(CString Operation)
{
LPVOID lpMsgBuf;
USHORT Index = 0;
CString strLastError = "";
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
strLastError = Operation + (LPCTSTR)lpMsgBuf;
strLastError.TrimRight();
Index = m_ResultsList.InsertString(-1, strLastError);
ScrollToBottomOfListBox(Index);
LocalFree(lpMsgBuf);
}
void CUsbhidiocDlg::DisplayReceivedData(char ReceivedByte)
{
CString strByteRead;
strByteRead.Format("%02X", ReceivedByte);
strByteRead = strByteRead.Right(2);
m_BytesReceived.InsertString(-1, strByteRead);
}
bool CUsbhidiocDlg::FindTheHID()
{
HIDD_ATTRIBUTES Attributes;
DWORD DeviceUsage;
SP_DEVICE_INTERFACE_DATA devInfoData;
bool LastDevice = FALSE;
int MemberIndex = 0;
LONG Result;
CString UsageDescription;
Length = 0;
detailData = NULL;
DeviceHandle=NULL;
HidD_GetHidGuid(&HidGuid);
hDevInfo=SetupDiGetClassDevs
(&HidGuid,
NULL,
NULL,
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
HDEVINFO hDeviceList = SetupDiGetClassDevs (&HidGuid,NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
devInfoData.cbSize = sizeof(devInfoData);
MemberIndex = 0;
LastDevice = FALSE;
_SP_DEVINFO_DATA _info;
ZeroMemory(&_info,sizeof(SP_DEVINFO_DATA));
_info.cbSize = sizeof(SP_DEVINFO_DATA);
int nIndex = 0;
while (SetupDiEnumDeviceInfo (hDeviceList, nIndex++, &_info))
{
do
{
Result=SetupDiEnumDeviceInterfaces
(hDevInfo,
0,
&HidGuid,
MemberIndex,
&devInfoData);
if (Result != 0)
{
Result = SetupDiGetDeviceInterfaceDetail
(hDevInfo,
&devInfoData,
NULL,
0,
&Length,
NULL);
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
Result = SetupDiGetDeviceInterfaceDetail
(hDevInfo,
&devInfoData,
detailData,
Length,
&Required,
NULL);
DeviceHandle=CreateFile
(detailData->DevicePath,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
DisplayLastError("CreateFile: ");
Attributes.Size = sizeof(Attributes);
Result = HidD_GetAttributes
(DeviceHandle,
&Attributes);
DisplayLastError("HidD_GetAttributes: ");
MyDeviceDetected = FALSE;
if (Attributes.VendorID == VendorID)
{
if (Attributes.ProductID == ProductID)
{
MyDeviceDetected = TRUE;
MyDevicePathName = detailData->DevicePath;
DisplayData("Device detected");
RegisterForDeviceNotifications();
GetDeviceCapabilities();
DeviceUsage = (Capabilities.UsagePage * 256) + Capabilities.Usage;
if (DeviceUsage == 0x102)
{
UsageDescription = "mouse";
}
if (DeviceUsage == 0x106)
{
UsageDescription = "keyboard";
}
if ((DeviceUsage == 0x102) | (DeviceUsage == 0x106))
{
DisplayData("");
DisplayData("*************************");
DisplayData("The device is a system " + UsageDescription + ".");
DisplayData("Windows 2000 and Windows XP don't allow applications");
DisplayData("to directly request Input reports from or ");
DisplayData("write Output reports to these devices.");
DisplayData("*************************");
DisplayData("");
}
WriteHandle=CreateFile
(detailData->DevicePath,
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL);
DisplayLastError("CreateFile: ");
PrepareForOverlappedTransfer();
}
else
CloseHandle(DeviceHandle);
}
else
CloseHandle(DeviceHandle);
free(detailData);
}
else
LastDevice=TRUE;
MemberIndex = MemberIndex + 1;
}
while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
}
if (MyDeviceDetected == FALSE)
DisplayData("Device not detected");
else
DisplayData("Device detected");
SetupDiDestroyDeviceInfoList(hDevInfo);
DisplayLastError("SetupDiDestroyDeviceInfoList");
return MyDeviceDetected;
}
void CUsbhidiocDlg::GetDeviceCapabilities()
{
PHIDP_PREPARSED_DATA PreparsedData;
HidD_GetPreparsedData
(DeviceHandle,
&PreparsedData);
DisplayLastError("HidD_GetPreparsedData: ");
HidP_GetCaps
(PreparsedData,
&Capabilities);
DisplayLastError("HidP_GetCaps: ");
ValueToDisplay.Format("%s%X", "Usage Page: ", Capabilities.UsagePage);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Input Report Byte Length: ", Capabilities.InputReportByteLength);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Output Report Byte Length: ", Capabilities.OutputReportByteLength);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Feature Report Byte Length: ", Capabilities.FeatureReportByteLength);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Link Collection Nodes: ", Capabilities.NumberLinkCollectionNodes);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Input Button Caps: ", Capabilities.NumberInputButtonCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of InputValue Caps: ", Capabilities.NumberInputValueCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of InputData Indices: ", Capabilities.NumberInputDataIndices);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Output Button Caps: ", Capabilities.NumberOutputButtonCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Output Value Caps: ", Capabilities.NumberOutputValueCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Output Data Indices: ", Capabilities.NumberOutputDataIndices);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Feature Button Caps: ", Capabilities.NumberFeatureButtonCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Feature Value Caps: ", Capabilities.NumberFeatureValueCaps);
DisplayData(ValueToDisplay);
ValueToDisplay.Format("%s%d", "Number of Feature Data Indices: ", Capabilities.NumberFeatureDataIndices);
DisplayData(ValueToDisplay);
HidD_FreePreparsedData(PreparsedData);
DisplayLastError("HidD_FreePreparsedData: ") ;
}
LRESULT CUsbhidiocDlg::Main_OnDeviceChange(WPARAM wParam, LPARAM lParam)
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
switch(wParam)
{
case DBT_DEVICEARRIVAL:
DisplayData("A device has been attached.");
if (DeviceNameMatch(lParam))
{
DisplayData("My device has been attached.");
}
return TRUE;
case DBT_DEVICEREMOVECOMPLETE:
DisplayData("A device has been removed.");
if (DeviceNameMatch(lParam))
{
DisplayData("My device has been removed.");
MyDeviceDetected = false;
}
return TRUE;
default:
return TRUE;
}
}
void CUsbhidiocDlg::OnChangeResults()
{
}
void CUsbhidiocDlg::OnChange_txtInputReportBufferSize()
{
}
void CUsbhidiocDlg::OnChange_txtProductID()
{
CString ProductIDtext;
CEdit* m_ProductID = (CEdit*) GetDlgItem(IDC_txtProductID);
m_ProductID->GetWindowText(ProductIDtext);
ProductID = strtoul("0x" + ProductIDtext, 0, 16);
MyDeviceDetected=false;
}
void CUsbhidiocDlg::OnChange_txtVendorID()
{
CString VendorIDtext;
CEdit* m_VendorID = (CEdit*) GetDlgItem(IDC_txtVendorID);
m_VendorID->GetWindowText(VendorIDtext);
VendorID = strtoul("0x" + VendorIDtext, 0, 16);
MyDeviceDetected=false;
}
void CUsbhidiocDlg::On_chkUseControlTransfersOnly()
{
}
void CUsbhidiocDlg::OnClose()
{
CDialog::OnClose();
}
void CUsbhidiocDlg::On_cmdFindMyDevice()
{
CUsbhidiocDlg::FindTheHID();
}
void CUsbhidiocDlg::OnContinuous()
{
CString Caption;
m_Continuous.GetWindowText(Caption);
if (Caption == "Continuous")
{
m_Continuous.SetWindowText("Stop Continuous");
ReadAndWriteToDevice();
SetTimer(ID_CLOCK_TIMER, 5000, NULL);
}
else
{
m_Continuous.SetWindowText("Continuous");
KillTimer(ID_CLOCK_TIMER);
}
}
void CUsbhidiocDlg::OnOK()
{
CDialog::OnOK();
}
void CUsbhidiocDlg::OnOnce()
{
ReadAndWriteToDevice();
}
void CUsbhidiocDlg::On_cmdInputReportBufferSize()
{
CString InputReportBufferSizeText;
ULONG InputReportBufferSize;
boolean result;
if (MyDeviceDetected==FALSE)
{
MyDeviceDetected=FindTheHID();
}
if (MyDeviceDetected==TRUE)
{
CEdit* m_InputReportBufferSize = (CEdit*) GetDlgItem(IDC_txtInputReportBufferSize);
m_InputReportBufferSize->GetWindowText(InputReportBufferSizeText);
InputReportBufferSize = strtoul(InputReportBufferSizeText, 0, 10);
result = HidD_SetNumInputBuffers
(DeviceHandle,
InputReportBufferSize);
DisplayLastError("HidD_SetNumInputBuffers: ");
result = HidD_GetNumInputBuffers
(DeviceHandle,
&InputReportBufferSize);
DisplayLastError("HidD_GetNumInputBuffers: ");
if (result)
{
SetDlgItemInt (IDC_txtInputReportBufferSize, InputReportBufferSize);
}
else
{
SetDlgItemInt (IDC_txtInputReportBufferSize, 2);
}
}
}
void CUsbhidiocDlg::On_optExchangeFeatureReports()
{
ReportType = 1;
}
void CUsbhidiocDlg::On_optExchangeInputAndOutputReports()
{
ReportType = 0;
}
void CUsbhidiocDlg::OnTimer(UINT nIDEvent)
{
ReadAndWriteToDevice();
CDialog::OnTimer(nIDEvent);
}
void CUsbhidiocDlg::PrepareForOverlappedTransfer()
{
ReadHandle=CreateFile
(detailData->DevicePath,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
DisplayLastError("CreateFile (ReadHandle): ");
if (hEventObject == 0)
{
hEventObject = CreateEvent
(NULL,
TRUE,
TRUE,
"");
DisplayLastError("CreateEvent: ") ;
HIDOverlapped.hEvent = hEventObject;
HIDOverlapped.Offset = 0;
HIDOverlapped.OffsetHigh = 0;
}
}
void CUsbhidiocDlg::ReadAndWriteToDevice()
{
DisplayData("***HID Test Report***");
DisplayCurrentTime();
if (MyDeviceDetected==FALSE)
{
MyDeviceDetected=FindTheHID();
}
if (MyDeviceDetected==TRUE)
{
switch (ReportType)
{
case 0:
{
WriteOutputReport();
ReadInputReport();
break;
}
case 1:
{
WriteFeatureReport();
ReadFeatureReport();
break;
}
default:
{
break;
}
}
} }
void CUsbhidiocDlg::ReadFeatureReport()
{
CString ByteToDisplay = "";
BOOLEAN Result;
FeatureReport[0]=0;
if (DeviceHandle != INVALID_HANDLE_VALUE)
{
Result = HidD_GetFeature
(DeviceHandle,
FeatureReport,
Capabilities.FeatureReportByteLength);
DisplayLastError("HidD_GetFeature: ");
}
if (!Result)
{
CloseHandles();
DisplayData("Can't read from device");
MyDeviceDetected = FALSE;
}
else
{
DisplayData("Received Feature report: ");
DisplayFeatureReport();
}
}
void CUsbhidiocDlg::ReadInputReport()
{
CString ByteToDisplay = "";
DWORD Result;
InputReport[0]=0;
UpdateData(true);
if (m_UseControlTransfersOnly)
{
if (ReadHandle != INVALID_HANDLE_VALUE)
{
Result = HidD_GetInputReport
(ReadHandle,
InputReport,
Capabilities.InputReportByteLength);
DisplayLastError("HidD_GetInputReport: ");
}
else
{
Result = FALSE;
}
if (!Result)
{
CloseHandles();
DisplayData("Can't read from device");
MyDeviceDetected = FALSE;
}
else
{
DisplayData("Received Input report: ");
DisplayInputReport();
}
}
else
{
if (ReadHandle != INVALID_HANDLE_VALUE)
{
Result = ReadFile
(ReadHandle,
InputReport,
Capabilities.InputReportByteLength,
&NumberOfBytesRead,
(LPOVERLAPPED) &HIDOverlapped);
}
DisplayLastError("ReadFile: ") ;
Result = WaitForSingleObject
(hEventObject,
6000);
DisplayLastError("WaitForSingleObject: ") ;
switch (Result)
{
case WAIT_OBJECT_0:
{
DisplayData("Received Input report,");
break;
}
case WAIT_TIMEOUT:
{
ValueToDisplay.Format("%s", "ReadFile timeout");
DisplayData(ValueToDisplay);
Result = CancelIo(ReadHandle);
CloseHandles();
DisplayData("Can't read from device");
MyDeviceDetected = FALSE;
break;
}
default:
{
ValueToDisplay.Format("%s", "Undefined error");
CloseHandles();
DisplayData("Can't read from device");
MyDeviceDetected = FALSE;
break;
}
}
ResetEvent(hEventObject);
DisplayInputReport();
}
}
void CUsbhidiocDlg::RegisterForDeviceNotifications()
{
DEV_BROADCAST_DEVICEINTERFACE DevBroadcastDeviceInterface;
HDEVNOTIFY DeviceNotificationHandle;
DevBroadcastDeviceInterface.dbcc_size = sizeof(DevBroadcastDeviceInterface);
DevBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
DevBroadcastDeviceInterface.dbcc_classguid = HidGuid;
DeviceNotificationHandle =
RegisterDeviceNotification(m_hWnd, &DevBroadcastDeviceInterface, DEVICE_NOTIFY_WINDOW_HANDLE);
}
void CUsbhidiocDlg::ScrollToBottomOfListBox(USHORT Index)
{
m_ResultsList.SetCurSel( Index );
m_ResultsList.SetCurSel( -1 );
}
void CUsbhidiocDlg::WriteFeatureReport()
{
DWORD BytesWritten = 0;
INT Index =0;
ULONG Result;
CString strBytesWritten = "";
FeatureReport[0]=0;
if (m_cbutAutoIncrement.GetCheck()>0)
{
Index=m_cboByteToSend0.GetCurSel();
Index=Index+1;
m_cboByteToSend0.SetCurSel(Index);
}
if (m_cbutAutoIncrement.GetCheck()>0)
{
Index=m_cboByteToSend1.GetCurSel();
Index=Index+1;
m_cboByteToSend1.SetCurSel(Index);
}
FeatureReport[1]=m_cboByteToSend0.GetCurSel();
FeatureReport[2]=m_cboByteToSend1.GetCurSel();
FeatureReport[0]=0;
if (DeviceHandle != INVALID_HANDLE_VALUE)
{
Result = HidD_SetFeature
(DeviceHandle,
FeatureReport,
Capabilities.FeatureReportByteLength);
}
DisplayLastError("HidD_SetFeature: ");
if (!Result)
{
CloseHandles();
DisplayData("Can't write to device");
MyDeviceDetected = FALSE;
}
else
{
DisplayData("A Feature report was written to the device.");
}
}
void CUsbhidiocDlg::WriteOutputReport()
{
DWORD BytesWritten = 0;
INT Index =0;
ULONG Result;
CString strBytesWritten = "";
UpdateData(true);
OutputReport[0]=0;
if (m_cbutAutoIncrement.GetCheck()>0)
{
Index=m_cboByteToSend0.GetCurSel();
Index=Index+1;
m_cboByteToSend0.SetCurSel(Index);
}
if (m_cbutAutoIncrement.GetCheck()>0)
{
Index=m_cboByteToSend1.GetCurSel();
Index=Index+1;
m_cboByteToSend1.SetCurSel(Index);
}
OutputReport[1]=m_cboByteToSend0.GetCurSel();
OutputReport[2]=m_cboByteToSend1.GetCurSel();
OutputReport[0]=0;
if (m_UseControlTransfersOnly)
{
if (WriteHandle != INVALID_HANDLE_VALUE)
{
Result = HidD_SetOutputReport
(WriteHandle,
OutputReport,
Capabilities.OutputReportByteLength);
DisplayLastError("HidD_SetOutputReport: ");
}
if (Result)
{
DisplayData("An Output report was written to the device.");
}
else
{
CloseHandles();
DisplayData("Can't write to device");
MyDeviceDetected = FALSE;
}
}
else
{
if (WriteHandle != INVALID_HANDLE_VALUE)
{
Result = WriteFile
(WriteHandle,
OutputReport,
Capabilities.OutputReportByteLength,
&BytesWritten,
NULL);
}
DisplayLastError("WriteFile: ");
if (!Result)
{
CloseHandles();
DisplayData("Can't write to device");
MyDeviceDetected = FALSE;
}
else
{
DisplayData("An Output report was written to the device.");
strBytesWritten.Format("%s%d", "Bytes Written: ", BytesWritten);
DisplayData(strBytesWritten);
}
}
}
void CUsbhidiocDlg::OnBnClickedButton1()
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;
hDevInfo = SetupDiGetClassDevs(NULL,
0, 0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );
if (hDevInfo == INVALID_HANDLE_VALUE)
{
return;
}
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR buffer = NULL;
DWORD buffersize = 0;
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_DEVICEDESC,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
{
if (buffer) LocalFree(buffer);
buffer = new TCHAR[buffersize * 2];
}
else
{
break;
}
}
CString tempStr;
tempStr = "Result:";
tempStr = tempStr + buffer;
DisplayData(tempStr);
if (buffer) LocalFree(buffer);
}
if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS )
{
return;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return;
}</dbt.h></setupapi.h></initguid.h></wtypes.h>