VXD 调用 RING3 的 代码的方法
发信人: ahping (ahping), 信区: programmer
标 题: VXD 调用 RING3 的 代码的方法 发信站: WYU研会BBS (Thu Nov 18 22:16:55 1999), 转信
MSDN中介绍了两种:NestedExecution , ShellCallDll。 其中ShellCallDll调用RING3中的WINDOWS 16位DLL。 (MSDN中没有介绍调用32位DLL的方法) 两种方法都要用到 EventCallBackFunction 。 首先VXD要schedule一个event(对NestedExecution适用的是VMEvent; 对ShellCallDll适用的是AppiTimeEvent),并且把一段包含调用 NestedExecution 或 ShellCallDll的程序作为此Event的回调函数, VMM在适当的时候就会调用此函数。 NestedExecution使用例子: file://回调函数 {... Begin_Nest_Exec(); pRegs->CBRS.Client_AH = 0x30; Exec_Int(0x21); file://调用DOS服务 End_Nest_Exec(); ... } ShellCallDll使用例子: file://回调函数 VOID _cdecl Appy_Handler(PVOID RefData, DWORD flags) { struct { WORD style; SEGOFFSET szTitle; SEGOFFSET szText; WORD hWnd; } msgboxargs; PVOID la; char* msg = ((DWORD)RefData==_CREATE_) ? "New VM Created" : "VM destroyed"; msgboxargs.hWnd = 0; msgboxargs.szText = _SHELL_LocalAllocEx(LMEM_STRING, 0, msg, &la); msgboxargs.szTitle = _SHELL_LocalAllocEx(LMEM_STRING, 0, "Appy Time Test", &la); msgboxargs.style = MB_OK; // 库名, 函数名 _SHELL_CallDll("USER", "MESSAGEBOX", file://显示一个消息框 sizeof(msgboxargs), &msgboxargs ); _SHELL_LocalFree(msgboxargs.szText); _SHELL_LocalFree(msgboxargs.szTitle); } MSDN中强调:调用Win16 DLL 的安全时间:是在AppiTimeEvent的回调函数 Appy_Handler()中,可用_SHELL_CallDll(),但是用 NestedExecution 的方法是危险的。 原因可能是:Win9X是多线程抢先多任务的,而它内部保留了 Win16 的DLL,以支持16位的应用程序,另外Win9X中的USER32,GDI32... 等 部分Win32 DLL 也是通过调用Win16的DLL实现的。然而Win16 的DLL“不”支持 “重入”。这在Windows3.1的协同多任务时是可行的,但在抢先多任务下却必须 作调整。Win9x中引入一个名为Win16Mutex的全局同步信号量,任何16位进程 要想执行必须获得Win16Mutex,而当去调用GetMessage()时释放Win16Mutex并 把自己挂起,返回时重新获得Win16Mutex;WIN32的DLL要调用WIN16的DLL的过程 也必须先获得Win16Mutex,之后释放Win16Mutex。这样一来,Win16的DLL就可以 安全运行了。估计:_SHELL_CallDll()的内部具备类似的同步过程, _SHELL_LocalFree(msgboxargs.szTitle); } MSDN中强调:调用Win16 DLL 的安全时间:是在AppiTimeEvent的回调函数 Appy_Handler()中,可用_SHELL_CallDll(),但是用 NestedExecution 的方法是危险的。 原因可能是:Win9X是多线程抢先多任务的,而它内部保留了 Win16 的DLL,以支持16位的应用程序,另外Win9X中的USER32,GDI32... 等 部分Win32 DLL 也是通过调用Win16的DLL实现的。然而Win16 的DLL“不”支持 “重入”。这在Windows3.1的协同多任务时是可行的,但在抢先多任务下却必须 作调整。Win9x中引入一个名为Win16Mutex的全局同步信号量,任何16位进程 要想执行必须获得Win16Mutex,而当去调用GetMessage()时释放Win16Mutex并 把自己挂起,返回时重新获得Win16Mutex;WIN32的DLL要调用WIN16的DLL的过程 也必须先获得Win16Mutex,之后释放Win16Mutex。这样一来,Win16的DLL就可以 安全运行了。估计:_SHELL_CallDll()的内部具备类似的同步过程, 所以调用是安全的。而NestedExecution不进行类似的同步。所以回有“重入” 的危险。(本来可以试试在NestedExecution 用Win16Mutex进行同步,遗憾的是 MSDN 中已经指出 :Win16Mutex对程序员不可见。) NestedExecution只好用来在适当的情况下调用DOS服务,或BIOS中断处理过程。 -- ※ 来源:.WYU研会BBS SUN1.[FROM: lyp] -- 死生契阔 与子相悦 执子之手 与子偕老 ?

|