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

Last change on this file since 17 was 17, checked in by phaller, 26 years ago

Code cleanup #1 for build, mainly addresses linkage problems

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