|
|
/*++
* * WOW v1.0 * * Copyright (c) 1991, Microsoft Corporation * * INIT.C * WOW16 user initialisation code * * History: * * Created 15-Apr-1991 by Nigel Thompson (nigelt) * * Revised 19-May-1991 by Jeff Parsons (jeffpar) * IFDEF'ed everything, since everything was only needed by RMLOAD.C, * and that has been largely IFDEF'ed as well (see RMLOAD.C for details) --*/
#define FIRST_CALL_MUST_BE_USER_BUG
#include "user.h"
/* These must match counterparts in mvdm\inc\wowusr.h */ #define NW_FINALUSERINIT 4 // Internal
#define NW_KRNL386SEGS 5 // Internal
DWORD API NotifyWow(WORD, LPBYTE); VOID FAR PASCAL PatchUserStrRtnsToThunk(VOID); /***************************************************************************
global data items
***************************************************************************/
#ifdef NEEDED
HDC hdcBits; // USER's general hdc
OEMINFO oemInfo; // lots of interresting info
#endif
#ifdef FIRST_CALL_MUST_BE_USER_BUG
HWND hwndDesktop; // handle to the desktop window
#endif
BOOL fThunkStrRtns; // if TRUE we thunk to Win32 (see winlang.asm)
FARPROC LPCHECKMETAFILE;
/***************************************************************************
initialisation routine
***************************************************************************/
int FAR PASCAL LibMain(HANDLE hInstance) { #ifdef NEEDED
HDC hDC; #endif
HANDLE hLib; HANDLE hInstKrnl;
dprintf(3,"Initializing...");
// Notify the hInstance of USER to wow32.
// - Nanduri
//
// Overload this to return the ANSI code page from Win32 GetACP.
// - DaveHart 5-May-94
//
{ #ifdef PMODE32
extern _cdecl wow16gpsi(void); extern _cdecl wow16CsrFlag(void); extern _cdecl wow16gHighestUserAddress(void); #endif
WORD wCS; extern WORD MaxDWPMsg; extern BYTE DWPBits[1]; extern WORD cbDWPBits;
// NOTE: these two structs are also in mvdm\inc\wowusr.h
// USERCLIENTGLOBALS & KRNL386SEGS
// - they must be the same!!!
struct { WORD hInstance; LPSTR FAR *lpgpsi; LPSTR FAR *lpCallCsrFlag; DWORD dwBldInfo; LPWORD lpwMaxDWPMsg; LPSTR lpDWPBits; WORD cbDWPBits; WORD wUnusedPadding; DWORD pfnGetProcModule; LPSTR FAR *lpHighestAddress; } UserInit16;
struct { WORD CodeSeg1; WORD CodeSeg2; WORD CodeSeg3; WORD DataSeg1; } Krnl386Segs; UserInit16.hInstance = (WORD)hInstance; #ifdef PMODE32
UserInit16.lpgpsi = (LPSTR *)wow16gpsi; UserInit16.lpCallCsrFlag = (LPSTR *)wow16CsrFlag; UserInit16.lpHighestAddress = (LPSTR *)&wow16gHighestUserAddress; #else
UserInit16.lpgpsi = (LPSTR *)0; UserInit16.lpCallCsrFlag = (LPSTR *)0; UserInit16.lpHighestAddress = (LPSTR *)0; #endif
#ifdef WOWDBG
UserInit16.dwBldInfo = (((DWORD)WOW) << 16) | 0x80000000; #else
UserInit16.dwBldInfo = (((DWORD)WOW) << 16); #endif
_asm mov wCS, cs; UserInit16.lpwMaxDWPMsg = (LPWORD) MAKELONG((WORD)&MaxDWPMsg, wCS); UserInit16.lpDWPBits = (LPBYTE) MAKELONG((WORD)&DWPBits[0], wCS); UserInit16.cbDWPBits = *(LPWORD) MAKELONG((WORD)&cbDWPBits, wCS); UserInit16.pfnGetProcModule = (DWORD)(FARPROC) GetProcModule;
fThunkStrRtns = NotifyWow(NW_FINALUSERINIT, (LPBYTE)&UserInit16);
// now that wow32 knows pfnGetProcModule we can call GetProcAddress
// to get the kernel code & data segs
hInstKrnl = LoadLibrary("krnl386.exe"); FreeLibrary(hInstKrnl);
Krnl386Segs.CodeSeg1 = HIWORD(GetProcAddress(hInstKrnl, "LoadResource")); Krnl386Segs.CodeSeg2 = HIWORD(GetProcAddress(hInstKrnl, "LoadModule")); Krnl386Segs.CodeSeg3 = HIWORD(GetProcAddress(hInstKrnl, "FindResource")); Krnl386Segs.DataSeg1 = (WORD)hInstKrnl;
NotifyWow(NW_KRNL386SEGS, (LPBYTE)&Krnl386Segs);
//
// fThunkStrRtns defaults to TRUE outside the U.S. English
// locale and FALSE in the U.S. English locale. If we are
// thunking, patch the exported U.S. implementations to simply
// near jmp to the equivalent thunk.
//
if (fThunkStrRtns) { PatchUserStrRtnsToThunk(); } }
#ifdef FIRST_CALL_MUST_BE_USER_BUG
// get the desktop window handle
WinEval(hwndDesktop = GetDesktopWindow()); #endif
#ifdef NEEDED
// create a compatible dc we can use for general bitmap stuff
WinEval(hDC = GetDC(hwndDesktop)); WinEval(hdcBits = CreateCompatibleDC(hDC));
// fill in the oemInfo structure
// NOTE: We only fill in the bits we need for WOW not all of it
oemInfo.cxIcon = GetSystemMetrics(SM_CXICON); oemInfo.cyIcon = GetSystemMetrics(SM_CYICON); oemInfo.cxCursor = GetSystemMetrics(SM_CXCURSOR); oemInfo.cyCursor = GetSystemMetrics(SM_CYCURSOR); oemInfo.ScreenBitCount = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); oemInfo.DispDrvExpWinVer= GetVersion();
ReleaseDC(hwndDesktop, hDC);
#endif
hLib = LoadLibrary( "gdi.exe" ); LPCHECKMETAFILE = GetProcAddress( hLib, "CHECKMETAFILE" );
LoadString(hInstanceWin, STR_SYSERR, szSysError, 20); LoadString(hInstanceWin, STR_DIVBYZERO,szDivZero, 50);
dprintf(3,"Initialisation complete");
return TRUE; }
/***************************************************************************
debugging support
***************************************************************************/
#ifdef DEBUG
void cdecl dDbgOut(int iLevel, LPSTR lpszFormat, ...) { char buf[256]; int iLogLevel; char far *lpcLogLevel;
// Get the external logging level from the emulated ROM
iLogLevel = 0; (LONG)lpcLogLevel = 0x00400042; if (*lpcLogLevel >= '0' && *lpcLogLevel <= '9') iLogLevel = (*lpcLogLevel-'0')*10+(*(lpcLogLevel+1)-'0');
if (iLevel==iLogLevel && (iLogLevel&1) || iLevel<=iLogLevel && !(iLogLevel&1)) { OutputDebugString(" W16USER:"); wvsprintf(buf, lpszFormat, (LPSTR)(&lpszFormat + 1)); OutputDebugString(buf); OutputDebugString("\r\n"); } }
void cdecl dDbgAssert(LPSTR exp, LPSTR file, int line) { dDbgOut(0, "Assertion FAILED in file %s, line %d: %s\n", (LPSTR)file, line, (LPSTR)exp); }
#endif
|