国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

詳述C++語言的VxD與外界通訊的所有接口

2019-11-17 05:09:30
字體:
來源:轉載
供稿:網友
一.什么是VxD?

  從多任務操作系統Windows 3.1起,計算機中的任一物理設備x可同時被基于Dos或Windows的多個進程使用,這種一對多的關系稱為"設備虛擬化",各進程通過運行在核心層的VxD(虛擬x設備驅動程序)存取物理設備x.操作系統提供給用戶的軟件服務也可以用VxD實現.計算機中的其它資源,如CPU,內存等也可同時被多個進程使用,各進程在系統提供的虛擬機(VM)環境下存取這類資源.
  VxD可由虛擬機治理器(VMM)在開機時裝入核心層(稱靜態裝入,即置VxD于c:/windows/system目錄下,在c:/windows/system.ini文件中,對節[386Enh]加一行"device=此VxD文件名"),或由應用程序實時裝入(稱動態裝入),而后,各進程便可存取鎖定在內存中的VxD數據區,以實時控制VxD的行為,VxD的內部結構可防止兩個進程同時存取其數據區.VxD通過響應VMM發給它的事件與外界交互.  Windows 95中,基于Dos的每個進程在單獨的VM中運行(稱在V86模式下運行),既可按Dos單進程方式,在640k低內存中運行(稱在實模式下運行),又可利用多進程環境的優點,在整個內存中運行(稱在保護模式下運行),以通過95的DPMI接口存取內存高端的Windows圖形環境.其它16位或32位應用程序均在同一系統VM中運行.  下面只討論95環境下的VxD.  二. VxD的創建:  1. 由匯編語言創建VxD:需安裝微軟公司的Win32 SDK及DDK.  2. 由C或C++語言創建VxD:需安裝VC2.0或BC4.0,及Vireo Software公司的VToolsD軟件包.VToolsD含3個實用工具:可創建VxD框架的QuickVxD;可動態裝卸VxD的VxD Loader;可顯示內存VxD特性的VxD Viewer;  QuickVxD含7個對話頁:  (1) Device Parameters頁包括:最多8個字符的VxD名,唯一標識號(ID),相對其它VxD的裝入順序(VxD Viewer可顯出某VxD的裝入順序值Init Order,若指定新VxD的裝入順序小于此Init Order,則新VxD將在此VxD前被裝入),實現語言(C或C++),靜、動態裝入方式等.  (2) VxD Services頁包括:可被其它VxD訪問的接口(稱為VxD服務),要求本VxD的ID>0,且未與內存各VxD的ID值沖突. 此ID可向微軟公司申請,也可使用Vireo公司的VIREO_TEST_ID(3180h).下稱此類ID為接口ID.  (3) API頁包括:可被應用程序在實模式/V86模式下、保護模式下、DPMI的實模式/V86模式下、DPMI的保護模式下訪問的接口(統稱應用接口),前兩者要求本VxD提供接口ID,后兩者只要求本VxD提供以0結尾的唯一標識串;訪問前,先要靜態或動態裝入本VxD(第4者要求靜態裝入). 第1,3者可被普通匯編程序訪問,第2,4者可被在BC的windows 3.x(16)平臺上生成的Windows程序訪問.  (4) Control Messages頁包括: 對出現在Windows 3.1及Windows 95中各消息的響應,如靜態裝入時的DYNAMIC_INIT消息.  (5) Windows95 Control Messages頁包括: 對只出現在Windows 95中各消息的響應,如動態裝入時的SYS_DYNAMIC_INIT消息.  (6) 用C++實現VxD時,Classes頁包括: 從虛擬設備驅動程序類VDevice派生的類名(如MyDevice),此類的成員函數將接收(4)及(5)頁中出現的大多數消息.  從VM實例類VVirtualMachine派生的類名(如MyVM),此類的成員函數將接收貫穿在VM生命期中的各消息,如系統VM初啟消息Sys_VM_Init;  從線程實例類VThread派生的類名(如MyThread).此類的成員函數將接收貫穿在線程生命期中的各消息,如新線程初啟消息THREAD_INIT;  (7) Output Files頁包括: 體現以上內容的3個VxD文件(.h,.c或.cpp,.mak)將被存放的目錄位置. 更多文章 更多內容請看C/C++技術專題專題,或
  3. C++語言的VxD與外界通訊的所有接口: 我們將簡要實現my.VxD的應用接口及服務,它們均作為類的函數成員,存于my.h,my.cpp中.  (1) 被32位C應用程序訪問的接口:

  應用程序先用CreateFile打開VxD,后用DeviceIoControl使VMM發送W32_DEVICEIOCONTROL消息給VxD:  HANDLE h;char ibuf[2],obuf[2];BOOL r;DWord oc;OVERLAPPED o;  h=CreateFile("http:////.//my.vxd",0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0); //打開靜態my.VxD,或動態裝入my.VxD  r=DeviceIoControl(h,命令碼C,ibuf,sizeof(ibuf),obuf,sizeof(obuf),&oc,NULL或&o); /*與my.VxD的事件過程OnW32DeviceIoControl交換數據,用ibuf向VxD傳數據,用obuf從VxD取 數據,VxD傳回的數據總量放在oc中*/  CloseHandle(h);//關閉或動態卸下VxD  my.VxD應在windows 95 control messages頁上選W32_DEVICEIOCONTROL事件,在 DWORD MyDevice::OnW32DeviceIoControl(PIOCTLPARAMS p)事件過程中寫:switch(p->dioc_IOCtlCode){
case 命令碼C:
用p指向的IOCTLPAR
AMS結構,與應用程序交換數據;
if (成功) return(0); /*
使DeviceIoControl的返回值r為TRUE*/
else return(1);
default:
return(0);
}  以上做法要求VxD立即交換數據(同步通訊),值FILE_FLAG_DELETE_ON_CLOSE指明 CloseHandle將不在內存中保留引用記數為0的VxD.
  VxD也可延遲交換數據,此時,應用程序先傳值FILE_FLAG_DELETE_ON_CLOSEFILE_FLAG_OVERLAPPED  到CreateFile,用o.hEvent=CreateEvent(0,TRUE,0,NULL)創建事件,再傳o的地址到DeviceIoControl,然后用GetOverlappedResult(h,&o,&oc,TRUE)在o上睡眠.  此時,p->lpoOverlapped一定大于0,VxD可用VMM服務_LinPageLock,按頁上鎖p->dioc_InBuf指向的應用程序ibuf區,p->dioc_OutBuf指向的obuf區,p->lpoOverlapped指向的o結構.要交換數據時,可置數據及數據總量到p->dioc_OutBuf及p->lpoOverlapped->O_InternalHigh,然后調用VMM服務  VWIN32_DIOCCompletionRoutine(p->lpoOverlapped->O_Internal)喚醒應用程序.  VMM動態裝卸VxD時,以命令碼0及-1發送W32_DEVICEIOCONTROL消息給VxD,故Vireo公司建議命令碼C取[2048,4095].  (2) 被Real/V86模式下16位應用程序訪問的接口:  my.VxD先要指定接口ID(如3180h),再在API頁上選Standard application Entry Points框中的Real/V86 Mode標簽,即可生成MyDevice::V86_API_Entry入口,訪問它的匯編程序是:entry dd ?
mov ax,1684h ;功能號
mov bx,3180h ;接口ID
int 2fh ;取入口的段/
偏移到es/di,成功時,
di及es返回非零值mov ax,es
or ax,di
jz L0mov word ptr [entry],di
mov word ptr [entry+2],esmov ah,碼C
call [entry]  L0: 錯誤處理
MyDevice::V86_API_Entry(VMHANDLE hVM
,CLIENT_STRUCT* p)入口可以是:
if (p->CBRS.Client_AH==碼C) p->CBRS.Client_AL=0;  (3) 被保護模式下16位應用程序訪問的接口:

  與(2)類似,但選PRotected Mode標簽,即可生成MyDevice::PM_API_Entry入口,訪問它的程序是:int PASCAL WinMain(HANDLE h1,HANDLE h0,
LPSTR lpCmdLine,int nCmdShow){
FARPROC entry; //32位
_asm{
mov ax,1684h
mov bx,3180h
int 2fh;取入口的選擇符/偏移到es/di,成功時,di及es返回非零值mov ax,es
or ax,di
jz L0mov word ptr [entry],di
mov word ptr [entry+2],esmov ah,碼C
call [entry]
}  對PM_API_Entry的處理如(3.2).

  (4) 被DPMI的實模式/V86模式下16位應用程序訪問的接口:  與(2)類似,但在API頁上選Vendor Specific Application Entry Points中的Real/V86 Mode標簽,然后在Vendor ID String中輸入唯一標識串my,即可生成My_V86VendorEntry::handler入口,訪問它的程序是:str db 'my',0 ;VxD的唯一標識串
entry dd ?
mov ax,168Ah ;功能號
lea si,str ;要求ds/si值是str的段值/偏移值
int 2Fh ;取入口的段/偏移到es/di,成功時,al返回0
cmp al,0
jne L0
mov word ptr [entry],di
mov word ptr [entry+2],es
...
call [entry]
  對handler的處理如(3.2).

  (5) 被DPMI的保護模式下16位應用程序訪問的接口: 與(4)類似,但選Protected Mode標簽,即可生成My_ProtVendorEntry::handler入口,訪問它的程序是:int PASCAL WinMain(HANDLE h1,HANDLE h0,
LPSTR lpCmdLine,int nCmdShow){
char *id="my";
FARPROC entry;
_asm{
mov ax,168Ah
mov si,id
int 2Fh ;取入口的選擇符/偏移到es/di
cmp al,0
...
}
}  對handler的處理如(3.2).

  (6) 可被其它VxD訪問的接口:  若your.VxD欲調my.VxD的做兩數相減的minus接口,需在my.VxD的VxD service頁上輸入原型DWORD _cdecl minus(DWORD i,DWORD j),再在MyDevice::minus中,寫return(i-j);  your.mak中,需處理中間文件wrap.cpp:OBJECTS=your.OBJ wrap.obj
...
wrap.OBJ:wrap.cpp my.h  wrap.cpp中,對帶參數的VxD服務,需用VMM宏指令VxDJmp轉入,各參數進入wrap時,已按C的調用約定入棧;對不帶參數VxD服務,可調用VMM宏指令VxDCall(接口名):
#include "my.h"
DWORD _cdecl MyDevice::
minus(DWORD i,DWORD j){
VxDJmp(minus);
}  your.cpp的某一函數f,可用VMM服務Get_DDB,查my.VxD是否已裝入,若未裝入,則用VxDLDR服務

  VxDLDR_LoadDevice將其裝入:
#define DEVICE_MAIN
#include "your.h"
Declare_Virtual_Device(YOUR)
#undef DEVICE_MAIN  #include "my.h" //此行需在DEVICE_MAIN外
VOID f(){
PDEVICEINFO pinfo;
PDDB pddb;
DWORD r;
pddb=Get_DDB(0,"MY ");
//用空格補全長度小于8的VxD名
if (pddb==0) {//未裝入
r=VxDLDR_LoadDevice("my.VxD",
VxDLDR_INIT_DEVICE,&pinfo,&pddb);
if (r!=0) //VxDLDR_LoadDevice未能成功裝入my.VxD
return;
}
MyDevice::minus(值1,值2);
} 更多文章 更多內容請看C/C++技術專題專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黑山县| 河间市| 扶绥县| 松潘县| 新和县| 河曲县| 东海县| 荔浦县| 安义县| 孟连| 电白县| 奎屯市| 监利县| 大宁县| 伽师县| 个旧市| 双牌县| 剑阁县| 莱阳市| 白城市| 抚远县| 浪卡子县| 游戏| 天祝| 什邡市| 庄河市| 通海县| 泰宁县| 潜江市| 连南| 顺昌县| 荔浦县| 内丘县| 浮山县| 赞皇县| 西城区| 正安县| 新绛县| 托克托县| 南华县| 卓资县|