Rewrite InterlockedPopEntrySList
This commit is contained in:
parent
870aa092bb
commit
6ddd0b4700
|
@ -1348,38 +1348,31 @@ SHIM_CALL KeRemoveQueueDpc_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
xe::mutex global_list_mutex_;
|
xe::mutex global_list_mutex_;
|
||||||
|
|
||||||
// http://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html
|
pointer_result_t InterlockedPopEntrySList(pointer_t<X_SLIST_HEADER> plist_ptr) {
|
||||||
struct SLIST_HEADER {
|
|
||||||
xe::be<uint32_t> next;
|
|
||||||
xe::be<uint16_t> depth;
|
|
||||||
xe::be<uint16_t> sequence;
|
|
||||||
};
|
|
||||||
|
|
||||||
pointer_result_t InterlockedPopEntrySList(pointer_t<SLIST_HEADER> plist_ptr) {
|
|
||||||
std::lock_guard<xe::mutex> lock(global_list_mutex_);
|
std::lock_guard<xe::mutex> lock(global_list_mutex_);
|
||||||
|
|
||||||
uint32_t first = plist_ptr->next;
|
if (plist_ptr->next.next == 0) {
|
||||||
if (first == 0) {
|
|
||||||
// List empty!
|
// List empty!
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the second element.
|
// Get the first element.
|
||||||
uint8_t* p = kernel_memory()->TranslateVirtual(first);
|
auto result = kernel_memory()->TranslateVirtual<X_SINGLE_LIST_ENTRY*>(
|
||||||
auto second = xe::load_and_swap<uint32_t>(p);
|
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 the one we popped
|
||||||
return first;
|
return popped;
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT(InterlockedPopEntrySList, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(InterlockedPopEntrySList, ExportTag::kImplemented);
|
||||||
|
|
||||||
pointer_result_t InterlockedFlushSList(pointer_t<SLIST_HEADER> plist_ptr) {
|
pointer_result_t InterlockedFlushSList(pointer_t<X_SLIST_HEADER> plist_ptr) {
|
||||||
std::lock_guard<xe::mutex> lock(global_list_mutex_);
|
std::lock_guard<xe::mutex> lock(global_list_mutex_);
|
||||||
|
|
||||||
uint32_t next = plist_ptr->next;
|
uint32_t next = plist_ptr->next.next;
|
||||||
plist_ptr->next = 0;
|
plist_ptr->next.next = 0;
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,9 +280,9 @@ struct X_ANSI_STRING {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct X_UNICODE_STRING {
|
struct X_UNICODE_STRING {
|
||||||
xe::be<uint16_t> length;
|
xe::be<uint16_t> length; // 0x0
|
||||||
xe::be<uint16_t> maximum_length;
|
xe::be<uint16_t> maximum_length; // 0x2
|
||||||
xe::be<uint32_t> pointer;
|
xe::be<uint32_t> pointer; // 0x4
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
length = 0;
|
length = 0;
|
||||||
|
@ -322,9 +322,28 @@ static_assert_size(X_VIDEO_MODE, 48);
|
||||||
struct X_LIST_ENTRY {
|
struct X_LIST_ENTRY {
|
||||||
be<uint32_t> flink_ptr; // next entry / head
|
be<uint32_t> flink_ptr; // next entry / head
|
||||||
be<uint32_t> blink_ptr; // previous entry / head
|
be<uint32_t> 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);
|
static_assert_size(X_LIST_ENTRY, 8);
|
||||||
|
|
||||||
|
struct X_SINGLE_LIST_ENTRY {
|
||||||
|
be<uint32_t> 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<uint16_t> depth; // 0x4
|
||||||
|
be<uint16_t> sequence; // 0x6
|
||||||
|
};
|
||||||
|
static_assert_size(X_SLIST_HEADER, 8);
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
Loading…
Reference in New Issue