Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstubs.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * PURPOSE: stubs 00005 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 00006 */ 00007 00008 /* INCLUDES ******************************************************************/ 00009 00010 #include <ntoskrnl.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 VOID 00016 KiRetireDpcListInDpcStack( 00017 PKPRCB Prcb, 00018 PVOID DpcStack); 00019 00020 VOID 00021 NTAPI 00022 KiDpcInterruptHandler(VOID) 00023 { 00024 PKPRCB Prcb = KeGetCurrentPrcb(); 00025 PKTHREAD NewThread, OldThread; 00026 KIRQL OldIrql; 00027 00028 /* Raise to DISPATCH_LEVEL */ 00029 OldIrql = KfRaiseIrql(DISPATCH_LEVEL); 00030 00031 /* Send an EOI */ 00032 KiSendEOI(); 00033 00034 /* Check for pending timers, pending DPCs, or pending ready threads */ 00035 if ((Prcb->DpcData[0].DpcQueueDepth) || 00036 (Prcb->TimerRequest) || 00037 (Prcb->DeferredReadyListHead.Next)) 00038 { 00039 /* Retire DPCs while under the DPC stack */ 00040 KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack); 00041 } 00042 00043 /* Enable interrupts */ 00044 _enable(); 00045 00046 /* Check for quantum end */ 00047 if (Prcb->QuantumEnd) 00048 { 00049 /* Handle quantum end */ 00050 Prcb->QuantumEnd = FALSE; 00051 KiQuantumEnd(); 00052 } 00053 else if (Prcb->NextThread) 00054 { 00055 /* Capture current thread data */ 00056 OldThread = Prcb->CurrentThread; 00057 NewThread = Prcb->NextThread; 00058 00059 /* Set new thread data */ 00060 Prcb->NextThread = NULL; 00061 Prcb->CurrentThread = NewThread; 00062 00063 /* The thread is now running */ 00064 NewThread->State = Running; 00065 OldThread->WaitReason = WrDispatchInt; 00066 00067 /* Make the old thread ready */ 00068 KxQueueReadyThread(OldThread, Prcb); 00069 00070 /* Swap to the new thread */ 00071 KiSwapContext(APC_LEVEL, OldThread); 00072 } 00073 00074 /* Go back to old irql and disable interrupts */ 00075 KeLowerIrql(OldIrql); 00076 _disable(); 00077 } 00078 00079 00080 VOID 00081 FASTCALL 00082 KeZeroPages(IN PVOID Address, 00083 IN ULONG Size) 00084 { 00085 /* Not using XMMI in this routine */ 00086 RtlZeroMemory(Address, Size); 00087 } 00088 00089 PVOID 00090 NTAPI 00091 KeSwitchKernelStack(PVOID StackBase, PVOID StackLimit) 00092 { 00093 UNIMPLEMENTED; 00094 __debugbreak(); 00095 return NULL; 00096 } 00097 00098 NTSTATUS 00099 NTAPI 00100 KeUserModeCallback(IN ULONG RoutineIndex, 00101 IN PVOID Argument, 00102 IN ULONG ArgumentLength, 00103 OUT PVOID *Result, 00104 OUT PULONG ResultLength) 00105 { 00106 UNIMPLEMENTED; 00107 __debugbreak(); 00108 return STATUS_UNSUCCESSFUL; 00109 } 00110 00111 VOID 00112 FASTCALL 00113 KiIdleLoop(VOID) 00114 { 00115 PKPRCB Prcb = KeGetCurrentPrcb(); 00116 PKTHREAD OldThread, NewThread; 00117 00118 /* Initialize the idle loop: disable interrupts */ 00119 _enable(); 00120 YieldProcessor(); 00121 YieldProcessor(); 00122 _disable(); 00123 00124 /* Now loop forever */ 00125 while (TRUE) 00126 { 00127 /* Check for pending timers, pending DPCs, or pending ready threads */ 00128 if ((Prcb->DpcData[0].DpcQueueDepth) || 00129 (Prcb->TimerRequest) || 00130 (Prcb->DeferredReadyListHead.Next)) 00131 { 00132 /* Quiesce the DPC software interrupt */ 00133 HalClearSoftwareInterrupt(DISPATCH_LEVEL); 00134 00135 /* Handle it */ 00136 KiRetireDpcList(Prcb); 00137 } 00138 00139 /* Check if a new thread is scheduled for execution */ 00140 if (Prcb->NextThread) 00141 { 00142 /* Enable interupts */ 00143 _enable(); 00144 00145 /* Capture current thread data */ 00146 OldThread = Prcb->CurrentThread; 00147 NewThread = Prcb->NextThread; 00148 00149 /* Set new thread data */ 00150 Prcb->NextThread = NULL; 00151 Prcb->CurrentThread = NewThread; 00152 00153 /* The thread is now running */ 00154 NewThread->State = Running; 00155 00156 /* Do the swap at SYNCH_LEVEL */ 00157 KfRaiseIrql(SYNCH_LEVEL); 00158 00159 /* Switch away from the idle thread */ 00160 KiSwapContext(APC_LEVEL, OldThread); 00161 00162 /* Go back to DISPATCH_LEVEL */ 00163 KeLowerIrql(DISPATCH_LEVEL); 00164 00165 /* We are back in the idle thread -- disable interrupts again */ 00166 _enable(); 00167 YieldProcessor(); 00168 YieldProcessor(); 00169 _disable(); 00170 } 00171 else 00172 { 00173 /* Continue staying idle. Note the HAL returns with interrupts on */ 00174 Prcb->PowerState.IdleFunction(&Prcb->PowerState); 00175 } 00176 } 00177 } 00178 00179 00207 VOID 00208 NTAPI 00209 KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, 00210 IN PKTRAP_FRAME TrapFrame, 00211 IN PKNORMAL_ROUTINE NormalRoutine, 00212 IN PVOID NormalContext, 00213 IN PVOID SystemArgument1, 00214 IN PVOID SystemArgument2) 00215 { 00216 CONTEXT Context; 00217 ULONG64 AlignedRsp, Stack; 00218 EXCEPTION_RECORD SehExceptRecord; 00219 00220 /* Sanity check, that the trap frame is from user mode */ 00221 ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); 00222 00223 /* Convert the current trap frame to a context */ 00224 Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; 00225 KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context); 00226 00227 /* We jump to KiUserApcDispatcher in ntdll */ 00228 TrapFrame->Rip = (ULONG64)KeUserApcDispatcher; 00229 00230 /* Setup Ring 3 segments */ 00231 TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK; 00232 TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK; 00233 TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK; 00234 TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK; 00235 TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK; 00236 TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK; 00237 00238 /* Sanitize EFLAGS, enable interrupts */ 00239 TrapFrame->EFlags = (Context.EFlags & EFLAGS_USER_SANITIZE); 00240 TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK; 00241 00242 /* Set parameters for KiUserApcDispatcher */ 00243 Context.P1Home = (ULONG64)NormalContext; 00244 Context.P2Home = (ULONG64)SystemArgument1; 00245 Context.P3Home = (ULONG64)SystemArgument2; 00246 Context.P4Home = (ULONG64)NormalRoutine; 00247 00248 /* Check if thread has IOPL and force it enabled if so */ 00249 //if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL; 00250 00251 /* Align Stack to 16 bytes and allocate space */ 00252 AlignedRsp = Context.Rsp & ~15; 00253 Stack = AlignedRsp - sizeof(CONTEXT); 00254 TrapFrame->Rsp = Stack; 00255 00256 /* The stack must be 16 byte aligned for KiUserApcDispatcher */ 00257 ASSERT((Stack & 15) == 0); 00258 00259 /* Protect with SEH */ 00260 _SEH2_TRY 00261 { 00262 /* Probe the stack */ 00263 ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8); 00264 00265 /* Copy the context */ 00266 RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT)); 00267 } 00268 _SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER)) 00269 { 00270 /* Dispatch the exception */ 00271 SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip; 00272 KiDispatchException(&SehExceptRecord, 00273 ExceptionFrame, 00274 TrapFrame, 00275 UserMode, 00276 TRUE); 00277 } 00278 _SEH2_END; 00279 } 00280 00281 VOID 00282 NTAPI 00283 KiSwapProcess(IN PKPROCESS NewProcess, 00284 IN PKPROCESS OldProcess) 00285 { 00286 PKIPCR Pcr = (PKIPCR)KeGetPcr(); 00287 #ifdef CONFIG_SMP 00288 LONG SetMember; 00289 00290 /* Update active processor mask */ 00291 SetMember = (LONG)Pcr->SetMember; 00292 InterlockedXor((PLONG)&NewProcess->ActiveProcessors, SetMember); 00293 InterlockedXor((PLONG)&OldProcess->ActiveProcessors, SetMember); 00294 #endif 00295 00296 /* Update CR3 */ 00297 __writecr3(NewProcess->DirectoryTableBase[0]); 00298 00299 /* Update IOPM offset */ 00300 Pcr->TssBase->IoMapBase = NewProcess->IopmOffset; 00301 } 00302 00303 #define MAX_SYSCALL_PARAMS 16 00304 00305 NTSTATUS 00306 NtSyscallFailure(void) 00307 { 00308 /* This is the failure function */ 00309 return STATUS_ACCESS_VIOLATION; 00310 } 00311 00312 PVOID 00313 KiSystemCallHandler( 00314 IN PKTRAP_FRAME TrapFrame, 00315 IN ULONG64 P2, 00316 IN ULONG64 P3, 00317 IN ULONG64 P4) 00318 { 00319 PKSERVICE_TABLE_DESCRIPTOR DescriptorTable; 00320 PKTHREAD Thread; 00321 PULONG64 KernelParams, UserParams; 00322 ULONG ServiceNumber, Offset, Count; 00323 ULONG64 UserRsp; 00324 00325 DPRINT("Syscall #%ld\n", TrapFrame->Rax); 00326 //__debugbreak(); 00327 00328 /* Increase system call count */ 00329 __addgsdword(FIELD_OFFSET(KIPCR, Prcb.KeSystemCalls), 1); 00330 00331 /* Get the current thread */ 00332 Thread = KeGetCurrentThread(); 00333 00334 /* Set previous mode */ 00335 Thread->PreviousMode = TrapFrame->PreviousMode = UserMode; 00336 00337 /* Save the old trap frame and set the new */ 00338 TrapFrame->TrapFrame = (ULONG64)Thread->TrapFrame; 00339 Thread->TrapFrame = TrapFrame; 00340 00341 /* Before enabling interrupts get the user rsp from the KPCR */ 00342 UserRsp = __readgsqword(FIELD_OFFSET(KIPCR, UserRsp)); 00343 TrapFrame->Rsp = UserRsp; 00344 00345 /* Enable interrupts */ 00346 _enable(); 00347 00348 /* If the usermode rsp was not a usermode address, prepare an exception */ 00349 if (UserRsp > MmUserProbeAddress) UserRsp = MmUserProbeAddress; 00350 00351 /* Get the address of the usermode and kernelmode parameters */ 00352 UserParams = (PULONG64)UserRsp + 1; 00353 KernelParams = (PULONG64)TrapFrame - MAX_SYSCALL_PARAMS; 00354 00355 /* Get the system call number from the trap frame and decode it */ 00356 ServiceNumber = (ULONG)TrapFrame->Rax; 00357 Offset = (ServiceNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK; 00358 ServiceNumber &= SERVICE_NUMBER_MASK; 00359 00360 /* Get descriptor table */ 00361 DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset); 00362 00363 /* Get stack bytes and calculate argument count */ 00364 Count = DescriptorTable->Number[ServiceNumber] / 8; 00365 00366 __try 00367 { 00368 switch (Count) 00369 { 00370 case 16: KernelParams[15] = UserParams[15]; 00371 case 15: KernelParams[14] = UserParams[14]; 00372 case 14: KernelParams[13] = UserParams[13]; 00373 case 13: KernelParams[12] = UserParams[12]; 00374 case 12: KernelParams[11] = UserParams[11]; 00375 case 11: KernelParams[10] = UserParams[10]; 00376 case 10: KernelParams[9] = UserParams[9]; 00377 case 9: KernelParams[8] = UserParams[8]; 00378 case 8: KernelParams[7] = UserParams[7]; 00379 case 7: KernelParams[6] = UserParams[6]; 00380 case 6: KernelParams[5] = UserParams[5]; 00381 case 5: KernelParams[4] = UserParams[4]; 00382 case 4: KernelParams[3] = P4; 00383 case 3: KernelParams[2] = P3; 00384 case 2: KernelParams[1] = P2; 00385 case 1: KernelParams[0] = TrapFrame->R10; 00386 case 0: 00387 break; 00388 00389 default: 00390 __debugbreak(); 00391 break; 00392 } 00393 } 00394 __except(1) 00395 { 00396 TrapFrame->Rax = _SEH2_GetExceptionCode(); 00397 return (PVOID)NtSyscallFailure; 00398 } 00399 00400 00401 return (PVOID)DescriptorTable->Base[ServiceNumber]; 00402 } 00403 00404 00405 // FIXME: we need to 00406 VOID 00407 KiSystemService(IN PKTHREAD Thread, 00408 IN PKTRAP_FRAME TrapFrame, 00409 IN ULONG Instruction) 00410 { 00411 UNIMPLEMENTED; 00412 __debugbreak(); 00413 } 00414 00415 NTSYSAPI 00416 NTSTATUS 00417 NTAPI 00418 NtCallbackReturn 00419 ( IN PVOID Result OPTIONAL, IN ULONG ResultLength, IN NTSTATUS Status ) 00420 { 00421 UNIMPLEMENTED; 00422 __debugbreak(); 00423 return STATUS_UNSUCCESSFUL; 00424 } 00425 00426 NTSTATUS 00427 NTAPI 00428 NtSetLdtEntries 00429 (ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2) 00430 { 00431 UNIMPLEMENTED; 00432 __debugbreak(); 00433 return STATUS_UNSUCCESSFUL; 00434 } 00435 00436 NTSTATUS 00437 NTAPI 00438 NtVdmControl(IN ULONG ControlCode, 00439 IN PVOID ControlData) 00440 { 00441 /* Not supported */ 00442 return STATUS_NOT_IMPLEMENTED; 00443 } 00444 00445 NTSTATUS 00446 NTAPI 00447 KiCallUserMode( 00448 IN PVOID *OutputBuffer, 00449 IN PULONG OutputLength) 00450 { 00451 UNIMPLEMENTED; 00452 __debugbreak(); 00453 return STATUS_UNSUCCESSFUL; 00454 } 00455 00456 #undef ExQueryDepthSList 00457 NTKERNELAPI 00458 USHORT 00459 ExQueryDepthSList(IN PSLIST_HEADER ListHead) 00460 { 00461 return (USHORT)(ListHead->Alignment & 0xffff); 00462 } 00463 00464 00465 ULONG ProcessCount; 00466 BOOLEAN CcPfEnablePrefetcher; 00467 00468 Generated on Sat May 26 2012 04:20:19 for ReactOS by
1.7.6.1
|