VXD 呼叫 RING3 的 程式碼的方法 (轉)

worldblog發表於2007-12-08
VXD 呼叫 RING3 的 程式碼的方法 (轉)[@more@]

 

VXD RING3 的 程式碼的方法


發信人: ah (ahping), 信區: programmer

標  題: VXD 呼叫 RING3 的 程式碼的方法
發信站: WYU研會BBS (Thu Nov 18 22:16:55 1999), 轉信

MSDN中介紹了兩種:NestedExecution , CallDll。
其中ShellCallDll呼叫RING3中的 16位DLL。
(MSDN中沒有介紹呼叫32位DLL的方法)
兩種方法都要用到 EventCallBackFunction 。
首先VXD要schedule一個event(對NestedExecution適用的是VMEvent;
對ShellCallDll適用的是AppiTimeEvent),並且把一段包含呼叫
NestedExecution 或 ShellCallDll的作為此Event的回撥,
VMM在適當的時候就會呼叫此函式。
NestedExecution使用例子:
調函式
{...
 Begin_Nest_Exec();
 pRegs->CBRS.Client_AH = 0x30;
 Exec_Int(0x21);  用DOS服務
 End_Nest_Exec();
 ...
}
ShellCallDll使用例子:
調函式
VOID _cdecl Appy_Handler(PVOID RefData, D 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",  示一個訊息框
  sizeof(msgboxargs), &msgboxargs
  );
 _SHELL_LocalFree(msgboxargs.szText);
 _SHELL_LocalFree(msgboxargs.szTitle);
}
MSDN中強調:呼叫Win16 DLL 的時間:是在AppiTimeEvent的回撥函式
  Appy_Handler()中,可用_SHELL_CallDll(),但是用
  NestedExecution 的方法是危險的。
原因可能是:是多執行緒搶先多工的,而它內部保留了
Win16 的DLL,以支援16位的應用程式,另外Win9X中的USER32,GDI32... 等
部分 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服務,或中斷處理過程。
--
※ 來源:.WYU研會BBS SUN1.[FROM: lyp]
 
--
  死生契闊  與子相悅
  執子之手  與子偕老  ? 
 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989858/,如需轉載,請註明出處,否則將追究法律責任。

相關文章