Commit f4eaa15a authored by Alexandre Julliard's avatar Alexandre Julliard

kernel32: Moved allocation of the DOS memory area to ntdll.

parent 1603a51d
......@@ -151,77 +151,37 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except)
return EXCEPTION_CONTINUE_SEARCH;
}
/**********************************************************************
* setup_dos_mem
/***********************************************************************
* DOSMEM_Init
*
* Setup the first megabyte for DOS memory access
* Create the dos memory segments, and store them into the KERNEL
* exported values.
*/
static char* setup_dos_mem(void)
BOOL DOSMEM_Init(void)
{
size_t size;
int page_size = getpagesize();
void *addr = NULL;
void * const low_64k = (void *)DOSMEM_64KB;
/* check without the first 64K */
char *sysmem;
void *addr = (void *)1;
SIZE_T size = DOSMEM_SIZE - 1;
if (wine_mmap_is_in_reserved_area( low_64k, DOSMEM_SIZE - DOSMEM_64KB ) != 1)
if (NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 0, &size,
MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS ))
{
addr = wine_anon_mmap( low_64k, DOSMEM_SIZE - DOSMEM_64KB, PROT_READ | PROT_WRITE, 0 );
if (addr != low_64k)
{
if (addr != MAP_FAILED) munmap( addr, DOSMEM_SIZE - DOSMEM_64KB );
ERR("Cannot use first megabyte for DOS address space, please report\n" );
/* allocate the DOS area somewhere else */
if (!(DOSMEM_dosmem = VirtualAlloc( NULL, DOSMEM_SIZE, MEM_RESERVE, PAGE_NOACCESS )))
{
ERR( "Cannot allocate DOS memory\n" );
ExitProcess(1);
}
return DOSMEM_dosmem;
}
ERR( "Cannot allocate DOS memory\n" );
ExitProcess(1);
}
/* now try to allocate the low 64K too */
if (wine_mmap_is_in_reserved_area( NULL, DOSMEM_64KB ) != 1)
DOSMEM_dosmem = addr;
if (!addr)
{
addr = wine_anon_mmap( (void *)page_size, DOSMEM_64KB - page_size, PROT_READ | PROT_WRITE, 0 );
if (addr == (void *)page_size)
{
addr = NULL;
TRACE( "successfully mapped low 64K range\n" );
}
else
{
if (addr != MAP_FAILED) munmap( addr, DOSMEM_64KB - page_size );
addr = low_64k;
TRACE( "failed to map low 64K range\n" );
}
DOSMEM_protect = DOSMEM_64KB;
sysmem = (char *)0xf0000; /* store sysmem in high addresses for now */
}
else
{
WARN( "First megabyte not available for DOS address space.\n" );
DOSMEM_protect = 0;
sysmem = DOSMEM_dosmem;
}
else addr = NULL;
/* now reserve the whole range */
size = (char *)DOSMEM_SIZE - (char *)addr;
wine_anon_mmap( addr, size, PROT_NONE, MAP_FIXED );
/* inform the memory manager that there is a mapping here, but don't commit yet */
VirtualAlloc( addr, size, MEM_RESERVE | MEM_SYSTEM, PAGE_NOACCESS );
DOSMEM_protect = DOSMEM_64KB;
DOSMEM_dosmem = NULL;
return (char *)0xf0000; /* store sysmem in high addresses for now */
}
/***********************************************************************
* DOSMEM_Init
*
* Create the dos memory segments, and store them into the KERNEL
* exported values.
*/
BOOL DOSMEM_Init(void)
{
char* sysmem = setup_dos_mem();
RtlAddVectoredExceptionHandler(FALSE, dosmem_handler);
DOSMEM_0000H = GLOBAL_CreateBlock( GMEM_FIXED, sysmem,
......
......@@ -861,6 +861,66 @@ static NTSTATUS decommit_pages( struct file_view *view, size_t start, size_t siz
/***********************************************************************
* allocate_dos_memory
*
* Allocate the DOS memory range.
*/
static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot )
{
size_t size;
void *addr = NULL;
void * const low_64k = (void *)0x10000;
const size_t dosmem_size = 0x110000;
int unix_prot = VIRTUAL_GetUnixProt( vprot );
struct list *ptr;
/* check for existing view */
if ((ptr = list_head( &views_list )))
{
struct file_view *first_view = LIST_ENTRY( ptr, struct file_view, entry );
if (first_view->base < (void *)dosmem_size) return STATUS_CONFLICTING_ADDRESSES;
}
/* check without the first 64K */
if (wine_mmap_is_in_reserved_area( low_64k, dosmem_size - 0x10000 ) != 1)
{
addr = wine_anon_mmap( low_64k, dosmem_size - 0x10000, unix_prot, 0 );
if (addr != low_64k)
{
if (addr != (void *)-1) munmap( addr, dosmem_size - 0x10000 );
return map_view( view, NULL, dosmem_size, 0xffff, 0, vprot );
}
}
/* now try to allocate the low 64K too */
if (wine_mmap_is_in_reserved_area( NULL, 0x10000 ) != 1)
{
addr = wine_anon_mmap( (void *)page_size, 0x10000 - page_size, unix_prot, 0 );
if (addr == (void *)page_size)
{
addr = NULL;
TRACE( "successfully mapped low 64K range\n" );
}
else
{
if (addr != (void *)-1) munmap( addr, 0x10000 - page_size );
addr = low_64k;
TRACE( "failed to map low 64K range\n" );
}
}
/* now reserve the whole range */
size = (char *)dosmem_size - (char *)addr;
wine_anon_mmap( addr, size, unix_prot, MAP_FIXED );
return create_view( view, addr, size, vprot );
}
/***********************************************************************
* map_image
*
* Map an executable (PE format) image into memory.
......@@ -1506,6 +1566,9 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
if (is_beyond_limit( 0, size, working_set_limit )) return STATUS_WORKING_SET_LIMIT_RANGE;
vprot = VIRTUAL_GetProt( protect ) | VPROT_VALLOC;
if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED;
if (*ret)
{
if (type & MEM_RESERVE) /* Round down to 64k boundary */
......@@ -1514,6 +1577,20 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
base = ROUND_ADDR( *ret, page_mask );
size = (((UINT_PTR)*ret + size + page_mask) & ~page_mask) - (UINT_PTR)base;
/* address 1 is magic to mean DOS area */
if (!base && *ret == (void *)1 && size == 0x110000)
{
server_enter_uninterrupted_section( &csVirtual, &sigset );
status = allocate_dos_memory( &view, vprot );
if (status == STATUS_SUCCESS)
{
*ret = view->base;
*size_ptr = view->size;
}
server_leave_uninterrupted_section( &csVirtual, &sigset );
return status;
}
/* disallow low 64k, wrap-around and kernel space */
if (((char *)base < (char *)0x10000) ||
((char *)base + size < (char *)base) ||
......@@ -1542,8 +1619,6 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
return STATUS_INVALID_PARAMETER;
}
}
vprot = VIRTUAL_GetProt( protect ) | VPROT_VALLOC;
if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED;
/* Reserve the memory */
......
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