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

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

VirtualAlloc fixes & changes

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