📄 termsdriver.c
字号:
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <basetyps.h>
#include <winioctl.h>
#include "hidsdi.h"
#include <setupapi.h>
#include <malloc.h>
#include "usbioctl.h"
#include "usbdesc.h"
#include "TermsDriver.h"
#define TermsDriver(foo) Java_TermsDriver_ ## foo
typedef struct _STRING_DESCRIPTOR_NODE
{
struct _STRING_DESCRIPTOR_NODE *Next;
UCHAR DescriptorIndex;
USHORT LanguageID;
USB_STRING_DESCRIPTOR StringDescriptor[0];
} STRING_DESCRIPTOR_NODE, *PSTRING_DESCRIPTOR_NODE;
//------------读写事件,用于检测超时时间内的动作-----------
HANDLE ReadEventObject;
HANDLE WriteEventObject;
//---------------------------------------------------------
HANDLE TermsDriver(hcom)=NULL;
//---------------打印设备与HID设备的GUID-------------------
GUID DeviceGuid;
//---------------------------------------------------------
//---------------HID设备的能力描述符-----------------------
HIDP_CAPS Capabilities;
//---------------------------------------------------------
//---------------设备接口细节------------------------------
PSP_DEVICE_INTERFACE_DETAIL_DATA DetailData;
//---------------------------------------------------------
//---------------非阻塞读写标志----------------------------
OVERLAPPED HIDOverlappedRead;
OVERLAPPED HIDOverlappedWrite;
//---------------------------------------------------------
//---------------获得HID设备能力---------------------------
void GetDeviceCapabilities(){
PHIDP_PREPARSED_DATA PreparsedData; //预解析数据,装载设备能力的描述
HidD_GetPreparsedData(TermsDriver(hcom),&PreparsedData);
HidP_GetCaps(PreparsedData,&Capabilities); //将预解析数据填入设备能力描述符结构体中
HidD_FreePreparsedData(PreparsedData); //释放资源
}
//---------------------------------------------------------
//---------------HID设备传输有阻塞的可能,该函数为非阻塞模式传输定义事件------
void PreparedForOverlappedTransfer(){
if(ReadEventObject==NULL){
ReadEventObject=CreateEvent(NULL,TRUE,TRUE,"");
HIDOverlappedRead.hEvent=ReadEventObject;
HIDOverlappedRead.Offset=0;
HIDOverlappedRead.OffsetHigh=0;
}
if(WriteEventObject==NULL){
WriteEventObject=CreateEvent(NULL,TRUE,TRUE,"");
HIDOverlappedWrite.hEvent=WriteEventObject;
HIDOverlappedWrite.Offset=0;
HIDOverlappedWrite.OffsetHigh=0;
}
}
//----------------打印设备寻找字符串的私有函数--------------------------------
BOOL AreThereManufacturerStringDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDesc){
if(DeviceDesc->iManufacturer)
return TRUE;
else
return FALSE;
}
PUSB_STRING_DESCRIPTOR GetManufacturerStringDescriptor(HANDLE hUSBDevice,
unsigned long index,
PUSB_DEVICE_DESCRIPTOR DeviceDesc)
{
//PSTRING_DESCRIPTOR_NODE supportedLanguagesString;
//PSTRING_DESCRIPTOR_NODE stringDescNodeTail;
unsigned char DescriptorIndex=0x00;
unsigned short LanguageID=0;
unsigned char stringDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST)+
MAXIMUM_USB_STRING_LENGTH];
BOOL success;
unsigned long nBytes;
unsigned long nBytesReturned;
//unsigned long numLanguageIDs;
//unsigned short *languageIDs;
PUSB_DESCRIPTOR_REQUEST stringDescReq;
PUSB_STRING_DESCRIPTOR stringDesc;
PSTRING_DESCRIPTOR_NODE stringDescNode;
nBytes = sizeof(stringDescReqBuf);
stringDescReq = (PUSB_DESCRIPTOR_REQUEST)stringDescReqBuf;
stringDesc = (PUSB_STRING_DESCRIPTOR)(stringDescReq+1);
DescriptorIndex=DeviceDesc->iManufacturer;
// Zero fill the entire request structure
//
memset(stringDescReq, 0, nBytes);
stringDescReq->ConnectionIndex = index;
stringDescReq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8)
| DescriptorIndex;
stringDescReq->SetupPacket.wIndex = LanguageID;
stringDescReq->SetupPacket.wLength = (unsigned short)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST));
// Now issue the get descriptor request.
//
success = DeviceIoControl(hUSBDevice,
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
stringDescReq,
nBytes,
stringDescReq,
nBytes,
&nBytesReturned,
NULL);
if(!success)
{
return NULL;
}
if (nBytesReturned < 2)
{
return NULL;
}
if (stringDesc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE)
{
return NULL;
}
if (stringDesc->bLength != nBytesReturned - sizeof(USB_DESCRIPTOR_REQUEST))
{
return NULL;
}
if (stringDesc->bLength % 2 != 0)
{
return NULL;
}
//
// Looks good, allocate some (zero filled) space for the string descriptor
// node and copy the string descriptor to it.
//
stringDescNode = (PSTRING_DESCRIPTOR_NODE)malloc(sizeof(STRING_DESCRIPTOR_NODE) +
stringDesc->bLength);
if (stringDescNode == NULL)
{
return NULL;
}
memcpy(stringDescNode->StringDescriptor,
stringDesc,
stringDesc->bLength);
return stringDescNode->StringDescriptor;
}
void EnumerateDevice(HANDLE hUSBDevice,unsigned char buf[]){
BOOL success;
PUSB_NODE_CONNECTION_INFORMATION connectionInfo;
//PUSB_DESCRIPTOR_REQUEST configDesc;
PUSB_STRING_DESCRIPTOR stringDescs;
unsigned long nBytes;
nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) +
sizeof(USB_PIPE_INFO) * 30;
connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)malloc(nBytes);
if(connectionInfo==NULL){
}
else{
connectionInfo->ConnectionIndex = 0;
success = DeviceIoControl(hUSBDevice,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,
connectionInfo,
nBytes,
connectionInfo,
nBytes,
&nBytes,
NULL);
if (AreThereManufacturerStringDescriptor(&connectionInfo->DeviceDescriptor)){
stringDescs = GetManufacturerStringDescriptor(
hUSBDevice,
0,
&connectionInfo->DeviceDescriptor);
//buf=stringDescs->bString[0];
memcpy(buf,stringDescs->bString[0],sizeof(stringDescs->bString[0]));
free(connectionInfo);
}
}
}
//----------------------------------------------------------------------------
//----------------当printFlag为TRUE时寻找打印设备,否则寻找HID类设备----------
//----------------找寻设备一共分为8步-----------------------------------------
// 1、获取对应的USB类设备的GUID
// 2、获得拥有该GUID类的设备的集合
// 3、遍历设备集合里每一个设备的接口标识
// 4、获取每一个标识下接口的详细数据结构
// 5、获取设备路径,打开设备
// 6、获得设备的字符串描述符
// 7、与既定规则进行比较
// 8、如果不符合,关闭设备,继续寻找;如果符合,继续操作。
//---------------------------------------------------------------------------
BOOL SearchDevices(byte deviceType[],BOOL printFlag){
HIDD_ATTRIBUTES attributes;
BOOL LastDevice=FALSE;
BOOL DeviceDetected=FALSE;
long Required;
HANDLE hDevInfo;
SP_DEVICE_INTERFACE_DATA DevInfoData;
int Length,i,MemberIndex,Result;
unsigned char tmpStr[128];
unsigned char str[64];
unsigned char str1[10];
memset(tmpStr,0x00,128);
memset(str,0x00,64);
memset(str1,0x00,10);
if(printFlag==TRUE){
printf("1 haha!\n");
//--------获取Print类设备的GUID---------
DeviceGuid.Data1 = 0x28d78fad;
DeviceGuid.Data2 = 0x5a12;
DeviceGuid.Data3 = 0x11D1;
DeviceGuid.Data4[0] = 0xae;
DeviceGuid.Data4[1] = 0x5b;
DeviceGuid.Data4[2] = 0x00;
DeviceGuid.Data4[3] = 0x00;
DeviceGuid.Data4[4] = 0xf8;
DeviceGuid.Data4[5] = 0x03;
DeviceGuid.Data4[6] = 0xa8;
DeviceGuid.Data4[7] = 0xc2;
//--------------------------------------
/*
//-------获取Print蕾设备的GUID2---------
DeviceGuid.Data1 = 0x36FC9E60;
DeviceGuid.Data2 = 0xC465;
DeviceGuid.Data3 = 0x11CF;
DeviceGuid.Data4[0] = 0x80;
DeviceGuid.Data4[1] = 0x56;
DeviceGuid.Data4[2] = 0x44;
DeviceGuid.Data4[3] = 0x45;
DeviceGuid.Data4[4] = 0x53;
DeviceGuid.Data4[5] = 0x54;
DeviceGuid.Data4[6] = 0x00;
DeviceGuid.Data4[7] = 0x00;
//--------------------------------------
*/
//-------获得指定类的设备集合-----------
hDevInfo=SetupDiGetClassDevs(&DeviceGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
//--------------------------------------
DevInfoData.cbSize=sizeof(DevInfoData);
MemberIndex=0;
LastDevice=FALSE;
//-------遍历该类下每一个设备-----------
do{
//---获取设备的标识结构-------------
Result=SetupDiEnumDeviceInterfaces(hDevInfo,
0,
&DeviceGuid,
MemberIndex,
&DevInfoData);
if(Result!=0){
//---获得用于分配PSP_DEVICE_INTERFACE_DETAIL_DATA的空间的长度---
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);
printf("path is %s\n",DetailData->DevicePath);
//----获取设备路径,以非独占、非阻塞方式打开设备----
//----以非阻塞方式打开USB口设备-------------------
TermsDriver(hcom)=CreateFile(DetailData->DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
/*
//-----获得厂商字符串,然后进行比较-----
//HidD_GetManufacturerString(TermsDriver(hcom),
// tmpStr,
// 128);
EnumerateDevice(TermsDriver(hcom),tmpStr);
//-----将Unicode编码转化为ASCII码-------
for(i=0;i<64;i++){
str[i]=tmpStr[2*i];
}
//--------------------------------------
str1[0]=str[12];// I
str1[1]=str[13];// C
str1[2]=str[14];// B
str1[3]=str[15];// C
//----------------比较细则--------------
if(strcmp(deviceType,"pr2")==0||strcmp(deviceType,"Ar2400")==0){
str1[4]=str[16];
if(strcmp(str1,"ICBC1")==0||strcmp(str1,"ICBC0")==0){
DeviceDetected=TRUE;
PreparedForOverlappedTransfer();
}
}else{
if(strcmp(deviceType,"scanner")==0){
str1[4]=str[16];
if(strcmp(str1,"ICBC2")==0){
DeviceDetected=TRUE;
PreparedForOverlappedTransfer();
}else{
if(strcmp(str1,"ICBC0")==0){
str1[5]=str[17];
if(strcmp(str1,"ICBC01")==0){
DeviceDetected=TRUE;
PreparedForOverlappedTransfer();
}else{
//CloseHandle(TermsDriver(hcom));
}
}else {
//CloseHandle(TermsDriver(hcom));
}
}
}
}
//--------------------------------------------------
*/
DeviceDetected=TRUE;
LastDevice=TRUE;
PreparedForOverlappedTransfer();
free(DetailData);
}else
LastDevice=TRUE;
MemberIndex=MemberIndex+1;
}while(LastDevice!=TRUE&&DeviceDetected!=TRUE);
SetupDiDestroyDeviceInfoList(hDevInfo);
return DeviceDetected;
}else{
//------------------寻找HID类设备--------------------
memset(tmpStr,0x00,128);//厂商Unicode编码的字符串
memset(str,0x00,64);//厂商Unicode编码高位编码
memset(str1,0x00,10);
LastDevice=FALSE;
DeviceDetected=FALSE;
MemberIndex=0;
Result=0;
Length=0;
i=0;
TermsDriver(hcom)=NULL;
//获得HID类型设备的Guid
HidD_GetHidGuid(&DeviceGuid);
hDevInfo=SetupDiGetClassDevs(&DeviceGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
DevInfoData.cbSize=sizeof(DevInfoData);
do
{
Result=SetupDiEnumDeviceInterfaces(hDevInfo,
0,
&DeviceGuid,
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);
TermsDriver(hcom)=CreateFile(DetailData->DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
attributes.Size=sizeof(attributes);
DeviceDetected=FALSE;
Result=HidD_GetAttributes(TermsDriver(hcom),&attributes);
HidD_GetManufacturerString(TermsDriver(hcom),
tmpStr,
128);
for(i=0;i<64;i++){
str[i]=tmpStr[2*i];
}
str1[0]=str[12];
str1[1]=str[13];
str1[2]=str[14];
str1[3]=str[15];
if(strcmp(deviceType,"PinKey")==0){
str1[4]=str[16];
if(strcmp(str1,"ICBC1")==0){
DeviceDetected=TRUE;
GetDeviceCapabilities();
PreparedForOverlappedTransfer();
}
else
if(strcmp(str1,"ICBC0")==0){
str1[5]=str[17];
if(strcmp(str1,"ICBC01")==0){
DeviceDetected=TRUE;
GetDeviceCapabilities();
PreparedForOverlappedTransfer();
}else{
//CloseHandle(TermsDriver(hcom));
}
}
}
if(strcmp(deviceType,"MSFDriver")==0){
str1[4]=str[16];
if(strcmp(str1,"ICBC2")==0){
DeviceDetected=TRUE;
GetDeviceCapabilities();
PreparedForOverlappedTransfer();
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -