mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 06:30:37 +00:00
Move get current directory and set current directory int21
subfunctions into winedos. Fix quite a few bugs in the implementation of these functions.
This commit is contained in:
parent
6f27b3bc06
commit
4cbc69a223
@ -147,8 +147,19 @@ static BYTE INT21_GetCurrentDrive()
|
||||
static BYTE INT21_MapDrive( BYTE drive )
|
||||
{
|
||||
if (drive)
|
||||
{
|
||||
WCHAR drivespec[3] = {'A', ':', 0};
|
||||
UINT drivetype;
|
||||
|
||||
drivespec[0] += drive - 1;
|
||||
drivetype = GetDriveTypeW( drivespec );
|
||||
|
||||
if (drivetype == DRIVE_UNKNOWN || drivetype == DRIVE_NO_ROOT_DIR)
|
||||
return MAX_DOS_DRIVES;
|
||||
|
||||
return drive - 1;
|
||||
|
||||
}
|
||||
|
||||
return INT21_GetCurrentDrive();
|
||||
}
|
||||
|
||||
@ -208,7 +219,7 @@ static BOOL INT21_ReadChar( BYTE *input, CONTEXT86 *waitctx )
|
||||
*
|
||||
* Return DOS country code for default system locale.
|
||||
*/
|
||||
static WORD INT21_GetSystemCountryCode()
|
||||
static WORD INT21_GetSystemCountryCode( void )
|
||||
{
|
||||
/*
|
||||
* FIXME: Determine country code. We should probably use
|
||||
@ -369,6 +380,144 @@ static WORD INT21_GetHeapSelector( CONTEXT86 *context )
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* INT21_GetCurrentDirectory
|
||||
*
|
||||
* Handler for:
|
||||
* - function 0x47
|
||||
* - subfunction 0x47 of function 0x71
|
||||
*/
|
||||
static BOOL INT21_GetCurrentDirectory( CONTEXT86 *context, BOOL islong )
|
||||
{
|
||||
char *buffer = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Esi);
|
||||
BYTE new_drive = INT21_MapDrive( DL_reg(context) );
|
||||
BYTE old_drive = INT21_GetCurrentDrive();
|
||||
WCHAR pathW[MAX_PATH];
|
||||
char pathA[MAX_PATH];
|
||||
WCHAR *ptr = pathW;
|
||||
|
||||
TRACE( "drive %d\n", DL_reg(context) );
|
||||
|
||||
if (new_drive == MAX_DOS_DRIVES)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DRIVE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab current directory.
|
||||
*/
|
||||
|
||||
INT21_SetCurrentDrive( new_drive );
|
||||
if (!GetCurrentDirectoryW( MAX_PATH, pathW ))
|
||||
{
|
||||
INT21_SetCurrentDrive( old_drive );
|
||||
return FALSE;
|
||||
}
|
||||
INT21_SetCurrentDrive( old_drive );
|
||||
|
||||
/*
|
||||
* Convert into short format.
|
||||
*/
|
||||
|
||||
if (!islong)
|
||||
{
|
||||
DWORD result = GetShortPathNameW( pathW, pathW, MAX_PATH );
|
||||
if (!result)
|
||||
return FALSE;
|
||||
if (result > MAX_PATH)
|
||||
{
|
||||
WARN( "Short path too long!\n" );
|
||||
SetLastError(ERROR_NETWORK_BUSY); /* Internal Wine error. */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The returned pathname does not include
|
||||
* the drive letter, colon or leading backslash.
|
||||
*/
|
||||
|
||||
if (ptr[0] == '\\')
|
||||
{
|
||||
/*
|
||||
* FIXME: We should probably just strip host part from name...
|
||||
*/
|
||||
FIXME( "UNC names are not supported.\n" );
|
||||
SetLastError(ERROR_NETWORK_BUSY); /* Internal Wine error. */
|
||||
return FALSE;
|
||||
}
|
||||
else if (!ptr[0] || ptr[1] != ':' || ptr[2] != '\\')
|
||||
{
|
||||
WARN( "Path is neither UNC nor DOS path: %s\n",
|
||||
wine_dbgstr_w(ptr) );
|
||||
SetLastError(ERROR_NETWORK_BUSY); /* Internal Wine error. */
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove drive letter, colon and leading backslash. */
|
||||
ptr += 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert into OEM string.
|
||||
*/
|
||||
|
||||
if (!WideCharToMultiByte(CP_OEMCP, 0, ptr, -1, pathA,
|
||||
MAX_PATH, NULL, NULL))
|
||||
{
|
||||
WARN( "Cannot convert path!\n" );
|
||||
SetLastError(ERROR_NETWORK_BUSY); /* Internal Wine error. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Success.
|
||||
*/
|
||||
|
||||
if (!islong)
|
||||
{
|
||||
/* Undocumented success code. */
|
||||
SET_AX( context, 0x0100 );
|
||||
|
||||
/* Truncate buffer to 64 bytes. */
|
||||
pathA[63] = 0;
|
||||
}
|
||||
|
||||
TRACE( "%c:=%s\n", 'A' + new_drive, pathA );
|
||||
|
||||
strcpy( buffer, pathA );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* INT21_SetCurrentDirectory
|
||||
*
|
||||
* Handler for:
|
||||
* - function 0x3b
|
||||
* - subfunction 0x3b of function 0x71
|
||||
*/
|
||||
static BOOL INT21_SetCurrentDirectory( CONTEXT86 *context )
|
||||
{
|
||||
WCHAR dirW[MAX_PATH];
|
||||
char *dirA = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
|
||||
BYTE drive = INT21_GetCurrentDrive();
|
||||
BOOL result;
|
||||
|
||||
TRACE( "SET CURRENT DIRECTORY %s\n", dirA );
|
||||
|
||||
MultiByteToWideChar(CP_OEMCP, 0, dirA, -1, dirW, MAX_PATH);
|
||||
result = SetCurrentDirectoryW( dirW );
|
||||
|
||||
/* This function must not change current drive. */
|
||||
INT21_SetCurrentDrive( drive );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* INT21_BufferedInput
|
||||
*
|
||||
@ -1968,7 +2117,8 @@ static void INT21_LongFilename( CONTEXT86 *context )
|
||||
break;
|
||||
|
||||
case 0x3b: /* LONG FILENAME - CHANGE DIRECTORY */
|
||||
INT_Int21Handler( context );
|
||||
if (!INT21_SetCurrentDirectory( context ))
|
||||
bSetDOSExtendedError = TRUE;
|
||||
break;
|
||||
|
||||
case 0x41: /* LONG FILENAME - DELETE FILE */
|
||||
@ -1991,6 +2141,10 @@ static void INT21_LongFilename( CONTEXT86 *context )
|
||||
break;
|
||||
|
||||
case 0x47: /* LONG FILENAME - GET CURRENT DIRECTORY */
|
||||
if (!INT21_GetCurrentDirectory( context, TRUE ))
|
||||
bSetDOSExtendedError = TRUE;
|
||||
break;
|
||||
|
||||
case 0x4e: /* LONG FILENAME - FIND FIRST MATCHING FILE */
|
||||
case 0x4f: /* LONG FILENAME - FIND NEXT MATCHING FILE */
|
||||
INT_Int21Handler( context );
|
||||
@ -2758,6 +2912,10 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||
break;
|
||||
|
||||
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
|
||||
if (!INT21_SetCurrentDirectory( context ))
|
||||
bSetDOSExtendedError = TRUE;
|
||||
break;
|
||||
|
||||
case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
|
||||
case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
|
||||
INT_Int21Handler( context );
|
||||
@ -2910,7 +3068,8 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||
break;
|
||||
|
||||
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
|
||||
INT_Int21Handler( context );
|
||||
if (!INT21_GetCurrentDirectory( context, FALSE ))
|
||||
bSetDOSExtendedError = TRUE;
|
||||
break;
|
||||
|
||||
case 0x48: /* ALLOCATE MEMORY */
|
||||
|
@ -532,24 +532,6 @@ static BOOL INT21_ExtendedOpenCreateFile(CONTEXT86 *context )
|
||||
}
|
||||
|
||||
|
||||
static BOOL INT21_ChangeDir( CONTEXT86 *context )
|
||||
{
|
||||
int drive;
|
||||
char *dirname = CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx);
|
||||
WCHAR dirnameW[MAX_PATH];
|
||||
|
||||
TRACE("changedir %s\n", dirname);
|
||||
if (dirname[0] && (dirname[1] == ':'))
|
||||
{
|
||||
drive = toupper(dirname[0]) - 'A';
|
||||
dirname += 2;
|
||||
}
|
||||
else drive = DRIVE_GetCurrentDrive();
|
||||
MultiByteToWideChar(CP_OEMCP, 0, dirname, -1, dirnameW, MAX_PATH);
|
||||
return DRIVE_Chdir( drive, dirnameW );
|
||||
}
|
||||
|
||||
|
||||
static int INT21_FindFirst( CONTEXT86 *context )
|
||||
{
|
||||
char *p;
|
||||
@ -661,23 +643,6 @@ static BOOL INT21_CreateTempFile( CONTEXT86 *context )
|
||||
}
|
||||
|
||||
|
||||
static BOOL INT21_GetCurrentDirectory( CONTEXT86 *context )
|
||||
{
|
||||
int drive = DOS_GET_DRIVE( DL_reg(context) );
|
||||
char *ptr = (char *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Esi );
|
||||
|
||||
if (!DRIVE_IsValid(drive))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_DRIVE );
|
||||
return FALSE;
|
||||
}
|
||||
WideCharToMultiByte(CP_OEMCP, 0, DRIVE_GetDosCwd(drive), -1, ptr, 64, NULL, NULL);
|
||||
ptr[63] = 0; /* ensure 0 termination */
|
||||
SET_AX( context, 0x0100 ); /* success return code */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int INT21_GetDiskSerialNumber( CONTEXT86 *context )
|
||||
{
|
||||
BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
|
||||
@ -893,12 +858,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||
if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff );
|
||||
break;
|
||||
|
||||
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
|
||||
TRACE("CHDIR %s\n",
|
||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
||||
bSetDOSExtendedError = !INT21_ChangeDir(context);
|
||||
break;
|
||||
|
||||
case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
|
||||
TRACE("CREAT flag 0x%02x %s\n",CX_reg(context),
|
||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
||||
@ -936,12 +895,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
|
||||
TRACE("CWD - GET CURRENT DIRECTORY for drive %s\n",
|
||||
INT21_DriveName( DL_reg(context)));
|
||||
bSetDOSExtendedError = !INT21_GetCurrentDirectory(context);
|
||||
break;
|
||||
|
||||
case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
|
||||
TRACE("FINDFIRST mask 0x%04x spec %s\n",CX_reg(context),
|
||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
||||
@ -1048,12 +1001,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||
case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
|
||||
switch(AL_reg(context))
|
||||
{
|
||||
case 0x47: /* Get current directory */
|
||||
TRACE(" LONG FILENAME - GET CURRENT DIRECTORY for drive %s\n",
|
||||
INT21_DriveName(DL_reg(context)));
|
||||
bSetDOSExtendedError = !INT21_GetCurrentDirectory(context);
|
||||
break;
|
||||
|
||||
case 0x4e: /* Find first file */
|
||||
TRACE(" LONG FILENAME - FIND FIRST MATCHING FILE for %s\n",
|
||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx));
|
||||
@ -1134,19 +1081,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
||||
bSetDOSExtendedError = INT21_ExtendedOpenCreateFile(context);
|
||||
break;
|
||||
|
||||
case 0x3b: /* Change directory */
|
||||
TRACE("LONG FILENAME - CHANGE DIRECTORY %s\n",
|
||||
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
||||
if (!SetCurrentDirectoryA(CTX_SEG_OFF_TO_LIN(context,
|
||||
context->SegDs,
|
||||
context->Edx
|
||||
))
|
||||
) {
|
||||
SET_CFLAG(context);
|
||||
SET_AL( context, GetLastError() );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unimplemented long file name function:\n");
|
||||
INT_BARF( context, 0x21 );
|
||||
|
Loading…
Reference in New Issue
Block a user