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

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

Thread bugfixes

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