source: trunk/src/kernel32/wprocess.cpp@ 46

Last change on this file since 46 was 46, checked in by sandervl, 26 years ago

* empty log message *

File size: 17.8 KB
Line 
1/*
2 *
3 * Project Odin Software License can be found in LICENSE.TXT
4 *
5 */
6/*
7 * Win32 process functions
8 *
9 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
10 *
11 */
12#include <os2win.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include "unicode.h"
17#include "windll.h"
18#include "winexe.h"
19#ifdef __IBMCPP__
20#include <builtin.h>
21#endif
22#include "except.h"
23#include "os2util.h"
24#include "console2.h"
25#include "cio.h"
26#include "versionos2.h" /*PLF Wed 98-03-18 02:36:51*/
27
28BOOL fExeStarted = FALSE;
29BOOL fFreeLibrary = FALSE;
30
31/******************************************************************************/
32//SvL: 4-10-'98: Put in separate procedure, as ICC changes FS:0 when there
33// are new or delete calls present.
34//******************************************************************************
35void RegisterExe(LONG Win32TableId, LONG NameTableId, LONG VersionResId,
36 LONG Pe2lxVersion, HINSTANCE hinstance)
37{
38 if(WinExe != NULL) //should never happen
39 delete(WinExe);
40
41 //SvL: Use 0 instead of the real instance handle (for resource lookup)
42 Win32Exe *winexe = new Win32Exe(0, NameTableId, Win32TableId);
43 if(winexe) {
44 winexe->setVersionId(VersionResId);
45 winexe->setOS2InstanceHandle(hinstance);
46 }
47 else {
48 eprintf(("Win32Exe creation failed!\n"));
49 DebugInt3();
50 }
51 char *modname;
52 if(modname = getenv("WIN32MODULE")) {
53 dprintf(("Set full path for exe to %s", modname));
54 winexe->setFullPath(modname);
55 }
56
57 fExeStarted = TRUE;
58}
59//******************************************************************************
60//******************************************************************************
61VOID WIN32API RegisterResourceUsage(LONG Win32TableId, LONG NameTableId,
62 LONG VersionResId, LONG Pe2lxVersion,
63 HINSTANCE hinstance)
64{
65 if(getenv("WIN32_IOPL2")) {
66 io_init1();
67 }
68 dprintf(("RegisterResourceUsage %X resid = %d\n", hinstance, VersionResId));
69
70 CheckVersion(Pe2lxVersion, OS2GetDllName(hinstance));
71
72 RegisterExe(Win32TableId, NameTableId, VersionResId, Pe2lxVersion, hinstance);
73
74 //NOTE: Breaks Quake 2 if enabled
75 if(getenv("WIN32_NOEXCEPTION")) {
76 ChangeTIBStack(); //disable exceptions
77 }
78}
79//******************************************************************************
80//******************************************************************************
81void CreateDll(LONG Win32TableId, LONG NameTableId, LONG VersionResId,
82 HINSTANCE hinstance, WIN32DLLENTRY pfnDllEntry)
83{
84 Win32Dll *winmod = Win32Dll::findModule(hinstance);
85
86 if(winmod != NULL) {
87 //dll manually loaded by PE loader (Win32Dll::init)
88 winmod->OS2DllInit(hinstance, NameTableId, Win32TableId, pfnDllEntry);
89 return;
90 }
91
92 //converted win32 dll loaded by OS/2 loader
93 winmod = new Win32Dll(hinstance, NameTableId, Win32TableId, pfnDllEntry);
94 if(winmod == NULL) {
95 eprintf(("Failed to allocate module object!\n"));
96 DebugInt3();
97 return;
98 }
99 //SvL: 19-8-'98
100 winmod->AddRef();
101 winmod->setVersionId(VersionResId);
102}
103//******************************************************************************
104//******************************************************************************
105VOID WIN32API RegisterDll(LONG Win32TableId, LONG NameTableId,
106 LONG VersionResId, LONG Pe2lxVersion,
107 HINSTANCE hinstance)
108{
109 WIN32DLLENTRY pfnDllEntry;
110 char *name;
111
112 pfnDllEntry = (WIN32DLLENTRY)GetDllEntryPoint(); //== return address
113
114 if(getenv("WIN32_IOPL2")) {
115 io_init1();
116 }
117 name = OS2GetDllName(hinstance);
118 CheckVersion(Pe2lxVersion, name);
119
120 dprintf(("RegisterDll %X %s\n", hinstance, name));
121
122 CreateDll(Win32TableId, NameTableId, VersionResId, hinstance, pfnDllEntry);
123
124 /* @@@PH 1998/03/17 console devices initialization */
125 ConsoleDevicesRegister();
126}
127//******************************************************************************
128//******************************************************************************
129void _System Win32DllExitList(ULONG reason)
130{
131 dprintf(("Win32DllExitList %d\n", reason));
132
133 if(WinExe) {
134 delete WinExe;
135 WinExe = NULL;
136 }
137 return;
138}
139//******************************************************************************
140//Called when a dll is detached (either at process exit or when FreeLibrary is called)
141//******************************************************************************
142BOOL WIN32API DLLExitList(HINSTANCE hInstance)
143{
144// dprintf(("DLLExitList"));
145 Win32Dll *winmod = Win32Dll::findModule(hInstance);
146
147 if(winmod == NULL) {//probably called after we manually unloaded it in ExitProcess
148 return(1); //remove it from memory
149 }
150 dprintf(("DllExitList for %s (%X)\n", OS2GetDllName(winmod->getInstanceHandle()), winmod->getInstanceHandle()));
151 delete(winmod);
152
153 if(fFreeLibrary) {
154 dprintf(("KERNEL32: DLLExitList Ditched by FreeLibrary\n"));
155 return(1); //remove it as we no longer need it
156 }
157 return(0); //don't remove it (OS/2 can unload them at process exit in the wrong order!)
158}
159//******************************************************************************
160//******************************************************************************
161VOID WIN32API ExitProcess(DWORD exitcode)
162{
163 dprintf(("KERNEL32: ExitProcess %d\n", exitcode));
164
165 //avoid crashes since win32 & OS/2 exception handler aren't identical
166 //(terminate process generates two exceptions)
167 /* @@@PH 1998/02/12 Added Console Support */
168 if (ConsoleIsActive())
169 ConsoleWaitClose();
170
171 try {
172 Win32DllExitList(-1);
173 }
174 catch(...) {
175 dprintf(("dll exitlist exception\n"));
176 }
177 SetExceptionChain((ULONG)-1);
178 O32_ExitProcess(exitcode);
179}
180//******************************************************************************
181//******************************************************************************
182BOOL WIN32API FreeLibrary(HINSTANCE hinstance)
183{
184 Win32Dll *winmod;
185 BOOL rc;
186
187 dprintf(("FreeLibrary"));
188 winmod = Win32Dll::findModule(hinstance);
189 if(winmod) {
190 winmod->Release();
191 return(TRUE);
192 }
193 dprintf(("KERNEL32: FreeLibrary %s %X\n", OS2GetDllName(hinstance), hinstance));
194
195 //TODO: Not thread safe
196 fFreeLibrary = TRUE; //ditch dll
197 rc = O32_FreeLibrary(hinstance);
198 fFreeLibrary = FALSE;
199 dprintf(("FreeLibrary returned %X\n", rc));
200 return(TRUE);
201}
202/******************************************************************************/
203/******************************************************************************/
204HINSTANCE WIN32API LoadLibraryA(LPCTSTR lpszLibFile)
205{
206 HINSTANCE hDll;
207 Win32Dll *module;
208
209 hDll = O32_LoadLibrary(lpszLibFile);
210 dprintf(("KERNEL32: LoadLibraryA %s returned %X (%d)\n", lpszLibFile, hDll, GetLastError()));
211 if(hDll) {
212 return hDll; //converted dll or win32k took care of it
213 }
214
215 if(Win32Image::isPEImage((char *)lpszLibFile)) {
216 module = Win32Dll::findModule((char *)lpszLibFile);
217 if(module) {//don't load it again
218 module->AddRef();
219 return module->getInstanceHandle();
220 }
221 module = new Win32Dll((char *)lpszLibFile);
222 if(module == NULL)
223 return(0);
224
225 module->init();
226 if(module->getError() != NO_ERROR) {
227 dprintf(("LoadLibary %s failed (::init)\n", lpszLibFile));
228 delete module;
229 return(0);
230 }
231 if(module->attachProcess() == FALSE) {
232 dprintf(("LoadLibary %s failed (::attachProcess)\n", lpszLibFile));
233 delete module;
234 return(0);
235 }
236 module->AddRef();
237 return module->getInstanceHandle();
238 }
239 else return(0);
240}
241//******************************************************************************
242//******************************************************************************
243HINSTANCE WIN32API LoadLibraryExA(LPCTSTR lpszLibFile, HANDLE hFile, DWORD dwFlags)
244{
245 Win32Dll *module;
246 HINSTANCE hDll;
247
248 dprintf(("KERNEL32: LoadLibraryExA %s (%X)\n", lpszLibFile, dwFlags));
249 hDll = O32_LoadLibrary(lpszLibFile);
250 if(hDll) {
251 return hDll; //converted dll or win32k took care of it
252 }
253
254 if(Win32Image::isPEImage((char *)lpszLibFile)) {
255 module = Win32Dll::findModule((char *)lpszLibFile);
256 if(module) {//don't load it again
257 module->AddRef();
258 return module->getInstanceHandle();
259 }
260 module = new Win32Dll((char *)lpszLibFile);
261 if(module == NULL)
262 return(0);
263
264 module->init();
265 if(module->getError() != NO_ERROR) {
266 dprintf(("LoadLibary %s failed (::init)\n", lpszLibFile));
267 delete module;
268 return(0);
269 }
270 if(dwFlags & DONT_RESOLVE_DLL_REFERENCES) {
271 module->setNoEntryCalls();
272 }
273 if(module->attachProcess() == FALSE) {
274 dprintf(("LoadLibary %s failed (::attachProcess)\n", lpszLibFile));
275 delete module;
276 return(0);
277 }
278 module->AddRef();
279 return module->getInstanceHandle();
280 }
281 return(0);
282}
283//******************************************************************************
284//******************************************************************************
285HINSTANCE WIN32API LoadLibraryW(LPCWSTR lpModule)
286{
287 char *asciimodule;
288 HINSTANCE rc;
289
290 asciimodule = UnicodeToAsciiString((LPWSTR)lpModule);
291 dprintf(("KERNEL32: OS2LoadLibraryW %s\n", asciimodule));
292 rc = LoadLibraryA(asciimodule);
293 free(asciimodule);
294 return(rc);
295}
296//******************************************************************************
297//******************************************************************************
298HINSTANCE WIN32API LoadLibraryExW(LPCWSTR lpModule, HANDLE hFile, DWORD dwFlags)
299{
300 char *asciimodule;
301 HINSTANCE rc;
302
303 asciimodule = UnicodeToAsciiString((LPWSTR)lpModule);
304 dprintf(("KERNEL32: OS2LoadLibraryExW %s (%d)\n", asciimodule, dwFlags));
305 rc = LoadLibraryExA(asciimodule, hFile, dwFlags);
306 free(asciimodule);
307 return(rc);
308}
309//******************************************************************************
310//******************************************************************************
311LPCSTR WIN32API GetCommandLineA()
312{
313 LPTSTR cmdline = NULL;
314
315 if(WinExe) {
316 cmdline = WinExe->getCommandLine();
317 }
318 if(cmdline == NULL) //not used for converted exes
319 cmdline = O32_GetCommandLine();
320
321 dprintf(("KERNEL32: GetCommandLine %s\n", cmdline));
322 //SvL: Replace original startup code exception handler
323 ReplaceExceptionHandler();
324 return(cmdline);
325}
326//******************************************************************************
327//******************************************************************************
328LPCWSTR WIN32API GetCommandLineW(void)
329{
330 static WCHAR *UnicodeCmdLine = NULL;
331 char *asciicmdline = NULL;
332
333 //SvL: Replace original startup code exception handler
334 ReplaceExceptionHandler();
335
336 if(UnicodeCmdLine)
337 return(UnicodeCmdLine); //already called before
338
339 if(WinExe) {
340 asciicmdline = WinExe->getCommandLine();
341 }
342 if(asciicmdline == NULL) //not used for converted exes
343 asciicmdline = O32_GetCommandLine();
344
345 if(asciicmdline) {
346 UnicodeCmdLine = (WCHAR *)malloc(strlen(asciicmdline)*2 + 2);
347 AsciiToUnicode(asciicmdline, UnicodeCmdLine);
348 dprintf(("KERNEL32: OS2GetCommandLineW: %s\n", asciicmdline));
349 return(UnicodeCmdLine);
350 }
351 dprintf(("KERNEL32: OS2GetCommandLineW: asciicmdline == NULL\n"));
352 return NULL;
353}
354//******************************************************************************
355//******************************************************************************
356DWORD WIN32API GetModuleFileNameA(HMODULE hinstModule, LPTSTR lpszPath, DWORD cchPath)
357{
358 DWORD rc;
359 Win32Image *module;
360 char *fpath = NULL;
361
362 dprintf(("GetModuleFileName %X", hinstModule));
363 if(hinstModule == 0 || hinstModule == -1 || (WinExe && hinstModule == WinExe->getOS2InstanceHandle())) {
364 module = (Win32Image *)WinExe;
365 }
366 else {
367 module = (Win32Image *)Win32Dll::findModule(hinstModule);
368 }
369
370 if(module) {
371 fpath = module->getFullPath();
372 }
373 if(fpath) {
374 //SvL: 13-9-98: +1
375 rc = min(strlen(fpath)+1, cchPath);
376 strncpy(lpszPath, fpath, rc);
377 }
378 else rc = O32_GetModuleFileName(hinstModule, lpszPath, cchPath);
379
380 if(rc) {
381 dprintf(("KERNEL32: GetModuleFileName %s %d\n", lpszPath, hinstModule));
382 }
383 return(rc);
384}
385//******************************************************************************
386//******************************************************************************
387DWORD WIN32API GetModuleFileNameW(HMODULE hModule, LPWSTR lpFileName, DWORD nSize)
388{
389 char *asciifilename = (char *)malloc(nSize+1);
390 DWORD rc;
391
392 dprintf(("KERNEL32: OS2GetModuleFileNameW\n"));
393 rc = GetModuleFileNameA(hModule, asciifilename, nSize);
394 if(rc) AsciiToUnicode(asciifilename, lpFileName);
395 free(asciifilename);
396 return(rc);
397}
398//******************************************************************************
399//******************************************************************************
400BOOL WIN32API CreateProcessA(LPCSTR lpszImageName, LPSTR lpszCommandLine,
401 PSECURITY_ATTRIBUTES arg3,
402 PSECURITY_ATTRIBUTES arg4, BOOL arg5, DWORD arg6,
403 PVOID arg7, LPCSTR arg8, LPSTARTUPINFOA arg9,
404 LPPROCESS_INFORMATION arg10)
405{
406 BOOL rc;
407 char *cmdline;
408 BOOL fAllocStr = FALSE;
409
410 if(O32_CreateProcess(lpszImageName, lpszCommandLine, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) == TRUE)
411 return(TRUE);
412
413 //probably a win32 exe, so run it in the pe loader
414 if(lpszImageName) {
415 if(lpszCommandLine) {
416 cmdline = (char *)malloc(strlen(lpszImageName)+strlen(lpszCommandLine) + 16);
417 sprintf(cmdline, "%s %s", lpszImageName, lpszCommandLine);
418 fAllocStr = TRUE;
419 }
420 else cmdline = (char *)lpszImageName;
421 }
422 else cmdline = (char *)lpszCommandLine;
423
424 dprintf(("KERNEL32: CreateProcess %s\n", cmdline));
425 rc = O32_CreateProcess("PE.EXE", (LPCSTR)cmdline, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
426 if(fAllocStr)
427 free(cmdline);
428
429 dprintf(("KERNEL32: CreateProcess returned %d\n", rc));
430 return(rc);
431}
432//******************************************************************************
433//******************************************************************************
434BOOL WIN32API CreateProcessW(LPCWSTR arg1, LPWSTR arg2,
435 PSECURITY_ATTRIBUTES arg3,
436 PSECURITY_ATTRIBUTES arg4,
437 BOOL arg5, DWORD arg6, PVOID arg7,
438 LPCWSTR arg8, LPSTARTUPINFOW arg9,
439 LPPROCESS_INFORMATION arg10)
440{
441 BOOL rc;
442 char *astring1, *astring2, *astring3;
443
444 dprintf(("KERNEL32: OS2CreateProcessW DOESN't WORK"));
445 astring1 = UnicodeToAsciiString((LPWSTR)arg1);
446 astring2 = UnicodeToAsciiString(arg2);
447 astring3 = UnicodeToAsciiString((LPWSTR)arg8);
448 // NOTE: This will not work as is (needs UNICODE support)
449 rc = CreateProcessA(astring1, astring2, arg3, arg4, arg5, arg6, arg7,
450 astring3, (LPSTARTUPINFOA)arg9, arg10);
451 FreeAsciiString(astring3);
452 FreeAsciiString(astring2);
453 FreeAsciiString(astring1);
454 return(rc);
455}
456//******************************************************************************
457//******************************************************************************
458FARPROC WIN32API GetProcAddress(HMODULE hModule, LPCSTR lpszProc)
459{
460 Win32Dll *winmod;
461 FARPROC proc;
462 ULONG ulAPIOrdinal;
463
464 winmod = Win32Dll::findModule((HINSTANCE)hModule);
465 if(winmod) {
466 ulAPIOrdinal = (ULONG)lpszProc;
467 if (ulAPIOrdinal <= 0x0000FFFF) {
468 return (FARPROC)winmod->getApi((int)ulAPIOrdinal);
469 }
470 else return (FARPROC)winmod->getApi((char *)lpszProc);
471 }
472 proc = O32_GetProcAddress(hModule, lpszProc);
473 dprintf(("KERNEL32: GetProcAddress %s from %X returned %X\n", lpszProc, hModule, proc));
474 return(proc);
475}
476//******************************************************************************
477//Retrieve the version
478//******************************************************************************
479BOOL SYSTEM GetVersionStruct(char *modname, char *verstruct, ULONG bufLength)
480{
481 HINSTANCE hinstance;
482 Win32Image *winimage;
483
484 dprintf(("GetVersionStruct"));
485 hinstance = OS2QueryModuleHandle(modname);
486 if(hinstance == 0) {
487 dprintf(("GetVersionStruct can't find handle for %s\n", modname));
488 return(FALSE);
489 }
490 if(WinExe && WinExe->getOS2InstanceHandle() == hinstance) {
491 winimage = (Win32Image *)WinExe;
492 }
493 else {
494 winimage = (Win32Image *)Win32Dll::findModule(hinstance);
495 if(winimage == NULL) {
496 dprintf(("GetVersionStruct can't find Win32Image for %s\n", modname));
497 return(FALSE);
498 }
499 }
500 if(winimage->getVersionId() == -1) {
501 dprintf(("GetVersionStruct: %s has no version resource!\n", modname));
502 return(FALSE);
503 }
504 return OS2GetResource(hinstance, winimage->getVersionId(), verstruct, bufLength);
505}
506//******************************************************************************
507//******************************************************************************
508ULONG SYSTEM GetVersionSize(char *modname)
509{
510 HINSTANCE hinstance;
511 Win32Image *winimage;
512
513 dprintf(("GetVersionSize of %s\n", modname));
514 hinstance = OS2QueryModuleHandle(modname);
515 if(hinstance == 0) {
516 dprintf(("GetVersionSize can't find handle for %s\n", modname));
517 return(FALSE);
518 }
519
520 if(WinExe && WinExe->getOS2InstanceHandle() == hinstance) {
521 winimage = (Win32Image *)WinExe;
522 }
523 else {
524 winimage = (Win32Image *)Win32Dll::findModule(hinstance);
525 if(winimage == NULL) {
526 dprintf(("GetVersionSize can't find Win32Image for %s\n", modname));
527 return(FALSE);
528 }
529 }
530 if(winimage->getVersionId() == -1) {
531 dprintf(("GetVersionSize: %s has no version resource!\n", modname));
532 return(FALSE);
533 }
534 ULONG size = OS2GetResourceSize(hinstance, winimage->getVersionId());
535
536 dprintf(("Version resource size = %d, id %d\n", size, winimage->getVersionId()));
537 return(size);
538}
539//******************************************************************************
540//******************************************************************************
Note: See TracBrowser for help on using the repository browser.