Add prototype for GetCompressedFileSize. Move some int21 functions to
winedos. Improve file attribute functions.
This commit is contained in:
parent
ac89a159ac
commit
6f6eb82dfc
|
@ -43,6 +43,11 @@
|
||||||
*/
|
*/
|
||||||
extern void WINAPI INT_Int21Handler( CONTEXT86 *context );
|
extern void WINAPI INT_Int21Handler( CONTEXT86 *context );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forward declarations.
|
||||||
|
*/
|
||||||
|
static BOOL INT21_RenameFile( CONTEXT86 *context );
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(int21);
|
WINE_DEFAULT_DEBUG_CHANNEL(int21);
|
||||||
|
|
||||||
|
|
||||||
|
@ -357,6 +362,49 @@ static void INT21_BufferedInput( CONTEXT86 *context )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* INT21_CreateDirectory
|
||||||
|
*
|
||||||
|
* Handler for:
|
||||||
|
* - function 0x39
|
||||||
|
* - subfunction 0x39 of function 0x71
|
||||||
|
* - subfunction 0xff of function 0x43 (CL == 0x39)
|
||||||
|
*/
|
||||||
|
static BOOL INT21_CreateDirectory( CONTEXT86 *context )
|
||||||
|
{
|
||||||
|
WCHAR dirW[MAX_PATH];
|
||||||
|
char *dirA = CTX_SEG_OFF_TO_LIN(context,
|
||||||
|
context->SegDs,
|
||||||
|
context->Edx);
|
||||||
|
|
||||||
|
TRACE( "CREATE DIRECTORY %s\n", dirA );
|
||||||
|
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, dirA, -1, dirW, MAX_PATH);
|
||||||
|
|
||||||
|
if (CreateDirectoryW(dirW, NULL))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: CreateDirectory's LastErrors will clash with the ones
|
||||||
|
* used by DOS. AH=39 only returns 3 (path not found) and
|
||||||
|
* 5 (access denied), while CreateDirectory return several
|
||||||
|
* ones. Remap some of them. -Marcus
|
||||||
|
*/
|
||||||
|
switch (GetLastError())
|
||||||
|
{
|
||||||
|
case ERROR_ALREADY_EXISTS:
|
||||||
|
case ERROR_FILENAME_EXCED_RANGE:
|
||||||
|
case ERROR_DISK_FULL:
|
||||||
|
SetLastError(ERROR_ACCESS_DENIED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INT21_ExtendedCountryInformation
|
* INT21_ExtendedCountryInformation
|
||||||
*
|
*
|
||||||
|
@ -478,6 +526,257 @@ static void INT21_ExtendedCountryInformation( CONTEXT86 *context )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* INT21_FileAttributes
|
||||||
|
*
|
||||||
|
* Handler for:
|
||||||
|
* - function 0x43
|
||||||
|
* - subfunction 0x43 of function 0x71
|
||||||
|
*/
|
||||||
|
static BOOL INT21_FileAttributes( CONTEXT86 *context,
|
||||||
|
BYTE subfunction,
|
||||||
|
BOOL islong )
|
||||||
|
{
|
||||||
|
WCHAR fileW[MAX_PATH];
|
||||||
|
char *fileA = CTX_SEG_OFF_TO_LIN(context,
|
||||||
|
context->SegDs,
|
||||||
|
context->Edx);
|
||||||
|
HANDLE handle;
|
||||||
|
BOOL status;
|
||||||
|
FILETIME filetime;
|
||||||
|
DWORD result;
|
||||||
|
WORD date, time;
|
||||||
|
|
||||||
|
switch (subfunction)
|
||||||
|
{
|
||||||
|
case 0x00: /* GET FILE ATTRIBUTES */
|
||||||
|
TRACE( "GET FILE ATTRIBUTES for %s\n", fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
result = GetFileAttributesW( fileW );
|
||||||
|
if (result == -1)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_CX( context, (WORD)result );
|
||||||
|
if (!islong)
|
||||||
|
SET_AX( context, (WORD)result ); /* DR DOS */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x01: /* SET FILE ATTRIBUTES */
|
||||||
|
TRACE( "SET FILE ATTRIBUTES 0x%02x for %s\n",
|
||||||
|
CX_reg(context), fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
if (!SetFileAttributesW( fileW, CX_reg(context) ))
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x02: /* GET COMPRESSED FILE SIZE */
|
||||||
|
TRACE( "GET COMPRESSED FILE SIZE for %s\n", fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
result = GetCompressedFileSizeW( fileW, NULL );
|
||||||
|
if (result == INVALID_FILE_SIZE)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_AX( context, LOWORD(result) );
|
||||||
|
SET_DX( context, HIWORD(result) );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x03: /* SET FILE LAST-WRITTEN DATE AND TIME */
|
||||||
|
if (!islong)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "SET FILE LAST-WRITTEN DATE AND TIME, file %s\n", fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
handle = CreateFileW( fileW, GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
DosDateTimeToFileTime( DI_reg(context),
|
||||||
|
CX_reg(context),
|
||||||
|
&filetime );
|
||||||
|
status = SetFileTime( handle, NULL, NULL, &filetime );
|
||||||
|
|
||||||
|
CloseHandle( handle );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x04: /* GET FILE LAST-WRITTEN DATE AND TIME */
|
||||||
|
if (!islong)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "GET FILE LAST-WRITTEN DATE AND TIME, file %s\n", fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
handle = CreateFileW( fileW, GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
status = GetFileTime( handle, NULL, NULL, &filetime );
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
FileTimeToDosDateTime( &filetime, &date, &time );
|
||||||
|
SET_DI( context, date );
|
||||||
|
SET_CX( context, time );
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle( handle );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x05: /* SET FILE LAST ACCESS DATE */
|
||||||
|
if (!islong)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "SET FILE LAST ACCESS DATE, file %s\n", fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
handle = CreateFileW( fileW, GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
DosDateTimeToFileTime( DI_reg(context),
|
||||||
|
0,
|
||||||
|
&filetime );
|
||||||
|
status = SetFileTime( handle, NULL, &filetime, NULL );
|
||||||
|
|
||||||
|
CloseHandle( handle );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x06: /* GET FILE LAST ACCESS DATE */
|
||||||
|
if (!islong)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "GET FILE LAST ACCESS DATE, file %s\n", fileA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
|
||||||
|
|
||||||
|
handle = CreateFileW( fileW, GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
status = GetFileTime( handle, NULL, &filetime, NULL );
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
FileTimeToDosDateTime( &filetime, &date, NULL );
|
||||||
|
SET_DI( context, date );
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle( handle );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x07: /* SET FILE CREATION DATE AND TIME */
|
||||||
|
if (!islong)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "SET FILE CREATION DATE AND TIME, file %s\n", fileA );
|
||||||
|
|
||||||
|
handle = CreateFileW( fileW, GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: SI has number of 10-millisecond units past time in CX.
|
||||||
|
*/
|
||||||
|
DosDateTimeToFileTime( DI_reg(context),
|
||||||
|
CX_reg(context),
|
||||||
|
&filetime );
|
||||||
|
status = SetFileTime( handle, &filetime, NULL, NULL );
|
||||||
|
|
||||||
|
CloseHandle( handle );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x08: /* GET FILE CREATION DATE AND TIME */
|
||||||
|
if (!islong)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "GET FILE CREATION DATE AND TIME, handle %d\n",
|
||||||
|
BX_reg(context) );
|
||||||
|
|
||||||
|
handle = CreateFileW( fileW, GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
status = GetFileTime( handle, &filetime, NULL, NULL );
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
FileTimeToDosDateTime( &filetime, &date, &time );
|
||||||
|
SET_DI( context, date );
|
||||||
|
SET_CX( context, time );
|
||||||
|
/*
|
||||||
|
* FIXME: SI has number of 10-millisecond units past
|
||||||
|
* time in CX.
|
||||||
|
*/
|
||||||
|
SET_SI( context, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(handle);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xff: /* EXTENDED-LENGTH FILENAME OPERATIONS */
|
||||||
|
if (islong || context->Ebp != 0x5053)
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(CL_reg(context))
|
||||||
|
{
|
||||||
|
case 0x39:
|
||||||
|
if (!INT21_CreateDirectory( context ))
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x56:
|
||||||
|
if (!INT21_RenameFile( context ))
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
INT_BARF( context, 0x21 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INT21_FileDateTime
|
* INT21_FileDateTime
|
||||||
*
|
*
|
||||||
|
@ -751,10 +1050,14 @@ static void INT21_LongFilename( CONTEXT86 *context )
|
||||||
switch (AL_reg(context))
|
switch (AL_reg(context))
|
||||||
{
|
{
|
||||||
case 0x0d: /* RESET DRIVE */
|
case 0x0d: /* RESET DRIVE */
|
||||||
case 0x39: /* LONG FILENAME - MAKE DIRECTORY */
|
|
||||||
INT_Int21Handler( context );
|
INT_Int21Handler( context );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x39: /* LONG FILENAME - MAKE DIRECTORY */
|
||||||
|
if (!INT21_CreateDirectory( context ))
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x3a: /* LONG FILENAME - REMOVE DIRECTORY */
|
case 0x3a: /* LONG FILENAME - REMOVE DIRECTORY */
|
||||||
{
|
{
|
||||||
WCHAR dirW[MAX_PATH];
|
WCHAR dirW[MAX_PATH];
|
||||||
|
@ -788,6 +1091,10 @@ static void INT21_LongFilename( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x43: /* LONG FILENAME - EXTENDED GET/SET FILE ATTRIBUTES */
|
case 0x43: /* LONG FILENAME - EXTENDED GET/SET FILE ATTRIBUTES */
|
||||||
|
if (!INT21_FileAttributes( context, BL_reg(context), TRUE ))
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x47: /* LONG FILENAME - GET CURRENT DIRECTORY */
|
case 0x47: /* LONG FILENAME - GET CURRENT DIRECTORY */
|
||||||
case 0x4e: /* LONG FILENAME - FIND FIRST MATCHING FILE */
|
case 0x4e: /* LONG FILENAME - FIND FIRST MATCHING FILE */
|
||||||
case 0x4f: /* LONG FILENAME - FIND NEXT MATCHING FILE */
|
case 0x4f: /* LONG FILENAME - FIND NEXT MATCHING FILE */
|
||||||
|
@ -795,21 +1102,8 @@ static void INT21_LongFilename( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x56: /* LONG FILENAME - RENAME FILE */
|
case 0x56: /* LONG FILENAME - RENAME FILE */
|
||||||
{
|
if (!INT21_RenameFile(context))
|
||||||
WCHAR fromW[MAX_PATH];
|
bSetDOSExtendedError = TRUE;
|
||||||
WCHAR toW[MAX_PATH];
|
|
||||||
char *fromA = CTX_SEG_OFF_TO_LIN(context,
|
|
||||||
context->SegDs,context->Edx);
|
|
||||||
char *toA = CTX_SEG_OFF_TO_LIN(context,
|
|
||||||
context->SegEs,context->Edi);
|
|
||||||
|
|
||||||
TRACE( "LONG FILENAME - RENAME FILE %s to %s\n", fromA, toA );
|
|
||||||
MultiByteToWideChar(CP_OEMCP, 0, fromA, -1, fromW, MAX_PATH);
|
|
||||||
MultiByteToWideChar(CP_OEMCP, 0, toA, -1, toW, MAX_PATH);
|
|
||||||
|
|
||||||
if (!MoveFileW( fromW, toW ))
|
|
||||||
bSetDOSExtendedError = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x60: /* LONG FILENAME - CONVERT PATH */
|
case 0x60: /* LONG FILENAME - CONVERT PATH */
|
||||||
|
@ -836,6 +1130,31 @@ static void INT21_LongFilename( CONTEXT86 *context )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* INT21_RenameFile
|
||||||
|
*
|
||||||
|
* Handler for:
|
||||||
|
* - function 0x56
|
||||||
|
* - subfunction 0x56 of function 0x71
|
||||||
|
* - subfunction 0xff of function 0x43 (CL == 0x56)
|
||||||
|
*/
|
||||||
|
static BOOL INT21_RenameFile( CONTEXT86 *context )
|
||||||
|
{
|
||||||
|
WCHAR fromW[MAX_PATH];
|
||||||
|
WCHAR toW[MAX_PATH];
|
||||||
|
char *fromA = CTX_SEG_OFF_TO_LIN(context,
|
||||||
|
context->SegDs,context->Edx);
|
||||||
|
char *toA = CTX_SEG_OFF_TO_LIN(context,
|
||||||
|
context->SegEs,context->Edi);
|
||||||
|
|
||||||
|
TRACE( "RENAME FILE %s to %s\n", fromA, toA );
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, fromA, -1, fromW, MAX_PATH);
|
||||||
|
MultiByteToWideChar(CP_OEMCP, 0, toA, -1, toW, MAX_PATH);
|
||||||
|
|
||||||
|
return MoveFileW( fromW, toW );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INT21_GetExtendedError
|
* INT21_GetExtendedError
|
||||||
*/
|
*/
|
||||||
|
@ -1349,7 +1668,8 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
|
case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
|
||||||
INT_Int21Handler( context );
|
if (!INT21_CreateDirectory( context ))
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3a: /* "RMDIR" - REMOVE DIRECTORY */
|
case 0x3a: /* "RMDIR" - REMOVE DIRECTORY */
|
||||||
|
@ -1380,7 +1700,38 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
|
case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
|
||||||
INT_Int21Handler( context );
|
TRACE( "READ from %d to %04lX:%04X for %d bytes\n",
|
||||||
|
BX_reg(context),
|
||||||
|
context->SegDs,
|
||||||
|
DX_reg(context),
|
||||||
|
CX_reg(context) );
|
||||||
|
{
|
||||||
|
DWORD result;
|
||||||
|
WORD count = CX_reg(context);
|
||||||
|
BYTE *buffer = CTX_SEG_OFF_TO_LIN( context,
|
||||||
|
context->SegDs,
|
||||||
|
context->Edx );
|
||||||
|
|
||||||
|
/* Some programs pass a count larger than the allocated buffer */
|
||||||
|
if (DOSVM_IsWin16())
|
||||||
|
{
|
||||||
|
WORD maxcount = GetSelectorLimit16( context->SegDs )
|
||||||
|
- DX_reg(context) + 1;
|
||||||
|
if (count > maxcount)
|
||||||
|
count = maxcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Reading from console (BX=1) in DOS mode
|
||||||
|
* does not work as it is supposed to work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ReadFile( DosFileHandleToWin32Handle(BX_reg(context)),
|
||||||
|
buffer, count, &result, NULL ))
|
||||||
|
SET_AX( context, (WORD)result );
|
||||||
|
else
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */
|
case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */
|
||||||
|
@ -1425,8 +1776,30 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
|
case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
|
||||||
|
TRACE( "LSEEK handle %d offset %ld from %s\n",
|
||||||
|
BX_reg(context),
|
||||||
|
MAKELONG( DX_reg(context), CX_reg(context) ),
|
||||||
|
(AL_reg(context) == 0) ?
|
||||||
|
"start of file" : ((AL_reg(context) == 1) ?
|
||||||
|
"current file position" : "end of file") );
|
||||||
|
{
|
||||||
|
HANDLE handle = DosFileHandleToWin32Handle(BX_reg(context));
|
||||||
|
LONG offset = MAKELONG( DX_reg(context), CX_reg(context) );
|
||||||
|
DWORD status = SetFilePointer( handle, offset,
|
||||||
|
NULL, AL_reg(context) );
|
||||||
|
if (status == INVALID_SET_FILE_POINTER)
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_AX( context, LOWORD(status) );
|
||||||
|
SET_DX( context, HIWORD(status) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x43: /* FILE ATTRIBUTES */
|
case 0x43: /* FILE ATTRIBUTES */
|
||||||
INT_Int21Handler( context );
|
if (!INT21_FileAttributes( context, AL_reg(context), FALSE ))
|
||||||
|
bSetDOSExtendedError = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x44: /* IOCTL */
|
case 0x44: /* IOCTL */
|
||||||
|
@ -1617,21 +1990,8 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x56: /* "RENAME" - RENAME FILE */
|
case 0x56: /* "RENAME" - RENAME FILE */
|
||||||
{
|
if (!INT21_RenameFile( context ))
|
||||||
WCHAR fromW[MAX_PATH];
|
bSetDOSExtendedError = TRUE;
|
||||||
WCHAR toW[MAX_PATH];
|
|
||||||
char *fromA = CTX_SEG_OFF_TO_LIN(context,
|
|
||||||
context->SegDs,context->Edx);
|
|
||||||
char *toA = CTX_SEG_OFF_TO_LIN(context,
|
|
||||||
context->SegEs,context->Edi);
|
|
||||||
|
|
||||||
TRACE( "RENAME %s to %s\n", fromA, toA );
|
|
||||||
MultiByteToWideChar(CP_OEMCP, 0, fromA, -1, fromW, MAX_PATH);
|
|
||||||
MultiByteToWideChar(CP_OEMCP, 0, toA, -1, toW, MAX_PATH);
|
|
||||||
|
|
||||||
if (!MoveFileW( fromW, toW ))
|
|
||||||
bSetDOSExtendedError = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x57: /* FILE DATE AND TIME */
|
case 0x57: /* FILE DATE AND TIME */
|
||||||
|
|
|
@ -1300,6 +1300,9 @@ BOOL WINAPI GetCommTimeouts(HANDLE,LPCOMMTIMEOUTS);
|
||||||
LPSTR WINAPI GetCommandLineA(void);
|
LPSTR WINAPI GetCommandLineA(void);
|
||||||
LPWSTR WINAPI GetCommandLineW(void);
|
LPWSTR WINAPI GetCommandLineW(void);
|
||||||
#define GetCommandLine WINELIB_NAME_AW(GetCommandLine)
|
#define GetCommandLine WINELIB_NAME_AW(GetCommandLine)
|
||||||
|
DWORD WINAPI GetCompressedFileSizeA(LPCSTR,LPDWORD);
|
||||||
|
DWORD WINAPI GetCompressedFileSizeW(LPCWSTR,LPDWORD);
|
||||||
|
#define GetCompressedFileSize WINELIB_NAME_AW(GetCompressedFileSize)
|
||||||
BOOL WINAPI GetComputerNameA(LPSTR,LPDWORD);
|
BOOL WINAPI GetComputerNameA(LPSTR,LPDWORD);
|
||||||
BOOL WINAPI GetComputerNameW(LPWSTR,LPDWORD);
|
BOOL WINAPI GetComputerNameW(LPWSTR,LPDWORD);
|
||||||
#define GetComputerName WINELIB_NAME_AW(GetComputerName)
|
#define GetComputerName WINELIB_NAME_AW(GetComputerName)
|
||||||
|
|
134
msdos/int21.c
134
msdos/int21.c
|
@ -1020,28 +1020,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||||
if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff );
|
if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
|
|
||||||
TRACE("MKDIR %s\n",
|
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
|
||||||
bSetDOSExtendedError = (!CreateDirectory16( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx ), NULL));
|
|
||||||
/* FIXME: CreateDirectory's LastErrors will clash with the ones
|
|
||||||
* used by dos. AH=39 only returns 3 (path not found) and 5 (access
|
|
||||||
* denied), while CreateDirectory return several ones. remap some of
|
|
||||||
* them. -Marcus
|
|
||||||
*/
|
|
||||||
if (bSetDOSExtendedError) {
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_ALREADY_EXISTS:
|
|
||||||
case ERROR_FILENAME_EXCED_RANGE:
|
|
||||||
case ERROR_DISK_FULL:
|
|
||||||
SetLastError(ERROR_ACCESS_DENIED);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
|
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
|
||||||
TRACE("CHDIR %s\n",
|
TRACE("CHDIR %s\n",
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
||||||
|
@ -1060,69 +1038,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||||
OpenExistingFile(context);
|
OpenExistingFile(context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
|
|
||||||
TRACE("READ from %d to %04lX:%04X for %d byte\n",BX_reg(context),
|
|
||||||
context->SegDs,DX_reg(context),CX_reg(context) );
|
|
||||||
{
|
|
||||||
LONG result;
|
|
||||||
if (ISV86(context))
|
|
||||||
result = _hread16( BX_reg(context),
|
|
||||||
CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx ),
|
|
||||||
CX_reg(context) );
|
|
||||||
else
|
|
||||||
result = WIN16_hread( BX_reg(context),
|
|
||||||
MAKESEGPTR( context->SegDs, context->Edx ),
|
|
||||||
CX_reg(context) );
|
|
||||||
if (result == -1) bSetDOSExtendedError = TRUE;
|
|
||||||
else SET_AX( context, (WORD)result );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
|
|
||||||
TRACE("LSEEK handle %d offset %ld from %s\n",
|
|
||||||
BX_reg(context), MAKELONG(DX_reg(context),CX_reg(context)),
|
|
||||||
(AL_reg(context)==0)?"start of file":(AL_reg(context)==1)?
|
|
||||||
"current file position":"end of file");
|
|
||||||
{
|
|
||||||
LONG status = _llseek16( BX_reg(context),
|
|
||||||
MAKELONG(DX_reg(context),CX_reg(context)),
|
|
||||||
AL_reg(context) );
|
|
||||||
if (status == -1) bSetDOSExtendedError = TRUE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SET_AX( context, LOWORD(status) );
|
|
||||||
SET_DX( context, HIWORD(status) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x43: /* FILE ATTRIBUTES */
|
|
||||||
switch (AL_reg(context))
|
|
||||||
{
|
|
||||||
case 0x00:
|
|
||||||
TRACE("GET FILE ATTRIBUTES for %s\n",
|
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
|
||||||
SET_AX( context, GetFileAttributesA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx)));
|
|
||||||
if (AX_reg(context) == 0xffff) bSetDOSExtendedError = TRUE;
|
|
||||||
else SET_CX( context, AX_reg(context) );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x01:
|
|
||||||
TRACE("SET FILE ATTRIBUTES 0x%02x for %s\n", CX_reg(context),
|
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
|
||||||
bSetDOSExtendedError =
|
|
||||||
(!SetFileAttributesA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx),
|
|
||||||
CX_reg(context) ));
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
FIXME("GET COMPRESSED FILE SIZE for %s stub\n",
|
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x44: /* IOCTL */
|
case 0x44: /* IOCTL */
|
||||||
switch (AL_reg(context))
|
switch (AL_reg(context))
|
||||||
{
|
{
|
||||||
|
@ -1334,55 +1249,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||||
case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
|
case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
|
||||||
switch(AL_reg(context))
|
switch(AL_reg(context))
|
||||||
{
|
{
|
||||||
case 0x39: /* Create directory */
|
|
||||||
TRACE("LONG FILENAME - MAKE DIRECTORY %s\n",
|
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx));
|
|
||||||
bSetDOSExtendedError = (!CreateDirectoryA(
|
|
||||||
CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx ), NULL));
|
|
||||||
/* FIXME: CreateDirectory's LastErrors will clash with the ones
|
|
||||||
* used by dos. AH=39 only returns 3 (path not found) and 5 (access
|
|
||||||
* denied), while CreateDirectory return several ones. remap some of
|
|
||||||
* them. -Marcus
|
|
||||||
*/
|
|
||||||
if (bSetDOSExtendedError) {
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_ALREADY_EXISTS:
|
|
||||||
case ERROR_FILENAME_EXCED_RANGE:
|
|
||||||
case ERROR_DISK_FULL:
|
|
||||||
SetLastError(ERROR_ACCESS_DENIED);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x43: /* Get/Set file attributes */
|
|
||||||
TRACE("LONG FILENAME -EXTENDED GET/SET FILE ATTRIBUTES %s\n",
|
|
||||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx));
|
|
||||||
switch (BL_reg(context))
|
|
||||||
{
|
|
||||||
case 0x00: /* Get file attributes */
|
|
||||||
TRACE("\tretrieve attributes\n");
|
|
||||||
SET_CX( context, GetFileAttributesA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx)));
|
|
||||||
if (CX_reg(context) == 0xffff) bSetDOSExtendedError = TRUE;
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
TRACE("\tset attributes 0x%04x\n",CX_reg(context));
|
|
||||||
bSetDOSExtendedError = (!SetFileAttributesA(
|
|
||||||
CTX_SEG_OFF_TO_LIN(context, context->SegDs,
|
|
||||||
context->Edx),
|
|
||||||
CX_reg(context) ) );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FIXME("Unimplemented long file name function:\n");
|
|
||||||
INT_BARF( context, 0x21 );
|
|
||||||
SET_CFLAG(context);
|
|
||||||
SET_AL( context, 0 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x47: /* Get current directory */
|
case 0x47: /* Get current directory */
|
||||||
TRACE(" LONG FILENAME - GET CURRENT DIRECTORY for drive %s\n",
|
TRACE(" LONG FILENAME - GET CURRENT DIRECTORY for drive %s\n",
|
||||||
INT21_DriveName(DL_reg(context)));
|
INT21_DriveName(DL_reg(context)));
|
||||||
|
|
Loading…
Reference in New Issue