ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

stubs.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.