}
+/***********************************************************************
+ * INT21_LongFilename
+ *
+ * Handler for function 0x71.
+ */
+static void INT21_LongFilename( CONTEXT86 *context )
+{
+ BOOL bSetDOSExtendedError = FALSE;
+
+ if (HIBYTE(HIWORD(GetVersion16())) < 0x07)
+ {
+ TRACE( "LONG FILENAME - functions supported only under DOS7\n" );
+ SET_CFLAG( context );
+ SET_AL( context, 0 );
+ return;
+ }
+
+ switch (AL_reg(context))
+ {
+ case 0x0d: /* RESET DRIVE */
+ case 0x39: /* LONG FILENAME - MAKE DIRECTORY */
+ INT_Int21Handler( context );
+ break;
+
+ case 0x3a: /* LONG FILENAME - REMOVE DIRECTORY */
+ {
+ WCHAR dirW[MAX_PATH];
+ char *dirA = CTX_SEG_OFF_TO_LIN(context,
+ context->SegDs, context->Edx);
+
+ TRACE( "LONG FILENAME - REMOVE DIRECTORY %s\n", dirA );
+ MultiByteToWideChar(CP_OEMCP, 0, dirA, -1, dirW, MAX_PATH);
+
+ if (!RemoveDirectoryW( dirW ))
+ bSetDOSExtendedError = TRUE;
+ }
+ break;
+
+ case 0x3b: /* LONG FILENAME - CHANGE DIRECTORY */
+ INT_Int21Handler( context );
+ break;
+
+ case 0x41: /* LONG FILENAME - DELETE FILE */
+ {
+ WCHAR fileW[MAX_PATH];
+ char *fileA = CTX_SEG_OFF_TO_LIN(context,
+ context->SegDs, context->Edx);
+
+ TRACE( "LONG FILENAME - DELETE FILE %s\n", fileA );
+ MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
+
+ if (!DeleteFileW( fileW ))
+ bSetDOSExtendedError = TRUE;
+ }
+ break;
+
+ case 0x43: /* LONG FILENAME - EXTENDED GET/SET FILE ATTRIBUTES */
+ case 0x47: /* LONG FILENAME - GET CURRENT DIRECTORY */
+ case 0x4e: /* LONG FILENAME - FIND FIRST MATCHING FILE */
+ case 0x4f: /* LONG FILENAME - FIND NEXT MATCHING FILE */
+ INT_Int21Handler( context );
+ break;
+
+ case 0x56: /* LONG FILENAME - RENAME FILE */
+ {
+ 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( "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;
+
+ case 0x60: /* LONG FILENAME - CONVERT PATH */
+ case 0x6c: /* LONG FILENAME - CREATE OR OPEN FILE */
+ case 0xa0: /* LONG FILENAME - GET VOLUME INFORMATION */
+ case 0xa1: /* LONG FILENAME - "FindClose" - TERMINATE DIRECTORY SEARCH */
+ case 0xa6: /* LONG FILENAME - GET FILE INFO BY HANDLE */
+ case 0xa7: /* LONG FILENAME - CONVERT TIME */
+ case 0xa8: /* LONG FILENAME - GENERATE SHORT FILENAME */
+ case 0xa9: /* LONG FILENAME - SERVER CREATE OR OPEN FILE */
+ case 0xaa: /* LONG FILENAME - SUBST */
+ INT_Int21Handler( context );
+ break;
+
+ default:
+ INT_BARF( context, 0x21 );
+ }
+
+ if (bSetDOSExtendedError)
+ {
+ SET_AX( context, GetLastError() );
+ SET_CFLAG( context );
+ }
+}
+
+
/***********************************************************************
* INT21_GetExtendedError
*/
break;
case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
- case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
+ INT_Int21Handler( context );
+ break;
+
+ case 0x3a: /* "RMDIR" - REMOVE DIRECTORY */
+ {
+ WCHAR dirW[MAX_PATH];
+ char *dirA = CTX_SEG_OFF_TO_LIN(context,
+ context->SegDs, context->Edx);
+
+ TRACE( "REMOVE DIRECTORY %s\n", dirA );
+
+ MultiByteToWideChar(CP_OEMCP, 0, dirA, -1, dirW, MAX_PATH);
+
+ if (!RemoveDirectoryW( dirW ))
+ bSetDOSExtendedError = TRUE;
+ }
+ break;
+
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
+ INT_Int21Handler( context );
+ break;
+
case 0x3e: /* "CLOSE" - CLOSE FILE */
+ TRACE( "CLOSE handle %d\n", BX_reg(context) );
+ if (_lclose16( BX_reg(context) ) == HFILE_ERROR16)
+ bSetDOSExtendedError = TRUE;
+ break;
+
case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
INT_Int21Handler( context );
break;
break;
case 0x41: /* "UNLINK" - DELETE FILE */
+ {
+ WCHAR fileW[MAX_PATH];
+ char *fileA = CTX_SEG_OFF_TO_LIN(context,
+ context->SegDs,
+ context->Edx);
+
+ TRACE( "UNLINK %s\n", fileA );
+ MultiByteToWideChar(CP_OEMCP, 0, fileA, -1, fileW, MAX_PATH);
+
+ if (!DeleteFileW( fileW ))
+ bSetDOSExtendedError = TRUE;
+ }
+ break;
+
case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
case 0x43: /* FILE ATTRIBUTES */
INT_Int21Handler( context );
break;
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
+ TRACE( "FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n",
+ BX_reg(context), CX_reg(context) );
+ if (FILE_Dup2( BX_reg(context), CX_reg(context) ) == HFILE_ERROR16)
+ bSetDOSExtendedError = TRUE;
+ break;
+
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
INT_Int21Handler( context );
break;
break;
case 0x56: /* "RENAME" - RENAME FILE */
- INT_Int21Handler( 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 %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;
case 0x57: /* FILE DATE AND TIME */
break;
case 0x71: /* MSDOS 7 - LONG FILENAME FUNCTIONS */
- INT_Int21Handler( context );
+ INT21_LongFilename( context );
break;
case 0x73: /* MSDOS7 - FAT32 */
}
break;
- case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
- TRACE("RMDIR %s\n",
- (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
- bSetDOSExtendedError = (!RemoveDirectory16( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
- context->Edx )));
- break;
-
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
TRACE("CHDIR %s\n",
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
OpenExistingFile(context);
break;
- case 0x3e: /* "CLOSE" - CLOSE FILE */
- TRACE("CLOSE handle %d\n",BX_reg(context));
- SET_AX( context, _lclose16( BX_reg(context) ));
- bSetDOSExtendedError = (AX_reg(context) != 0);
- 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) );
}
break;
- case 0x41: /* "UNLINK" - DELETE FILE */
- TRACE("UNLINK %s\n",
- (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
- bSetDOSExtendedError = (!DeleteFileA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,
- context->Edx )));
- 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)),
}
break;
- case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
- TRACE("FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n",
- BX_reg(context),CX_reg(context));
- bSetDOSExtendedError = (FILE_Dup2( BX_reg(context), CX_reg(context) ) == HFILE_ERROR16);
- break;
-
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
TRACE("CWD - GET CURRENT DIRECTORY for drive %s\n",
INT21_DriveName( DL_reg(context)));
else SET_AX( context, 0 ); /* OK */
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 =
- (!MoveFileA( CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx),
- CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi)));
- break;
-
case 0x5a: /* CREATE TEMPORARY FILE */
TRACE("CREATE TEMPORARY FILE\n");
bSetDOSExtendedError = !INT21_CreateTempFile(context);
break;
case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
- if ((GetVersion()&0xC0000004)!=0xC0000004) {
- /* not supported on anything but Win95 */
- TRACE("LONG FILENAME functions supported only by win95\n");
- SET_CFLAG(context);
- SET_AL( context, 0 );
- } else
switch(AL_reg(context))
{
case 0x39: /* Create directory */
}
}
break;
- case 0x3a: /* Remove directory */
- TRACE("LONG FILENAME - REMOVE DIRECTORY %s\n",
- (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx));
- bSetDOSExtendedError = (!RemoveDirectoryA(
- CTX_SEG_OFF_TO_LIN(context, context->SegDs,
- context->Edx )));
- 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));
SET_AL( context, GetLastError() );
}
break;
- case 0x41: /* Delete file */
- TRACE("LONG FILENAME - DELETE FILE %s\n",
- (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
- if (!DeleteFileA(CTX_SEG_OFF_TO_LIN(context,
- context->SegDs,
- context->Edx)
- )) {
- SET_CFLAG(context);
- SET_AL( context, GetLastError() );
- }
- break;
- case 0x56: /* Move (rename) file */
- {
- LPCSTR fn1 = (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
- LPCSTR fn2 = (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi);
- TRACE("LONG FILENAME - RENAME FILE %s to %s\n", fn1, fn2);
- if (!MoveFileA(fn1, fn2))
- {
- SET_CFLAG(context);
- SET_AL( context, GetLastError() );
- }
- }
- break;
+
default:
FIXME("Unimplemented long file name function:\n");
INT_BARF( context, 0x21 );