ReactOS 0.4.15-dev-7906-g1b85a5f
usercall.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include "ke_i.h"
Include dependency graph for usercall.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define BUILD_SYSCALLS
 
#define PROTO
 
#define FUNC
 

Functions

VOID KiSystemService (IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, IN ULONG Instruction)
 
VOID NTAPI KiInitializeUserApc (IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
NTSTATUS NTAPI KeUserModeCallback (IN ULONG RoutineIndex, IN PVOID Argument, IN ULONG ArgumentLength, OUT PVOID *Result, OUT PULONG ResultLength)
 
NTSTATUS NTAPI KiCallUserMode (IN PVOID *OutputBuffer, IN PULONG OutputLength)
 
NTSTATUS NTAPI NtCallbackReturn (_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS CallbackStatus)
 

Variables

BUILD_SYSCALLS typedef NTSTATUS(* PKI_SYSCALL_PARAM_HANDLER )(IN PVOID p, IN PVOID *g)
 
PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers [0x12]
 

Macro Definition Documentation

◆ BUILD_SYSCALLS

#define BUILD_SYSCALLS
Value:
SYSCALL(00, ()) \
SYSCALL(01, (_1)) \
SYSCALL(02, (_1, _2)) \
SYSCALL(03, (_1, _2, _3)) \
SYSCALL(04, (_1, _2, _3, _4 )) \
SYSCALL(05, (_1, _2, _3, _4, _5)) \
SYSCALL(06, (_1, _2, _3, _4, _5, _6)) \
SYSCALL(07, (_1, _2, _3, _4, _5, _6, _7)) \
SYSCALL(08, (_1, _2, _3, _4, _5, _6, _7, _8)) \
SYSCALL(09, (_1, _2, _3, _4, _5, _6, _7, _8, _9)) \
SYSCALL(0A, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a)) \
SYSCALL(0B, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b)) \
SYSCALL(0C, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c)) \
SYSCALL(0D, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d)) \
SYSCALL(0E, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e)) \
SYSCALL(0F, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f)) \
SYSCALL(10, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10)) \
SYSCALL(11, (_1, _2, _3, _4, _5, _6, _7, _8, _9, a, b, c, d, e, f, _10, _11))
#define D(d)
Definition: builtin.c:4557
Definition: ehthrow.cxx:93
Definition: ehthrow.cxx:54
Definition: terminate.cpp:24
static const WCHAR E[]
Definition: oid.c:1253
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define _8
Definition: ke_i.h:76
#define _10
Definition: ke_i.h:84
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define _2
Definition: ke_i.h:70
#define _5
Definition: ke_i.h:73
#define _6
Definition: ke_i.h:74
#define _3
Definition: ke_i.h:71
#define _1
Definition: ke_i.h:69
#define SYSCALL(x, y)
Definition: ke_i.h:90
#define _7
Definition: ke_i.h:75
#define _9
Definition: ke_i.h:77
#define _11
Definition: ke_i.h:85
#define _4
Definition: ke_i.h:72
#define F(x, y, z)
Definition: md5.c:51

Definition at line 20 of file usercall.c.

◆ FUNC

#define FUNC

Definition at line 50 of file usercall.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file usercall.c.

◆ PROTO

#define PROTO

Definition at line 43 of file usercall.c.

Function Documentation

◆ KeUserModeCallback()

NTSTATUS NTAPI KeUserModeCallback ( IN ULONG  RoutineIndex,
IN PVOID  Argument,
IN ULONG  ArgumentLength,
OUT PVOID Result,
OUT PULONG  ResultLength 
)

Definition at line 309 of file usercall.c.

314{
315 ASSERT(FALSE);
317}
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ KiCallUserMode()

NTSTATUS NTAPI KiCallUserMode ( IN PVOID OutputBuffer,
IN PULONG  OutputLength 
)

Definition at line 321 of file usercall.c.

324{
325 ASSERT(FALSE);
327}

Referenced by KeUserModeCallback().

◆ KiInitializeUserApc()

VOID NTAPI KiInitializeUserApc ( IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN PKNORMAL_ROUTINE  NormalRoutine,
IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 266 of file usercall.c.

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}
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
struct _CONTEXT CONTEXT
#define CONTEXT_FULL
Definition: nt_native.h:1375
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
PVOID KeUserApcDispatcher
Definition: ke.h:141
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_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

◆ KiSystemService()

VOID KiSystemService ( IN PKTHREAD  Thread,
IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Instruction 
)

Definition at line 82 of file usercall.c.

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}
DWORD Id
PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers[0x12]
Definition: usercall.c:57
@ Instruction
Definition: asmpp.cpp:82
static SERVICE_TABLE_ENTRYW ServiceTable[2]
Definition: eventlog.c:24
#define UNIMPLEMENTED
Definition: debug.h:115
#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
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
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 for
Definition: utility.h:88
#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
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define KiGetLinkedTrapFrame(x)
Definition: ke.h:177
#define KiGetPreviousMode(tf)
Definition: ke.h:180
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
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
void * PVOID
Definition: typedefs.h:50
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by KiSoftwareInterruptHandler().

◆ NtCallbackReturn()

NTSTATUS NTAPI NtCallbackReturn ( _In_ PVOID  Result,
_In_ ULONG  ResultLength,
_In_ NTSTATUS  CallbackStatus 
)

Definition at line 331 of file usercall.c.

335{
336 ASSERT(FALSE);
338}

Variable Documentation

◆ KiSyscallHandlers

PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers[0x12]
Initial value:
=
{
KiSyscall00Param,
KiSyscall01Param,
KiSyscall02Param,
KiSyscall03Param,
KiSyscall04Param,
KiSyscall05Param,
KiSyscall06Param,
KiSyscall07Param,
KiSyscall08Param,
KiSyscall09Param,
KiSyscall0AParam,
KiSyscall0BParam,
KiSyscall0CParam,
KiSyscall0DParam,
KiSyscall0EParam,
KiSyscall0FParam,
KiSyscall10Param,
KiSyscall11Param,
}

Definition at line 57 of file usercall.c.

Referenced by KiSystemService().

◆ PKI_SYSCALL_PARAM_HANDLER

BUILD_SYSCALLS typedef NTSTATUS(* PKI_SYSCALL_PARAM_HANDLER) (IN PVOID p, IN PVOID *g) ( IN PVOID  p,
IN PVOID g 
)

Definition at line 56 of file usercall.c.