ChangeLog: * dlls/winedos/int21.c * msdos/int21.c Move all other simple functions to winedos. nog.
--- msdos/int21.c.7 2002-11-27 16:08:32.000000000 +0200 +++ msdos/int21.c 2002-11-27 16:08:54.000000000 +0200 @@ -252,23 +252,6 @@ return FALSE; } -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) */ @@ -324,16 +307,6 @@ /* microsoft's programmers should be shot for using CP/M style int21 calls in Windows for Workgroup's winfile.exe */ -static void DeleteFileFCB( CONTEXT86 *context ) -{ - FIXME("(%p): stub\n", context); -} - -static void RenameFileFCB( CONTEXT86 *context ) -{ - FIXME("(%p): stub\n", context); -} - static BOOL INT21_networkfunc (CONTEXT86 *context) { @@ -408,153 +381,6 @@ switch(AH_reg(context)) { - case 0x09: /* WRITE STRING TO STANDARD OUTPUT */ - TRACE("WRITE '$'-terminated string from %04lX:%04X to stdout\n", - context->SegDs,DX_reg(context) ); - { - LPSTR data = CTX_SEG_OFF_TO_LIN(context,context->SegDs,context->Edx); - LPSTR p = data; - /* do NOT use strchr() to calculate the string length, - as '\0' is valid string content, too ! - Maybe we should check for non-'$' strings, but DOS doesn't. */ - while (*p != '$') p++; - _hwrite16( 1, data, (int)p - (int)data); - SET_AL( context, '$' ); /* yes, '$' (0x24) gets returned in AL */ - } - break; - - case 0x0a: /* BUFFERED INPUT */ - { - char *buffer = ((char *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, - context->Edx )); - int res; - - TRACE("BUFFERED INPUT (size=%d)\n",buffer[0]); - if (buffer[1]) - TRACE("Handle old chars in buffer!\n"); - res=_lread16( 0, buffer+2,buffer[0]); - buffer[1]=res; - if(buffer[res+1] == '\n') - buffer[res+1] = '\r'; - break; - } - - case 0x2e: /* SET VERIFY FLAG */ - TRACE("SET VERIFY FLAG ignored\n"); - /* we cannot change the behaviour anyway, so just ignore it */ - break; - - case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */ - case 0x1d: - case 0x1e: - case 0x20: - case 0x6b: /* NULL FUNCTION */ - SET_AL( context, 0 ); - break; - - case 0x0d: /* DISK BUFFER FLUSH */ - TRACE("DISK BUFFER FLUSH ignored\n"); - RESET_CFLAG(context); /* dos 6+ only */ - break; - - case 0x0e: /* SELECT DEFAULT DRIVE */ - TRACE("SELECT DEFAULT DRIVE %d\n", DL_reg(context)); - DRIVE_SetCurrentDrive( DL_reg(context) ); - SET_AL( context, MAX_DOS_DRIVES ); - break; - - case 0x13: /* DELETE FILE USING FCB */ - DeleteFileFCB(context); - break; - - case 0x17: /* RENAME FILE USING FCB */ - RenameFileFCB(context); - break; - - case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */ - { - TDB *pTask = TASK_GetCurrent(); - pTask->dta = MAKESEGPTR(context->SegDs,DX_reg(context)); - TRACE("Set DTA: %08lx\n", pTask->dta); - } - break; - - case 0x2a: /* GET SYSTEM DATE */ - INT21_GetSystemDate(context); - break; - - case 0x2b: /* SET SYSTEM DATE */ - FIXME("SetSystemDate(%02d/%02d/%04d): not allowed\n", - DL_reg(context), DH_reg(context), CX_reg(context) ); - SET_AL( context, 0 ); /* Let's pretend we succeeded */ - break; - - case 0x2c: /* GET SYSTEM TIME */ - INT21_GetSystemTime(context); - break; - - case 0x2d: /* SET SYSTEM TIME */ - FIXME("SetSystemTime(%02d:%02d:%02d.%02d): not allowed\n", - CH_reg(context), CL_reg(context), - DH_reg(context), DL_reg(context) ); - SET_AL( context, 0 ); /* Let's pretend we succeeded */ - break; - - case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */ - TRACE("GET DISK TRANSFER AREA ADDRESS\n"); - { - TDB *pTask = TASK_GetCurrent(); - context->SegEs = SELECTOROF( pTask->dta ); - SET_BX( context, OFFSETOF( pTask->dta ) ); - } - break; - - case 0x30: /* GET DOS VERSION */ - TRACE("GET DOS VERSION %s requested\n", - (AL_reg(context) == 0x00)?"OEM number":"version flag"); - SET_AX( context, (HIWORD(GetVersion16()) >> 8) | (HIWORD(GetVersion16()) << 8) ); -#if 0 - SET_AH( context, 0x7 ); - SET_AL( context, 0xA ); -#endif - - SET_BX( context, 0x00FF ); /* 0x123456 is Wine's serial # */ - SET_CX( context, 0x0000 ); - break; - - case 0x31: /* TERMINATE AND STAY RESIDENT */ - FIXME("TERMINATE AND STAY RESIDENT stub\n"); - break; - - case 0x37: - { - unsigned char switchchar='/'; - switch (AL_reg(context)) - { - case 0x00: /* "SWITCHAR" - GET SWITCH CHARACTER */ - TRACE("SWITCHAR - GET SWITCH CHARACTER\n"); - SET_AL( context, 0x00 ); /* success*/ - SET_DL( context, switchchar ); - break; - case 0x01: /*"SWITCHAR" - SET SWITCH CHARACTER*/ - TRACE("SWITCHAR - SET SWITCH CHARACTER\n"); - switchchar = DL_reg(context); - SET_AL( context, 0x00 ); /* success*/ - break; - default: /*"AVAILDEV" - SPECIFY \DEV\ PREFIX USE*/ - INT_BARF( context, 0x21 ); - break; - } - break; - } - - case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ - TRACE("GET COUNTRY-SPECIFIC INFORMATION for country 0x%02x\n", - AL_reg(context)); - SET_AX( context, 0x02 ); /* no country support available */ - SET_CFLAG(context); - break; - case 0x44: /* IOCTL */ switch (AL_reg(context)) { @@ -746,36 +572,6 @@ } break; - case 0x54: /* Get Verify Flag */ - TRACE("Get Verify Flag - Not Supported\n"); - SET_AL( context, 0x00 ); /* pretend we can tell. 00h = off 01h = on */ - 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 0x5d: /* NETWORK */ - FIXME("Function 0x%04x not implemented.\n", AX_reg (context)); - /* Fix the following while you're at it. */ - SetLastError( ER_NoNetwork ); - bSetDOSExtendedError = TRUE; - break; - case 0x5e: bSetDOSExtendedError = INT21_networkfunc (context); break; @@ -810,11 +606,6 @@ } 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); TRACE("GET EXTENDED COUNTRY INFORMATION code page %d country %d\n", @@ -858,23 +649,6 @@ } break; } - case 0x66: /* GLOBAL CODE PAGE TABLE */ - switch (AL_reg(context)) - { - case 0x01: - TRACE("GET GLOBAL CODE PAGE TABLE\n"); - SET_BX( context, CodePage ); - SET_DX( context, CodePage ); - RESET_CFLAG(context); - break; - case 0x02: - TRACE("SET GLOBAL CODE PAGE TABLE active page %d system page %d\n", - BX_reg(context),DX_reg(context)); - CodePage = BX_reg(context); - RESET_CFLAG(context); - break; - } - break; case 0x67: /* SET HANDLE COUNT */ TRACE("SET HANDLE COUNT to %d\n",BX_reg(context) ); --- dlls/winedos/int21.c.7 2002-11-27 16:08:43.000000000 +0200 +++ dlls/winedos/int21.c 2002-11-27 16:08:54.000000000 +0200 @@ -104,6 +104,8 @@ DWORD dpbsegptr; +WORD CodePage = 437; + /*********************************************************************** * INT21_CreateHeap [internal] * @@ -1250,6 +1252,41 @@ SET_AL( context, ascii ); break; + case 0x09: /* WRITE STRING TO STANDARD OUTPUT */ + TRACE("WRITE '$'-terminated string from %04lX:%04X to stdout\n", + context->SegDs, DX_reg(context)); + { + LPSTR data = CTX_SEG_OFF_TO_LIN(context, context->SegDs, + context->Edx); + /* do NOT use strchr() to calculate the string length, + as '\0' is valid string content, too ! + Maybe we should check for non-'$' strings, but DOS doesn't. */ + while(*data != '$') { + DOSVM_PutChar(*data); + data++; + } + SET_AL(context, '$'); /* yes, '$' (0x24) gets returned in AL */ + } + break; + + case 0x0a: /* BUFFERED INPUT */ + { + char *buffer = ((char *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, + context->Edx)); + DWORD res; + + TRACE("BUFFERED INPUT (size=%d)\n", buffer[0]); + if(buffer[1]) + TRACE("Handle old chars in buffer!\n"); + + ReadFile(GetStdHandle(STD_INPUT_HANDLE), buffer + 2, buffer[0], + &res, NULL); + buffer[1] = res; + if(buffer[res + 1] == '\n') + buffer[res + 1] = '\r'; + } + break; + case 0x0b: /* GET STDIN STATUS */ { BIOSDATA *data = BIOS_DATA; @@ -1260,6 +1297,23 @@ } break; + case 0x0d: /* DISK BUFFER FLUSH */ + TRACE("DISK BUFFER FLUSH ignored\n"); + RESET_CFLAG(context); /* dos 6+ only */ + break; + + case 0x0e: /* SELECT DEFAULT DRIVE */ + { + char driveA[] = "a:"; + + *driveA += DL_reg(context); + + TRACE("SELECT DEFAULT DRIVE %d\n", DL_reg(context)); + SetCurrentDirectoryA(driveA); + SET_AL(context, MAX_DOS_DRIVES); + } + break; + case 0x11: /* FIND FIRST MATCHING FILE USING FCB */ TRACE("FIND FIRST MATCHING FILE USING FCB %p\n", CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx)); @@ -1270,10 +1324,30 @@ SET_AL(context, INT21_FindNextFCB(context) ? 0x00 : 0xff); break; + case 0x13: /* DELETE FILE USING FCB */ + FIXME("Delete file using FCB: stub\n"); + break; + + case 0x17: /* RENAME FILE USING FCB */ + FIXME("Rename file using FCB: stub\n");; + break; + + case 0x18: /* NULL FUNCTION FOR CP/M COMPATIBILITY */ + SET_AL(context, 0); + break; + case 0x19: /* GET CURRENT DEFAULT DRIVE */ SET_AL(context, GetDosDrive(0)); break; + case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */ + { + TDB *pTask = GlobalLock16(GetCurrentTask()); + pTask->dta = MAKESEGPTR(context->SegDs, DX_reg(context)); + TRACE("Set DTA: %08lx\n", pTask->dta); + } + break; + case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */ SET_DL(context, 0); if(!INT21_GetDriveAllocInfo(context)) SET_AX(context, 0xffff); @@ -1283,10 +1357,19 @@ if(!INT21_GetDriveAllocInfo(context)) SET_AX(context, 0xffff); break; + case 0x1d: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */ + case 0x1e: + SET_AL(context, 0); + break; + case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */ GetDrivePB(context, GetDosDrive(0)); break; + case 0x20: /* NULL FUNCTION FOR CP/M COMPATIBILITY */ + SET_AL(context, 0); + break; + case 0x25: /* SET INTERRUPT VECTOR */ if(DOSVM_IsWin16()) DOSVM_SetPMHandler16(AL_reg(context), (FARPROC16)MAKESEGPTR(context->SegDs, @@ -1311,6 +1394,75 @@ } break; + case 0x2a: /* GET SYSTEM DATE */ + { + SYSTEMTIME systime; + GetLocalTime(&systime); + SET_CX(context, systime.wYear); + SET_DX(context, (systime.wMonth << 8) | systime.wDay); + SET_AX(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) ); + SET_AL( context, 0 ); /* Let's pretend we succeeded */ + break; + + case 0x2c: /* GET SYSTEM TIME */ + { + SYSTEMTIME systime; + GetLocalTime(&systime); + SET_CX(context, (systime.wHour << 8) | systime.wMinute); + SET_DX(context, (systime.wSecond << 8) | + (systime.wMilliseconds / 10)); + } + break; + + case 0x2d: /* SET SYSTEM TIME */ + FIXME("SetSystemTime(%02d:%02d:%02d.%02d): not allowed\n", + CH_reg(context), CL_reg(context), + DH_reg(context), DL_reg(context) ); + SET_AL( context, 0 ); /* Let's pretend we succeeded */ + break; + + case 0x2e: /* SET VERIFY FLAG */ + TRACE("SET VERIFY FLAG ignored\n"); + /* we cannot change the behaviour anyway, so just ignore it */ + break; + + case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */ + TRACE("GET DISK TRANSFER AREA ADDRESS\n"); + context->SegEs = SELECTOROF(GetCurrentDTA(context)); + SET_BX(context, OFFSETOF(GetCurrentDTA(context))); + break; + + case 0x30: /* GET DOS VERSION */ + TRACE("GET DOS VERSION %s requested\n", + (AL_reg(context) == 0x00) ? "OEM number" : "version flag"); + SET_AX(context, (HIWORD(GetVersion16()) >> 8) | + (HIWORD(GetVersion16()) << 8)); +#if 0 + SET_AH(context, 0x7); + SET_AL(context, 0xA); +#endif + + /* There is something funny going on here, as if the windows version + * is win95 or greater then GetVersion16 returns the dos version in the + * high order word but anything below win95 returns the dos version in + * the low order word. I haven't actually tested any of this, just my + * findings by browsing through misc/version.c */ + + SET_BX(context, 0x00FF); /* 0x123456 is Wine's serial # */ + SET_CX(context, 0x0000); + TRACE("Dos version: %d.%d\n", AH_reg(context), AL_reg(context)); + break; + + case 0x31: /* TERMINATE AND STAY RESIDENT */ + FIXME("TERMINATE AND STAY RESIDENT stub\n"); + break; + case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */ TRACE("GET DOS DRIVE PARAMETER BLOCK FOR DRIVE %s\n", INT21_DriveName(DL_reg(context))); @@ -1389,6 +1541,34 @@ if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff ); break; + case 0x37: + { + unsigned char switchchar='/'; + switch (AL_reg(context)) { + case 0x00: /* "SWITCHAR" - GET SWITCH CHARACTER */ + TRACE("SWITCHAR - GET SWITCH CHARACTER\n"); + SET_AL( context, 0x00 ); /* success*/ + SET_DL( context, switchchar ); + break; + case 0x01: /*"SWITCHAR" - SET SWITCH CHARACTER*/ + TRACE("SWITCHAR - SET SWITCH CHARACTER\n"); + switchchar = DL_reg(context); + SET_AL( context, 0x00 ); /* success*/ + break; + default: /*"AVAILDEV" - SPECIFY \DEV\ PREFIX USE*/ + INT_BARF( context, 0x21 ); + break; + } + } + break; + + case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ + TRACE("GET COUNTRY-SPECIFIC INFORMATION for country 0x%02x\n", + AL_reg(context)); + SET_AX( context, 0x02 ); /* no country support available */ + SET_CFLAG(context); + break; + case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */ TRACE("MKDIR %s\n", (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx)); bSetDOSExtendedError = !CreateDirectoryA(CTX_SEG_OFF_TO_LIN(context, @@ -1654,6 +1834,11 @@ } break; + case 0x54: /* Get Verify Flag */ + TRACE("Get Verify Flag - Not Supported\n"); + SET_AL(context, 0x00); /* pretend we can tell. 00h = off 01h = on */ + break; + case 0x56: /* "RENAME" - RENAME FILE */ TRACE("RENAME %s to %s\n", (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx), (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi)); bSetDOSExtendedError = @@ -1699,6 +1884,23 @@ } 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 0x59: /* Get extended error info */ INT21_GetExtendedError(context); break; @@ -1758,6 +1960,14 @@ } break; + case 0x5d: /* NETWORK */ + FIXME("Function 0x%04x not implemented.\n", AX_reg (context)); + /* Fix the following while you're at it. */ + SetLastError(ER_NoNetwork); + bSetDOSExtendedError = TRUE; + break; + + case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ TRACE("TRUENAME %s\n", (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Esi)); { @@ -1786,6 +1996,29 @@ } break; + case 0x64: /* OS/2 DOS BOX */ + INT_BARF(context, 0x21); + SET_CFLAG(context); + break; + + case 0x66: /* GLOBAL CODE PAGE TABLE */ + switch (AL_reg(context)) + { + case 0x01: + TRACE("GET GLOBAL CODE PAGE TABLE\n"); + SET_BX( context, CodePage ); + SET_DX( context, CodePage ); + RESET_CFLAG(context); + break; + case 0x02: + TRACE("SET GLOBAL CODE PAGE TABLE active page %d system page %d\n", + BX_reg(context),DX_reg(context)); + CodePage = BX_reg(context); + RESET_CFLAG(context); + break; + } + break; + case 0x68: /* "FFLUSH" - COMMIT FILE */ TRACE("FFLUSH/COMMIT handle %d\n",BX_reg(context)); bSetDOSExtendedError = (!FlushFileBuffers(DosFileHandleToWin32Handle( @@ -1797,6 +2030,10 @@ bSetDOSExtendedError = (!FlushFileBuffers(DosFileHandleToWin32Handle( BX_reg(context)))); break; + case 0x6b: /* NULL FUNCTION FOR CP/M COMPATIBILITY */ + SET_AL(context, 0); + break; + case 0x6c: /* Extended Open/Create*/ TRACE("EXTENDED OPEN/CREATE %s\n", (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edi)); bSetDOSExtendedError = !INT21_ExtendedOpenCreateFile(context);