windows-nt/Source/XPSP1/NT/base/mvdm/wow16/user/init.c

238 lines
6.8 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
*
* 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