目前vtoolsd的最新版本为3.0,它支持设备访问体系结构daa(device access architecture),所编写的程序代码将可以在所有windows平台(包括win 95、win 98以及windows nt)上共享。当然也可以使用microsoft公司的ddk(device developer kit)来开发vxd,但ddk不能像vtoolsd那样通过屏蔽系统及vxd的底层技术细节提供丰富的c运行库和c++类库,而是让开发人员充分享用面向对象编程方法的方便与快捷,因此仅就该点而言,使用ddk是不方便的。
4.vxd程序设计实例
我在开发可视电话音频卡的设计过程中,用vtoolsd 2.03、vc++ 5.0为自制的pc/xt总线扩展卡开发了虚拟设备驱动程序audcard.vxd。该卡每20ms申请一次中断,中断由应用程序动态载入系统的audcard.vxd响应并加以处理。中断服务程序isr(interrupt service routine)结束后,调用函数shell_postmessage( )向应用程序窗口发送自定义消息。应用程序接受消息后,再通过函数deviceiocontrol( )与vxd的接口函数onw32deviceiocontrol( )互传缓冲区数据。程序结束即可动态卸载vxd。下图表示在win 95下vxd对硬件中断的处理过程。
图win95下硬件中断的处理过程
当中断发生时,处理器转换为ring0级保护模式。windows系统并不像dos那样通过中断描述符表idt(interrupt descriptor table)直接指向中断处理过程,而是由idt入口指向vmm中的程序。该程序将判断是否为中断调用,如果是,则把中断控制权交给虚拟可编程中断控制器vpicd(virtual programmable interrupt controller device),vpicd实际上是一个重要的vxd。vpicd再将其交给另一个注册了该中断的vxd(如audcard.vxd)来处理。vxd程序是通过调用vpicd服务vpicd_virtualize_irq来注册中断的。
虚拟设备驱动程序audcard.vxd的部分源代码audcard.h和audcard.cpp在网上,网址为:www.pccomputing.com.cn。此应用程序使用了下列函数:createfile()动态加载vxd、closehandle()并动态卸载vxd、pretranslatemessage()截获消息、deviceiocontrol()与vxd互传缓冲区数据。虚拟设备驱动程序audcard.vxd经调试后工作正常,未发生过任何丢失数据或死机的现象。
下面是虚拟设备驱动程序audcard.vxd的部分源代码audcard.h和audcard.cpp,限于篇幅,由quickvxd自动生成的audcard.mak未列出。
①audcard.h
//audcard.h - include file for vxd audcard
#include
#define device_class audcarddevice
#define audcard_deviceid undefined_device_id
#define audcard_init_order undefined_init_order#define audcard_major
#define audcard_minor 0
#define my_irq 5 //定义5号中断
class myhwint:public vhardwareint
{
public:
myhwint():vhardwareint(my_irq,0,0,0){}
virtual void onhardwareint(vmhandle);
};
class audcarddevice : public vdevice
{
public:
virtual bool onsysdynamicdeviceinit();
virtual bool onsysdynamicdeviceexit();
virtual dword onw32deviceiocontrol(pioctlparams pdiocparams);
myhwint* pmyirq;
};
class audcardvm : public vvirtualmachine
{
public:
audcardvm(vmhandle hvm);
};
class audcardthread : public vthread
{
public:
audcardthread(threadhandle hthread);
};