Merge pull request #1911 from Fisherman166/ReadWriteLock
Implement ExReadWriteLock Kernel functions
This commit is contained in:
commit
e5af2b1754
|
@ -12,12 +12,12 @@
|
|||
#ifndef XBOXKRNL_EX_H
|
||||
#define XBOXKRNL_EX_H
|
||||
|
||||
XBSYSAPI EXPORTNUM(12) NTSTATUS NTAPI ExAcquireReadWriteLockExclusive
|
||||
XBSYSAPI EXPORTNUM(12) VOID NTAPI ExAcquireReadWriteLockExclusive
|
||||
(
|
||||
IN PERWLOCK ReadWriteLock
|
||||
);
|
||||
|
||||
XBSYSAPI EXPORTNUM(13) NTSTATUS NTAPI ExAcquireReadWriteLockShared
|
||||
XBSYSAPI EXPORTNUM(13) VOID NTAPI ExAcquireReadWriteLockShared
|
||||
(
|
||||
IN PERWLOCK ReadWriteLock
|
||||
);
|
||||
|
@ -134,7 +134,7 @@ XBSYSAPI EXPORTNUM(27) VOID NTAPI ExRaiseStatus
|
|||
IN NTSTATUS Status
|
||||
);
|
||||
|
||||
XBSYSAPI EXPORTNUM(28) NTSTATUS NTAPI ExReleaseReadWriteLock
|
||||
XBSYSAPI EXPORTNUM(28) VOID NTAPI ExReleaseReadWriteLock
|
||||
(
|
||||
IN PERWLOCK ReadWriteLock
|
||||
);
|
||||
|
|
|
@ -1279,9 +1279,9 @@ EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION;
|
|||
// ******************************************************************
|
||||
typedef struct _KSEMAPHORE
|
||||
{
|
||||
DISPATCHER_HEADER Header;
|
||||
LONG Limit;
|
||||
}
|
||||
DISPATCHER_HEADER Header; // 0x00
|
||||
LONG Limit; // 0x10
|
||||
} // 0x14
|
||||
KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE;
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1310,13 +1310,13 @@ MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION;
|
|||
// ******************************************************************
|
||||
typedef struct _ERWLOCK
|
||||
{
|
||||
LONG LockCount;
|
||||
ULONG WritersWaitingCount;
|
||||
ULONG ReadersWaitingCount;
|
||||
ULONG ReadersEntryCount;
|
||||
KEVENT WriterEvent;
|
||||
KSEMAPHORE ReaderSemaphore;
|
||||
}
|
||||
LONG LockCount; // 0x00
|
||||
ULONG WritersWaitingCount; // 0x04
|
||||
ULONG ReadersWaitingCount; // 0x08
|
||||
ULONG ReadersEntryCount; // 0x0C
|
||||
KEVENT WriterEvent; // 0x10
|
||||
KSEMAPHORE ReaderSemaphore; // 0x20
|
||||
} // 0x34
|
||||
ERWLOCK, *PERWLOCK;
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -144,34 +144,64 @@ static bool eeprom_data_is_valid(xboxkrnl::XC_VALUE_INDEX index)
|
|||
// * 0x000C - ExAcquireReadWriteLockExclusive()
|
||||
// ******************************************************************
|
||||
// Source:APILogger - Uncertain
|
||||
XBSYSAPI EXPORTNUM(12) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExAcquireReadWriteLockExclusive
|
||||
XBSYSAPI EXPORTNUM(12) xboxkrnl::VOID NTAPI xboxkrnl::ExAcquireReadWriteLockExclusive
|
||||
(
|
||||
IN PERWLOCK ReadWriteLock
|
||||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(ReadWriteLock);
|
||||
|
||||
// KeWaitForSingleObject
|
||||
LOG_UNIMPLEMENTED();
|
||||
|
||||
RETURN(S_OK);
|
||||
bool interrupt_mode = DisableInterrupts();
|
||||
ReadWriteLock->LockCount++;
|
||||
if (ReadWriteLock->LockCount != 0) {
|
||||
ReadWriteLock->WritersWaitingCount++;
|
||||
RestoreInterruptMode(interrupt_mode);
|
||||
KeWaitForSingleObject(
|
||||
&ReadWriteLock->WriterEvent,
|
||||
Executive,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
else {
|
||||
RestoreInterruptMode(interrupt_mode);
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * 0x000D - ExAcquireReadWriteLockShared()
|
||||
// ******************************************************************
|
||||
// Source:APILogger - Uncertain
|
||||
XBSYSAPI EXPORTNUM(13) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExAcquireReadWriteLockShared
|
||||
XBSYSAPI EXPORTNUM(13) xboxkrnl::VOID NTAPI xboxkrnl::ExAcquireReadWriteLockShared
|
||||
(
|
||||
IN PERWLOCK ReadWriteLock
|
||||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(ReadWriteLock);
|
||||
|
||||
// KeWaitForSingleObject
|
||||
LOG_UNIMPLEMENTED();
|
||||
|
||||
RETURN(S_OK);
|
||||
bool interrupt_mode = DisableInterrupts();
|
||||
bool must_wait_on_active_write = ReadWriteLock->ReadersEntryCount == 0;
|
||||
bool must_wait_on_queued_write = (ReadWriteLock->ReadersEntryCount != 0) && (ReadWriteLock->WritersWaitingCount != 0);
|
||||
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()
|
||||
// ******************************************************************
|
||||
// Source:APILogger - Uncertain
|
||||
XBSYSAPI EXPORTNUM(28) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExReleaseReadWriteLock
|
||||
XBSYSAPI EXPORTNUM(28) xboxkrnl::VOID NTAPI xboxkrnl::ExReleaseReadWriteLock
|
||||
(
|
||||
IN PERWLOCK 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);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
Loading…
Reference in New Issue