diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 5937756063d..9f0c310c34e 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -1070,6 +1070,7 @@ ################################################################ # Wine extensions: Win16 functions that are needed by other dlls # +@ stdcall _lclose16(long) _lclose16 @ stdcall AllocCStoDSAlias16(long) AllocCStoDSAlias16 @ stdcall AllocSelectorArray16(long) AllocSelectorArray16 @ stdcall ConvertDialog32To16(ptr long ptr) ConvertDialog32To16 @@ -1144,6 +1145,7 @@ @ cdecl DOSMEM_Init(long) DOSMEM_Init @ cdecl DOSMEM_ResizeBlock(ptr long long) DOSMEM_ResizeBlock @ cdecl DRIVE_OpenDevice(long long) DRIVE_OpenDevice +@ cdecl FILE_Dup2(long long) FILE_Dup2 @ stdcall INT_Int21Handler(ptr) INT_Int21Handler @ cdecl LOCAL_Alloc(long long long) LOCAL_Alloc @ cdecl LOCAL_Compact(long long long) LOCAL_Compact diff --git a/dlls/winedos/int21.c b/dlls/winedos/int21.c index 1d17478ed00..7fc6be582d1 100644 --- a/dlls/winedos/int21.c +++ b/dlls/winedos/int21.c @@ -731,6 +731,111 @@ static void INT21_Ioctl( CONTEXT86 *context ) } +/*********************************************************************** + * 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 */ @@ -1244,11 +1349,36 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) 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; @@ -1280,6 +1410,20 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) 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 ); @@ -1310,6 +1454,12 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *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; @@ -1467,7 +1617,21 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) 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 */ @@ -1632,7 +1796,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) break; case 0x71: /* MSDOS 7 - LONG FILENAME FUNCTIONS */ - INT_Int21Handler( context ); + INT21_LongFilename( context ); break; case 0x73: /* MSDOS7 - FAT32 */ diff --git a/msdos/int21.c b/msdos/int21.c index 672e0a9af82..ba44a7bfb93 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -1041,13 +1041,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) } 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)); @@ -1066,12 +1059,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) 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) ); @@ -1091,13 +1078,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *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)), @@ -1241,12 +1221,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *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))); @@ -1270,15 +1244,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *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); @@ -1366,12 +1331,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *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 */ @@ -1396,13 +1355,7 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) } } 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)); @@ -1527,29 +1480,7 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context ) 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 );