ReactOS  0.4.13-dev-443-g10f00f8
stubs.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * PURPOSE: stubs
5  * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
6  */
7 
8 /* INCLUDES ******************************************************************/
9 
10 #include <ntoskrnl.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 VOID
17  PKPRCB Prcb,
18  PVOID DpcStack);
19 
20 VOID
21 NTAPI
23 {
24  PKPRCB Prcb = KeGetCurrentPrcb();
25  PKTHREAD NewThread, OldThread;
26  KIRQL OldIrql;
27 
28  /* Raise to DISPATCH_LEVEL */
30 
31  /* Send an EOI */
32  KiSendEOI();
33 
34  /* Check for pending timers, pending DPCs, or pending ready threads */
35  if ((Prcb->DpcData[0].DpcQueueDepth) ||
36  (Prcb->TimerRequest) ||
38  {
39  /* Retire DPCs while under the DPC stack */
41  }
42 
43  /* Enable interrupts */
44  _enable();
45 
46  /* Check for quantum end */
47  if (Prcb->QuantumEnd)
48  {
49  /* Handle quantum end */
50  Prcb->QuantumEnd = FALSE;
51  KiQuantumEnd();
52  }
53  else if (Prcb->NextThread)
54  {
55  /* Capture current thread data */
56  OldThread = Prcb->CurrentThread;
57  NewThread = Prcb->NextThread;
58 
59  /* Set new thread data */
60  Prcb->NextThread = NULL;
61  Prcb->CurrentThread = NewThread;
62 
63  /* The thread is now running */
64  NewThread->State = Running;
65  OldThread->WaitReason = WrDispatchInt;
66 
67  /* Make the old thread ready */
68  KxQueueReadyThread(OldThread, Prcb);
69 
70  /* Swap to the new thread */
71  KiSwapContext(APC_LEVEL, OldThread);
72  }
73 
74  /* Go back to old irql and disable interrupts */
76  _disable();
77 }
78 
79 
80 VOID
83  IN ULONG Size)
84 {
85  /* Not using XMMI in this routine */
87 }
88 
89 PVOID
90 NTAPI
91 KeSwitchKernelStack(PVOID StackBase, PVOID StackLimit)
92 {
94  __debugbreak();
95  return NULL;
96 }
97 
99 NTAPI
101  IN PVOID Argument,
102  IN ULONG ArgumentLength,
103  OUT PVOID *Result,
105 {
107  __debugbreak();
108  return STATUS_UNSUCCESSFUL;
109 }
110 
111 VOID
112 FASTCALL
114 {
115  PKPRCB Prcb = KeGetCurrentPrcb();
116  PKTHREAD OldThread, NewThread;
117 
118  /* Now loop forever */
119  while (TRUE)
120  {
121  /* Start of the idle loop: disable interrupts */
122  _enable();
123  YieldProcessor();
124  YieldProcessor();
125  _disable();
126 
127  /* Check for pending timers, pending DPCs, or pending ready threads */
128  if ((Prcb->DpcData[0].DpcQueueDepth) ||
129  (Prcb->TimerRequest) ||
130  (Prcb->DeferredReadyListHead.Next))
131  {
132  /* Quiesce the DPC software interrupt */
134 
135  /* Handle it */
136  KiRetireDpcList(Prcb);
137  }
138 
139  /* Check if a new thread is scheduled for execution */
140  if (Prcb->NextThread)
141  {
142  /* Enable interrupts */
143  _enable();
144 
145  /* Capture current thread data */
146  OldThread = Prcb->CurrentThread;
147  NewThread = Prcb->NextThread;
148 
149  /* Set new thread data */
150  Prcb->NextThread = NULL;
151  Prcb->CurrentThread = NewThread;
152 
153  /* The thread is now running */
154  NewThread->State = Running;
155 
156  /* Do the swap at SYNCH_LEVEL */
158 
159  /* Switch away from the idle thread */
160  KiSwapContext(APC_LEVEL, OldThread);
161 
162  /* Go back to DISPATCH_LEVEL */
164  }
165  else
166  {
167  /* Continue staying idle. Note the HAL returns with interrupts on */
168  Prcb->PowerState.IdleFunction(&Prcb->PowerState);
169  }
170  }
171 }
172 
173 
201 VOID
202 NTAPI
204  IN PKTRAP_FRAME TrapFrame,
205  IN PKNORMAL_ROUTINE NormalRoutine,
206  IN PVOID NormalContext,
209 {
211  ULONG64 AlignedRsp, Stack;
212  EXCEPTION_RECORD SehExceptRecord;
213 
214  /* Sanity check, that the trap frame is from user mode */
215  ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
216 
217  /* Convert the current trap frame to a context */
219  KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
220 
221  /* We jump to KiUserApcDispatcher in ntdll */
222  TrapFrame->Rip = (ULONG64)KeUserApcDispatcher;
223 
224  /* Setup Ring 3 segments */
225  TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
226  TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
227  TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
228  TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
229  TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
230  TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
231 
232  /* Sanitize EFLAGS, enable interrupts */
233  TrapFrame->EFlags = (Context.EFlags & EFLAGS_USER_SANITIZE);
234  TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
235 
236  /* Set parameters for KiUserApcDispatcher */
237  Context.P1Home = (ULONG64)NormalContext;
238  Context.P2Home = (ULONG64)SystemArgument1;
239  Context.P3Home = (ULONG64)SystemArgument2;
240  Context.P4Home = (ULONG64)NormalRoutine;
241 
242  /* Check if thread has IOPL and force it enabled if so */
243  //if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
244 
245  /* Align Stack to 16 bytes and allocate space */
246  AlignedRsp = Context.Rsp & ~15;
247  Stack = AlignedRsp - sizeof(CONTEXT);
248  TrapFrame->Rsp = Stack;
249 
250  /* The stack must be 16 byte aligned for KiUserApcDispatcher */
251  ASSERT((Stack & 15) == 0);
252 
253  /* Protect with SEH */
254  _SEH2_TRY
255  {
256  /* Probe the stack */
257  ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8);
258 
259  /* Copy the context */
260  RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT));
261  }
263  {
264  /* Dispatch the exception */
265  SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
266  KiDispatchException(&SehExceptRecord,
267  ExceptionFrame,
268  TrapFrame,
269  UserMode,
270  TRUE);
271  }
272  _SEH2_END;
273 }
274 
275 VOID
276 NTAPI
278  IN PKPROCESS OldProcess)
279 {
280  PKIPCR Pcr = (PKIPCR)KeGetPcr();
281 
282 #ifdef CONFIG_SMP
283  /* Update active processor mask */
284  InterlockedXor64((PLONG64)&NewProcess->ActiveProcessors, Pcr->Prcb.SetMember);
285  InterlockedXor64((PLONG64)&OldProcess->ActiveProcessors, Pcr->Prcb.SetMember);
286 #endif
287 
288  /* Update CR3 */
289  __writecr3(NewProcess->DirectoryTableBase[0]);
290 
291  /* Update IOPM offset */
292  Pcr->TssBase->IoMapBase = NewProcess->IopmOffset;
293 }
294 
295 #define MAX_SYSCALL_PARAMS 16
296 
297 NTSTATUS
299 {
300  /* This is the failure function */
302 }
303 
304 PVOID
306  IN PKTRAP_FRAME TrapFrame,
307  IN ULONG64 P2,
308  IN ULONG64 P3,
309  IN ULONG64 P4)
310 {
311  PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
313  PULONG64 KernelParams, UserParams;
314  ULONG ServiceNumber, Offset, Count;
315  ULONG64 UserRsp;
316 
317  DPRINT("Syscall #%ld\n", TrapFrame->Rax);
318  //__debugbreak();
319 
320  /* Increase system call count */
321  __addgsdword(FIELD_OFFSET(KIPCR, Prcb.KeSystemCalls), 1);
322 
323  /* Get the current thread */
325 
326  /* Set previous mode */
327  Thread->PreviousMode = TrapFrame->PreviousMode = UserMode;
328 
329  /* Save the old trap frame and set the new */
330  TrapFrame->TrapFrame = (ULONG64)Thread->TrapFrame;
331  Thread->TrapFrame = TrapFrame;
332 
333  /* Before enabling interrupts get the user rsp from the KPCR */
334  UserRsp = __readgsqword(FIELD_OFFSET(KIPCR, UserRsp));
335  TrapFrame->Rsp = UserRsp;
336 
337  /* Enable interrupts */
338  _enable();
339 
340  /* If the usermode rsp was not a usermode address, prepare an exception */
341  if (UserRsp > MmUserProbeAddress) UserRsp = MmUserProbeAddress;
342 
343  /* Get the address of the usermode and kernelmode parameters */
344  UserParams = (PULONG64)UserRsp + 1;
345  KernelParams = (PULONG64)TrapFrame - MAX_SYSCALL_PARAMS;
346 
347  /* Get the system call number from the trap frame and decode it */
348  ServiceNumber = (ULONG)TrapFrame->Rax;
349  Offset = (ServiceNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK;
350  ServiceNumber &= SERVICE_NUMBER_MASK;
351 
352  /* Get descriptor table */
353  DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset);
354 
355  /* Get stack bytes and calculate argument count */
356  Count = DescriptorTable->Number[ServiceNumber] / 8;
357 
358  __try
359  {
360  switch (Count)
361  {
362  case 16: KernelParams[15] = UserParams[15];
363  case 15: KernelParams[14] = UserParams[14];
364  case 14: KernelParams[13] = UserParams[13];
365  case 13: KernelParams[12] = UserParams[12];
366  case 12: KernelParams[11] = UserParams[11];
367  case 11: KernelParams[10] = UserParams[10];
368  case 10: KernelParams[9] = UserParams[9];
369  case 9: KernelParams[8] = UserParams[8];
370  case 8: KernelParams[7] = UserParams[7];
371  case 7: KernelParams[6] = UserParams[6];
372  case 6: KernelParams[5] = UserParams[5];
373  case 5: KernelParams[4] = UserParams[4];
374  case 4: KernelParams[3] = P4;
375  case 3: KernelParams[2] = P3;
376  case 2: KernelParams[1] = P2;
377  case 1: KernelParams[0] = TrapFrame->R10;
378  case 0:
379  break;
380 
381  default:
382  __debugbreak();
383  break;
384  }
385  }
386  __except(1)
387  {
388  TrapFrame->Rax = _SEH2_GetExceptionCode();
389  return (PVOID)NtSyscallFailure;
390  }
391 
392 
393  return (PVOID)DescriptorTable->Base[ServiceNumber];
394 }
395 
396 
397 // FIXME: we need to
398 VOID
400  IN PKTRAP_FRAME TrapFrame,
401  IN ULONG Instruction)
402 {
404  __debugbreak();
405 }
406 
407 NTSYSAPI
408 NTSTATUS
409 NTAPI
412 {
414  __debugbreak();
415  return STATUS_UNSUCCESSFUL;
416 }
417 
418 NTSTATUS
419 NTAPI
421 (ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
422 {
424  __debugbreak();
425  return STATUS_UNSUCCESSFUL;
426 }
427 
428 NTSTATUS
429 NTAPI
431  IN PVOID ControlData)
432 {
433  /* Not supported */
434  return STATUS_NOT_IMPLEMENTED;
435 }
436 
437 NTSTATUS
438 NTAPI
441  IN PULONG OutputLength)
442 {
444  __debugbreak();
445  return STATUS_UNSUCCESSFUL;
446 }
447 
450 
451 
ULONG MmUserProbeAddress
Definition: init.c:50
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
NTSTATUS NTAPI NtVdmControl(IN ULONG ControlCode, IN PVOID ControlData)
Definition: stubs.c:430
NTSTATUS NTAPI KeUserModeCallback(IN ULONG RoutineIndex, IN PVOID Argument, IN ULONG ArgumentLength, OUT PVOID *Result, OUT PULONG ResultLength)
Definition: stubs.c:100
#define KGDT64_R3_CODE
Definition: ketypes.h:76
#define IN
Definition: typedefs.h:38
#define SERVICE_TABLE_SHIFT
Definition: ketypes.h:71
struct _CONTEXT CONTEXT
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define MODE_MASK
Definition: orders.h:326
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: stubs.c:203
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:82
PVOID KeUserApcDispatcher
Definition: ke.h:137
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
KDPC_DATA DpcData[2]
Definition: ketypes.h:676
PVOID KiSystemCallHandler(IN PKTRAP_FRAME TrapFrame, IN ULONG64 P2, IN ULONG64 P3, IN ULONG64 P4)
Definition: stubs.c:305
#define SERVICE_TABLE_MASK
Definition: ketypes.h:78
void __cdecl _enable(void)
Definition: intrin_arm.h:373
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
struct _KIPCR * PKIPCR
VOID KiRetireDpcListInDpcStack(PKPRCB Prcb, PVOID DpcStack)
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define KGDT64_R3_CMTEB
Definition: ketypes.h:78
VOID NTAPI KiQuantumEnd(VOID)
Definition: dpc.c:465
PROCESSOR_POWER_STATE PowerState
Definition: ketypes.h:795
#define CONTEXT_FULL
Definition: compat.h:270
UCHAR QuantumEnd
Definition: ketypes.h:696
#define SERVICE_NUMBER_MASK
Definition: ketypes.h:83
#define UNIMPLEMENTED
Definition: stubs.c:20
#define FASTCALL
Definition: nt_native.h:50
#define NTSYSAPI
Definition: ntoskrnl.h:14
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
struct _KTHREAD * NextThread
Definition: ketypes.h:567
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define KeGetPcr()
Definition: ke.h:25
PVOID ExceptionAddress
Definition: compat.h:199
_SEH2_TRY
Definition: create.c:4250
struct _KTSS64 * TssBase
Definition: ketypes.h:861
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE VOID YieldProcessor(VOID)
Definition: ke.h:32
BOOLEAN CcPfEnablePrefetcher
Definition: stubs.c:449
UCHAR KIRQL
Definition: env_spec_w32.h:591
FORCEINLINE VOID KxQueueReadyThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: ke_x.h:1343
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1675
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
VOID NTAPI KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, PKEXCEPTION_FRAME ExceptionFrame, PKTRAP_FRAME Tf, KPROCESSOR_MODE PreviousMode, BOOLEAN SearchFrames)
#define KGDT64_R3_DATA
Definition: ketypes.h:75
#define EFLAGS_USER_SANITIZE
Definition: ketypes.h:133
ULONG ProcessCount
Definition: stubs.c:448
NTSTATUS NTAPI NtSetLdtEntries(ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
Definition: stubs.c:421
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _KTHREAD * CurrentThread
Definition: ketypes.h:566
#define RPL_MASK
Definition: ketypes.h:69
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
_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:426
void DPRINT(...)
Definition: polytest.cpp:61
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
VOID FASTCALL KiIdleLoop(VOID)
Definition: stubs.c:113
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:147
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
void * PVOID
Definition: retypes.h:9
#define InterlockedXor64
Definition: interlocked.h:291
NTSTATUS NtSyscallFailure(void)
Definition: stubs.c:298
UCHAR WaitReason
Definition: ketypes.h:1854
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
UINT64 TimerRequest
Definition: ketypes.h:691
#define MAX_SYSCALL_PARAMS
Definition: stubs.c:295
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned __int64 ULONG64
Definition: imports.h:198
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:636
VOID FORCEINLINE KiSendEOI(VOID)
Definition: ke.h:287
KPRCB Prcb
Definition: ketypes.h:889
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
BOOLEAN NTAPI KiSwapContext(PKTHREAD CurrentThread, PKTHREAD NewThread)
Definition: stubs.c:147
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
UINT64 SetMember
Definition: ketypes.h:578
Definition: compat.h:428
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
SINGLE_LIST_ENTRY DeferredReadyListHead
Definition: ketypes.h:628
volatile ULONG DpcQueueDepth
Definition: ketypes.h:746
_SEH2_END
Definition: create.c:4424
PVOID DpcStack
Definition: ketypes.h:677
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
PVOID NTAPI KeSwitchKernelStack(PVOID StackBase, PVOID StackLimit)
Definition: stubs.c:91
NTSTATUS NTAPI KiCallUserMode(IN PVOID *OutputBuffer, IN PULONG OutputLength)
Definition: stubs.c:439
PPROCESSOR_IDLE_FUNCTION IdleFunction
Definition: potypes.h:68
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:282
#define OUT
Definition: typedefs.h:39
volatile UCHAR State
Definition: ketypes.h:1679
void __cdecl _disable(void)
Definition: intrin_arm.h:365
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
unsigned __int64 * PULONG64
Definition: imports.h:198
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
#define KeGetCurrentThread
Definition: hal.h:44
VOID NTAPI KiDpcInterruptHandler(VOID)
Definition: stubs.c:22
VOID NTAPI KiSwapProcess(IN PKPROCESS NewProcess, IN PKPROCESS OldProcess)
Definition: stubs.c:277
__int64 * PLONG64
Definition: basetsd.h:185
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID KiSystemService(IN PKTHREAD Thread, IN PKTRAP_FRAME TrapFrame, IN ULONG Instruction)
Definition: stubs.c:399
VOID FASTCALL KiRetireDpcList(IN PKPRCB Prcb)
Definition: dpc.c:561
#define CONTEXT_DEBUG_REGISTERS
Definition: compat.h:268
NTSYSAPI NTSTATUS NTAPI NtCallbackReturn(IN PVOID Result OPTIONAL, IN ULONG ResultLength, IN NTSTATUS Status)
Definition: stubs.c:411
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68