diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 024541cdb3b..61fb303898c 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -1159,4 +1159,3 @@ @ cdecl LOCAL_Size(long long) @ cdecl LOCAL_Unlock(long long) @ stdcall NE_DefResourceHandler(long long long) -@ cdecl SELECTOR_AllocBlock(ptr long long) diff --git a/dlls/winedos/himem.c b/dlls/winedos/himem.c index 748f7542561..32b9c589c70 100644 --- a/dlls/winedos/himem.c +++ b/dlls/winedos/himem.c @@ -19,7 +19,6 @@ */ #include "dosexe.h" -#include "selectors.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(dosmem); @@ -83,12 +82,36 @@ LPVOID DOSVM_AllocUMB( DWORD size ) } +/********************************************************************** + * alloc_selector + * + * Allocate a selector corresponding to a real mode address. + * size must be < 64k. + */ +static WORD alloc_selector( void *base, DWORD size, unsigned char flags ) +{ + WORD sel = wine_ldt_alloc_entries( 1 ); + + if (sel) + { + LDT_ENTRY entry; + wine_ldt_set_base( &entry, base ); + wine_ldt_set_limit( &entry, size - 1 ); + wine_ldt_set_flags( &entry, flags ); + wine_ldt_set_entry( sel, &entry ); + } + return sel; +} + + /*********************************************************************** * DOSVM_AllocCodeUMB * * Allocate upper memory block for storing code stubs. * Initializes real mode segment and 16-bit protected mode selector * for the allocated code block. + * + * FIXME: should allocate a single PM selector for the whole UMB range. */ LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) { @@ -98,7 +121,7 @@ LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) *segment = (DWORD)ptr >> 4; if (selector) - *selector = SELECTOR_AllocBlock( ptr, size, WINE_LDT_FLAGS_CODE ); + *selector = alloc_selector( ptr, size, WINE_LDT_FLAGS_CODE ); return ptr; } @@ -119,7 +142,7 @@ LPVOID DOSVM_AllocDataUMB( DWORD size, WORD *segment, WORD *selector ) *segment = (DWORD)ptr >> 4; if (selector) - *selector = SELECTOR_AllocBlock( ptr, size, WINE_LDT_FLAGS_DATA ); + *selector = alloc_selector( ptr, size, WINE_LDT_FLAGS_DATA ); return ptr; } diff --git a/dlls/winedos/int31.c b/dlls/winedos/int31.c index ff54f57b495..70602bda4dd 100644 --- a/dlls/winedos/int31.c +++ b/dlls/winedos/int31.c @@ -29,7 +29,6 @@ #include "wownt32.h" #include "task.h" #include "dosexe.h" -#include "selectors.h" #include "excpt.h" #include "wine/debug.h" @@ -83,6 +82,27 @@ BOOL DOSVM_IsDos32(void) } +/********************************************************************** + * alloc_pm_selector + * + * Allocate a 64k sized selector corresponding to a real mode segment. + */ +static WORD alloc_pm_selector( WORD seg, unsigned char flags ) +{ + WORD sel = wine_ldt_alloc_entries( 1 ); + + if (sel) + { + LDT_ENTRY entry; + wine_ldt_set_base( &entry, (void *)(seg << 4) ); + wine_ldt_set_limit( &entry, 0xffff ); + wine_ldt_set_flags( &entry, flags ); + wine_ldt_set_entry( sel, &entry ); + } + return sel; +} + + /********************************************************************** * dpmi_exception_handler * @@ -348,7 +368,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag ) DWORD esp,edi; INT_SetRealModeContext(MapSL(MAKESEGPTR( rmcb->regs_sel, rmcb->regs_ofs )), context); - ss = SELECTOR_AllocBlock( (void *)(context->SegSs<<4), 0x10000, WINE_LDT_FLAGS_DATA ); + ss = alloc_pm_selector( context->SegSs, WINE_LDT_FLAGS_DATA ); esp = context->Esp; FIXME("untested!\n"); @@ -377,7 +397,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag ) es = ctx.SegEs; edi = ctx.Edi; } - FreeSelector16(ss); + wine_ldt_free_entries( ss, 1 ); INT_GetRealModeContext( MapSL( MAKESEGPTR( es, edi )), context); #else ERR("RMCBs only implemented for i386\n"); @@ -567,19 +587,19 @@ static void StartPM( CONTEXT86 *context ) RESET_CFLAG(context); dpmi_flag = AX_reg(context); /* our mode switch wrapper have placed the desired CS into DX */ - cs = SELECTOR_AllocBlock( (void *)(DX_reg(context)<<4), 0x10000, WINE_LDT_FLAGS_CODE ); + cs = alloc_pm_selector( context->Edx, WINE_LDT_FLAGS_CODE ); /* due to a flaw in some CPUs (at least mine), it is best to mark stack segments as 32-bit if they can be used in 32-bit code. Otherwise, these CPUs may not set the high word of esp during a ring transition (from kernel code) to the 16-bit stack, and this causes trouble if executing 32-bit code using this stack. */ if (dpmi_flag & 1) selflags |= WINE_LDT_FLAGS_32BIT; - ss = SELECTOR_AllocBlock( (void *)(context->SegSs<<4), 0x10000, selflags ); + ss = alloc_pm_selector( context->SegSs, selflags ); /* do the same for the data segments, just in case */ if (context->SegDs == context->SegSs) ds = ss; - else ds = SELECTOR_AllocBlock( (void *)(context->SegDs<<4), 0x10000, selflags ); - es = SELECTOR_AllocBlock( psp, 0x100, selflags ); + else ds = alloc_pm_selector( context->SegDs, selflags ); + es = alloc_pm_selector( DOSVM_psp, selflags ); /* convert environment pointer, as the spec says, but we're a bit lazy about the size here... */ - psp->environment = SELECTOR_AllocBlock( (void *)(env_seg<<4), 0x10000, WINE_LDT_FLAGS_DATA ); + psp->environment = alloc_pm_selector( env_seg, WINE_LDT_FLAGS_DATA ); pm_ctx = *context; pm_ctx.SegCs = DOSVM_dpmi_segments->dpmi_sel; @@ -614,12 +634,12 @@ static void StartPM( CONTEXT86 *context ) ExitThread( DPMI_retval ); #if 0 - FreeSelector16(psp->environment); + wine_ldt_free_entries( psp->environment, 1 ); psp->environment = env_seg; - FreeSelector16(es); - if (ds != ss) FreeSelector16(ds); - FreeSelector16(ss); - FreeSelector16(cs); + wine_ldt_free_entries(es,1); + if (ds != ss) wine_ldt_free_entries(ds,1); + wine_ldt_free_entries(ss,1); + wine_ldt_free_entries(cs,1); #endif }