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

Last change on this file since 8706 was 8436, checked in by sandervl, 23 years ago

TLS fix for pe2lx images

File size: 7.0 KB
Line 
1/* $Id: winexepe2lx.cpp,v 1.11 2002-05-16 13:45:32 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
34#include "cio.h" // I/O
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
51
52/**
53 * Register a Pe2Lx Executable module.
54 * This is called from the TIBFix code in the Pe2Lx exe. It creates the WinExe object from
55 * the instance handle passed in.
56 * @param ulPe2LxVersion Pe2Lx version number.
57 * @param hinstance Module handle.
58 * @param ulReserved Reserved.
59 * @sketch I/O init.
60 * Check that pe2lx version matches the version of kernel32.dll.
61 * Frees WinExe if is not NULL - should never happen!
62 * Write info to the log.
63 * Create Pe2Lx Exe object.
64 * Call start (which calls the entry point).
65 * @status completely implemented.
66 * @author Sander van Leeuwen, knut st. osmundsen
67 */
68void WIN32API RegisterPe2LxExe(ULONG ulPe2LxVersion, HINSTANCE hinstance, ULONG ulReserved)
69{
70 Win32Pe2LxExe *pWinPe2LxExe;
71
72 /* I/O init. */
73 if (getenv("WIN32_IOPL2"))
74 io_init1();
75
76 /* Check that pe2lx version matches the version of kernel32.dll. */
77 CheckVersion(ulPe2LxVersion & ~0x80000000UL, OSLibGetDllName(hinstance));
78
79 /* Write info to the log. */
80 dprintf(("RegisterPe2LxExe: ulPe2LxVersion = %#x\n", ulPe2LxVersion));
81 dprintf(("RegisterPe2LxExe: hinstance = %#x\n", hinstance));
82 dprintf(("RegisterPe2LxExe: ulReserved = %#x\n", ulReserved));
83 dprintf(("RegisterPe2LxExe: name = %s\n", OSLibGetDllName(hinstance)));
84
85 /* Might allready be initiated because of early init. */
86 if ( WinExe != NULL
87 && ( (ulPe2LxVersion & 0x80000000UL) != 0x80000000UL)
88 || !Win32Pe2LxExe::fEarlyInit)
89 {
90 delete WinExe;
91 WinExe = NULL;
92 }
93
94 if (WinExe == NULL)
95 {
96 /* Create Pe2Lx Exe object. */
97 pWinPe2LxExe = new Win32Pe2LxExe(hinstance, (ulPe2LxVersion & 0x80000000UL) == 0x80000000UL);
98 if (pWinPe2LxExe == NULL)
99 {
100 eprintf(("RegisterPe2LxExe: new returned a NULL-pointer\n"));
101 return;
102 }
103 if (!pWinPe2LxExe->init())
104 {
105 eprintf(("RegisterPe2LxExe: init-method failed.\n"));
106 delete pWinPe2LxExe;
107 return;
108 }
109 }
110 else
111 pWinPe2LxExe = (Win32Pe2LxExe*)WinExe;
112
113 /* Call start (which calls the entry point). */
114 /*DebugInt3();*/
115 pWinPe2LxExe->start();
116}
117
118
119/**
120 * Constructor - creates an pe2lx exe object from a module handle to a pe2lx exe module.
121 * @param hinstance Module handle.
122 * @param fWin32k TRUE: Win32k module.
123 * FALSE: Pe2Lx module.
124 * @status completely implmented.
125 * @author Sander van Leeuwen, knut st. osmundsen
126 * @remark Win32Pe2LxImage may throw an exception!
127 */
128Win32Pe2LxExe::Win32Pe2LxExe(HINSTANCE hinstance, BOOL fWin32k)
129 : Win32ImageBase(hinstance),
130 Win32ExeBase(hinstance),
131 Win32Pe2LxImage(hinstance, fWin32k)
132{
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())
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//******************************************************************************
Note: See TracBrowser for help on using the repository browser.