📄 usbadcserverdlg.cpp
字号:
SP_DEVINFO_DATA did = {sizeof(SP_DEVINFO_DATA)};
if(SetupDiGetDeviceInterfaceDetail(hDevInfo,&ifData,detail,needed,NULL,&did)){
if( strstr(detail->DevicePath,"vid_4d41") != NULL &&
strstr(detail->DevicePath,"pid_464c") != NULL ){
DevicePath = detail->DevicePath;
DevicePath.MakeUpper();
break;
}
}
delete[] (PBYTE)detail;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
hHidDevice = CreateFile((LPCTSTR)DevicePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(hHidDevice != INVALID_HANDLE_VALUE){
PHIDD_ATTRIBUTES Attributes = (PHIDD_ATTRIBUTES)malloc(sizeof(HIDD_ATTRIBUTES));
if(HidD_GetAttributes(hHidDevice,Attributes)){
PHIDP_PREPARSED_DATA PreParsedData;
HidD_GetPreparsedData(hHidDevice,&PreParsedData);
HidP_GetCaps(PreParsedData,&pDevCapabilities);
m_vUsbName.Format("PID%04X VID%04X REV%04X IN%02X OUT%02X",
Attributes->ProductID,Attributes->VendorID,Attributes->VersionNumber,
pDevCapabilities.InputReportByteLength,pDevCapabilities.OutputReportByteLength );
memset(Product,0,24);
HidD_GetSerialNumberString(hHidDevice,(PVOID)Product,26);
CString tmpStr;
DeviceSN.Empty();
for(int i=0;i<12;i++){
tmpStr.Format("%02X",(unsigned char)Product[i*2]);
DeviceSN+=tmpStr;
if(i%2==1)DeviceSN+=" ";
}
m_vUsbsn=DeviceSN;
if(ThreadOpened == FALSE){
if(_beginthread(RecvThreadFunction, 0, hHidDevice) >= 0){ //打开接收线程
CreateThreadWR();
GetDlgItem(IDC_BTN_MANUAL)->EnableWindow(1);
GetDlgItem(IDC_BTN_SFILE)->EnableWindow(1);
ThreadOpened = TRUE;
}
}
}
}else{
ThreadOpened = FALSE;
//bThreadGoing = FALSE;
GetDlgItem(IDC_BTN_MANUAL)->EnableWindow(0);
GetDlgItem(IDC_BTN_SFILE)->EnableWindow(0);
m_vUsbName ="设备未连接!";
m_vUsbsn ="";
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
DWORD WINAPI CUSBADCserverDlg::WriteReport(void *)
{
static DWORD NumberOfBytesWriten; //must be global variable or static variable
static OVERLAPPED HidOverlapped;
while(TRUE){
if(WRITE_ROPRT){
if(hHidDevice != INVALID_HANDLE_VALUE){
WriteFile(hHidDevice,OutputReport,pDevCapabilities.OutputReportByteLength,
&NumberOfBytesWriten,(LPOVERLAPPED)&HidOverlapped);
WRITE_ROPRT = FALSE;
}
}
_sleep(10);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//建立线程
DWORD CUSBADCserverDlg::CreateThreadWR()
{
if(hWriteThread!= NULL) CloseHandle(hWriteThread);
hWriteThread = CreateThread(NULL,0,WriteReport,NULL,0,&WriteThreadId);
if(hWriteThread == NULL)AfxMessageBox("建立写线程错误,错误号为: %d !",GetLastError());
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//接收线程,程序启动即开始运行监测USB数据接收
void __cdecl RecvThreadFunction(HANDLE hHidDevice)
{
CString msg;
UINT i;
DWORD recvdBytes;
HANDLE hIOWaiter = CreateEvent(NULL, TRUE, FALSE, NULL);
if(hIOWaiter == NULL) goto exit2;
OVERLAPPED OverLapped;
OverLapped.Offset = 0;
OverLapped.OffsetHigh = 0;
OverLapped.hEvent = hIOWaiter;
for(i=0;bThreadGoing ==TRUE;i++){
if(i>=IN_REPORTS_NUM)i=0;
ResetEvent(hIOWaiter);
if(!ReadFile(hHidDevice, &InputReport[i], pDevCapabilities.InputReportByteLength, &recvdBytes, &OverLapped)) { //ReadFile->
DWORD err = GetLastError();
if(err != ERROR_IO_PENDING && err != ERROR_DEVICE_NOT_CONNECTED && bThreadGoing){
msg.Format("读操作错误: %d", err);
AfxMessageBox(msg); goto exit1; //未知异常退出
}
while(WaitForSingleObject(hIOWaiter, 1) == WAIT_TIMEOUT){
if(!bThreadGoing){ //查询读中止标志
if(hHidDevice != INVALID_HANDLE_VALUE){
CancelIo(hHidDevice);
}
goto exit1;
}
}
if(!GetOverlappedResult(hHidDevice, &OverLapped, &recvdBytes, false)){
err = GetLastError();
if(err != ERROR_DEVICE_NOT_CONNECTED && bThreadGoing){
msg.Format("GetOverlappedResult例程错误: %d", err);
AfxMessageBox(msg); //例和出错
if(hHidDevice != INVALID_HANDLE_VALUE){
CancelIo(hHidDevice);
}
goto exit1;
}
}
}
AfxGetMainWnd()->SendMessage(IDM_RECV_DATA,(UINT )i, (LPARAM)(&InputReport[i]));
}
exit1:
CloseHandle(hIOWaiter);
exit2:
_endthread();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
LONG CUSBADCserverDlg::OnReceivedData(UINT wParam, LONG lParam)
{
CString tmpStr;
if(bAutoClear)m_vRecv = "";
for(int i=0;i< pDevCapabilities.InputReportByteLength ;i++){
FileBuffer[FilePos]=InputReport[wParam][i];
if(++FilePos > FILE_MAX_SIZE) FilePos = FILE_MAX_SIZE;
tmpStr.Format("%02X ",InputReport[wParam][i]);
m_vRecv += tmpStr;
}
dReportsRecv ++;
return (LRESULT) 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnManual()
{
int i,m;
u8 hexbuf[1024];
u8 chrbuf[2048];
if(ThreadOpened==FALSE)return;
UpdateData(TRUE);
m = m_vSend.GetLength();
if(m>2048)m=2048;
if(m==0)return;
for(i=0;i<m;i++)chrbuf[i]=m_vSend.GetAt(i);
for(;i<2048;i++) chrbuf[i]=0;
m/=2;
StringToHex(chrbuf,hexbuf,m);
if( m > pDevCapabilities.OutputReportByteLength)
m = pDevCapabilities.OutputReportByteLength;
for(i=0;i<m;i++)OutputReport[i]= hexbuf[i];
m_vSend="";
m_vRecv="";
m_vCnts.Format("%d",++dReportsSent);
m_cCnts.SetWindowText(m_vCnts);
WRITE_ROPRT = TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnSfile()
{
DWORD i;
CFileDialog FileDialog(TRUE,NULL,"",OFN_HIDEREADONLY,"USB数据文件(*.BIN)|*.BIN|所有类型 (*.*)|*.*||");
if(FileDialog.DoModal()!=IDOK)return ;
CString PathFile = FileDialog.GetPathName();
CString ExtFile = FileDialog.GetFileExt();
CFile pDataFile;
if(!pDataFile.Open(PathFile,CFile::typeBinary|CFile::modeRead,NULL)){
AfxMessageBox("建立文件错误\r\n"+PathFile);
return ;
}
DWORD m = pDataFile.GetLength();
if(m > pDevCapabilities.OutputReportByteLength)
m = pDevCapabilities.OutputReportByteLength;
for(i=0;i< pDevCapabilities.OutputReportByteLength ; i++)
OutputReport[i]=0;
pDataFile.Read(OutputReport,m);
pDataFile.Close();
if(m==0)return;
CString tmpStr;
m_vSend = "";
for(i=0;i<m;i++){
tmpStr.Format("%02X ",OutputReport[i]);
m_vSend += tmpStr;
}
m_cSend.SetWindowText(m_vSend);
m_vRecv="";
m_cRecv.SetWindowText(m_vRecv);
m_vCnts.Format("%d",++dReportsSent);
m_cCnts.SetWindowText(m_vCnts);
WRITE_ROPRT = TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnRclear()
{
m_vRecv = "";
m_cRecv.SetWindowText(m_vRecv);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnCheckRfile()
{
DWORD tm,md;
CString FileName = m_vUsbName + " " + m_vUsbsn + ".BIN";
CFileDialog FileDialog(TRUE,NULL,FileName,OFN_HIDEREADONLY,"USB数据文件(*.BIN)|*.BIN|所有类型 (*.*)|*.*||");
if(FileDialog.DoModal()!=IDOK)return ;
CString PathFile = FileDialog.GetPathName();
CString ExtFile = FileDialog.GetFileExt();
if(!pDataFile.Open(PathFile,CFile::typeBinary|CFile::modeWrite|CFile::modeCreate,NULL)){
AfxMessageBox("建立文件错误\r\n"+PathFile);
return ;
}
tm = FilePos / FILE_PAGE_SIZE;
md = FilePos % FILE_PAGE_SIZE;
FilePos = 0;
for(DWORD i=0;i<tm;i++)pDataFile.Write(FileBuffer,i * FILE_PAGE_SIZE);
pDataFile.Write(FileBuffer,i * FILE_PAGE_SIZE + md);
pDataFile.Close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnCheckAutos()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
UINT n = m_iPeriod;
if(n<3)n=3;
if(m_cAutoS.GetCheck()) SetTimer(TIMER_AUTOS,n,NULL);
else KillTimer(TIMER_AUTOS);
UpdateData(FALSE);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnCheckAutoc()
{
// TODO: Add your control notification handler code here
if(m_cAutoC.GetCheck()) bAutoClear=TRUE;
else bAutoClear=FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnBtnClear()
{
// TODO: Add your control notification handler code here
dReportsSent = dReportsRecv =0;
m_vCnts.Format("%d",dReportsSent);
m_cCnts.SetWindowText(m_vCnts);
m_vCntr.Format("%d",dReportsRecv);
m_cCntr.SetWindowText(m_vCntr);
FilePos = 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void CUSBADCserverDlg::OnOk()
{
// TODO: Add your control notification handler code here
if(hHidDevice !=INVALID_HANDLE_VALUE)CloseHandle(hHidDevice);
if(hWriteThread !=INVALID_HANDLE_VALUE)CloseHandle(hWriteThread);
CDialog::OnOK();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//功能: 将字符串转换成为十六进制数,
//输入: str: 输入字符串,其数据有效为'0'~09','a'~'f','A'~'F',间隔符可有可无,有时须是数据之外的
// hex: 输出数据指针
// len: 输出数据缓冲最大长度,若字符串数据不够,返回实际个数,超出时返回len
//返回: 输出数据字节数
u16 StringToHex(u8 *str,u8 *hex,u16 len)
{
u16 i,j;
u8 chnew,chold;
u8 begin,stop;
begin=0;stop=0;chold=0;
for(i=0,j=0;j/2<len;i++){
chnew=*(str+i);
if (chnew==0) break;
else if (chnew>='0'&&chnew<='9') {chnew=chnew-'0';}
else if (chnew>='a'&&chnew<='f') {chnew=chnew-'a'+10;}
else if (chnew>='A'&&chnew<='F') {chnew=chnew-'A'+10;}
else {chnew=16;}
if(chnew<16){
if(j%2==0) hex[j/2] =chnew*16;
else hex[j/2]+=chnew;
j++;
}else if(chold<16){
if(j%2==1) {
hex[(j-1)/2]/=16;
j++;
}
}
chold=chnew;
}
for(i=j/2;i<len;i++)hex[i]=0; //结束符后全清零
return j/2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -