Implement KeReleaseSemaphore based on kernel reverse engineering. Needs KiWaitTest to be implemented to be fully functional.
This commit is contained in:
parent
e5af2b1754
commit
db1429a4b9
|
@ -321,7 +321,7 @@ XBSYSAPI EXPORTNUM(132) LONG NTAPI KeReleaseSemaphore
|
|||
(
|
||||
IN PRKSEMAPHORE Semaphore,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Adjustment,
|
||||
IN LONG Adjustment,
|
||||
IN BOOLEAN Wait
|
||||
);
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ typedef long NTSTATUS;
|
|||
#define STATUS_USER_APC ((DWORD )0x000000C0L)
|
||||
// The SCSI input buffer was too large (not necessarily an error!)
|
||||
#define STATUS_DATA_OVERRUN ((DWORD )0xC000003CL)
|
||||
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((DWORD )0xC0000047L)
|
||||
#define STATUS_INVALID_IMAGE_FORMAT ((DWORD )0xC000007BL)
|
||||
#define STATUS_INSUFFICIENT_RESOURCES ((DWORD )0xC000009AL)
|
||||
#define STATUS_TOO_MANY_SECRETS ((DWORD )0xC0000156L)
|
||||
|
|
|
@ -600,11 +600,11 @@ XBSYSAPI EXPORTNUM(28) xboxkrnl::VOID NTAPI xboxkrnl::ExReleaseReadWriteLock
|
|||
|
||||
if (ReadWriteLock->ReadersEntryCount == 0) {
|
||||
if (ReadWriteLock->ReadersWaitingCount != 0) {
|
||||
ULONG temp_readers_waiting = ReadWriteLock->ReadersWaitingCount;
|
||||
ULONG orig_readers_waiting = ReadWriteLock->ReadersWaitingCount;
|
||||
ReadWriteLock->ReadersEntryCount = ReadWriteLock->ReadersWaitingCount;
|
||||
ReadWriteLock->ReadersWaitingCount = 0;
|
||||
RestoreInterruptMode(interrupt_mode);
|
||||
KeReleaseSemaphore(&ReadWriteLock->ReaderSemaphore, 1, (BOOLEAN)temp_readers_waiting, 0);
|
||||
KeReleaseSemaphore(&ReadWriteLock->ReaderSemaphore, 1, (LONG)orig_readers_waiting, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1314,7 +1314,7 @@ XBSYSAPI EXPORTNUM(132) xboxkrnl::LONG NTAPI xboxkrnl::KeReleaseSemaphore
|
|||
(
|
||||
IN PRKSEMAPHORE Semaphore,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Adjustment,
|
||||
IN LONG Adjustment,
|
||||
IN BOOLEAN Wait
|
||||
)
|
||||
{
|
||||
|
@ -1325,9 +1325,35 @@ XBSYSAPI EXPORTNUM(132) xboxkrnl::LONG NTAPI xboxkrnl::KeReleaseSemaphore
|
|||
LOG_FUNC_ARG(Wait)
|
||||
LOG_FUNC_END;
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
UCHAR orig_irql = KeRaiseIrqlToDpcLevel();
|
||||
LONG initial_state = Semaphore->Header.SignalState;
|
||||
LONG adjusted_signalstate = Semaphore->Header.SignalState + Adjustment;
|
||||
|
||||
BOOL limit_reached = adjusted_signalstate > Semaphore->Limit;
|
||||
BOOL signalstate_overflow = adjusted_signalstate < initial_state;
|
||||
if (limit_reached || signalstate_overflow) {
|
||||
KiUnlockDispatcherDatabase(orig_irql);
|
||||
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
||||
}
|
||||
Semaphore->Header.SignalState = adjusted_signalstate;
|
||||
|
||||
//TODO: Implement KiWaitTest
|
||||
#if 0
|
||||
if ((initial_state == 0) && (IsListEmpty(&Semaphore->Header.WaitListHead) == FALSE)) {
|
||||
KiWaitTest(&Semaphore->Header, Increment);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Wait) {
|
||||
PKTHREAD current_thread = KeGetCurrentThread();
|
||||
current_thread->WaitNext = TRUE;
|
||||
current_thread->WaitIrql = orig_irql;
|
||||
}
|
||||
else {
|
||||
KiUnlockDispatcherDatabase(orig_irql);
|
||||
}
|
||||
|
||||
RETURN(0);
|
||||
RETURN(initial_state);
|
||||
}
|
||||
|
||||
XBSYSAPI EXPORTNUM(133) xboxkrnl::PKDEVICE_QUEUE_ENTRY NTAPI xboxkrnl::KeRemoveByKeyDeviceQueue
|
||||
|
|
Loading…
Reference in New Issue