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

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

Allow executable api exports

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