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

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

Added GetTHDBFromThreadId + link THDB structures

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