Module: wine Branch: master Commit: a0c4bfef9dc1c2598fa10742d5d3aa3822833224 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a0c4bfef9dc1c2598fa10742d5...
Author: Alexandre Julliard julliard@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 )