Return scancode when extended keycodes are read using console input

functions. Move file stamp handling to winedos. Implement DOS7 file
stamp extensions.
This commit is contained in:
Jukka Heinonen 2003-01-28 00:18:57 +00:00 committed by Alexandre Julliard
parent 7ee13d8f3e
commit f92c8ca401
2 changed files with 179 additions and 76 deletions

View file

@ -82,6 +82,40 @@ typedef struct _INT21_HEAP {
#include "poppack.h" #include "poppack.h"
/***********************************************************************
* INT21_ReadChar
*
* Reads a character from the standard input.
* Extended keycodes will be returned as two separate characters.
*/
static BOOL INT21_ReadChar( BYTE *input, BOOL peek )
{
static BYTE pending_scan = 0;
if (pending_scan)
{
if (input)
*input = pending_scan;
if (!peek)
pending_scan = 0;
return TRUE;
}
else
{
BYTE ascii;
BYTE scan;
if (!DOSVM_Int16ReadChar( &ascii, &scan, peek ))
return FALSE;
if (input)
*input = ascii;
if (!peek && !ascii)
pending_scan = scan;
return TRUE;
}
}
/*********************************************************************** /***********************************************************************
* INT21_GetSystemCountryCode * INT21_GetSystemCountryCode
* *
@ -369,6 +403,106 @@ static void INT21_ExtendedCountryInformation( CONTEXT86 *context )
} }
/***********************************************************************
* INT21_FileDateTime
*
* Handler for function 0x57.
*/
static BOOL INT21_FileDateTime( CONTEXT86 *context )
{
HANDLE handle = DosFileHandleToWin32Handle(BX_reg(context));
FILETIME filetime;
WORD date, time;
switch (AL_reg(context)) {
case 0x00: /* Get last-written stamp */
TRACE( "GET FILE LAST-WRITTEN DATE AND TIME, handle %d\n",
BX_reg(context) );
{
if (!GetFileTime( handle, NULL, NULL, &filetime ))
return FALSE;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
break;
}
case 0x01: /* Set last-written stamp */
TRACE( "SET FILE LAST-WRITTEN DATE AND TIME, handle %d\n",
BX_reg(context) );
{
DosDateTimeToFileTime( DX_reg(context),
CX_reg(context),
&filetime );
if (!SetFileTime( handle, NULL, NULL, &filetime ))
return FALSE;
break;
}
case 0x04: /* Get last access stamp, DOS 7 */
TRACE( "GET FILE LAST ACCESS DATE AND TIME, handle %d\n",
BX_reg(context) );
{
if (!GetFileTime( handle, NULL, &filetime, NULL ))
return FALSE;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
break;
}
case 0x05: /* Set last access stamp, DOS 7 */
TRACE( "SET FILE LAST ACCESS DATE AND TIME, handle %d\n",
BX_reg(context) );
{
DosDateTimeToFileTime( DX_reg(context),
CX_reg(context),
&filetime );
if (!SetFileTime( handle, NULL, &filetime, NULL ))
return FALSE;
break;
}
case 0x06: /* Get creation stamp, DOS 7 */
TRACE( "GET FILE CREATION DATE AND TIME, handle %d\n",
BX_reg(context) );
{
if (!GetFileTime( handle, &filetime, NULL, NULL ))
return FALSE;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
/*
* FIXME: SI has number of 10-millisecond units past time in CX.
*/
SET_SI( context, 0 );
break;
}
case 0x07: /* Set creation stamp, DOS 7 */
TRACE( "SET FILE CREATION DATE AND TIME, handle %d\n",
BX_reg(context) );
{
/*
* FIXME: SI has number of 10-millisecond units past time in CX.
*/
DosDateTimeToFileTime( DX_reg(context),
CX_reg(context),
&filetime );
if (!SetFileTime( handle, &filetime, NULL, NULL ))
return FALSE;
break;
}
default:
INT_BARF( context, 0x21 );
break;
}
return TRUE;
}
/*********************************************************************** /***********************************************************************
* INT21_GetPSP * INT21_GetPSP
* *
@ -544,7 +678,7 @@ static void INT21_GetExtendedError( CONTEXT86 *context )
/*********************************************************************** /***********************************************************************
* DOSVM_Int21Handler (WINEDOS16.133) * DOSVM_Int21Handler
* *
* Interrupt 0x21 handler. * Interrupt 0x21 handler.
*/ */
@ -584,8 +718,11 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
{ {
BYTE ascii; BYTE ascii;
TRACE("DIRECT CHARACTER INPUT WITH ECHO\n"); TRACE("DIRECT CHARACTER INPUT WITH ECHO\n");
DOSVM_Int16ReadChar(&ascii, NULL, FALSE); INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii ); SET_AL( context, ascii );
/*
* FIXME: What to echo when extended keycodes are read?
*/
DOSVM_PutChar(AL_reg(context)); DOSVM_PutChar(AL_reg(context));
} }
break; break;
@ -602,43 +739,41 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break; break;
case 0x06: /* DIRECT CONSOLE IN/OUTPUT */ case 0x06: /* DIRECT CONSOLE IN/OUTPUT */
/* FIXME: Use DOSDEV_Peek/Read/Write(DOSDEV_Console(),...) !! */ if (DL_reg(context) == 0xff)
if (DL_reg(context) == 0xff) { {
static char scan = 0;
TRACE("Direct Console Input\n"); TRACE("Direct Console Input\n");
if (scan) {
/* return pending scancode */ if (INT21_ReadChar( NULL, TRUE ))
SET_AL( context, scan ); {
RESET_ZFLAG(context);
scan = 0;
} else {
BYTE ascii; BYTE ascii;
if (DOSVM_Int16ReadChar(&ascii,&scan,TRUE)) { INT21_ReadChar( &ascii, FALSE );
DOSVM_Int16ReadChar(&ascii,&scan,FALSE); SET_AL( context, ascii );
/* return ASCII code */ RESET_ZFLAG( context );
SET_AL( context, ascii );
RESET_ZFLAG(context);
/* return scan code on next call only if ascii==0 */
if (ascii) scan = 0;
} else {
/* nothing pending, clear everything */
SET_AL( context, 0 );
SET_ZFLAG(context);
scan = 0; /* just in case */
}
} }
} else { else
{
/* no character available */
SET_AL( context, 0 );
SET_ZFLAG( context );
}
}
else
{
TRACE("Direct Console Output\n"); TRACE("Direct Console Output\n");
DOSVM_PutChar(DL_reg(context)); DOSVM_PutChar(DL_reg(context));
/*
* At least DOS versions 2.1-7.0 return character
* that was written in AL register.
*/
SET_AL( context, DL_reg(context) );
} }
break; break;
case 0x07: /* DIRECT CHARACTER INPUT WITHOUT ECHO */ case 0x07: /* DIRECT CHARACTER INPUT WITHOUT ECHO */
{ {
BYTE ascii; BYTE ascii;
/* FIXME: Use DOSDEV_Peek/Read(DOSDEV_Console(),...) !! */
TRACE("DIRECT CHARACTER INPUT WITHOUT ECHO\n"); TRACE("DIRECT CHARACTER INPUT WITHOUT ECHO\n");
DOSVM_Int16ReadChar(&ascii, NULL, FALSE); INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii ); SET_AL( context, ascii );
} }
break; break;
@ -646,9 +781,8 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
case 0x08: /* CHARACTER INPUT WITHOUT ECHO */ case 0x08: /* CHARACTER INPUT WITHOUT ECHO */
{ {
BYTE ascii; BYTE ascii;
/* FIXME: Use DOSDEV_Peek/Read(DOSDEV_Console(),...) !! */
TRACE("CHARACTER INPUT WITHOUT ECHO\n"); TRACE("CHARACTER INPUT WITHOUT ECHO\n");
DOSVM_Int16ReadChar(&ascii, NULL, FALSE); INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii ); SET_AL( context, ascii );
} }
break; break;
@ -664,11 +798,10 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
case 0x0b: /* GET STDIN STATUS */ case 0x0b: /* GET STDIN STATUS */
TRACE( "GET STDIN STATUS\n" ); TRACE( "GET STDIN STATUS\n" );
{ {
BIOSDATA *data = BIOS_DATA; if (INT21_ReadChar( NULL, TRUE ))
if(data->FirstKbdCharPtr == data->NextKbdCharPtr) SET_AL( context, 0xff ); /* character available */
SET_AL( context, 0 );
else else
SET_AL( context, 0xff ); SET_AL( context, 0 ); /* no character available */
} }
break; break;
@ -1080,10 +1213,14 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break; break;
case 0x56: /* "RENAME" - RENAME FILE */ case 0x56: /* "RENAME" - RENAME FILE */
case 0x57: /* FILE DATE AND TIME */
INT_Int21Handler( context ); INT_Int21Handler( context );
break; break;
case 0x57: /* FILE DATE AND TIME */
if (!INT21_FileDateTime( context ))
bSetDOSExtendedError = TRUE;
break;
case 0x58: /* GET OR SET MEMORY ALLOCATION STRATEGY */ case 0x58: /* GET OR SET MEMORY ALLOCATION STRATEGY */
TRACE( "GET OR SET MEMORY ALLOCATION STRATEGY, subfunction %d\n", TRACE( "GET OR SET MEMORY ALLOCATION STRATEGY, subfunction %d\n",
AL_reg(context) ); AL_reg(context) );
@ -1111,7 +1248,15 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
case 0x5a: /* CREATE TEMPORARY FILE */ case 0x5a: /* CREATE TEMPORARY FILE */
case 0x5b: /* CREATE NEW FILE */ case 0x5b: /* CREATE NEW FILE */
case 0x5c: /* "FLOCK" - RECORD LOCKING */ case 0x5c: /* "FLOCK" - RECORD LOCKING */
INT_Int21Handler( context );
break;
case 0x5d: /* NETWORK 5D */ case 0x5d: /* NETWORK 5D */
FIXME( "Network function 5D not implemented.\n" );
SetLastError( ER_NoNetwork );
bSetDOSExtendedError = TRUE;
break;
case 0x5e: /* NETWORK 5E */ case 0x5e: /* NETWORK 5E */
case 0x5f: /* NETWORK 5F */ case 0x5f: /* NETWORK 5F */
case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */

View file

@ -1441,41 +1441,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi))); CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi)));
break; break;
case 0x57: /* FILE DATE AND TIME */
switch (AL_reg(context))
{
case 0x00: /* Get */
{
FILETIME filetime;
TRACE("GET FILE DATE AND TIME for handle %d\n",
BX_reg(context));
if (!GetFileTime( DosFileHandleToWin32Handle(BX_reg(context)), NULL, NULL, &filetime ))
bSetDOSExtendedError = TRUE;
else
{
WORD date, time;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
}
}
break;
case 0x01: /* Set */
{
FILETIME filetime;
TRACE("SET FILE DATE AND TIME for handle %d\n",
BX_reg(context));
DosDateTimeToFileTime( DX_reg(context), CX_reg(context),
&filetime );
bSetDOSExtendedError =
(!SetFileTime( DosFileHandleToWin32Handle(BX_reg(context)),
NULL, NULL, &filetime ));
}
break;
}
break;
case 0x5a: /* CREATE TEMPORARY FILE */ case 0x5a: /* CREATE TEMPORARY FILE */
TRACE("CREATE TEMPORARY FILE\n"); TRACE("CREATE TEMPORARY FILE\n");
bSetDOSExtendedError = !INT21_CreateTempFile(context); bSetDOSExtendedError = !INT21_CreateTempFile(context);
@ -1490,13 +1455,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
bSetDOSExtendedError = (AX_reg(context) != 0); bSetDOSExtendedError = (AX_reg(context) != 0);
break; 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: case 0x5e:
bSetDOSExtendedError = INT21_networkfunc (context); bSetDOSExtendedError = INT21_networkfunc (context);
break; break;