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

This commit is contained in:
Alexandre Julliard 2008-11-14 17:40:54 +01:00
parent 70088c4ef3
commit a0c4bfef9d
4 changed files with 54 additions and 15 deletions

View File

@ -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 )))

View File

@ -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 );

View File

@ -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] );

View File

@ -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)
@ -1285,6 +1285,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
*/