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

Last change on this file since 10397 was 10397, checked in by sandervl, 22 years ago

Loader updates

File size: 5.7 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#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 (poh->SizeOfStackReserve > 128*1024) ? poh->SizeOfStackReserve : 128*1024;
187}
188//******************************************************************************
189//******************************************************************************
Note: See TracBrowser for help on using the repository browser.