Fixed header dependencies to be fully compatible with the Windows
[wine] / dlls / kernel / process.c
1 /*
2  * Win32 processes
3  *
4  * Copyright 1996, 1998 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include "wine/winbase16.h"
25 #include "wine/winuser16.h"
26 #include "ntstatus.h"
27 #include "thread.h"
28 #include "wine/server.h"
29 #include "wine/debug.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(process);
32
33 /* Process flags */
34 #define PDB32_DEBUGGED      0x0001  /* Process is being debugged */
35 #define PDB32_WIN16_PROC    0x0008  /* Win16 process */
36 #define PDB32_DOS_PROC      0x0010  /* Dos process */
37 #define PDB32_CONSOLE_PROC  0x0020  /* Console process */
38 #define PDB32_FILE_APIS_OEM 0x0040  /* File APIs are OEM */
39 #define PDB32_WIN32S_PROC   0x8000  /* Win32s process */
40
41
42 static DWORD shutdown_flags = 0;
43 static DWORD shutdown_priority = 0x280;
44 static DWORD process_dword;
45 static BOOL oem_file_apis;
46
47
48 /***********************************************************************
49  *           GetProcessFlags    (KERNEL32.@)
50  */
51 DWORD WINAPI GetProcessFlags( DWORD processid )
52 {
53     IMAGE_NT_HEADERS *nt;
54     DWORD flags = 0;
55
56     if (processid && processid != GetCurrentProcessId()) return 0;
57
58     if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
59     {
60         if (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
61             flags |= PDB32_CONSOLE_PROC;
62     }
63     if (!AreFileApisANSI()) flags |= PDB32_FILE_APIS_OEM;
64     if (IsDebuggerPresent()) flags |= PDB32_DEBUGGED;
65     return flags;
66 }
67
68
69 /***********************************************************************
70  *           GetProcessDword    (KERNEL.485)
71  *           GetProcessDword    (KERNEL32.18)
72  * 'Of course you cannot directly access Windows internal structures'
73  */
74 DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
75 {
76     DWORD               x, y;
77     STARTUPINFOW        siw;
78
79     TRACE("(%ld, %d)\n", dwProcessID, offset );
80
81     if (dwProcessID && dwProcessID != GetCurrentProcessId())
82     {
83         ERR("%d: process %lx not accessible\n", offset, dwProcessID);
84         return 0;
85     }
86
87     switch ( offset )
88     {
89     case GPD_APP_COMPAT_FLAGS:
90         return GetAppCompatFlags16(0);
91     case GPD_LOAD_DONE_EVENT:
92         return 0;
93     case GPD_HINSTANCE16:
94         return GetTaskDS16();
95     case GPD_WINDOWS_VERSION:
96         return GetExeVersion16();
97     case GPD_THDB:
98         return (DWORD)NtCurrentTeb() - 0x10 /* FIXME */;
99     case GPD_PDB:
100         return (DWORD)NtCurrentTeb()->Peb;
101     case GPD_STARTF_SHELLDATA: /* return stdoutput handle from startupinfo ??? */
102         GetStartupInfoW(&siw);
103         return (DWORD)siw.hStdOutput;
104     case GPD_STARTF_HOTKEY: /* return stdinput handle from startupinfo ??? */
105         GetStartupInfoW(&siw);
106         return (DWORD)siw.hStdInput;
107     case GPD_STARTF_SHOWWINDOW:
108         GetStartupInfoW(&siw);
109         return siw.wShowWindow;
110     case GPD_STARTF_SIZE:
111         GetStartupInfoW(&siw);
112         x = siw.dwXSize;
113         if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
114         y = siw.dwYSize;
115         if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
116         return MAKELONG( x, y );
117     case GPD_STARTF_POSITION:
118         GetStartupInfoW(&siw);
119         x = siw.dwX;
120         if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
121         y = siw.dwY;
122         if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
123         return MAKELONG( x, y );
124     case GPD_STARTF_FLAGS:
125         GetStartupInfoW(&siw);
126         return siw.dwFlags;
127     case GPD_PARENT:
128         return 0;
129     case GPD_FLAGS:
130         return GetProcessFlags(0);
131     case GPD_USERDATA:
132         return process_dword;
133     default:
134         ERR("Unknown offset %d\n", offset );
135         return 0;
136     }
137 }
138
139 /***********************************************************************
140  *           SetProcessDword    (KERNEL.484)
141  * 'Of course you cannot directly access Windows internal structures'
142  */
143 void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value )
144 {
145     TRACE("(%ld, %d)\n", dwProcessID, offset );
146
147     if (dwProcessID && dwProcessID != GetCurrentProcessId())
148     {
149         ERR("%d: process %lx not accessible\n", offset, dwProcessID);
150         return;
151     }
152
153     switch ( offset )
154     {
155     case GPD_APP_COMPAT_FLAGS:
156     case GPD_LOAD_DONE_EVENT:
157     case GPD_HINSTANCE16:
158     case GPD_WINDOWS_VERSION:
159     case GPD_THDB:
160     case GPD_PDB:
161     case GPD_STARTF_SHELLDATA:
162     case GPD_STARTF_HOTKEY:
163     case GPD_STARTF_SHOWWINDOW:
164     case GPD_STARTF_SIZE:
165     case GPD_STARTF_POSITION:
166     case GPD_STARTF_FLAGS:
167     case GPD_PARENT:
168     case GPD_FLAGS:
169         ERR("Not allowed to modify offset %d\n", offset );
170         break;
171     case GPD_USERDATA:
172         process_dword = value;
173         break;
174     default:
175         ERR("Unknown offset %d\n", offset );
176         break;
177     }
178 }
179
180
181 /***********************************************************************
182  *           ExitProcess   (KERNEL.466)
183  */
184 void WINAPI ExitProcess16( WORD status )
185 {
186     DWORD count;
187     ReleaseThunkLock( &count );
188     ExitProcess( status );
189 }
190
191
192 /*********************************************************************
193  *           OpenProcess   (KERNEL32.@)
194  */
195 HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
196 {
197     HANDLE ret = 0;
198     SERVER_START_REQ( open_process )
199     {
200         req->pid     = id;
201         req->access  = access;
202         req->inherit = inherit;
203         if (!wine_server_call_err( req )) ret = reply->handle;
204     }
205     SERVER_END_REQ;
206     return ret;
207 }
208
209
210 /*********************************************************************
211  *           MapProcessHandle   (KERNEL.483)
212  */
213 DWORD WINAPI MapProcessHandle( HANDLE handle )
214 {
215     DWORD ret = 0;
216     SERVER_START_REQ( get_process_info )
217     {
218         req->handle = handle;
219         if (!wine_server_call_err( req )) ret = reply->pid;
220     }
221     SERVER_END_REQ;
222     return ret;
223 }
224
225
226 /***********************************************************************
227  *           SetPriorityClass   (KERNEL32.@)
228  */
229 BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
230 {
231     BOOL ret;
232     SERVER_START_REQ( set_process_info )
233     {
234         req->handle   = hprocess;
235         req->priority = priorityclass;
236         req->mask     = SET_PROCESS_INFO_PRIORITY;
237         ret = !wine_server_call_err( req );
238     }
239     SERVER_END_REQ;
240     return ret;
241 }
242
243
244 /***********************************************************************
245  *           GetPriorityClass   (KERNEL32.@)
246  */
247 DWORD WINAPI GetPriorityClass(HANDLE hprocess)
248 {
249     DWORD ret = 0;
250     SERVER_START_REQ( get_process_info )
251     {
252         req->handle = hprocess;
253         if (!wine_server_call_err( req )) ret = reply->priority;
254     }
255     SERVER_END_REQ;
256     return ret;
257 }
258
259
260 /***********************************************************************
261  *          SetProcessAffinityMask   (KERNEL32.@)
262  */
263 BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask )
264 {
265     BOOL ret;
266     SERVER_START_REQ( set_process_info )
267     {
268         req->handle   = hProcess;
269         req->affinity = affmask;
270         req->mask     = SET_PROCESS_INFO_AFFINITY;
271         ret = !wine_server_call_err( req );
272     }
273     SERVER_END_REQ;
274     return ret;
275 }
276
277
278 /**********************************************************************
279  *          GetProcessAffinityMask    (KERNEL32.@)
280  */
281 BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess,
282                                       LPDWORD lpProcessAffinityMask,
283                                       LPDWORD lpSystemAffinityMask )
284 {
285     BOOL ret = FALSE;
286     SERVER_START_REQ( get_process_info )
287     {
288         req->handle = hProcess;
289         if (!wine_server_call_err( req ))
290         {
291             if (lpProcessAffinityMask) *lpProcessAffinityMask = reply->process_affinity;
292             if (lpSystemAffinityMask) *lpSystemAffinityMask = reply->system_affinity;
293             ret = TRUE;
294         }
295     }
296     SERVER_END_REQ;
297     return ret;
298 }
299
300
301 /***********************************************************************
302  *           GetProcessVersion    (KERNEL32.@)
303  */
304 DWORD WINAPI GetProcessVersion( DWORD processid )
305 {
306     IMAGE_NT_HEADERS *nt;
307
308     if (processid && processid != GetCurrentProcessId())
309     {
310         FIXME("should use ReadProcessMemory\n");
311         return 0;
312     }
313     if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
314         return ((nt->OptionalHeader.MajorSubsystemVersion << 16) |
315                 nt->OptionalHeader.MinorSubsystemVersion);
316     return 0;
317 }
318
319
320 /***********************************************************************
321  *              SetProcessWorkingSetSize        [KERNEL32.@]
322  * Sets the min/max working set sizes for a specified process.
323  *
324  * PARAMS
325  *    hProcess [I] Handle to the process of interest
326  *    minset   [I] Specifies minimum working set size
327  *    maxset   [I] Specifies maximum working set size
328  *
329  * RETURNS  STD
330  */
331 BOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess, SIZE_T minset,
332                                      SIZE_T maxset)
333 {
334     FIXME("(%p,%ld,%ld): stub - harmless\n",hProcess,minset,maxset);
335     if(( minset == (SIZE_T)-1) && (maxset == (SIZE_T)-1)) {
336         /* Trim the working set to zero */
337         /* Swap the process out of physical RAM */
338     }
339     return TRUE;
340 }
341
342 /***********************************************************************
343  *           GetProcessWorkingSetSize    (KERNEL32.@)
344  */
345 BOOL WINAPI GetProcessWorkingSetSize(HANDLE hProcess, PSIZE_T minset,
346                                      PSIZE_T maxset)
347 {
348     FIXME("(%p,%p,%p): stub\n",hProcess,minset,maxset);
349     /* 32 MB working set size */
350     if (minset) *minset = 32*1024*1024;
351     if (maxset) *maxset = 32*1024*1024;
352     return TRUE;
353 }
354
355
356 /***********************************************************************
357  *           SetProcessShutdownParameters    (KERNEL32.@)
358  */
359 BOOL WINAPI SetProcessShutdownParameters(DWORD level, DWORD flags)
360 {
361     FIXME("(%08lx, %08lx): partial stub.\n", level, flags);
362     shutdown_flags = flags;
363     shutdown_priority = level;
364     return TRUE;
365 }
366
367
368 /***********************************************************************
369  * GetProcessShutdownParameters                 (KERNEL32.@)
370  *
371  */
372 BOOL WINAPI GetProcessShutdownParameters( LPDWORD lpdwLevel, LPDWORD lpdwFlags )
373 {
374     *lpdwLevel = shutdown_priority;
375     *lpdwFlags = shutdown_flags;
376     return TRUE;
377 }
378
379
380 /***********************************************************************
381  *           GetProcessPriorityBoost    (KERNEL32.@)
382  */
383 BOOL WINAPI GetProcessPriorityBoost(HANDLE hprocess,PBOOL pDisablePriorityBoost)
384 {
385     FIXME("(%p,%p): semi-stub\n", hprocess, pDisablePriorityBoost);
386     
387     /* Report that no boost is present.. */
388     *pDisablePriorityBoost = FALSE;
389     
390     return TRUE;
391 }
392
393 /***********************************************************************
394  *           SetProcessPriorityBoost    (KERNEL32.@)
395  */
396 BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost)
397 {
398     FIXME("(%p,%d): stub\n",hprocess,disableboost);
399     /* Say we can do it. I doubt the program will notice that we don't. */
400     return TRUE;
401 }
402
403
404 /***********************************************************************
405  *              ReadProcessMemory (KERNEL32.@)
406  */
407 BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, SIZE_T size,
408                                SIZE_T *bytes_read )
409 {
410     NTSTATUS status = NtReadVirtualMemory( process, addr, buffer, size, bytes_read );
411     if (status) SetLastError( RtlNtStatusToDosError(status) );
412     return !status;
413 }
414
415
416 /***********************************************************************
417  *           WriteProcessMemory                 (KERNEL32.@)
418  */
419 BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPCVOID buffer, SIZE_T size,
420                                 SIZE_T *bytes_written )
421 {
422     NTSTATUS status = NtWriteVirtualMemory( process, addr, buffer, size, bytes_written );
423     if (status) SetLastError( RtlNtStatusToDosError(status) );
424     return !status;
425 }
426
427
428 /***********************************************************************
429  *              RegisterServiceProcess (KERNEL.491)
430  *              RegisterServiceProcess (KERNEL32.@)
431  *
432  * A service process calls this function to ensure that it continues to run
433  * even after a user logged off.
434  */
435 DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
436 {
437     /* I don't think that Wine needs to do anything in that function */
438     return 1; /* success */
439 }
440
441
442 /**************************************************************************
443  *              SetFileApisToOEM   (KERNEL32.@)
444  */
445 VOID WINAPI SetFileApisToOEM(void)
446 {
447     oem_file_apis = TRUE;
448 }
449
450
451 /**************************************************************************
452  *              SetFileApisToANSI   (KERNEL32.@)
453  */
454 VOID WINAPI SetFileApisToANSI(void)
455 {
456     oem_file_apis = FALSE;
457 }
458
459
460 /******************************************************************************
461  * AreFileApisANSI [KERNEL32.@]  Determines if file functions are using ANSI
462  *
463  * RETURNS
464  *    TRUE:  Set of file functions is using ANSI code page
465  *    FALSE: Set of file functions is using OEM code page
466  */
467 BOOL WINAPI AreFileApisANSI(void)
468 {
469     return !oem_file_apis;
470 }
471
472
473 /***********************************************************************
474  *           GetCurrentProcess   (KERNEL32.@)
475  */
476 #undef GetCurrentProcess
477 HANDLE WINAPI GetCurrentProcess(void)
478 {
479     return (HANDLE)0xffffffff;
480 }