kernel32: Moved allocation of the DOS memory area to ntdll.
This commit is contained in:
parent
1603a51d4e
commit
f4eaa15aec
|
@ -151,68 +151,6 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except)
|
|||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* setup_dos_mem
|
||||
*
|
||||
* Setup the first megabyte for DOS memory access
|
||||
*/
|
||||
static char* setup_dos_mem(void)
|
||||
{
|
||||
size_t size;
|
||||
int page_size = getpagesize();
|
||||
void *addr = NULL;
|
||||
void * const low_64k = (void *)DOSMEM_64KB;
|
||||
|
||||
/* check without the first 64K */
|
||||
|
||||
if (wine_mmap_is_in_reserved_area( low_64k, DOSMEM_SIZE - DOSMEM_64KB ) != 1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* now try to allocate the low 64K too */
|
||||
|
||||
if (wine_mmap_is_in_reserved_area( NULL, DOSMEM_64KB ) != 1)
|
||||
{
|
||||
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" );
|
||||
}
|
||||
}
|
||||
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
|
||||
*
|
||||
|
@ -221,7 +159,29 @@ static char* setup_dos_mem(void)
|
|||
*/
|
||||
BOOL DOSMEM_Init(void)
|
||||
{
|
||||
char* sysmem = setup_dos_mem();
|
||||
char *sysmem;
|
||||
void *addr = (void *)1;
|
||||
SIZE_T size = DOSMEM_SIZE - 1;
|
||||
|
||||
if (NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 0, &size,
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS ))
|
||||
{
|
||||
ERR( "Cannot allocate DOS memory\n" );
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
DOSMEM_dosmem = addr;
|
||||
if (!addr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
RtlAddVectoredExceptionHandler(FALSE, dosmem_handler);
|
||||
DOSMEM_0000H = GLOBAL_CreateBlock( GMEM_FIXED, sysmem,
|
||||
|
|
|
@ -860,6 +860,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
|
||||
*
|
||||
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue