diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index a9555b9eb83..5fc92a04ef7 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -992,6 +992,7 @@ @ stdcall FindResource16(long str str) FindResource16 @ stdcall FreeResource16(long) FreeResource16 @ stdcall FreeSelector16(long) FreeSelector16 +@ stdcall GetCurrentPDB16() GetCurrentPDB16 @ stdcall GetCurrentTask() GetCurrentTask @ stdcall GetDOSEnvironment16() GetDOSEnvironment16 @ stdcall GetExePtr(long) GetExePtr diff --git a/dlls/winedos/devices.c b/dlls/winedos/devices.c index b5167bbd9f1..2724b2349eb 100644 --- a/dlls/winedos/devices.c +++ b/dlls/winedos/devices.c @@ -456,13 +456,18 @@ Output of DOS 6.22: void DOSDEV_InstallDOSDevices(void) { DOS_DATASEG *dataseg; - UINT16 seg; + WORD seg; + WORD selector; unsigned int n; /* allocate DOS data segment or something */ - DOS_LOLSeg = GlobalDOSAlloc16(sizeof(DOS_DATASEG)); - seg = HIWORD(DOS_LOLSeg); - dataseg = MapSL( MAKESEGPTR(LOWORD(DOS_LOLSeg), 0) ); + dataseg = DOSVM_AllocDataUMB( sizeof(DOS_DATASEG), &seg, &selector ); + + DOS_LOLSeg = MAKESEGPTR( seg, 0 ); + DOSMEM_LOL()->wine_rm_lol = + MAKESEGPTR( seg, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) ); + DOSMEM_LOL()->wine_pm_lol = + MAKESEGPTR( selector, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) ); /* initialize the magnificent List Of Lists */ InitListOfLists(&dataseg->lol); diff --git a/dlls/winedos/dosexe.h b/dlls/winedos/dosexe.h index f9f4091aa85..864447d8333 100644 --- a/dlls/winedos/dosexe.h +++ b/dlls/winedos/dosexe.h @@ -57,7 +57,6 @@ typedef void (WINAPI *INTPROC)(CONTEXT86*); extern WORD DOSVM_psp; /* psp of current DOS task */ extern WORD DOSVM_retval; /* return value of previous DOS task */ -extern DWORD DOS_LOLSeg; extern struct DPMI_segments *DOSVM_dpmi_segments; #if defined(linux) && defined(__i386__) && defined(HAVE_SYS_VM86_H) @@ -118,6 +117,9 @@ extern void WINAPI DOSVM_Int3eHandler(CONTEXT86*); /* himem.c */ extern void DOSVM_InitSegments(void); +extern LPVOID DOSVM_AllocUMB(DWORD); +extern LPVOID DOSVM_AllocCodeUMB(DWORD, WORD *, WORD *); +extern LPVOID DOSVM_AllocDataUMB(DWORD, WORD *, WORD *); /* int09.c */ extern void WINAPI DOSVM_Int09Handler(CONTEXT86*); diff --git a/dlls/winedos/himem.c b/dlls/winedos/himem.c index ced0870eb7e..b97bccd0e30 100644 --- a/dlls/winedos/himem.c +++ b/dlls/winedos/himem.c @@ -66,7 +66,7 @@ static DWORD DOSVM_umb_free = DOSVM_UMB_BOTTOM; * overhead. Use of this routine also preserves precious DOS * conventional memory. */ -static LPVOID DOSVM_AllocUMB( DWORD size ) +LPVOID DOSVM_AllocUMB( DWORD size ) { LPVOID ptr = (LPVOID)DOSVM_umb_free; @@ -89,7 +89,7 @@ static LPVOID DOSVM_AllocUMB( DWORD size ) * Initializes real mode segment and 16-bit protected mode selector * for the allocated code block. */ -static LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) +LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) { LPVOID ptr = DOSVM_AllocUMB( size ); @@ -103,6 +103,27 @@ static LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector ) } +/*********************************************************************** + * DOSVM_AllocDataUMB + * + * Allocate upper memory block for storing data. + * Initializes real mode segment and 16-bit protected mode selector + * for the allocated data block. + */ +LPVOID DOSVM_AllocDataUMB( DWORD size, WORD *segment, WORD *selector ) +{ + LPVOID ptr = DOSVM_AllocUMB( size ); + + if (segment) + *segment = (DWORD)ptr >> 4; + + if (selector) + *selector = SELECTOR_AllocBlock( ptr, size, WINE_LDT_FLAGS_DATA ); + + return ptr; +} + + /*********************************************************************** * DOSVM_InitSegments * diff --git a/dlls/winedos/int21.c b/dlls/winedos/int21.c index 33bbc03341a..b35917b99c4 100644 --- a/dlls/winedos/int21.c +++ b/dlls/winedos/int21.c @@ -44,8 +44,30 @@ extern void WINAPI INT_Int21Handler( CONTEXT86 *context ); WINE_DEFAULT_DEBUG_CHANNEL(int21); +/*********************************************************************** + * INT21_GetPSP + * + * Handler for functions 0x51 and 0x62. + */ +static void INT21_GetPSP( CONTEXT86 *context ) +{ + TRACE( "GET CURRENT PSP ADDRESS (%02x)\n", AH_reg(context) ); + + /* + * FIXME: should we return the original DOS PSP upon + * Windows startup ? + */ + if (!ISV86(context) && DOSVM_IsWin16()) + SET_BX( context, LOWORD(GetCurrentPDB16()) ); + else + SET_BX( context, DOSVM_psp ); +} + + /*********************************************************************** * INT21_Ioctl + * + * Handler for function 0x44. */ static void INT21_Ioctl( CONTEXT86 *context ) { @@ -347,7 +369,6 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) case 0x0d: /* DISK BUFFER FLUSH */ TRACE("DISK BUFFER FLUSH ignored\n"); - RESET_CFLAG( context ); /* dos 6+ only */ break; case 0x0e: /* SELECT DEFAULT DRIVE */ @@ -410,7 +431,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) TRACE("SET INTERRUPT VECTOR 0x%02x\n",AL_reg(context)); { FARPROC16 ptr = (FARPROC16)MAKESEGPTR( context->SegDs, DX_reg(context) ); - if (DOSVM_IsWin16()) + if (!ISV86(context) && DOSVM_IsWin16()) DOSVM_SetPMHandler16( AL_reg(context), ptr ); else DOSVM_SetRMHandler( AL_reg(context), ptr ); @@ -424,10 +445,21 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) break; case 0x29: /* PARSE FILENAME INTO FCB */ - case 0x2a: /* GET SYSTEM DATE */ INT_Int21Handler( context ); break; + case 0x2a: /* GET SYSTEM DATE */ + TRACE( "GET SYSTEM DATE\n" ); + { + SYSTEMTIME systime; + GetLocalTime( &systime ); + SET_CX( context, systime.wYear ); + SET_DH( context, systime.wMonth ); + SET_DL( context, systime.wDay ); + SET_AL( context, systime.wDayOfWeek ); + } + break; + case 0x2b: /* SET SYSTEM DATE */ FIXME("SetSystemDate(%02d/%02d/%04d): not allowed\n", DL_reg(context), DH_reg(context), CX_reg(context) ); @@ -435,7 +467,15 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) break; case 0x2c: /* GET SYSTEM TIME */ - INT_Int21Handler( context ); + TRACE( "GET SYSTEM TIME\n" ); + { + SYSTEMTIME systime; + GetLocalTime( &systime ); + SET_CL( context, systime.wHour ); + SET_CH( context, systime.wMinute ); + SET_DH( context, systime.wSecond ); + SET_DL( context, systime.wMilliseconds / 10 ); + } break; case 0x2d: /* SET SYSTEM TIME */ @@ -469,7 +509,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) TRACE("GET INTERRUPT VECTOR 0x%02x\n",AL_reg(context)); { FARPROC16 addr; - if (DOSVM_IsWin16()) + if (!ISV86(context) && DOSVM_IsWin16()) addr = DOSVM_GetPMHandler16( AL_reg(context) ); else addr = DOSVM_GetRMHandler( AL_reg(context) ); @@ -527,8 +567,59 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */ case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ + INT_Int21Handler( context ); + break; + case 0x48: /* ALLOCATE MEMORY */ + TRACE( "ALLOCATE MEMORY for %d paragraphs\n", BX_reg(context) ); + { + WORD selector = 0; + DWORD bytes = (DWORD)BX_reg(context) << 4; + + if (!ISV86(context) && DOSVM_IsWin16()) + { + DWORD rv = GlobalDOSAlloc16( bytes ); + selector = LOWORD( rv ); + } + else + DOSMEM_GetBlock( bytes, &selector ); + + if (selector) + SET_AX( context, selector ); + else + { + SET_CFLAG(context); + SET_AX( context, 0x0008 ); /* insufficient memory */ + SET_BX( context, DOSMEM_Available() >> 4 ); + } + } + break; + case 0x49: /* FREE MEMORY */ + TRACE( "FREE MEMORY segment %04lX\n", context->SegEs ); + { + BOOL ok; + + if (!ISV86(context) && DOSVM_IsWin16()) + { + ok = !GlobalDOSFree16( context->SegEs ); + + /* If we don't reset ES_reg, we will fail in the relay code */ + if (ok) + context->SegEs = 0; + } + else + ok = DOSMEM_FreeBlock( (void*)((DWORD)context->SegEs << 4) ); + + if (!ok) + { + TRACE("FREE MEMORY failed\n"); + SET_CFLAG(context); + SET_AX( context, 0x0009 ); /* memory block address invalid */ + } + } + break; + case 0x4a: /* RESIZE MEMORY BLOCK */ INT_Int21Handler( context ); break; @@ -573,29 +664,21 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) break; case 0x51: /* GET PSP ADDRESS */ - if (DOSVM_IsWin16()) { - INT_Int21Handler( context ); - break; - } - - TRACE("GET CURRENT PROCESS ID (GET PSP ADDRESS)\n"); - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, DOSVM_psp ); + INT21_GetPSP( context ); break; case 0x52: /* "SYSVARS" - GET LIST OF LISTS */ - TRACE("SYSVARS - GET LIST OF LISTS\n"); - if (DOSVM_IsWin16()) + if (!ISV86(context) && DOSVM_IsWin16()) { - FIXME("LOLSeg broken for now\n"); - context->SegEs = 0; - SET_BX( context, 0 ); + SEGPTR ptr = DOSMEM_LOL()->wine_pm_lol; + context->SegEs = SELECTOROF(ptr); + SET_BX( context, OFFSETOF(ptr) ); } else { - context->SegEs = HIWORD(DOS_LOLSeg); - SET_BX( context, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) ); + SEGPTR ptr = DOSMEM_LOL()->wine_rm_lol; + context->SegEs = SELECTOROF(ptr); + SET_BX( context, OFFSETOF(ptr) ); } break; @@ -606,10 +689,29 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) case 0x56: /* "RENAME" - RENAME FILE */ case 0x57: /* FILE DATE AND TIME */ - case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ INT_Int21Handler( context ); break; + case 0x58: /* GET OR SET MEMORY ALLOCATION STRATEGY */ + TRACE( "GET OR SET MEMORY ALLOCATION STRATEGY, subfunction %d\n", + AL_reg(context) ); + switch (AL_reg(context)) + { + case 0x00: /* GET ALLOCATION STRATEGY */ + SET_AX( context, 1 ); /* low memory best fit */ + break; + + case 0x01: /* SET ALLOCATION STRATEGY */ + TRACE( "Set allocation strategy to %d - ignored\n", + BL_reg(context) ); + break; + + default: + INT_BARF( context, 0x21 ); + break; + } + break; + case 0x59: /* GET EXTENDED ERROR INFO */ INT21_GetExtendedError( context ); break; @@ -626,22 +728,29 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) break; case 0x62: /* GET PSP ADDRESS */ - if (DOSVM_IsWin16()) { - INT_Int21Handler( context ); - break; - } - - TRACE("GET CURRENT PSP ADDRESS\n"); - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, DOSVM_psp ); + INT21_GetPSP( context ); break; case 0x63: /* MISC. LANGUAGE SUPPORT */ + INT_Int21Handler( context ); + break; + case 0x64: /* OS/2 DOS BOX */ + INT_BARF( context, 0x21 ); + SET_CFLAG(context); + break; + case 0x65: /* GET EXTENDED COUNTRY INFORMATION */ case 0x66: /* GLOBAL CODE PAGE TABLE */ + INT_Int21Handler( context ); + break; + case 0x67: /* SET HANDLE COUNT */ + TRACE( "SET HANDLE COUNT to %d\n", BX_reg(context) ); + if (SetHandleCount( BX_reg(context) ) < BX_reg(context) ) + bSetDOSExtendedError = TRUE; + break; + case 0x68: /* "FFLUSH" - COMMIT FILE */ case 0x69: /* DISK SERIAL NUMBER */ case 0x6a: /* COMMIT FILE */ diff --git a/dlls/winedos/module.c b/dlls/winedos/module.c index 2a6e16fb263..8aeeedfcdae 100644 --- a/dlls/winedos/module.c +++ b/dlls/winedos/module.c @@ -174,7 +174,7 @@ static char int08[]={ static void MZ_InitHandlers(void) { WORD seg; - LPBYTE start=DOSMEM_GetBlock(sizeof(int08),&seg); + LPBYTE start = DOSVM_AllocCodeUMB( sizeof(int08), &seg, 0 ); memcpy(start,int08,sizeof(int08)); /* INT 08: point it at our tick-incrementing handler */ ((SEGPTR*)0)[0x08]=MAKESEGPTR(seg,0); diff --git a/include/msdos.h b/include/msdos.h index 8b50f67d57e..cda62f89822 100644 --- a/include/msdos.h +++ b/include/msdos.h @@ -20,7 +20,7 @@ #ifndef __WINE_MSDOS_H #define __WINE_MSDOS_H -#include "winnt.h" +#include "wine/windef16.h" #include "pshpack1.h" @@ -117,6 +117,8 @@ typedef struct _DOS_LISTOFLISTS BYTE boot_drive; /* 43 */ BYTE flag_DWORD_moves; /* 44 01h for 386+, 00h otherwise */ WORD size_extended_mem; /* 45 size of extended mem in KB */ + SEGPTR wine_rm_lol; /* -- wine: Real mode pointer to LOL */ + SEGPTR wine_pm_lol; /* -- wine: Protected mode pointer to LOL */ } DOS_LISTOFLISTS; #include "poppack.h" @@ -209,8 +211,6 @@ typedef struct _DOS_LISTOFLISTS #define EL_Serial 0x04 #define EL_Memory 0x05 -void WINAPI DOS3Call( CONTEXT86 *context ); - #define DOSCONF_MEM_HIGH 0x0001 #define DOSCONF_MEM_UMB 0x0002 #define DOSCONF_NUMLOCK 0x0004 diff --git a/msdos/int21.c b/msdos/int21.c index b829766bc6a..6ef08ebe73a 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -468,22 +468,6 @@ static void INT21_ParseFileNameIntoFCB( CONTEXT86 *context ) SET_SI( context, context->Esi + (int)s - (int)filename ); } -static void INT21_GetSystemDate( CONTEXT86 *context ) -{ - SYSTEMTIME systime; - GetLocalTime( &systime ); - SET_CX( context, systime.wYear ); - SET_DX( context, (systime.wMonth << 8) | systime.wDay ); - SET_AX( context, systime.wDayOfWeek ); -} - -static void INT21_GetSystemTime( CONTEXT86 *context ) -{ - SYSTEMTIME systime; - GetLocalTime( &systime ); - SET_CX( context, (systime.wHour << 8) | systime.wMinute ); - SET_DX( context, (systime.wSecond << 8) | (systime.wMilliseconds / 10) ); -} /* Many calls translate a drive argument like this: drive number (00h = default, 01h = A:, etc) @@ -1106,14 +1090,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) INT21_ParseFileNameIntoFCB(context); break; - case 0x2a: /* GET SYSTEM DATE */ - INT21_GetSystemDate(context); - break; - - case 0x2c: /* GET SYSTEM TIME */ - INT21_GetSystemTime(context); - break; - case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */ TRACE("GET DISK TRANSFER AREA ADDRESS\n"); { @@ -1510,52 +1486,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) bSetDOSExtendedError = !INT21_GetCurrentDirectory(context); break; - case 0x48: /* ALLOCATE MEMORY */ - TRACE("ALLOCATE MEMORY for %d paragraphs\n", BX_reg(context)); - { - LPVOID *mem; - if (ISV86(context)) - { - mem= DOSMEM_GetBlock((DWORD)BX_reg(context)<<4,NULL); - if (mem) - SET_AX( context, DOSMEM_MapLinearToDos(mem)>>4 ); - } - else - { - mem = (LPVOID)GlobalDOSAlloc16(BX_reg(context)<<4); - if (mem) - SET_AX( context, (DWORD)mem&0xffff ); - } - if (!mem) - { - SET_CFLAG(context); - SET_AX( context, 0x0008 ); /* insufficient memory */ - SET_BX( context, DOSMEM_Available()>>4 ); - } - } - break; - - case 0x49: /* FREE MEMORY */ - TRACE("FREE MEMORY segment %04lX\n", context->SegEs); - { - BOOL ret; - if (ISV86(context)) - ret= DOSMEM_FreeBlock(DOSMEM_MapDosToLinear(context->SegEs<<4)); - else - { - ret = !GlobalDOSFree16(context->SegEs); - /* If we don't reset ES_reg, we will fail in the relay code */ - context->SegEs=ret; - } - if (!ret) - { - TRACE("FREE MEMORY failed\n"); - SET_CFLAG(context); - SET_AX( context, 0x0009 ); /* memory block address invalid */ - } - } - break; - case 0x4a: /* RESIZE MEMORY BLOCK */ TRACE("RESIZE MEMORY segment %04lX to %d paragraphs\n", context->SegEs, BX_reg(context)); if (!ISV86(context)) @@ -1596,17 +1526,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) } else SET_AX( context, 0 ); /* OK */ break; - case 0x51: /* GET PSP ADDRESS */ - TRACE("GET CURRENT PROCESS ID (GET PSP ADDRESS)\n"); - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, GetCurrentPDB16() ); - break; - case 0x62: /* GET PSP ADDRESS */ - /* FIXME: should we return the original DOS PSP upon */ - /* Windows startup ? */ - SET_BX( context, GetCurrentPDB16() ); - break; case 0x56: /* "RENAME" - RENAME FILE */ TRACE("RENAME %s to %s\n", @@ -1652,24 +1571,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) } break; - case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ - TRACE("GET OR SET MEMORY/UMB ALLOCATION STRATEGY subfunction %d\n", - AL_reg(context)); - switch (AL_reg(context)) - { - case 0x00: - SET_AX( context, 1 ); - break; - case 0x02: - SET_AX( context, 0 ); - break; - case 0x01: - case 0x03: - break; - } - RESET_CFLAG(context); - break; - case 0x5a: /* CREATE TEMPORARY FILE */ TRACE("CREATE TEMPORARY FILE\n"); bSetDOSExtendedError = !INT21_CreateTempFile(context); @@ -1746,10 +1647,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) break; } break; - case 0x64: /* OS/2 DOS BOX */ - INT_BARF( context, 0x21 ); - SET_CFLAG(context); - break; case 0x65:{/* GET EXTENDED COUNTRY INFORMATION */ BYTE *dataptr=CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi); @@ -1812,12 +1709,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) } break; - case 0x67: /* SET HANDLE COUNT */ - TRACE("SET HANDLE COUNT to %d\n",BX_reg(context) ); - SetHandleCount16( BX_reg(context) ); - if (GetLastError()) bSetDOSExtendedError = TRUE; - break; - case 0x68: /* "FFLUSH" - COMMIT FILE */ case 0x6a: /* COMMIT FILE */ TRACE("FFLUSH/COMMIT handle %d\n",BX_reg(context));