ReactOS  0.4.15-dev-2991-g632fa1c
stubs.c File Reference
#include <ntoskrnl.h>
#include <fltkernel.h>
#include <debug.h>
Include dependency graph for stubs.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MAX_SYSCALL_PARAMS   16
 

Functions

VOID KiRetireDpcListInDpcStack (PKPRCB Prcb, PVOID DpcStack)
 
NTSTATUS KiConvertToGuiThread (VOID)
 
 _Requires_lock_not_held_ (Prcb->PrcbLock) VOID NTAPI KiDpcInterruptHandler(VOID)
 
VOID FASTCALL KeZeroPages (IN PVOID Address, IN ULONG Size)
 
PVOID KiSwitchKernelStackHelper (LONG_PTR StackOffset, PVOID OldStackBase)
 
PVOID NTAPI KiSwitchKernelStack (PVOID StackBase, PVOID StackLimit)
 
DECLSPEC_NORETURN VOID KiIdleLoop (VOID)
 
VOID NTAPI KiSwapProcess (IN PKPROCESS NewProcess, IN PKPROCESS OldProcess)
 
NTSTATUS NtSyscallFailure (void)
 
PVOID KiSystemCallHandler (VOID)
 
VOID KiSystemService (IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, IN ULONG Instruction)
 
NTSTATUS NTAPI NtSetLdtEntries (ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
 
NTSTATUS NTAPI NtVdmControl (IN ULONG ControlCode, IN PVOID ControlData)
 

Variables

ULONG ProcessCount
 
SIZE_T KeXStateLength = sizeof(XSAVE_FORMAT)
 

Macro Definition Documentation

◆ MAX_SYSCALL_PARAMS

#define MAX_SYSCALL_PARAMS   16

Definition at line 255 of file stubs.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file stubs.c.

Function Documentation

◆ _Requires_lock_not_held_()

_Requires_lock_not_held_ ( Prcb->  PrcbLock)

Definition at line 28 of file stubs.c.

32 {
33  PKPRCB Prcb = KeGetCurrentPrcb();
34  PKTHREAD NewThread, OldThread;
35  KIRQL OldIrql;
36 
37  /* Raise to DISPATCH_LEVEL */
39 
40  /* Send an EOI */
41  KiSendEOI();
42 
43  /* Check for pending timers, pending DPCs, or pending ready threads */
44  if ((Prcb->DpcData[0].DpcQueueDepth) ||
45  (Prcb->TimerRequest) ||
47  {
48  /* Retire DPCs while under the DPC stack */
50  }
51 
52  /* Enable interrupts */
53  _enable();
54 
55  /* Check for quantum end */
56  if (Prcb->QuantumEnd)
57  {
58  /* Handle quantum end */
59  Prcb->QuantumEnd = FALSE;
60  KiQuantumEnd();
61  }
62  else if (Prcb->NextThread)
63  {
64  /* Acquire the PRCB lock */
65  KiAcquirePrcbLock(Prcb);
66 
67  /* Capture current thread data */
68  OldThread = Prcb->CurrentThread;
69  NewThread = Prcb->NextThread;
70 
71  /* Set new thread data */
72  Prcb->NextThread = NULL;
73  Prcb->CurrentThread = NewThread;
74 
75  /* The thread is now running */
76  NewThread->State = Running;
77  OldThread->WaitReason = WrDispatchInt;
78 
79  /* Make the old thread ready */
80  KxQueueReadyThread(OldThread, Prcb);
81 
82  /* Swap to the new thread */
83  KiSwapContext(APC_LEVEL, OldThread);
84  }
85 
86  /* Disable interrupts and go back to old irql */
87  _disable();
89 }
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KDPC_DATA DpcData[2]
Definition: ketypes.h:680
void __cdecl _enable(void)
Definition: intrin_arm.h:373
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1079
VOID KiRetireDpcListInDpcStack(PKPRCB Prcb, PVOID DpcStack)
VOID NTAPI KiQuantumEnd(VOID)
UCHAR QuantumEnd
Definition: ketypes.h:700
struct _KTHREAD * NextThread
Definition: ketypes.h:571
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
struct _KTHREAD * CurrentThread
Definition: ketypes.h:570
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
UCHAR WaitReason
Definition: ketypes.h:1896
KIRQL OldIrql
Definition: mm.h:1502
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
UINT64 TimerRequest
Definition: ketypes.h:695
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
BOOLEAN NTAPI KiSwapContext(PKTHREAD CurrentThread, PKTHREAD NewThread)
Definition: stubs.c:147
FORCEINLINE VOID KiSendEOI(VOID)
Definition: ke.h:342
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:632
volatile ULONG DpcQueueDepth
Definition: ketypes.h:788
PVOID DpcStack
Definition: ketypes.h:681
#define NULL
Definition: types.h:112
volatile UCHAR State
Definition: ketypes.h:1721
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define APC_LEVEL
Definition: env_spec_w32.h:695

◆ KeZeroPages()

VOID FASTCALL KeZeroPages ( IN PVOID  Address,
IN ULONG  Size 
)

Definition at line 94 of file stubs.c.

96 {
97  /* Not using XMMI in this routine */
99 }
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
static WCHAR Address[46]
Definition: ping.c:68
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ KiConvertToGuiThread()

NTSTATUS KiConvertToGuiThread ( VOID  )

Referenced by KiSystemCallHandler().

◆ KiIdleLoop()

DECLSPEC_NORETURN VOID KiIdleLoop ( VOID  )

Definition at line 175 of file stubs.c.

176 {
177  PKPRCB Prcb = KeGetCurrentPrcb();
178  PKTHREAD OldThread, NewThread;
179 
180  /* Now loop forever */
181  while (TRUE)
182  {
183  /* Start of the idle loop: disable interrupts */
184  _enable();
185  YieldProcessor();
186  YieldProcessor();
187  _disable();
188 
189  /* Check for pending timers, pending DPCs, or pending ready threads */
190  if ((Prcb->DpcData[0].DpcQueueDepth) ||
191  (Prcb->TimerRequest) ||
192  (Prcb->DeferredReadyListHead.Next))
193  {
194  /* Quiesce the DPC software interrupt */
196 
197  /* Handle it */
198  KiRetireDpcList(Prcb);
199  }
200 
201  /* Check if a new thread is scheduled for execution */
202  if (Prcb->NextThread)
203  {
204  /* Enable interrupts */
205  _enable();
206 
207  /* Capture current thread data */
208  OldThread = Prcb->CurrentThread;
209  NewThread = Prcb->NextThread;
210 
211  /* Set new thread data */
212  Prcb->NextThread = NULL;
213  Prcb->CurrentThread = NewThread;
214 
215  /* The thread is now running */
216  NewThread->State = Running;
217 
218  /* Do the swap at SYNCH_LEVEL */
220 
221  /* Switch away from the idle thread */
222  KiSwapContext(APC_LEVEL, OldThread);
223 
224  /* Go back to DISPATCH_LEVEL */
226  }
227  else
228  {
229  /* Continue staying idle. Note the HAL returns with interrupts on */
230  Prcb->PowerState.IdleFunction(&Prcb->PowerState);
231  }
232  }
233 }
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KDPC_DATA DpcData[2]
Definition: ketypes.h:680
#define TRUE
Definition: types.h:120
void __cdecl _enable(void)
Definition: intrin_arm.h:373
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1079
PROCESSOR_POWER_STATE PowerState
Definition: ketypes.h:799
struct _KTHREAD * NextThread
Definition: ketypes.h:571
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
struct _KTHREAD * CurrentThread
Definition: ketypes.h:570
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
UINT64 TimerRequest
Definition: ketypes.h:695
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
BOOLEAN NTAPI KiSwapContext(PKTHREAD CurrentThread, PKTHREAD NewThread)
Definition: stubs.c:147
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:632
volatile ULONG DpcQueueDepth
Definition: ketypes.h:788
#define NULL
Definition: types.h:112
PPROCESSOR_IDLE_FUNCTION IdleFunction
Definition: potypes.h:68
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
volatile UCHAR State
Definition: ketypes.h:1721
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID FASTCALL KiRetireDpcList(IN PKPRCB Prcb)
Definition: dpc.c:562

◆ KiRetireDpcListInDpcStack()

VOID KiRetireDpcListInDpcStack ( PKPRCB  Prcb,
PVOID  DpcStack 
)

◆ KiSwapProcess()

VOID NTAPI KiSwapProcess ( IN PKPROCESS  NewProcess,
IN PKPROCESS  OldProcess 
)

Definition at line 237 of file stubs.c.

239 {
240  PKIPCR Pcr = (PKIPCR)KeGetPcr();
241 
242 #ifdef CONFIG_SMP
243  /* Update active processor mask */
244  InterlockedXor64((PLONG64)&NewProcess->ActiveProcessors, Pcr->Prcb.SetMember);
245  InterlockedXor64((PLONG64)&OldProcess->ActiveProcessors, Pcr->Prcb.SetMember);
246 #endif
247 
248  /* Update CR3 */
249  __writecr3(NewProcess->DirectoryTableBase[0]);
250 
251  /* Update IOPM offset */
252  Pcr->TssBase->IoMapBase = NewProcess->IopmOffset;
253 }
struct _KIPCR * PKIPCR
#define KeGetPcr()
Definition: ke.h:26
struct _KTSS64 * TssBase
Definition: ketypes.h:865
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1795
#define InterlockedXor64
Definition: interlocked.h:291
KPRCB Prcb
Definition: ketypes.h:893
UINT64 SetMember
Definition: ketypes.h:582
__int64 * PLONG64
Definition: basetsd.h:185

◆ KiSwitchKernelStack()

PVOID NTAPI KiSwitchKernelStack ( PVOID  StackBase,
PVOID  StackLimit 
)

Definition at line 121 of file stubs.c.

122 {
123  PKTHREAD CurrentThread;
124  PVOID OldStackBase;
125  LONG_PTR StackOffset;
127  PKIPCR Pcr;
128 
129  /* Get the current thread */
130  CurrentThread = KeGetCurrentThread();
131 
132  /* Save the old stack base */
133  OldStackBase = CurrentThread->StackBase;
134 
135  /* Get the size of the current stack */
136  StackSize = (ULONG_PTR)CurrentThread->StackBase - CurrentThread->StackLimit;
137  ASSERT(StackSize <= (ULONG_PTR)StackBase - (ULONG_PTR)StackLimit);
138 
139  /* Copy the current stack contents to the new stack */
140  RtlCopyMemory((PUCHAR)StackBase - StackSize,
141  (PVOID)CurrentThread->StackLimit,
142  StackSize);
143 
144  /* Calculate the offset between the old and the new stack */
145  StackOffset = (PUCHAR)StackBase - (PUCHAR)CurrentThread->StackBase;
146 
147  /* Disable interrupts while messing with the stack */
148  _disable();
149 
150  /* Set the new trap frame */
151  CurrentThread->TrapFrame = (PKTRAP_FRAME)Add2Ptr(CurrentThread->TrapFrame,
152  StackOffset);
153 
154  /* Set the new initial stack */
155  CurrentThread->InitialStack = Add2Ptr(CurrentThread->InitialStack,
156  StackOffset);
157 
158  /* Set the new stack limits */
159  CurrentThread->StackBase = StackBase;
160  CurrentThread->StackLimit = (ULONG_PTR)StackLimit;
161  CurrentThread->LargeStack = TRUE;
162 
163  /* Adjust RspBase in the PCR */
164  Pcr = (PKIPCR)KeGetPcr();
165  Pcr->Prcb.RspBase += StackOffset;
166 
167  /* Adjust Rsp0 in the TSS */
168  Pcr->TssBase->Rsp0 += StackOffset;
169 
170  return OldStackBase;
171 }
#define Add2Ptr(PTR, INC)
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
struct _KIPCR * PKIPCR
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1706
#define KeGetPcr()
Definition: ke.h:26
struct _KTSS64 * TssBase
Definition: ketypes.h:865
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ASSERT(a)
Definition: mode.c:44
volatile VOID * StackLimit
Definition: ketypes.h:1597
KPRCB Prcb
Definition: ketypes.h:893
_In_ USHORT _In_ CCHAR StackSize
Definition: iofuncs.h:1058
PVOID StackBase
Definition: ketypes.h:1598
ULONG_PTR SIZE_T
Definition: typedefs.h:80
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
struct _KTRAP_FRAME * PKTRAP_FRAME
#define KeGetCurrentThread
Definition: hal.h:55
PVOID InitialStack
Definition: ketypes.h:1596
UINT64 RspBase
Definition: ketypes.h:580

◆ KiSwitchKernelStackHelper()

PVOID KiSwitchKernelStackHelper ( LONG_PTR  StackOffset,
PVOID  OldStackBase 
)

◆ KiSystemCallHandler()

PVOID KiSystemCallHandler ( VOID  )

Definition at line 265 of file stubs.c.

267 {
268  PKTRAP_FRAME TrapFrame;
269  PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
271  PULONG64 KernelParams, UserParams;
272  ULONG ServiceNumber, Offset, Count;
273  ULONG64 UserRsp;
274 
275  /* Get a pointer to the trap frame */
277 
278  /* Increase system call count */
279  __addgsdword(FIELD_OFFSET(KIPCR, Prcb.KeSystemCalls), 1);
280 
281  /* Get the current thread */
283 
284  /* Set previous mode */
285  Thread->PreviousMode = TrapFrame->PreviousMode = UserMode;
286 
287  /* Save the old trap frame and set the new */
288  TrapFrame->TrapFrame = (ULONG64)Thread->TrapFrame;
289  Thread->TrapFrame = TrapFrame;
290 
291  /* We don't have an exception frame yet */
292  TrapFrame->ExceptionFrame = 0;
293 
294  /* Before enabling interrupts get the user rsp from the KPCR */
295  UserRsp = __readgsqword(FIELD_OFFSET(KIPCR, UserRsp));
296  TrapFrame->Rsp = UserRsp;
297 
298  /* Enable interrupts */
299  _enable();
300 
301  /* If the usermode rsp was not a usermode address, prepare an exception */
302  if (UserRsp > MmUserProbeAddress) UserRsp = MmUserProbeAddress;
303 
304  /* Get the address of the usermode and kernelmode parameters */
305  UserParams = (PULONG64)UserRsp + 1;
306  KernelParams = (PULONG64)TrapFrame - MAX_SYSCALL_PARAMS;
307 
308  /* Get the system call number from the trap frame and decode it */
309  ServiceNumber = (ULONG)TrapFrame->Rax;
310  Offset = (ServiceNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK;
311  ServiceNumber &= SERVICE_NUMBER_MASK;
312 
313  /* Check for win32k system calls */
315  {
316  ULONG GdiBatchCount;
317 
318  /* Read the GDI batch count from the TEB */
319  _SEH2_TRY
320  {
321  GdiBatchCount = NtCurrentTeb()->GdiBatchCount;
322  }
324  {
325  GdiBatchCount = 0;
326  }
327  _SEH2_END;
328 
329  /* Flush batch, if there are entries */
330  if (GdiBatchCount != 0)
331  {
333  }
334  }
335 
336  /* Get descriptor table */
337  DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset);
338 
339  /* Validate the system call number */
340  if (ServiceNumber >= DescriptorTable->Limit)
341  {
342  /* Check if this is a GUI call */
343  if (!(Offset & SERVICE_TABLE_TEST))
344  {
345  /* Fail the call */
346  TrapFrame->Rax = STATUS_INVALID_SYSTEM_SERVICE;
347  return (PVOID)NtSyscallFailure;
348  }
349 
350  /* Convert us to a GUI thread
351  To be entirely correct. we return KiConvertToGuiThread,
352  which allocates a new stack, switches to it, calls
353  PsConvertToGuiThread and resumes in the middle of
354  KiSystemCallEntry64 to restart the system call handling. */
355  return (PVOID)KiConvertToGuiThread;
356  }
357 
358  /* Get stack bytes and calculate argument count */
359  Count = DescriptorTable->Number[ServiceNumber] / 8;
360 
361  _SEH2_TRY
362  {
363  switch (Count)
364  {
365  case 16: KernelParams[15] = UserParams[15];
366  case 15: KernelParams[14] = UserParams[14];
367  case 14: KernelParams[13] = UserParams[13];
368  case 13: KernelParams[12] = UserParams[12];
369  case 12: KernelParams[11] = UserParams[11];
370  case 11: KernelParams[10] = UserParams[10];
371  case 10: KernelParams[9] = UserParams[9];
372  case 9: KernelParams[8] = UserParams[8];
373  case 8: KernelParams[7] = UserParams[7];
374  case 7: KernelParams[6] = UserParams[6];
375  case 6: KernelParams[5] = UserParams[5];
376  case 5: KernelParams[4] = UserParams[4];
377  case 4:
378  case 3:
379  case 2:
380  case 1:
381  case 0:
382  break;
383 
384  default:
385  ASSERT(FALSE);
386  break;
387  }
388  }
390  {
391  TrapFrame->Rax = _SEH2_GetExceptionCode();
392  return (PVOID)NtSyscallFailure;
393  }
394  _SEH2_END;
395 
396  return (PVOID)DescriptorTable->Base[ServiceNumber];
397 }
ULONG MmUserProbeAddress
Definition: init.c:50
#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
void * _AddressOfReturnAddress(void)
NTSTATUS KiConvertToGuiThread(VOID)
#define SERVICE_NUMBER_MASK
Definition: ketypes.h:83
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
UINT64 Rax
Definition: ketypes.h:322
#define SERVICE_TABLE_TEST
Definition: ketypes.h:90
void * PVOID
Definition: retypes.h:9
NTSTATUS NtSyscallFailure(void)
Definition: stubs.c:258
int Count
Definition: noreturn.cpp:7
#define ASSERT(a)
Definition: mode.c:44
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define MAX_SYSCALL_PARAMS
Definition: stubs.c:255
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
unsigned __int64 ULONG64
Definition: imports.h:198
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_SEH2_END
Definition: create.c:4400
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch
Definition: win32.c:20
UINT64 Rsp
Definition: ketypes.h:390
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
UINT64 ExceptionFrame
Definition: ketypes.h:380
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_INVALID_SYSTEM_SERVICE
Definition: ntstatus.h:265
unsigned __int64 * PULONG64
Definition: imports.h:198
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
struct _KTRAP_FRAME * PKTRAP_FRAME
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define KeGetCurrentThread
Definition: hal.h:55
UINT64 TrapFrame
Definition: ketypes.h:372
CHAR PreviousMode
Definition: ketypes.h:317

◆ KiSystemService()

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

Definition at line 402 of file stubs.c.

405 {
407  __debugbreak();
408 }
#define UNIMPLEMENTED
Definition: stubs.c:20
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698

◆ NtSetLdtEntries()

NTSTATUS NTAPI NtSetLdtEntries ( ULONG  Selector1,
LDT_ENTRY  LdtEntry1,
ULONG  Selector2,
LDT_ENTRY  LdtEntry2 
)

Definition at line 413 of file stubs.c.

414 {
416  __debugbreak();
417  return STATUS_UNSUCCESSFUL;
418 }
#define UNIMPLEMENTED
Definition: stubs.c:20
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by init_funcs().

◆ NtSyscallFailure()

NTSTATUS NtSyscallFailure ( void  )

Definition at line 258 of file stubs.c.

259 {
260  /* This is the failure function */
261  return (NTSTATUS)KeGetCurrentThread()->TrapFrame->Rax;
262 }
LONG NTSTATUS
Definition: precomp.h:26
#define KeGetCurrentThread
Definition: hal.h:55

Referenced by KiSystemCallHandler().

◆ NtVdmControl()

NTSTATUS NTAPI NtVdmControl ( IN ULONG  ControlCode,
IN PVOID  ControlData 
)

Definition at line 422 of file stubs.c.

424 {
425  /* Not supported */
426  return STATUS_NOT_IMPLEMENTED;
427 }
return STATUS_NOT_IMPLEMENTED

Referenced by KiEnterV86Mode().

Variable Documentation

◆ KeXStateLength

SIZE_T KeXStateLength = sizeof(XSAVE_FORMAT)

Definition at line 17 of file stubs.c.

◆ ProcessCount

ULONG ProcessCount

Definition at line 16 of file stubs.c.