source: trunk/src/kernel32/winexepeldr.cpp@ 9780

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

Touch all stack pages we skip in the out of stack workaround for 16 bits code. Jumping over the guard page causes a protection violation exception

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