diff --git a/files/directory.c b/files/directory.c
index 8255579f3b271d24c12fa4b2980cd660caaca8e2..3d81f69063d2278ca2c2c729a6b678e714029aab 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -294,7 +294,7 @@ BOOL32 WINAPI CreateDirectory32A( LPCSTR path,
     if (DOSFS_GetDevice( path ))
     {
         TRACE(file, "cannot use device '%s'!\n",path);
-        DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
+        SetLastError( ERROR_ACCESS_DENIED );
         return FALSE;
     }
     if (!DOSFS_GetFullName( path, FALSE, &full_name )) return 0;
@@ -362,7 +362,7 @@ BOOL32 WINAPI RemoveDirectory32A( LPCSTR path )
     if (DOSFS_GetDevice( path ))
     {
         TRACE(file, "cannot remove device '%s'!\n", path);
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_FILE_NOT_FOUND );
         return FALSE;
     }
     if (!DOSFS_GetFullName( path, TRUE, &full_name )) return FALSE;
@@ -401,7 +401,7 @@ static BOOL32 DIR_TryPath( const DOS_FULL_NAME *dir, LPCSTR name,
     if ((p_s >= full_name->short_name + sizeof(full_name->short_name) - 14) ||
         (p_l >= full_name->long_name + sizeof(full_name->long_name) - 1))
     {
-        DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_PATH_NOT_FOUND );
         return FALSE;
     }
     if (!DOSFS_FindUnixName( dir->long_name, name, p_l,
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 47d86e2655563bae0cb621e626afcb0f9c8a9006..22c0ed2d479ee41de2c74e73b4428426f02528a8 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -72,12 +72,6 @@ static const DOS_DEVICE DOSFS_Devices[] =
 #define GET_DRIVE(path) \
     (((path)[1] == ':') ? toupper((path)[0]) - 'A' : DOSFS_CurDrive)
 
-    /* DOS extended error status */
-WORD DOS_ExtendedError;
-BYTE DOS_ErrorClass;
-BYTE DOS_ErrorAction;
-BYTE DOS_ErrorLocus;
-
 /* Directory info for DOSFS_ReadDir */
 typedef struct
 {
@@ -319,7 +313,7 @@ static DOS_DIR *DOSFS_OpenDir( LPCSTR path )
     DOS_DIR *dir = HeapAlloc( SystemHeap, 0, sizeof(*dir) );
     if (!dir)
     {
-        DOS_ERROR( ER_OutOfMemory, EC_OutOfResource, SA_Abort, EL_Memory );
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
         return NULL;
     }
 
@@ -716,7 +710,7 @@ static int DOSFS_GetPathDrive( const char **name )
 
     if (!DRIVE_IsValid(drive))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return -1;
     }
     return drive;
@@ -800,7 +794,7 @@ BOOL32 DOSFS_GetFullName( LPCSTR name, BOOL32 check_last, DOS_FULL_NAME *full )
         if ((p_s >= full->short_name + sizeof(full->short_name) - 14) ||
             (p_l >= full->long_name + sizeof(full->long_name) - 1))
         {
-            DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
+            SetLastError( ERROR_PATH_NOT_FOUND );
             return FALSE;
         }
 
@@ -841,12 +835,12 @@ BOOL32 DOSFS_GetFullName( LPCSTR name, BOOL32 check_last, DOS_FULL_NAME *full )
     {
         if (check_last)
         {
-            DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+            SetLastError( ERROR_FILE_NOT_FOUND );
             return FALSE;
         }
         if (*name)  /* Not last */
         {
-            DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
+            SetLastError( ERROR_PATH_NOT_FOUND );
             return FALSE;
         }
     }
@@ -1052,7 +1046,7 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result,
             }
         }
         if ( *endchar )
-        {   DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        {   SetLastError( ERROR_PATH_NOT_FOUND );
             return 0;
         }
         while (!IS_END_OF_NAME(*name) && (!*endchar) )
@@ -1330,7 +1324,7 @@ HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATA32A *data )
     if (!FindNextFile16( handle, data ))
     {
         FindClose16( handle );
-        DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_NO_MORE_FILES );
         return INVALID_HANDLE_VALUE16;
     }
     return handle;
@@ -1381,13 +1375,13 @@ BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATA32A *data )
 
     if (!(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
     {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return FALSE;
     }
     GlobalUnlock16( handle );
     if (!info->path || !info->dir)
     {
-        DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_NO_MORE_FILES );
         return FALSE;
     }
     if (!DOSFS_FindNextEx( info, data ))
@@ -1395,7 +1389,7 @@ BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATA32A *data )
         DOSFS_CloseDir( info->dir ); info->dir = NULL;
         HeapFree( SystemHeap, 0, info->path );
         info->path = info->long_mask = NULL;
-        DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_NO_MORE_FILES );
         return FALSE;
     }
     return TRUE;
@@ -1440,7 +1434,7 @@ BOOL16 WINAPI FindClose16( HANDLE16 handle )
     if ((handle == INVALID_HANDLE_VALUE16) ||
         !(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
     {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return FALSE;
     }
     if (info->dir) DOSFS_CloseDir( info->dir );
diff --git a/files/drive.c b/files/drive.c
index 2c69d0b9ee7806bc1919366b3d0bf6d7ec68f6f4..0c63a9c5bc216176482bf9048ad6104b4d0b838d 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -34,6 +34,7 @@
 
 #include "windows.h"
 #include "winbase.h"
+#include "winerror.h"
 #include "drive.h"
 #include "file.h"
 #include "heap.h"
@@ -267,7 +268,7 @@ int DRIVE_SetCurrentDrive( int drive )
     TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
     if (!DRIVE_IsValid( drive ))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
     TRACE(dosfs, "%c:\n", 'A' + drive );
@@ -460,7 +461,7 @@ int DRIVE_Chdir( int drive, const char *path )
     if (!FILE_Stat( full_name.long_name, &info )) return 0;
     if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
     {
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_FILE_NOT_FOUND );
         return 0;
     }
     unix_cwd = full_name.long_name + strlen( DOSDrives[drive].root );
@@ -493,7 +494,7 @@ int DRIVE_Disable( int drive  )
 {
     if ((drive < 0) || (drive >= MAX_DOS_DRIVES) || !DOSDrives[drive].root)
     {
-        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
     DOSDrives[drive].flags |= DRIVE_DISABLED;
@@ -508,7 +509,7 @@ int DRIVE_Enable( int drive  )
 {
     if ((drive < 0) || (drive >= MAX_DOS_DRIVES) || !DOSDrives[drive].root)
     {
-        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
     DOSDrives[drive].flags &= ~DRIVE_DISABLED;
@@ -533,7 +534,7 @@ int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive )
         !old->root ||
 	(new_drive < 0) || (new_drive >= MAX_DOS_DRIVES))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
 
@@ -644,7 +645,7 @@ static int DRIVE_GetFreeSpace( int drive, LPULARGE_INTEGER size,
 
     if (!DRIVE_IsValid(drive))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
 
diff --git a/files/file.c b/files/file.c
index 9bef1e535c25ab4edd4bced046329d1e8217b870..72b3df4c95ba84f3712ddb87020ee9de39689a56 100644
--- a/files/file.c
+++ b/files/file.c
@@ -226,7 +226,7 @@ test_ro_int24:
 fail_int24:
   FIXME(file,"generate INT24 missing\n");
   /* Is this the right error? */
-  DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
+  SetLastError( ERROR_ACCESS_DENIED );
   return TRUE;
   
 test_ro_err05:
@@ -235,7 +235,7 @@ test_ro_err05:
   /* fall through */
 fail_error05:
   TRACE(file,"Access Denied, oldmode 0x%02x mode 0x%02x\n",oldmode,mode);
-  DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
+  SetLastError( ERROR_ACCESS_DENIED );
   return TRUE;
 }
 #endif
@@ -254,45 +254,45 @@ void FILE_SetDosError(void)
     switch (save_errno)
     {
     case EAGAIN:
-        DOS_ERROR( ER_ShareViolation, EC_Temporary, SA_Retry, EL_Disk );
+        SetLastError( ERROR_SHARING_VIOLATION );
         break;
     case EBADF:
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         break;
     case ENOSPC:
-        DOS_ERROR( ER_DiskFull, EC_MediaError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_HANDLE_DISK_FULL );
         break;
     case EACCES:
     case EPERM:
     case EROFS:
-        DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
+        SetLastError( ERROR_ACCESS_DENIED );
         break;
     case EBUSY:
-        DOS_ERROR( ER_LockViolation, EC_AccessDenied, SA_Abort, EL_Disk );
+        SetLastError( ERROR_LOCK_VIOLATION );
         break;
     case ENOENT:
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_FILE_NOT_FOUND );
         break;
     case EISDIR:
-        DOS_ERROR( ER_CanNotMakeDir, EC_AccessDenied, SA_Abort, EL_Unknown );
+        SetLastError( ERROR_CANNOT_MAKE );
         break;
     case ENFILE:
     case EMFILE:
-        DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Unknown );
+        SetLastError( ERROR_NO_MORE_FILES );
         break;
     case EEXIST:
-        DOS_ERROR( ER_FileExists, EC_Exists, SA_Abort, EL_Disk );
+        SetLastError( ERROR_FILE_EXISTS );
         break;
     case EINVAL:
     case ESPIPE:
-        DOS_ERROR( ER_SeekError, EC_NotFound, SA_Ignore, EL_Disk );
+        SetLastError( ERROR_SEEK );
         break;
     case ENOTEMPTY:
-        DOS_ERROR( ERROR_DIR_NOT_EMPTY, EC_Exists, SA_Ignore, EL_Disk );
+        SetLastError( ERROR_DIR_NOT_EMPTY );
         break;
     default:
         perror( "int21: unknown errno" );
-        DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort, EL_Unknown );
+        SetLastError( ERROR_GEN_FAILURE );
         break;
     }
     errno = save_errno;
@@ -329,8 +329,8 @@ HFILE32 FILE_DupUnixHandle( int fd, DWORD access )
 
     if (!(file = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) )))
     {
-        DOS_ERROR( ER_TooManyOpenFiles, EC_ProgramError, SA_Abort, EL_Disk );
         CLIENT_CloseHandle( reply.handle );
+        SetLastError( ERROR_TOO_MANY_OPEN_FILES );
         return (HFILE32)NULL;
     }
     file->header.type = K32OBJ_FILE;
@@ -507,7 +507,7 @@ HFILE32 WINAPI CreateFile32A( LPCSTR filename, DWORD access, DWORD sharing,
 
 	/* Do not silence this please. It is a critical error. -MM */
         ERR(file, "Couldn't open device '%s'!\n",filename);
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_FILE_NOT_FOUND );
         return HFILE_ERROR32;
     }
 
@@ -766,7 +766,7 @@ UINT32 WINAPI GetTempFileName32A( LPCSTR path, LPCSTR prefix, UINT32 unique,
                 CloseHandle( handle );
                 break;
             }
-            if (DOS_ExtendedError != ER_FileExists)
+            if (GetLastError() != ERROR_FILE_EXISTS)
                 break;  /* No need to go on */
             num++;
             sprintf( p, "%04x.tmp", num );
@@ -932,7 +932,7 @@ found:
             CloseHandle( hFileRet );
             WARN(file, "(%s): OF_VERIFY failed\n", name );
             /* FIXME: what error here? */
-            DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+            SetLastError( ERROR_FILE_NOT_FOUND );
             goto error;
         }
     }
@@ -940,17 +940,27 @@ found:
 
 success:  /* We get here if the open was successful */
     TRACE(file, "(%s): OK, return = %d\n", name, hFileRet );
-    if (mode & OF_EXIST) /* Return the handle, but close it first */
-        CloseHandle( hFileRet );
+    if (win32)
+    {
+        if (mode & OF_EXIST) /* Return the handle, but close it first */
+            CloseHandle( hFileRet );
+    }
+    else
+    {
+        hFileRet = FILE_AllocDosHandle( hFileRet );
+        if (hFileRet == HFILE_ERROR16) goto error;
+        if (mode & OF_EXIST) /* Return the handle, but close it first */
+            _lclose16( hFileRet );
+    }
     return hFileRet;
 
 not_found:  /* We get here if the file does not exist */
     WARN(file, "'%s' not found\n", name );
-    DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+    SetLastError( ERROR_FILE_NOT_FOUND );
     /* fall through */
 
 error:  /* We get here if there was an error opening the file */
-    ofs->nErrCode = DOS_ExtendedError;
+    ofs->nErrCode = GetLastError();
     WARN(file, "(%s): return = HFILE_ERROR error= %d\n", 
 		  name,ofs->nErrCode );
     return HFILE_ERROR32;
@@ -962,8 +972,7 @@ error:  /* We get here if there was an error opening the file */
  */
 HFILE16 WINAPI OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode )
 {
-    TRACE(file,"OpenFile16(%s,%i)\n", name, mode);
-    return FILE_AllocDosHandle( FILE_DoOpenFile( name, ofs, mode, FALSE ) );
+    return FILE_DoOpenFile( name, ofs, mode, FALSE );
 }
 
 
@@ -1025,8 +1034,8 @@ HFILE16 FILE_AllocDosHandle( HANDLE32 handle )
             return i;
         }
 error:
-    DOS_ERROR( ER_TooManyOpenFiles, EC_ProgramError, SA_Abort, EL_Disk );
     CloseHandle( handle );
+    SetLastError( ERROR_TOO_MANY_OPEN_FILES );
     return INVALID_HANDLE_VALUE16;
 }
 
@@ -1041,7 +1050,7 @@ HANDLE32 FILE_GetHandle32( HFILE16 hfile )
     HANDLE32 *table = PROCESS_Current()->dos_handles;
     if ((hfile >= DOS_TABLE_SIZE) || !table || !table[hfile])
     {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return INVALID_HANDLE_VALUE32;
     }
     return table[hfile];
@@ -1061,13 +1070,13 @@ HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 )
     if ((hFile1 >= DOS_TABLE_SIZE) || (hFile2 >= DOS_TABLE_SIZE) ||
         !table || !table[hFile1])
     {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return HFILE_ERROR16;
     }
     if (hFile2 < 5)
     {
         FIXME( file, "stdio handle closed, need proper conversion\n" );
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return HFILE_ERROR16;
     }
     if (!DuplicateHandle( GetCurrentProcess(), table[hFile1],
@@ -1090,12 +1099,12 @@ HFILE16 WINAPI _lclose16( HFILE16 hFile )
     if (hFile < 5)
     {
         FIXME( file, "stdio handle closed, need proper conversion\n" );
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return HFILE_ERROR16;
     }
     if ((hFile >= DOS_TABLE_SIZE) || !table || !table[hFile])
     {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_HANDLE );
         return HFILE_ERROR16;
     }
     TRACE( file, "%d (handle32=%d)\n", hFile, table[hFile] );
@@ -1443,7 +1452,7 @@ UINT16 WINAPI SetHandleCount16( UINT16 count )
         HGLOBAL16 newhandle = GlobalAlloc16( GMEM_MOVEABLE, count );
         if (!newhandle)
         {
-            DOS_ERROR( ER_OutOfMemory, EC_OutOfResource, SA_Abort, EL_Memory );
+            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
             return pdb->nbFiles;
         }
         newfiles = (BYTE *)GlobalLock16( newhandle );
@@ -1528,7 +1537,7 @@ BOOL32 WINAPI DeleteFile32A( LPCSTR path )
     if (DOSFS_GetDevice( path ))
     {
         WARN(file, "cannot remove DOS device '%s'!\n", path);
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_FILE_NOT_FOUND );
         return FALSE;
     }
 
@@ -1682,7 +1691,7 @@ BOOL32 WINAPI MoveFileEx32A( LPCSTR fn1, LPCSTR fn2, DWORD flag )
 	/* use copy, if allowed */
 	if (!(flag & MOVEFILE_COPY_ALLOWED)) {
 	  /* FIXME: Use right error code */
-	  DOS_ERROR( ER_FileExists, EC_Exists, SA_Abort, EL_Disk );
+	  SetLastError( ERROR_FILE_EXISTS );
 	  return FALSE;
 	}
 	else mode =1;
@@ -1691,7 +1700,7 @@ BOOL32 WINAPI MoveFileEx32A( LPCSTR fn1, LPCSTR fn2, DWORD flag )
 	/* target exists, check if we may overwrite */
 	if (!(flag & MOVEFILE_REPLACE_EXISTING)) {
 	  /* FIXME: Use right error code */
-	  DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
+	  SetLastError( ERROR_ACCESS_DENIED );
 	  return FALSE;
 	}
     }
@@ -1699,8 +1708,7 @@ BOOL32 WINAPI MoveFileEx32A( LPCSTR fn1, LPCSTR fn2, DWORD flag )
       if (flag & MOVEFILE_DELAY_UNTIL_REBOOT) {
 	if (flag & MOVEFILE_COPY_ALLOWED) {  
 	  WARN(file, "Illegal flag\n");
-	  DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort,
-		     EL_Unknown );
+	  SetLastError( ERROR_GEN_FAILURE );
 	  return FALSE;
 	}
 	/* FIXME: (bon@elektron.ikp.physik.th-darmstadt.de 970706)
@@ -1791,8 +1799,7 @@ BOOL32 WINAPI MoveFile32A( LPCSTR fn1, LPCSTR fn2 )
       if (S_ISDIR(fstat.st_mode)) {
 	/* No Move for directories across file systems */
 	/* FIXME: Use right error code */
-	DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort,
-		   EL_Unknown );
+	SetLastError( ERROR_GEN_FAILURE );
 	return FALSE;
       }
       else
@@ -2126,7 +2133,7 @@ BOOL32 WINAPI LockFile(
 
   /* shadow locks internally */
   if (!DOS_AddLock(file, &f)) {
-    DOS_ERROR( ER_LockViolation, EC_AccessDenied, SA_Ignore, EL_Disk );
+    SetLastError( ERROR_LOCK_VIOLATION );
     return FALSE;
   }
 
@@ -2134,7 +2141,7 @@ BOOL32 WINAPI LockFile(
 #ifdef USE_UNIX_LOCKS
   if (fcntl(file->unix_handle, F_SETLK, &f) == -1) {
     if (errno == EACCES || errno == EAGAIN) {
-      DOS_ERROR( ER_LockViolation, EC_AccessDenied, SA_Ignore, EL_Disk );
+      SetLastError( ERROR_LOCK_VIOLATION );
     }
     else {
       FILE_SetDosError();
diff --git a/include/msdos.h b/include/msdos.h
index ca68cf2711b7acd2dfcaef8621c788fb306c2062..e59dc64e372aea36fc19898af5b045586c0b92bc 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -113,15 +113,6 @@ extern struct DosDeviceStruct LPT[MAX_PORTS];
 #define FA_ARCHIVE   0x20        /* Archive */
 #define FA_UNUSED    0x40        /* Unused */
 
-
-extern WORD DOS_ExtendedError;
-extern BYTE DOS_ErrorClass, DOS_ErrorAction, DOS_ErrorLocus;
-
-#define DOS_ERROR(err,class,action,locus) \
-    ( SetLastError(err), \
-      DOS_ErrorClass = (class), DOS_ErrorAction = (action), \
-      DOS_ErrorLocus = (locus), DOS_ExtendedError = (err) )
-
 /* Error codes */
 
 #define ER_NoError           0x00
diff --git a/msdos/int21.c b/msdos/int21.c
index 9b422a501299b7696a6ab9025a04bdadafd4ab1b..df36e8ce538498443e40e0c7e3f4011b719c3e2c 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -17,6 +17,7 @@
 #include <utime.h>
 #include <ctype.h>
 #include "windows.h"
+#include "winerror.h"
 #include "drive.h"
 #include "file.h"
 #include "heap.h"
@@ -178,7 +179,7 @@ static void GetDrivePB( CONTEXT *context, int drive )
 {
         if(!DRIVE_IsValid(drive))
         {
-            DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+            SetLastError( ERROR_INVALID_DRIVE );
             AX_reg(context) = 0x00ff;
         }
         else if (heap || INT21_CreateHeap())
@@ -253,7 +254,7 @@ static BOOL32 ioctlGenericBlkDevReq( CONTEXT *context )
 
 	if (!DRIVE_IsValid(drive))
         {
-            DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
+            SetLastError( ERROR_FILE_NOT_FOUND );
             return TRUE;
 	}
 
@@ -432,83 +433,7 @@ static void OpenExistingFile( CONTEXT *context )
                                AL_reg(context) );
     if (AX_reg(context) == (WORD)HFILE_ERROR16)
     {
-        AX_reg(context) = DOS_ExtendedError;
-        SET_CFLAG(context);
-    }
-#if 0
-    {
-        int handle;
-        int mode;
-        int lock;
-
-        switch (AX_reg(context) & 0x0070)
-	{
-	  case 0x00:    /* compatability mode */
-	  case 0x40:    /* DENYNONE */
-            lock = -1;
-	    break;
-
-	  case 0x30:    /* DENYREAD */
-	    TRACE(int21, "(%s): DENYREAD changed to DENYALL\n",
-			 (char *)CTX_SEG_OFF_TO_LIN(context, DS_reg(context),EDX_reg(context)));
-	  case 0x10:    /* DENYALL */  
-	    lock = LOCK_EX;
-	    break;
-
-	  case 0x20:    /* DENYWRITE */
-	    lock = LOCK_SH;
-	    break;
-
-	  default:
-	    lock = -1;
-        }
-
-	if (lock != -1)
-        {
-
-	  int result,retries=sharing_retries;
-	  {
-#if defined(__svr4__) || defined(_SCO_DS)
-              ERR(int21, "Should call flock and needs porting to lockf\n");
-              result = 0;
-              retries = 0;
-#else
-	    result = flock(handle, lock | LOCK_NB);
-#endif
-	    if ( retries && (!result) )
-	    {
-              int i;
-              for(i=0;i<32768*((int)sharing_pause);i++)
-		  result++;                          /* stop the optimizer */
-              for(i=0;i<32768*((int)sharing_pause);i++)
-		  result--;
-	    }
-          }
-	  while( (!result) && (!(retries--)) );
-
-	  if(result)  
-	  {
-	    errno_to_doserr();
-	    AX_reg(context) = DOS_ExtendedError;
-	    close(handle);
-	    SET_CFLAG(context);
-	    return;
-	  }
-
-        }
-
-	Error (0,0,0);
-	AX_reg(context) = handle;
-	RESET_CFLAG(context);
-    }
-#endif
-}
-
-static void CloseFile( CONTEXT *context )
-{
-    if ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0)
-    {
-        AX_reg(context) = DOS_ExtendedError;
+        AX_reg(context) = GetLastError();
         SET_CFLAG(context);
     }
 }
@@ -532,8 +457,7 @@ static BOOL32 INT21_ExtendedOpenCreateFile(CONTEXT *context )
 
       if ((action & 0x07) == 0)
       {
-	  BX_reg(context) = AX_reg(context);
-	  CloseFile(context);
+	  _lclose16( AX_reg(context) );
 	  AX_reg(context) = 0x0050;	/*File exists*/
 	  SET_CFLAG(context);
 	  WARN(int21, "extended open/create: failed because file exists \n");
@@ -543,21 +467,15 @@ static BOOL32 INT21_ExtendedOpenCreateFile(CONTEXT *context )
 	/* Truncate it, but first check if opened for write */
 	if ((BL_reg(context) & 0x0007)== 0) 
 	{
-		  BX_reg(context) = AX_reg(context);
-		  CloseFile(context);
-		  WARN(int21, "extended open/create: failed, trunc on ro file\n");
-		  AX_reg(context) = 0x000C;	/*Access code invalid*/
-		  SET_CFLAG(context);
+            _lclose16( AX_reg(context) );
+            WARN(int21, "extended open/create: failed, trunc on ro file\n");
+            AX_reg(context) = 0x000C;	/*Access code invalid*/
+            SET_CFLAG(context);
 	}
 	else
 	{
-		/* Shuffle arguments to call CloseFile while
-		 * preserving BX and DX */
-
 		TRACE(int21, "extended open/create: Closing before truncate\n");
-		BX_reg(context) = AX_reg(context);
-		CloseFile(context);
-		if (EFL_reg(context) & 0x0001) 
+                if (_lclose16( AX_reg(context) ))
 		{
 		   WARN(int21, "extended open/create: close before trunc failed\n");
 		   AX_reg(context) = 0x0019;	/*Seek Error*/
@@ -641,7 +559,7 @@ static int INT21_FindFirst( CONTEXT *context )
     dta->unixPath = NULL;
     if (!DOSFS_GetFullName( path, FALSE, &full_name ))
     {
-        AX_reg(context) = DOS_ExtendedError;
+        AX_reg(context) = GetLastError();
         SET_CFLAG(context);
         return 0;
     }
@@ -656,8 +574,8 @@ static int INT21_FindFirst( CONTEXT *context )
     {
         HeapFree( GetProcessHeap(), 0, dta->unixPath );
         dta->unixPath = NULL;
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
-        AX_reg(context) = ER_FileNotFound;
+        SetLastError( ERROR_FILE_NOT_FOUND );
+        AX_reg(context) = ERROR_FILE_NOT_FOUND;
         SET_CFLAG(context);
         return 0;
     }
@@ -727,7 +645,7 @@ static BOOL32 INT21_CreateTempFile( CONTEXT *context )
             TRACE(int21, "created %s\n", name );
             return TRUE;
         }
-        if (DOS_ExtendedError != ER_FileExists) return FALSE;
+        if (GetLastError() != ERROR_FILE_EXISTS) return FALSE;
     }
 }
 
@@ -739,7 +657,7 @@ static BOOL32 INT21_GetCurrentDirectory( CONTEXT *context )
 
     if (!DRIVE_IsValid(drive))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return FALSE;
     }
     lstrcpyn32A( ptr, DRIVE_GetDosCwd(drive), 64 );
@@ -770,7 +688,7 @@ static int INT21_GetDiskSerialNumber( CONTEXT *context )
 	
     if (!DRIVE_IsValid(drive))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
     
@@ -789,7 +707,7 @@ static int INT21_SetDiskSerialNumber( CONTEXT *context )
 
     if (!DRIVE_IsValid(drive))
     {
-        DOS_ERROR( ER_InvalidDrive, EC_NotFound, SA_Abort, EL_Disk );
+        SetLastError( ERROR_INVALID_DRIVE );
         return 0;
     }
 
@@ -919,7 +837,7 @@ static void fLock( CONTEXT * context )
           if (!LockFile(FILE_GetHandle32(BX_reg(context)),
                         MAKELONG(DX_reg(context),CX_reg(context)), 0,
                         MAKELONG(DI_reg(context),SI_reg(context)), 0)) {
-	    AX_reg(context) = DOS_ExtendedError;
+	    AX_reg(context) = GetLastError();
 	    SET_CFLAG(context);
 	  }
           break;
@@ -932,7 +850,7 @@ static void fLock( CONTEXT * context )
           if (!UnlockFile(FILE_GetHandle32(BX_reg(context)),
                           MAKELONG(DX_reg(context),CX_reg(context)), 0,
                           MAKELONG(DI_reg(context),SI_reg(context)), 0)) {
-	    AX_reg(context) = DOS_ExtendedError;
+	    AX_reg(context) = GetLastError();
 	    SET_CFLAG(context);
 	  }
 	  return;
@@ -954,7 +872,7 @@ INT21_networkfunc (CONTEXT *context)
 	  if (gethostname (dst, 15))
 	  {
 	       WARN(int21,"failed!\n");
-	       DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
+	       SetLastError( ER_NoNetwork );
 	       return TRUE;
 	  } else {
 	       int len = strlen (dst);
@@ -969,7 +887,7 @@ INT21_networkfunc (CONTEXT *context)
      }
 
      default:
-	  DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
+	  SetLastError( ER_NoNetwork );
 	  return TRUE;
      }
 }
@@ -1060,6 +978,120 @@ Output of DOS 6.22:
 	return seg_LOL+(WORD)&((DOS_LISTOFLISTS*)0)->ptr_first_DPB;
 }
 
+
+/***********************************************************************
+ *           INT21_GetExtendedError
+ */
+static void INT21_GetExtendedError( CONTEXT *context )
+{
+    BYTE class, action, locus;
+    WORD error = GetLastError();
+
+    switch(error)
+    {
+    case ERROR_SUCCESS:
+        class = action = locus = 0;
+        break;
+    case ERROR_DIR_NOT_EMPTY:
+        class  = EC_Exists;
+        action = SA_Ignore;
+        locus  = EL_Disk;
+        break;
+    case ERROR_ACCESS_DENIED:
+        class  = EC_AccessDenied;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_CANNOT_MAKE:
+        class  = EC_AccessDenied;
+        action = SA_Abort;
+        locus  = EL_Unknown;
+        break;
+    case ERROR_HANDLE_DISK_FULL:
+        class  = EC_MediaError;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_FILE_EXISTS:
+        class  = EC_Exists;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_FILE_NOT_FOUND:
+        class  = EC_NotFound;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ER_GeneralFailure:
+        class  = EC_SystemFailure;
+        action = SA_Abort;
+        locus  = EL_Unknown;
+        break;
+    case ERROR_INVALID_DRIVE:
+        class  = EC_MediaError;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_INVALID_HANDLE:
+        class  = EC_ProgramError;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_LOCK_VIOLATION:
+        class  = EC_AccessDenied;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_NO_MORE_FILES:
+        class  = EC_MediaError;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ER_NoNetwork:
+        class  = EC_NotFound;
+        action = SA_Abort;
+        locus  = EL_Network;
+        break;
+    case ERROR_NOT_ENOUGH_MEMORY:
+        class  = EC_OutOfResource;
+        action = SA_Abort;
+        locus  = EL_Memory;
+        break;
+    case ERROR_PATH_NOT_FOUND:
+        class  = EC_NotFound;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    case ERROR_SEEK:
+        class  = EC_NotFound;
+        action = SA_Ignore;
+        locus  = EL_Disk;
+        break;
+    case ERROR_SHARING_VIOLATION:
+        class  = EC_Temporary;
+        action = SA_Retry;
+        locus  = EL_Disk;
+        break;
+    case ERROR_TOO_MANY_OPEN_FILES:
+        class  = EC_ProgramError;
+        action = SA_Abort;
+        locus  = EL_Disk;
+        break;
+    default:
+        FIXME( int21, "Unknown error %d\n", error );
+        class  = EC_SystemFailure;
+        action = SA_Abort;
+        locus  = EL_Unknown;
+        break;
+    }
+    TRACE( int21, "GET EXTENDED ERROR code 0x%02x class 0x%02x action 0x%02x locus %02x\n",
+           error, class, action, locus );
+    AX_reg(context) = error;
+    BH_reg(context) = class;
+    BL_reg(context) = action;
+    CH_reg(context) = locus;
+}
+
 /***********************************************************************
  *           DOS3Call  (KERNEL.102)
  */
@@ -1078,12 +1110,7 @@ void WINAPI DOS3Call( CONTEXT *context )
 
     if (AH_reg(context) == 0x59)  /* Get extended error info */
     {
-        TRACE(int21, "GET EXTENDED ERROR code 0x%02x class 0x%02x action 0x%02x locus %02x\n",
-	      DOS_ExtendedError, DOS_ErrorClass, DOS_ErrorAction, DOS_ErrorLocus);
-        AX_reg(context) = DOS_ExtendedError;
-        BH_reg(context) = DOS_ErrorClass;
-        BL_reg(context) = DOS_ErrorAction;
-        CH_reg(context) = DOS_ErrorLocus;
+        INT21_GetExtendedError( context );
         return;
     }
 
@@ -1096,7 +1123,7 @@ void WINAPI DOS3Call( CONTEXT *context )
 
     if (AH_reg(context)>=0x2f) {
         /* extended error is used by (at least) functions 0x2f to 0x62 */
-        DOS_ERROR( 0, 0, 0, 0 );
+        SetLastError(0);
     }
     RESET_CFLAG(context);  /* Not sure if this is a good idea */
 
@@ -1593,8 +1620,8 @@ void WINAPI DOS3Call( CONTEXT *context )
             switch(GetDriveType16( DOS_GET_DRIVE( BL_reg(context) )))
             {
             case DRIVE_CANNOTDETERMINE:
-                DOS_ERROR( ER_InvalidDrive, EC_NotFound, SA_Abort, EL_Disk );
-                AX_reg(context) = ER_InvalidDrive;
+                SetLastError( ERROR_INVALID_DRIVE );
+                AX_reg(context) = ERROR_INVALID_DRIVE;
                 SET_CFLAG(context);
                 break;
             case DRIVE_REMOVABLE:
@@ -1612,8 +1639,8 @@ void WINAPI DOS3Call( CONTEXT *context )
             switch(GetDriveType16( DOS_GET_DRIVE( BL_reg(context) )))
             {
             case DRIVE_CANNOTDETERMINE:
-                DOS_ERROR( ER_InvalidDrive, EC_NotFound, SA_Abort, EL_Disk );
-                AX_reg(context) = ER_InvalidDrive;
+                SetLastError( ERROR_INVALID_DRIVE );
+                AX_reg(context) = ERROR_INVALID_DRIVE;
                 SET_CFLAG(context);
                 break;
             case DRIVE_REMOTE:
@@ -1802,8 +1829,8 @@ void WINAPI DOS3Call( CONTEXT *context )
         TRACE(int21,"FINDNEXT\n");
         if (!INT21_FindNext(context))
         {
-            DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
-            AX_reg(context) = ER_NoMoreFiles;
+            SetLastError( ERROR_NO_MORE_FILES );
+            AX_reg(context) = ERROR_NO_MORE_FILES;
             SET_CFLAG(context);
         }
         else AX_reg(context) = 0;  /* OK */
@@ -1908,7 +1935,7 @@ void WINAPI DOS3Call( CONTEXT *context )
     case 0x5d: /* NETWORK */
         FIXME(int21,"Function 0x%04x not implemented.\n", AX_reg (context));
 	/* Fix the following while you're at it.  */
-        DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
+        SetLastError( ER_NoNetwork );
 	bSetDOSExtendedError = TRUE;
         break;
 
@@ -1923,7 +1950,7 @@ void WINAPI DOS3Call( CONTEXT *context )
             TRACE(int21,"ENABLE DRIVE %c:\n",(DL_reg(context)+'A'));
             if (!DRIVE_Enable( DL_reg(context) ))
             {
-                DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+                SetLastError( ERROR_INVALID_DRIVE );
 		bSetDOSExtendedError = TRUE;
             }
             break;
@@ -1932,7 +1959,7 @@ void WINAPI DOS3Call( CONTEXT *context )
             TRACE(int21,"DISABLE DRIVE %c:\n",(DL_reg(context)+'A'));
             if (!DRIVE_Disable( DL_reg(context) ))
             {
-                DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+                SetLastError( ERROR_INVALID_DRIVE );
 		bSetDOSExtendedError = TRUE;
             } 
             break;
@@ -1940,7 +1967,7 @@ void WINAPI DOS3Call( CONTEXT *context )
         default:
             /* network software not installed */
             TRACE(int21,"NETWORK function AX=%04x not implemented\n",AX_reg(context));
-            DOS_ERROR( ER_NoNetwork, EC_NotFound, SA_Abort, EL_Network );
+            SetLastError( ER_NoNetwork );
 	    bSetDOSExtendedError = TRUE;
             break;
         }
@@ -2020,7 +2047,7 @@ void WINAPI DOS3Call( CONTEXT *context )
     case 0x67: /* SET HANDLE COUNT */
         TRACE(int21,"SET HANDLE COUNT to %d\n",BX_reg(context) );
         SetHandleCount16( BX_reg(context) );
-        if (DOS_ExtendedError) bSetDOSExtendedError = TRUE;
+        if (GetLastError()) bSetDOSExtendedError = TRUE;
         break;
 
     case 0x68: /* "FFLUSH" - COMMIT FILE */
@@ -2183,7 +2210,7 @@ void WINAPI DOS3Call( CONTEXT *context )
 					))
 	    ) {
 		SET_CFLAG(context);
-		AL_reg(context) = DOS_ExtendedError;
+		AL_reg(context) = GetLastError();
 	    }
 	    break;
         case 0x41:  /* Delete file */
@@ -2194,7 +2221,7 @@ void WINAPI DOS3Call( CONTEXT *context )
 					EDX_reg(context))
 	    )) {
 		SET_CFLAG(context);
-		AL_reg(context) = DOS_ExtendedError;
+		AL_reg(context) = GetLastError();
 	    }
 	    break;
         case 0x56:  /* Move (rename) file */
@@ -2232,13 +2259,12 @@ void WINAPI DOS3Call( CONTEXT *context )
 
     if( bSetDOSExtendedError )		/* set general error condition */
     {   
-	AX_reg(context) = DOS_ExtendedError;
+	AX_reg(context) = GetLastError();
 	SET_CFLAG(context);
     }
 
     if ((EFL_reg(context) & 0x0001))
-      TRACE(int21, "failed, errorcode 0x%02x class 0x%02x action 0x%02x locus %02x\n",
-	  DOS_ExtendedError, DOS_ErrorClass, DOS_ErrorAction, DOS_ErrorLocus);
+        TRACE(int21, "failed, error 0x%04lx\n", GetLastError() );
  
     TRACE(int21, "returning: AX=%04x BX=%04x CX=%04x DX=%04x "
                  "SI=%04x DI=%04x DS=%04x ES=%04x EFL=%08lx\n",