/////////////////////////////////////////////////////////////////////////////// // // KeStopSchedulingProcess // // Stops scheduling specified process. // STATUS KeStopSchedulingProcess( PPROCESS Process ) { ASSERT(Process); // // determine in which list the process is located // switch (Process->State) { case running: // // mark as blocked so that it won't get scheduled again // Process->State = blocked; // // choose a different process to run // KepReschedule(); break; case ready: // in a ready queue KepDequeueProcess(Process); break; case blocked: // in a blocked list if (!KepRemoveFromProcessList(&KepTimerList, Process) && !KepRemoveFromProcessList(&KepBlockedList, Process)) { KeBugCheck("KeStopSchedulingProcess: process blocked, but in no blocked queue"); } break; default: KeBugCheck("KeStopSchedulingProcess: unhandled process state"); } // // object no longer in our queues -> dereference // ObDereferenceObject(Process); return STATUS_SUCCESS; }
void co_os_free_pages(void *ptr, unsigned int pages) { if (ptr == 0) KeBugCheck(0x11117777 + 1); if (pages == 0) KeBugCheck(0x11117777 + 2); #ifdef DEBUG_CO_OS_ALLOC co_debug_allocations("PAGE FREE %d(%u) - %p", allocs, pages, ptr); allocs--; #endif MmFreeNonCachedMemory(ptr, pages * CO_ARCH_PAGE_SIZE); }
VOID WRITE_REGISTER_ULONG( volatile PULONG Register, ULONG Value ) /*++ Routine Description: Write to the specified register address. Arguments: Register - Supplies a pointer to the register in EISA I/O space. Value - The value to be written to the register. Return Value: None --*/ { // // We are assuming that the longword is aligned // ASSERT(((ULONG)Register & 0x3) == 0x0); if (IS_EISA_QVA(Register)) { *(volatile PULONG)(EISA_LONG_LEN | ((ULONG)Register << EISA_BIT_SHIFT)) = Value; HalpMb; return; } // // ULONG operations are not supported on the combo chip // if (IS_COMBO_QVA(Register)) { KeBugCheck("Invalid Combo QVA in WRITE_REGISTER_ULONG\n"); } KeBugCheck("Invalid QVA in WRITE_REGISTER_ULONG\n"); }
/** Reverses all operations recorded in the stacked memory object. * * Reversing an operation means freeing memory the operation had allocated. * * @param StackedMemory Stacked memory object. * * @remark * If the stacked memory object contains no operation records, nothing happens. */ VOID StackedMemoryAllFree(PUTILS_STACK StackedMemory) { PUTILS_STACK_ITEM stackItem = NULL; PUTILS_STACKED_MEMORY_RECORD stackRecord = NULL; DEBUG_ENTER_FUNCTION("StackedMemory=0x%p", StackedMemory); while (!StackEmpty(StackedMemory)) { stackItem = StackPopNoFree(StackedMemory); stackRecord = CONTAINING_RECORD(stackItem, UTILS_STACKED_MEMORY_RECORD, StackItem); switch (stackRecord->AllocType) { case smatHeap: HeapMemoryFree(stackRecord->Address); break; case smatVirtual: VirtualMemoryFreeUser(stackRecord->Address); break; default: DEBUG_ERROR("Invalid stacked memory record type (%u)", stackRecord->AllocType); KeBugCheck(0); break; } HeapMemoryFree(stackRecord); } DEBUG_EXIT_FUNCTION_VOID(); return; }
NTSTATUS NTAPI MmMpwThreadMain(PVOID Ignored) { NTSTATUS Status; ULONG PagesWritten; LARGE_INTEGER Timeout; Timeout.QuadPart = -50000000; for(;;) { Status = KeWaitForSingleObject(&MpwThreadEvent, 0, KernelMode, FALSE, &Timeout); if (!NT_SUCCESS(Status)) { DbgPrint("MpwThread: Wait failed\n"); KeBugCheck(MEMORY_MANAGEMENT); return(STATUS_UNSUCCESSFUL); } PagesWritten = 0; #ifndef NEWCC // XXX arty -- we flush when evicting pages or destorying cache // sections. CcRosFlushDirtyPages(128, &PagesWritten); #endif } }
VOID NTAPI MmRebalanceMemoryConsumers(VOID) { LONG Target; ULONG i; ULONG NrFreedPages; NTSTATUS Status; Target = (MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired; Target = max(Target, (LONG) MiMinimumPagesPerRun); for (i = 0; i < MC_MAXIMUM && Target > 0; i++) { if (MiMemoryConsumers[i].Trim != NULL) { Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages); if (!NT_SUCCESS(Status)) { KeBugCheck(MEMORY_MANAGEMENT); } Target = Target - NrFreedPages; } } }
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity) { KAFFINITY OldAffinity; /* Get the current affinity */ OldAffinity = Thread->UserAffinity; /* Make sure that the affinity is valid */ if (((Affinity & Thread->ApcState.Process->Affinity) != (Affinity)) || (!Affinity)) { /* Bugcheck the system */ KeBugCheck(INVALID_AFFINITY_SET); } /* Update the new affinity */ Thread->UserAffinity = Affinity; /* Check if system affinity is disabled */ if (!Thread->SystemAffinityActive) { #ifdef CONFIG_SMP /* FIXME: TODO */ DPRINT1("Affinity support disabled!\n"); #endif } /* Return the old affinity */ return OldAffinity; }
/////////////////////////////////////////////////////////////////////////////// // // KepDequeueProcess // // Removes a process from the ready queue. // VOID KepDequeueProcess( PPROCESS Process ) { PPROCESS currentProcess; ASSERT(Process->Priority < PROCESS_PRIORITY_LEVELS); currentProcess = KepReadyQueues[Process->Priority].First; // // handle special case when Process is the first in the queue // if (currentProcess == Process) { // // (if the process was the only one in the queue, it's NextPCB is NULL // and that's enough for us - no need to check for this special case) // KepReadyQueues[Process->Priority].First = currentProcess->NextPCB; currentProcess->NextPCB = NULL; return; } // // find the process in the queue // while (currentProcess->NextPCB) { if (currentProcess->NextPCB == Process) { // // unlink process from the list // currentProcess->NextPCB = Process->NextPCB; // // handle special case when this process was the last on the list // if (KepReadyQueues[Process->Priority].Last == Process) { KepReadyQueues[Process->Priority].Last = currentProcess; } Process->NextPCB = NULL; return; } // // move to the next queue entry // currentProcess = currentProcess->NextPCB; } KeBugCheck("KepDequeueProcess: process is not in the priority queue"); }
ULONG NTAPI MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget) { ULONG Target = InitialTarget; ULONG NrFreedPages = 0; NTSTATUS Status; /* Make sure we can trim this consumer */ if (!MiMemoryConsumers[Consumer].Trim) { /* Return the unmodified initial target */ return InitialTarget; } if (MiMemoryConsumers[Consumer].PagesUsed > MiMemoryConsumers[Consumer].PagesTarget) { /* Consumer page limit exceeded */ Target = max(Target, MiMemoryConsumers[Consumer].PagesUsed - MiMemoryConsumers[Consumer].PagesTarget); } if (MmAvailablePages < MiMinimumAvailablePages) { /* Global page limit exceeded */ Target = (ULONG)max(Target, MiMinimumAvailablePages - MmAvailablePages); } if (Target) { if (!InitialTarget) { /* If there was no initial target, * swap at least MiMinimumPagesPerRun */ Target = max(Target, MiMinimumPagesPerRun); } /* Now swap the pages out */ Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages); DPRINT("Trimming consumer %lu: Freed %lu pages with a target of %lu pages\n", Consumer, NrFreedPages, Target); if (!NT_SUCCESS(Status)) { KeBugCheck(MEMORY_MANAGEMENT); } /* Update the target */ if (NrFreedPages < Target) Target -= NrFreedPages; else Target = 0; /* Return the remaining pages needed to meet the target */ return Target; } else { /* Initial target is zero and we don't have anything else to add */ return 0; } }
/////////////////////////////////////////////////////////////////////////////// // // KeResumeProcess // // Moves process from the blocked or sleeping list to the ready queue // and changes it's state to ready. // VOID KeResumeProcess( PPROCESS Process ) { ASSERT(Process); ASSERT(Process->State == blocked); if (Process->ResumeMethod) Process->ResumeMethod(Process); // // remove process from the blocked list // if (!KepRemoveFromProcessList(&KepTimerList, Process) && !KepRemoveFromProcessList(&KepBlockedList, Process)) { KeBugCheck("KeResumeProcess: process blocked, but in no blocked queue"); } // // add process to the scheduling queue // KepEnqueueProcess(Process); // // reschedule if this process has higher priority than the current process // if (Process->Priority > KeCurrentProcess->Priority) { KepReschedule(); } }
/////////////////////////////////////////////////////////////////////////////// // // KeChangeProcessPriority // // Changes the priority of specified process. // VOID KeChangeProcessPriority( PPROCESS Process, ULONG NewPriority ) { ASSERT(Process); ASSERT(NewPriority < PROCESS_PRIORITY_LEVELS); switch (Process->State) { case running: case blocked: Process->Priority = NewPriority; break; case ready: KepDequeueProcess(Process); Process->Priority = NewPriority; KepEnqueueProcess(Process); break; default: KeBugCheck("KeChangeProcessPriority: unhandled process state"); } }
VOID NTAPI PspSystemThreadStartup(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext) { PETHREAD Thread; PSTRACE(PS_THREAD_DEBUG, "StartRoutine: %p StartContext: %p\n", StartRoutine, StartContext); /* Unlock the dispatcher Database */ KeLowerIrql(PASSIVE_LEVEL); Thread = PsGetCurrentThread(); /* Make sure the thread isn't gone */ _SEH2_TRY { if (!(Thread->Terminated) && !(Thread->DeadThread)) { /* Call the Start Routine */ StartRoutine(StartContext); } } _SEH2_EXCEPT(PspUnhandledExceptionInSystemThread(_SEH2_GetExceptionInformation())) { /* Bugcheck if we got here */ KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); } _SEH2_END; /* Exit the thread */ PspTerminateThreadByPointer(Thread, STATUS_SUCCESS, TRUE); }
VOID NTAPI CcScheduleReadAhead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length) { PWORK_QUEUE_WITH_READ_AHEAD WorkItem; DPRINT("Schedule read ahead %08x%08x:%x %wZ\n", FileOffset->HighPart, FileOffset->LowPart, Length, &FileObject->FileName); WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem)); if (!WorkItem) KeBugCheck(0); ObReferenceObject(FileObject); WorkItem->FileObject = FileObject; WorkItem->FileOffset = *FileOffset; WorkItem->Length = Length; ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem); ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue); DPRINT("Done\n"); }
/*++ * @name FsRtlDeleteTunnelCache * @unimplemented * * FILLME * * @param Cache * FILLME * * @return None * * @remarks None * *--*/ VOID NTAPI FsRtlInitializeTunnelCache(IN PTUNNEL Cache) { /* Unimplemented */ KeBugCheck(FILE_SYSTEM); }
/** Unlocks a given bucket of a general hash table. * * @param Table A hash table the bucket of which is to be unlocked. * @param Index A zero-based index of the bucked to unlock. * @param Irql A value of IRQL the caller had been running before the table * was locked. The parameter is ignored for passive IRQL tables and tables access * to whom is not synchronized. * * @remark * If access to the table is not synchronized, the routine performs nothing. * * The @link(HASH_TABLE_IRQL_VALIDATE) is used to check whether the caller * runs at a valid IRQL. */ static VOID HashTableUnlock(PHASH_TABLE Table, ULONG32 Index, KIRQL Irql) { HASH_TABLE_IRQL_VALIDATE(Table); ASSERT(Index < Table->Size); switch (Table->Type) { case httPassiveLevel: ExReleaseResourceLite(&Table->Locks[Index]); KeLeaveCriticalRegion(); break; case httDispatchLevel: if (Table->DispatchLockExclusive[Index]) { Table->DispatchLockExclusive[Index] = FALSE; KeReleaseSpinLock(&Table->DispatchLocks[Index], Irql); } else { KeReleaseSpinLock(&Table->DispatchLocks[Index], Irql); } break; case httNoSynchronization: break; default: DEBUG_ERROR("Invalid hash table type: %u", Table->Type); KeBugCheck(0); break; } return; }
ULONG READ_REGISTER_ULONG( volatile PULONG Register ) /*++ Routine Description: Read from the specified register address. Arguments: Register - Supplies a pointer to the register in EISA I/O space. Return Value: Returns the value read from the specified register address. --*/ { // // We are assuming that the longword is aligned // ASSERT(((ULONG)Register & 0x3) == 0x0); if (IS_EISA_QVA(Register)) { HalpMb; return (*(volatile PULONG)(EISA_LONG_LEN | ((ULONG)Register << EISA_BIT_SHIFT))); } // // ULONG operations are not supported on the combo chip // if (IS_COMBO_QVA(Register)) { KeBugCheck("Invalid Combo QVA in READ_REGISTER_ULONG\n"); } KeBugCheck("Invalid QVA in READ_REGISTER_ULONG\n"); }
/*++ * @name FsRtlDeleteKeyFromTunnelCache * @unimplemented * * FILLME * * @param Cache * FILLME * * @param DirectoryKey * FILLME * * @return None * * @remarks None * *--*/ VOID NTAPI FsRtlDeleteKeyFromTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey) { /* Unimplemented */ KeBugCheck(FILE_SYSTEM); }
/* * @implemented */ PFILE_LOCK_INFO NTAPI FsRtlGetNextFileLock(IN PFILE_LOCK FileLock, IN BOOLEAN Restart) { KeBugCheck(FILE_SYSTEM); return NULL; }
/* * @implemented */ BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp) { KeBugCheck(FILE_SYSTEM); return FALSE; }
VOID KepReschedule( VOID ) { LONG i; // // look for a process with higher priority than the current one // (but if current process got blocked, don't limit the search) // LONG bottomPriority = (KeCurrentProcess->State == blocked) ? 0 : (LONG)KeCurrentProcess->Priority; // // scan the ready queue and find the first non-empty slot // for (i = PROCESS_PRIORITY_LEVELS - 1; i >= bottomPriority; i--) { // // is the queue non-empty? // if (KepReadyQueues[i].First) { // // if the current process is not blocked, add it to ready queue // (if it's blocked, someone else already put it where it belongs) // if (KeCurrentProcess->State != blocked) { KepEnqueueProcess(KeCurrentProcess); } // // lets schedule the first process in this queue // KeCurrentProcess = KepReadyQueues[i].First; KepDequeueProcess(KeCurrentProcess); break; } } // // if no process could be scheduled, someone killed process 0 - too bad! // if (KeCurrentProcess->State == blocked) KeBugCheck("Critical system process terminated or blocked unexpectedly"); // // reset quantum for this process // KeCurrentProcess->Quantum = 5; // // set state to running // KeCurrentProcess->State = running; }
void __CRTDECL operator delete[](void *) throw() { NETKVM_ASSERT(FALSE); #ifdef DBG #pragma warning (push) #pragma warning (disable:28159) KeBugCheck(100); #pragma warning (pop) #endif }
/* * @implemented */ NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL) { KeBugCheck(FILE_SYSTEM); return STATUS_UNSUCCESSFUL; }
void __CRTDECL operator delete(void *, unsigned int) throw() { ASSERT(FALSE); #ifdef DBG #pragma warning (push) #pragma warning (disable:28159) KeBugCheck(100); #pragma warning (pop) #endif }
VOID ObpUnlinkObjectFromTypeList( POBJECT_HEADER objectHeader ) { POBJECT_HEADER currentObject; ASSERT_OBJECT(objectHeader); // // make sure object has a type associated // ASSERT(objectHeader->Type); // // get the head of the list // currentObject = objectHeader->Type->FirstObjectOfType; // // handle special case when first object is the object being removed // if (currentObject == objectHeader) { objectHeader->Type->FirstObjectOfType = currentObject->NextObjectOfType; return; } // // walk the list of objects with this type // while (currentObject) { // // check to see if following object is the object to be unlinked // if (currentObject->NextObjectOfType == objectHeader) { // // unlink it // currentObject->NextObjectOfType = objectHeader->NextObjectOfType; return; } // // move to the next list entry // currentObject = currentObject->NextObjectOfType; } // // object was not in the list, crash // KeBugCheck("ObpUnlinkObjectFromTypeList: object was not in the list"); }
VOID MsDereferenceNode ( IN PNODE_HEADER NodeHeader ) /*++ Routine Description: This routine dereferences a generic mailslot block. It figures out the type of block this is, and calls the appropriate worker function. Arguments: NodeHeader - A pointer to a generic mailslot block header. Return Value: None --*/ { PAGED_CODE(); switch ( NodeHeader->NodeTypeCode ) { case MSFS_NTC_VCB: MsDereferenceVcb( (PVCB)NodeHeader ); break; case MSFS_NTC_ROOT_DCB: MsDereferenceRootDcb( (PROOT_DCB)NodeHeader ); break; case MSFS_NTC_FCB: MsDereferenceFcb( (PFCB)NodeHeader ); break; case MSFS_NTC_CCB: case MSFS_NTC_ROOT_DCB_CCB: MsDereferenceCcb( (PCCB)NodeHeader ); break; default: // // This block is not one of ours. // KeBugCheck( MAILSLOT_FILE_SYSTEM ); } return; }
VOID NTAPI PspDeleteThread(IN PVOID ObjectBody) { PETHREAD Thread = (PETHREAD)ObjectBody; PEPROCESS Process = Thread->ThreadsProcess; PAGED_CODE(); PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody); PSREFTRACE(Thread); ASSERT(Thread->Tcb.Win32Thread == NULL); /* Check if we have a stack */ if (Thread->Tcb.InitialStack) { /* Release it */ MmDeleteKernelStack((PVOID)Thread->Tcb.StackBase, Thread->Tcb.LargeStack); } /* Check if we have a CID Handle */ if (Thread->Cid.UniqueThread) { /* Delete the CID Handle */ if (!(ExDestroyHandle(PspCidTable, Thread->Cid.UniqueThread, NULL))) { /* Something wrong happened, bugcheck */ KeBugCheck(CID_HANDLE_DELETION); } } /* Cleanup impersionation information */ PspDeleteThreadSecurity(Thread); /* Make sure the thread was inserted, before continuing */ if (!Process) return; /* Check if the thread list is valid */ if (Thread->ThreadListEntry.Flink) { /* Lock the thread's process */ KeEnterCriticalRegion(); ExAcquirePushLockExclusive(&Process->ProcessLock); /* Remove us from the list */ RemoveEntryList(&Thread->ThreadListEntry); /* Release the lock */ ExReleasePushLockExclusive(&Process->ProcessLock); KeLeaveCriticalRegion(); } /* Dereference the Process */ ObDereferenceObject(Process); }
void co_os_free(void *ptr) { #ifdef DEBUG_CO_OS_ALLOC co_debug_allocations("MEM FREE %d - %p", allocs, ptr); allocs--; #endif if (ptr == 0) KeBugCheck(0x11117777 + 4); ExFreePoolWithTag(ptr, CO_OS_POOL_TAG); }
BOOLEAN HalHandleNMI( IN PKINTERRUPT Interrupt, IN PVOID ServiceContext ) /*++ Routine Description: This function is called when an EISA NMI occurs. It print the appropriate status information and bugchecks. Arguments: Interrupt - Supplies a pointer to the interrupt object ServiceContext - Bug number to call bugcheck with. Return Value: Returns TRUE. --*/ { UCHAR StatusByte; #ifdef IDLE_PROCESSOR // // Clear interrupt flag // HalpInterruptReceived = 0; #endif StatusByte = READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus); if (StatusByte & 0x80) { HalDisplayString ("NMI: Parity Check / Parity Error\n"); } if (StatusByte & 0x40) { HalDisplayString ("NMI: Channel Check / IOCHK\n"); } // // This is an Sio machine, no extnded nmi information, so just do it. // KeBugCheck(NMI_HARDWARE_FAILURE); return(TRUE); }
/* * @implemented */ BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process) { KeBugCheck(FILE_SYSTEM); return FALSE; }
/*++ * @name FsRtlAddToTunnelCache * @unimplemented * * FILLME * * @param Cache * FILLME * * @param DirectoryKey * FILLME * * @param ShortName * FILLME * * @param LongName * FILLME * * @param KeyByShortName * FILLME * * @param DataLength * FILLME * * @param Data * FILLME * * @return None * * @remarks None * *--*/ VOID NTAPI FsRtlAddToTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING ShortName, IN PUNICODE_STRING LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN PVOID Data) { /* Unimplemented */ KeBugCheck(FILE_SYSTEM); }