source: trunk/src/kernel32/winexepeldr.cpp

Last change on this file 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: 5.9 KB
Line 
1/* $Id: winexepeldr.cpp,v 1.24 2004-01-15 10:39:10 sandervl Exp $ */
2
3/*
4 * Win32 PE loader Exe class
5 *
6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_DOSFILEMGR /* File Manager values */
13#define INCL_DOSERRORS /* DOS Error values */
14#define INCL_DOSPROCESS /* DOS Process values */
15#define INCL_DOSMISC /* DOS Miscellanous values */
16#define INCL_WIN
17#include <os2wrap.h> //Odin32 OS/2 api wrappers
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#ifndef __GNUC__
22#include <iostream.h>
23#include <fstream.h>
24#endif
25#include <misc.h>
26#include <win32type.h>
27#include <win32api.h>
28#include "winexepeldr.h"
29#include <wprocess.h>
30#include <pefile.h>
31
32#include "conwin.h" // Windows Header for console only
33#include "console.h"
34
35#include "exceptions.h"
36#include "exceptutil.h"
37
38#include "oslibmisc.h"
39
40#define DBG_LOCALLOG DBG_winexepeldr
41#include "dbglocal.h"
42
43
44#ifdef PROFILE
45#include <perfview.h>
46#include <profiler.h>
47#endif /* PROFILE */
48
49
50extern char szErrorModule[];
51
52BOOL fPeLoader = FALSE;
53
54//******************************************************************************
55//Called by ring 3 pe loader to create win32 executable
56//PE.EXE command line options:
57// /OPT:[x1=y,x2=z,..]
58// x = CURDIR -> set current directory to y
59// (not other options available at this time)
60//******************************************************************************
61extern "C"
62DWORD WIN32API CreateWin32PeLdrExe(char *szFileName, char *szCmdLine,
63 char *peoptions,
64 ULONG reservedMem, ULONG ulPEOffset,
65 BOOL fConsoleApp, BOOL fVioConsole,
66 char *pszErrorModule, ULONG cbErrorModule)
67{
68 APIRET rc;
69 PPIB ppib;
70 PTIB ptib;
71 WINEXCEPTION_FRAME exceptFrame;
72 Win32PeLdrExe *WinExe;
73 char *szFullCmdLine;
74
75 fPeLoader = TRUE;
76
77 WinExe = new Win32PeLdrExe(szFileName, fConsoleApp);
78
79 rc = DosGetInfoBlocks(&ptib, &ppib);
80 if(rc) {
81 delete WinExe;
82 return LDRERROR_INTERNAL;
83 }
84 //Handle special pe cmd line options here (/OPT:[x1=y,x2=z,..])
85 if(peoptions) {
86 char *option;
87
88 option = strchr(peoptions, '[');
89 if(option) {
90 option++;
91 option = strstr(option, "CURDIR=");
92 if(option) {
93 char *curdir, *tmp;
94 int curdirlength;
95
96 option += 7;
97 tmp = option;
98 while(*tmp != ']' && *tmp != ',' && *tmp != 0) {
99 tmp++;
100 }
101 curdirlength = (int)(tmp-option);
102 curdir = (char *)malloc(curdirlength+1);
103 memcpy(curdir, option, curdirlength);
104 curdir[curdirlength] = 0;
105 SetCurrentDirectoryA((LPCSTR)curdir);
106 free(curdir);
107 }
108 }
109 }
110 //exe length + space + (possibly) 2x'"' + cmd line length + 0 terminator
111 szFullCmdLine = (char *)malloc(strlen(szFileName) + 3 + strlen(szCmdLine) + 1);
112 //Enclose executable name in quotes if it (or it's directory) contains spaces
113 if(strchr(szFileName, ' ') != NULL) {
114 sprintf(szFullCmdLine, "\"%s\"", szFileName);
115 }
116 else strcpy(szFullCmdLine, szFileName);
117 strcat(szFullCmdLine, " ");
118 strcat(szFullCmdLine, szCmdLine);
119 InitCommandLine(szFullCmdLine);
120 dprintf(("Cmd line: %s", szFullCmdLine));
121 free(szFullCmdLine);
122
123 //Init console before loading executable as dlls might want to print
124 //something on the console while being loaded
125 if(WinExe->isConsoleApp())
126 {
127 dprintf(("Console application!\n"));
128
129 rc = iConsoleInit(fVioConsole); /* initialize console subsystem */
130 if (rc != NO_ERROR) /* check for errors */
131 dprintf(("KERNEL32:Win32Image:Init ConsoleInit failed with %u.\n", rc));
132 }
133
134 OS2SetExceptionHandler(&exceptFrame);
135 rc = WinExe->init(reservedMem, ulPEOffset);
136 if(rc != LDRERROR_SUCCESS)
137 {
138 if(szErrorModule[0] != 0) {
139 strncpy(pszErrorModule, szErrorModule, cbErrorModule-1);
140 pszErrorModule[cbErrorModule-1] = 0;
141 }
142 delete WinExe;
143 OS2UnsetExceptionHandler(&exceptFrame);
144 return rc;
145 }
146 OS2UnsetExceptionHandler(&exceptFrame);
147
148#ifdef PROFILE
149 // Note: after this point, we might start collecting performance
150 // information about the called functions.
151 PerfView_Initialize();
152 ProfilerInitialize();
153 ProfilerEnable(TRUE);
154#endif /* PROFILE */
155
156
157 WinExe->start();
158
159 delete WinExe;
160
161 return LDRERROR_SUCCESS;
162}
163//******************************************************************************
164//******************************************************************************
165Win32PeLdrExe::Win32PeLdrExe(char *szFileName, BOOL fConsoleApp) :
166 Win32ImageBase(-1),
167 Win32ExeBase(-1),
168 Win32PeLdrImage(szFileName, TRUE)
169{
170 //Signal to TEB management that we're an ummodified Win32 app and
171 //require setting FS to our special win32 selector
172 fSwitchTIBSel = TRUE;
173
174 dprintf(("Win32PeLdrExe ctor: %s", szFileName));
175 this->fConsoleApp = fConsoleApp;
176
177 //SvL: set temporary full path here as console init needs it
178 setFullPath(szFileName);
179}
180//******************************************************************************
181//******************************************************************************
182Win32PeLdrExe::~Win32PeLdrExe()
183{
184 fExitProcess = TRUE;
185}
186//******************************************************************************
187//Default stack size is 1MB; the PE loader reads it from the executable header
188//******************************************************************************
189ULONG Win32PeLdrExe::getDefaultStackSize()
190{
191 //Note: MUST use 128kb as a minimum. Or else the workarounds for out of
192 // stack space in 16 bits code (thread entrypoint) might fail.
193 return (poh->SizeOfStackReserve > 128*1024) ? poh->SizeOfStackReserve : 128*1024;
194}
195//******************************************************************************
196//******************************************************************************
Note: See TracBrowser for help on using the repository browser.