source: trunk/src/kernel32/winexepe2lx.cpp@ 22018

Last change on this file since 22018 was 22010, checked in by dmik, 13 years ago

kernel32: Disable Win32 TIB switch completely by default.

Previously, It was ON until the EXE type had been identified (e.g. when
loading KERNEL32.DLL and the DLLs it drags in). This could make
some apps spin in an exception handler loop (like OpenOffice
trying to load JVM.DLL).

This closes #83.

File size: 7.1 KB
Line 
1/* $Id: winexepe2lx.cpp,v 1.14 2004-01-15 10:39:10 sandervl Exp $ */
2
3/*
4 * Win32 PE2LX Exe class
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1999-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13/*******************************************************************************
14* Defined Constants And Macros *
15*******************************************************************************/
16#define INCL_DOSERRORS /* DOS Error values */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <os2wrap.h> //Odin32 OS/2 api wrappers
23
24#include <stdlib.h> //getenv
25
26#include <misc.h>
27#include <win32type.h>
28#include <win32k.h>
29#include "winexepe2lx.h"
30#include <cpuhlp.h>
31#include <wprocess.h>
32#include <win32api.h>
33#include <odinpe.h>
34
35#include "oslibmisc.h" // OSLibGetDllName
36#include "conwin.h" // Windows Header for console only
37#include "console.h"
38
39#include "exceptions.h"
40#include "exceptutil.h"
41
42#define DBG_LOCALLOG DBG_winexepe2lx
43#include "dbglocal.h"
44
45
46/*******************************************************************************
47* Global Variables *
48*******************************************************************************/
49BOOL Win32Pe2LxExe::fEarlyInit = FALSE;
50
51extern "C" {
52
53/**
54 * Register a Pe2Lx Executable module.
55 * This is called from the TIBFix code in the Pe2Lx exe. It creates the WinExe object from
56 * the instance handle passed in.
57 * @param ulPe2LxVersion Pe2Lx version number.
58 * @param hinstance Module handle.
59 * @param ulReserved Reserved.
60 * @sketch I/O init.
61 * Check that pe2lx version matches the version of kernel32.dll.
62 * Frees WinExe if is not NULL - should never happen!
63 * Write info to the log.
64 * Create Pe2Lx Exe object.
65 * Call start (which calls the entry point).
66 * @status completely implemented.
67 * @author Sander van Leeuwen, knut st. osmundsen
68 */
69void WIN32API RegisterPe2LxExe(ULONG ulPe2LxVersion, HINSTANCE hinstance, ULONG ulReserved)
70{
71 Win32Pe2LxExe *pWinPe2LxExe;
72
73 /* Check that pe2lx version matches the version of kernel32.dll. */
74 CheckVersion(ulPe2LxVersion & ~0x80000000UL, OSLibGetDllName(hinstance));
75
76 /* Write info to the log. */
77 dprintf(("RegisterPe2LxExe: ulPe2LxVersion = %#x\n", ulPe2LxVersion));
78 dprintf(("RegisterPe2LxExe: hinstance = %#x\n", hinstance));
79 dprintf(("RegisterPe2LxExe: ulReserved = %#x\n", ulReserved));
80 dprintf(("RegisterPe2LxExe: name = %s\n", OSLibGetDllName(hinstance)));
81
82 /* Might allready be initiated because of early init. */
83 if ( WinExe != NULL
84 && ( (ulPe2LxVersion & 0x80000000UL) != 0x80000000UL)
85 || !Win32Pe2LxExe::fEarlyInit)
86 {
87 delete WinExe;
88 WinExe = NULL;
89 }
90
91 if (WinExe == NULL)
92 {
93 /* Create Pe2Lx Exe object. */
94 pWinPe2LxExe = new Win32Pe2LxExe(hinstance, (ulPe2LxVersion & 0x80000000UL) == 0x80000000UL);
95 if (pWinPe2LxExe == NULL)
96 {
97 eprintf(("RegisterPe2LxExe: new returned a NULL-pointer\n"));
98 return;
99 }
100 if (pWinPe2LxExe->init() != LDRERROR_SUCCESS)
101 {
102 eprintf(("RegisterPe2LxExe: init-method failed.\n"));
103 delete pWinPe2LxExe;
104 return;
105 }
106 }
107 else
108 pWinPe2LxExe = (Win32Pe2LxExe*)WinExe;
109
110 /* Call start (which calls the entry point). */
111 /*DebugInt3();*/
112 pWinPe2LxExe->start();
113}
114
115
116/**
117 * Constructor - creates an pe2lx exe object from a module handle to a pe2lx exe module.
118 * @param hinstance Module handle.
119 * @param fWin32k TRUE: Win32k module.
120 * FALSE: Pe2Lx module.
121 * @status completely implmented.
122 * @author Sander van Leeuwen, knut st. osmundsen
123 * @remark Win32Pe2LxImage may throw an exception!
124 */
125Win32Pe2LxExe::Win32Pe2LxExe(HINSTANCE hinstance, BOOL fWin32k)
126 : Win32ImageBase(hinstance),
127 Win32ExeBase(hinstance),
128 Win32Pe2LxImage(hinstance, fWin32k)
129{
130 //Signal to TEB management that we're an ummodified Win32 app and
131 //require setting FS to our special win32 selector
132 fSwitchTIBSel = TRUE;
133}
134
135
136/**
137 * Destructor - does nothing.
138 * @status completely implemented.
139 * @author Sander van Leeuwen
140 */
141Win32Pe2LxExe::~Win32Pe2LxExe()
142{
143
144}
145
146
147/**
148 * Init object.
149 * Must be called immedeately after the object construction.
150 * @returns Success indicator. (TRUE == success)
151 * @sketch
152 * @status completely implemented.
153 * @author knut st. osmundsen
154 */
155BOOL Win32Pe2LxExe::init()
156{
157 if (Win32Pe2LxImage::init())
158 {
159 fConsoleApp = pNtHdrs->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
160
161 /* console app? */
162 if (fConsoleApp)
163 {
164 APIRET rc;
165
166 dprintf(("Console application!\n"));
167
168 rc = iConsoleInit(TRUE); /* initialize console subsystem */
169 if (rc != NO_ERROR) /* check for errors */
170 dprintf(("KERNEL32:Win32Image:Init ConsoleInit failed with %u.\n", rc));
171 }
172 }
173 else
174 return FALSE;
175 return TRUE;
176}
177
178
179
180/**
181 * Preinitiate the executable before RegisterPe2LxExe is called.
182 * This is done by the first Pe2Lx DLL which is loaded.
183 *
184 * @returns Success idicator.
185 * @status
186 * @author knut st. osmundsen (kosmunds@csc.no)
187 * @remark
188 */
189BOOL Win32Pe2LxExe::earlyInit()
190{
191 /*
192 * Try make an win32k loaded executable object.
193 */
194 Win32Pe2LxExe * pExe = new Win32Pe2LxExe((HINSTANCE)OSLibGetPIB(PIB_TASKHNDL), libWin32kInstalled());
195 if (pExe)
196 {
197 if (pExe->init() == LDRERROR_SUCCESS)
198 {
199 WinExe = pExe;
200 return fEarlyInit = TRUE;
201 }
202 }
203
204 return FALSE;
205}
206//******************************************************************************
207//******************************************************************************
208ULONG Win32Pe2LxExe::start()
209{
210 WINEXCEPTION_FRAME exceptFrame;
211 ULONG rc;
212
213 dprintf(("Start executable %X\n", WinExe));
214
215 fExeStarted = TRUE;
216
217 //Allocate TLS index for this module
218 tlsAlloc();
219 tlsAttachThread(); //setup TLS (main thread)
220
221 //Note: The Win32 exception structure references by FS:[0] is the same
222 // in OS/2
223 OS2SetExceptionHandler((void *)&exceptFrame);
224 USHORT sel = SetWin32TIB(isPEImage() ? TIB_SWITCH_FORCE_WIN32 : TIB_SWITCH_DEFAULT);
225
226 //Set FPU control word to 0x27F (same as in NT)
227 CONTROL87(0x27F, 0xFFF);
228 dprintf(("KERNEL32: Win32ExeBase::start exe at %08xh\n",
229 (void*)entryPoint ));
230 rc = CallEntryPoint(entryPoint, NULL);
231
232 SetFS(sel); //restore FS
233
234 OS2UnsetExceptionHandler((void *)&exceptFrame);
235
236 ExitProcess(rc);
237 return rc;
238}
239//******************************************************************************
240//******************************************************************************
241
242} // extern "C"
Note: See TracBrowser for help on using the repository browser.