From b9c609a6b10d510103b30d2abaebaaaa0fdaf959 Mon Sep 17 00:00:00 2001 From: Kaldaien Date: Tue, 17 Dec 2024 05:49:14 -0500 Subject: [PATCH] Refactored undocumented Windows structures to reduce code duplication --- include/SpecialK/diagnostics/debug_utils.h | 3 + include/SpecialK/stdafx.h | 26 ++-- include/SpecialK/thread.h | 122 ++++++++++++++++- src/diagnostics/debug_utils.cpp | 146 ++------------------- src/input/hid_reports/playstation.cpp | 2 - src/process.cpp | 88 ++++++------- src/thread.cpp | 34 ++++- src/widgets/threads.cpp | 8 +- 8 files changed, 215 insertions(+), 214 deletions(-) diff --git a/include/SpecialK/diagnostics/debug_utils.h b/include/SpecialK/diagnostics/debug_utils.h index 94abf7432..947479b25 100644 --- a/include/SpecialK/diagnostics/debug_utils.h +++ b/include/SpecialK/diagnostics/debug_utils.h @@ -894,6 +894,9 @@ using NtTerminateProcess_pfn = NTSTATUS (*)(HANDLE, NTSTATUS); using RtlExitUserThread_pfn = VOID (NTAPI *)(_In_ NTSTATUS Status); using SHGetKnownFolderPath_pfn = HRESULT (WINAPI *)(REFKNOWNFOLDERID,DWORD,HANDLE,PWSTR*); +using RtlAcquirePebLock_pfn = void (NTAPI *)(void); +using RtlReleasePebLock_pfn = void (NTAPI *)(void); + extern SHGetKnownFolderPath_pfn SHGetKnownFolderPath_Original; extern GetCommandLineW_pfn GetCommandLineW_Original; diff --git a/include/SpecialK/stdafx.h b/include/SpecialK/stdafx.h index c49172f41..8206da548 100644 --- a/include/SpecialK/stdafx.h +++ b/include/SpecialK/stdafx.h @@ -48,6 +48,19 @@ #define UNICODE 1 +#ifndef NT_SUCCESS +# define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +# define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +# define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) +# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +// STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) +# define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL) +# define STATUS_ACCESS_DENIED ((NTSTATUS)0xc0000022L) +# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) +# define STATUS_ALERTED ((NTSTATUS)0x00000101L) +# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010AL) +#endif + #include #include #include @@ -16630,19 +16643,6 @@ extern bool __SK_bypass; extern const wchar_t* SK_VersionStrW; extern const char* SK_VersionStrA; -#ifndef NT_SUCCESS -# define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) -# define STATUS_SUCCESS ((NTSTATUS)0x00000000L) -# define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) -# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) -// STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) -# define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL) -# define STATUS_ACCESS_DENIED ((NTSTATUS)0xc0000022L) -# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) -# define STATUS_ALERTED ((NTSTATUS)0x00000101L) -# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010AL) -#endif - #ifndef __cpp_lib_format #define __cpp_lib_format #endif diff --git a/include/SpecialK/thread.h b/include/SpecialK/thread.h index 0e1ec7d0d..f59742122 100644 --- a/include/SpecialK/thread.h +++ b/include/SpecialK/thread.h @@ -730,15 +730,127 @@ struct SKWG_Thread_Entry std::wstring name = L""; }; -DWORD WINAPI -SK_DelayExecution (double dMilliseconds, BOOL bAlertable) noexcept; +#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 +#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 +#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 +#define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 +#define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 +#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 + +using SK_POBJECT_ATTRIBUTES = void*; + +using NtCreateThreadEx_pfn = NTSTATUS (NTAPI *)( + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ SK_POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ProcessHandle, + _In_ PVOID StartRoutine, + _In_opt_ PVOID Argument, + _In_ ULONG CreateFlags, + _In_opt_ ULONG_PTR ZeroBits, + _In_opt_ SIZE_T StackSize, + _In_opt_ SIZE_T MaximumStackSize, + _In_opt_ PVOID AttributeList +); -BOOL -WINAPI -SK_SetProcessAffinityMask (HANDLE hProcess, DWORD_PTR dwProcessAffinityMask); +using GetThreadContext_pfn = BOOL (WINAPI *)(HANDLE,LPCONTEXT); +using SetThreadContext_pfn = BOOL (WINAPI *)(HANDLE,const CONTEXT*); + +typedef enum _SK_THREAD_INFORMATION_CLASS { + ThreadBasicInformation, + ThreadTimes, + ThreadPriority, + ThreadBasePriority, + ThreadAffinityMask, + ThreadImpersonationToken, + ThreadDescriptorTableEntry, + ThreadEnableAlignmentFaultFixup, + ThreadEventPair_Reusable, + ThreadQuerySetWin32StartAddress, + ThreadZeroTlsCell, + ThreadPerformanceCount, + ThreadAmILastThread, + ThreadIdealProcessor, + ThreadPriorityBoost, + ThreadSetTlsArrayAddress, + ThreadIsIoPending_, + ThreadHideFromDebugger, + ThreadBreakOnTermination, + ThreadSwitchLegacyState, + ThreadIsTerminated, + ThreadLastSystemCall, + ThreadIoPriority, + ThreadCycleTime, + ThreadPagePriority, + ThreadActualBasePriority, + ThreadTebInformation, + ThreadCSwitchMon, + ThreadCSwitchPmu, + ThreadWow64Context, + ThreadGroupInformation, + ThreadUmsInformation, + ThreadCounterProfiling, + ThreadIdealProcessorEx, + ThreadCpuAccountingInformation, + ThreadSuspendCount, + ThreadHeterogeneousCpuPolicy, + ThreadContainerId, + ThreadNameInformation_, + ThreadSelectedCpuSets, + ThreadSystemThreadInformation, + ThreadActualGroupAffinity, + ThreadDynamicCodePolicyInfo, + ThreadExplicitCaseSensitivity, + ThreadWorkOnBehalfTicket, + ThreadSubsystemInformation, + ThreadDbgkWerReportActive, + ThreadAttachContainer, + ThreadManageWritesToExecutableMemory, + ThreadPowerThrottlingState, + ThreadWorkloadClass, + ThreadCreateStateChange, + ThreadApplyStateChange, + ThreadStrongerBadHandleChecks, + ThreadEffectiveIoPriority, + ThreadEffectivePagePriority, + ThreadUpdateLockOwnership, + ThreadSchedulerSharedDataSlot, + ThreadTebInformationAtomic, + ThreadIndexInformation, + MaxThreadInfoClass, +} SK_THREAD_INFORMATION_CLASS, +*PSK_THREAD_INFORMATION_CLASS; + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +using ZwSetInformationThread_pfn = NTSTATUS (NTAPI *)( + _In_ HANDLE ThreadHandle, + _In_ SK_THREAD_INFORMATION_CLASS ThreadInformationClass, + _In_ PVOID ThreadInformation, + _In_ ULONG ThreadInformationLength +); + +// The Nt function is the most obvious choice, but some sneaky +// software will hop right over this and call Zw... directly. +// +// --> Thus, don't even bother hooking NtSetInformationThread. +// +using NtSetInformationThread_pfn = NTSTATUS (NTAPI *)( + _In_ HANDLE ThreadHandle, + _In_ SK_THREAD_INFORMATION_CLASS ThreadInformationClass, + _In_ PVOID ThreadInformation, + _In_ ULONG ThreadInformationLength +); + +DWORD WINAPI SK_DelayExecution (double dMilliseconds, BOOL bAlertable) noexcept; +BOOL WINAPI SK_SetThreadIOPriority (HANDLE hThread, int ioPriority) noexcept; +BOOL WINAPI SK_SetProcessAffinityMask (HANDLE hProcess, DWORD_PTR dwProcessAffinityMask); void SK_Widget_InvokeThreadProfiler (void); void SK_ImGui_RebalanceThreadButton (void); + extern float __SK_Thread_RebalanceEveryNSeconds; #endif /* __SK__THREAD_H__ */ diff --git a/src/diagnostics/debug_utils.cpp b/src/diagnostics/debug_utils.cpp index 9016e3c79..bb33e2189 100644 --- a/src/diagnostics/debug_utils.cpp +++ b/src/diagnostics/debug_utils.cpp @@ -1620,144 +1620,16 @@ OutputDebugStringW_Detour (LPCWSTR lpOutputString) #endif } +GetThreadContext_pfn GetThreadContext_Original = nullptr; +SetThreadContext_pfn SetThreadContext_Original = nullptr; +NtCreateThreadEx_pfn NtCreateThreadEx_Original = nullptr; +NtCreateThreadEx_pfn ZwCreateThreadEx_Original = nullptr; +NtSetInformationThread_pfn NtSetInformationThread_Original = nullptr; +ZwSetInformationThread_pfn ZwSetInformationThread_Original = nullptr; -using GetThreadContext_pfn = BOOL (WINAPI *)(HANDLE,LPCONTEXT); -using SetThreadContext_pfn = BOOL (WINAPI *)(HANDLE,const CONTEXT *); - -GetThreadContext_pfn GetThreadContext_Original = nullptr; -SetThreadContext_pfn SetThreadContext_Original = nullptr; - -enum IO_PRIORITY_HINT : int -{ - IoPriorityVeryLow = 0, // Defragging, content indexing and other background I/Os. - IoPriorityLow, // Prefetching for applications. - IoPriorityNormal, // Normal I/Os. - IoPriorityHigh, // Used by filesystems for checkpoint I/O. - IoPriorityCritical, // Used by memory manager. Not available for applications. - MaxIoPriorityTypes -}; - -typedef enum _SK_THREAD_INFORMATION_CLASS { - ThreadBasicInformation, - ThreadTimes, - ThreadPriority, - ThreadBasePriority, - ThreadAffinityMask, - ThreadImpersonationToken, - ThreadDescriptorTableEntry, - ThreadEnableAlignmentFaultFixup, - ThreadEventPair, - ThreadQuerySetWin32StartAddress, - ThreadZeroTlsCell, - ThreadPerformanceCount, - ThreadAmILastThread, - ThreadIdealProcessor, - ThreadPriorityBoost, - ThreadSetTlsArrayAddress, - ThreadIsIoPending_, - ThreadHideFromDebugger, - ThreadBreakOnTermination, - ThreadSwitchLegacyState, - ThreadIsTerminated, - ThreadLastSystemCall, - ThreadIoPriority, - ThreadCycleTime, - ThreadPagePriority, - ThreadActualBasePriority, - ThreadTebInformation, - ThreadCSwitchMon, - ThreadCSwitchPmu, - ThreadWow64Context, - ThreadGroupInformation, - ThreadUmsInformation, - ThreadCounterProfiling, - ThreadIdealProcessorEx, - ThreadCpuAccountingInformation, - ThreadSuspendCount, - ThreadHeterogeneousCpuPolicy, - ThreadContainerId, - _ThreadNameInformation, - ThreadSelectedCpuSets, - ThreadSystemThreadInformation, - ThreadActualGroupAffinity, - ThreadDynamicCodePolicyInfo, - ThreadExplicitCaseSensitivity, - ThreadWorkOnBehalfTicket, - ThreadSubsystemInformation, - ThreadDbgkWerReportActive, - ThreadAttachContainer, - ThreadManageWritesToExecutableMemory, - ThreadPowerThrottlingState, -} SK_THREAD_INFORMATION_CLASS, -*PSK_THREAD_INFORMATION_CLASS; - -#ifndef NT_SUCCESS -# define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) -#endif - -#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 -#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 -#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 -#define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 -#define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 -#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 - -using ZwSetInformationThread_pfn = NTSTATUS (NTAPI *)( - _In_ HANDLE ThreadHandle, - _In_ SK_THREAD_INFORMATION_CLASS ThreadInformationClass, - _In_ PVOID ThreadInformation, - _In_ ULONG ThreadInformationLength -); - -// The Nt function is the most obvious choice, but some sneaky -// software will hop right over this and call Zw... directly. -// -// --> Thus, don't even bother hooking NtSetInformationThread. -// -using NtSetInformationThread_pfn = NTSTATUS (NTAPI *)( - _In_ HANDLE ThreadHandle, - _In_ SK_THREAD_INFORMATION_CLASS ThreadInformationClass, - _In_ PVOID ThreadInformation, - _In_ ULONG ThreadInformationLength -); - -using NtCreateThreadEx_pfn = NTSTATUS (NTAPI *)( - _Out_ PHANDLE ThreadHandle, - _In_ ACCESS_MASK DesiredAccess, - _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, - _In_ HANDLE ProcessHandle, - _In_ PVOID StartRoutine, - _In_opt_ PVOID Argument, - _In_ ULONG CreateFlags, - _In_opt_ ULONG_PTR ZeroBits, - _In_opt_ SIZE_T StackSize, - _In_opt_ SIZE_T MaximumStackSize, - _In_opt_ PVOID AttributeList - ); - -NtCreateThreadEx_pfn NtCreateThreadEx_Original = nullptr; -NtCreateThreadEx_pfn ZwCreateThreadEx_Original = nullptr; -NtSetInformationThread_pfn NtSetInformationThread_Original = nullptr; -ZwSetInformationThread_pfn ZwSetInformationThread_Original = nullptr; - -typedef void (NTAPI* RtlAcquirePebLock_pfn)(void); -typedef void (NTAPI* RtlReleasePebLock_pfn)(void); - -static RtlAcquirePebLock_pfn RtlAcquirePebLock_Original = nullptr; -static RtlReleasePebLock_pfn RtlReleasePebLock_Original = nullptr; - -bool -SK_SetThreadIOPriority (HANDLE hThread, int priority) -{ - IO_PRIORITY_HINT io_priority = - (IO_PRIORITY_HINT)priority; - static NtSetInformationThread_pfn - NtSetInformationThread = - (NtSetInformationThread_pfn)SK_GetProcAddress (L"NtDll", "NtSetInformationThread"); - return - (NT_SUCCESS (NtSetInformationThread(hThread, ThreadIoPriority, &io_priority, sizeof(IO_PRIORITY_HINT)))); -} +static RtlAcquirePebLock_pfn RtlAcquirePebLock_Original = nullptr; +static RtlReleasePebLock_pfn RtlReleasePebLock_Original = nullptr; #define SK_ANTIDEBUG_PARANOIA_STAGE2 #define SK_ANTIDEBUG_PARANOIA_STAGE3 @@ -4610,7 +4482,7 @@ SK_NtLdr_LockLoaderLock (ULONG Flags, ULONG* State, ULONG_PTR* Cookie) return STATUS_SUCCESS; // No-Op static LdrLockLoaderLock_pfn LdrLockLoaderLock = - (LdrLockLoaderLock_pfn)SK_GetProcAddress (L"NtDll.dll", + (LdrLockLoaderLock_pfn)SK_GetProcAddress (L"NtDll.dll", "LdrLockLoaderLock"); if (! LdrLockLoaderLock) diff --git a/src/input/hid_reports/playstation.cpp b/src/input/hid_reports/playstation.cpp index 93bb2c1c6..39a6a0b8f 100644 --- a/src/input/hid_reports/playstation.cpp +++ b/src/input/hid_reports/playstation.cpp @@ -86,8 +86,6 @@ SK_HID_PlayStationDevice::~SK_HID_PlayStationDevice (void) { } -extern bool SK_SetThreadIOPriority (HANDLE hThread, int priority); - void SK_HID_FlushPlayStationForceFeedback (void) { for (auto& ps_controller : SK_HID_PlayStationControllers) diff --git a/src/process.cpp b/src/process.cpp index 629a05623..8fc953b76 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -1,4 +1,4 @@ -/** +/** * This file is part of Special K. * * Special K is free software : you can redistribute it @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -123,35 +124,24 @@ typedef LONG (NTAPI *NtResumeProcess_pfn)(_In_ HANDLE ProcessHandle); NtResumeProcess_pfn NtResumeProcess = nullptr; -typedef struct _CLIENT_ID { - HANDLE UniqueProcess; - HANDLE UniqueThread; -} CLIENT_ID; - -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING; //-V677 - typedef struct _SYSTEM_THREAD { - FILETIME ftKernelTime; - FILETIME ftUserTime; - FILETIME ftCreateTime; + FILETIME ftKernelTime; // 100 nsec units + FILETIME ftUserTime; // 100 nsec units + FILETIME ftCreateTime; // relative to 01-01-1601 ULONG dWaitTime; #ifdef _M_AMD64 DWORD32 dwPaddingFor64Bit; #endif PVOID pStartAddress; - CLIENT_ID Cid; // PID / TID Pairing + CLIENT_ID Cid; // process/thread ids KPRIORITY dPriority; LONG dBasePriority; ULONG dContextSwitches; - ULONG dThreadState; // 2 = running, 5 = waiting + ULONG dThreadState; // 2=running, 5=waiting KWAIT_REASON WaitReason; - // Not needed if correct packing is used, but these data structures - // have tricky alignment and the whole world needs to know! + // Not even needed if correct packing is used, but let's just make this + // obvious since it's easy to overlook! DWORD32 dwPaddingEveryoneGets; } SYSTEM_THREAD, *PSYSTEM_THREAD; #define SYSTEM_THREAD_ sizeof (SYSTEM_THREAD) @@ -193,19 +183,19 @@ typedef struct _SYSTEM_PROCESS // common members LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; SYSTEM_THREAD aThreads [1]; -} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; -#define SYSTEM_PROCESS_ sizeof (SYSTEM_PROCESS_INFORMATION) +} SYSTEM_PROCESS_INFORMATION_SK, *PSYSTEM_PROCESS_INFORMATION_SK; +#define SYSTEM_PROCESS_ sizeof (SYSTEM_PROCESS_INFORMATION_SK) // There are about 100 more enumerates; all 100 of them are useless and omitted. -typedef enum _SYSTEM_INFORMATION_CLASS { - SystemProcessInformation = 5, -} SYSTEM_INFORMATION_CLASS; +typedef enum _SYSTEM_INFORMATION_CLASS_SK { + SystemProcessInformation_SK = 5, +} SYSTEM_INFORMATION_CLASS_SK; typedef NTSTATUS (WINAPI *NtQuerySystemInformation_pfn)( - _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, - _Inout_ PVOID SystemInformation, - _In_ ULONG SystemInformationLength, - _Out_opt_ PULONG ReturnLength + _In_ SYSTEM_INFORMATION_CLASS_SK SystemInformationClass, + _Inout_ PVOID SystemInformation, + _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength ); typedef NTSTATUS (WINAPI *NtDelayExecution_pfn)( @@ -216,18 +206,18 @@ typedef NTSTATUS (WINAPI *NtDelayExecution_pfn)( struct SK_NtDllContext { - BOOL _uninit = TRUE; - NtQuerySystemInformation_pfn QuerySystemInformation = nullptr; - NtDelayExecution_pfn DelayExecution = nullptr; - NtSuspendProcess_pfn SuspendProcess = nullptr; - NtResumeProcess_pfn ResumeProcess = nullptr; - - HMODULE Module = nullptr; - HANDLE hHeap = nullptr; - DWORD dwHeapSize = 0UL; - DWORD dwPadding0 = 0UL; - PSYSTEM_PROCESS_INFORMATION pSnapshot = nullptr; - volatile LONG _lock = 0L; + BOOL _uninit = TRUE; + NtQuerySystemInformation_pfn QuerySystemInformation = nullptr; + NtDelayExecution_pfn DelayExecution = nullptr; + NtSuspendProcess_pfn SuspendProcess = nullptr; + NtResumeProcess_pfn ResumeProcess = nullptr; + + HMODULE Module = nullptr; + HANDLE hHeap = nullptr; + DWORD dwHeapSize = 0UL; + DWORD dwPadding0 = 0UL; + PSYSTEM_PROCESS_INFORMATION_SK pSnapshot = nullptr; + volatile LONG _lock = 0L; void init (void) { @@ -253,7 +243,7 @@ struct SK_NtDllContext if (hHeap != nullptr) { - pSnapshot = (PSYSTEM_PROCESS_INFORMATION) + pSnapshot = (PSYSTEM_PROCESS_INFORMATION_SK) HeapAlloc (hHeap, 0x0, 262144); dwHeapSize = @@ -332,7 +322,7 @@ struct SK_NtDllContext SK_LazyGlobal SK_NtDll; -PSYSTEM_PROCESS_INFORMATION +PSYSTEM_PROCESS_INFORMATION_SK SK_Process_SnapshotNt (void) { SK_NtDll->init (); @@ -345,11 +335,11 @@ SK_Process_SnapshotNt (void) RtlZeroMemory ( SK_NtDll->pSnapshot, SK_NtDll->dwHeapSize ); - DWORD dData = 0; - PSYSTEM_PROCESS_INFORMATION pspi = nullptr; + DWORD dData = 0; + PSYSTEM_PROCESS_INFORMATION_SK pspi = nullptr; NTSTATUS ns = - SK_NtDll->QuerySystemInformation ( SystemProcessInformation, + SK_NtDll->QuerySystemInformation ( SystemProcessInformation_SK, SK_NtDll->pSnapshot, SK_NtDll->dwHeapSize, &dData ); @@ -361,7 +351,7 @@ SK_Process_SnapshotNt (void) (pspi == nullptr) && dSize != 0 ; dSize <<= 1 ) { - if ( ( pspi = (PSYSTEM_PROCESS_INFORMATION) + if ( ( pspi = (PSYSTEM_PROCESS_INFORMATION_SK) HeapReAlloc ( SK_NtDll->hHeap, 0x0, SK_NtDll->pSnapshot, dSize ) ) == nullptr ) { @@ -380,7 +370,7 @@ SK_Process_SnapshotNt (void) SK_NtDll->dwHeapSize = dSize; SK_NtDll->pSnapshot = pspi; - ns = SK_NtDll->QuerySystemInformation ( SystemProcessInformation, + ns = SK_NtDll->QuerySystemInformation ( SystemProcessInformation_SK, pspi, dSize, &dData ); if (ns != STATUS_SUCCESS) @@ -410,7 +400,7 @@ SK_Process_EnumerateThreads (PTHREAD_LIST pThreads, DWORD dwPID) SK_NtDll->init (); SK_NtDll->lock (); - PSYSTEM_PROCESS_INFORMATION pProc = nullptr; + PSYSTEM_PROCESS_INFORMATION_SK pProc = nullptr; if (SK_NtDll->pSnapshot == nullptr) { @@ -436,7 +426,7 @@ SK_Process_EnumerateThreads (PTHREAD_LIST pThreads, DWORD dwPID) if ((DWORD)((uintptr_t)pProc->UniqueProcessId & 0xFFFFFFFFU) == dwPID) break; - pProc = (SYSTEM_PROCESS_INFORMATION *)((BYTE *)pProc + pProc->NextThreadOffset); + pProc = (SYSTEM_PROCESS_INFORMATION_SK *)((BYTE *)pProc + pProc->NextThreadOffset); } while (pProc->NextThreadOffset != 0); diff --git a/src/thread.cpp b/src/thread.cpp index 2377ebaca..fd0950719 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -1208,4 +1208,36 @@ SK_Thread_SpinUntilFlaggedEx ( _In_ _Interlocked_operand_ LONG volatile const *p } -volatile LONG __SK_MMCS_PendingChanges = 0; \ No newline at end of file +volatile LONG __SK_MMCS_PendingChanges = 0; + + + +enum IO_PRIORITY_HINT : int +{ + IoPriorityVeryLow = 0, // Defragging, content indexing and other background I/Os. + IoPriorityLow, // Prefetching for applications. + IoPriorityNormal, // Normal I/Os. + IoPriorityHigh, // Used by filesystems for checkpoint I/O. + IoPriorityCritical, // Used by memory manager. Not available for applications. + MaxIoPriorityTypes +}; + +BOOL +WINAPI +SK_SetThreadIOPriority (HANDLE hThread, int ioPriority) noexcept +{ + auto io_priority = + static_cast (ioPriority); + + static NtSetInformationThread_pfn + NtSetInformationThread = + (NtSetInformationThread_pfn)SK_GetProcAddress (L"NtDll", + "NtSetInformationThread"); + + return NtSetInformationThread != nullptr && + NT_SUCCESS (NtSetInformationThread ( + hThread, + ThreadIoPriority, + &io_priority, + sizeof (IO_PRIORITY_HINT))); +} \ No newline at end of file diff --git a/src/widgets/threads.cpp b/src/widgets/threads.cpp index 402fb3516..0c39a18dc 100644 --- a/src/widgets/threads.cpp +++ b/src/widgets/threads.cpp @@ -135,12 +135,6 @@ typedef struct _CLIENT_ID { HANDLE UniqueThread; } CLIENT_ID; -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING; //-V677 - typedef struct _SYSTEM_THREAD { FILETIME ftKernelTime; // 100 nsec units FILETIME ftUserTime; // 100 nsec units @@ -174,7 +168,7 @@ typedef struct _SYSTEM_PROCESS // common members LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; - UNICODE_STRING ImageName; +UNICODE_STRING_SK ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; HANDLE InheritedFromUniqueProcessId;