diff --git a/files/directory.c b/files/directory.c index c2ac33109b8..63041592253 100644 --- a/files/directory.c +++ b/files/directory.c @@ -295,6 +295,13 @@ BOOL16 WINAPI CreateDirectory16( LPCSTR path, LPVOID dummy ) /*********************************************************************** * CreateDirectory32A (KERNEL32.39) + * RETURNS: + * TRUE : success + * FALSE : failure + * ERROR_DISK_FULL: on full disk + * ERROR_ALREADY_EXISTS: if directory name exists (even as file) + * ERROR_ACCESS_DENIED: on permission problems + * ERROR_FILENAME_EXCED_RANGE: too long filename(s) */ BOOL WINAPI CreateDirectoryA( LPCSTR path, LPSECURITY_ATTRIBUTES lpsecattribs ) @@ -309,11 +316,16 @@ BOOL WINAPI CreateDirectoryA( LPCSTR path, return FALSE; } if (!DOSFS_GetFullName( path, FALSE, &full_name )) return 0; - if ((mkdir( full_name.long_name, 0777 ) == -1) && (errno != EEXIST)) - { - WARN (file, "Errno %i trying to create directory %s.\n", errno, full_name.long_name); - FILE_SetDosError(); - return FALSE; + if (mkdir( full_name.long_name, 0777 ) == -1) { + WARN (file, "Errno %i trying to create directory %s.\n", errno, full_name.long_name); + /* the FILE_SetDosError() generated error codes don't match the + * CreateDirectory ones for some errnos */ + switch (errno) { + case EEXIST: SetLastError(ERROR_ALREADY_EXISTS); break; + case ENOSPC: SetLastError(ERROR_DISK_FULL); break; + default: FILE_SetDosError();break; + } + return FALSE; } return TRUE; } diff --git a/msdos/int21.c b/msdos/int21.c index 6f7c9b1e0c2..d53b1616d4a 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -1010,12 +1010,14 @@ static void INT21_GetExtendedError( CONTEXT *context ) action = SA_Abort; locus = EL_Unknown; break; + case ERROR_DISK_FULL: case ERROR_HANDLE_DISK_FULL: class = EC_MediaError; action = SA_Abort; locus = EL_Disk; break; case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: class = EC_Exists; action = SA_Abort; locus = EL_Disk; @@ -1469,6 +1471,21 @@ void WINAPI DOS3Call( CONTEXT *context ) (LPCSTR)CTX_SEG_OFF_TO_LIN(context, DS_reg(context), EDX_reg(context))); bSetDOSExtendedError = (!CreateDirectory16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context), EDX_reg(context) ), 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 */