ReactOS 0.4.15-dev-7924-g5949c20
usercall.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/ke/arm/usercall.c
5 * PURPOSE: Implements system calls and user-mode callbacks for ARM
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS ********************************************************************/
16
17//
18// System call wrapper generator
19//
20#define BUILD_SYSCALLS \
21SYSCALL(00, ()) \
22SYSCALL(01, (_1)) \
23SYSCALL(02, (_1, _2)) \
24SYSCALL(03, (_1, _2, _3)) \
25SYSCALL(04, (_1, _2, _3, _4 )) \
26SYSCALL(05, (_1, _2, _3, _4, _5)) \
27SYSCALL(06, (_1, _2, _3, _4, _5, _6)) \
28SYSCALL(07, (_1, _2, _3, _4, _5, _6, _7)) \
29SYSCALL(08, (_1, _2, _3, _4, _5, _6, _7, _8)) \
30SYSCALL(09, (_1, _2, _3, _4, _5, _6, _7, _8, _9)) \
31SYSCALL(0A, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a)) \
32SYSCALL(0B, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b)) \
33SYSCALL(0C, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c)) \
34SYSCALL(0D, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d)) \
35SYSCALL(0E, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e)) \
36SYSCALL(0F, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f)) \
37SYSCALL(10, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10)) \
38SYSCALL(11, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10, _11))
39
40//
41// Generate function pointer definitions
42//
43#define PROTO
44#include "ke_i.h"
46
47//
48// Generate function code
49//
50#define FUNC
51#include "ke_i.h"
53
54/* SYSTEM CALL STUBS **********************************************************/
55
58{
59 KiSyscall00Param,
60 KiSyscall01Param,
61 KiSyscall02Param,
62 KiSyscall03Param,
63 KiSyscall04Param,
64 KiSyscall05Param,
65 KiSyscall06Param,
66 KiSyscall07Param,
67 KiSyscall08Param,
68 KiSyscall09Param,
69 KiSyscall0AParam,
70 KiSyscall0BParam,
71 KiSyscall0CParam,
72 KiSyscall0DParam,
73 KiSyscall0EParam,
74 KiSyscall0FParam,
75 KiSyscall10Param,
76 KiSyscall11Param,
77};
78
79/* FUNCIONS *******************************************************************/
80
81VOID
83 IN PKTRAP_FRAME TrapFrame,
85{
86 ULONG Id, Number, ArgumentCount, i;
87 PKPCR Pcr;
89 PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
90 PVOID SystemCall;
91 PVOID* Argument;
92 PVOID Arguments[0x11]; // Maximum 17 arguments
94 ASSERT(TrapFrame->Reserved == 0xBADB0D00);
95
96 //
97 // Increase count of system calls
98 //
99 Pcr = KeGetPcr();
100 Pcr->CurrentPrcb->KeSystemCalls++;
101
102 //
103 // Get the system call ID
104 //
105 Id = Instruction & 0xFFFFF;
106 //DPRINT1("[SWI] (%x) %p (%d) \n", Id, Thread, Thread->PreviousMode);
107
108 //
109 // Get the descriptor table
110 //
111 ServiceTable = (ULONG_PTR)Thread->ServiceTable;
114 DescriptorTable = (PVOID)ServiceTable;
115
116 //
117 // Get the service call number and validate it
118 //
120 if (Number > DescriptorTable->Limit)
121 {
122 //
123 // Check if this is a GUI call
124 //
126 ASSERT(FALSE);
127 }
128
129 //
130 // Save the function responsible for handling this system call
131 //
132 SystemCall = (PVOID)DescriptorTable->Base[Number];
133
134 //
135 // Check if this is a GUI call
136 //
138 {
139 //
140 // TODO
141 //
143 ASSERT(FALSE);
144 }
145
146 //
147 // Check how many arguments this system call takes
148 //
149 ArgumentCount = DescriptorTable->Number[Number] / 4;
150 ASSERT(ArgumentCount <= 17);
151
152 //
153 // Copy the register-arguments first
154 // First four arguments are in a1, a2, a3, a4
155 //
156 Argument = (PVOID*)&TrapFrame->R0;
157 for (i = 0; (i < ArgumentCount) && (i < 4); i++)
158 {
159 //
160 // Copy them into the kernel stack
161 //
162 Arguments[i] = *Argument;
163 Argument++;
164 }
165
166 //
167 // If more than four, we'll have some on the user stack
168 //
169 if (ArgumentCount > 4)
170 {
171 //
172 // Check where the stack is
173 //
174 if (Thread->PreviousMode == UserMode)
175 {
176 //
177 // FIXME-USER: Validate the user stack
178 //
179 ASSERT(FALSE);
180 Argument = (PVOID*)TrapFrame->Sp;
181 }
182 else
183 {
184 //
185 // We were called from the kernel
186 //
187 Argument = (PVOID*)(TrapFrame + 1);
188 }
189
190 //
191 // Copy the rest
192 //
193 for (i = 4; i < ArgumentCount; i++)
194 {
195 //
196 // Copy into kernel stack
197 //
198 Arguments[i] = *Argument;
199 Argument++;
200 }
201 }
202
203 //
204 // We can safely enable interrupts here
205 //
206 _enable();
207
208 //
209 // Do the system call and save result in EAX
210 //
211 TrapFrame->R0 = KiSyscallHandlers[ArgumentCount]((PVOID)SystemCall,
212 (PVOID)Arguments);
213
214 //
215 // Check if this was a user call
216 //
217 if (KiGetPreviousMode(TrapFrame) == UserMode)
218 {
219 //
220 // Make sure we didn't return at elevated IRQL
221 //
223 if (OldIrql != PASSIVE_LEVEL)
224 {
225 //
226 // Forcibly put us in a sane state
227 //
228 KeGetPcr()->CurrentIrql = 0;
229 _disable();
230
231 //
232 // Fail
233 //
234 KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE,
235 (ULONG_PTR)SystemCall,
236 OldIrql,
237 0,
238 0);
239 }
240
241 //
242 // Make sure we're not attached and that APCs are not disabled
243 //
244 if ((KeGetCurrentThread()->ApcStateIndex != CurrentApcEnvironment) ||
245 (KeGetCurrentThread()->CombinedApcDisable != 0))
246 {
247 //
248 // Fail
249 //
250 KeBugCheckEx(APC_INDEX_MISMATCH,
251 (ULONG_PTR)SystemCall,
252 KeGetCurrentThread()->ApcStateIndex,
253 KeGetCurrentThread()->CombinedApcDisable,
254 0);
255 }
256 }
257
258 //
259 // Restore the old trap frame
260 //
261 Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
262}
263
264VOID
265NTAPI
267 IN PKTRAP_FRAME TrapFrame,
268 IN PKNORMAL_ROUTINE NormalRoutine,
269 IN PVOID NormalContext,
272{
273 CONTEXT Context = { 0 };
275 ULONG ContextLength;
276 DPRINT1("User APC: %p %p %p\n", NormalContext, SystemArgument1, SystemArgument2);
277
278 //
279 // Build the user mode context
280 //
281 Context.ContextFlags = CONTEXT_FULL;
282 KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
283
284 //
285 // Setup the context on the user stack
286 //
287 ContextLength = sizeof(CONTEXT);
288 Stack = (ULONG_PTR)(Context.Sp & ~7) - ContextLength;
289
290 //
291 // Make sure the stack is valid, and copy the context
292 //
293 ProbeForWrite((PVOID)Stack, ContextLength, sizeof(QUAD));
295
296 //
297 // Setup the trap frame when we return to user mode
298 //
299 TrapFrame->R0 = (ULONG)NormalContext;
300 TrapFrame->R1 = (ULONG)SystemArgument1;
301 TrapFrame->R2 = (ULONG)SystemArgument2;
302 TrapFrame->R3 = (ULONG)NormalRoutine;
303 TrapFrame->Sp = Stack;
304 TrapFrame->Lr = (ULONG)KeUserApcDispatcher;
305}
306
308NTAPI
310 IN PVOID Argument,
311 IN ULONG ArgumentLength,
314{
315 ASSERT(FALSE);
317}
318
320NTAPI
323 IN PULONG OutputLength)
324{
325 ASSERT(FALSE);
327}
328
330NTAPI
335{
336 ASSERT(FALSE);
338}
339
DWORD Id
NTSTATUS NTAPI KeUserModeCallback(IN ULONG RoutineIndex, IN PVOID Argument, IN ULONG ArgumentLength, OUT PVOID *Result, OUT PULONG ResultLength)
Definition: usercall.c:229
VOID NTAPI KiInitializeUserApc(_In_ PKEXCEPTION_FRAME ExceptionFrame, _Inout_ PKTRAP_FRAME TrapFrame, _In_ PKNORMAL_ROUTINE NormalRoutine, _In_ PVOID NormalContext, _In_ PVOID SystemArgument1, _In_ PVOID SystemArgument2)
Definition: usercall.c:48
NTSTATUS NTAPI NtCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS CallbackStatus)
Definition: usercall.c:329
BUILD_SYSCALLS typedef NTSTATUS(* PKI_SYSCALL_PARAM_HANDLER)(IN PVOID p, IN PVOID *g)
Definition: usercall.c:56
#define BUILD_SYSCALLS
Definition: usercall.c:20
VOID KiSystemService(IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, IN ULONG Instruction)
Definition: usercall.c:82
PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers[0x12]
Definition: usercall.c:57
@ Instruction
Definition: asmpp.cpp:82
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static SERVICE_TABLE_ENTRYW ServiceTable[2]
Definition: eventlog.c:24
#define UNIMPLEMENTED
Definition: debug.h:115
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:21
#define ULONG_PTR
Definition: config.h:101
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_In_ FLT_PREOP_CALLBACK_STATUS CallbackStatus
Definition: fltkernel.h:1020
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KeGetCurrentThread
Definition: hal.h:55
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define for
Definition: utility.h:88
#define _In_
Definition: ms_sal.h:308
#define UserMode
Definition: asm.h:35
#define KeGetPcr()
Definition: ketypes.h:81
#define SERVICE_TABLE_SHIFT
Definition: ketypes.h:71
#define SERVICE_TABLE_MASK
Definition: ketypes.h:78
#define SERVICE_NUMBER_MASK
Definition: ketypes.h:83
@ CurrentApcEnvironment
Definition: ketypes.h:769
#define SERVICE_TABLE_TEST
Definition: ketypes.h:90
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:744
struct _CONTEXT CONTEXT
#define CONTEXT_FULL
Definition: nt_native.h:1375
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define KiGetLinkedTrapFrame(x)
Definition: ke.h:177
#define KiGetPreviousMode(tf)
Definition: ke.h:180
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
NTSTATUS NTAPI KiCallUserMode(IN PVOID *OutputBuffer, IN PULONG OutputLength)
Definition: usercall.c:321
PVOID KeUserApcDispatcher
Definition: ke.h:141
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
Definition: ke.h:294
struct _KPRCB * CurrentPrcb
Definition: ke.h:304
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689