mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 08:27:18 +00:00
ntdll: Implement the cross-process work list functions.
This commit is contained in:
parent
dbe7788817
commit
049fb065c4
|
@ -1108,6 +1108,11 @@
|
|||
@ stdcall -arch=win64 RtlWow64GetThreadContext(long ptr)
|
||||
@ stdcall -arch=win64 RtlWow64GetThreadSelectorEntry(long ptr long ptr)
|
||||
@ stdcall RtlWow64IsWowGuestMachineSupported(long ptr)
|
||||
@ stdcall -arch=win64 RtlWow64PopAllCrossProcessWorkFromWorkList(ptr ptr)
|
||||
@ stdcall -arch=win64 RtlWow64PopCrossProcessWorkFromFreeList(ptr)
|
||||
@ stdcall -arch=win64 RtlWow64PushCrossProcessWorkOntoFreeList(ptr ptr)
|
||||
@ stdcall -arch=win64 RtlWow64PushCrossProcessWorkOntoWorkList(ptr ptr ptr)
|
||||
@ stdcall -arch=win64 RtlWow64RequestCrossProcessHeavyFlush(ptr)
|
||||
@ stdcall -arch=win64 RtlWow64SetThreadContext(long ptr)
|
||||
@ stub RtlWriteMemoryStream
|
||||
@ stdcall RtlWriteRegistryValue(long ptr wstr long ptr long)
|
||||
|
|
|
@ -302,7 +302,119 @@ done:
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* RtlWow64PopAllCrossProcessWorkFromWorkList (NTDLL.@)
|
||||
*/
|
||||
CROSS_PROCESS_WORK_ENTRY * WINAPI RtlWow64PopAllCrossProcessWorkFromWorkList( CROSS_PROCESS_WORK_HDR *list, BOOLEAN *flush )
|
||||
{
|
||||
CROSS_PROCESS_WORK_HDR prev, new;
|
||||
UINT pos, prev_pos = 0;
|
||||
|
||||
do
|
||||
{
|
||||
prev.hdr = list->hdr;
|
||||
if (!prev.first) break;
|
||||
new.first = 0;
|
||||
new.counter = prev.counter + 1;
|
||||
} while (InterlockedCompareExchange64( &list->hdr, new.hdr, prev.hdr ) != prev.hdr);
|
||||
|
||||
*flush = (prev.first & CROSS_PROCESS_LIST_FLUSH) != 0;
|
||||
if (!(pos = prev.first & ~CROSS_PROCESS_LIST_FLUSH)) return NULL;
|
||||
|
||||
/* reverse the list */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CROSS_PROCESS_WORK_ENTRY *entry = CROSS_PROCESS_LIST_ENTRY( list, pos );
|
||||
UINT next = entry->next;
|
||||
entry->next = prev_pos;
|
||||
if (!next) return entry;
|
||||
prev_pos = pos;
|
||||
pos = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlWow64PopCrossProcessWorkFromFreeList (NTDLL.@)
|
||||
*/
|
||||
CROSS_PROCESS_WORK_ENTRY * WINAPI RtlWow64PopCrossProcessWorkFromFreeList( CROSS_PROCESS_WORK_HDR *list )
|
||||
{
|
||||
CROSS_PROCESS_WORK_ENTRY *ret;
|
||||
CROSS_PROCESS_WORK_HDR prev, new;
|
||||
|
||||
do
|
||||
{
|
||||
prev.hdr = list->hdr;
|
||||
if (!prev.first) return NULL;
|
||||
ret = CROSS_PROCESS_LIST_ENTRY( list, prev.first );
|
||||
new.first = ret->next;
|
||||
new.counter = prev.counter + 1;
|
||||
} while (InterlockedCompareExchange64( &list->hdr, new.hdr, prev.hdr ) != prev.hdr);
|
||||
|
||||
ret->next = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlWow64PushCrossProcessWorkOntoFreeList (NTDLL.@)
|
||||
*/
|
||||
BOOLEAN WINAPI RtlWow64PushCrossProcessWorkOntoFreeList( CROSS_PROCESS_WORK_HDR *list, CROSS_PROCESS_WORK_ENTRY *entry )
|
||||
{
|
||||
CROSS_PROCESS_WORK_HDR prev, new;
|
||||
|
||||
do
|
||||
{
|
||||
prev.hdr = list->hdr;
|
||||
entry->next = prev.first;
|
||||
new.first = (char *)entry - (char *)list;
|
||||
new.counter = prev.counter + 1;
|
||||
} while (InterlockedCompareExchange64( &list->hdr, new.hdr, prev.hdr ) != prev.hdr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlWow64PushCrossProcessWorkOntoWorkList (NTDLL.@)
|
||||
*/
|
||||
BOOLEAN WINAPI RtlWow64PushCrossProcessWorkOntoWorkList( CROSS_PROCESS_WORK_HDR *list, CROSS_PROCESS_WORK_ENTRY *entry, void **unknown )
|
||||
{
|
||||
CROSS_PROCESS_WORK_HDR prev, new;
|
||||
|
||||
*unknown = NULL;
|
||||
do
|
||||
{
|
||||
prev.hdr = list->hdr;
|
||||
entry->next = prev.first;
|
||||
new.first = ((char *)entry - (char *)list) | (prev.first & CROSS_PROCESS_LIST_FLUSH);
|
||||
new.counter = prev.counter + 1;
|
||||
} while (InterlockedCompareExchange64( &list->hdr, new.hdr, prev.hdr ) != prev.hdr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RtlWow64RequestCrossProcessHeavyFlush (NTDLL.@)
|
||||
*/
|
||||
BOOLEAN WINAPI RtlWow64RequestCrossProcessHeavyFlush( CROSS_PROCESS_WORK_HDR *list )
|
||||
{
|
||||
CROSS_PROCESS_WORK_HDR prev, new;
|
||||
|
||||
do
|
||||
{
|
||||
prev.hdr = list->hdr;
|
||||
new.first = prev.first | CROSS_PROCESS_LIST_FLUSH;
|
||||
new.counter = prev.counter + 1;
|
||||
} while (InterlockedCompareExchange64( &list->hdr, new.hdr, prev.hdr ) != prev.hdr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
||||
/**********************************************************************
|
||||
* RtlCreateUserProcess (NTDLL.@)
|
||||
|
|
|
@ -36,6 +36,11 @@ static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE,HANDLE,PVOID*,const LARGE
|
|||
#ifdef _WIN64
|
||||
static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
|
||||
static NTSTATUS (WINAPI *pRtlWow64GetThreadSelectorEntry)(HANDLE,THREAD_DESCRIPTOR_INFORMATION*,ULONG,ULONG*);
|
||||
static CROSS_PROCESS_WORK_ENTRY * (WINAPI *pRtlWow64PopAllCrossProcessWorkFromWorkList)(CROSS_PROCESS_WORK_HDR*,BOOLEAN*);
|
||||
static CROSS_PROCESS_WORK_ENTRY * (WINAPI *pRtlWow64PopCrossProcessWorkFromFreeList)(CROSS_PROCESS_WORK_HDR*);
|
||||
static BOOLEAN (WINAPI *pRtlWow64PushCrossProcessWorkOntoFreeList)(CROSS_PROCESS_WORK_HDR*,CROSS_PROCESS_WORK_ENTRY*);
|
||||
static BOOLEAN (WINAPI *pRtlWow64PushCrossProcessWorkOntoWorkList)(CROSS_PROCESS_WORK_HDR*,CROSS_PROCESS_WORK_ENTRY*,void**);
|
||||
static BOOLEAN (WINAPI *pRtlWow64RequestCrossProcessHeavyFlush)(CROSS_PROCESS_WORK_HDR*);
|
||||
#else
|
||||
static NTSTATUS (WINAPI *pNtWow64AllocateVirtualMemory64)(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG);
|
||||
static NTSTATUS (WINAPI *pNtWow64GetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*);
|
||||
|
@ -95,6 +100,11 @@ static void init(void)
|
|||
#ifdef _WIN64
|
||||
GET_PROC( RtlWow64GetCpuAreaInfo );
|
||||
GET_PROC( RtlWow64GetThreadSelectorEntry );
|
||||
GET_PROC( RtlWow64PopAllCrossProcessWorkFromWorkList );
|
||||
GET_PROC( RtlWow64PopCrossProcessWorkFromFreeList );
|
||||
GET_PROC( RtlWow64PushCrossProcessWorkOntoFreeList );
|
||||
GET_PROC( RtlWow64PushCrossProcessWorkOntoWorkList );
|
||||
GET_PROC( RtlWow64RequestCrossProcessHeavyFlush );
|
||||
#else
|
||||
GET_PROC( NtWow64AllocateVirtualMemory64 );
|
||||
GET_PROC( NtWow64GetNativeSystemInformation );
|
||||
|
@ -834,6 +844,142 @@ static void test_image_mappings(void)
|
|||
|
||||
#ifdef _WIN64
|
||||
|
||||
static void test_cross_process_work_list(void)
|
||||
{
|
||||
UINT i, next, count = 10, size = offsetof( CROSS_PROCESS_WORK_LIST, entries[count] );
|
||||
BOOLEAN res, flush;
|
||||
CROSS_PROCESS_WORK_ENTRY *ptr, *ret;
|
||||
CROSS_PROCESS_WORK_LIST *list = calloc( size, 1 );
|
||||
|
||||
if (!pRtlWow64PopAllCrossProcessWorkFromWorkList)
|
||||
{
|
||||
win_skip( "cross process list not supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
list = calloc( size, 1 );
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
res = pRtlWow64PushCrossProcessWorkOntoFreeList( &list->free_list, &list->entries[i] );
|
||||
ok( res == TRUE, "%u: RtlWow64PushCrossProcessWorkOntoFreeList failed\n", i );
|
||||
}
|
||||
|
||||
ok( list->free_list.counter == count, "wrong counter %u\n", list->free_list.counter );
|
||||
ok( CROSS_PROCESS_LIST_ENTRY( &list->free_list, list->free_list.first ) == &list->entries[count - 1],
|
||||
"wrong offset %u\n", list->free_list.first );
|
||||
for (i = count; i > 1; i--)
|
||||
ok( CROSS_PROCESS_LIST_ENTRY( &list->free_list, list->entries[i - 1].next ) == &list->entries[i - 2],
|
||||
"%u: wrong offset %x / %x\n", i, list->entries[i - 1].next,
|
||||
(UINT)((char *)&list->entries[i - 2] - (char *)&list->free_list) );
|
||||
ok( !list->entries[0].next, "wrong last offset %x\n", list->entries[0].next );
|
||||
|
||||
next = list->entries[count - 1].next;
|
||||
ptr = pRtlWow64PopCrossProcessWorkFromFreeList( &list->free_list );
|
||||
ok( ptr == (void *)&list->entries[count - 1], "wrong ptr %p (%p)\n", ptr, list );
|
||||
ok( !ptr->next, "next not reset %x\n", ptr->next );
|
||||
ok( list->free_list.first == next, "wrong offset %x / %x\n", list->free_list.first, next );
|
||||
ok( list->free_list.counter == count + 1, "wrong counter %u\n", list->free_list.counter );
|
||||
|
||||
ptr->next = 0xdead;
|
||||
ptr->id = 3;
|
||||
ptr->addr = 0xdeadbeef;
|
||||
ptr->size = 0x1000;
|
||||
ptr->args[0] = 7;
|
||||
ret = (void *)0xdeadbeef;
|
||||
res = pRtlWow64PushCrossProcessWorkOntoWorkList( &list->work_list, ptr, (void **)&ret );
|
||||
ok( res == TRUE, "RtlWow64PushCrossProcessWorkOntoWorkList failed\n" );
|
||||
ok( !ret, "got ret ptr %p\n", ret );
|
||||
ok( list->work_list.counter == 1, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( ptr == CROSS_PROCESS_LIST_ENTRY( &list->work_list, list->work_list.first), "wrong ptr %p / %p\n",
|
||||
ptr, CROSS_PROCESS_LIST_ENTRY( &list->work_list, list->work_list.first ));
|
||||
ok( !ptr->next, "got next %x\n", ptr->next );
|
||||
|
||||
next = list->work_list.first;
|
||||
ptr = pRtlWow64PopCrossProcessWorkFromFreeList( &list->free_list );
|
||||
ok( list->free_list.counter == count + 2, "wrong counter %u\n", list->free_list.counter );
|
||||
ptr->id = 20;
|
||||
ptr->addr = 0x123456;
|
||||
ptr->size = 0x2345;
|
||||
res = pRtlWow64PushCrossProcessWorkOntoWorkList( &list->work_list, ptr, (void **)&ret );
|
||||
ok( res == TRUE, "RtlWow64PushCrossProcessWorkOntoWorkList failed\n" );
|
||||
ok( !ret, "got ret ptr %p\n", ret );
|
||||
ok( list->work_list.counter == 2, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( list->work_list.first == (char *)ptr - (char *)&list->work_list, "wrong ptr %p / %p\n",
|
||||
ptr, (char *)list + list->work_list.first );
|
||||
ok( ptr->next == next, "got wrong next %x / %x\n", ptr->next, next );
|
||||
|
||||
flush = 0xcc;
|
||||
ptr = pRtlWow64PopAllCrossProcessWorkFromWorkList( &list->work_list, &flush );
|
||||
ok( !flush, "RtlWow64PopAllCrossProcessWorkFromWorkList flush is TRUE\n" );
|
||||
ok( list->work_list.counter == 3, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( !list->work_list.first, "list not empty %x\n", list->work_list.first );
|
||||
ok( ptr->addr == 0xdeadbeef, "wrong addr %s\n", wine_dbgstr_longlong(ptr->addr) );
|
||||
ok( ptr->size == 0x1000, "wrong size %s\n", wine_dbgstr_longlong(ptr->size) );
|
||||
ok( ptr->next, "next not set\n" );
|
||||
|
||||
ptr = CROSS_PROCESS_LIST_ENTRY( &list->work_list, ptr->next );
|
||||
ok( ptr->addr == 0x123456, "wrong addr %s\n", wine_dbgstr_longlong(ptr->addr) );
|
||||
ok( ptr->size == 0x2345, "wrong size %s\n", wine_dbgstr_longlong(ptr->size) );
|
||||
ok( !ptr->next, "list not terminated\n" );
|
||||
|
||||
res = pRtlWow64PushCrossProcessWorkOntoWorkList( &list->work_list, ptr, (void **)&ret );
|
||||
ok( res == TRUE, "RtlWow64PushCrossProcessWorkOntoWorkList failed\n" );
|
||||
ok( !ret, "got ret ptr %p\n", ret );
|
||||
ok( list->work_list.counter == 4, "wrong counter %u\n", list->work_list.counter );
|
||||
|
||||
res = pRtlWow64RequestCrossProcessHeavyFlush( &list->work_list );
|
||||
ok( res == TRUE, "RtlWow64RequestCrossProcessHeavyFlush failed\n" );
|
||||
ok( list->work_list.counter == 5, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( list->work_list.first & CROSS_PROCESS_LIST_FLUSH, "flush flag not set %x\n", list->work_list.first );
|
||||
ok( ptr == CROSS_PROCESS_LIST_ENTRY( &list->work_list, list->work_list.first), "wrong ptr %p / %p\n",
|
||||
ptr, CROSS_PROCESS_LIST_ENTRY( &list->work_list, list->work_list.first ));
|
||||
|
||||
flush = 0xcc;
|
||||
ptr = pRtlWow64PopAllCrossProcessWorkFromWorkList( &list->work_list, &flush );
|
||||
ok( flush == TRUE, "RtlWow64PopAllCrossProcessWorkFromWorkList flush not set\n" );
|
||||
ok( list->work_list.counter == 6, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( !list->work_list.first, "list not empty %x\n", list->work_list.first );
|
||||
ok( ptr->addr == 0x123456, "wrong addr %s\n", wine_dbgstr_longlong(ptr->addr) );
|
||||
ok( ptr->size == 0x2345, "wrong size %s\n", wine_dbgstr_longlong(ptr->size) );
|
||||
ok( !ptr->next, "next not set\n" );
|
||||
|
||||
flush = 0xcc;
|
||||
ptr = pRtlWow64PopAllCrossProcessWorkFromWorkList( &list->work_list, &flush );
|
||||
ok( flush == FALSE, "RtlWow64PopAllCrossProcessWorkFromWorkList flush set\n" );
|
||||
ok( list->work_list.counter == 6, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( !list->work_list.first, "list not empty %x\n", list->work_list.first );
|
||||
ok( !ptr, "got ptr %p\n", ptr );
|
||||
|
||||
res = pRtlWow64RequestCrossProcessHeavyFlush( &list->work_list );
|
||||
ok( res == TRUE, "RtlWow64RequestCrossProcessHeavyFlush failed\n" );
|
||||
ok( list->work_list.counter == 7, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( list->work_list.first & CROSS_PROCESS_LIST_FLUSH, "flush flag not set %x\n", list->work_list.first );
|
||||
|
||||
res = pRtlWow64RequestCrossProcessHeavyFlush( &list->work_list );
|
||||
ok( res == TRUE, "RtlWow64RequestCrossProcessHeavyFlush failed\n" );
|
||||
ok( list->work_list.counter == 8, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( list->work_list.first & CROSS_PROCESS_LIST_FLUSH, "flush flag not set %x\n", list->work_list.first );
|
||||
|
||||
flush = 0xcc;
|
||||
ptr = pRtlWow64PopAllCrossProcessWorkFromWorkList( &list->work_list, &flush );
|
||||
ok( flush == TRUE, "RtlWow64PopAllCrossProcessWorkFromWorkList flush set\n" );
|
||||
ok( list->work_list.counter == 9, "wrong counter %u\n", list->work_list.counter );
|
||||
ok( !list->work_list.first, "list not empty %x\n", list->work_list.first );
|
||||
ok( !ptr, "got ptr %p\n", ptr );
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ptr = pRtlWow64PopCrossProcessWorkFromFreeList( &list->free_list );
|
||||
if (!ptr) break;
|
||||
ok( list->free_list.counter == count + 3 + i, "wrong counter %u\n", list->free_list.counter );
|
||||
}
|
||||
ok( list->free_list.counter == count + 2 + i, "wrong counter %u\n", list->free_list.counter );
|
||||
ok( !list->free_list.first, "first still set %x\n", list->free_list.first );
|
||||
|
||||
free( list );
|
||||
}
|
||||
|
||||
|
||||
static void test_cpu_area(void)
|
||||
{
|
||||
if (pRtlWow64GetCpuAreaInfo)
|
||||
|
@ -1634,7 +1780,9 @@ START_TEST(wow64)
|
|||
test_peb_teb();
|
||||
test_selectors();
|
||||
test_image_mappings();
|
||||
#ifndef _WIN64
|
||||
#ifdef _WIN64
|
||||
test_cross_process_work_list();
|
||||
#else
|
||||
test_nt_wow64();
|
||||
test_modules();
|
||||
test_init_block();
|
||||
|
|
|
@ -4117,6 +4117,50 @@ C_ASSERT( sizeof(WOW64INFO) == 40 );
|
|||
#define WOW64_CPUFLAGS_MSFT64 0x01
|
||||
#define WOW64_CPUFLAGS_SOFTWARE 0x02
|
||||
|
||||
/* undocumented layout of WOW64INFO.CrossProcessWorkList */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT next;
|
||||
UINT id;
|
||||
ULONGLONG addr;
|
||||
ULONGLONG size;
|
||||
UINT args[4];
|
||||
} CROSS_PROCESS_WORK_ENTRY;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT first;
|
||||
UINT counter;
|
||||
};
|
||||
volatile LONGLONG hdr;
|
||||
} CROSS_PROCESS_WORK_HDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CROSS_PROCESS_WORK_HDR free_list;
|
||||
CROSS_PROCESS_WORK_HDR work_list;
|
||||
ULONGLONG unknown[4];
|
||||
CROSS_PROCESS_WORK_ENTRY entries[1];
|
||||
} CROSS_PROCESS_WORK_LIST;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CrossProcessPreVirtualAlloc = 0,
|
||||
CrossProcessPostVirtualAlloc = 1,
|
||||
CrossProcessPreVirtualFree = 2,
|
||||
CrossProcessPostVirtualFree = 3,
|
||||
CrossProcessPreVirtualProtect = 4,
|
||||
CrossProcessPostVirtualProtect = 5,
|
||||
CrossProcessFlushCache = 6,
|
||||
} CROSS_PROCESS_NOTIFICATION;
|
||||
|
||||
#define CROSS_PROCESS_LIST_FLUSH 0x80000000
|
||||
#define CROSS_PROCESS_LIST_ENTRY(list,pos) \
|
||||
((CROSS_PROCESS_WORK_ENTRY *)((char *)(list) + ((pos) & ~CROSS_PROCESS_LIST_FLUSH)))
|
||||
|
||||
/* wow64.dll functions */
|
||||
void * WINAPI Wow64AllocateTemp(SIZE_T);
|
||||
void WINAPI Wow64ApcRoutine(ULONG_PTR,ULONG_PTR,ULONG_PTR,CONTEXT*);
|
||||
|
@ -4977,6 +5021,11 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_
|
|||
NTSYSAPI NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT*,void**,void**);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadSelectorEntry(HANDLE,THREAD_DESCRIPTOR_INFORMATION*,ULONG,ULONG*);
|
||||
NTSYSAPI CROSS_PROCESS_WORK_ENTRY * WINAPI RtlWow64PopAllCrossProcessWorkFromWorkList(CROSS_PROCESS_WORK_HDR*,BOOLEAN*);
|
||||
NTSYSAPI CROSS_PROCESS_WORK_ENTRY * WINAPI RtlWow64PopCrossProcessWorkFromFreeList(CROSS_PROCESS_WORK_HDR*);
|
||||
NTSYSAPI BOOLEAN WINAPI RtlWow64PushCrossProcessWorkOntoFreeList(CROSS_PROCESS_WORK_HDR*,CROSS_PROCESS_WORK_ENTRY*);
|
||||
NTSYSAPI BOOLEAN WINAPI RtlWow64PushCrossProcessWorkOntoWorkList(CROSS_PROCESS_WORK_HDR*,CROSS_PROCESS_WORK_ENTRY*,void**);
|
||||
NTSYSAPI BOOLEAN WINAPI RtlWow64RequestCrossProcessHeavyFlush(CROSS_PROCESS_WORK_HDR*);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
|
||||
#else
|
||||
NTSYSAPI NTSTATUS WINAPI NtWow64AllocateVirtualMemory64(HANDLE,ULONG64*,ULONG64,ULONG64*,ULONG,ULONG);
|
||||
|
|
Loading…
Reference in a new issue