kernel32: Reserve the low 64Kb area separately from the rest of the DOS memory.
This commit is contained in:
parent
195ca1e85f
commit
f02ef19fdb
|
@ -142,9 +142,8 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except)
|
||||||
{
|
{
|
||||||
if (except->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
if (except->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||||
{
|
{
|
||||||
DWORD addr = except->ExceptionRecord->ExceptionInformation[1];
|
char *addr = (char *)except->ExceptionRecord->ExceptionInformation[1];
|
||||||
if (addr >= (ULONG_PTR)DOSMEM_dosmem + DOSMEM_protect &&
|
if (addr >= DOSMEM_dosmem + DOSMEM_protect && addr < DOSMEM_dosmem + DOSMEM_SIZE)
|
||||||
addr < (ULONG_PTR)DOSMEM_dosmem + DOSMEM_SIZE)
|
|
||||||
{
|
{
|
||||||
if (load_winedos()) return EXCEPTION_CONTINUE_EXECUTION;
|
if (load_winedos()) return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
|
@ -159,42 +158,58 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except)
|
||||||
*/
|
*/
|
||||||
static char* setup_dos_mem(void)
|
static char* setup_dos_mem(void)
|
||||||
{
|
{
|
||||||
int sys_offset = 0;
|
size_t size;
|
||||||
int page_size = getpagesize();
|
int page_size = getpagesize();
|
||||||
void *addr = NULL;
|
void *addr = NULL;
|
||||||
|
void * const low_64k = (void *)DOSMEM_64KB;
|
||||||
|
|
||||||
if (wine_mmap_is_in_reserved_area( NULL, DOSMEM_SIZE ) != 1)
|
/* check without the first 64K */
|
||||||
{
|
|
||||||
addr = wine_anon_mmap( (void *)page_size, DOSMEM_SIZE-page_size,
|
|
||||||
PROT_READ | PROT_WRITE, 0 );
|
|
||||||
if (addr == (void *)page_size) addr = NULL; /* we got what we wanted */
|
|
||||||
else munmap( addr, DOSMEM_SIZE - page_size );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addr)
|
if (wine_mmap_is_in_reserved_area( low_64k, DOSMEM_SIZE - DOSMEM_64KB ) != 1)
|
||||||
{
|
{
|
||||||
/* now reserve from address 0 */
|
addr = wine_anon_mmap( low_64k, DOSMEM_SIZE - DOSMEM_64KB, PROT_READ | PROT_WRITE, 0 );
|
||||||
wine_anon_mmap( NULL, DOSMEM_SIZE, PROT_NONE, MAP_FIXED );
|
if (addr != low_64k)
|
||||||
|
|
||||||
/* inform the memory manager that there is a mapping here, but don't commit yet */
|
|
||||||
VirtualAlloc( NULL, DOSMEM_SIZE, MEM_RESERVE | MEM_SYSTEM, PAGE_NOACCESS );
|
|
||||||
sys_offset = 0xf0000;
|
|
||||||
DOSMEM_protect = DOSMEM_64KB;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
if (addr != MAP_FAILED) munmap( addr, DOSMEM_SIZE - DOSMEM_64KB );
|
||||||
ERR("Cannot use first megabyte for DOS address space, please report\n" );
|
ERR("Cannot use first megabyte for DOS address space, please report\n" );
|
||||||
/* allocate the DOS area somewhere else */
|
/* allocate the DOS area somewhere else */
|
||||||
addr = VirtualAlloc( NULL, DOSMEM_SIZE, MEM_RESERVE, PAGE_NOACCESS );
|
if (!(DOSMEM_dosmem = VirtualAlloc( NULL, DOSMEM_SIZE, MEM_RESERVE, PAGE_NOACCESS )))
|
||||||
if (!addr)
|
|
||||||
{
|
{
|
||||||
ERR( "Cannot allocate DOS memory\n" );
|
ERR( "Cannot allocate DOS memory\n" );
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
return DOSMEM_dosmem;
|
||||||
}
|
}
|
||||||
DOSMEM_dosmem = addr;
|
}
|
||||||
RtlAddVectoredExceptionHandler(FALSE, dosmem_handler);
|
|
||||||
return (char*)addr + sys_offset;
|
/* 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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,6 +223,7 @@ BOOL DOSMEM_Init(void)
|
||||||
{
|
{
|
||||||
char* sysmem = setup_dos_mem();
|
char* sysmem = setup_dos_mem();
|
||||||
|
|
||||||
|
RtlAddVectoredExceptionHandler(FALSE, dosmem_handler);
|
||||||
DOSMEM_0000H = GLOBAL_CreateBlock( GMEM_FIXED, sysmem,
|
DOSMEM_0000H = GLOBAL_CreateBlock( GMEM_FIXED, sysmem,
|
||||||
DOSMEM_64KB, 0, WINE_LDT_FLAGS_DATA );
|
DOSMEM_64KB, 0, WINE_LDT_FLAGS_DATA );
|
||||||
DOSMEM_BiosDataSeg = GLOBAL_CreateBlock( GMEM_FIXED, sysmem + 0x400,
|
DOSMEM_BiosDataSeg = GLOBAL_CreateBlock( GMEM_FIXED, sysmem + 0x400,
|
||||||
|
|
Loading…
Reference in New Issue