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

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

Added new logging feature

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