Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
9.7 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WUMAN.C
  8. * WOW32 16-bit User API support (manually-coded thunks)
  9. *
  10. * History:
  11. * Created 27-Jan-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. MODNAME(wuman.c);
  16. WBP W32WordBreakProc = NULL;
  17. extern DWORD fThunkStrRtns;
  18. extern WORD gwKrnl386CodeSeg1;
  19. extern WORD gwKrnl386CodeSeg2;
  20. extern WORD gwKrnl386CodeSeg3;
  21. extern WORD gwKrnl386DataSeg1;
  22. ULONG FASTCALL WU32ExitWindows(PVDMFRAME pFrame)
  23. // BUGBUG mattfe 4-mar-92, this routine should not return if we close down
  24. // all the apps successfully.
  25. {
  26. ULONG ul;
  27. register PEXITWINDOWS16 parg16;
  28. GETARGPTR(pFrame, sizeof(EXITWINDOWS16), parg16);
  29. ul = GETBOOL16(ExitWindows(
  30. DWORD32(parg16->dwReserved),
  31. WORD32(parg16->wReturnCode)
  32. ));
  33. FREEARGPTR(parg16);
  34. RETURN(ul);
  35. }
  36. WORD gUser16CS = 0;
  37. ULONG FASTCALL WU32NotifyWow(PVDMFRAME pFrame)
  38. {
  39. ULONG ul = 0;
  40. register PNOTIFYWOW16 parg16;
  41. GETARGPTR(pFrame, sizeof(NOTIFYWOW16), parg16);
  42. switch (FETCHWORD(parg16->Id)) {
  43. case NW_LOADACCELERATORS:
  44. ul = WU32LoadAccelerators(FETCHDWORD(parg16->pData));
  45. break;
  46. case NW_LOADICON:
  47. case NW_LOADCURSOR:
  48. ul = (ULONG) W32CheckIfAlreadyLoaded(parg16->pData, FETCHWORD(parg16->Id));
  49. break;
  50. case NW_WINHELP:
  51. {
  52. // this call is made from IWinHelp in USER.exe to find the
  53. // '16bit' help window if it exists.
  54. //
  55. LPSZ lpszClass;
  56. GETMISCPTR(parg16->pData, lpszClass);
  57. ul = (ULONG)(pfnOut.pfnWOWFindWindow)((LPCSTR)lpszClass, (LPCSTR)NULL);
  58. if (ul) {
  59. // check if hwndWinHelp belongs to this process or not.
  60. DWORD pid, pidT;
  61. pid = pidT = GetCurrentProcessId();
  62. GetWindowThreadProcessId((HWND)ul, &pid);
  63. ul = (ULONG)MAKELONG((WORD)GETHWND16(ul),(WORD)(pid == pidT));
  64. }
  65. FREEMISCPTR(lpszClass);
  66. }
  67. break;
  68. case NW_KRNL386SEGS:
  69. {
  70. PKRNL386SEGS pKrnl386Segs;
  71. GETVDMPTR(parg16->pData, sizeof(KRNL386SEGS), pKrnl386Segs);
  72. gwKrnl386CodeSeg1 = pKrnl386Segs->CodeSeg1;
  73. gwKrnl386CodeSeg2 = pKrnl386Segs->CodeSeg2;
  74. gwKrnl386CodeSeg3 = pKrnl386Segs->CodeSeg3;
  75. gwKrnl386DataSeg1 = pKrnl386Segs->DataSeg1;
  76. }
  77. break;
  78. case NW_FINALUSERINIT:
  79. {
  80. static BYTE CallCsrFlag = 0;
  81. extern DWORD gpsi;
  82. PUSERCLIENTGLOBALS pfinit16;
  83. WORD UNALIGNED *pwMaxDWPMsg;
  84. PBYTE pDWPBits;
  85. #ifdef DEBUG
  86. WORD wMsg;
  87. int i;
  88. PSZ pszFormat;
  89. #endif
  90. GETVDMPTR(parg16->pData, sizeof(USERCLIENTGLOBALS), pfinit16);
  91. GETVDMPTR(pfinit16->lpwMaxDWPMsg, sizeof(WORD), pwMaxDWPMsg);
  92. GETVDMPTR(pfinit16->lpDWPBits, pfinit16->cbDWPBits, pDWPBits);
  93. // store the 16bit hmod of user.exe
  94. gUser16hInstance = (WORD)pfinit16->hInstance;
  95. WOW32ASSERTMSGF((gUser16hInstance),
  96. ("WOW Error gUser16hInstance == NULL!\n"));
  97. // store the 16bit CS of user.exe
  98. gUser16CS = HIWORD(pFrame->vpCSIP);
  99. // initialize user16client globals
  100. if (pfinit16->lpgpsi) {
  101. BYTE **lpT;
  102. GETVDMPTR(pfinit16->lpgpsi, sizeof(DWORD), lpT);
  103. *lpT = (BYTE *)gpsi;
  104. FLUSHVDMCODEPTR((ULONG)pfinit16->lpgpsi, sizeof(DWORD), lpT);
  105. FREEVDMPTR(lpT);
  106. }
  107. if (pfinit16->lpCsrFlag) {
  108. BYTE **lpT;
  109. GETVDMPTR(pfinit16->lpCsrFlag, sizeof(DWORD), lpT);
  110. *lpT = (LPSTR)&CallCsrFlag;
  111. FLUSHVDMCODEPTR((ULONG)pfinit16->lpCsrFlag, sizeof(DWORD), lpT);
  112. FREEVDMPTR(lpT);
  113. }
  114. if (pfinit16->lpHighestAddress) {
  115. DWORD *lpT;
  116. SYSTEM_BASIC_INFORMATION sbi;
  117. NTSTATUS Status;
  118. GETVDMPTR(pfinit16->lpHighestAddress, sizeof(DWORD), lpT);
  119. Status = NtQuerySystemInformation(SystemBasicInformation,
  120. &sbi,
  121. sizeof(sbi),
  122. NULL);
  123. WOW32ASSERTMSGF((NT_SUCCESS(Status)),
  124. ("WOW Error NtQuerySystemInformation failed!\n"));
  125. *lpT = sbi.MaximumUserModeAddress;
  126. FLUSHVDMCODEPTR((ULONG)pfinit16->lpHighestAddress, sizeof(DWORD), lpT);
  127. FREEVDMPTR(lpT);
  128. }
  129. /* No longer required now that user32 & user.exe are separate
  130. DEAD CODE if (HIWORD(pfinit16->dwBldInfo) != HIWORD(pfnOut.dwBldInfo)) {
  131. DEAD CODE MessageBeep(0);
  132. DEAD CODE MessageBoxA(NULL, "user.exe and user32.dll are mismatched.",
  133. DEAD CODE "WOW Error", MB_OK | MB_ICONEXCLAMATION);
  134. DEAD CODE }
  135. */
  136. *pwMaxDWPMsg = (pfnOut.pfnWowGetDefWindowProcBits)(pDWPBits, pfinit16->cbDWPBits);
  137. FLUSHVDMCODEPTR(pfinit16->lpwMaxDWPMsg, sizeof(WORD), pwMaxDWPMsg);
  138. FLUSHVDMCODEPTR(pfinit16->lpDWPBits, pfinit16->cbDWPBits, pDWPBits);
  139. #ifdef DEBUG
  140. LOGDEBUG(LOG_TRACE, ("WU32NotifyWow: got DefWindowProc bits, wMaxDWPMsg = 0x%x.\n", *pwMaxDWPMsg));
  141. LOGDEBUG(LOG_TRACE, ("The following messages will be passed on to 32-bit DefWindowProc:\n"));
  142. #define FPASSTODWP32(msg) \
  143. (pDWPBits[msg >> 3] & (1 << (msg & 7)))
  144. wMsg = 0;
  145. i = 0;
  146. while (wMsg <= *pwMaxDWPMsg) {
  147. if (FPASSTODWP32(wMsg)) {
  148. if ( i & 3 ) {
  149. pszFormat = ", %s";
  150. } else {
  151. pszFormat = "\n%s";
  152. }
  153. LOGDEBUG(LOG_TRACE, (pszFormat, aw32Msg[wMsg].lpszW32));
  154. i++;
  155. }
  156. wMsg++;
  157. }
  158. LOGDEBUG(LOG_TRACE, ("\n\n"));
  159. #endif
  160. gpfn16GetProcModule = pfinit16->pfnGetProcModule;
  161. //
  162. // Return value tells User16 whether to thunk
  163. // string routines to Win32 or use the fast
  164. // US-only versions. TRUE means thunk.
  165. //
  166. // If the locale is U.S. English, we default to
  167. // not thunking, outside the U.S. we default to
  168. // thunking. See wow32.c's use of fThunkStrRtns.
  169. //
  170. // We engage in this nastiness because the Winstone 94
  171. // Access 1.1 test takes *twice* as long to run in
  172. // the US if we thunk lstrcmp and lstrcmpi to Win32.
  173. //
  174. // By adding a value "ThunkNLS" to the WOW registry
  175. // key of type REG_DWORD, the user can force thunking
  176. // to Win32 (value 1) or use the fast US-only ones (value 0).
  177. //
  178. ul = fThunkStrRtns;
  179. FREEVDMPTR(pDWPBits);
  180. FREEVDMPTR(pwMaxDWPMsg);
  181. FREEVDMPTR(pfinit16);
  182. }
  183. break;
  184. default:
  185. ul = 0;
  186. break;
  187. }
  188. FREEARGPTR(parg16);
  189. return ul;
  190. }
  191. ULONG FASTCALL WU32WOWWordBreakProc(PVDMFRAME pFrame)
  192. {
  193. PSZ psz1;
  194. ULONG ul;
  195. register PWOWWORDBREAKPROC16 parg16;
  196. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  197. GETPSZPTR(parg16->lpszEditText, psz1);
  198. ul = (*W32WordBreakProc)(psz1, parg16->ichCurrentWord, parg16->cbEditText,
  199. parg16->action);
  200. FREEPSZPTR(psz1);
  201. FREEARGPTR(parg16);
  202. RETURN(ul);
  203. }
  204. //
  205. // WU32MouseEvent: Thunk for 16-bit register-based API mouse_event,
  206. // with the help of user16 function mouse_event (in
  207. // winmisc2.asm).
  208. //
  209. ULONG FASTCALL WU32MouseEvent(PVDMFRAME pFrame)
  210. {
  211. ULONG ul;
  212. register PMOUSEEVENT16 parg16;
  213. typedef ULONG (WINAPI *PFMOUSE_EVENT)(DWORD, DWORD, DWORD, DWORD, DWORD);
  214. GETARGPTR(pFrame, sizeof(PMOUSEEVENT16), parg16);
  215. //
  216. // mouse_event is declared void, but we'll return the same value as
  217. // user32.
  218. //
  219. ul = ((PFMOUSE_EVENT)(PVOID)mouse_event)(
  220. parg16->wFlags,
  221. parg16->dx,
  222. parg16->dy,
  223. parg16->cButtons,
  224. parg16->dwExtraInfo
  225. );
  226. FREEARGPTR(parg16);
  227. RETURN(ul);
  228. }
  229. //
  230. // WU32KeybdEvent: Thunk for 16-bit register-based API keybd_event,
  231. // with the help of user16 function keybd_event (in
  232. // winmisc2.asm).
  233. //
  234. ULONG FASTCALL WU32KeybdEvent(PVDMFRAME pFrame)
  235. {
  236. ULONG ul;
  237. register PKEYBDEVENT16 parg16;
  238. typedef ULONG (WINAPI *PFKEYBD_EVENT)(BYTE, BYTE, DWORD, DWORD);
  239. GETARGPTR(pFrame, sizeof(PKEYBDEVENT16), parg16);
  240. //
  241. // keybd_event is declared void, but we'll return the same value as
  242. // user32.
  243. //
  244. ul = ((PFKEYBD_EVENT)(PVOID)keybd_event)(
  245. LOBYTE(parg16->bVirtualKey),
  246. LOBYTE(parg16->bScanCode),
  247. ((HIBYTE(parg16->bVirtualKey) == 0x80) ? KEYEVENTF_KEYUP : 0) |
  248. ((HIBYTE(parg16->bScanCode) == 0x1) ? KEYEVENTF_EXTENDEDKEY : 0),
  249. parg16->dwExtraInfo
  250. );
  251. FREEARGPTR(parg16);
  252. RETURN(ul);
  253. }