ReactOS  0.4.15-dev-976-g0f66c66
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 _1
#define _9
Definition: ke_i.h:77
#define SYSCALL(x, y)
Definition: ke_i.h:90
#define _2
Definition: ke_i.h:70
#define e
Definition: ke_i.h:82
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define d
Definition: ke_i.h:81
#define D(d)
Definition: builtin.c:4557
const GLubyte * c
Definition: glext.h:8905
#define _7
Definition: ke_i.h:75
Definition: ttei1.cpp:12
#define _3
#define _11
Definition: ke_i.h:85
static const WCHAR E[]
Definition: oid.c:1253
#define _8
Definition: ke_i.h:76
Definition: ttei6.cpp:27
#define B(row, col)
#define _4
Definition: ke_i.h:72
#define _5
Definition: ke_i.h:73
#define _6
Definition: ke_i.h:74
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define _10
Definition: ke_i.h:84
#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);
316  return STATUS_NOT_IMPLEMENTED;
317 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define FALSE
Definition: types.h:117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

◆ KiCallUserMode()

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

Definition at line 321 of file usercall.c.

324 {
325  ASSERT(FALSE);
326  return STATUS_NOT_IMPLEMENTED;
327 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define FALSE
Definition: types.h:117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

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 };
274  ULONG_PTR Stack;
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));
294  RtlMoveMemory((PVOID)Stack, &Context, sizeof(CONTEXT));
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 }
PVOID KeUserApcDispatcher
Definition: ke.h:137
struct _CONTEXT CONTEXT
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:147
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define CONTEXT_FULL
Definition: nt_native.h:1375
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101

◆ 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
93  KIRQL OldIrql;
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;
113  ServiceTable += Offset;
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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
PKI_SYSCALL_PARAM_HANDLER KiSyscallHandlers[0x12]
Definition: usercall.c:57
#define SERVICE_TABLE_SHIFT
Definition: ketypes.h:71
#define SERVICE_TABLE_MASK
Definition: ketypes.h:78
void __cdecl _enable(void)
Definition: intrin_arm.h:373
Definition: ke.h:289
#define SERVICE_NUMBER_MASK
Definition: ketypes.h:83
#define KeGetPcr()
Definition: ke.h:25
DWORD Id
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
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
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
#define SERVICE_TABLE_TEST
Definition: ketypes.h:90
void * PVOID
Definition: retypes.h:9
struct _KPRCB * CurrentPrcb
Definition: ke.h:300
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define for
Definition: utility.h:88
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
#define KiGetLinkedTrapFrame(x)
Definition: ke.h:133
#define KiGetPreviousMode(tf)
Definition: ke.h:180
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define ULONG_PTR
Definition: config.h:101
#define KeGetCurrentThread
Definition: hal.h:44
SERVICE_TABLE_ENTRYW ServiceTable[]
Definition: service.c:18
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

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);
337  return STATUS_NOT_IMPLEMENTED;
338 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define FALSE
Definition: types.h:117
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

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)

Definition at line 56 of file usercall.c.