diff --git a/import/OpenXDK/include/xboxkrnl/ex.h b/import/OpenXDK/include/xboxkrnl/ex.h index 025bfac15..74624efb6 100644 --- a/import/OpenXDK/include/xboxkrnl/ex.h +++ b/import/OpenXDK/include/xboxkrnl/ex.h @@ -61,7 +61,10 @@ XBSYSAPI EXPORTNUM(17) VOID NTAPI ExFreePool IN PVOID P ); -XBSYSAPI EXPORTNUM(18) NTSTATUS NTAPI ExInitializeReadWriteLock +// ****************************************************************** +// * 0x0012 - ExInitializeReadWriteLock() +// ****************************************************************** +XBSYSAPI EXPORTNUM(18) VOID NTAPI ExInitializeReadWriteLock ( IN PERWLOCK ReadWriteLock ); @@ -152,24 +155,30 @@ XBSYSAPI EXPORTNUM(30) OBJECT_TYPE ExSemaphoreObjectType; XBSYSAPI EXPORTNUM(31) OBJECT_TYPE ExTimerObjectType; +// ****************************************************************** +// * 0x0020 - ExfInterlockedInsertHeadList() +// ****************************************************************** XBSYSAPI EXPORTNUM(32) PLIST_ENTRY FASTCALL ExfInterlockedInsertHeadList ( IN PLIST_ENTRY ListHead, - IN PLIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock + IN PLIST_ENTRY ListEntry ); +// ****************************************************************** +// * 0x0021 - ExfInterlockedInsertTailList() +// ****************************************************************** XBSYSAPI EXPORTNUM(33) PLIST_ENTRY FASTCALL ExfInterlockedInsertTailList ( IN PLIST_ENTRY ListHead, - IN PLIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock + IN PLIST_ENTRY ListEntry ); +// ****************************************************************** +// * 0x0022 - ExfInterlockedRemoveHeadList() +// ****************************************************************** XBSYSAPI EXPORTNUM(34) PLIST_ENTRY FASTCALL ExfInterlockedRemoveHeadList ( - IN PLIST_ENTRY ListHead, - IN PKSPIN_LOCK Lock + IN PLIST_ENTRY ListHead ); XBSYSAPI EXPORTNUM(51) LONG FASTCALL KRNL(InterlockedCompareExchange) diff --git a/import/OpenXDK/include/xboxkrnl/kernel.h b/import/OpenXDK/include/xboxkrnl/kernel.h index a5b3ed507..c101b5b78 100644 --- a/import/OpenXDK/include/xboxkrnl/kernel.h +++ b/import/OpenXDK/include/xboxkrnl/kernel.h @@ -147,8 +147,25 @@ XBSYSAPI EXPORTNUM(109) VOID NTAPI KeInitializeInterrupt XBSYSAPI VOID *KeInitializeMutant; -XBSYSAPI VOID *KeInitializeQueue; -XBSYSAPI VOID *KeInitializeSemaphore; + +// ****************************************************************** +// * 0x006F - KeInitializeQueue() +// ****************************************************************** +XBSYSAPI EXPORTNUM(111) VOID NTAPI KeInitializeQueue +( + IN PKQUEUE Queue, + IN ULONG Count OPTIONAL +); + +// ****************************************************************** +// * 0x0070 - KeInitializeSemaphore() +// ****************************************************************** +XBSYSAPI EXPORTNUM(112) VOID NTAPI KeInitializeSemaphore +( + IN PRKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit +); // ****************************************************************** // * 0x0071 - KeInitializeTimerEx() diff --git a/import/OpenXDK/include/xboxkrnl/rtl.h b/import/OpenXDK/include/xboxkrnl/rtl.h index 99dbdb512..b11c23d7e 100644 --- a/import/OpenXDK/include/xboxkrnl/rtl.h +++ b/import/OpenXDK/include/xboxkrnl/rtl.h @@ -168,7 +168,13 @@ XBSYSAPI EXPORTNUM(277) VOID NTAPI RtlEnterCriticalSection IN PRTL_CRITICAL_SECTION CriticalSection ); -XBSYSAPI VOID *RtlEnterCriticalSectionAndRegion; +// ****************************************************************** +// * 0x0116 - RtlEnterCriticalSectionAndRegion() +// ****************************************************************** +XBSYSAPI EXPORTNUM(278) VOID NTAPI RtlEnterCriticalSectionAndRegion +( + IN PRTL_CRITICAL_SECTION CriticalSection +); // ****************************************************************** // * 0x0117 - RtlEqualString() @@ -313,7 +319,13 @@ XBSYSAPI EXPORTNUM(294) VOID NTAPI RtlLeaveCriticalSection IN PRTL_CRITICAL_SECTION CriticalSection ); -XBSYSAPI VOID *RtlLeaveCriticalSectionAndRegion; +// ****************************************************************** +// * 0x0127 - RtlLeaveCriticalSectionAndRegion() +// ****************************************************************** +XBSYSAPI EXPORTNUM(295) VOID NTAPI RtlLeaveCriticalSectionAndRegion +( + IN PRTL_CRITICAL_SECTION CriticalSection +); // ****************************************************************** // * RtlLowerChar diff --git a/import/OpenXDK/include/xboxkrnl/xbox.h b/import/OpenXDK/include/xboxkrnl/xbox.h index 3e6e1d668..4de29960c 100644 --- a/import/OpenXDK/include/xboxkrnl/xbox.h +++ b/import/OpenXDK/include/xboxkrnl/xbox.h @@ -417,12 +417,13 @@ XBSYSAPI EXPORTNUM(369) NTSTATUS NTAPI UnknownAPI369 XBSYSAPI EXPORTNUM(370) NTSTATUS NTAPI XProfpControl // PROFILING ( - // UNKNOWN ARGUMENTS + ULONG Action, + ULONG Param ); XBSYSAPI EXPORTNUM(371) NTSTATUS NTAPI XProfpGetData // PROFILING ( - // UNKNOWN ARGUMENTS + // NO ARGUMENTS ); XBSYSAPI EXPORTNUM(372) NTSTATUS NTAPI IrtClientInitFast // PROFILING diff --git a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h index d67bb6f93..76943792a 100644 --- a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h +++ b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h @@ -1526,6 +1526,8 @@ KDPC, *PKDPC; // ****************************************************************** typedef enum _KOBJECTS { + QueueObject = 4, + SemaphoreObject = 5, TimerNotificationObject = 8, TimerSynchronizationObject = 9, DpcObject = 0x13, diff --git a/src/Common/Logging.h b/src/Common/Logging.h index 98b218f0b..07aa86253 100644 --- a/src/Common/Logging.h +++ b/src/Common/Logging.h @@ -220,6 +220,12 @@ extern thread_local std::string _logPrefix; std::cout << _logPrefix << __func__ << " unimplemented!\n"; \ } } while (0) +// LOG_INCOMPLETE indicates that Cxbx is missing part of an implementation of an api +#define LOG_INCOMPLETE() \ + do { if(g_bPrintfOn) { \ + std::cout << _logPrefix << __func__ << " incomplete!\n"; \ + } } while (0) + // RETURN logs the given result and then returns it (so this should appear last in functions) #define RETURN(r) do { LOG_FUNC_RESULT(r) return r; } while (0) diff --git a/src/CxbxKrnl/EmuKrnl.cpp b/src/CxbxKrnl/EmuKrnl.cpp index d8c67441f..ae4415f47 100644 --- a/src/CxbxKrnl/EmuKrnl.cpp +++ b/src/CxbxKrnl/EmuKrnl.cpp @@ -146,7 +146,9 @@ XBSYSAPI EXPORTNUM(51) xboxkrnl::LONG FASTCALL xboxkrnl::KRNL(InterlockedCompare LOG_FUNC_ARG(Comparand) LOG_FUNC_END; - RETURN(InterlockedCompareExchange((NtDll::PLONG)Destination, (NtDll::LONG)Exchange, (NtDll::LONG)Comparand)); + LONG res = InterlockedCompareExchange((NtDll::PLONG)Destination, (NtDll::LONG)Exchange, (NtDll::LONG)Comparand); + + RETURN(res); } // ****************************************************************** @@ -160,7 +162,9 @@ XBSYSAPI EXPORTNUM(52) xboxkrnl::LONG FASTCALL xboxkrnl::KRNL(InterlockedDecreme { LOG_FUNC_ONE_ARG(Addend); - RETURN(InterlockedDecrement((NtDll::PLONG)Addend)); + LONG res = InterlockedDecrement((NtDll::PLONG)Addend); + + RETURN(res); } // ****************************************************************** @@ -174,7 +178,9 @@ XBSYSAPI EXPORTNUM(53) xboxkrnl::LONG FASTCALL xboxkrnl::KRNL(InterlockedIncreme { LOG_FUNC_ONE_ARG(Addend); - RETURN(InterlockedIncrement((NtDll::PLONG)Addend)); + LONG res = InterlockedIncrement((NtDll::PLONG)Addend); + + RETURN(res); } // ****************************************************************** @@ -192,7 +198,9 @@ XBSYSAPI EXPORTNUM(54) xboxkrnl::LONG FASTCALL xboxkrnl::KRNL(InterlockedExchang LOG_FUNC_ARG(Value) LOG_FUNC_END; - RETURN(InterlockedExchange((NtDll::PLONG)Destination, (NtDll::LONG)Value)); + LONG res = InterlockedExchange((NtDll::PLONG)Destination, (NtDll::LONG)Value); + + RETURN(res); } // ****************************************************************** @@ -210,7 +218,9 @@ XBSYSAPI EXPORTNUM(55) xboxkrnl::LONG FASTCALL xboxkrnl::KRNL(InterlockedExchang LOG_FUNC_ARG(Value) LOG_FUNC_END; - RETURN(InterlockedExchangeAdd((NtDll::PLONG)Addend, (NtDll::LONG)Value)); + LONG res = InterlockedExchangeAdd((NtDll::PLONG)Addend, (NtDll::LONG)Value); + + RETURN(res); } // ****************************************************************** @@ -225,7 +235,9 @@ XBSYSAPI EXPORTNUM(56) xboxkrnl::PSINGLE_LIST_ENTRY FASTCALL xboxkrnl::KRNL(Inte { LOG_FUNC_ONE_ARG(ListHead); - RETURN((xboxkrnl::PSINGLE_LIST_ENTRY)InterlockedFlushSList((::PSLIST_HEADER)ListHead)); + PSINGLE_LIST_ENTRY res = (PSINGLE_LIST_ENTRY)InterlockedFlushSList((::PSLIST_HEADER)ListHead); + + RETURN(res); } // ****************************************************************** @@ -239,7 +251,9 @@ XBSYSAPI EXPORTNUM(57) xboxkrnl::PSLIST_ENTRY FASTCALL xboxkrnl::KRNL(Interlocke { LOG_FUNC_ONE_ARG(ListHead); - RETURN((PSLIST_ENTRY)InterlockedPopEntrySList((::PSLIST_HEADER)ListHead)); + PSLIST_ENTRY res = (PSLIST_ENTRY)InterlockedPopEntrySList((::PSLIST_HEADER)ListHead); + + RETURN(res); } // ****************************************************************** @@ -257,7 +271,9 @@ XBSYSAPI EXPORTNUM(58) xboxkrnl::PSLIST_ENTRY FASTCALL xboxkrnl::KRNL(Interlocke LOG_FUNC_ARG(ListEntry) LOG_FUNC_END; - RETURN((xboxkrnl::PSLIST_ENTRY)InterlockedPushEntrySList((::PSLIST_HEADER)ListHead, (::PSLIST_ENTRY)ListEntry)); + PSLIST_ENTRY res = (PSLIST_ENTRY)InterlockedPushEntrySList((::PSLIST_HEADER)ListHead, (::PSLIST_ENTRY)ListEntry); + + RETURN(res); } // ****************************************************************** @@ -415,10 +431,14 @@ XBSYSAPI EXPORTNUM(369) xboxkrnl::NTSTATUS NTAPI xboxkrnl::UnknownAPI369 // ****************************************************************** XBSYSAPI EXPORTNUM(370) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XProfpControl // PROFILING ( - // UNKNOWN ARGUMENTS + ULONG Action, + ULONG Param ) { - LOG_FUNC(); + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Action) + LOG_FUNC_ARG(Param) + LOG_FUNC_END; LOG_UNIMPLEMENTED(); @@ -430,7 +450,7 @@ XBSYSAPI EXPORTNUM(370) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XProfpControl // PROF // ****************************************************************** XBSYSAPI EXPORTNUM(371) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XProfpGetData // PROFILING ( - // UNKNOWN ARGUMENTS + // NO ARGUMENTS ) { LOG_FUNC(); diff --git a/src/CxbxKrnl/EmuKrnlEx.cpp b/src/CxbxKrnl/EmuKrnlEx.cpp index bf874cfe0..a19f0152d 100644 --- a/src/CxbxKrnl/EmuKrnlEx.cpp +++ b/src/CxbxKrnl/EmuKrnlEx.cpp @@ -55,6 +55,7 @@ namespace NtDll #include "CxbxKrnl.h" // For CxbxKrnlCleanup #include "Emu.h" // For EmuWarning() #include "EmuAlloc.h" // For CxbxFree(), CxbxCalloc(), etc. +#include "EmuKrnl.h" // For InsertHeadList, InsertTailList, RemoveHeadList #pragma warning(disable:4005) // Ignore redefined status values #include // For STATUS_BUFFER_TOO_SMALL @@ -161,16 +162,19 @@ XBSYSAPI EXPORTNUM(17) xboxkrnl::VOID NTAPI xboxkrnl::ExFreePool // * 0x0012 - ExInitializeReadWriteLock() // ****************************************************************** // Source:APILogger - Uncertain -XBSYSAPI EXPORTNUM(18) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ExInitializeReadWriteLock +XBSYSAPI EXPORTNUM(18) xboxkrnl::VOID NTAPI xboxkrnl::ExInitializeReadWriteLock ( IN PERWLOCK ReadWriteLock ) { LOG_FUNC_ONE_ARG(ReadWriteLock); - LOG_UNIMPLEMENTED(); - - RETURN(S_OK); + ReadWriteLock->LockCount = -1; + ReadWriteLock->WritersWaitingCount = 0; + ReadWriteLock->ReadersWaitingCount = 0; + ReadWriteLock->ReadersEntryCount = 0; + KeInitializeEvent(&ReadWriteLock->WriterEvent, SynchronizationEvent, FALSE); + KeInitializeSemaphore(&ReadWriteLock->ReaderSemaphore, 0, MAXLONG); } // ****************************************************************** @@ -597,19 +601,31 @@ XBSYSAPI EXPORTNUM(31) xboxkrnl::OBJECT_TYPE xboxkrnl::ExTimerObjectType = XBSYSAPI EXPORTNUM(32) xboxkrnl::PLIST_ENTRY FASTCALL xboxkrnl::ExfInterlockedInsertHeadList ( IN PLIST_ENTRY ListHead, - IN PLIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock + IN PLIST_ENTRY ListEntry ) { LOG_FUNC_BEGIN LOG_FUNC_ARG(ListHead) LOG_FUNC_ARG(ListEntry) - LOG_FUNC_ARG(Lock) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + /* Disable interrupts and acquire the spinlock */ + // BOOLEAN Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); + LOG_INCOMPLETE(); // TODO : Lock - RETURN(ListHead); + /* Save the first entry */ + PLIST_ENTRY FirstEntry = ListHead->Flink; + /* Insert the new entry */ + InsertHeadList(ListHead, ListEntry); + + /* Release the spinlock and restore interrupts */ + // _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); + + /* Return the old first entry or NULL for empty list */ + if (FirstEntry == ListHead) + FirstEntry = NULL; + + RETURN(FirstEntry); } // ****************************************************************** @@ -619,19 +635,32 @@ XBSYSAPI EXPORTNUM(32) xboxkrnl::PLIST_ENTRY FASTCALL xboxkrnl::ExfInterlockedIn XBSYSAPI EXPORTNUM(33) xboxkrnl::PLIST_ENTRY FASTCALL xboxkrnl::ExfInterlockedInsertTailList ( IN PLIST_ENTRY ListHead, - IN PLIST_ENTRY ListEntry, - IN PKSPIN_LOCK Lock + IN PLIST_ENTRY ListEntry ) { LOG_FUNC_BEGIN LOG_FUNC_ARG(ListHead) LOG_FUNC_ARG(ListEntry) - LOG_FUNC_ARG(Lock) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + /* Disable interrupts and acquire the spinlock */ + // BOOLEAN Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); + LOG_INCOMPLETE(); // TODO : Lock - RETURN(ListHead); + /* Save the last entry */ + PLIST_ENTRY LastEntry = ListHead->Blink; + + /* Insert the new entry */ + InsertTailList(ListHead, ListEntry); + + /* Release the spinlock and restore interrupts */ + // _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); + + /* Return the old last entry or NULL for empty list */ + if (LastEntry == ListHead) + LastEntry = NULL; + + RETURN(LastEntry); } // ****************************************************************** @@ -640,16 +669,37 @@ XBSYSAPI EXPORTNUM(33) xboxkrnl::PLIST_ENTRY FASTCALL xboxkrnl::ExfInterlockedIn // Source:ReactOS XBSYSAPI EXPORTNUM(34) xboxkrnl::PLIST_ENTRY FASTCALL xboxkrnl::ExfInterlockedRemoveHeadList ( - IN PLIST_ENTRY ListHead, - IN PKSPIN_LOCK Lock + IN PLIST_ENTRY ListHead ) { - LOG_FUNC_BEGIN - LOG_FUNC_ARG(ListHead) - LOG_FUNC_ARG(Lock) - LOG_FUNC_END; + LOG_FUNC_ONE_ARG(ListHead); - LOG_UNIMPLEMENTED(); + /* Disable interrupts and acquire the spinlock */ + // BOOLEAN Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); + LOG_INCOMPLETE(); // TODO : Lock + + PLIST_ENTRY ListEntry; + + /* Check if the list is empty */ + if (IsListEmpty(ListHead)) + { + /* Return NULL */ + ListEntry = NULL; + } + else + { + /* Remove the first entry from the list head */ + ListEntry = RemoveHeadList(ListHead); +#if DBG + ListEntry->Flink = (PLIST_ENTRY)0xBADDD0FF; + ListEntry->Blink = (PLIST_ENTRY)0xBADDD0FF; +#endif + } + + /* Release the spinlock and restore interrupts */ + // _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); + + /* Return the entry */ + RETURN(ListEntry); - RETURN(ListHead); } diff --git a/src/CxbxKrnl/EmuKrnlHal.cpp b/src/CxbxKrnl/EmuKrnlHal.cpp index 63469e433..43727a34a 100644 --- a/src/CxbxKrnl/EmuKrnlHal.cpp +++ b/src/CxbxKrnl/EmuKrnlHal.cpp @@ -247,15 +247,13 @@ XBSYSAPI EXPORTNUM(45) xboxkrnl::NTSTATUS NTAPI xboxkrnl::HalReadSMBusValue LOG_FUNC_ARG_OUT(DataValue) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); - if (ReadWord) { - // Write UCHAR + LOG_INCOMPLETE(); // TODO : Read UCHAR, possibly as simple as: *((PWORD)DataValue) = value } else { - // Write BYTE + // Read BYTE if (DataValue) - *DataValue = 1; + *DataValue = 1; // TODO : What value? } RETURN(STATUS_SUCCESS); @@ -434,7 +432,8 @@ XBSYSAPI EXPORTNUM(329) xboxkrnl::VOID NTAPI xboxkrnl::READ_PORT_BUFFER_UCHAR LOG_FUNC_ARG(Count) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + while (Count-- > 0) + *Buffer++ = EmuX86_IORead8((xbaddr)Port); } // ****************************************************************** @@ -453,7 +452,8 @@ XBSYSAPI EXPORTNUM(330) xboxkrnl::VOID NTAPI xboxkrnl::READ_PORT_BUFFER_USHORT LOG_FUNC_ARG(Count) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + while (Count-- > 0) + *Buffer++ = EmuX86_IORead16((xbaddr)Port); } // ****************************************************************** @@ -472,7 +472,8 @@ XBSYSAPI EXPORTNUM(331) xboxkrnl::VOID NTAPI xboxkrnl::READ_PORT_BUFFER_ULONG LOG_FUNC_ARG(Count) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + while (Count-- > 0) + *Buffer++ = EmuX86_IORead32((xbaddr)Port); } // ****************************************************************** @@ -491,7 +492,8 @@ XBSYSAPI EXPORTNUM(332) xboxkrnl::VOID NTAPI xboxkrnl::WRITE_PORT_BUFFER_UCHAR LOG_FUNC_ARG(Count) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + while (Count-- > 0) + EmuX86_IOWrite8((xbaddr)Port, *Buffer++); } // ****************************************************************** @@ -510,7 +512,8 @@ XBSYSAPI EXPORTNUM(333) xboxkrnl::VOID NTAPI xboxkrnl::WRITE_PORT_BUFFER_USHORT LOG_FUNC_ARG(Count) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + while (Count-- > 0) + EmuX86_IOWrite16((xbaddr)Port, *Buffer++); } // ****************************************************************** @@ -529,7 +532,8 @@ XBSYSAPI EXPORTNUM(334) xboxkrnl::VOID NTAPI xboxkrnl::WRITE_PORT_BUFFER_ULONG LOG_FUNC_ARG(Count) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + while (Count-- > 0) + EmuX86_IOWrite32((xbaddr)Port, *Buffer++); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlKe.cpp b/src/CxbxKrnl/EmuKrnlKe.cpp index 53a151022..1d873e295 100644 --- a/src/CxbxKrnl/EmuKrnlKe.cpp +++ b/src/CxbxKrnl/EmuKrnlKe.cpp @@ -72,6 +72,13 @@ typedef struct _DpcData { DpcData g_DpcData = { 0 }; // Note : g_DpcData is initialized in InitDpcAndTimerThread() +xboxkrnl::ULONGLONG LARGE_INTEGER2ULONGLONG(xboxkrnl::LARGE_INTEGER value) +{ + // Weird construction because there doesn't seem to exist an implicit + // conversion of LARGE_INTEGER to ULONGLONG : + return *((PULONGLONG)&value); +} + // TODO : Move all Ki* functions to EmuKrnlKi.h/cpp : #define KiRemoveTreeTimer(Timer) \ @@ -620,6 +627,53 @@ XBSYSAPI EXPORTNUM(109) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeInterrupt // struct and calls the right dispatch routine (depending on InterruptMode). } +// ****************************************************************** +// * 0x006F - KeInitializeQueue() +// ****************************************************************** +XBSYSAPI EXPORTNUM(111) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeQueue +( + IN PKQUEUE Queue, + IN ULONG Count OPTIONAL +) +{ + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Queue) + LOG_FUNC_ARG(Count) + LOG_FUNC_END; + + Queue->Header.Type = QueueObject; + Queue->Header.Size = sizeof(KQUEUE) / sizeof(LONG); + Queue->Header.SignalState = 0; + InitializeListHead(&Queue->Header.WaitListHead); + InitializeListHead(&Queue->EntryListHead); + InitializeListHead(&Queue->ThreadListHead); + Queue->CurrentCount = 0; + Queue->MaximumCount = (Count > 1) ? Count : 1; +} + +// ****************************************************************** +// * 0x0070 - KeInitializeSemaphore() +// ****************************************************************** +XBSYSAPI EXPORTNUM(112) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeSemaphore +( + IN PRKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit +) +{ + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Semaphore) + LOG_FUNC_ARG(Count) + LOG_FUNC_ARG(Limit) + LOG_FUNC_END; + + Semaphore->Header.Type = SemaphoreObject; + Semaphore->Header.Size = sizeof(KSEMAPHORE) / sizeof(LONG); + Semaphore->Header.SignalState = Count; + InitializeListHead(&Semaphore->Header.WaitListHead); + Semaphore->Limit = Limit; +} + // ****************************************************************** // * 0x0071 - KeInitializeTimerEx() // ****************************************************************** @@ -738,6 +792,8 @@ XBSYSAPI EXPORTNUM(125) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryInterruptTime // in which case we should not LOG_FUNC nor RETURN (use normal return instead). LOG_FUNC(); + ULONGLONG ret; + LARGE_INTEGER InterruptTime; while (true) @@ -755,9 +811,8 @@ XBSYSAPI EXPORTNUM(125) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryInterruptTime break; } - // Weird construction because there doesn't seem to exist an implicit - // conversion of LARGE_INTEGER to ULONGLONG : - RETURN(*((PULONGLONG)&InterruptTime)); + ret = LARGE_INTEGER2ULONGLONG(InterruptTime); + RETURN(ret); } // ****************************************************************** @@ -767,6 +822,7 @@ XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCo { LOG_FUNC(); + ULONGLONG ret; ::LARGE_INTEGER PerformanceCounter; // TODO : When Cxbx emulates the RDTSC opcode, use the same handling here. @@ -781,7 +837,8 @@ XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCo // We appy a conversion factor here, to fake Xbox1-like increment-speed behaviour : PerformanceCounter.QuadPart = (ULONGLONG)(NativeToXbox_FactorForPerformanceFrequency * PerformanceCounter.QuadPart); - RETURN(PerformanceCounter.QuadPart); + ret = PerformanceCounter.QuadPart; + RETURN(ret); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlNt.cpp b/src/CxbxKrnl/EmuKrnlNt.cpp index 3714771c8..5d20b5797 100644 --- a/src/CxbxKrnl/EmuKrnlNt.cpp +++ b/src/CxbxKrnl/EmuKrnlNt.cpp @@ -167,6 +167,8 @@ XBSYSAPI EXPORTNUM(187) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtClose // delete 'special' handles EmuHandle *iEmuHandle = HandleToEmuHandle(Handle); ret = iEmuHandle->NtClose(); + + LOG_UNIMPLEMENTED(); // TODO : Base this on the Ob* functions } else // close normal handles @@ -231,6 +233,7 @@ XBSYSAPI EXPORTNUM(189) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateEvent LOG_FUNC_ARG(EventType) LOG_FUNC_ARG(InitialState) LOG_FUNC_END; + /* NTSTATUS Status; @@ -239,8 +242,8 @@ XBSYSAPI EXPORTNUM(189) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateEvent } else { PKEVENT Event; - Status = ObCreateObject(&ExEventObjectType, ObjectAttributes, sizeof(KEVENT), (PVOID *)&Event); + Status = ObCreateObject(&ExEventObjectType, ObjectAttributes, sizeof(KEVENT), (PVOID *)&Event); if (NT_SUCCESS(Status)) { KeInitializeEvent(Event, EventType, InitialState); Status = ObInsertObject(Event, ObjectAttributes, 0, EventHandle); @@ -249,6 +252,8 @@ XBSYSAPI EXPORTNUM(189) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateEvent RETURN(Status); */ + LOG_INCOMPLETE(); // TODO : Verify arguments, use ObCreateObject, KeInitializeEvent and ObInsertObject instead of this: + // initialize object attributes NativeObjectAttributes nativeObjectAttributes; CxbxObjectAttributesToNT(ObjectAttributes, /*var*/nativeObjectAttributes); @@ -293,6 +298,8 @@ XBSYSAPI EXPORTNUM(190) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateFile { LOG_FORWARD("IoCreateFile"); + // TODO : How to base this on ObCreateObject, KeInitialize and ObInsertObject ? + return xboxkrnl::IoCreateFile( FileHandle, DesiredAccess, @@ -322,6 +329,26 @@ XBSYSAPI EXPORTNUM(192) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateMutant LOG_FUNC_ARG(InitialOwner) LOG_FUNC_END; +/* + NTSTATUS Status; + + if (!verify arguments) { + Status = STATUS_INVALID_PARAMETER; + } + else { + PKMUTANT Mutant; + + Status = ObCreateObject(&ExMutantObjectType, ObjectAttributes, sizeof(KMUTANT), (PVOID *)&Mutant); + if (NT_SUCCESS(Status)) { + KeInitializeMutant(Mutant, InitialOwner); + Status = ObInsertObject(Mutant, ObjectAttributes, 0, /*OUT* /MutantHandle); + } + } + + RETURN(Status); +*/ + LOG_INCOMPLETE(); // TODO : Verify arguments, use ObCreateObject, KeInitializeMutant and ObInsertObject instead of this: + // initialize object attributes NativeObjectAttributes nativeObjectAttributes; CxbxObjectAttributesToNT(ObjectAttributes, /*var*/nativeObjectAttributes); @@ -362,6 +389,26 @@ XBSYSAPI EXPORTNUM(193) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateSemaphore LOG_FUNC_ARG(MaximumCount) LOG_FUNC_END; +/* + NTSTATUS Status; + + if (!verify arguments) { + Status = STATUS_INVALID_PARAMETER; + } + else { + PKSEMAPHORE Semaphore; + + Status = ObCreateObject(&ExSemaphoreObjectType, ObjectAttributes, sizeof(KSEMAPHORE), (PVOID *)&Semaphore); + if (NT_SUCCESS(Status)) { + KeInitializeSemaphore(Semaphore, InitialCount, /*Limit=* /MaximumCount); + Status = ObInsertObject(Semaphore, ObjectAttributes, 0, /*OUT* /SemaphoreHandle); + } + } + + RETURN(Status); +*/ + LOG_INCOMPLETE(); // TODO : Verify arguments, use ObCreateObject, KeInitializeSemaphore and ObInsertObject instead of this: + // TODO : Is this the correct ACCESS_MASK? : const ACCESS_MASK DesiredAccess = SEMAPHORE_ALL_ACCESS; @@ -400,6 +447,26 @@ XBSYSAPI EXPORTNUM(194) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateTimer LOG_FUNC_ARG(TimerType) LOG_FUNC_END; +/* + NTSTATUS Status; + + if (!verify arguments) { + Status = STATUS_INVALID_PARAMETER; + } + else { + PKTIMER Timer; + + Status = ObCreateObject(&ExTimerType, ObjectAttributes, sizeof(KTIMER), (PVOID *)&Timer); + if (NT_SUCCESS(Status)) { + KeInitializeTimerEx(Timer, TimerType); + Status = ObInsertObject(Timer, ObjectAttributes, 0, /*OUT* /TimerHandle); + } + } + + RETURN(Status); +*/ + LOG_INCOMPLETE(); // TODO : Verify arguments, use ObCreateObject, KeInitializeTimerEx and ObInsertObject instead of this: + // TODO : Is this the correct ACCESS_MASK? : const ACCESS_MASK DesiredAccess = TIMER_ALL_ACCESS; @@ -525,6 +592,20 @@ XBSYSAPI EXPORTNUM(197) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtDuplicateObject if (IsEmuHandle(SourceHandle)) { EmuHandle* iEmuHandle = HandleToEmuHandle(SourceHandle); ret = iEmuHandle->NtDuplicateObject(TargetHandle, Options); +/* + PVOID Object; + + ret = ObReferenceObjectByHandle(SourceHandle, /*ObjectType=* /NULL, &Object); + if (NT_SUCCESS(ret)) { + if (ObpIsFlagSet(Options, DUPLICATE_CLOSE_SOURCE)) + NtClose(SourceHandle); + + status = ObOpenObjectByPointer(Object, OBJECT_TO_OBJECT_HEADER(Object)->Type, /*OUT* /TargetHandle); + ObDereferenceObject(Object); + } + else + *TargetHandle = NULL; +*/ } else { diff --git a/src/CxbxKrnl/EmuKrnlOb.cpp b/src/CxbxKrnl/EmuKrnlOb.cpp index 073d9a9e5..f671400a0 100644 --- a/src/CxbxKrnl/EmuKrnlOb.cpp +++ b/src/CxbxKrnl/EmuKrnlOb.cpp @@ -62,6 +62,7 @@ namespace NtDll #pragma warning(default:4005) #define OB_FLAG_NAMED_OBJECT 1 +#define OB_FLAG_PERMANENT_OBJECT 2 // ****************************************************************** // * 0x00EF - ObCreateObject() @@ -196,7 +197,21 @@ XBSYSAPI EXPORTNUM(242) xboxkrnl::VOID NTAPI xboxkrnl::ObMakeTemporaryObject { LOG_FUNC_ONE_ARG(Object); - LOG_UNIMPLEMENTED(); + /* Get the header */ + POBJECT_HEADER ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + + /* Acquire object lock */ + //ObpAcquireObjectLock(ObjectHeader); + LOG_INCOMPLETE(); // TODO : Lock, etc. + + /* Remove the flag */ + ObjectHeader->Flags &= ~OB_FLAG_PERMANENT_OBJECT; + + /* Release the lock */ + // ObpReleaseObjectLock(ObjectHeader); + + /* Check if we should delete the object now */ + //ObpDeleteNameCheck(ObjectBody); } // ****************************************************************** @@ -422,5 +437,3 @@ XBSYSAPI EXPORTNUM(251) xboxkrnl::VOID FASTCALL xboxkrnl::ObfReferenceObject InterlockedIncrement(&ObjectHeader->PointerCount); } - - diff --git a/src/CxbxKrnl/EmuKrnlRtl.cpp b/src/CxbxKrnl/EmuKrnlRtl.cpp index 1b9b172a8..63ca8a253 100644 --- a/src/CxbxKrnl/EmuKrnlRtl.cpp +++ b/src/CxbxKrnl/EmuKrnlRtl.cpp @@ -436,6 +436,23 @@ XBSYSAPI EXPORTNUM(277) xboxkrnl::VOID NTAPI xboxkrnl::RtlEnterCriticalSection } } +// ****************************************************************** +// * 0x0116 - RtlEnterCriticalSectionAndRegion() +// ****************************************************************** +XBSYSAPI EXPORTNUM(278) xboxkrnl::VOID NTAPI xboxkrnl::RtlEnterCriticalSectionAndRegion +( + IN PRTL_CRITICAL_SECTION CriticalSection +) +{ + /** sorta pointless + LOG_FUNC_ONE_ARG(CriticalSection); + //*/ + + LOG_INCOMPLETE(); // TODO : How to enter region? + + RtlEnterCriticalSection(CriticalSection); +} + // ****************************************************************** // * 0x0117 - RtlEqualString() // ****************************************************************** @@ -753,6 +770,10 @@ XBSYSAPI EXPORTNUM(294) xboxkrnl::VOID NTAPI xboxkrnl::RtlLeaveCriticalSection return; } + /* sorta pointless + LOG_FUNC_ONE_ARG(CriticalSection); + //*/ + int iSection = FindCriticalSection(CriticalSection); if (iSection >= 0) @@ -764,12 +785,26 @@ XBSYSAPI EXPORTNUM(294) xboxkrnl::VOID NTAPI xboxkrnl::RtlLeaveCriticalSection CriticalSection->RecursionCount = GlobalCriticalSections[iSection].NativeCriticalSection.RecursionCount; CriticalSection->OwningThread = GlobalCriticalSections[iSection].NativeCriticalSection.OwningThread; } + // Note: We need to execute this before debug output to avoid trouble //NtDll::RtlLeaveCriticalSection((NtDll::_RTL_CRITICAL_SECTION*)CriticalSection); +} - /* sorta pointless +// ****************************************************************** +// * 0x0127 - RtlLeaveCriticalSectionAndRegion() +// ****************************************************************** +XBSYSAPI EXPORTNUM(295) xboxkrnl::VOID NTAPI xboxkrnl::RtlLeaveCriticalSectionAndRegion +( + IN PRTL_CRITICAL_SECTION CriticalSection +) +{ + /** sorta pointless LOG_FUNC_ONE_ARG(CriticalSection); //*/ + + RtlLeaveCriticalSection(CriticalSection); + + LOG_INCOMPLETE(); // TODO : How to leave region? } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlXe.cpp b/src/CxbxKrnl/EmuKrnlXe.cpp index 0b508aa78..f1d0da046 100644 --- a/src/CxbxKrnl/EmuKrnlXe.cpp +++ b/src/CxbxKrnl/EmuKrnlXe.cpp @@ -78,10 +78,9 @@ XBSYSAPI EXPORTNUM(327) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XeLoadSection NTSTATUS ret = STATUS_SUCCESS; - if (Section->SectionReferenceCount > 0) - Section->SectionReferenceCount++; - else - LOG_UNIMPLEMENTED(); + if (Section->SectionReferenceCount++ == 0) { + LOG_INCOMPLETE(); // TODO : Load section - probably lock this too + } RETURN(ret); } @@ -104,14 +103,13 @@ XBSYSAPI EXPORTNUM(328) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XeUnloadSection NTSTATUS ret = STATUS_SUCCESS; - if (Section->SectionReferenceCount > 0) - Section->SectionReferenceCount--; - else - { - LOG_UNIMPLEMENTED(); - ret = STATUS_INVALID_PARAMETER; + if (Section->SectionReferenceCount > 0) { + if (--Section->SectionReferenceCount == 0) { + LOG_INCOMPLETE(); // TODO : Unload section - probably lock this too + } } - + else + ret = STATUS_INVALID_PARAMETER; RETURN(ret); } diff --git a/src/CxbxKrnl/KernelThunk.cpp b/src/CxbxKrnl/KernelThunk.cpp index 33246af05..26754590a 100644 --- a/src/CxbxKrnl/KernelThunk.cpp +++ b/src/CxbxKrnl/KernelThunk.cpp @@ -178,8 +178,8 @@ extern "C" CXBXKRNL_API uint32 CxbxKrnl_KernelThunkTable[379] = (uint32)FUNC(&xboxkrnl::KeInitializeEvent), // 0x006C (108) (uint32)FUNC(&xboxkrnl::KeInitializeInterrupt), // 0x006D (109) (uint32)PANIC(0x006E), // 0x006E (110) KeInitializeMutant - (uint32)PANIC(0x006F), // 0x006F (111) KeInitializeQueue - (uint32)PANIC(0x0070), // 0x0070 (112) KeInitializeSemaphore + (uint32)FUNC(&xboxkrnl::KeInitializeQueue), // 0x006F (111) + (uint32)FUNC(&xboxkrnl::KeInitializeSemaphore), // 0x0070 (112) (uint32)FUNC(&xboxkrnl::KeInitializeTimerEx), // 0x0071 (113) (uint32)PANIC(0x0072), // 0x0072 (114) KeInsertByKeyDeviceQueue (uint32)PANIC(0x0073), // 0x0073 (115) KeInsertDeviceQueue @@ -345,7 +345,7 @@ extern "C" CXBXKRNL_API uint32 CxbxKrnl_KernelThunkTable[379] = (uint32)FUNC(&xboxkrnl::RtlDowncaseUnicodeChar), // 0x0113 (275) (uint32)FUNC(&xboxkrnl::RtlDowncaseUnicodeString), // 0x0114 (276) (uint32)FUNC(&xboxkrnl::RtlEnterCriticalSection), // 0x0115 (277) - (uint32)PANIC(0x0116), // 0x0116 (278) RtlEnterCriticalSectionAndRegion + (uint32)FUNC(&xboxkrnl::RtlEnterCriticalSectionAndRegion), // 0x0116 (278) (uint32)FUNC(&xboxkrnl::RtlEqualString), // 0x0117 (279) (uint32)FUNC(&xboxkrnl::RtlEqualUnicodeString), // 0x0118 (280) (uint32)FUNC(&xboxkrnl::RtlExtendedIntegerMultiply), // 0x0119 (281) @@ -362,7 +362,7 @@ extern "C" CXBXKRNL_API uint32 CxbxKrnl_KernelThunkTable[379] = (uint32)FUNC(&xboxkrnl::RtlIntegerToChar), // 0x0124 (292) (uint32)FUNC(&xboxkrnl::RtlIntegerToUnicodeString), // 0x0125 (293) (uint32)FUNC(&xboxkrnl::RtlLeaveCriticalSection), // 0x0126 (294) - (uint32)PANIC(0x0127), // 0x0127 (295) RtlLeaveCriticalSectionAndRegion + (uint32)FUNC(&xboxkrnl::RtlLeaveCriticalSectionAndRegion), // 0x0127 (295) (uint32)FUNC(&xboxkrnl::RtlLowerChar), // 0x0128 (296) (uint32)FUNC(&xboxkrnl::RtlMapGenericMask), // 0x0129 (297) (uint32)FUNC(&xboxkrnl::RtlMoveMemory), // 0x012A (298)