新增功能中,主要完成的两个功能就是KeyID的读取和修改,即实现Get_KeyID和Set_KeyID功能。程序构思大致是:对于Get_KeyID,在接收到PC端发来的读取KeyID的中断后,立即从端点1发送8字节的KeyID,这一段没有什么特别之处;对于Set_KeyID,在接收到信号后,立即转入Set_KeyID子程序。首先将存储KeyID的Flash去保护,然后寄存器置位,即在硬件上给Flash一个高电平,接着进行擦除,再将保存于缓冲区的PC发来的新KeyID存储到Flash中。最后,置Flash状态寄存器位,给Flash加保护。
2.4 PC端新增功能的USB驱动程序设计
Windows 98的驱动程序从结构上来说分为两层:内核层和用户层。USB的客户驱动程序属于用户层,而USB类驱动程序和底层驱动程序则属于内核层。目前,USB还属于起步阶段,Windows对USB的支持还不够完善,仅支持内核层。USB开发人员所要做的,就是开发客户驱动程序,直接与类驱动程序打交道。
HID属于USB设备类中的一个子类,Windows对它提供了非常强大的支持,尤其是在用户层提供了Hid.dll,其中包含了用户层驱动程序与类驱动程序通信需要的各种功能模块,将它们以API的形式提供给用户函数接口。这样,在编写客户驱动程序的时候就可以直接调用这些API函数来完成诸如IN、OUT等功能,大大降低了编写驱动程序的难度。
HID客户驱动程序访问HID类驱动程序,由HID类驱动程序完成大多数工作,而硬件交互由HID小驱动程序HidUsb.sys处理,HID小驱动程序调用USB底层驱动程序USBD.sys访问设备。
这里介绍用户模式的HID客户驱动程序设计过程。它主要包括三个方面的工作:
·查找所有HID设备;
·对于查找到的每一个HID设备,检查其功能,判断是否为感兴趣的设备;
·根据用户需要读取HID输入Report(Feature)或者写HID输出Report(Feature)。
程序流程如下:
(1)查找USB安全钥设备;
(2)读取HID设备功能;
(3)具体实现Get_KeyID和Set_KeyID子函数;
BOOL CUsbKey::GetKeyID() //Get_KeyID子程序
{...
result=HidD_GetFeature(HidDevice, ReadBuffer,0x09);
//调用此函数,获取从端点1发来的8字节KeyID;
for(tmpInt=0;tmpInt
KeyID_Get[tmpInt]=ReadBuffer[tmpInt+1];
return TRUE;
}
BOOL CUsbKey::SetKeyID() // Set_KeyID子程序
{ int i;
long result;
int DataBuffer[16];
WriteBuffer[0]=0; //写缓冲区首字节清0,作为Set_Feature函数的要求
char *c; //获得对话框内输入8字节新KeyID字符串的指针
c=(char *)(LPCSTR)str_KeyIDSet;
for (i=0;i
DataBuffer[i]=*c++;
…… //此处省略了对输入的8个字节的KeyID的16进制检查代码
for(i=0;i<8;i++)
WriteBuffer[i+1]=DataBuffer[2*i]+DataBuffer[2*i+1];
result=HidD_SetFeature(HidDevice,WriteBuffer, 0x09);
return TRUE;
}
(4)程序运行结果。
编译连接之后,最终会生成可执行文件KEYDEMO.exe。执行它即可SK通信,实现各种功能。