diff --git a/NTOSKRNL/KE/mutex.cpp b/NTOSKRNL/KE/mutex.cpp index cd54a06..effd47f 100644 --- a/NTOSKRNL/KE/mutex.cpp +++ b/NTOSKRNL/KE/mutex.cpp @@ -20,20 +20,20 @@ constexpr ULONG MUTEX_READY_TO_BE_AQUIRED = 0; /*Internal Function*/ -/* Fast Mutex definitions */ +// Fast Mutex definitions #define FM_LOCK_BIT 0x1 -#define FM_LOCK_BIT_V 0x0 #define FM_LOCK_WAITER_WOKEN 0x2 #define FM_LOCK_WAITER_INC 0x4 +#define FM_RECURSIVE_BIT 0x8 -typedef struct _FAST_MUTEX -{ - LONG Count; //0x0 - VOID* Owner; //0x4 - ULONG Contention; //0x8 - struct _KEVENT Event; //0xc - ULONG OldIrql; //0x1c -} FAST_MUTEX, *PFAST_MUTEX; //0x20 bytes (sizeof) +typedef struct _FAST_MUTEX { + LONG Count; // 0x0: 0 = free, 1 = owned, negative = waiters + PVOID Owner; // 0x4: Owning thread + ULONG Contention; // 0x8: Contention count + KEVENT Event; // 0xC: Wait event + ULONG OldIrql; // 0x1C: Saved IRQL + LONG RecursionDepth; // 0x20: For recursive mutexes +} FAST_MUTEX, *PFAST_MUTEX; // 0x24 bytes (sizeof) typedef PFAST_MUTEX PKGUARDED_MUTEX; @@ -407,3 +407,37 @@ KeReleaseGuardedMutex( KeLowerIrql(OldIrql); KeLeaveGuardedRegion(); } + +/* Specific to Alcyone, Not found in Windows NT */ + +VOID NTAPI KeInitializeRecursiveFastMutex(_Out_ PFAST_MUTEX Mutex) { + KeInitializeFastMutex(Mutex); + Mutex->Count |= FM_RECURSIVE_BIT; +} + +NTSTATUS NTAPI KeAcquireFastMutexTimeout(_Inout_ PFAST_MUTEX Mutex, _In_ PLARGE_INTEGER Timeout) { + if (KeTryToAcquireFastMutex(Mutex)) { + return STATUS_SUCCESS; + } + NTSTATUS Status = KeWaitForSingleObject(&Mutex->Event, WrFastMutex, KernelMode, FALSE, Timeout); + if (Status == STATUS_SUCCESS) { + KiAcquireFastMutex(Mutex); + } + return Status; +} + +BOOLEAN NTAPI KeIsMutexOwned(_In_ PFAST_MUTEX Mutex) { + return (Mutex->Owner == KeGetCurrentThread()); +} + +NTSTATUS NTAPI KeAcquireGuardedMutexTimeout(_Inout_ PKGUARDED_MUTEX Mutex, _In_ PLARGE_INTEGER Timeout) { + KeEnterGuardedRegion(); + NTSTATUS Status = KeAcquireFastMutexTimeout(Mutex, Timeout); + if (Status != STATUS_SUCCESS) { + KeLeaveGuardedRegion(); + } + return Status; +} + + +