VOID FsRtlStackOverflowRead ( IN PVOID Context ) /*++ Routine Description: This routine processes all of the stack overflow request posted by the various file systems Arguments: Return Value: None. --*/ { PSTACK_OVERFLOW_ITEM StackOverflowItem; // // Since stack overflow reads are always recursive, set the // TopLevelIrp field appropriately so that recursive reads // from this point will not think they are top level. // PsGetCurrentThread()->TopLevelIrp = FSRTL_FSP_TOP_LEVEL_IRP; // // Get a pointer to the stack overflow item and then call // the callback routine to do the work // StackOverflowItem = (PSTACK_OVERFLOW_ITEM)Context; (StackOverflowItem->StackOverflowRoutine)(StackOverflowItem->Context, StackOverflowItem->Event); // // Deallocate the work item, or simply return the serial item. // if (StackOverflowItem == &StackOverflowFallback) { KeSetEvent( &StackOverflowFallbackSerialEvent, 0, FALSE ); } else { ExFreePool( StackOverflowItem ); } PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)NULL; }
POWNER_ENTRY DLDpFindCurrentThread( IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread ) { if (Resource->OwnerThreads[0].OwnerThread == Thread) return &(Resource->OwnerThreads[0]); if (Resource->OwnerThreads[1].OwnerThread == Thread) return &(Resource->OwnerThreads[1]); POWNER_ENTRY LastEntry, CurrentEntry, FirstEmptyEntry = NULL; if (!(Resource->OwnerThreads[1].OwnerThread)) FirstEmptyEntry = &(Resource->OwnerThreads[1]); CurrentEntry = Resource->OwnerTable; LastEntry = &(Resource->OwnerTable[Resource->OwnerThreads[0].TableSize]); while (CurrentEntry != LastEntry) { if (CurrentEntry->OwnerThread == Thread) { PCHAR CurrentThread = (PCHAR)PsGetCurrentThread(); *((PULONG)(CurrentThread + 0x136)) = CurrentEntry - Resource->OwnerTable; return CurrentEntry; } if (!(CurrentEntry->OwnerThread)) { FirstEmptyEntry = CurrentEntry; } CurrentEntry++; } if (FirstEmptyEntry) { PCHAR CurrentThread = (PCHAR)PsGetCurrentThread(); *((PULONG)(CurrentThread + 0x136)) = FirstEmptyEntry - Resource->OwnerTable; return FirstEmptyEntry; } else { // Grow OwnerTable USHORT OldSize = Resource->OwnerThreads[0].TableSize; USHORT NewSize = 3; if (OldSize) NewSize = OldSize + 4; POWNER_ENTRY NewEntry = (POWNER_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(OWNER_ENTRY)*NewSize,RESOURCE_TABLE_TAG); RtlZeroMemory(NewEntry,sizeof(OWNER_ENTRY)*NewSize); if (Resource->OwnerTable) { RtlMoveMemory(NewEntry,Resource->OwnerTable,sizeof(OWNER_ENTRY)*OldSize); ExFreePool(Resource->OwnerTable); } Resource->OwnerTable = NewEntry; PCHAR CurrentThread = (PCHAR)PsGetCurrentThread(); *((PULONG)(CurrentThread + 0x136)) = OldSize; Resource->OwnerThreads[0].TableSize = NewSize; return &(NewEntry[OldSize]); } }
VOID FsRtlStackOverflowRead ( IN PVOID Context ) /*++ Routine Description: This routine processes all of the stack overflow request posted by the various file systems Arguments: Return Value: None. --*/ { PSTACK_OVERFLOW_ITEM StackOverflowItem; // // Since stack overflow reads are always recursive, set the // TopLevelIrp field appropriately so that recurive reads // from this point will not think they are top level. // PsGetCurrentThread()->TopLevelIrp = FSRTL_FSP_TOP_LEVEL_IRP; // // Get a pointer to the stack overflow item and then call // the callback routine to do the work // StackOverflowItem = (PSTACK_OVERFLOW_ITEM)Context; (StackOverflowItem->StackOverflowRoutine)(StackOverflowItem->Context, StackOverflowItem->Event); // // Deallocate the work item and then go back to the loop to // to wait for another work item // ExFreePool( StackOverflowItem ); PsGetCurrentThread()->TopLevelIrp = (ULONG)NULL; }
/* * @implemented */ NTSTATUS NTAPI SeImpersonateClientEx(IN PSECURITY_CLIENT_CONTEXT ClientContext, IN PETHREAD ServerThread OPTIONAL) { BOOLEAN EffectiveOnly; PAGED_CODE(); if (ClientContext->DirectlyAccessClientToken == FALSE) { EffectiveOnly = ClientContext->SecurityQos.EffectiveOnly; } else { EffectiveOnly = ClientContext->DirectAccessEffectiveOnly; } if (ServerThread == NULL) { ServerThread = PsGetCurrentThread(); } return PsImpersonateClient(ServerThread, ClientContext->ClientToken, TRUE, EffectiveOnly, ClientContext->SecurityQos.ImpersonationLevel); }
BOOLEAN AFSIs64BitProcess( IN ULONGLONG ProcessId) { NTSTATUS ntStatus = STATUS_SUCCESS; BOOLEAN bIs64Bit = FALSE; AFSProcessCB *pProcessCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; __Enter { AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSIs64BitProcess Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n", pDeviceExt->Specific.Control.ProcessTree.TreeLock, PsGetCurrentThread())); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)ProcessId, (AFSBTreeEntry **)&pProcessCB); if( pProcessCB != NULL) { bIs64Bit = BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); } AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); } return bIs64Bit; }
BOOLEAN APIENTRY DxEngIsHdevLockedByCurrentThread(HDEV hDev) { // Based on EngIsSemaphoreOwnedByCurrentThread w/o the Ex call. PERESOURCE pSem = (PERESOURCE)(((PPDEVOBJ)hDev)->hsemDevLock); return pSem->OwnerEntry.OwnerThread == (ERESOURCE_THREAD)PsGetCurrentThread(); }
/* Changing the thread context should be done from within the thread */ VOID changeTrapFlagForThreadAPC( IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2 ) { int isSetTheFlag = (int)Apc->SystemArgument1; KEVENT * operationComplete = (KEVENT *)Apc->SystemArgument2; UNREFERENCED_PARAMETER(NormalRoutine); UNREFERENCED_PARAMETER(NormalContext); UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); PAGED_CODE(); ADDRESS ethread = (ADDRESS)PsGetCurrentThread(); if (0 == isSetTheFlag) { changeTrapFlag(ethread, 0); } else { changeTrapFlag(ethread, 1); } KeSetEvent(operationComplete, 0, FALSE); }
/* * @implemented */ NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage) { NTSTATUS Status; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); PORT_MESSAGE CapturedReplyMessage; PLPCP_PORT_OBJECT Port; PLPCP_MESSAGE Message; PETHREAD Thread = PsGetCurrentThread(), WakeupThread; PAGED_CODE(); LPCTRACE(LPC_REPLY_DEBUG, "Handle: %p. Message: %p.\n", PortHandle, ReplyMessage); /* Check if the call comes from user mode */ if (PreviousMode != KernelMode) { _SEH2_TRY { ProbeForRead(ReplyMessage, sizeof(*ReplyMessage), sizeof(ULONG)); CapturedReplyMessage = *(volatile PORT_MESSAGE*)ReplyMessage; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }
/* * @implemented */ NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage) { PLPCP_PORT_OBJECT Port; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status; PLPCP_MESSAGE Message; PETHREAD Thread = PsGetCurrentThread(), WakeupThread; //PORT_MESSAGE CapturedReplyMessage; PAGED_CODE(); LPCTRACE(LPC_REPLY_DEBUG, "Handle: %p. Message: %p.\n", PortHandle, ReplyMessage); if (KeGetPreviousMode() == UserMode) { _SEH2_TRY { ProbeForRead(ReplyMessage, sizeof(PORT_MESSAGE), sizeof(ULONG)); /*RtlCopyMemory(&CapturedReplyMessage, ReplyMessage, sizeof(PORT_MESSAGE)); ReplyMessage = &CapturedReplyMessage;*/ } _SEH2_EXCEPT(ExSystemExceptionFilter()) { DPRINT1("SEH crash [1]\n"); DbgBreakPoint(); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; if (Window) ASSERT_REFS_CO(Window); if(Window && Window->head.pti->pEThread != PsGetCurrentThread()) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } if(ThreadQueue->CaretInfo->Visible) { PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd); IntKillTimer(pwnd, IDCARETTIMER, TRUE); co_IntHideCaret(ThreadQueue->CaretInfo); ThreadQueue->CaretInfo->Visible = 0; ThreadQueue->CaretInfo->Showing = 0; } return TRUE; }
NTSTATUS PsLookupProcessByProcessId( __in HANDLE ProcessId, __deref_out PEPROCESS *Process ) /*++ Routine Description: This function accepts the process id of a process and returns a referenced pointer to the process. Arguments: ProcessId - Specifies the Process ID of the process. Process - Returns a referenced pointer to the process specified by the process id. Return Value: STATUS_SUCCESS - A process was located based on the contents of the process id. STATUS_INVALID_PARAMETER - The process was not found. --*/ { PHANDLE_TABLE_ENTRY CidEntry; PEPROCESS lProcess; PETHREAD CurrentThread; NTSTATUS Status; PAGED_CODE(); Status = STATUS_INVALID_PARAMETER; CurrentThread = PsGetCurrentThread (); KeEnterCriticalRegionThread (&CurrentThread->Tcb); CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId); if (CidEntry != NULL) { lProcess = (PEPROCESS)CidEntry->Object; if (lProcess->Pcb.Header.Type == ProcessObject && lProcess->GrantedAccess != 0) { if (ObReferenceObjectSafe(lProcess)) { *Process = lProcess; Status = STATUS_SUCCESS; } } ExUnlockHandleTableEntry(PspCidTable, CidEntry); } KeLeaveCriticalRegionThread (&CurrentThread->Tcb); return Status; }
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); }
NTSTATUS OcTplTestFuncParam10( IN ULONG_PTR Param1, IN ULONG_PTR Param2, IN ULONG_PTR Param3, IN ULONG_PTR Param4, IN ULONG_PTR Param5, IN ULONG_PTR Param6, IN ULONG_PTR Param7, IN ULONG_PTR Param8, IN ULONG_PTR Param9, IN ULONG_PTR Param10 ) { g_FunctionCalled[ 0xA ] = TRUE; DbgPrint(" ThreadpoolTest: OcTplTestFuncParam10 Thread = 0x%ph \n", PsGetCurrentThread() ); OC_TPL_CHECK_PARAMETER( 1 ) OC_TPL_CHECK_PARAMETER( 2 ) OC_TPL_CHECK_PARAMETER( 3 ) OC_TPL_CHECK_PARAMETER( 4 ) OC_TPL_CHECK_PARAMETER( 5 ) OC_TPL_CHECK_PARAMETER( 6 ) OC_TPL_CHECK_PARAMETER( 7 ) OC_TPL_CHECK_PARAMETER( 8 ) OC_TPL_CHECK_PARAMETER( 9 ) OC_TPL_CHECK_PARAMETER( 10 ) Sleep(300); return STATUS_SUCCESS; }
NTSTATUS NTAPI MiCreatePebOrTeb(IN PEPROCESS Process, IN ULONG Size, OUT PULONG_PTR Base) { PETHREAD Thread = PsGetCurrentThread(); PMMVAD_LONG Vad; NTSTATUS Status; ULONG RandomCoeff; ULONG_PTR StartAddress, EndAddress; LARGE_INTEGER CurrentTime; TABLE_SEARCH_RESULT Result = TableFoundNode; PMMADDRESS_NODE Parent; /* Allocate a VAD */ Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV'); if (!Vad) return STATUS_NO_MEMORY; /* Setup the primary flags with the size, and make it commited, private, RW */ Vad->u.LongFlags = 0; Vad->u.VadFlags.CommitCharge = BYTES_TO_PAGES(Size); Vad->u.VadFlags.MemCommit = TRUE; Vad->u.VadFlags.PrivateMemory = TRUE; Vad->u.VadFlags.Protection = MM_READWRITE; Vad->u.VadFlags.NoChange = TRUE; /* Setup the secondary flags to make it a secured, writable, long VAD */ Vad->u2.LongFlags2 = 0; Vad->u2.VadFlags2.OneSecured = TRUE; Vad->u2.VadFlags2.LongVad = TRUE; Vad->u2.VadFlags2.ReadOnly = FALSE; /* Lock the process address space */ KeAcquireGuardedMutex(&Process->AddressCreationLock); /* Check if this is a PEB creation */ if (Size == sizeof(PEB)) { /* Start at the highest valid address */ StartAddress = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1; /* Select the random coefficient */ KeQueryTickCount(&CurrentTime); CurrentTime.LowPart &= ((64 * _1KB) >> PAGE_SHIFT) - 1; if (CurrentTime.LowPart <= 1) CurrentTime.LowPart = 2; RandomCoeff = CurrentTime.LowPart << PAGE_SHIFT; /* Select the highest valid address minus the random coefficient */ StartAddress -= RandomCoeff; EndAddress = StartAddress + ROUND_TO_PAGES(Size) - 1; /* Try to find something below the random upper margin */ Result = MiFindEmptyAddressRangeDownTree(ROUND_TO_PAGES(Size), EndAddress, PAGE_SIZE, &Process->VadRoot, Base, &Parent); }
VOID KernelKillThreadRoutine( __in PKAPC Apc, __in __out PKNORMAL_ROUTINE* NormalRoutine, __in __out PVOID* NormalContext, __in __out PVOID* SystemArgument1, __in __out PVOID* SystemArgument2 ) { PULONG ThreadFlags = NULL; UNREFERENCED_PARAMETER(Apc); UNREFERENCED_PARAMETER(NormalRoutine); UNREFERENCED_PARAMETER(NormalContext); UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); BDKitFreePool(Apc); //ETHREAD中CrossThreadFlags的偏移量为0x248 ThreadFlags=(PULONG)((ULONG)PsGetCurrentThread()+0x248); if( MmIsAddressValid(ThreadFlags) ) { *ThreadFlags |= PS_CROSS_THREAD_FLAGS_SYSTEM; //(*PspExitThread_XP)(STATUS_SUCCESS);//PspExitThread不可用,需要自己定位 PsTerminateSystemThread (STATUS_SUCCESS); } }
VOID NTAPI LpcExitThread(IN PETHREAD Thread) { PLPCP_MESSAGE Message; ASSERT(Thread == PsGetCurrentThread()); /* Acquire the lock */ KeAcquireGuardedMutex(&LpcpLock); /* Make sure that the Reply Chain is empty */ if (!IsListEmpty(&Thread->LpcReplyChain)) { /* It's not, remove the entry */ RemoveEntryList(&Thread->LpcReplyChain); } /* Set the thread in exit mode */ Thread->LpcExitThreadCalled = TRUE; Thread->LpcReplyMessageId = 0; /* Check if there's a reply message */ Message = LpcpGetMessageFromThread(Thread); if (Message) { /* FIXME: TODO */ ASSERT(FALSE); } /* Release the lock */ KeReleaseGuardedMutex(&LpcpLock); }
VOID DLDAcquireExclusive(PERESOURCE Resource, ULONG BugCheckId, ULONG Line ) { KIRQL oldIrql; KeAcquireSpinLock(&Resource->SpinLock, &oldIrql); ERESOURCE_THREAD Thread = (ERESOURCE_THREAD)PsGetCurrentThread(); if (!Resource->ActiveCount) goto SimpleAcquire; if ((Resource->Flag & ResourceOwnedExclusive) && Resource->OwnerThreads[0].OwnerThread == Thread) { Resource->OwnerThreads[0].OwnerCount++; KeReleaseSpinLock(&Resource->SpinLock, oldIrql); return; } DLDpAcquireResourceExclusiveLite(Resource, Thread, oldIrql,BugCheckId,Line); return; SimpleAcquire: Resource->Flag |= ResourceOwnedExclusive; Resource->ActiveCount = 1; Resource->OwnerThreads[0].OwnerThread = Thread; Resource->OwnerThreads[0].OwnerCount = 1; KeReleaseSpinLock(&Resource->SpinLock, oldIrql); }
/* * @unimplemented */ DWORD_PTR APIENTRY NtUserCallNoParam(DWORD Routine) { DWORD_PTR Result = 0; DECLARE_RETURN(DWORD_PTR); TRACE("Enter NtUserCallNoParam\n"); UserEnterExclusive(); switch(Routine) { case NOPARAM_ROUTINE_CREATEMENU: Result = (DWORD_PTR)UserCreateMenu(FALSE); break; case NOPARAM_ROUTINE_CREATEMENUPOPUP: Result = (DWORD_PTR)UserCreateMenu(TRUE); break; case NOPARAM_ROUTINE_DESTROY_CARET: Result = (DWORD_PTR)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread); break; case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP: Result = (DWORD_PTR)IntInitMessagePumpHook(); break; case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP: Result = (DWORD_PTR)IntUninitMessagePumpHook(); break; case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO: Result = (DWORD_PTR)MsqGetMessageExtraInfo(); break; case NOPARAM_ROUTINE_MSQCLEARWAKEMASK: RETURN( (DWORD_PTR)IntMsqClearWakeMask()); case NOPARAM_ROUTINE_GETMSESSAGEPOS: { PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); RETURN( (DWORD_PTR)MAKELONG(pti->ptLast.x, pti->ptLast.y)); } case NOPARAM_ROUTINE_RELEASECAPTURE: RETURN( (DWORD_PTR)IntReleaseCapture()); default: ERR("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine); EngSetLastError(ERROR_INVALID_PARAMETER); break; } RETURN(Result); CLEANUP: TRACE("Leave NtUserCallNoParam, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; PWND pWnd = NULL; if (Window) ASSERT_REFS_CO(Window); if(Window && Window->head.pti->pEThread != PsGetCurrentThread()) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } if (!ThreadQueue->CaretInfo->Visible) { ThreadQueue->CaretInfo->Visible = 1; pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo->hWnd); if (!ThreadQueue->CaretInfo->Showing && pWnd) { IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0); } IntSetTimer(pWnd, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc, TMRF_SYSTEM); } return TRUE; }
NTSTATUS CfixkrpSetCurrentFilament( __in PCFIXKRP_FILAMENT_REGISTRY Registry, __in PCFIXKRP_FILAMENT Filament ) { PJPHT_HASHTABLE_ENTRY OldEntry; KIRQL OldIrql; PCFIXKRP_FILAMENT_ENTRY Entry; ASSERT( Registry ); ASSERT( Filament ); ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); Entry = ExAllocatePoolWithTag( NonPagedPool, sizeof( CFIXKRP_FILAMENT_ENTRY ), CFIXKR_POOL_TAG ); if ( Entry == NULL ) { return STATUS_NO_MEMORY; } if ( CfixkrGetCurrentThreadId() != Filament->MainThreadId ) { // // This is not the main thread - so register as child thread. // NTSTATUS Status = CfixkrsRegisterChildThreadFilament( Filament, PsGetCurrentThread() ); if ( ! NT_SUCCESS( Status ) ) { ExFreePoolWithTag( Entry, CFIXKR_POOL_TAG ); return Status; } } // // Assign the filament to the current thread. // Entry->Key.Thread = KeGetCurrentThread(); Entry->Filament = Filament; CfixkrsAcquireLockFilamentRegistry( Registry, &OldIrql ); JphtPutEntryHashtable( &Registry->Table, &Entry->Key.HashtableEntry, &OldEntry ); CfixkrsReleaseLockFilamentRegistry( Registry, OldIrql ); // // If OldEntry != NULL, we must have enetered a recusion, which // should not occur. // ASSERT( OldEntry == NULL ); return STATUS_SUCCESS; }
VOID NTAPI ExSwapinWorkerThreads(IN BOOLEAN AllowSwap) { KEVENT Event; PETHREAD CurrentThread = PsGetCurrentThread(), Thread; PEPROCESS Process = PsInitialSystemProcess; KAPC Apc; PAGED_CODE(); /* Initialize an event so we know when we're done */ KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Lock this routine */ ExAcquireFastMutex(&ExpWorkerSwapinMutex); /* New threads cannot swap anymore */ ExpWorkersCanSwap = AllowSwap; /* Loop all threads in the system process */ Thread = PsGetNextProcessThread(Process, NULL); while (Thread) { /* Skip threads with explicit permission to do this */ if (Thread->ExWorkerCanWaitUser) goto Next; /* Check if we reached ourselves */ if (Thread == CurrentThread) { /* Do it inline */ KeSetKernelStackSwapEnable(AllowSwap); } else { /* Queue an APC */ KeInitializeApc(&Apc, &Thread->Tcb, InsertApcEnvironment, ExpSetSwappingKernelApc, NULL, NULL, KernelMode, &AllowSwap); if (KeInsertQueueApc(&Apc, &Event, NULL, 3)) { /* Wait for the APC to run */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeClearEvent(&Event); } } /* Next thread */ Next: Thread = PsGetNextProcessThread(Process, Thread); } /* Release the lock */ ExReleaseFastMutex(&ExpWorkerSwapinMutex); }
//little bit another kind of hook -virtualization-based- :P EXTERN_C void* RdmsrHook( __inout ULONG_PTR* reg ) { void* ret = (void*)reg[RCX]; DbgPrint("\nRdmsrHook %p [pethread : %p]\n", ret, PsGetCurrentThread()); reg[RCX] = IA64_SYSENTER_EIP; KeBreak(); return ret; }
VOID CdRaiseStatusEx ( _In_ PIRP_CONTEXT IrpContext, _In_ NTSTATUS Status, _In_ BOOLEAN NormalizeStatus, _In_opt_ ULONG FileId, _In_opt_ ULONG Line ) { BOOLEAN BreakIn = FALSE; AssertVerifyDevice( IrpContext, Status); if (CdTraceRaises) { DbgPrint( "%p CdRaiseStatusEx 0x%x @ fid %d, line %d\n", PsGetCurrentThread(), Status, FileId, Line); } if (CdTestRaisedStatus && !CdBreakOnAnyRaise) { ULONG Index; for (Index = 0; Index < (sizeof( CdInterestingExceptionCodes) / sizeof( CdInterestingExceptionCodes[0])); Index++) { if ((STATUS_SUCCESS != CdInterestingExceptionCodes[Index]) && (CdInterestingExceptionCodes[Index] == Status)) { BreakIn = TRUE; break; } } } if (BreakIn || CdBreakOnAnyRaise) { DbgPrint( "CDFS: Breaking on raised status %08x (BI=%d,BA=%d)\n", Status, BreakIn, CdBreakOnAnyRaise); DbgPrint( "CDFS: (FILEID %d LINE %d)\n", FileId, Line); DbgPrint( "CDFS: Contact CDFS.SYS component owner for triage.\n"); DbgPrint( "CDFS: 'eb %p 0;eb %p 0' to disable this alert.\n", &CdTestRaisedStatus, &CdBreakOnAnyRaise); NT_ASSERT(FALSE); } if (NormalizeStatus) { IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR); } else { IrpContext->ExceptionStatus = Status; } IrpContext->RaisedAtLineFile = (FileId << 16) | Line; ExRaiseStatus( IrpContext->ExceptionStatus); }
NTSTATUS NTAPI MmNotPresentFaultCacheSection(KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl) { PETHREAD Thread; PMMSUPPORT AddressSpace; NTSTATUS Status; Address &= ~(PAGE_SIZE - 1); DPRINT("MmNotPresentFault(Mode %d, Address %Ix)\n", Mode, Address); Thread = PsGetCurrentThread(); if (KeGetCurrentIrql() >= DISPATCH_LEVEL) { DPRINT1("Page fault at high IRQL %u, address %Ix\n", KeGetCurrentIrql(), Address); ASSERT(FALSE); return STATUS_UNSUCCESSFUL; } /* Find the memory area for the faulting address */ if (Address >= (ULONG_PTR)MmSystemRangeStart) { /* Check permissions */ if (Mode != KernelMode) { DPRINTC("Address: %x\n", Address); return STATUS_ACCESS_VIOLATION; } AddressSpace = MmGetKernelAddressSpace(); } else { AddressSpace = &PsGetCurrentProcess()->Vm; } Thread->ActiveFaultCount++; Status = MmNotPresentFaultCacheSectionInner(Mode, AddressSpace, Address, FromMdl, Thread); Thread->ActiveFaultCount--; ASSERT(Status != STATUS_UNSUCCESSFUL); ASSERT(Status != STATUS_INVALID_PARAMETER); DPRINT("MmAccessFault %p:%Ix -> %x\n", MmGetAddressSpaceOwner(AddressSpace), Address, Status); return Status; }
VOID ExpShutdownWorker ( IN PVOID Parameter ) { PETHREAD CurrentThread; PSHUTDOWN_WORK_ITEM ShutdownItem; ShutdownItem = (PSHUTDOWN_WORK_ITEM) Parameter; ASSERT (ShutdownItem != NULL); if (ShutdownItem->PrevThread != NULL) { // // Wait for the previous thread to exit -- if it's in the same // queue, it probably has already, but we need to make sure // (and if it's not, we *definitely* need to make sure). // KeWaitForSingleObject (ShutdownItem->PrevThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject (ShutdownItem->PrevThread); ShutdownItem->PrevThread = NULL; } // // Decrement the worker count. // InterlockedDecrement (&ExWorkerQueue[ShutdownItem->QueueType].Info.QueueWorkerInfo); CurrentThread = PsGetCurrentThread(); if ((!ExpCheckQueueShutdown(DelayedWorkQueue, ShutdownItem)) && (!ExpCheckQueueShutdown(CriticalWorkQueue, ShutdownItem))) { // // We're the last worker to exit // ASSERT (!ExpLastWorkerThread); ExpLastWorkerThread = CurrentThread; ObReferenceObject (ExpLastWorkerThread); KeSetEvent (&ExpThreadSetManagerShutdownEvent, 0, FALSE); } KeSetKernelStackSwapEnable (TRUE); CurrentThread->ActiveExWorker = 0; PsTerminateSystemThread (STATUS_SYSTEM_SHUTDOWN); }
/** * Native kernel thread wrapper function. * * This will forward to rtThreadMain and do termination upon return. * * @param pvArg Pointer to the argument package. */ static VOID __stdcall rtThreadNativeMain(PVOID pvArg) { PETHREAD Self = PsGetCurrentThread(); PRTTHREADINT pThread = (PRTTHREADINT)pvArg; rtThreadMain(pThread, (RTNATIVETHREAD)Self, &pThread->szName[0]); ObDereferenceObject(Self); /* the rtThreadNativeCreate ref. */ }
NTSTATUS OcTplTestFuncParam0() { g_FunctionCalled[ 0x0 ] = TRUE; DbgPrint(" ThreadpoolTest: OcTplTestFuncParam0 Thread = 0x%ph \n", PsGetCurrentThread() ); return STATUS_SUCCESS; }
/* * @implemented */ VOID NTAPI SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) { /* Call the extended API */ SeCaptureSubjectContextEx(PsGetCurrentThread(), PsGetCurrentProcess(), SubjectContext); }
void DetermineThreadType() { if (ThreadServiceTableOffset == 0) return; if (* (PULONG) ((PCHAR) PsGetCurrentThread() + ThreadServiceTableOffset) != (ULONG) &KeServiceDescriptorTable[0]) IsGuiThread = TRUE; }
/* * @implemented */ VOID NTAPI FsRtlWorkerThread(IN PVOID StartContext) { KIRQL Irql; PLIST_ENTRY Entry; PWORK_QUEUE_ITEM WorkItem; ULONG QueueId = (ULONG)StartContext; /* Set our priority according to the queue we're dealing with */ KeSetPriorityThread(&PsGetCurrentThread()->Tcb, LOW_REALTIME_PRIORITY + QueueId); /* Loop for events */ for (;;) { /* Look for next event */ Entry = KeRemoveQueue(&FsRtlWorkerQueues[QueueId], KernelMode, NULL); WorkItem = CONTAINING_RECORD(Entry, WORK_QUEUE_ITEM, List); /* Call its routine (here: FsRtlStackOverflowRead) */ WorkItem->WorkerRoutine(WorkItem->Parameter); /* Check we're still at passive level or bugcheck */ Irql = KeGetCurrentIrql(); if (Irql != PASSIVE_LEVEL) { KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL, (ULONG_PTR)WorkItem->WorkerRoutine, (ULONG_PTR)Irql, (ULONG_PTR)WorkItem->WorkerRoutine, (ULONG_PTR)WorkItem); } } }