Sort entry points alphabetically.
[wine] / dlls / ntdll / process.c
1 /*
2  * NT basis DLL
3  *
4  * This file contains the Nt* API functions of NTDLL.DLL.
5  * In the original ntdll.dll they all seem to just call int 0x2e (down to the NTOSKRNL)
6  *
7  * Copyright 1996-1998 Marcus Meissner
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include "wine/debug.h"
30
31 #include "windef.h"
32 #include "winternl.h"
33 #include "ntdll_misc.h"
34 #include "wine/server.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
37
38 /*
39  *      Process object
40  */
41
42 /******************************************************************************
43  *  NtTerminateProcess                  [NTDLL.@]
44  *
45  *  Native applications must kill themselves when done
46  */
47 NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
48 {
49     NTSTATUS ret;
50     BOOL self;
51     SERVER_START_REQ( terminate_process )
52     {
53         req->handle    = handle;
54         req->exit_code = exit_code;
55         ret = wine_server_call( req );
56         self = !ret && reply->self;
57     }
58     SERVER_END_REQ;
59     if (self) exit( exit_code );
60     return ret;
61 }
62
63 /******************************************************************************
64 *  NtQueryInformationProcess            [NTDLL.@]
65 *  ZwQueryInformationProcess            [NTDLL.@]
66 *
67 */
68 NTSTATUS WINAPI NtQueryInformationProcess(
69         IN HANDLE ProcessHandle,
70         IN PROCESSINFOCLASS ProcessInformationClass,
71         OUT PVOID ProcessInformation,
72         IN ULONG ProcessInformationLength,
73         OUT PULONG ReturnLength)
74 {
75     NTSTATUS ret = STATUS_SUCCESS;
76     ULONG len = 0;
77
78     TRACE("(%p,0x%08x,%p,0x%08lx,%p)\n",
79           ProcessHandle,ProcessInformationClass,
80           ProcessInformation,ProcessInformationLength,
81           ReturnLength);
82
83     switch (ProcessInformationClass) 
84     {
85     case ProcessBasicInformation:
86         {
87             PROCESS_BASIC_INFORMATION pbi;
88
89             if (ProcessInformationLength >= sizeof(PROCESS_BASIC_INFORMATION))
90             {
91                 if (!ProcessInformation)
92                     ret = STATUS_ACCESS_VIOLATION;
93                 else if (!ProcessHandle)
94                     ret = STATUS_INVALID_HANDLE;
95                 else
96                 {
97                     SERVER_START_REQ(get_process_info)
98                     {
99                         req->handle = ProcessHandle;
100                         if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
101                         {
102                             pbi.ExitStatus = reply->exit_code;
103                             pbi.PebBaseAddress = (DWORD)reply->peb;
104                             pbi.AffinityMask = reply->process_affinity;
105                             pbi.BasePriority = reply->priority;
106                             pbi.UniqueProcessId = reply->pid;
107                             pbi.InheritedFromUniqueProcessId = reply->ppid;
108                         }
109                     }
110                     SERVER_END_REQ;
111
112                     memcpy(ProcessInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION));
113
114                     len = sizeof(PROCESS_BASIC_INFORMATION);
115                 }
116
117                 if (ProcessInformationLength > sizeof(PROCESS_BASIC_INFORMATION))
118                     ret = STATUS_INFO_LENGTH_MISMATCH;
119             }
120             else ret = STATUS_INFO_LENGTH_MISMATCH;
121         }
122         break;
123     case ProcessIoCounters:
124         {
125             IO_COUNTERS pii;
126
127             if (ProcessInformationLength >= sizeof(IO_COUNTERS))
128             {
129                 if (!ProcessInformation)
130                     ret = STATUS_ACCESS_VIOLATION;
131                 else if (!ProcessHandle)
132                     ret = STATUS_INVALID_HANDLE;
133                 else
134                 {
135                     /* FIXME : real data */
136                     memset(&pii, 0 , sizeof(IO_COUNTERS));
137
138                     memcpy(ProcessInformation, &pii, sizeof(IO_COUNTERS));
139
140                     len = sizeof(IO_COUNTERS);
141                 }
142
143                 if (ProcessInformationLength > sizeof(IO_COUNTERS))
144                     ret = STATUS_INFO_LENGTH_MISMATCH;
145             }
146             else ret = STATUS_INFO_LENGTH_MISMATCH;
147         }
148         break;
149     case ProcessVmCounters:
150         {
151             VM_COUNTERS pvmi;
152
153             if (ProcessInformationLength >= sizeof(VM_COUNTERS))
154             {
155                 if (!ProcessInformation)
156                     ret = STATUS_ACCESS_VIOLATION;
157                 else if (!ProcessHandle)
158                     ret = STATUS_INVALID_HANDLE;
159                 else
160                 {
161                     /* FIXME : real data */
162                     memset(&pvmi, 0 , sizeof(VM_COUNTERS));
163
164                     memcpy(ProcessInformation, &pvmi, sizeof(VM_COUNTERS));
165
166                     len = sizeof(VM_COUNTERS);
167                 }
168
169                 if (ProcessInformationLength > sizeof(VM_COUNTERS))
170                     ret = STATUS_INFO_LENGTH_MISMATCH;
171             }
172             else ret = STATUS_INFO_LENGTH_MISMATCH;
173         }
174         break;
175     case ProcessTimes:
176         {
177             KERNEL_USER_TIMES pti;
178
179             if (ProcessInformationLength >= sizeof(KERNEL_USER_TIMES))
180             {
181                 if (!ProcessInformation)
182                     ret = STATUS_ACCESS_VIOLATION;
183                 else if (!ProcessHandle)
184                     ret = STATUS_INVALID_HANDLE;
185                 else
186                 {
187                     /* FIXME : real data */
188                     memset(&pti, 0, sizeof(KERNEL_USER_TIMES));
189
190                     memcpy(ProcessInformation, &pti, sizeof(KERNEL_USER_TIMES));
191
192                     len = sizeof(KERNEL_USER_TIMES);
193                 }
194
195                 if (ProcessInformationLength > sizeof(KERNEL_USER_TIMES))
196                     ret = STATUS_INFO_LENGTH_MISMATCH;
197             }
198             else ret = STATUS_INFO_LENGTH_MISMATCH;
199         }
200         break;
201     case ProcessDebugPort:
202         /* "These are not the debuggers you are looking for." *
203          * set it to 0 aka "no debugger" to satisfy copy protections */
204         if (ProcessInformationLength == 4)
205         {
206             memset(ProcessInformation, 0, ProcessInformationLength);
207             len = 4;
208         }
209         else ret = STATUS_INFO_LENGTH_MISMATCH;
210         break;
211     case ProcessHandleCount:
212         if (ProcessInformationLength >= 4)
213         {
214             if (!ProcessInformation)
215                 ret = STATUS_ACCESS_VIOLATION;
216             else if (!ProcessHandle)
217                 ret = STATUS_INVALID_HANDLE;
218             else
219             {
220                 memset(ProcessInformation, 0, 4);
221
222
223                 len = 4;
224             }
225
226             if (ProcessInformationLength > 4)
227                 ret = STATUS_INFO_LENGTH_MISMATCH;
228          }
229          else ret = STATUS_INFO_LENGTH_MISMATCH;
230          break;
231     case ProcessWow64Information:
232         if (ProcessInformationLength == 4)
233         {
234             memset(ProcessInformation, 0, ProcessInformationLength);
235             len = 4;
236         }
237         else ret = STATUS_INFO_LENGTH_MISMATCH;
238         break;
239     default:
240         FIXME("(%p,0x%08x,%p,0x%08lx,%p),stub!\n",
241               ProcessHandle,ProcessInformationClass,
242               ProcessInformation,ProcessInformationLength,
243               ReturnLength);
244         ret = STATUS_INVALID_INFO_CLASS;
245         break;
246     }
247
248     if (ReturnLength) *ReturnLength = len;
249     
250     return ret;
251 }
252
253 /******************************************************************************
254  * NtSetInformationProcess [NTDLL.@]
255  * ZwSetInformationProcess [NTDLL.@]
256  */
257 NTSTATUS WINAPI NtSetInformationProcess(
258         IN HANDLE ProcessHandle,
259         IN PROCESSINFOCLASS ProcessInformationClass,
260         IN PVOID ProcessInformation,
261         IN ULONG ProcessInformationLength)
262 {
263     FIXME("(%p,0x%08x,%p,0x%08lx) stub\n",
264           ProcessHandle,ProcessInformationClass,ProcessInformation,ProcessInformationLength);
265     return 0;
266 }
267
268 /******************************************************************************
269  * NtFlushInstructionCache [NTDLL.@]
270  * ZwFlushInstructionCache [NTDLL.@]
271  */
272 NTSTATUS WINAPI NtFlushInstructionCache(
273         IN HANDLE ProcessHandle,
274         IN LPCVOID BaseAddress,
275         IN ULONG Size)
276 {
277 #ifdef __i386__
278     TRACE("%p %p %ld - no-op on x86\n", ProcessHandle, BaseAddress, Size );
279 #else
280     FIXME("%p %p %ld\n", ProcessHandle, BaseAddress, Size );
281 #endif
282     return STATUS_SUCCESS;
283 }