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

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

Implemented Get/SetProcessAffinityMask & SetThreadAffinityMask

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