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

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

Fixed Odin zombie processes when there's a trap inside vfprintf during logging.

File size: 32.1 KB
Line 
1/* $Id: wprocess.cpp,v 1.64 2000-01-02 22:09:02 sandervl Exp $ */
2
3/*
4 * Win32 process functions
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * NOTE: Even though Odin32 OS/2 apps don't switch FS selectors,
9 * we still allocate a TEB to store misc information.
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14#include <odin.h>
15#include <odinwrap.h>
16#include <os2win.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <unicode.h>
22#include <windllbase.h>
23#include <winexebase.h>
24#include <windllpeldr.h>
25#include <winfakepeldr.h>
26#include <vmutex.h>
27
28#ifdef __IBMCPP__
29#include <builtin.h>
30#endif
31
32#include "exceptutil.h"
33#include "oslibmisc.h"
34#include "oslibdebug.h"
35
36#include "console.h"
37#include "cio.h"
38#include "versionos2.h" /*PLF Wed 98-03-18 02:36:51*/
39#include <wprocess.h>
40#include "mmap.h"
41
42
43ODINDEBUGCHANNEL(KERNEL32-WPROCESS)
44
45
46//******************************************************************************
47//******************************************************************************
48BOOL fFreeLibrary = FALSE;
49BOOL fIsOS2Image = FALSE; //TRUE -> Odin32 OS/2 application (not converted!)
50 //FALSE -> otherwise
51//Process database
52PDB ProcessPDB = {0};
53USHORT ProcessTIBSel = 0;
54DWORD *TIBFlatPtr = 0;
55
56//list of thread database structures
57static THDB *threadList = 0;
58static VMutex threadListMutex;
59//******************************************************************************
60//******************************************************************************
61TEB *WIN32API GetThreadTEB()
62{
63 if(TIBFlatPtr == NULL)
64 return 0;
65
66 return (TEB *)*TIBFlatPtr;
67}
68//******************************************************************************
69//******************************************************************************
70THDB *WIN32API GetThreadTHDB()
71{
72 TEB *winteb;
73 THDB *thdb;
74
75 if(TIBFlatPtr == NULL)
76 return 0;
77
78 winteb = (TEB *)*TIBFlatPtr;
79 if(winteb == NULL) {
80 return NULL;
81 }
82 thdb = (THDB *)(winteb+1);
83
84 return thdb;
85}
86//******************************************************************************
87//******************************************************************************
88THDB *WIN32API GetTHDBFromThreadId(ULONG threadId)
89{
90 THDB *thdb = threadList;
91
92 threadListMutex.enter();
93 while(thdb) {
94 if(thdb->threadId == threadId) {
95 break;
96 }
97 thdb = thdb->next;
98 }
99 threadListMutex.leave();
100 return thdb;
101}
102//******************************************************************************
103// Set up the TIB selector and memory for the current thread
104//******************************************************************************
105TEB *InitializeTIB(BOOL fMainThread)
106{
107 TEB *winteb;
108 THDB *thdb;
109
110 USHORT tibsel;
111
112 //Allocate one dword to store the flat address of our TEB
113 if(fMainThread) {
114 TIBFlatPtr = (DWORD *)OSLibAllocThreadLocalMemory(1);
115 if(TIBFlatPtr == 0) {
116 dprintf(("InitializeTIB: local thread memory alloc failed!!"));
117 DebugInt3();
118 return NULL;
119 }
120 }
121 if(OSLibAllocSel(PAGE_SIZE, &tibsel) == FALSE)
122 {
123 dprintf(("InitializeTIB: selector alloc failed!!"));
124 DebugInt3();
125 return NULL;
126 }
127 winteb = (TEB *)OSLibSelToFlat(tibsel);
128 if(winteb == NULL)
129 {
130 dprintf(("InitializeTIB: DosSelToFlat failed!!"));
131 DebugInt3();
132 return NULL;
133 }
134 memset(winteb, 0, PAGE_SIZE);
135 thdb = (THDB *)(winteb+1);
136 *TIBFlatPtr = (DWORD)winteb;
137
138 winteb->except = (PVOID)-1; /* 00 Head of exception handling chain */
139 winteb->stack_top = (PVOID)OSLibGetTIB(TIB_STACKTOP); /* 04 Top of thread stack */
140 winteb->stack_low = (PVOID)OSLibGetTIB(TIB_STACKLOW); /* 08 Stack low-water mark */
141 winteb->htask16 = (USHORT)OSLibGetPIB(PIB_TASKHNDL); /* 0c Win16 task handle */
142 winteb->stack_sel = getSS(); /* 0e 16-bit stack selector */
143 winteb->self = winteb; /* 18 Pointer to this structure */
144 winteb->flags = TEBF_WIN32; /* 1c Flags */
145 winteb->queue = 0; /* 28 Message queue */
146 winteb->tls_ptr = &thdb->tls_array[0]; /* 2c Pointer to TLS array */
147 winteb->process = &ProcessPDB; /* 30 owning process (used by NT3.51 applets)*/
148
149 memcpy(&thdb->teb, winteb, sizeof(TEB));
150 thdb->process = &ProcessPDB;
151 thdb->exit_code = 0x103; /* STILL_ACTIVE */
152 thdb->teb_sel = tibsel;
153 thdb->OrgTIBSel = GetFS();
154 thdb->pWsockData = NULL;
155 thdb->threadId = GetCurrentThreadId();
156
157 threadListMutex.enter();
158 THDB *thdblast = threadList;
159 if(!thdblast) {
160 threadList = thdb;
161 }
162 else {
163 while(thdblast->next) {
164 thdblast = thdblast->next;
165 }
166 thdblast->next = thdb;
167 }
168 thdb->next = NULL;
169 threadListMutex.leave();
170
171 if(OSLibGetPIB(PIB_TASKTYPE) == TASKTYPE_PM)
172 {
173 thdb->flags = 0; //todo gui
174 }
175 else thdb->flags = 0; //todo textmode
176
177 if(fMainThread)
178 {
179 //todo initialize PDB during process creation
180 //todo: initialize TLS array if required
181 //TLS in executable always TLS index 0?
182 ProcessTIBSel = tibsel;
183 ProcessPDB.exit_code = 0x103; /* STILL_ACTIVE */
184 ProcessPDB.threads = 1;
185 ProcessPDB.running_threads = 1;
186 ProcessPDB.ring0_threads = 1;
187 ProcessPDB.system_heap = GetProcessHeap();
188 ProcessPDB.parent = 0;
189 ProcessPDB.group = &ProcessPDB;
190 ProcessPDB.priority = 8; /* Normal */
191 ProcessPDB.heap = ProcessPDB.system_heap; /* will be changed later on */
192 ProcessPDB.next = NULL;
193 ProcessPDB.winver = 0xffff; /* to be determined */
194 ProcessPDB.server_pid = (void *)GetCurrentProcessId();
195
196 GetSystemTime(&ProcessPDB.creationTime);
197
198 /* Initialize the critical section */
199 InitializeCriticalSection( &ProcessPDB.crit_section );
200 }
201 dprintf(("InitializeTIB setup TEB with selector %x", tibsel));
202 dprintf(("InitializeTIB: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
203 return winteb;
204}
205//******************************************************************************
206// Destroy the TIB selector and memory for the current thread
207//******************************************************************************
208void DestroyTIB()
209{
210 SHORT orgtibsel;
211 TEB *winteb;
212 THDB *thdb;
213
214 dprintf(("DestroyTIB: FS = %x", GetFS()));
215 dprintf(("DestroyTIB: FS:[0] = %x", QueryExceptionChain()));
216
217 winteb = (TEB *)*TIBFlatPtr;
218 if(winteb) {
219 thdb = (THDB *)(winteb+1);
220 orgtibsel = thdb->OrgTIBSel;
221
222 threadListMutex.enter();
223 THDB *curthdb = threadList;
224 if(curthdb == thdb) {
225 threadList = thdb->next;
226 }
227 else {
228 while(curthdb->next != thdb) {
229 curthdb = curthdb->next;
230 if(curthdb == NULL) {
231 dprintf(("DestroyTIB: couldn't find thdb %x", thdb));
232 DebugInt3();
233 break;
234 }
235 }
236 if(curthdb) {
237 curthdb->next = thdb->next;
238 }
239 }
240 threadListMutex.leave();
241
242 //Restore our original FS selector
243 SetFS(orgtibsel);
244
245 //And free our own
246 OSLibFreeSel(thdb->teb_sel);
247
248 *TIBFlatPtr = 0;
249 }
250 else dprintf(("Already destroyed TIB"));
251
252 dprintf(("DestroyTIB: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
253 return;
254}
255/******************************************************************************/
256/******************************************************************************/
257void SetPDBInstance(HINSTANCE hInstance)
258{
259 ProcessPDB.hInstance = hInstance;
260}
261/******************************************************************************/
262/******************************************************************************/
263void WIN32API RestoreOS2TIB()
264{
265 SHORT orgtibsel;
266 TEB *winteb;
267 THDB *thdb;
268
269 //If we're running an Odin32 OS/2 application (not converted!), then we
270 //we don't switch FS selectors
271 if(fIsOS2Image) {
272 return;
273 }
274
275 winteb = (TEB *)*TIBFlatPtr;
276 if(winteb) {
277 thdb = (THDB *)(winteb+1);
278 orgtibsel = thdb->OrgTIBSel;
279
280 //Restore our original FS selector
281 SetFS(orgtibsel);
282 }
283}
284/******************************************************************************/
285/******************************************************************************/
286USHORT WIN32API SetWin32TIB()
287{
288 SHORT win32tibsel;
289 TEB *winteb;
290 THDB *thdb;
291
292 //If we're running an Odin32 OS/2 application (not converted!), then we
293 //we don't switch FS selectors
294 if(fIsOS2Image) {
295 return GetFS();
296 }
297
298 winteb = (TEB *)*TIBFlatPtr;
299 if(winteb) {
300 thdb = (THDB *)(winteb+1);
301 win32tibsel = thdb->teb_sel;
302
303 //Restore our win32 FS selector
304 return SetReturnFS(win32tibsel);
305 }
306 else {
307 //we didn't create this thread, so allocate a selector now
308 //NOTE: Possible memory leak (i.e. DART threads in WINMM)
309 winteb = InitializeTIB();
310 if(winteb == NULL) {
311 DebugInt3();
312 return GetFS();
313 }
314 thdb = (THDB *)(winteb+1);
315 win32tibsel = thdb->teb_sel;
316
317 //Restore our win32 FS selector
318 return SetReturnFS(win32tibsel);
319 }
320 // nested calls are OK, OS2ToWinCallback for instance
321 //else DebugInt3();
322
323 return GetFS();
324}
325//******************************************************************************
326//******************************************************************************
327void _System Win32DllExitList(ULONG reason)
328{
329 dprintf(("Win32DllExitList %d\n", reason));
330
331 if(WinExe) {
332 delete(WinExe);
333 WinExe = NULL;
334 }
335 return;
336}
337//******************************************************************************
338//******************************************************************************
339VOID WIN32API ExitProcess(DWORD exitcode)
340{
341 dprintf(("KERNEL32: ExitProcess %d\n", exitcode));
342 dprintf(("KERNEL32: ExitProcess FS = %x\n", GetFS()));
343
344 SetOS2ExceptionChain(-1);
345
346 Win32DllExitList(0);
347
348 //Note: Needs to be done after Win32DllExitList (destruction of exe + dll objects)
349 //Flush and delete all open memory mapped files
350 Win32MemMap::deleteAll();
351
352 //Restore original OS/2 TIB selector
353 DestroyTIB();
354 SetExceptionChain((ULONG)-1);
355
356 //avoid crashes since win32 & OS/2 exception handler aren't identical
357 //(terminate process generates two exceptions)
358 /* @@@PH 1998/02/12 Added Console Support */
359 if (iConsoleIsActive())
360 iConsoleWaitClose();
361
362 O32_ExitProcess(exitcode);
363}
364//******************************************************************************
365//******************************************************************************
366BOOL WIN32API FreeLibrary(HINSTANCE hinstance)
367{
368 Win32DllBase *winmod;
369 BOOL rc;
370
371 dprintf(("FreeLibrary"));
372 winmod = Win32DllBase::findModule(hinstance);
373 if(winmod) {
374 winmod->Release();
375 return(TRUE);
376 }
377 dprintf(("KERNEL32: FreeLibrary %s %X\n", OSLibGetDllName(hinstance), hinstance));
378
379 //TODO: Not thread safe
380 fFreeLibrary = TRUE; //ditch dll
381 rc = O32_FreeLibrary(hinstance);
382 fFreeLibrary = FALSE;
383 dprintf(("FreeLibrary returned %X\n", rc));
384 return(TRUE);
385}
386/******************************************************************************/
387/******************************************************************************/
388static HINSTANCE iLoadLibraryA(LPCTSTR lpszLibFile, DWORD dwFlags)
389{
390 char modname[CCHMAXPATH];
391 HINSTANCE hDll;
392 Win32DllBase *module;
393
394 module = Win32DllBase::findModule((LPSTR)lpszLibFile);
395 if(module) {
396 module->AddRef();
397 dprintf(("iLoadLibrary: found %s -> handle %x", lpszLibFile, module->getInstanceHandle()));
398 return module->getInstanceHandle();
399 }
400
401 strcpy(modname, lpszLibFile);
402 strupr(modname);
403 //rename dll if necessary (i.e. OLE32 -> OLE32OS2)
404 Win32DllBase::renameDll(modname);
405
406 hDll = O32_LoadLibrary(modname);
407 dprintf(("KERNEL32: iLoadLibraryA %s returned %X (%d)\n",
408 lpszLibFile,
409 hDll,
410 GetLastError()));
411 if(hDll)
412 {
413 return hDll; //converted dll or win32k took care of it
414 }
415
416 if(!strstr(modname, ".")) {
417 strcat(modname,".DLL");
418 }
419
420 if(Win32ImageBase::isPEImage((char *)modname))
421 {
422 module = Win32DllBase::findModule((char *)modname);
423 if(module) {//don't load it again
424 module->AddRef();
425 return module->getInstanceHandle();
426 }
427
428 Win32PeLdrDll *peldrDll = new Win32PeLdrDll((char *)modname);
429 if(peldrDll == NULL)
430 return(0);
431
432 peldrDll->init(0);
433 if(peldrDll->getError() != NO_ERROR) {
434 dprintf(("LoadLibary %s failed (::init)\n", lpszLibFile));
435 delete(peldrDll);
436 return(0);
437 }
438 if(dwFlags & DONT_RESOLVE_DLL_REFERENCES) {
439 peldrDll->setNoEntryCalls();
440 }
441
442 if(peldrDll->attachProcess() == FALSE) {
443 dprintf(("LoadLibary %s failed (::attachProcess)\n", lpszLibFile));
444 delete(peldrDll);
445 return(0);
446 }
447 peldrDll->AddRef();
448 return peldrDll->getInstanceHandle();
449 }
450 else return(0);
451}
452//******************************************************************************
453//******************************************************************************
454HINSTANCE16 WIN32API LoadLibrary16(LPCTSTR lpszLibFile)
455{
456 dprintf(("ERROR: LoadLibrary16 %s, not implemented", lpszLibFile));
457 return 0;
458}
459//******************************************************************************
460//******************************************************************************
461VOID WIN32API FreeLibrary16(HINSTANCE16 hinstance)
462{
463 dprintf(("ERROR: FreeLibrary16 %x, not implemented", hinstance));
464}
465//******************************************************************************
466//******************************************************************************
467FARPROC WIN32API GetProcAddress16(HMODULE hModule, LPCSTR lpszProc)
468{
469 dprintf(("ERROR: GetProcAddress16 %x %x, not implemented", hModule, lpszProc));
470 return 0;
471}
472//******************************************************************************
473//******************************************************************************
474HINSTANCE WIN32API LoadLibraryA(LPCTSTR lpszLibFile)
475{
476 HINSTANCE hDll;
477
478 dprintf(("KERNEL32: LoadLibraryA(%s)\n",
479 lpszLibFile));
480 dprintf(("KERNEL32: LoadLibrary %x FS = %x\n", GetCurrentThreadId(), GetFS()));
481
482 hDll = iLoadLibraryA(lpszLibFile, 0);
483 if (hDll == 0)
484 {
485 char * pszName;
486
487 // remove path from the image name
488 pszName = strrchr((char *)lpszLibFile,
489 '\\');
490 if (pszName != NULL)
491 {
492 pszName++; // skip backslash
493
494 // now try again without fully qualified path
495 hDll = iLoadLibraryA(pszName, 0);
496 }
497 }
498
499 return hDll;
500}
501//******************************************************************************
502//******************************************************************************
503HINSTANCE WIN32API LoadLibraryExA(LPCTSTR lpszLibFile, HANDLE hFile, DWORD dwFlags)
504{
505 HINSTANCE hDll;
506
507 dprintf(("KERNEL32: LoadLibraryExA %s (%X)\n", lpszLibFile, dwFlags));
508 hDll = iLoadLibraryA(lpszLibFile, dwFlags);
509 if (hDll == 0)
510 {
511 char * pszName;
512
513 // remove path from the image name
514 pszName = strrchr((char *)lpszLibFile,
515 '\\');
516 if (pszName != NULL)
517 {
518 pszName++; // skip backslash
519
520 // now try again without fully qualified path
521 hDll = iLoadLibraryA(pszName, dwFlags);
522 }
523 }
524
525 return hDll;
526}
527//******************************************************************************
528//******************************************************************************
529HINSTANCE WIN32API LoadLibraryW(LPCWSTR lpModule)
530{
531 char *asciimodule;
532 HINSTANCE rc;
533
534 asciimodule = UnicodeToAsciiString((LPWSTR)lpModule);
535 dprintf(("KERNEL32: OS2LoadLibraryW %s\n", asciimodule));
536 rc = LoadLibraryA(asciimodule);
537 free(asciimodule);
538 return(rc);
539}
540//******************************************************************************
541//******************************************************************************
542HINSTANCE WIN32API LoadLibraryExW(LPCWSTR lpModule, HANDLE hFile, DWORD dwFlags)
543{
544 char *asciimodule;
545 HINSTANCE rc;
546
547 asciimodule = UnicodeToAsciiString((LPWSTR)lpModule);
548 dprintf(("KERNEL32: OS2LoadLibraryExW %s (%d)\n", asciimodule, dwFlags));
549 rc = LoadLibraryExA(asciimodule, hFile, dwFlags);
550 free(asciimodule);
551 return(rc);
552}
553//******************************************************************************
554//******************************************************************************
555LPCSTR WIN32API GetCommandLineA()
556{
557 LPTSTR cmdline = NULL;
558
559 if(WinExe) {
560 cmdline = WinExe->getCommandLine();
561 }
562 if(cmdline == NULL) //not used for converted exes
563 cmdline = O32_GetCommandLine();
564
565 dprintf(("KERNEL32: GetCommandLine %s\n", cmdline));
566 dprintf(("KERNEL32: FS = %x\n", GetFS()));
567 return(cmdline);
568}
569//******************************************************************************
570//******************************************************************************
571LPCWSTR WIN32API GetCommandLineW(void)
572{
573 static WCHAR *UnicodeCmdLine = NULL;
574 char *asciicmdline = NULL;
575
576 dprintf(("KERNEL32: FS = %x\n", GetFS()));
577
578 if(UnicodeCmdLine)
579 return(UnicodeCmdLine); //already called before
580
581 if(WinExe) {
582 asciicmdline = WinExe->getCommandLine();
583 }
584 if(asciicmdline == NULL) //not used for converted exes
585 asciicmdline = O32_GetCommandLine();
586
587 if(asciicmdline) {
588 UnicodeCmdLine = (WCHAR *)malloc(strlen(asciicmdline)*2 + 2);
589 AsciiToUnicode(asciicmdline, UnicodeCmdLine);
590 dprintf(("KERNEL32: OS2GetCommandLineW: %s\n", asciicmdline));
591 return(UnicodeCmdLine);
592 }
593 dprintf(("KERNEL32: OS2GetCommandLineW: asciicmdline == NULL\n"));
594 return NULL;
595}
596//******************************************************************************
597//******************************************************************************
598DWORD WIN32API GetModuleFileNameA(HMODULE hinstModule, LPTSTR lpszPath, DWORD cchPath)
599{
600 DWORD rc;
601 Win32ImageBase *module;
602 char *fpath = NULL;
603
604 dprintf(("GetModuleFileName %X", hinstModule));
605 if(hinstModule == 0 || hinstModule == -1 || (WinExe && hinstModule == WinExe->getInstanceHandle())) {
606 module = (Win32ImageBase *)WinExe;
607 }
608 else {
609 module = (Win32ImageBase *)Win32DllBase::findModule(hinstModule);
610 }
611
612 if(module) {
613 fpath = module->getFullPath();
614 }
615 if(fpath) {
616 //SvL: 13-9-98: +1
617 rc = min(strlen(fpath)+1, cchPath);
618 strncpy(lpszPath, fpath, rc);
619 }
620 else rc = O32_GetModuleFileName(hinstModule, lpszPath, cchPath);
621
622 if(rc) {
623 dprintf(("KERNEL32: GetModuleFileName %s %d\n", lpszPath, hinstModule));
624 }
625 return(rc);
626}
627//******************************************************************************
628//******************************************************************************
629DWORD WIN32API GetModuleFileNameW(HMODULE hModule, LPWSTR lpFileName, DWORD nSize)
630{
631 char *asciifilename = (char *)malloc(nSize+1);
632 DWORD rc;
633
634 dprintf(("KERNEL32: OSLibGetModuleFileNameW\n"));
635 rc = GetModuleFileNameA(hModule, asciifilename, nSize);
636 if(rc) AsciiToUnicode(asciifilename, lpFileName);
637 free(asciifilename);
638 return(rc);
639}
640//******************************************************************************
641//NOTE: GetModuleHandleA does NOT support files with multiple dots (i.e.
642// very.weird.exe)
643//******************************************************************************
644HANDLE WIN32API GetModuleHandleA(LPCTSTR lpszModule)
645{
646 HANDLE hMod;
647 Win32DllBase *windll;
648 char szModule[CCHMAXPATH];
649 BOOL fDllModule = FALSE;
650
651 if(lpszModule == NULL) {
652 if(WinExe)
653 hMod = WinExe->getInstanceHandle();
654 else hMod = -1;
655 }
656 else {
657 strcpy(szModule, OSLibStripPath((char *)lpszModule));
658 strupr(szModule);
659 if(strstr(szModule, ".DLL")) {
660 fDllModule = TRUE;
661 }
662 else {
663 if(!strstr(szModule, ".")) {
664 //if there's no extension or trainling dot, we
665 //assume it's a dll (see Win32 SDK docs)
666 fDllModule = TRUE;
667 }
668 }
669 char *dot = strstr(szModule, ".");
670 if(dot)
671 *dot = 0;
672
673 if(!fDllModule && WinExe && !strcmpi(szModule, WinExe->getModuleName())) {
674 hMod = WinExe->getInstanceHandle();
675 }
676 else {
677 windll = Win32DllBase::findModule(szModule);
678 if(windll) {
679 hMod = windll->getInstanceHandle();
680 }
681 else hMod = OSLibiGetModuleHandleA((char *)lpszModule);
682 }
683 }
684
685 dprintf(("KERNEL32: GetModuleHandle %s returned %X\n", lpszModule, hMod));
686 return(hMod);
687}
688//******************************************************************************
689//******************************************************************************
690HMODULE WIN32API GetModuleHandleW(LPCWSTR arg1)
691{
692 HMODULE rc;
693 char *astring;
694
695 astring = UnicodeToAsciiString((LPWSTR)arg1);
696 rc = GetModuleHandleA(astring);
697 dprintf(("KERNEL32: OS2GetModuleHandleW %s returned %X\n", astring, rc));
698 FreeAsciiString(astring);
699 return(rc);
700}
701//******************************************************************************
702//******************************************************************************
703BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
704 LPSECURITY_ATTRIBUTES lpProcessAttributes,
705 LPSECURITY_ATTRIBUTES lpThreadAttributes,
706 BOOL bInheritHandles, DWORD dwCreationFlags,
707 LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
708 LPSTARTUPINFOA lpStartupInfo,
709 LPPROCESS_INFORMATION lpProcessInfo )
710{
711 THDB *pThreadDB = (THDB*)GetThreadTHDB();
712 char *cmdline = NULL;
713 BOOL rc;
714
715 dprintf(("KERNEL32: CreateProcessA %s cline:%s inherit:%d cFlags:%x Env:%x CurDir:%s StartupFlags:%x\n",
716 lpApplicationName, lpCommandLine, bInheritHandles, dwCreationFlags,
717 lpEnvironment, lpCurrentDirectory, lpStartupInfo));
718
719 // open32 does not support DEBUG_ONLY_THIS_PROCESS
720 if(dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
721 dwCreationFlags |= DEBUG_PROCESS;
722
723 if(O32_CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
724 lpThreadAttributes, bInheritHandles, dwCreationFlags,
725 lpEnvironment, lpCurrentDirectory, lpStartupInfo,
726 lpProcessInfo) == TRUE)
727 {
728 if (dwCreationFlags & DEBUG_PROCESS && pThreadDB != NULL)
729 {
730 if(pThreadDB->pidDebuggee != 0)
731 {
732 // TODO: handle this
733 dprintf(("KERNEL32: CreateProcess ERROR: This thread is already a debugger\n"));
734 }
735 else
736 {
737 pThreadDB->pidDebuggee = lpProcessInfo->dwProcessId;
738 OSLibStartDebugger((ULONG*)&pThreadDB->pidDebuggee);
739 }
740 }
741 else pThreadDB->pidDebuggee = 0;
742
743 return(TRUE);
744 }
745 //probably a win32 exe, so run it in the pe loader
746 if(lpApplicationName) {
747 if(lpCommandLine) {
748 //skip exe name in lpCommandLine
749 while(*lpCommandLine != 0 && *lpCommandLine != ' ')
750 lpCommandLine++;
751
752 if(*lpCommandLine != 0) {
753 lpCommandLine++;
754 }
755 cmdline = (char *)malloc(strlen(lpApplicationName)+strlen(lpCommandLine) + 16);
756 sprintf(cmdline, "PE.EXE %s %s", lpApplicationName, lpCommandLine);
757 }
758 else {
759 cmdline = (char *)malloc(strlen(lpApplicationName) + 16);
760 sprintf(cmdline, "PE.EXE %s", lpApplicationName);
761 }
762 }
763 else {
764 cmdline = (char *)malloc(strlen(lpCommandLine) + 16);
765 sprintf(cmdline, "PE.EXE %s", lpCommandLine);
766 }
767 dprintf(("KERNEL32: CreateProcess %s\n", cmdline));
768 rc = O32_CreateProcess("PE.EXE", (LPCSTR)cmdline,lpProcessAttributes,
769 lpThreadAttributes, bInheritHandles, dwCreationFlags,
770 lpEnvironment, lpCurrentDirectory, lpStartupInfo,
771 lpProcessInfo);
772 if(rc == TRUE) {
773 if (dwCreationFlags & DEBUG_PROCESS && pThreadDB != NULL)
774 {
775 if(pThreadDB->pidDebuggee != 0)
776 {
777 // TODO: handle this
778 dprintf(("KERNEL32: CreateProcess ERROR: This thread is already a debugger\n"));
779 }
780 else
781 {
782 pThreadDB->pidDebuggee = lpProcessInfo->dwProcessId;
783 OSLibStartDebugger((ULONG*)&pThreadDB->pidDebuggee);
784 }
785 }
786 else
787 pThreadDB->pidDebuggee = 0;
788 }
789 if(cmdline)
790 free(cmdline);
791
792 if(lpProcessInfo)
793 dprintf(("KERNEL32: CreateProcess returned %d hPro:%x hThr:%x pid:%x tid:%x\n",
794 rc, lpProcessInfo->hProcess, lpProcessInfo->hThread,
795 lpProcessInfo->dwProcessId,lpProcessInfo->dwThreadId));
796 else
797 dprintf(("KERNEL32: CreateProcess returned %d\n", rc));
798 return(rc);
799}
800//******************************************************************************
801//******************************************************************************
802BOOL WIN32API CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
803 PSECURITY_ATTRIBUTES lpProcessAttributes,
804 PSECURITY_ATTRIBUTES lpThreadAttributes,
805 BOOL bInheritHandles, DWORD dwCreationFlags,
806 LPVOID lpEnvironment,
807 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
808 LPPROCESS_INFORMATION lpProcessInfo)
809{
810 BOOL rc;
811 char *astring1 = 0, *astring2 = 0, *astring3 = 0;
812
813 dprintf(("KERNEL32: CreateProcessW"));
814 if(lpApplicationName)
815 astring1 = UnicodeToAsciiString((LPWSTR)lpApplicationName);
816 if(lpCommandLine)
817 astring2 = UnicodeToAsciiString(lpCommandLine);
818 if(lpCurrentDirectory)
819 astring3 = UnicodeToAsciiString((LPWSTR)lpCurrentDirectory);
820 rc = CreateProcessA(astring1, astring2, lpProcessAttributes, lpThreadAttributes,
821 bInheritHandles, dwCreationFlags, lpEnvironment,
822 astring3, (LPSTARTUPINFOA)lpStartupInfo,
823 lpProcessInfo);
824 if(astring3) FreeAsciiString(astring3);
825 if(astring2) FreeAsciiString(astring2);
826 if(astring1) FreeAsciiString(astring1);
827 return(rc);
828}
829//******************************************************************************
830//******************************************************************************
831HINSTANCE WIN32API WinExec(LPCSTR lpCmdLine, UINT nCmdShow)
832{
833 STARTUPINFOA startinfo = {0};
834 PROCESS_INFORMATION procinfo;
835
836 dprintf(("KERNEL32: WinExec %s\n", lpCmdLine));
837 startinfo.dwFlags = nCmdShow;
838 if(CreateProcessA(NULL, (LPSTR)lpCmdLine, NULL, NULL, FALSE, 0, NULL, NULL,
839 &startinfo, &procinfo) == FALSE)
840 {
841 return 0;
842 }
843 return procinfo.hProcess; //correct?
844}
845//******************************************************************************
846//******************************************************************************
847FARPROC WIN32API GetProcAddress(HMODULE hModule, LPCSTR lpszProc)
848{
849 Win32ImageBase *winmod;
850 FARPROC proc;
851 ULONG ulAPIOrdinal;
852
853 if(hModule == 0 || hModule == -1 || (WinExe && hModule == WinExe->getInstanceHandle())) {
854 winmod = WinExe;
855 }
856 else winmod = (Win32ImageBase *)Win32DllBase::findModule((HINSTANCE)hModule);
857
858 if(winmod) {
859 ulAPIOrdinal = (ULONG)lpszProc;
860 if (ulAPIOrdinal <= 0x0000FFFF) {
861 proc = (FARPROC)winmod->getApi((int)ulAPIOrdinal);
862 }
863 else proc = (FARPROC)winmod->getApi((char *)lpszProc);
864 if(proc == 0) {
865 SetLastError(ERROR_PROC_NOT_FOUND);
866 }
867 return proc;
868 }
869 proc = O32_GetProcAddress(hModule, lpszProc);
870 if(HIWORD(lpszProc))
871 dprintf(("KERNEL32: GetProcAddress %s from %X returned %X\n", lpszProc, hModule, proc));
872 else dprintf(("KERNEL32: GetProcAddress %x from %X returned %X\n", lpszProc, hModule, proc));
873 return(proc);
874}
875//******************************************************************************
876//Retrieve the version
877//******************************************************************************
878BOOL SYSTEM GetVersionStruct(char *lpszModName, char *verstruct, ULONG bufLength)
879{
880 Win32ImageBase *winimage;
881 Win32PeLdrRsrcImg *rsrcimg;
882
883 dprintf(("GetVersionStruct of module %s", lpszModName));
884 if(WinExe && !stricmp(WinExe->getFullPath(), lpszModName)) {
885 winimage = (Win32ImageBase *)WinExe;
886 }
887 else {
888 winimage = (Win32ImageBase *)Win32DllBase::findModule(lpszModName);
889 if(winimage == NULL)
890 {
891 char modname[CCHMAXPATH];
892
893 strcpy(modname, lpszModName);
894 //rename dll if necessary (i.e. OLE32 -> OLE32OS2)
895 Win32DllBase::renameDll(modname);
896
897 if(Win32ImageBase::isPEImage(modname) == FALSE)
898 {
899 HINSTANCE hInstance;
900
901 //must be an LX dll, just load it (app will probably load it anyway)
902 hInstance = LoadLibraryA(modname);
903 if(hInstance == 0)
904 return 0;
905 winimage = (Win32ImageBase *)Win32DllBase::findModule(hInstance);
906 if(winimage) {
907 return winimage->getVersionStruct(verstruct, bufLength);
908 }
909 return 0;
910 }
911 //SvL: Try to load it
912 rsrcimg = new Win32PeLdrRsrcImg(modname);
913 if(rsrcimg == NULL)
914 return 0;
915
916 rsrcimg->init(0);
917 if(rsrcimg->getError() != NO_ERROR)
918 {
919 dprintf(("GetVersionStruct can't load %s\n", modname));
920 delete rsrcimg;
921 return(FALSE);
922 }
923 BOOL rc = rsrcimg->getVersionStruct(verstruct, bufLength);
924 delete rsrcimg;
925 return rc;
926 }
927 }
928 return winimage->getVersionStruct(verstruct, bufLength);
929}
930//******************************************************************************
931//******************************************************************************
932ULONG SYSTEM GetVersionSize(char *lpszModName)
933{
934 Win32ImageBase *winimage;
935 Win32PeLdrRsrcImg *rsrcimg;
936
937 dprintf(("GetVersionSize of %s\n", lpszModName));
938
939 if(WinExe && !stricmp(WinExe->getFullPath(), lpszModName)) {
940 winimage = (Win32ImageBase *)WinExe;
941 }
942 else {
943 winimage = (Win32ImageBase *)Win32DllBase::findModule(lpszModName);
944 if(winimage == NULL)
945 {
946 char modname[CCHMAXPATH];
947
948 strcpy(modname, lpszModName);
949 //rename dll if necessary (i.e. OLE32 -> OLE32OS2)
950 Win32DllBase::renameDll(modname);
951
952 if(Win32ImageBase::isPEImage(modname) == FALSE)
953 {
954 HINSTANCE hInstance;
955
956 //must be an LX dll, just load it (app will probably load it anyway)
957 hInstance = LoadLibraryA(modname);
958 if(hInstance == 0)
959 return 0;
960 winimage = (Win32ImageBase *)Win32DllBase::findModule(hInstance);
961 if(winimage) {
962 return winimage->getVersionSize();
963 }
964 return 0;
965 }
966
967 //SvL: Try to load it
968 rsrcimg = new Win32PeLdrRsrcImg(modname);
969 if(rsrcimg == NULL)
970 return 0;
971
972 rsrcimg->init(0);
973 if(rsrcimg->getError() != NO_ERROR)
974 {
975 dprintf(("GetVersionSize can't load %s\n", modname));
976 delete rsrcimg;
977 return(FALSE);
978 }
979 int size = rsrcimg->getVersionSize();
980 delete rsrcimg;
981 return size;
982 }
983 }
984 return winimage->getVersionSize();
985}
986//******************************************************************************
987//TODO:What does this do exactly??
988//******************************************************************************
989ODINFUNCTION1(BOOL,DisableThreadLibraryCalls,HMODULE,hModule)
990{
991 Win32DllBase *winmod;
992 FARPROC proc;
993 ULONG ulAPIOrdinal;
994
995 winmod = Win32DllBase::findModule((HINSTANCE)hModule);
996 if(winmod)
997 {
998 // don't call ATTACH/DETACH thread functions in DLL
999 winmod->setThreadLibraryCalls(FALSE);
1000 return TRUE;
1001 }
1002 else
1003 {
1004 // raise error condition
1005 SetLastError(ERROR_INVALID_HANDLE);
1006 return FALSE;
1007 }
1008}
1009//******************************************************************************
1010//******************************************************************************
Note: See TracBrowser for help on using the repository browser.