Release 970101

Wed Jan  1 15:36:17 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/listbox.c]
	Use FindFirstFile/FindNextFile in LISTBOX_Directory.

	* [files/dos_fs.c]
	Rewrote FindFirstFile/FindNextFile to use DOSFS_FindNext().

	* [files/file.c] [files/directory.c]
	Use Win32 kernel objects and handles for file handles.
	Unified SearchPath() and OpenFile().

	* [loader/builtin.c]
	Moved to if1632/ directory.

	* [tools/build.c] [debugger/*] [miscemu/*]
	Win16 register functions now receive the same CONTEXT * structure
	as Win32 functions.

	* [include/sigcontext.h] [miscemu/instr.c]
	Added new macros to get register values from the SIGCONTEXT
	structure (only used for instruction emulation now).

	* [scheduler/process.c] [scheduler/thread.c] (New files)
	Allocate process and thread structures.

	* [scheduler/process.c] [win32/k32obj.c]
	Added Win32 kernel objects and handles management.

	* [loader/task.c]
	Create a Win32 process and thread for every Win16 task.

	* [misc/commdlg.c] [misc/shell.c] [windows/msgbox.c]
	Built-in resources are now in Win32 format. This also avoids
	16-bit callbacks for built-in dialogs.

	* [misc/lzexpand.c]
	Differentiate between 16-bit and 32-bit file handles.

	* [miscemu/int*.c]
	Moved all int emulation to msdos/ directory.

	* [msdos/*]
	New directory msdos/ contains all MS-DOS emulation code that can
	also be used for Winelib; this should enable Winelib apps to use
	DOS3Call and related functions.

	* [rc/winerc.c]
	A few bug fixes for Win32 resource format.

	* [windows/winpos.c]
	Hack in WINPOS_ReorderOwnerPopups() to avoid X crashed (still not
	right though).

Sun Dec 29 17:47:55 1996  O. Flebbe <flebbe@science-computing.uni-tuebingen.de>

	* [loader/pe_image.c]
	Make sure BSS of a PE_Image is zero.

Sat Dec 28 22:15:34 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/scroll.c]
	ScrollWindowEx() rewrite, ScrollDC() fix.

	* [windows/nonclient.c] [controls/menu.c]
	Fixed Alt-Space crashes in dialogs.

	* [windows/event.c] [windows/message.c]
	Some changes in mouse message generation.

Thu Dec 26 09:25:24 1996  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [debugger/stabs.c]
	Dummy DEBUG_ReadExecutableDbgInfo provided for !__ELF__ case.

Tue Dec 24 00:59:05 MET 1996  Martin Buck <martin-2.buck@student.uni-ulm.de>

	* [windows/event.c]
	Changed XK_Page_{Up,Down} to XK_{Prior,Next} for X11R5
	compatibility.
diff --git a/files/file.c b/files/file.c
index 5f41ecf..f841b81 100644
--- a/files/file.c
+++ b/files/file.c
@@ -5,6 +5,7 @@
  * Copyright 1996 Alexandre Julliard
  */
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -19,221 +20,110 @@
 
 #include "windows.h"
 #include "winerror.h"
-#include "directory.h"
 #include "dos_fs.h"
 #include "drive.h"
+#include "file.h"
 #include "global.h"
 #include "heap.h"
 #include "msdos.h"
 #include "options.h"
 #include "ldt.h"
+#include "process.h"
 #include "task.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "xmalloc.h"
 
-#define MAX_OPEN_FILES 64  /* Max. open files for all tasks; must be <255 */
 
-typedef struct tagDOS_FILE
+typedef struct
 {
-    struct tagDOS_FILE *next;
-    int                 count;        /* Usage count (0 if free) */
-    int                 unix_handle;
-    int                 mode;
-    char               *unix_name;
-    WORD                filedate;
-    WORD                filetime;
-    DWORD               type;         /* Type for win32 apps */
+    K32OBJ    header;
+    int       unix_handle;
+    int       mode;
+    char     *unix_name;
+    DWORD     type;         /* Type for win32 apps */
 } DOS_FILE;
 
-/* Global files array */
-static DOS_FILE DOSFiles[MAX_OPEN_FILES];
-
-static DOS_FILE *FILE_First = DOSFiles;
-static DOS_FILE *FILE_LastUsed = DOSFiles;
-
-/* Small file handles array for boot-up, before the first PDB is created */
-#define MAX_BOOT_HANDLES  4
-static BYTE bootFileHandles[MAX_BOOT_HANDLES] = { 0xff, 0xff, 0xff, 0xff };
 
 /***********************************************************************
  *           FILE_Alloc
  *
- * Allocate a DOS file.
+ * Allocate a file.
  */
-static DOS_FILE *FILE_Alloc(void)
+static HFILE32 FILE_Alloc( DOS_FILE **file )
 {
-    DOS_FILE *file = FILE_First;
-    if (file) FILE_First = file->next;
-    else if (FILE_LastUsed >= &DOSFiles[MAX_OPEN_FILES-1])
+    HFILE32 handle;
+    *file = HeapAlloc( SystemHeap, 0, sizeof(DOS_FILE) );
+    if (!*file)
     {
         DOS_ERROR( ER_TooManyOpenFiles, EC_ProgramError, SA_Abort, EL_Disk );
         return NULL;
     }
-    else file = ++FILE_LastUsed;
-    file->count = 1;
-    file->unix_handle = -1;
-    file->unix_name = NULL;
-    file->type = FILE_TYPE_DISK;
-    return file;
+    (*file)->header.type = K32OBJ_FILE;
+    (*file)->header.refcount = 0;
+    (*file)->unix_handle = -1;
+    (*file)->unix_name = NULL;
+    (*file)->type = FILE_TYPE_DISK;
+
+    handle = PROCESS_AllocHandle( &(*file)->header, 0 );
+    if (handle == INVALID_HANDLE_VALUE32) *file = NULL;
+    return handle;
 }
 
 
 /***********************************************************************
- *           FILE_Close
+ *           FILE_Destroy
  *
- * Close a DOS file.
+ * Destroy a DOS file.
  */
-static BOOL FILE_Close( DOS_FILE *file )
+void FILE_Destroy( K32OBJ *ptr )
 {
-    if (!file->count) return FALSE;
-    if (--file->count > 0) return TRUE;
-    /* Now really close the file */
+    DOS_FILE *file = (DOS_FILE *)ptr;
+    assert( ptr->type == K32OBJ_FILE );
+
     if (file->unix_handle != -1) close( file->unix_handle );
-    if (file->unix_name) free( file->unix_name );
-    file->next = FILE_First;
-    FILE_First = file;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           FILE_GetPDBFiles
- *
- * Return a pointer to the current PDB files array.
- */
-static void FILE_GetPDBFiles( BYTE **files, WORD *nbFiles )
-{
-    PDB *pdb;
-
-    if ((pdb = (PDB *)GlobalLock16( GetCurrentPDB() )) != NULL)
-    {
-        *files = PTR_SEG_TO_LIN( pdb->fileHandlesPtr );
-        *nbFiles = pdb->nbFiles;
-    }
-    else
-    {
-        *files = bootFileHandles;
-        *nbFiles = MAX_BOOT_HANDLES;
-    }
-}
-
-
-/***********************************************************************
- *           FILE_AllocTaskHandle
- *
- * Allocate a task file handle for a DOS file.
- */
-static HFILE FILE_AllocTaskHandle( DOS_FILE *dos_file )
-{
-    BYTE *files, *fp;
-    WORD i, nbFiles;
-
-    FILE_GetPDBFiles( &files, &nbFiles );
-    fp = files + 1;  /* Don't use handle 0, as some programs don't like it */
-    for (i = nbFiles - 1; (i > 0) && (*fp != 0xff); i--, fp++);
-    if (!i)
-    {  /* No more handles or files */
-        DOS_ERROR( ER_TooManyOpenFiles, EC_ProgramError, SA_Abort, EL_Disk );
-        return -1;
-    }
-    *fp = dos_file ? (BYTE)(dos_file - DOSFiles) : 0;
-    dprintf_file(stddeb, 
-       "FILE_AllocTaskHandle: returning task handle %d, dos_file %d, file %d of %d \n", 
-             (fp - files), *fp, nbFiles - i, nbFiles  );
-    return (HFILE)(fp - files);
-}
-
-
-/***********************************************************************
- *           FILE_FreeTaskHandle
- *
- * Free a per-task file handle.
- */
-static void FILE_FreeTaskHandle( HFILE handle )
-{
-    BYTE *files;
-    WORD nbFiles;
-
-    FILE_GetPDBFiles( &files, &nbFiles );
-    dprintf_file( stddeb,"FILE_FreeTaskHandle: dos=%d file=%d\n",
-                  handle, files[handle] );
-    if ((handle < 0) || (handle >= (INT)nbFiles))
-    {
-        fprintf( stderr, "FILE_FreeTaskHandle: invalid file handle %d\n",
-                 handle );
-        return;
-    }
-    files[handle] = 0xff;
-}
-
-
-/***********************************************************************
- *           FILE_SetTaskHandle
- *
- * Set the value of a task handle (no error checking).
- */
-static void FILE_SetTaskHandle( HFILE handle, DOS_FILE *file )
-{
-    BYTE *files;
-    WORD nbFiles;
-
-    FILE_GetPDBFiles( &files, &nbFiles );
-    files[handle] = (BYTE)(file - DOSFiles);
+    if (file->unix_name) HeapFree( SystemHeap, 0, file->unix_name );
+    ptr->type = K32OBJ_UNKNOWN;
+    HeapFree( SystemHeap, 0, file );
 }
 
 
 /***********************************************************************
  *           FILE_GetFile
  *
- * Return the DOS file associated to a task file handle.
+ * Return the DOS file associated to a task file handle. FILE_ReleaseFile must
+ * be called to release the file.
  */
-static DOS_FILE *FILE_GetFile( HFILE handle )
+static DOS_FILE *FILE_GetFile( HFILE32 handle )
 {
-    BYTE *files;
-    WORD nbFiles;
-    DOS_FILE *file;
-
-    FILE_GetPDBFiles( &files, &nbFiles );
-    if ((handle < 0) || (handle >= (INT)nbFiles) ||
-        (files[handle] >= MAX_OPEN_FILES) ||
-        !(file = &DOSFiles[files[handle]])->count)
-    {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
-        return NULL;
-    }
-    return file;
-}
-
-
-int FILE_GetUnixHandle( HFILE hFile )
-{
-    DOS_FILE *file;
-
-    if (!(file = FILE_GetFile( hFile ))) return -1;
-    return file->unix_handle;
+    return (DOS_FILE *)PROCESS_GetObjPtr( handle, K32OBJ_FILE );
 }
 
 
 /***********************************************************************
- *           FILE_CloseAllFiles
+ *           FILE_ReleaseFile
  *
- * Close all open files of a given PDB. Used on task termination.
+ * Release a DOS file obtained with FILE_GetFile.
  */
-void FILE_CloseAllFiles( HANDLE16 hPDB )
+static void FILE_ReleaseFile( DOS_FILE *file )
 {
-    BYTE *files;
-    WORD count;
-    PDB *pdb = (PDB *)GlobalLock16( hPDB );
+    K32OBJ_DecCount( &file->header );
+}
 
-    if (!pdb) return;
-    files = PTR_SEG_TO_LIN( pdb->fileHandlesPtr );
-    dprintf_file(stddeb,"FILE_CloseAllFiles: closing %d files\n",pdb->nbFiles);
-    for (count = pdb->nbFiles; count > 0; count--, files++)
-    {
-        if (*files < MAX_OPEN_FILES) FILE_Close( &DOSFiles[*files] );
-        *files = 0xff;
-    }
+
+/***********************************************************************
+ *           FILE_GetUnixHandle
+ *
+ * Return the Unix handle associated to a file handle.
+ */
+int FILE_GetUnixHandle( HFILE32 hFile )
+{
+    DOS_FILE *file;
+    int ret;
+
+    if (!(file = FILE_GetFile( hFile ))) return -1;
+    ret = file->unix_handle;
+    FILE_ReleaseFile( file );
+    return ret;
 }
 
 
@@ -290,20 +180,20 @@
  *
  * Duplicate a Unix handle into a task handle.
  */
-HFILE FILE_DupUnixHandle( int fd )
+HFILE32 FILE_DupUnixHandle( int fd )
 {
-    HFILE handle;
+    HFILE32 handle;
     DOS_FILE *file;
 
-    if (!(file = FILE_Alloc())) return HFILE_ERROR;
-    if ((file->unix_handle = dup(fd)) == -1)
+    if ((handle = FILE_Alloc( &file )) != INVALID_HANDLE_VALUE32)
     {
-        FILE_SetDosError();
-        FILE_Close( file );
-        return HFILE_ERROR;
+        if ((file->unix_handle = dup(fd)) == -1)
+        {
+            FILE_SetDosError();
+            CloseHandle( handle );
+            return INVALID_HANDLE_VALUE32;
+        }
     }
-    if ((handle = FILE_AllocTaskHandle( file )) == HFILE_ERROR)
-        FILE_Close( file );
     return handle;
 }
 
@@ -311,12 +201,15 @@
 /***********************************************************************
  *           FILE_OpenUnixFile
  */
-static DOS_FILE *FILE_OpenUnixFile( const char *name, int mode )
+static HFILE32 FILE_OpenUnixFile( const char *name, int mode )
 {
+    HFILE32 handle;
     DOS_FILE *file;
     struct stat st;
 
-    if (!(file = FILE_Alloc())) return NULL;
+    if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32)
+        return INVALID_HANDLE_VALUE32;
+
     if ((file->unix_handle = open( name, mode, 0666 )) == -1)
     {
         if (Options.allowReadOnly && (mode == O_RDWR))
@@ -328,32 +221,29 @@
     if ((file->unix_handle == -1) || (fstat( file->unix_handle, &st ) == -1))
     {
         FILE_SetDosError();
-        FILE_Close( file );
-        return NULL;
+        CloseHandle( handle );
+        return INVALID_HANDLE_VALUE32;
     }
     if (S_ISDIR(st.st_mode))
     {
         DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
-        FILE_Close( file );
-        return NULL;
+        CloseHandle( handle );
+        return INVALID_HANDLE_VALUE32;
     }
 
     /* File opened OK, now fill the DOS_FILE */
 
-    file->unix_name = xstrdup( name );
-    DOSFS_ToDosDateTime( st.st_mtime, &file->filedate, &file->filetime );
-    return file;
+    file->unix_name = HEAP_strdupA( SystemHeap, 0, name );
+    return handle;
 }
 
 
 /***********************************************************************
  *           FILE_Open
  */
-HFILE FILE_Open( LPCSTR path, INT32 mode )
+HFILE32 FILE_Open( LPCSTR path, INT32 mode )
 {
     const char *unixName;
-    DOS_FILE *file;
-    HFILE handle;
 
     dprintf_file(stddeb, "FILE_Open: '%s' %04x\n", path, mode );
     if ((unixName = DOSFS_IsDevice( path )) != NULL)
@@ -363,25 +253,23 @@
         {
             dprintf_file(stddeb, "FILE_Open: Non-existing device\n");
             DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
-            return HFILE_ERROR;
+            return HFILE_ERROR32;
         }
     }
     else /* check for filename, don't check for last entry if creating */
         if (!(unixName = DOSFS_GetUnixFileName( path, !(mode & O_CREAT) )))
-            return HFILE_ERROR;
+            return HFILE_ERROR32;
 
-    if (!(file = FILE_OpenUnixFile( unixName, mode ))) return HFILE_ERROR;
-    if ((handle = FILE_AllocTaskHandle( file )) == HFILE_ERROR)
-        FILE_Close( file );
-    return handle;
+    return FILE_OpenUnixFile( unixName, mode );
 }
 
 
 /***********************************************************************
  *           FILE_Create
  */
-static DOS_FILE *FILE_Create( LPCSTR path, int mode, int unique )
+static HFILE32 FILE_Create( LPCSTR path, int mode, int unique )
 {
+    HFILE32 handle;
     DOS_FILE *file;
     const char *unixName;
 
@@ -391,104 +279,155 @@
     {
         dprintf_file(stddeb, "FILE_Create: creating device '%s'!\n", unixName);
         DOS_ERROR( ER_AccessDenied, EC_NotFound, SA_Abort, EL_Disk );
-        return NULL;
+        return INVALID_HANDLE_VALUE32;
     }
 
-    if (!(file = FILE_Alloc())) return NULL;
+    if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32)
+        return INVALID_HANDLE_VALUE32;
 
     if (!(unixName = DOSFS_GetUnixFileName( path, FALSE )))
     {
-        FILE_Close( file );
-        return NULL;
+        CloseHandle( handle );
+        return INVALID_HANDLE_VALUE32;
     }
     if ((file->unix_handle = open( unixName,
                            O_CREAT | O_TRUNC | O_RDWR | (unique ? O_EXCL : 0),
                            mode )) == -1)
     {
         FILE_SetDosError();
-        FILE_Close( file );
-        return NULL;
+        CloseHandle( handle );
+        return INVALID_HANDLE_VALUE32;
     } 
 
     /* File created OK, now fill the DOS_FILE */
 
-    file->unix_name = xstrdup( unixName );
-    DOSFS_ToDosDateTime( time(NULL), &file->filedate, &file->filetime );
-    return file;
+    file->unix_name = HEAP_strdupA( SystemHeap, 0, unixName );
+    return handle;
+}
+
+
+/***********************************************************************
+ *           FILE_FillInfo
+ *
+ * Fill a file information from a struct stat.
+ */
+static void FILE_FillInfo( struct stat *st, BY_HANDLE_FILE_INFORMATION *info )
+{
+    info->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
+    if (S_ISDIR(st->st_mode))
+        info->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+
+    DOSFS_UnixTimeToFileTime( st->st_mtime, &info->ftCreationTime );
+    DOSFS_UnixTimeToFileTime( st->st_mtime, &info->ftLastWriteTime );
+    DOSFS_UnixTimeToFileTime( st->st_atime, &info->ftLastAccessTime );
+
+    info->dwVolumeSerialNumber = 0;  /* FIXME */
+    info->nFileSizeHigh = 0;
+    info->nFileSizeLow  = S_ISDIR(st->st_mode) ? 0 : st->st_size;
+    info->nNumberOfLinks = st->st_nlink;
+    info->nFileIndexHigh = 0;
+    info->nFileIndexLow  = st->st_ino;
 }
 
 
 /***********************************************************************
  *           FILE_Stat
  *
- * Stat a Unix path name. Return 1 if OK.
+ * Stat a Unix path name. Return TRUE if OK.
  */
-int FILE_Stat( LPCSTR unixName, BYTE *pattr, DWORD *psize,
-               WORD *pdate, WORD *ptime )
+BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info )
 {
     struct stat st;
 
     if (stat( unixName, &st ) == -1)
     {
         FILE_SetDosError();
-        return 0;
+        return FALSE;
     }
-    if (pattr) *pattr = FA_ARCHIVE | (S_ISDIR(st.st_mode) ? FA_DIRECTORY : 0);
-    if (psize) *psize = S_ISDIR(st.st_mode) ? 0 : st.st_size;
-    DOSFS_ToDosDateTime( st.st_mtime, pdate, ptime );
-    return 1;
+    FILE_FillInfo( &st, info );
+    return TRUE;
 }
 
 
 /***********************************************************************
- *           FILE_GetDateTime
- *
- * Get the date and time of a file.
+ *             GetFileInformationByHandle   (KERNEL32.219)
  */
-int FILE_GetDateTime( HFILE hFile, WORD *pdate, WORD *ptime, BOOL32 refresh )
+DWORD GetFileInformationByHandle( HFILE32 hFile,
+                                  BY_HANDLE_FILE_INFORMATION *info )
 {
     DOS_FILE *file;
+    DWORD ret = 0;
+    struct stat st;
 
     if (!(file = FILE_GetFile( hFile ))) return 0;
-    if (refresh)
+    if (fstat( file->unix_handle, &st ) == -1) FILE_SetDosError();
+    else
     {
-        struct stat st;
-        if (fstat( file->unix_handle, &st ) == -1)
-        {
-            FILE_SetDosError();
-            return 0;
-        }
-        DOSFS_ToDosDateTime( st.st_mtime, &file->filedate, &file->filetime );
+        FILE_FillInfo( &st, info );
+        ret = 1;
     }
-    *pdate = file->filedate;
-    *ptime = file->filetime;
-    return 1;
+    FILE_ReleaseFile( file );
+    return ret;
+}
+
+
+/**************************************************************************
+ *           GetFileAttributes16   (KERNEL.420)
+ */
+DWORD GetFileAttributes16( LPCSTR name )
+{
+    return GetFileAttributes32A( name );
+}
+
+
+/**************************************************************************
+ *           GetFileAttributes32A   (KERNEL32.217)
+ */
+DWORD GetFileAttributes32A( LPCSTR name )
+{
+    BY_HANDLE_FILE_INFORMATION info;
+
+    if (!FILE_Stat( name, &info )) return -1;
+    return info.dwFileAttributes;
+}
+
+
+/**************************************************************************
+ *           GetFileAttributes32W   (KERNEL32.218)
+ */
+DWORD GetFileAttributes32W( LPCWSTR name )
+{
+    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
+    DWORD res = GetFileAttributes32A( nameA );
+    HeapFree( GetProcessHeap(), 0, nameA );
+    return res;
 }
 
 
 /***********************************************************************
- *           FILE_SetDateTime
- *
- * Set the date and time of a file.
+ *           GetFileSize   (KERNEL32.220)
  */
-int FILE_SetDateTime( HFILE hFile, WORD date, WORD time )
+DWORD GetFileSize( HFILE32 hFile, LPDWORD filesizehigh )
 {
-    DOS_FILE *file;
-    struct tm newtm;
-    struct utimbuf filetime;
+    BY_HANDLE_FILE_INFORMATION info;
+    if (!GetFileInformationByHandle( hFile, &info )) return 0;
+    if (filesizehigh) *filesizehigh = info.nFileSizeHigh;
+    return info.nFileSizeLow;
+}
 
-    if (!(file = FILE_GetFile( hFile ))) return 0;
-    newtm.tm_sec  = (time & 0x1f) * 2;
-    newtm.tm_min  = (time >> 5) & 0x3f;
-    newtm.tm_hour = (time >> 11);
-    newtm.tm_mday = (date & 0x1f);
-    newtm.tm_mon  = ((date >> 5) & 0x0f) - 1;
-    newtm.tm_year = (date >> 9) + 80;
 
-    filetime.actime = filetime.modtime = mktime( &newtm );
-    if (utime( file->unix_name, &filetime ) != -1) return 1;
-    FILE_SetDosError();
-    return 0;
+/***********************************************************************
+ *           GetFileTime   (KERNEL32.221)
+ */
+BOOL32 GetFileTime( HFILE32 hFile, FILETIME *lpCreationTime,
+                    FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime )
+{
+    BY_HANDLE_FILE_INFORMATION info;
+    if (!GetFileInformationByHandle( hFile, &info )) return FALSE;
+    if (lpCreationTime)   *lpCreationTime   = info.ftCreationTime;
+    if (lpLastAccessTime) *lpLastAccessTime = info.ftLastAccessTime;
+    if (lpLastWriteTime)  *lpLastWriteTime  = info.ftLastWriteTime;
+    return TRUE;
 }
 
 
@@ -497,14 +436,15 @@
  *
  * dup() function for DOS handles.
  */
-HFILE FILE_Dup( HFILE hFile )
+HFILE32 FILE_Dup( HFILE32 hFile )
 {
     DOS_FILE *file;
-    HFILE handle;
+    HFILE32 handle;
 
     dprintf_file( stddeb, "FILE_Dup for handle %d\n", hFile );
-    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR;
-    if ((handle = FILE_AllocTaskHandle( file )) != HFILE_ERROR) file->count++;
+    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR32;
+    handle = PROCESS_AllocHandle( &file->header, 0 );
+    FILE_ReleaseFile( file );
     dprintf_file( stddeb, "FILE_Dup return handle %d\n", handle );
     return handle;
 }
@@ -515,29 +455,14 @@
  *
  * dup2() function for DOS handles.
  */
-HFILE FILE_Dup2( HFILE hFile1, HFILE hFile2 )
+HFILE32 FILE_Dup2( HFILE32 hFile1, HFILE32 hFile2 )
 {
     DOS_FILE *file;
-    PDB *pdb = (PDB *)GlobalLock16( GetCurrentPDB() );
-    BYTE *files = PTR_SEG_TO_LIN( pdb->fileHandlesPtr );
 
     dprintf_file( stddeb, "FILE_Dup2 for handle %d\n", hFile1 );
-    if (!(file = FILE_GetFile( hFile1 ))) return HFILE_ERROR;
-
-    if ((hFile2 < 0) || (hFile2 >= (INT)pdb->nbFiles))
-    {
-        DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
-        return HFILE_ERROR;
-    }
-    if (files[hFile2] < MAX_OPEN_FILES)
-    {
-        dprintf_file( stddeb, "FILE_Dup2 closing old handle2 %d\n",
-                      files[hFile2] );
-        FILE_Close( &DOSFiles[files[hFile2]] );
-    }
-    files[hFile2] = (BYTE)(file - DOSFiles);
-    file->count++;
-    dprintf_file( stddeb, "FILE_Dup2 return handle2 %d\n", hFile2 );
+    if (!(file = FILE_GetFile( hFile1 ))) return HFILE_ERROR32;
+    if (!PROCESS_SetObjPtr( hFile2, &file->header, 0 )) hFile2 = HFILE_ERROR32;
+    FILE_ReleaseFile( file );
     return hFile2;
 }
 
@@ -599,11 +524,11 @@
 
     do
     {
-        DOS_FILE *file;
-        if ((file = FILE_Create( buffer, 0666, TRUE )) != NULL)
+        HFILE32 handle;
+        if ((handle = FILE_Create(buffer,0666,TRUE)) != INVALID_HANDLE_VALUE32)
         {  /* We created it */
             dprintf_file( stddeb, "GetTempFileName: created %s\n", buffer );
-            FILE_Close( file );
+            CloseHandle( handle );
             break;
         }
         if (DOS_ExtendedError != ER_FileExists) break;  /* No need to go on */
@@ -641,31 +566,25 @@
 
 
 /***********************************************************************
- *           OpenFile   (KERNEL.74) (KERNEL32.396)
+ *           FILE_DoOpenFile
+ *
+ * Implementation of OpenFile16() and OpenFile32().
  */
-HFILE OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode )
+static HFILE32 FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode,
+                                BOOL32 win32 )
 {
-    DOS_FILE *file;
-    HFILE hFileRet;
+    HFILE32 hFileRet;
+    FILETIME filetime;
     WORD filedatetime[2];
     const char *unixName, *dosName;
     char *p;
-    int len, i, unixMode;
+    int unixMode;
 
     ofs->cBytes = sizeof(OFSTRUCT);
     ofs->nErrCode = 0;
     if (mode & OF_REOPEN) name = ofs->szPathName;
     dprintf_file( stddeb, "OpenFile: %s %04x\n", name, mode );
 
-    /* First allocate a task handle */
-
-    if ((hFileRet = FILE_AllocTaskHandle( NULL )) == HFILE_ERROR)
-    {
-        ofs->nErrCode = DOS_ExtendedError;
-        dprintf_file( stddeb, "OpenFile: no more task handles.\n" );
-        return HFILE_ERROR;
-    }
-
     /* OF_PARSE simply fills the structure */
 
     if (mode & OF_PARSE)
@@ -673,12 +592,9 @@
         if (!(dosName = DOSFS_GetDosTrueName( name, FALSE ))) goto error;
         lstrcpyn32A( ofs->szPathName, dosName, sizeof(ofs->szPathName) );
         ofs->fFixedDisk = (GetDriveType16( dosName[0]-'A' ) != DRIVE_REMOVABLE);
-        dprintf_file( stddeb, "OpenFile(%s): OF_PARSE, res = '%s', %d\n",
-                      name, ofs->szPathName, hFileRet );
-        /* Return the handle, but close it first */
-        FILE_FreeTaskHandle( hFileRet );
-/*        return hFileRet; */
-        return 0;  /* Progman seems to like this better */
+        dprintf_file( stddeb, "OpenFile(%s): OF_PARSE, res = '%s'\n",
+                      name, ofs->szPathName );
+        return 0;
     }
 
     /* OF_CREATE is completely different from all other options, so
@@ -686,76 +602,37 @@
 
     if (mode & OF_CREATE)
     {
-        if (!(file = FILE_Create( name, 0666, FALSE ))) goto error;
+        if ((hFileRet = FILE_Create(name,0666,FALSE))== INVALID_HANDLE_VALUE32)
+            goto error;
         lstrcpyn32A( ofs->szPathName, DOSFS_GetDosTrueName( name, FALSE ),
                      sizeof(ofs->szPathName) );
         goto success;
     }
 
-    /* Now look for the file */
-
-    /* First try the current directory */
-
-    lstrcpyn32A( ofs->szPathName, name, sizeof(ofs->szPathName) );
-    if ((unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE )) != NULL)
-        goto found;
-
-    /* Now try some different paths if none was specified */
+    /* If OF_SEARCH is set, ignore the given path */
 
     if ((mode & OF_SEARCH) && !(mode & OF_REOPEN))
     {
-        if (name[1] == ':') name += 2;
+        /* First try the file name as is */
+        if ((unixName = DOSFS_GetUnixFileName( name, TRUE )) != NULL)
+        {
+            lstrcpyn32A( ofs->szPathName, name, sizeof(ofs->szPathName) );
+            goto found;
+        }
+        /* Now remove the path */
+        if (name[0] && (name[1] == ':')) name += 2;
         if ((p = strrchr( name, '\\' ))) name = p + 1;
         if ((p = strrchr( name, '/' ))) name = p + 1;
         if (!name[0]) goto not_found;
     }
-    else
-    {
-        if ((name[1] == ':') || strchr( name, '/' ) || strchr( name, '\\' ))
-            goto not_found;
-    }
 
-    if ((len = sizeof(ofs->szPathName) - strlen(name) - 1) < 0) goto not_found;
+    /* Now look for the file */
 
-    /* Try the Windows directory */
-
-    GetWindowsDirectory32A( ofs->szPathName, len );
-    strcat( ofs->szPathName, "\\" );
-    strcat( ofs->szPathName, name );
-    if ((unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE )) != NULL)
-        goto found;
-
-    /* Try the Windows system directory */
-
-    GetSystemDirectory32A( ofs->szPathName, len );
-    strcat( ofs->szPathName, "\\" );
-    strcat( ofs->szPathName, name );
-    if ((unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE )) != NULL)
-        goto found;
-
-    /* Try the path of the current executable */
-
-    if (GetCurrentTask())
-    {
-        GetModuleFileName16( GetCurrentTask(), ofs->szPathName, len );
-        if ((p = strrchr( ofs->szPathName, '\\' )))
-        {
-            strcpy( p + 1, name );
-            if ((unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE )))
-                goto found;
-        }
-    }
-
-    /* Try all directories in path */
-
-    for (i = 0; ; i++)
-    {
-        if (!DIR_GetDosPath( i, ofs->szPathName, len )) goto not_found;
-        strcat( ofs->szPathName, "\\" );
-        strcat( ofs->szPathName, name );
-        if ((unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE)) != NULL)
-            break;
-    }
+    if (!DIR_SearchPath( NULL, name, NULL, sizeof(ofs->szPathName),
+                         ofs->szPathName, NULL, win32 ))
+        goto not_found;
+    if (!(unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE )))
+        goto not_found;
 
 found:
     dprintf_file( stddeb, "OpenFile: found '%s'\n", unixName );
@@ -766,9 +643,7 @@
     {
         if (unlink( unixName ) == -1) goto not_found;
         dprintf_file( stddeb, "OpenFile(%s): OF_DELETE return = OK\n", name);
-        /* Return the handle, but close it first */
-        FILE_FreeTaskHandle( hFileRet );
-        return hFileRet;
+        return 1;
     }
 
     switch(mode & 3)
@@ -782,14 +657,15 @@
         unixMode = O_RDONLY; break;
     }
 
-    if (!(file = FILE_OpenUnixFile( unixName, unixMode ))) goto not_found;
-    filedatetime[0] = file->filedate;
-    filedatetime[1] = file->filetime;
+    if ((hFileRet = FILE_OpenUnixFile( unixName, unixMode )) == HFILE_ERROR32)
+        goto not_found;
+    GetFileTime( hFileRet, NULL, NULL, &filetime );
+    FileTimeToDosDateTime( &filetime, &filedatetime[0], &filedatetime[1] );
     if ((mode & OF_VERIFY) && (mode & OF_REOPEN))
     {
         if (memcmp( ofs->reserved, filedatetime, sizeof(ofs->reserved) ))
         {
-            FILE_Close( file );
+            CloseHandle( hFileRet );
             dprintf_file( stddeb, "OpenFile(%s): OF_VERIFY failed\n", name );
             /* FIXME: what error here? */
             DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
@@ -798,17 +674,10 @@
     }
     memcpy( ofs->reserved, filedatetime, sizeof(ofs->reserved) );
 
-    if (mode & OF_EXIST)
-    {
-        FILE_Close( file );
-        /* Return the handle, but close it first */
-        FILE_FreeTaskHandle( hFileRet );
-        return hFileRet;
-    }
-
 success:  /* We get here if the open was successful */
     dprintf_file( stddeb, "OpenFile(%s): OK, return = %d\n", name, hFileRet );
-    FILE_SetTaskHandle( hFileRet, file );
+    if (mode & OF_EXIST) /* Return the handle, but close it first */
+        CloseHandle( hFileRet );
     return hFileRet;
 
 not_found:  /* We get here if the file does not exist */
@@ -819,151 +688,52 @@
 error:  /* We get here if there was an error opening the file */
     ofs->nErrCode = DOS_ExtendedError;
     dprintf_file( stddeb, "OpenFile(%s): return = HFILE_ERROR\n", name );
-    FILE_FreeTaskHandle( hFileRet );
-    return HFILE_ERROR;
+    return HFILE_ERROR32;
 }
 
-/***********************************************************************
- *           SearchPath32A   (KERNEL32.447)
- * Code borrowed from OpenFile above.
- */
-DWORD SearchPath32A(
-	LPCSTR path,LPCSTR fn,LPCSTR ext,DWORD buflen,LPSTR buf,LPSTR *lastpart
-) {
-    LPCSTR	unixName;
-    INT32	len;
-    char	testpath[1000]; /* should be enough for now */
-    char	*name,*p;
-    int		i;
-
-    if (ext==NULL)
-    	ext = "";
-    name=(char*)xmalloc(strlen(fn)+strlen(ext)+1);
-    strcpy(name,fn);
-    strcat(name,ext);
-
-    dprintf_file(stddeb,"SearchPath32A(%s,%s,%s,%ld,%p,%p)\n",
-    	path,fn,ext,buflen,buf,lastpart
-    );
-    if (path) {
-	strcpy(testpath,path);
-	strcat(testpath,"\\");
-	strcat(testpath,name);
-	if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL) {
-	    goto found;
-	} else {
-	    strcpy(testpath,name);
-	    if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
-		goto found;
-	    return 0;
-	}
-    }
-    if ((len=sizeof(testpath)-strlen(name)-1)<0)
-    	return 0;
-
-    /* Try the path of the current executable */
-    if (GetCurrentTask()) {
-	GetModuleFileName16(GetCurrentTask(),testpath,len);
-	if ((p=strrchr(testpath,'\\'))) {
-            strcpy(p+1,name);
-            if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE)))
-                goto found;
-        }
-    }
-
-    /* Try the current directory */
-    lstrcpyn32A(testpath,name,sizeof(testpath) );
-    if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
-        goto found;
-
-    /* Try the Windows directory */
-    GetWindowsDirectory32A(testpath,len);
-    strcat(testpath,"\\");
-    strcat(testpath,name);
-    if ((unixName = DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
-        goto found;
-
-    /* Try the Windows system directory */
-    GetSystemDirectory32A(testpath,len);
-    strcat(testpath,"\\");
-    strcat(testpath,name);
-    if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
-        goto found;
-
-    /* Try all directories in path */
-
-    for (i=0;;i++)
-    {
-        if (!DIR_GetDosPath(i,testpath,len)) 
-		return 0;
-        strcat(testpath,"\\");
-        strcat(testpath,name);
-        if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
-            break;
-    }
-
-found:
-    strncpy(buf,testpath,buflen);
-    if (NULL!=(p=strrchr(testpath,'\\')))
-    	p=p+1;
-    else
-        p=testpath;
-    if (lastpart) {
-	if (p-testpath<buflen)
-	    *lastpart=(p-testpath)+buf;
-	else
-	    *lastpart=NULL;
-    }
-    dprintf_file(stddeb,"	-> found %s,last part is %s\n",testpath,p);
-    return strlen(testpath);
-}
 
 /***********************************************************************
- *           SearchPath32W   (KERNEL32.448)
+ *           OpenFile16   (KERNEL.74)
  */
-DWORD SearchPath32W( LPCWSTR path, LPCWSTR fn, LPCWSTR ext, DWORD buflen,
-                     LPWSTR buf, LPWSTR *lastpart )
+HFILE16 OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode )
 {
-	LPSTR	pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
-	LPSTR	fnA = HEAP_strdupWtoA( GetProcessHeap(), 0, fn );
-	LPSTR	extA = HEAP_strdupWtoA( GetProcessHeap(), 0, ext );
-	LPSTR	lastpartA;
-	LPSTR	bufA = HeapAlloc( GetProcessHeap(), 0, buflen + 1 );
-	DWORD	ret;
-
-	ret = SearchPath32A(pathA,fnA,extA,buflen,bufA,&lastpartA);
-	lstrcpyAtoW( buf, bufA );
-	if (lastpart)
-        {
-            if (lastpartA) *lastpart = buf+(lastpartA-bufA);
-            else *lastpart = NULL;
-	}
-	HeapFree( GetProcessHeap(), 0, bufA );
-	HeapFree( GetProcessHeap(), 0, fnA );
-	HeapFree( GetProcessHeap(), 0, pathA );
-	HeapFree( GetProcessHeap(), 0, extA );
-	return ret;
+    return FILE_DoOpenFile( name, ofs, mode, FALSE );
 }
 
-/***********************************************************************
- *           _lclose   (KERNEL.81) (KERNEL32.592)
- */
-HFILE _lclose( HFILE hFile )
-{
-    DOS_FILE *file;
 
+/***********************************************************************
+ *           OpenFile32   (KERNEL32.396)
+ */
+HFILE32 OpenFile32( LPCSTR name, OFSTRUCT *ofs, UINT32 mode )
+{
+    return FILE_DoOpenFile( name, ofs, mode, TRUE );
+}
+
+
+/***********************************************************************
+ *           _lclose16   (KERNEL.81)
+ */
+HFILE16 _lclose16( HFILE16 hFile )
+{
     dprintf_file( stddeb, "_lclose: handle %d\n", hFile );
-    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR;
-    FILE_Close( file );
-    FILE_FreeTaskHandle( hFile );
-    return 0;
+    return CloseHandle( hFile ) ? 0 : HFILE_ERROR16;
+}
+
+
+/***********************************************************************
+ *           _lclose32   (KERNEL32.592)
+ */
+HFILE32 _lclose32( HFILE32 hFile )
+{
+    dprintf_file( stddeb, "_lclose: handle %d\n", hFile );
+    return CloseHandle( hFile ) ? 0 : HFILE_ERROR32;
 }
 
 
 /***********************************************************************
  *           WIN16_hread
  */
-LONG WIN16_hread( HFILE hFile, SEGPTR buffer, LONG count )
+LONG WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count )
 {
     LONG maxlen;
 
@@ -980,7 +750,7 @@
 /***********************************************************************
  *           WIN16_lread
  */
-UINT16 WIN16_lread( HFILE hFile, SEGPTR buffer, UINT16 count )
+UINT16 WIN16_lread( HFILE16 hFile, SEGPTR buffer, UINT16 count )
 {
     return (UINT16)WIN16_hread( hFile, buffer, (LONG)count );
 }
@@ -989,16 +759,17 @@
 /***********************************************************************
  *           _lread32   (KERNEL32.596)
  */
-UINT32 _lread32( HFILE hFile, LPVOID buffer, UINT32 count )
+UINT32 _lread32( HFILE32 hFile, LPVOID buffer, UINT32 count )
 {
     DOS_FILE *file;
     UINT32 result;
 
     dprintf_file( stddeb, "_lread32: %d %p %d\n", hFile, buffer, count );
     if (!(file = FILE_GetFile( hFile ))) return -1;
-    if (!count) return 0;
-    if ((result = read( file->unix_handle, buffer, count )) == -1)
+    if (!count) result = 0;
+    else if ((result = read( file->unix_handle, buffer, count )) == -1)
         FILE_SetDosError();
+    FILE_ReleaseFile( file );
     return result;
 }
 
@@ -1006,52 +777,58 @@
 /***********************************************************************
  *           _lread16   (KERNEL.82)
  */
-UINT16 _lread16( HFILE hFile, LPVOID buffer, UINT16 count )
+UINT16 _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
 {
     return (UINT16)_lread32( hFile, buffer, (LONG)count );
 }
 
 
 /***********************************************************************
- *           _lcreat   (KERNEL.83) (KERNEL32.593)
+ *           _lcreat16   (KERNEL.83)
  */
-HFILE _lcreat( LPCSTR path, INT32 attr )
+HFILE16 _lcreat16( LPCSTR path, INT16 attr )
 {
-    DOS_FILE *file;
-    HFILE handle;
-    int mode;
-    
-    dprintf_file( stddeb, "_lcreat: %s %02x\n", path, attr );
-    mode = (attr & 1) ? 0444 : 0666;
-    if (!(file = FILE_Create( path, mode, FALSE ))) return HFILE_ERROR;
-    if ((handle = FILE_AllocTaskHandle( file )) == HFILE_ERROR)
-        FILE_Close( file );
-    return handle;
+    int mode = (attr & 1) ? 0444 : 0666;
+    dprintf_file( stddeb, "_lcreat16: %s %02x\n", path, attr );
+    return (HFILE16)FILE_Create( path, mode, FALSE );
+}
+
+
+/***********************************************************************
+ *           _lcreat32   (KERNEL32.593)
+ */
+HFILE32 _lcreat32( LPCSTR path, INT32 attr )
+{
+    int mode = (attr & 1) ? 0444 : 0666;
+    dprintf_file( stddeb, "_lcreat32: %s %02x\n", path, attr );
+    return FILE_Create( path, mode, FALSE );
 }
 
 
 /***********************************************************************
  *           _lcreat_uniq   (Not a Windows API)
  */
-HFILE _lcreat_uniq( LPCSTR path, INT32 attr )
+HFILE32 _lcreat_uniq( LPCSTR path, INT32 attr )
 {
-    DOS_FILE *file;
-    HFILE handle;
-    int mode;
-    
+    int mode = (attr & 1) ? 0444 : 0666;
     dprintf_file( stddeb, "_lcreat: %s %02x\n", path, attr );
-    mode = (attr & 1) ? 0444 : 0666;
-    if (!(file = FILE_Create( path, mode, TRUE ))) return HFILE_ERROR;
-    if ((handle = FILE_AllocTaskHandle( file )) == HFILE_ERROR)
-        FILE_Close( file );
-    return handle;
+    return FILE_Create( path, mode, TRUE );
 }
 
 
 /***********************************************************************
- *           _llseek   (KERNEL.84) (KERNEL32.594)
+ *           _llseek16   (KERNEL.84)
  */
-LONG _llseek( HFILE hFile, LONG lOffset, INT32 nOrigin )
+LONG _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
+{
+    return _llseek32( hFile, lOffset, nOrigin );
+}
+
+
+/***********************************************************************
+ *           _llseek32   (KERNEL32.594)
+ */
+LONG _llseek32( HFILE32 hFile, LONG lOffset, INT32 nOrigin )
 {
     DOS_FILE *file;
     int origin, result;
@@ -1059,7 +836,7 @@
     dprintf_file( stddeb, "_llseek: handle %d, offset %ld, origin %d\n", 
                   hFile, lOffset, nOrigin);
 
-    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR;
+    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR32;
     switch(nOrigin)
     {
         case 1:  origin = SEEK_CUR; break;
@@ -1069,14 +846,24 @@
 
     if ((result = lseek( file->unix_handle, lOffset, origin )) == -1)
         FILE_SetDosError();
+    FILE_ReleaseFile( file );
     return result;
 }
 
 
 /***********************************************************************
- *           _lopen   (KERNEL.85) (KERNEL32.595)
+ *           _lopen16   (KERNEL.85)
  */
-HFILE _lopen( LPCSTR path, INT32 mode )
+HFILE16 _lopen16( LPCSTR path, INT16 mode )
+{
+    return _lopen32( path, mode );
+}
+
+
+/***********************************************************************
+ *           _lopen32   (KERNEL32.595)
+ */
+HFILE32 _lopen32( LPCSTR path, INT32 mode )
 {
     INT32 unixMode;
 
@@ -1102,41 +889,58 @@
 /***********************************************************************
  *           _lwrite16   (KERNEL.86)
  */
-UINT16 _lwrite16( HFILE hFile, LPCSTR buffer, UINT16 count )
+UINT16 _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
 {
-    return (UINT16)_hwrite( hFile, buffer, (LONG)count );
+    return (UINT16)_hwrite32( hFile, buffer, (LONG)count );
 }
 
 /***********************************************************************
  *           _lwrite32   (KERNEL.86)
  */
-UINT32 _lwrite32( HFILE hFile, LPCSTR buffer, UINT32 count )
+UINT32 _lwrite32( HFILE32 hFile, LPCSTR buffer, UINT32 count )
 {
-    return (UINT32)_hwrite( hFile, buffer, (LONG)count );
+    return (UINT32)_hwrite32( hFile, buffer, (LONG)count );
 }
 
 
 /***********************************************************************
- *           _hread   (KERNEL.349)
+ *           _hread16   (KERNEL.349)
  */
-LONG _hread( HFILE hFile, LPVOID buffer, LONG count)
+LONG _hread16( HFILE16 hFile, LPVOID buffer, LONG count)
 {
     return _lread32( hFile, buffer, count );
 }
 
 
 /***********************************************************************
- *           _hwrite   (KERNEL.350)
+ *           _hread32   (KERNEL32.590)
  */
-LONG _hwrite( HFILE hFile, LPCSTR buffer, LONG count )
+LONG _hread32( HFILE32 hFile, LPVOID buffer, LONG count)
+{
+    return _lread32( hFile, buffer, count );
+}
+
+
+/***********************************************************************
+ *           _hwrite16   (KERNEL.350)
+ */
+LONG _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
+{
+    return _hwrite32( hFile, buffer, count );
+}
+
+
+/***********************************************************************
+ *           _hwrite32   (KERNEL32.591)
+ */
+LONG _hwrite32( HFILE32 hFile, LPCSTR buffer, LONG count )
 {
     DOS_FILE *file;
     LONG result;
 
     dprintf_file( stddeb, "_hwrite: %d %p %ld\n", hFile, buffer, count );
 
-    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR;
-    
+    if (!(file = FILE_GetFile( hFile ))) return HFILE_ERROR32;
     if (count == 0)  /* Expand or truncate at current position */
         result = ftruncate( file->unix_handle,
                             lseek( file->unix_handle, 0, SEEK_CUR ) );
@@ -1144,6 +948,7 @@
         result = write( file->unix_handle, buffer, count );
 
     if (result == -1) FILE_SetDosError();
+    FILE_ReleaseFile( file );
     return result;
 }
 
@@ -1225,18 +1030,54 @@
 }
 
 
+/*************************************************************************
+ *           SetHandleCount32   (KERNEL32.494)
+ */
+UINT32 SetHandleCount32( UINT32 count )
+{
+    return MIN( 256, count );
+}
+
+
 /***********************************************************************
  *           FlushFileBuffers   (KERNEL32.133)
  */
-BOOL32 FlushFileBuffers( HFILE hFile )
+BOOL32 FlushFileBuffers( HFILE32 hFile )
 {
     DOS_FILE *file;
+    BOOL32 ret;
 
     dprintf_file( stddeb, "FlushFileBuffers(%d)\n", hFile );
     if (!(file = FILE_GetFile( hFile ))) return FALSE;
-    if (fsync( file->unix_handle ) != -1) return TRUE;
-    FILE_SetDosError();
-    return FALSE;
+    if (fsync( file->unix_handle ) != -1) ret = TRUE;
+    else
+    {
+        FILE_SetDosError();
+        ret = FALSE;
+    }
+    FILE_ReleaseFile( file );
+    return ret;
+}
+
+
+/**************************************************************************
+ *           SetEndOfFile   (KERNEL32.483)
+ */
+BOOL32 SetEndOfFile( HFILE32 hFile )
+{
+    DOS_FILE *file;
+    BOOL32 ret = TRUE;
+
+    dprintf_file( stddeb, "SetEndOfFile(%d)\n", hFile );
+    if (!(file = FILE_GetFile( hFile ))) return FALSE;
+    if (ftruncate( file->unix_handle,
+                   lseek( file->unix_handle, 0, SEEK_CUR ) ))
+    {
+        FILE_SetDosError();
+        ret = FALSE;
+    }
+    FILE_ReleaseFile( file );
+    return ret;
 }
 
 
@@ -1288,122 +1129,14 @@
 
 
 /***********************************************************************
- *           CreateDirectory16   (KERNEL.144)
- */
-BOOL16 CreateDirectory16( LPCSTR path, LPVOID dummy )
-{
-    dprintf_file( stddeb,"CreateDirectory16(%s,%p)\n", path, dummy );
-    return (BOOL16)CreateDirectory32A( path, NULL );
-}
-
-
-/***********************************************************************
- *           CreateDirectory32A   (KERNEL32.39)
- */
-BOOL32 CreateDirectory32A( LPCSTR path, LPSECURITY_ATTRIBUTES lpsecattribs )
-{
-    const char *unixName;
-
-    dprintf_file( stddeb, "CreateDirectory32A(%s,%p)\n", path, lpsecattribs );
-    if ((unixName = DOSFS_IsDevice( path )) != NULL)
-    {
-        dprintf_file(stddeb, "CreateDirectory: device '%s'!\n", unixName);
-        DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
-        return FALSE;
-    }
-    if (!(unixName = DOSFS_GetUnixFileName( path, FALSE ))) return 0;
-    if ((mkdir( unixName, 0777 ) == -1) && (errno != EEXIST))
-    {
-        FILE_SetDosError();
-        return FALSE;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           CreateDirectory32W   (KERNEL32.42)
- */
-BOOL32 CreateDirectory32W( LPCWSTR path, LPSECURITY_ATTRIBUTES lpsecattribs )
-{
-    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
-    BOOL32 ret = CreateDirectory32A( xpath, lpsecattribs );
-    HeapFree( GetProcessHeap(), 0, xpath );
-    return ret;
-}
-
-/***********************************************************************
- *           CreateDirectoryEx32A   (KERNEL32.40)
- */
-BOOL32 CreateDirectoryEx32A( LPCSTR template, LPCSTR path,
-                             LPSECURITY_ATTRIBUTES lpsecattribs)
-{
-    return CreateDirectory32A(path,lpsecattribs);
-}
-
-/***********************************************************************
- *           CreateDirectoryEx32W   (KERNEL32.41)
- */
-BOOL32 CreateDirectoryEx32W( LPCWSTR template, LPCWSTR path,
-                             LPSECURITY_ATTRIBUTES lpsecattribs)
-{
-    return CreateDirectory32W(path,lpsecattribs);
-}
-
-/***********************************************************************
- *           RemoveDirectory16   (KERNEL)
- */
-BOOL16 RemoveDirectory16( LPCSTR path )
-{
-    return (BOOL16)RemoveDirectory32A( path );
-}
-
-
-/***********************************************************************
- *           RemoveDirectory32A   (KERNEL32.437)
- */
-BOOL32 RemoveDirectory32A( LPCSTR path )
-{
-    const char *unixName;
-
-    dprintf_file(stddeb, "RemoveDirectory: '%s'\n", path );
-
-    if ((unixName = DOSFS_IsDevice( path )) != NULL)
-    {
-        dprintf_file(stddeb, "RemoveDirectory: device '%s'!\n", unixName);
-        DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
-        return FALSE;
-    }
-    if (!(unixName = DOSFS_GetUnixFileName( path, TRUE ))) return FALSE;
-    if (rmdir( unixName ) == -1)
-    {
-        FILE_SetDosError();
-        return FALSE;
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           RemoveDirectory32W   (KERNEL32.438)
- */
-BOOL32 RemoveDirectory32W( LPCWSTR path )
-{
-    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
-    BOOL32 ret = RemoveDirectory32A( xpath );
-    HeapFree( GetProcessHeap(), 0, xpath );
-    return ret;
-}
-
-
-/***********************************************************************
  *           FILE_SetFileType
  */
-BOOL32 FILE_SetFileType( HFILE hFile, DWORD type )
+BOOL32 FILE_SetFileType( HFILE32 hFile, DWORD type )
 {
-    DOS_FILE *file = FILE_GetFile(hFile);
+    DOS_FILE *file = FILE_GetFile( hFile );
     if (!file) return FALSE;
     file->type = type;
+    FILE_ReleaseFile( file );
     return TRUE;
 }
 
@@ -1411,65 +1144,27 @@
 /***********************************************************************
  *           GetFileType   (KERNEL32.222)
  */
-DWORD GetFileType( HFILE hFile )
+DWORD GetFileType( HFILE32 hFile )
 {
     DOS_FILE *file = FILE_GetFile(hFile);
-    
-    if (!file)
-    {
-    	SetLastError( ERROR_INVALID_HANDLE );
-    	return FILE_TYPE_UNKNOWN; /* FIXME: correct? */
-    }
+    if (!file) return FILE_TYPE_UNKNOWN; /* FIXME: correct? */
+    FILE_ReleaseFile( file );
     return file->type;
 }
 
 
 /***********************************************************************
- *              GetFileTime   (KERNEL32.221)
- */
-BOOL32 GetFileTime( HFILE hFile, FILETIME *lpCreationTime,
-                    FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime )
-{
-    DOS_FILE *file = FILE_GetFile(hFile);
-    struct stat stbuf;
-    
-    if (!file) {
-    	SetLastError( ERROR_INVALID_HANDLE );
-	return FILE_TYPE_UNKNOWN; /* FIXME: correct? */
-    }
-    dprintf_file(stddeb,"SetFileTime(%s,%p,%p,%p)\n",
-	file->unix_name,
-	lpCreationTime,
-	lpLastAccessTime,
-	lpLastWriteTime
-    );
-    if (-1==fstat(file->unix_handle,&stbuf)) {
-	FILE_SetDosError();
-	return FALSE;
-    }
-    if (lpLastWriteTime)
-    	DOSFS_UnixTimeToFileTime(stbuf.st_mtime,lpLastWriteTime);
-    if (lpCreationTime)
-	DOSFS_UnixTimeToFileTime(stbuf.st_ctime,lpCreationTime);
-    if (lpLastAccessTime)
-    	DOSFS_UnixTimeToFileTime(stbuf.st_atime,lpLastAccessTime);
-    return TRUE;
-}
-
-
-/***********************************************************************
  *              SetFileTime   (KERNEL32.493)
  */
-BOOL32 SetFileTime( HFILE hFile, FILETIME *lpCreationTime,
-                    FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime )
+BOOL32 SetFileTime( HFILE32 hFile,
+                    const FILETIME *lpCreationTime,
+                    const FILETIME *lpLastAccessTime,
+                    const FILETIME *lpLastWriteTime )
 {
     DOS_FILE *file = FILE_GetFile(hFile);
     struct utimbuf utimbuf;
     
-    if (!file) {
-    	SetLastError( ERROR_INVALID_HANDLE );
-    	return FILE_TYPE_UNKNOWN; /* FIXME: correct? */
-    }
+    if (!file) return FILE_TYPE_UNKNOWN; /* FIXME: correct? */
     dprintf_file(stddeb,"SetFileTime(%s,%p,%p,%p)\n",
 	file->unix_name,
 	lpCreationTime,
@@ -1484,9 +1179,12 @@
 	utimbuf.modtime	= DOSFS_FileTimeToUnixTime(lpLastWriteTime);
     else
 	utimbuf.modtime	= 0; /* FIXME */
-    if (-1==utime(file->unix_name,&utimbuf)) {
+    if (-1==utime(file->unix_name,&utimbuf))
+    {
+        FILE_ReleaseFile( file );
 	FILE_SetDosError();
 	return FALSE;
     }
+    FILE_ReleaseFile( file );
     return TRUE;
 }