Merge pull request #1911 from Fisherman166/ReadWriteLock

Implement ExReadWriteLock Kernel functions
This commit is contained in:
Luke Usher 2020-05-29 11:18:20 +01:00 committed by GitHub
commit e5af2b1754
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 26 deletions

View File

@ -12,12 +12,12 @@
#ifndef XBOXKRNL_EX_H #ifndef XBOXKRNL_EX_H
#define XBOXKRNL_EX_H #define XBOXKRNL_EX_H
XBSYSAPI EXPORTNUM(12) NTSTATUS NTAPI ExAcquireReadWriteLockExclusive XBSYSAPI EXPORTNUM(12) VOID NTAPI ExAcquireReadWriteLockExclusive
( (
IN PERWLOCK ReadWriteLock IN PERWLOCK ReadWriteLock
); );
XBSYSAPI EXPORTNUM(13) NTSTATUS NTAPI ExAcquireReadWriteLockShared XBSYSAPI EXPORTNUM(13) VOID NTAPI ExAcquireReadWriteLockShared
( (
IN PERWLOCK ReadWriteLock IN PERWLOCK ReadWriteLock
); );
@ -134,7 +134,7 @@ XBSYSAPI EXPORTNUM(27) VOID NTAPI ExRaiseStatus
IN NTSTATUS Status IN NTSTATUS Status
); );
XBSYSAPI EXPORTNUM(28) NTSTATUS NTAPI ExReleaseReadWriteLock XBSYSAPI EXPORTNUM(28) VOID NTAPI ExReleaseReadWriteLock
( (
IN PERWLOCK ReadWriteLock IN PERWLOCK ReadWriteLock
); );

View File

@ -1279,9 +1279,9 @@ EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION;
// ****************************************************************** // ******************************************************************
typedef struct _KSEMAPHORE typedef struct _KSEMAPHORE
{ {
DISPATCHER_HEADER Header; DISPATCHER_HEADER Header; // 0x00
LONG Limit; LONG Limit; // 0x10
} } // 0x14
KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE; KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE;
// ****************************************************************** // ******************************************************************
@ -1310,13 +1310,13 @@ MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION;
// ****************************************************************** // ******************************************************************
typedef struct _ERWLOCK typedef struct _ERWLOCK
{ {
LONG LockCount; LONG LockCount; // 0x00
ULONG WritersWaitingCount; ULONG WritersWaitingCount; // 0x04
ULONG ReadersWaitingCount; ULONG ReadersWaitingCount; // 0x08
ULONG ReadersEntryCount; ULONG ReadersEntryCount; // 0x0C
KEVENT WriterEvent; KEVENT WriterEvent; // 0x10
KSEMAPHORE ReaderSemaphore; KSEMAPHORE ReaderSemaphore; // 0x20
} } // 0x34
ERWLOCK, *PERWLOCK; ERWLOCK, *PERWLOCK;
// ****************************************************************** // ******************************************************************

View File

@ -144,34 +144,64 @@ static bool eeprom_data_is_valid(xboxkrnl::XC_VALUE_INDEX index)
// * 0x000C - ExAcquireReadWriteLockExclusive() // * 0x000C - ExAcquireReadWriteLockExclusive()
// ****************************************************************** // ******************************************************************
// Source:APILogger - Uncertain // Source:APILogger - Uncertain
XBSYSAPI EXPORTNUM(12) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExAcquireReadWriteLockExclusive XBSYSAPI EXPORTNUM(12) xboxkrnl::VOID NTAPI xboxkrnl::ExAcquireReadWriteLockExclusive
( (
IN PERWLOCK ReadWriteLock IN PERWLOCK ReadWriteLock
) )
{ {
LOG_FUNC_ONE_ARG(ReadWriteLock); LOG_FUNC_ONE_ARG(ReadWriteLock);
// KeWaitForSingleObject bool interrupt_mode = DisableInterrupts();
LOG_UNIMPLEMENTED(); ReadWriteLock->LockCount++;
if (ReadWriteLock->LockCount != 0) {
RETURN(S_OK); ReadWriteLock->WritersWaitingCount++;
RestoreInterruptMode(interrupt_mode);
KeWaitForSingleObject(
&ReadWriteLock->WriterEvent,
Executive,
0,
0,
0
);
}
else {
RestoreInterruptMode(interrupt_mode);
}
} }
// ****************************************************************** // ******************************************************************
// * 0x000D - ExAcquireReadWriteLockShared() // * 0x000D - ExAcquireReadWriteLockShared()
// ****************************************************************** // ******************************************************************
// Source:APILogger - Uncertain // Source:APILogger - Uncertain
XBSYSAPI EXPORTNUM(13) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExAcquireReadWriteLockShared XBSYSAPI EXPORTNUM(13) xboxkrnl::VOID NTAPI xboxkrnl::ExAcquireReadWriteLockShared
( (
IN PERWLOCK ReadWriteLock IN PERWLOCK ReadWriteLock
) )
{ {
LOG_FUNC_ONE_ARG(ReadWriteLock); LOG_FUNC_ONE_ARG(ReadWriteLock);
// KeWaitForSingleObject bool interrupt_mode = DisableInterrupts();
LOG_UNIMPLEMENTED(); bool must_wait_on_active_write = ReadWriteLock->ReadersEntryCount == 0;
bool must_wait_on_queued_write = (ReadWriteLock->ReadersEntryCount != 0) && (ReadWriteLock->WritersWaitingCount != 0);
RETURN(S_OK); bool must_wait = must_wait_on_active_write || must_wait_on_queued_write;
ReadWriteLock->LockCount++;
if ((ReadWriteLock->LockCount != 0) && must_wait) {
ReadWriteLock->ReadersWaitingCount++;
RestoreInterruptMode(interrupt_mode);
#if 0 //FIXME - Enable once KeReleaseSempahore is implemented (used in ExFreeReadWriteLock for Sharedlocks).
KeWaitForSingleObject(
&ReadWriteLock->ReaderSemaphore,
Executive,
0,
0,
0
);
#endif
}
else {
ReadWriteLock->ReadersEntryCount++;
RestoreInterruptMode(interrupt_mode);
}
} }
// ****************************************************************** // ******************************************************************
@ -553,16 +583,42 @@ XBSYSAPI EXPORTNUM(27) xboxkrnl::VOID NTAPI xboxkrnl::ExRaiseStatus
// * 0x001C - ExReleaseReadWriteLock() // * 0x001C - ExReleaseReadWriteLock()
// ****************************************************************** // ******************************************************************
// Source:APILogger - Uncertain // Source:APILogger - Uncertain
XBSYSAPI EXPORTNUM(28) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExReleaseReadWriteLock XBSYSAPI EXPORTNUM(28) xboxkrnl::VOID NTAPI xboxkrnl::ExReleaseReadWriteLock
( (
IN PERWLOCK ReadWriteLock IN PERWLOCK ReadWriteLock
) )
{ {
LOG_FUNC_ONE_ARG(ReadWriteLock); LOG_FUNC_ONE_ARG(ReadWriteLock);
LOG_UNIMPLEMENTED(); bool interrupt_mode = DisableInterrupts();
ReadWriteLock->LockCount--;
if (ReadWriteLock->LockCount == -1) {
ReadWriteLock->ReadersEntryCount = 0;
RestoreInterruptMode(interrupt_mode);
return;
}
RETURN(S_OK); if (ReadWriteLock->ReadersEntryCount == 0) {
if (ReadWriteLock->ReadersWaitingCount != 0) {
ULONG temp_readers_waiting = ReadWriteLock->ReadersWaitingCount;
ReadWriteLock->ReadersEntryCount = ReadWriteLock->ReadersWaitingCount;
ReadWriteLock->ReadersWaitingCount = 0;
RestoreInterruptMode(interrupt_mode);
KeReleaseSemaphore(&ReadWriteLock->ReaderSemaphore, 1, (BOOLEAN)temp_readers_waiting, 0);
return;
}
}
else {
ReadWriteLock->ReadersEntryCount--;
if (ReadWriteLock->ReadersEntryCount != 0) {
RestoreInterruptMode(interrupt_mode);
return;
}
}
ReadWriteLock->WritersWaitingCount--;
RestoreInterruptMode(interrupt_mode);
KeSetEvent(&ReadWriteLock->WriterEvent, 1, 0);
} }
// ****************************************************************** // ******************************************************************