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.

237 lines
6.8 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * INIT.C
  8. * WOW16 user initialisation code
  9. *
  10. * History:
  11. *
  12. * Created 15-Apr-1991 by Nigel Thompson (nigelt)
  13. *
  14. * Revised 19-May-1991 by Jeff Parsons (jeffpar)
  15. * IFDEF'ed everything, since everything was only needed by RMLOAD.C,
  16. * and that has been largely IFDEF'ed as well (see RMLOAD.C for details)
  17. --*/
  18. #define FIRST_CALL_MUST_BE_USER_BUG
  19. #include "user.h"
  20. /* These must match counterparts in mvdm\inc\wowusr.h */
  21. #define NW_FINALUSERINIT 4 // Internal
  22. #define NW_KRNL386SEGS 5 // Internal
  23. DWORD API NotifyWow(WORD, LPBYTE);
  24. VOID FAR PASCAL PatchUserStrRtnsToThunk(VOID);
  25. /***************************************************************************
  26. global data items
  27. ***************************************************************************/
  28. #ifdef NEEDED
  29. HDC hdcBits; // USER's general hdc
  30. OEMINFO oemInfo; // lots of interresting info
  31. #endif
  32. #ifdef FIRST_CALL_MUST_BE_USER_BUG
  33. HWND hwndDesktop; // handle to the desktop window
  34. #endif
  35. BOOL fThunkStrRtns; // if TRUE we thunk to Win32 (see winlang.asm)
  36. FARPROC LPCHECKMETAFILE;
  37. /***************************************************************************
  38. initialisation routine
  39. ***************************************************************************/
  40. int FAR PASCAL LibMain(HANDLE hInstance)
  41. {
  42. #ifdef NEEDED
  43. HDC hDC;
  44. #endif
  45. HANDLE hLib;
  46. HANDLE hInstKrnl;
  47. dprintf(3,"Initializing...");
  48. // Notify the hInstance of USER to wow32.
  49. // - Nanduri
  50. //
  51. // Overload this to return the ANSI code page from Win32 GetACP.
  52. // - DaveHart 5-May-94
  53. //
  54. {
  55. #ifdef PMODE32
  56. extern _cdecl wow16gpsi(void);
  57. extern _cdecl wow16CsrFlag(void);
  58. extern _cdecl wow16gHighestUserAddress(void);
  59. #endif
  60. WORD wCS;
  61. extern WORD MaxDWPMsg;
  62. extern BYTE DWPBits[1];
  63. extern WORD cbDWPBits;
  64. // NOTE: these two structs are also in mvdm\inc\wowusr.h
  65. // USERCLIENTGLOBALS & KRNL386SEGS
  66. // - they must be the same!!!
  67. struct {
  68. WORD hInstance;
  69. LPSTR FAR *lpgpsi;
  70. LPSTR FAR *lpCallCsrFlag;
  71. DWORD dwBldInfo;
  72. LPWORD lpwMaxDWPMsg;
  73. LPSTR lpDWPBits;
  74. WORD cbDWPBits;
  75. WORD wUnusedPadding;
  76. DWORD pfnGetProcModule;
  77. LPSTR FAR *lpHighestAddress;
  78. } UserInit16;
  79. struct {
  80. WORD CodeSeg1;
  81. WORD CodeSeg2;
  82. WORD CodeSeg3;
  83. WORD DataSeg1;
  84. } Krnl386Segs;
  85. UserInit16.hInstance = (WORD)hInstance;
  86. #ifdef PMODE32
  87. UserInit16.lpgpsi = (LPSTR *)wow16gpsi;
  88. UserInit16.lpCallCsrFlag = (LPSTR *)wow16CsrFlag;
  89. UserInit16.lpHighestAddress = (LPSTR *)&wow16gHighestUserAddress;
  90. #else
  91. UserInit16.lpgpsi = (LPSTR *)0;
  92. UserInit16.lpCallCsrFlag = (LPSTR *)0;
  93. UserInit16.lpHighestAddress = (LPSTR *)0;
  94. #endif
  95. #ifdef WOWDBG
  96. UserInit16.dwBldInfo = (((DWORD)WOW) << 16) | 0x80000000;
  97. #else
  98. UserInit16.dwBldInfo = (((DWORD)WOW) << 16);
  99. #endif
  100. _asm mov wCS, cs;
  101. UserInit16.lpwMaxDWPMsg = (LPWORD) MAKELONG((WORD)&MaxDWPMsg, wCS);
  102. UserInit16.lpDWPBits = (LPBYTE) MAKELONG((WORD)&DWPBits[0], wCS);
  103. UserInit16.cbDWPBits = *(LPWORD) MAKELONG((WORD)&cbDWPBits, wCS);
  104. UserInit16.pfnGetProcModule = (DWORD)(FARPROC) GetProcModule;
  105. fThunkStrRtns = NotifyWow(NW_FINALUSERINIT, (LPBYTE)&UserInit16);
  106. // now that wow32 knows pfnGetProcModule we can call GetProcAddress
  107. // to get the kernel code & data segs
  108. hInstKrnl = LoadLibrary("krnl386.exe");
  109. FreeLibrary(hInstKrnl);
  110. Krnl386Segs.CodeSeg1 = HIWORD(GetProcAddress(hInstKrnl,
  111. "LoadResource"));
  112. Krnl386Segs.CodeSeg2 = HIWORD(GetProcAddress(hInstKrnl,
  113. "LoadModule"));
  114. Krnl386Segs.CodeSeg3 = HIWORD(GetProcAddress(hInstKrnl,
  115. "FindResource"));
  116. Krnl386Segs.DataSeg1 = (WORD)hInstKrnl;
  117. NotifyWow(NW_KRNL386SEGS, (LPBYTE)&Krnl386Segs);
  118. //
  119. // fThunkStrRtns defaults to TRUE outside the U.S. English
  120. // locale and FALSE in the U.S. English locale. If we are
  121. // thunking, patch the exported U.S. implementations to simply
  122. // near jmp to the equivalent thunk.
  123. //
  124. if (fThunkStrRtns) {
  125. PatchUserStrRtnsToThunk();
  126. }
  127. }
  128. #ifdef FIRST_CALL_MUST_BE_USER_BUG
  129. // get the desktop window handle
  130. WinEval(hwndDesktop = GetDesktopWindow());
  131. #endif
  132. #ifdef NEEDED
  133. // create a compatible dc we can use for general bitmap stuff
  134. WinEval(hDC = GetDC(hwndDesktop));
  135. WinEval(hdcBits = CreateCompatibleDC(hDC));
  136. // fill in the oemInfo structure
  137. // NOTE: We only fill in the bits we need for WOW not all of it
  138. oemInfo.cxIcon = GetSystemMetrics(SM_CXICON);
  139. oemInfo.cyIcon = GetSystemMetrics(SM_CYICON);
  140. oemInfo.cxCursor = GetSystemMetrics(SM_CXCURSOR);
  141. oemInfo.cyCursor = GetSystemMetrics(SM_CYCURSOR);
  142. oemInfo.ScreenBitCount = GetDeviceCaps(hDC, BITSPIXEL)
  143. * GetDeviceCaps(hDC, PLANES);
  144. oemInfo.DispDrvExpWinVer= GetVersion();
  145. ReleaseDC(hwndDesktop, hDC);
  146. #endif
  147. hLib = LoadLibrary( "gdi.exe" );
  148. LPCHECKMETAFILE = GetProcAddress( hLib, "CHECKMETAFILE" );
  149. LoadString(hInstanceWin, STR_SYSERR, szSysError, 20);
  150. LoadString(hInstanceWin, STR_DIVBYZERO,szDivZero, 50);
  151. dprintf(3,"Initialisation complete");
  152. return TRUE;
  153. }
  154. /***************************************************************************
  155. debugging support
  156. ***************************************************************************/
  157. #ifdef DEBUG
  158. void cdecl dDbgOut(int iLevel, LPSTR lpszFormat, ...)
  159. {
  160. char buf[256];
  161. int iLogLevel;
  162. char far *lpcLogLevel;
  163. // Get the external logging level from the emulated ROM
  164. iLogLevel = 0;
  165. (LONG)lpcLogLevel = 0x00400042;
  166. if (*lpcLogLevel >= '0' && *lpcLogLevel <= '9')
  167. iLogLevel = (*lpcLogLevel-'0')*10+(*(lpcLogLevel+1)-'0');
  168. if (iLevel==iLogLevel && (iLogLevel&1) || iLevel<=iLogLevel && !(iLogLevel&1)) {
  169. OutputDebugString(" W16USER:");
  170. wvsprintf(buf, lpszFormat, (LPSTR)(&lpszFormat + 1));
  171. OutputDebugString(buf);
  172. OutputDebugString("\r\n");
  173. }
  174. }
  175. void cdecl dDbgAssert(LPSTR exp, LPSTR file, int line)
  176. {
  177. dDbgOut(0, "Assertion FAILED in file %s, line %d: %s\n",
  178. (LPSTR)file, line, (LPSTR)exp);
  179. }
  180. #endif