Alexandre Julliard : ntdll: Add private function to manage system virtual views instead of abusing NtAllocateVirtualMemory .

Alexandre Julliard julliard at winehq.org
Mon Nov 17 09:14:04 CST 2008


Module: wine
Branch: master
Commit: a0c4bfef9dc1c2598fa10742d5d3aa3822833224
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a0c4bfef9dc1c2598fa10742d5d3aa3822833224

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Nov 14 17:40:54 2008 +0100

ntdll: Add private function to manage system virtual views instead of abusing NtAllocateVirtualMemory.

---

 dlls/ntdll/loader.c     |   10 ++++------
 dlls/ntdll/ntdll_misc.h |    2 ++
 dlls/ntdll/server.c     |   10 ++--------
 dlls/ntdll/virtual.c    |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index eab7516..097f61a 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1316,12 +1316,10 @@ static WCHAR *get_builtin_fullname( const WCHAR *path, const char *filename )
 static void load_builtin_callback( void *module, const char *filename )
 {
     static const WCHAR emptyW[1];
-    void *addr;
     IMAGE_NT_HEADERS *nt;
     WINE_MODREF *wm;
     WCHAR *fullname;
     const WCHAR *load_path;
-    SIZE_T size;
 
     if (!module)
     {
@@ -1334,10 +1332,10 @@ static void load_builtin_callback( void *module, const char *filename )
         builtin_load_info->status = STATUS_INVALID_IMAGE_FORMAT;
         return;
     }
-    addr = module;
-    size = nt->OptionalHeader.SizeOfImage;
-    NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
-                             MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY );
+    virtual_create_system_view( module, nt->OptionalHeader.SizeOfImage,
+                                VPROT_SYSTEM | VPROT_IMAGE | VPROT_NOEXEC | VPROT_COMMITTED |
+                                VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
+
     /* create the MODREF */
 
     if (!(fullname = get_builtin_fullname( builtin_load_info->filename, filename )))
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index beffd77..a42fd11 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -136,6 +136,8 @@ extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES]
 
 /* virtual memory */
 extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info );
+extern NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot );
+extern SIZE_T virtual_free_system_view( PVOID *addr_ptr );
 extern NTSTATUS virtual_alloc_thread_stack( void *base, SIZE_T stack_size );
 extern void virtual_clear_thread_stack(void);
 extern BOOL virtual_handle_stack_fault( void *addr );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 62ccc2c..64d9a8b 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -142,7 +142,6 @@ static void fatal_perror( const char *err, ... )
 void server_exit_thread( int status )
 {
     struct wine_pthread_thread_info info;
-    SIZE_T size;
     int fds[4];
 
     RtlAcquirePebLock();
@@ -162,13 +161,8 @@ void server_exit_thread( int status )
     fds[3] = ntdll_get_thread_data()->request_fd;
     pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
 
-    size = 0;
-    NtFreeVirtualMemory( GetCurrentProcess(), &info.stack_base, &size, MEM_RELEASE | MEM_SYSTEM );
-    info.stack_size = size;
-
-    size = 0;
-    NtFreeVirtualMemory( GetCurrentProcess(), &info.teb_base, &size, MEM_RELEASE | MEM_SYSTEM );
-    info.teb_size = size;
+    info.stack_size = virtual_free_system_view( &info.stack_base );
+    info.teb_size = virtual_free_system_view( &info.teb_base );
 
     close( fds[0] );
     close( fds[1] );
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 7a12da2..a4fc82d 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -134,7 +134,7 @@ static void *working_set_limit;
    ((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
 
 #define ROUND_SIZE(addr,size) \
-   (((UINT)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
+   (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
 
 #define VIRTUAL_DEBUG_DUMP_VIEW(view) \
     do { if (TRACE_ON(virtual)) VIRTUAL_DumpView(view); } while (0)
@@ -1286,6 +1286,51 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
 
 
 /***********************************************************************
+ *           virtual_create_system_view
+ */
+NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot )
+{
+    FILE_VIEW *view;
+    NTSTATUS status;
+    sigset_t sigset;
+
+    size = ROUND_SIZE( base, size );
+    base = ROUND_ADDR( base, page_mask );
+    server_enter_uninterrupted_section( &csVirtual, &sigset );
+    status = create_view( &view, base, size, vprot );
+    if (!status) TRACE( "created %p-%p\n", base, (char *)base + size );
+    server_leave_uninterrupted_section( &csVirtual, &sigset );
+    return status;
+}
+
+
+/***********************************************************************
+ *           virtual_free_system_view
+ */
+SIZE_T virtual_free_system_view( PVOID *addr_ptr )
+{
+    FILE_VIEW *view;
+    sigset_t sigset;
+    SIZE_T size = 0;
+    char *base = ROUND_ADDR( *addr_ptr, page_mask );
+
+    server_enter_uninterrupted_section( &csVirtual, &sigset );
+    if ((view = VIRTUAL_FindView( base )))
+    {
+        TRACE( "freeing %p-%p\n", view->base, (char *)view->base + view->size );
+        /* return the values that the caller should use to unmap the area */
+        *addr_ptr = view->base;
+        /* make sure we don't munmap anything from a reserved area */
+        if (!wine_mmap_is_in_reserved_area( view->base, view->size )) size = view->size;
+        view->protect |= VPROT_SYSTEM;
+        delete_view( view );
+    }
+    server_leave_uninterrupted_section( &csVirtual, &sigset );
+    return size;
+}
+
+
+/***********************************************************************
  *           virtual_alloc_thread_stack
  */
 NTSTATUS virtual_alloc_thread_stack( void *base, SIZE_T size )




More information about the wine-cvs mailing list