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

Last change on this file since 7744 was 7744, checked in by sandervl, 24 years ago

DosSet/QueryAffinity fixes for non-SMP systems

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