Commit 9d9075ce authored by Jinoh Kang's avatar Jinoh Kang Committed by Alexandre Julliard

ntdll: Implement NtSetInformationVirtualMemory (intra-process case).

parent 442919ef
......@@ -388,6 +388,7 @@
@ stdcall -syscall NtSetInformationProcess(long long ptr long)
@ stdcall -syscall NtSetInformationThread(long long ptr long)
@ stdcall -syscall NtSetInformationToken(long long ptr long)
@ stdcall -syscall NtSetInformationVirtualMemory(long long ptr ptr ptr long)
@ stdcall -syscall NtSetIntervalProfile(long long)
@ stdcall -syscall NtSetIoCompletion(ptr long long long long)
@ stdcall -syscall NtSetLdtEntries(long int64 long int64)
......@@ -1416,6 +1417,7 @@
@ stdcall -private -syscall ZwSetInformationProcess(long long ptr long) NtSetInformationProcess
@ stdcall -private -syscall ZwSetInformationThread(long long ptr long) NtSetInformationThread
@ stdcall -private -syscall ZwSetInformationToken(long long ptr long) NtSetInformationToken
@ stdcall -private -syscall ZwSetInformationVirtualMemory(long long ptr ptr ptr long) NtSetInformationVirtualMemory
@ stdcall -private -syscall ZwSetIntervalProfile(long long) NtSetIntervalProfile
@ stdcall -private -syscall ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
@ stdcall -private -syscall ZwSetLdtEntries(long int64 long int64) NtSetLdtEntries
......
......@@ -310,6 +310,7 @@ static void * const syscalls[] =
NtSetInformationProcess,
NtSetInformationThread,
NtSetInformationToken,
NtSetInformationVirtualMemory,
NtSetIntervalProfile,
NtSetIoCompletion,
NtSetLdtEntries,
......
......@@ -4931,6 +4931,65 @@ NTSTATUS WINAPI NtAreMappedFilesTheSame(PVOID addr1, PVOID addr2)
}
static NTSTATUS prefetch_memory( HANDLE process, ULONG_PTR count,
PMEMORY_RANGE_ENTRY addresses, ULONG flags )
{
ULONG_PTR i;
PVOID base;
SIZE_T size;
static unsigned int once;
if (!once++)
{
FIXME( "(process=%p,flags=%u) NtSetInformationVirtualMemory(VmPrefetchInformation) partial stub\n",
process, flags );
}
for (i = 0; i < count; i++)
{
if (!addresses[i].NumberOfBytes) return STATUS_INVALID_PARAMETER_4;
}
if (process != NtCurrentProcess()) return STATUS_SUCCESS;
for (i = 0; i < count; i++)
{
base = ROUND_ADDR( addresses[i].VirtualAddress, page_mask );
size = ROUND_SIZE( addresses[i].VirtualAddress, addresses[i].NumberOfBytes );
madvise( base, size, MADV_WILLNEED );
}
return STATUS_SUCCESS;
}
/***********************************************************************
* NtSetInformationVirtualMemory (NTDLL.@)
* ZwSetInformationVirtualMemory (NTDLL.@)
*/
NTSTATUS WINAPI NtSetInformationVirtualMemory( HANDLE process,
VIRTUAL_MEMORY_INFORMATION_CLASS info_class,
ULONG_PTR count, PMEMORY_RANGE_ENTRY addresses,
PVOID ptr, ULONG size )
{
TRACE("(%p, info_class=%d, %lu, %p, %p, %u)\n",
process, info_class, count, addresses, ptr, size);
switch (info_class)
{
case VmPrefetchInformation:
if (!ptr) return STATUS_INVALID_PARAMETER_5;
if (size != sizeof(ULONG)) return STATUS_INVALID_PARAMETER_6;
if (!count) return STATUS_INVALID_PARAMETER_3;
return prefetch_memory( process, count, addresses, *(ULONG *)ptr );
default:
FIXME("(%p,info_class=%d,%lu,%p,%p,%u) Unknown information class\n",
process, info_class, count, addresses, ptr, size);
return STATUS_INVALID_PARAMETER_2;
}
}
/**********************************************************************
* NtFlushInstructionCache (NTDLL.@)
*/
......
......@@ -650,6 +650,12 @@ typedef struct
ULONG Reserved4;
} SYSTEM_EXTENDED_THREAD_INFORMATION32;
typedef struct
{
ULONG VirtualAddress;
ULONG NumberOfBytes;
} MEMORY_RANGE_ENTRY32;
struct __server_iovec32
{
ULONG ptr;
......
......@@ -211,6 +211,7 @@
SYSCALL_ENTRY( NtSetInformationProcess ) \
SYSCALL_ENTRY( NtSetInformationThread ) \
SYSCALL_ENTRY( NtSetInformationToken ) \
SYSCALL_ENTRY( NtSetInformationVirtualMemory ) \
SYSCALL_ENTRY( NtSetIntervalProfile ) \
SYSCALL_ENTRY( NtSetIoCompletion ) \
SYSCALL_ENTRY( NtSetLdtEntries ) \
......
......@@ -33,6 +33,21 @@
WINE_DEFAULT_DEBUG_CHANNEL(wow);
static MEMORY_RANGE_ENTRY *memory_range_entry_array_32to64( const MEMORY_RANGE_ENTRY32 *addresses32,
ULONG count )
{
MEMORY_RANGE_ENTRY *addresses = Wow64AllocateTemp( sizeof(MEMORY_RANGE_ENTRY) * count );
ULONG i;
for (i = 0; i < count; i++)
{
addresses[i].VirtualAddress = ULongToPtr( addresses32[i].VirtualAddress );
addresses[i].NumberOfBytes = addresses32[i].NumberOfBytes;
}
return addresses;
}
/**********************************************************************
* wow64_NtAllocateVirtualMemory
*/
......@@ -471,6 +486,37 @@ NTSTATUS WINAPI wow64_NtResetWriteWatch( UINT *args )
/**********************************************************************
* wow64_NtSetInformationVirtualMemory
*/
NTSTATUS WINAPI wow64_NtSetInformationVirtualMemory( UINT *args )
{
HANDLE process = get_handle( &args );
VIRTUAL_MEMORY_INFORMATION_CLASS info_class = get_ulong( &args );
ULONG count = get_ulong( &args );
MEMORY_RANGE_ENTRY32 *addresses32 = get_ptr( &args );
PVOID ptr = get_ptr( &args );
ULONG len = get_ulong( &args );
MEMORY_RANGE_ENTRY *addresses;
if (!count) return STATUS_INVALID_PARAMETER_3;
addresses = memory_range_entry_array_32to64( addresses32, count );
switch (info_class)
{
case VmPrefetchInformation:
break;
default:
FIXME( "(%p,info_class=%u,%lu,%p,%p,%lu): not implemented\n",
process, info_class, count, addresses32, ptr, len );
return STATUS_INVALID_PARAMETER_2;
}
return NtSetInformationVirtualMemory( process, info_class, count, addresses, ptr, len );
}
/**********************************************************************
* wow64_NtSetLdtEntries
*/
NTSTATUS WINAPI wow64_NtSetLdtEntries( UINT *args )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment