diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 9d91891b8..4769b8df3 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -1348,38 +1348,31 @@ SHIM_CALL KeRemoveQueueDpc_shim(PPCContext* ppc_context, xe::mutex global_list_mutex_; -// http://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html -struct SLIST_HEADER { - xe::be next; - xe::be depth; - xe::be sequence; -}; - -pointer_result_t InterlockedPopEntrySList(pointer_t plist_ptr) { +pointer_result_t InterlockedPopEntrySList(pointer_t plist_ptr) { std::lock_guard lock(global_list_mutex_); - uint32_t first = plist_ptr->next; - if (first == 0) { + if (plist_ptr->next.next == 0) { // List empty! return 0; } - // Get the second element. - uint8_t* p = kernel_memory()->TranslateVirtual(first); - auto second = xe::load_and_swap(p); + // Get the first element. + auto result = kernel_memory()->TranslateVirtual( + plist_ptr->next.next); - plist_ptr->next = second; + uint32_t popped = plist_ptr->next.next; + plist_ptr->next.next = result->next; // Return the one we popped - return first; + return popped; } DECLARE_XBOXKRNL_EXPORT(InterlockedPopEntrySList, ExportTag::kImplemented); -pointer_result_t InterlockedFlushSList(pointer_t plist_ptr) { +pointer_result_t InterlockedFlushSList(pointer_t plist_ptr) { std::lock_guard lock(global_list_mutex_); - uint32_t next = plist_ptr->next; - plist_ptr->next = 0; + uint32_t next = plist_ptr->next.next; + plist_ptr->next.next = 0; return next; } diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 671bc4c9f..5c24c965a 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -280,9 +280,9 @@ struct X_ANSI_STRING { }; struct X_UNICODE_STRING { - xe::be length; - xe::be maximum_length; - xe::be pointer; + xe::be length; // 0x0 + xe::be maximum_length; // 0x2 + xe::be pointer; // 0x4 void reset() { length = 0; @@ -322,9 +322,28 @@ static_assert_size(X_VIDEO_MODE, 48); struct X_LIST_ENTRY { be flink_ptr; // next entry / head be blink_ptr; // previous entry / head + + // Assumes X_LIST_ENTRY is within guest memory! + void initialize(uint8_t* virtual_membase) { + flink_ptr = (uint32_t)((uint8_t*)this - virtual_membase); + blink_ptr = (uint32_t)((uint8_t*)this - virtual_membase); + } }; static_assert_size(X_LIST_ENTRY, 8); +struct X_SINGLE_LIST_ENTRY { + be next; // 0x0 pointer to next entry +}; +static_assert_size(X_SINGLE_LIST_ENTRY, 4); + +// http://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html +struct X_SLIST_HEADER { + X_SINGLE_LIST_ENTRY next; // 0x0 + be depth; // 0x4 + be sequence; // 0x6 +}; +static_assert_size(X_SLIST_HEADER, 8); + #pragma pack(pop) } // namespace xe