ChangeLog: * dlls/winedos/int21.c * msdos/int21.c Move directory handling, File time and attribute functions to winedos. nog.
--- msdos/int21.c.3 2002-11-27 15:45:35.000000000 +0200 +++ msdos/int21.c 2002-11-27 15:46:00.000000000 +0200 @@ -558,24 +558,6 @@ return bExtendedError; } - -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 BOOL INT21_GetCurrentDirectory( CONTEXT86 *context ) { int drive = DOS_GET_DRIVE( DL_reg(context) ); @@ -923,12 +905,6 @@ SET_BX( context, (int)&heap->InDosFlag - (int)heap ); break; - case 0x36: /* GET FREE DISK SPACE */ - TRACE("GET FREE DISK SPACE FOR DRIVE %s\n", - INT21_DriveName( DL_reg(context))); - if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff ); - break; - case 0x37: { unsigned char switchchar='/'; @@ -958,74 +934,6 @@ SET_CFLAG(context); 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 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)); - bSetDOSExtendedError = !INT21_ChangeDir(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 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 */ switch (AL_reg(context)) { @@ -1222,50 +1130,6 @@ SET_AL( context, 0x00 ); /* pretend we can tell. 00h = off 01h = on */ 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 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 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ TRACE("GET OR SET MEMORY/UMB ALLOCATION STRATEGY subfunction %d\n", AL_reg(context)); @@ -1325,19 +1189,6 @@ } break; - case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ - TRACE("TRUENAME %s\n", - (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Esi)); - { - if (!GetFullPathNameA( CTX_SEG_OFF_TO_LIN(context, context->SegDs, - context->Esi), 128, - CTX_SEG_OFF_TO_LIN(context, context->SegEs, - context->Edi),NULL)) - bSetDOSExtendedError = TRUE; - else SET_AX( context, 0 ); - } - break; - case 0x61: /* UNUSED */ case 0x63: /* misc. language support */ switch (AL_reg(context)) { --- dlls/winedos/int21.c.3 2002-11-27 15:45:46.000000000 +0200 +++ dlls/winedos/int21.c 2002-11-27 15:46:00.000000000 +0200 @@ -336,6 +336,32 @@ } /*********************************************************************** + * INT21_GetFreeDiskSpace [internal] + * + * Gets the amount of free disk space. + * + * PARAMS: + * context [I]: Pointer to structure holding registers. + * + * RETURNS: + * 1: Success. + */ +static int INT21_GetFreeDiskSpace(CONTEXT86 *context) +{ + DWORD cluster_sectors, sector_bytes, free_clusters, total_clusters; + char root[] = "A:\\"; + + *root += GetDosDrive(DL_reg(context)); + if (!GetDiskFreeSpaceA(root, &cluster_sectors, §or_bytes, + &free_clusters, &total_clusters)) return 0; + SET_AX(context, cluster_sectors); + SET_BX(context, free_clusters); + SET_CX(context, sector_bytes); + SET_DX(context, total_clusters); + return 1; +} + +/*********************************************************************** * GetCurrentDTA [internal] * * Returns a pointer to the current DTA. @@ -1081,6 +1107,44 @@ } break; + case 0x36: /* GET FREE DISK SPACE */ + TRACE("GET FREE DISK SPACE FOR DRIVE %s\n", + INT21_DriveName( DL_reg(context))); + if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff ); + break; + + case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */ + TRACE("MKDIR %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 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */ + TRACE("RMDIR %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 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */ + TRACE("CHDIR %s\n", + (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx)); bSetDOSExtendedError = !SetCurrentDirectoryA(CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx)); 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)); { @@ -1163,6 +1227,12 @@ } 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)), @@ -1179,6 +1249,34 @@ } 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 */ DOSVM_Int21Handler_Ioctl( context ); break; @@ -1280,6 +1378,51 @@ } 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 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 0x59: /* Get extended error info */ INT21_GetExtendedError(context); break; @@ -1339,6 +1482,18 @@ } break; + case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ + TRACE("TRUENAME %s\n", + (LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Esi)); { + if(!GetFullPathNameA(CTX_SEG_OFF_TO_LIN(context, context->SegDs, + context->Esi), 128, + CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi),NULL)) + bSetDOSExtendedError = TRUE; + else SET_AX(context, 0); + } + break; + + case 0x62: /* GET PSP ADDRESS */ TRACE("GET CURRENT PSP ADDRESS\n"); /* FIXME: should we return the original DOS PSP upon */