[PATCH 4/6] ntdll: Implement NtSetInformationVirtualMemory.

Jinoh Kang jinoh.kang.kr at gmail.com
Thu Nov 25 12:25:51 CST 2021


Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
 configure                 |  6 ++++
 configure.ac              |  1 +
 dlls/ntdll/ntdll.spec     |  2 ++
 dlls/ntdll/unix/loader.c  |  1 +
 dlls/ntdll/unix/virtual.c | 65 +++++++++++++++++++++++++++++++++++++++
 include/config.h.in       |  3 ++
 6 files changed, 78 insertions(+)

diff --git a/configure b/configure
index ded6e71b815..d99e385120b 100755
--- a/configure
+++ b/configure
@@ -19000,6 +19000,12 @@ if test "x$ac_cv_func_mach_continuous_time" = xyes
 then :
   printf "%s\n" "#define HAVE_MACH_CONTINUOUS_TIME 1" >>confdefs.h
 
+fi
+ac_fn_c_check_func "$LINENO" "madvise" "ac_cv_func_madvise"
+if test "x$ac_cv_func_madvise" = xyes
+then :
+  printf "%s\n" "#define HAVE_MADVISE 1" >>confdefs.h
+
 fi
 ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
 if test "x$ac_cv_func_pipe2" = xyes
diff --git a/configure.ac b/configure.ac
index 4f7c7209da9..85a6f78d427 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1942,6 +1942,7 @@ AC_CHECK_FUNCS(\
 	getrandom \
 	kqueue \
 	mach_continuous_time \
+	madvise \
 	pipe2 \
 	port_create \
 	posix_fadvise \
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index e5a49ba1a1f..f85af7acebc 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -384,6 +384,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)
@@ -1405,6 +1406,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
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index f19d1d68dc7..d34f0b15d35 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -309,6 +309,7 @@ static void * const syscalls[] =
     NtSetInformationProcess,
     NtSetInformationThread,
     NtSetInformationToken,
+    NtSetInformationVirtualMemory,
     NtSetIntervalProfile,
     NtSetIoCompletion,
     NtSetLdtEntries,
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 5873a3e2335..e348e2a77e7 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4968,6 +4968,71 @@ 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 int once;
+
+    if (!once++) FIXME( "(process=%p,flags=%u) VmPrefetchInformation partial stub\n", process, flags );
+
+    if (process != NtCurrentProcess()) return STATUS_SUCCESS;
+
+    for (i = 0; i < count; i++)
+    {
+        if (!addresses[i].NumberOfBytes) return STATUS_INVALID_PARAMETER_4;
+    }
+
+    for (i = 0; i < count; i++)
+    {
+        MEMORY_RANGE_ENTRY entry;
+        memcpy(&entry, &addresses[i], sizeof(MEMORY_RANGE_ENTRY));
+
+        base = ROUND_ADDR( entry.VirtualAddress, page_mask );
+        size = ROUND_SIZE( entry.VirtualAddress, entry.NumberOfBytes );
+
+#ifdef HAVE_MADVISE
+        madvise(base, size, MADV_WILLNEED);
+#else
+        (void)base;
+        (void)size;
+#endif
+    }
+
+    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;
+            if (!addresses) return STATUS_ACCESS_VIOLATION;
+            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.@)
  */
diff --git a/include/config.h.in b/include/config.h.in
index 0fe50e8ce7c..234c3e1c8b5 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -293,6 +293,9 @@
 /* Define to 1 if you have the <mach-o/loader.h> header file. */
 #undef HAVE_MACH_O_LOADER_H
 
+/* Define to 1 if you have the `madvise' function. */
+#undef HAVE_MADVISE
+
 /* Define to 1 if you have the <Metal/Metal.h> header file. */
 #undef HAVE_METAL_METAL_H
 
-- 
2.31.1




More information about the wine-devel mailing list