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

Last change on this file since 3059 was 3059, checked in by sandervl, 25 years ago

Dll dependency changes

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