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

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

Add: added cvs variable $Id$ to source files.

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