source: trunk/src/kernel32/process.cpp@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 17.5 KB
Line 
1/* $Id: process.cpp,v 1.11 2004-02-10 15:37:54 sandervl Exp $ */
2
3/*
4 * Win32 process functions for OS/2
5 *
6 * Copyright 1999 Sander van Leeuwen (OS/2 Port)
7 *
8 * TODO: Not done yet! (setting up process structures)
9 *
10 * Based on Wine code (scheduler\process.c)
11 *
12 * Copyright 1996, 1998 Alexandre Julliard
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <odin.h>
18#include <odinwrap.h>
19#include <os2sel.h>
20
21#include <os2win.h>
22#include <winnt.h>
23#include <winnls.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include <misc.h>
28#include <wprocess.h>
29#include <win/task.h>
30#include "winimagebase.h"
31#include "oslibdos.h"
32
33#define DBG_LOCALLOG DBG_process
34#include "dbglocal.h"
35
36#define SHUTDOWN_NORETRY 1
37
38static unsigned int shutdown_noretry = 0;
39static unsigned int shutdown_priority = 0x280L;
40static DWORD ProcessAffinityMask = 1;
41static PDB *PROCESS_First = &ProcessPDB;
42
43extern "C" {
44
45/***********************************************************************
46 * PROCESS_IdToPDB
47 *
48 * Convert a process id to a PDB, making sure it is valid.
49 */
50PDB *PROCESS_IdToPDB( DWORD id )
51{
52 PDB *pdb;
53
54 if (!id) return PROCESS_Current();
55 pdb = PROCESS_First;
56 while (pdb)
57 {
58 if ((DWORD)pdb->server_pid == id) return pdb;
59 pdb = pdb->next;
60 }
61 SetLastError( ERROR_INVALID_PARAMETER );
62 return NULL;
63}
64//******************************************************************************
65//******************************************************************************
66HANDLE WIN32API OpenProcess(DWORD arg1, BOOL arg2, DWORD arg3)
67{
68 dprintf(("KERNEL32: OS2OpenProcess\n"));
69 return O32_OpenProcess(arg1, arg2, arg3);
70}
71//******************************************************************************
72//******************************************************************************
73BOOL WIN32API GetExitCodeProcess(HANDLE hProcess, LPDWORD arg2)
74{
75 BOOL rc;
76
77 rc = O32_GetExitCodeProcess(hProcess, arg2);
78 dprintf(("KERNEL32: GetExitCodeProcess %x returned %d (%x)", hProcess, rc, (arg2) ? *arg2 : 0));
79 return rc;
80}
81//******************************************************************************
82//******************************************************************************
83HANDLE WIN32API GetCurrentProcess(void)
84{
85 dprintf2(("KERNEL32: GetCurrentProcess\n"));
86 return O32_GetCurrentProcess();
87}
88//******************************************************************************
89//******************************************************************************
90DWORD WIN32API GetCurrentProcessId(void)
91{
92 dprintf2(("KERNEL32: GetCurrentProcessId\n"));
93 return O32_GetCurrentProcessId();
94}
95//******************************************************************************
96//******************************************************************************
97BOOL WIN32API TerminateProcess( HANDLE arg1, DWORD arg2)
98{
99 dprintf(("KERNEL32: TerminateProcess\n"));
100 return O32_TerminateProcess(arg1, arg2);
101}
102//******************************************************************************
103//******************************************************************************
104DWORD WIN32API GetProcessVersion(DWORD Processid)
105{
106 Win32ImageBase *image;
107 PDB *process = PROCESS_IdToPDB( Processid );
108 DWORD version;
109
110 if(process == NULL) {
111 dprintf(("GetProcessVersion: can't find process (%d)", Processid));
112 return 0;
113 }
114 image = Win32ImageBase::findModule(process->hInstance);
115 if(image) {
116 version = image->getVersion();
117 dprintf(("GetProcessVersion of %x = %x", Processid, version));
118 return version;
119 }
120 dprintf(("GetProcessVersion: can't find module %x (%d)", process->hInstance, Processid));
121 return 0;
122}
123/***********************************************************************
124 * SetProcessAffinityMask (KERNEL32.662)
125 */
126BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask )
127{
128 dprintf(("SetProcessAffinityMask %x %x", hProcess, affmask));
129 ProcessAffinityMask = affmask;
130 //TODO: should update all threads, but that doesn't seem possible in OS/2
131 SetThreadAffinityMask(GetCurrentThread(), ProcessAffinityMask);
132 return TRUE;
133}
134//******************************************************************************
135//******************************************************************************
136BOOL WIN32API GetProcessAffinityMask(HANDLE hProcess,
137 LPDWORD lpProcessAffinityMask,
138 LPDWORD lpSystemAffinityMask)
139{
140 dprintf(("GetProcessAffinityMask %x %x %x", hProcess, lpProcessAffinityMask, lpSystemAffinityMask));
141
142 /* It is definitely important for a process to know on what processor
143 it is running :-) */
144 if(lpProcessAffinityMask)
145 *lpProcessAffinityMask=ProcessAffinityMask;
146
147 if(lpSystemAffinityMask) {
148 OSLibDosQueryAffinity(MASK_SYSTEM, lpSystemAffinityMask);
149 }
150 return TRUE;
151}
152/***********************************************************************
153 * GetProcessHeaps [KERNEL32.376]
154 */
155DWORD WINAPI GetProcessHeaps(DWORD nrofheaps,HANDLE *heaps)
156{
157 dprintf(("GetProcessHeaps: (%ld,%p), incomplete implementation.\n",nrofheaps,heaps));
158
159 if (nrofheaps) {
160 heaps[0] = GetProcessHeap();
161 /* ... probably SystemHeap too ? */
162 return 1;
163 }
164 /* number of available heaps */
165 return 1;
166}
167/***********************************************************************
168 * RegisterServiceProcess (KERNEL, KERNEL32)
169 *
170 * A service process calls this function to ensure that it continues to run
171 * even after a user logged off.
172 */
173DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
174{
175 dprintf(("RegisterServiceProcess %x %x", dwProcessId, dwType));
176 /* I don't think that Wine needs to do anything in that function */
177 return 1; /* success */
178}
179/***********************************************************************
180 * Name : BOOL SetProcessShutdownParameters
181 * Purpose : The SetProcessShutdownParameters function sets shutdown parameters
182 * for the currently calling process. This function sets a shutdown
183 * order for a process relative to the other processes in the system.
184 * Parameters: DWORD dwLevel shutdown priority
185 * DWORD dwFlags shutdown flags
186 * Variables :
187 * Result : TRUE / FALSE
188 * Remark :
189 *
190 * SetProcessShutdownParameters (KERNEL32)
191 *
192 * CHANGED - James Sutherland (JamesSutherland@gmx.de)
193 * Now tracks changes made (but does not act on these changes)
194 * NOTE: the definition for SHUTDOWN_NORETRY was done on guesswork.
195 * It really shouldn't be here, but I'll move it when it's been checked!
196 */
197BOOL WINAPI SetProcessShutdownParameters(DWORD level,DWORD flags)
198{
199 if (flags & SHUTDOWN_NORETRY)
200 shutdown_noretry = 1;
201 else
202 shutdown_noretry = 0;
203 if (level > 0x100L && level < 0x3FFL)
204 shutdown_priority = level;
205 else
206 {
207 dprintf(("SetProcessShutdownParameters: invalid priority level 0x%08lx\n", level));
208 return FALSE;
209 }
210 return TRUE;
211}
212/***********************************************************************
213 * GetProcessShutdownParameters (KERNEL32)
214 * Name : BOOL GetProcessShutdownParameters
215 * Purpose : The GetProcessShutdownParameters function retrieves shutdown
216 * parameters for the currently calling process.
217 * Parameters: LPDWORD lpdwLevel
218 * LPDWORD lpdwFlags
219 * Variables :
220 * Result : TRUE / FALSE
221 * Remark :
222 *
223 */
224BOOL WINAPI GetProcessShutdownParameters( LPDWORD lpdwLevel,
225 LPDWORD lpdwFlags )
226{
227 dprintf(("GetProcessShutdownParameters"));
228 (*lpdwLevel) = shutdown_priority;
229 (*lpdwFlags) = (shutdown_noretry * SHUTDOWN_NORETRY);
230 return TRUE;
231}
232/***********************************************************************
233 * SetProcessPriorityBoost (KERNEL32)
234 */
235BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost)
236{
237 dprintf(("SetProcessPriorityBoost: (%d,%d): stub\n",hprocess,disableboost));
238 /* Say we can do it. I doubt the program will notice that we don't. */
239 return TRUE;
240}
241/***********************************************************************
242 * SetProcessWorkingSetSize [KERNEL32.662]
243 * Sets the min/max working set sizes for a specified process.
244 *
245 * PARAMS
246 * hProcess [I] Handle to the process of interest
247 * minset [I] Specifies minimum working set size
248 * maxset [I] Specifies maximum working set size
249 *
250 * RETURNS STD
251 */
252BOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess,DWORD minset,
253 DWORD maxset)
254{
255 dprintf(("SetProcessWorkingSetSize (0x%08x,%ld,%ld): stub - harmless\n",hProcess,minset,maxset));
256 if(( minset == -1) && (maxset == -1)) {
257 /* Trim the working set to zero */
258 /* Swap the process out of physical RAM */
259 }
260 return TRUE;
261}
262
263/***********************************************************************
264 * GetProcessFlags (KERNEL32)
265 */
266DWORD WINAPI GetProcessFlags( DWORD processid )
267{
268// PDB *pdb = PROCESS_IdToPDB( processid );
269// if (!pdb) return 0;
270// return pdb->flags;
271 dprintf(("STUB: GetProcessFlags %x", processid));
272 return 0;
273}
274
275/***********************************************************************
276 * GetProcessWorkingSetSize (KERNEL32)
277 * Name : BOOL SetProcessWorkingSetSize
278 * Purpose : The SetProcessWorkingSetSize function sets the minimum and
279 * maximum working set sizes for a specified process.
280 * The working set of a process is the set of memory pages currently
281 * visible to the process in physical RAM memory. These pages are
282 * resident and available for an application to use without triggering
283 * a page fault. The size of the working set of a process is specified
284 * in bytes. The minimum and maximum working set sizes affect the
285 * virtual memory paging behavior of a process.
286 * Parameters: HANDLE hProcess open handle to the process of interest
287 * DWORD dwMinimumWorkingSetSize specifies minimum working set size
288 * DWORD dwMaximumWorkingSetSize specifies maximum working set size
289 * Variables :
290 * Result : TRUE / FALSE
291 */
292BOOL WINAPI GetProcessWorkingSetSize(HANDLE hProcess,LPDWORD minset,
293 LPDWORD maxset)
294{
295 dprintf(("GetProcessWorkingSetSize 0x%08x,%p,%p): stub\n",hProcess,minset,maxset));
296 /* 32 MB working set size */
297 if (minset) *minset = 32*1024*1024;
298 if (maxset) *maxset = 32*1024*1024;
299 return TRUE;
300}
301/***********************************************************************
302 * GetProcessDword (KERNEL32.18) (KERNEL.485)
303 * 'Of course you cannot directly access Windows internal structures'
304 */
305DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
306{
307 PDB *process = PROCESS_IdToPDB( dwProcessID );
308 TDB *pTask;
309 DWORD x, y;
310
311 dprintf(("GetProcessDword: (%ld, %d)\n", dwProcessID, offset ));
312 if ( !process ) return 0;
313
314 switch ( offset )
315 {
316 case GPD_APP_COMPAT_FLAGS:
317 pTask = (TDB *)GlobalLock( process->task );
318 return pTask? pTask->compat_flags : 0;
319
320 case GPD_LOAD_DONE_EVENT:
321 return process->load_done_evt;
322
323 case GPD_HINSTANCE16:
324 pTask = (TDB *)GlobalLock( process->task );
325 return pTask? pTask->hInstance : 0;
326
327 case GPD_WINDOWS_VERSION:
328 pTask = (TDB *)GlobalLock( process->task );
329 return pTask? pTask->version : 0;
330
331 case GPD_THDB:
332 if ( process != PROCESS_Current() ) return 0;
333 return (DWORD)GetThreadTEB() + 0x30;
334
335 case GPD_PDB:
336 return (DWORD)process;
337
338 case GPD_STARTF_SHELLDATA: /* return stdoutput handle from startupinfo ??? */
339 return process->env_db->startup_info->hStdOutput;
340
341 case GPD_STARTF_HOTKEY: /* return stdinput handle from startupinfo ??? */
342 return process->env_db->startup_info->hStdInput;
343
344 case GPD_STARTF_SHOWWINDOW:
345 return process->env_db->startup_info->wShowWindow;
346
347 case GPD_STARTF_SIZE:
348 x = process->env_db->startup_info->dwXSize;
349 if ( x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
350 y = process->env_db->startup_info->dwYSize;
351 if ( y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
352 return MAKELONG( x, y );
353
354 case GPD_STARTF_POSITION:
355 x = process->env_db->startup_info->dwX;
356 if ( x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
357 y = process->env_db->startup_info->dwY;
358 if ( y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
359 return MAKELONG( x, y );
360
361 case GPD_STARTF_FLAGS:
362 return process->env_db->startup_info->dwFlags;
363
364 case GPD_PARENT:
365 if(process->parent)
366 return (DWORD)process->parent->server_pid;
367 return 0;
368
369 case GPD_FLAGS:
370 return process->flags;
371
372 case GPD_USERDATA:
373 return process->process_dword;
374
375 default:
376 dprintf(("GetProcessDword: Unknown offset %d\n", offset ));
377 return 0;
378 }
379}
380
381
382/***********************************************************************
383 * ODIN_SetProcessDword
384 *
385 * SvL: Special version that allows the caller to change some values
386 *
387 */
388void WINAPI ODIN_SetProcessDword( DWORD dwProcessID, INT offset, DWORD value )
389{
390 PDB *process = PROCESS_IdToPDB( dwProcessID );
391
392 dprintf(("SetProcessDword: (%ld, %d)\n", dwProcessID, offset));
393 if ( !process ) return;
394
395 switch ( offset )
396 {
397 case GPD_STARTF_SHOWWINDOW:
398 process->env_db->startup_info->wShowWindow = value;
399 break;
400
401 case GPD_STARTF_SIZE:
402 process->env_db->startup_info->dwXSize = LOWORD(value);
403 process->env_db->startup_info->dwYSize = HIWORD(value);
404 break;
405
406 case GPD_STARTF_POSITION:
407 process->env_db->startup_info->dwX = LOWORD(value);
408 process->env_db->startup_info->dwY = HIWORD(value);
409 break;
410
411 default:
412 dprintf(("SetProcessDword: Unknown offset %d\n", offset));
413 break;
414 }
415}
416
417/***********************************************************************
418 * SetProcessDword (KERNEL.484)
419 * 'Of course you cannot directly access Windows internal structures'
420 */
421void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value )
422{
423 PDB *process = PROCESS_IdToPDB( dwProcessID );
424
425 dprintf(("SetProcessDword: (%ld, %d)\n", dwProcessID, offset));
426 if ( !process ) return;
427
428 switch ( offset )
429 {
430 case GPD_APP_COMPAT_FLAGS:
431 case GPD_LOAD_DONE_EVENT:
432 case GPD_HINSTANCE16:
433 case GPD_WINDOWS_VERSION:
434 case GPD_THDB:
435 case GPD_PDB:
436 case GPD_STARTF_SHELLDATA:
437 case GPD_STARTF_HOTKEY:
438 case GPD_STARTF_SHOWWINDOW:
439 case GPD_STARTF_SIZE:
440 case GPD_STARTF_POSITION:
441 case GPD_STARTF_FLAGS:
442 case GPD_PARENT:
443 case GPD_FLAGS:
444 dprintf(("SetProcessDword: Not allowed to modify offset %d\n", offset ));
445 break;
446
447 case GPD_USERDATA:
448 process->process_dword = value;
449 break;
450
451 default:
452 dprintf(("SetProcessDword: Unknown offset %d\n", offset));
453 break;
454 }
455}
456/*****************************************************************************
457 * Name : BOOL GetProcessTimes
458 * Purpose : The GetProcessTimes function obtains timing information about a specified process.
459 * Parameters: HANDLE hProcess specifies the process of interest
460 * LPFILETIME lpCreationTime when the process was created
461 * LPFILETIME lpExitTime when the process exited
462 * LPFILETIME lpKernelTime time the process has spent in kernel mode
463 * LPFILETIME lpUserTime time the process has spent in user mode
464 * Variables :
465 * Result : TRUE / FALSE
466 * Remark :
467 * Status : UNTESTED STUB
468 *
469 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
470 *****************************************************************************/
471
472ULONG (WINAPI *NtdllRtlExtendedIntegerMultiply)(LARGE_INTEGER factor1,
473 INT factor2) = 0;
474
475BOOL WIN32API GetProcessTimes(HANDLE hProcess,
476 LPFILETIME lpCreationTime,
477 LPFILETIME lpExitTime,
478 LPFILETIME lpKernelTime,
479 LPFILETIME lpUserTime)
480{
481 LARGE_INTEGER *kerneltime, *usertime;
482
483 dprintf(("Kernel32: GetProcessTimes(%08xh,%08xh,%08xh,%08xh,%08xh) partly implemented",
484 hProcess,
485 lpCreationTime,
486 lpExitTime,
487 lpKernelTime,
488 lpUserTime));
489
490 if(!NtdllRtlExtendedIntegerMultiply) {
491 HINSTANCE hInstance = LoadLibraryA("NTDLL.DLL");
492 if(hInstance)
493 *(VOID **)&NtdllRtlExtendedIntegerMultiply=(void*)GetProcAddress(hInstance, (LPCSTR)"RtlExtendedIntegerMultiply");
494 }
495 if(!lpCreationTime || !lpExitTime || !lpKernelTime || !lpUserTime) {
496 SetLastError(ERROR_INVALID_PARAMETER);
497 return FALSE;
498 }
499 if(hProcess != GetCurrentProcess()) {
500 dprintf(("GetProcessTimes unknown process"));
501 return FALSE;
502 }
503
504 SystemTimeToFileTime(&ProcessPDB.creationTime, lpCreationTime);
505 memset(lpExitTime, 0, sizeof(FILETIME));
506 memset(lpKernelTime, 0, sizeof(FILETIME));
507 memset(lpUserTime, 0, sizeof(FILETIME));
508
509 kerneltime = (LARGE_INTEGER *)lpKernelTime;
510 usertime = (LARGE_INTEGER *)lpUserTime;
511 OSLibDosQueryProcTimes(GetCurrentProcessId(), &lpKernelTime->dwLowDateTime, &lpUserTime->dwLowDateTime);
512 //TODO: Isn't correct -> (if result's high dword != 0)
513 kerneltime->LowPart = NtdllRtlExtendedIntegerMultiply(*kerneltime, 10);
514 usertime->LowPart = NtdllRtlExtendedIntegerMultiply(*usertime, 10);
515 return TRUE;
516}
517//******************************************************************************
518//******************************************************************************
519
520} // extern "C"
521
Note: See TracBrowser for help on using the repository browser.