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/dos_fs.c b/files/dos_fs.c
index 6ce5881..fb3c0e7 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -8,16 +8,20 @@
#include <sys/types.h>
#include <ctype.h>
#include <dirent.h>
+#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <time.h>
+#include <unistd.h>
#if defined(__svr4__) || defined(_SCO_DS)
#include <sys/statfs.h>
#endif
#include "windows.h"
+#include "winerror.h"
#include "dos_fs.h"
#include "drive.h"
#include "file.h"
@@ -25,7 +29,15 @@
#include "msdos.h"
#include "stddebug.h"
#include "debug.h"
-#include "xmalloc.h"
+
+/* Define the VFAT ioctl to get both short and long file names */
+#if 0 /* not working yet */
+#ifdef linux
+#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, long)
+#else /* linux */
+#undef VFAT_IOCTL_READDIR_BOTH /* just in case... */
+#endif /* linux */
+#endif
/* Chars we don't want to see in DOS file names */
#define INVALID_DOS_CHARS "*?<>|\"+=,;[] \345"
@@ -55,6 +67,27 @@
BYTE DOS_ErrorAction;
BYTE DOS_ErrorLocus;
+/* Info structure for FindFirstFile handle */
+typedef struct
+{
+ LPSTR path;
+ LPSTR mask;
+ int drive;
+ int skip;
+} FIND_FIRST_INFO;
+
+
+/* Directory info for DOSFS_ReadDir */
+typedef struct
+{
+ DIR *dir;
+#ifdef VFAT_IOCTL_READDIR_BOTH
+ int fd;
+ char short_name[12];
+ struct dirent dirent[2];
+#endif
+} DOS_DIR;
+
/***********************************************************************
* DOSFS_ValidDOSName
@@ -150,7 +183,11 @@
{
p++;
strcpy( buffer, ". " );
- if (*p == '.') p++;
+ if (*p == '.')
+ {
+ buffer[1] = '.';
+ p++;
+ }
return (!*p || (*p == '/') || (*p == '\\')) ? buffer : NULL;
}
@@ -265,6 +302,7 @@
static int DOSFS_MatchLong( const char *mask, const char *name,
int case_sensitive )
{
+ if (!strcmp( mask, "*.*" )) return 1;
while (*name && *mask)
{
if (*mask == '*')
@@ -292,6 +330,95 @@
/***********************************************************************
+ * DOSFS_OpenDir
+ */
+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 );
+ return NULL;
+ }
+
+#ifdef VFAT_IOCTL_READDIR_BOTH
+
+ /* Check if the VFAT ioctl is supported on this directory */
+
+ if ((dir->fd = open( path, O_RDONLY )) != -1)
+ {
+ if (ioctl( dir->fd, VFAT_IOCTL_READDIR_BOTH, (long)dir->dirent ) == -1)
+ {
+ close( dir->fd );
+ dir->fd = -1;
+ }
+ else
+ {
+ /* Set the file pointer back at the start of the directory */
+ lseek( dir->fd, 0, SEEK_SET );
+ dir->dir = NULL;
+ return dir;
+ }
+ }
+#endif /* VFAT_IOCTL_READDIR_BOTH */
+
+ /* Now use the standard opendir/readdir interface */
+
+ if (!(dir->dir = opendir( path )))
+ {
+ HeapFree( SystemHeap, 0, dir );
+ return NULL;
+ }
+ return dir;
+}
+
+
+/***********************************************************************
+ * DOSFS_CloseDir
+ */
+static void DOSFS_CloseDir( DOS_DIR *dir )
+{
+#ifdef VFAT_IOCTL_READDIR_BOTH
+ if (dir->fd != -1) close( dir->fd );
+#endif /* VFAT_IOCTL_READDIR_BOTH */
+ if (dir->dir) closedir( dir->dir );
+ HeapFree( SystemHeap, 0, dir );
+}
+
+
+/***********************************************************************
+ * DOSFS_ReadDir
+ */
+static BOOL32 DOSFS_ReadDir( DOS_DIR *dir, LPCSTR *long_name,
+ LPCSTR *short_name )
+{
+ struct dirent *dirent;
+
+#ifdef VFAT_IOCTL_READDIR_BOTH
+ if (dir->fd != -1)
+ {
+ LPCSTR fcb_name;
+ if (ioctl( dir->fd, VFAT_IOCTL_READDIR_BOTH, (long)dir->dirent ) == -1)
+ return FALSE;
+ if (!dir->dirent[0].d_reclen) return FALSE;
+ fcb_name = DOSFS_ToDosFCBFormat( dir->dirent[0].d_name );
+ if (fcb_name) strcpy( dir->short_name, fcb_name );
+ else dir->short_name[0] = '\0';
+ *short_name = dir->short_name;
+ if (dir->dirent[1].d_name[0]) *long_name = dir->dirent[1].d_name;
+ else *long_name = dir->dirent[0].d_name;
+ return TRUE;
+ }
+#endif /* VFAT_IOCTL_READDIR_BOTH */
+
+ if (!(dirent = readdir( dir->dir ))) return FALSE;
+ *long_name = dirent->d_name;
+ *short_name = NULL;
+ return TRUE;
+}
+
+
+/***********************************************************************
* DOSFS_ToDosDateTime
*
* Convert a Unix time in the DOS date/time format.
@@ -344,7 +471,7 @@
*
* Convert a FILETIME format to Unix time.
*/
-time_t DOSFS_FileTimeToUnixTime( FILETIME *filetime )
+time_t DOSFS_FileTimeToUnixTime( const FILETIME *filetime )
{
/* FIXME :-) */
return filetime->dwLowDateTime;
@@ -359,7 +486,8 @@
* hashed version that fits in 8.3 format.
* File name can be terminated by '\0', '\\' or '/'.
*/
-const char *DOSFS_Hash( const char *name, int dir_format, int ignore_case )
+static const char *DOSFS_Hash( const char *name, int dir_format,
+ int ignore_case )
{
static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
static const char hash_chars[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
@@ -439,7 +567,7 @@
{
if (!dir_format) *dst++ = '.';
for (i = 3, ext++; (i > 0) && !IS_END_OF_NAME(*ext); i--, ext++)
- *dst++ = toupper(*ext);
+ *dst++ = strchr( invalid_chars, *ext ) ? '_' : toupper(*ext);
}
if (!dir_format) *dst = '\0';
}
@@ -455,53 +583,59 @@
* File name can be terminated by '\0', '\\' or '/'.
* Return 1 if OK, 0 if no file name matches.
*/
-static int DOSFS_FindUnixName( const char *path, const char *name,
- char *buffer, int maxlen, UINT32 drive_flags )
+BOOL32 DOSFS_FindUnixName( const char *path, const char *name,
+ char *buffer, int maxlen, UINT32 drive_flags )
{
- DIR *dir;
- struct dirent *dirent;
+ DOS_DIR *dir;
+ LPCSTR long_name, short_name;
+ char dos_name[12];
+ BOOL32 ret;
- const char *dos_name = DOSFS_ToDosFCBFormat( name );
const char *p = strchr( name, '/' );
int len = p ? (int)(p - name) : strlen(name);
- dprintf_dosfs( stddeb, "DOSFS_FindUnixName: %s %s\n", path, name );
+ dprintf_dosfs( stddeb, "DOSFS_FindUnixName: %s,%s\n", path, name );
if ((p = strchr( name, '\\' ))) len = MIN( (int)(p - name), len );
- if (!(dir = opendir( path )))
+ dos_name[0] = '\0';
+ if ((p = DOSFS_ToDosFCBFormat( name ))) strcpy( dos_name, p );
+
+ if (!(dir = DOSFS_OpenDir( path )))
{
dprintf_dosfs( stddeb, "DOSFS_FindUnixName(%s,%s): can't open dir\n",
path, name );
return 0;
}
- while ((dirent = readdir( dir )) != NULL)
+
+ while ((ret = DOSFS_ReadDir( dir, &long_name, &short_name )))
{
/* Check against Unix name */
- if (len == strlen(dirent->d_name))
+ if (len == strlen(long_name))
{
if (drive_flags & DRIVE_CASE_SENSITIVE)
{
- if (!lstrncmp32A( dirent->d_name, name, len )) break;
+ if (!lstrncmp32A( long_name, name, len )) break;
}
else
{
- if (!lstrncmpi32A( dirent->d_name, name, len )) break;
+ if (!lstrncmpi32A( long_name, name, len )) break;
}
}
- if (dos_name)
+ if (dos_name[0])
{
/* Check against hashed DOS name */
- const char *hash_name = DOSFS_Hash( dirent->d_name, TRUE,
+ if (!short_name)
+ short_name = DOSFS_Hash( long_name, TRUE,
!(drive_flags & DRIVE_CASE_SENSITIVE) );
- if (!strcmp( dos_name, hash_name )) break;
+ if (!strcmp( dos_name, short_name )) break;
}
}
- if (dirent) lstrcpyn32A( buffer, dirent->d_name, maxlen );
- closedir( dir );
+ if (ret && buffer) lstrcpyn32A( buffer, long_name, maxlen );
dprintf_dosfs( stddeb, "DOSFS_FindUnixName(%s,%s) -> %s\n",
- path, name, dirent ? buffer : "** Not found **" );
- return (dirent != NULL);
+ path, name, ret ? long_name : "** Not found **" );
+ DOSFS_CloseDir( dir );
+ return ret;
}
@@ -531,6 +665,41 @@
return NULL;
}
+/***********************************************************************
+ * DOSFS_GetPathDrive
+ *
+ * Get the drive specified by a given path name (DOS or Unix format).
+ */
+static int DOSFS_GetPathDrive( const char **name )
+{
+ int drive;
+ const char *p = *name;
+
+ if (*p && (p[1] == ':'))
+ {
+ drive = toupper(*p) - 'A';
+ *name += 2;
+ }
+ else if (*p == '/') /* Absolute Unix path? */
+ {
+ if ((drive = DRIVE_FindDriveRoot( name )) == -1)
+ {
+ fprintf( stderr, "Warning: %s not accessible from a DOS drive\n",
+ *name );
+ /* Assume it really was a DOS name */
+ drive = DRIVE_GetCurrentDrive();
+ }
+ }
+ else drive = DRIVE_GetCurrentDrive();
+
+ if (!DRIVE_IsValid(drive))
+ {
+ DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
+ return -1;
+ }
+ return drive;
+}
+
/***********************************************************************
* DOSFS_GetUnixFileName
@@ -542,33 +711,14 @@
const char * DOSFS_GetUnixFileName( const char * name, int check_last )
{
static char buffer[MAX_PATHNAME_LEN];
- int drive, len, found;
+ int drive, len;
+ BOOL32 found;
UINT32 flags;
char *p, *root;
dprintf_dosfs( stddeb, "DOSFS_GetUnixFileName: %s\n", name );
- if (name[0] && (name[1] == ':'))
- {
- drive = toupper(name[0]) - 'A';
- name += 2;
- }
- else if (name[0] == '/') /* Absolute Unix path? */
- {
- if ((drive = DRIVE_FindDriveRoot( &name )) == -1)
- {
- fprintf( stderr, "Warning: %s not accessible from a DOS drive\n",
- name );
- /* Assume it really was a DOS name */
- drive = DRIVE_GetCurrentDrive();
- }
- }
- else drive = DRIVE_GetCurrentDrive();
- if (!DRIVE_IsValid(drive))
- {
- DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
- return NULL;
- }
+ if ((drive = DOSFS_GetPathDrive( &name )) == -1) return NULL;
flags = DRIVE_GetFlags(drive);
lstrcpyn32A( buffer, DRIVE_GetRoot(drive), MAX_PATHNAME_LEN );
if (buffer[1]) root = buffer + strlen(buffer);
@@ -587,7 +737,7 @@
p = buffer[1] ? buffer + strlen(buffer) : buffer;
len = MAX_PATHNAME_LEN - strlen(buffer);
- found = 1;
+ found = TRUE;
while (*name && found)
{
const char *newname = DOSFS_CheckDotDot( name, root, '/', &len );
@@ -652,29 +802,8 @@
char *p;
dprintf_dosfs( stddeb, "DOSFS_GetDosTrueName(%s,%d)\n", name, unix_format);
- if (name[0] && (name[1] == ':'))
- {
- drive = toupper(name[0]) - 'A';
- name += 2;
- }
- else if (name[0] == '/') /* Absolute Unix path? */
- {
- if ((drive = DRIVE_FindDriveRoot( &name )) == -1)
- {
- fprintf( stderr, "Warning: %s not accessible from a DOS drive\n",
- name );
- /* Assume it really was a DOS name */
- drive = DRIVE_GetCurrentDrive();
- }
- }
- else drive = DRIVE_GetCurrentDrive();
- if (!DRIVE_IsValid(drive))
- {
- DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
- return NULL;
- }
-
+ if ((drive = DOSFS_GetPathDrive( &name )) == -1) return NULL;
p = buffer;
*p++ = 'A' + drive;
*p++ = ':';
@@ -748,25 +877,32 @@
*/
int DOSFS_FindNext( const char *path, const char *short_mask,
const char *long_mask, int drive, BYTE attr,
- int skip, DOS_DIRENT *entry )
+ int skip, WIN32_FIND_DATA32A *entry )
{
- static DIR *dir = NULL;
- struct dirent *dirent;
+ static DOS_DIR *dir = NULL;
int count = 0;
static char buffer[MAX_PATHNAME_LEN];
static int cur_pos = 0;
static int drive_root = 0;
char *p;
- const char *hash_name;
+ LPCSTR long_name, short_name;
UINT32 flags;
+ BY_HANDLE_FILE_INFORMATION info;
if ((attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL)
{
if (skip) return 0;
- strcpy( entry->name, DRIVE_GetLabel( drive ) );
- entry->attr = FA_LABEL;
- entry->size = 0;
- DOSFS_ToDosDateTime( time(NULL), &entry->date, &entry->time );
+ entry->dwFileAttributes = FILE_ATTRIBUTE_LABEL;
+ DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftCreationTime );
+ DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftLastAccessTime );
+ DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftLastWriteTime );
+ entry->nFileSizeHigh = 0;
+ entry->nFileSizeLow = 0;
+ entry->dwReserved0 = 0;
+ entry->dwReserved1 = 0;
+ strcpy( entry->cFileName,
+ DOSFS_ToDosDTAFormat( DRIVE_GetLabel( drive )) );
+ strcpy( entry->cAlternateFileName, entry->cFileName );
return 1;
}
@@ -778,9 +914,9 @@
dprintf_dosfs( stddeb, "DOSFS_FindNext: cache miss, path=%s skip=%d buf=%s cur=%d\n",
path, skip, buffer, cur_pos );
cur_pos = skip;
- if (dir) closedir(dir);
+ if (dir) DOSFS_CloseDir(dir);
if (!*path) path = "/";
- if (!(dir = opendir(path))) return 0;
+ if (!(dir = DOSFS_OpenDir(path))) return 0;
drive_path = path;
drive_root = 0;
if (DRIVE_FindDriveRoot( &drive_path ) != -1)
@@ -796,23 +932,22 @@
p = buffer + strlen(buffer);
attr |= FA_UNUSED | FA_ARCHIVE | FA_RDONLY;
flags = DRIVE_GetFlags( drive );
- hash_name = NULL;
- while ((dirent = readdir( dir )) != NULL)
+ while (DOSFS_ReadDir( dir, &long_name, &short_name ))
{
if (skip-- > 0) continue;
count++;
/* Don't return '.' and '..' in the root of the drive */
- if (drive_root && (dirent->d_name[0] == '.') &&
- (!dirent->d_name[1] ||
- ((dirent->d_name[1] == '.') && !dirent->d_name[2]))) continue;
+ if (drive_root && (long_name[0] == '.') &&
+ (!long_name[1] || ((long_name[1] == '.') && !long_name[2])))
+ continue;
/* Check the long mask */
if (long_mask)
{
- if (!DOSFS_MatchLong( long_mask, dirent->d_name,
+ if (!DOSFS_MatchLong( long_mask, long_name,
flags & DRIVE_CASE_SENSITIVE )) continue;
}
@@ -820,44 +955,208 @@
if (short_mask)
{
- hash_name = DOSFS_Hash( dirent->d_name, TRUE,
- !(flags & DRIVE_CASE_SENSITIVE) );
- if (!DOSFS_MatchShort( short_mask, hash_name )) continue;
+ if (!short_name)
+ short_name = DOSFS_Hash( long_name, TRUE,
+ !(flags & DRIVE_CASE_SENSITIVE) );
+ if (!DOSFS_MatchShort( short_mask, short_name )) continue;
}
/* Check the file attributes */
- lstrcpyn32A( p, dirent->d_name, sizeof(buffer) - (int)(p - buffer) );
- if (!FILE_Stat( buffer, &entry->attr, &entry->size,
- &entry->date, &entry->time ))
+ lstrcpyn32A( p, long_name, sizeof(buffer) - (int)(p - buffer) );
+ if (!FILE_Stat( buffer, &info ))
{
fprintf( stderr, "DOSFS_FindNext: can't stat %s\n", buffer );
continue;
}
- if (entry->attr & ~attr) continue;
+ if (info.dwFileAttributes & ~attr) continue;
/* We now have a matching entry; fill the result and return */
- if (!hash_name)
- hash_name = DOSFS_Hash( dirent->d_name, TRUE,
- !(flags & DRIVE_CASE_SENSITIVE) );
- strcpy( entry->name, hash_name );
- lstrcpyn32A( entry->unixname, dirent->d_name, sizeof(entry->unixname));
- if (!(flags & DRIVE_CASE_PRESERVING)) AnsiLower( entry->unixname );
- dprintf_dosfs( stddeb, "DOSFS_FindNext: returning %s %02x %ld\n",
- entry->name, entry->attr, entry->size );
+ if (!short_name)
+ short_name = DOSFS_Hash( long_name, TRUE,
+ !(flags & DRIVE_CASE_SENSITIVE) );
+
+ entry->dwFileAttributes = info.dwFileAttributes;
+ entry->ftCreationTime = info.ftCreationTime;
+ entry->ftLastAccessTime = info.ftLastAccessTime;
+ entry->ftLastWriteTime = info.ftLastWriteTime;
+ entry->nFileSizeHigh = info.nFileSizeHigh;
+ entry->nFileSizeLow = info.nFileSizeLow;
+ strcpy( entry->cAlternateFileName, DOSFS_ToDosDTAFormat(short_name) );
+ lstrcpyn32A( entry->cFileName, long_name, sizeof(entry->cFileName) );
+ if (!(flags & DRIVE_CASE_PRESERVING)) AnsiLower( entry->cFileName );
+ dprintf_dosfs( stddeb, "DOSFS_FindNext: returning %s (%s) %02lx %ld\n",
+ entry->cFileName, entry->cAlternateFileName,
+ entry->dwFileAttributes, entry->nFileSizeLow );
cur_pos += count;
p[-1] = '\0'; /* Remove trailing slash in buffer */
return count;
}
- closedir( dir );
+ DOSFS_CloseDir( dir );
dir = NULL;
return 0; /* End of directory */
}
+/*************************************************************************
+ * FindFirstFile16 (KERNEL.413)
+ */
+HANDLE16 FindFirstFile16( LPCSTR path, WIN32_FIND_DATA32A *data )
+{
+ HGLOBAL16 handle;
+ FIND_FIRST_INFO *info;
+ LPCSTR ptr;
+
+ if (!path) return 0;
+ if (!(ptr = DOSFS_GetUnixFileName( path, FALSE )))
+ return INVALID_HANDLE_VALUE16;
+ if (!(handle = GlobalAlloc16( GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO) )))
+ return INVALID_HANDLE_VALUE16;
+ info = (FIND_FIRST_INFO *)GlobalLock16( handle );
+ info->path = HEAP_strdupA( SystemHeap, 0, ptr );
+ info->mask = strrchr( info->path, '/' );
+ *(info->mask++) = '\0';
+ if (path[0] && (path[1] == ':')) info->drive = toupper(*path) - 'A';
+ else info->drive = DRIVE_GetCurrentDrive();
+ info->skip = 0;
+ GlobalUnlock16( handle );
+ if (!FindNextFile16( handle, data ))
+ {
+ FindClose16( handle );
+ DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
+ return INVALID_HANDLE_VALUE16;
+ }
+ return handle;
+}
+
+
+/*************************************************************************
+ * FindFirstFile32A (KERNEL32.123)
+ */
+HANDLE32 FindFirstFile32A( LPCSTR path, WIN32_FIND_DATA32A *data )
+{
+ HANDLE32 handle = FindFirstFile16( path, data );
+ if (handle == INVALID_HANDLE_VALUE16) return INVALID_HANDLE_VALUE32;
+ return handle;
+}
+
+
+/*************************************************************************
+ * FindFirstFile32W (KERNEL32.124)
+ */
+HANDLE32 FindFirstFile32W( LPCWSTR path, WIN32_FIND_DATA32W *data )
+{
+ WIN32_FIND_DATA32A dataA;
+ LPSTR pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
+ HANDLE32 handle = FindFirstFile32A( pathA, &dataA );
+ HeapFree( GetProcessHeap(), 0, pathA );
+ if (handle != INVALID_HANDLE_VALUE32)
+ {
+ data->dwFileAttributes = dataA.dwFileAttributes;
+ data->ftCreationTime = dataA.ftCreationTime;
+ data->ftLastAccessTime = dataA.ftLastAccessTime;
+ data->ftLastWriteTime = dataA.ftLastWriteTime;
+ data->nFileSizeHigh = dataA.nFileSizeHigh;
+ data->nFileSizeLow = dataA.nFileSizeLow;
+ lstrcpyAtoW( data->cFileName, dataA.cFileName );
+ lstrcpyAtoW( data->cAlternateFileName, dataA.cAlternateFileName );
+ }
+ return handle;
+}
+
+
+/*************************************************************************
+ * FindNextFile16 (KERNEL.414)
+ */
+BOOL16 FindNextFile16( HANDLE16 handle, WIN32_FIND_DATA32A *data )
+{
+ FIND_FIRST_INFO *info;
+ int count;
+
+ if (!(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
+ {
+ DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+ return FALSE;
+ }
+ GlobalUnlock16( handle );
+ if (!info->path)
+ {
+ DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
+ return FALSE;
+ }
+ if (!(count = DOSFS_FindNext( info->path, NULL, info->mask, info->drive,
+ 0xff, info->skip, data )))
+ {
+ HeapFree( SystemHeap, 0, info->path );
+ info->path = info->mask = NULL;
+ DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk );
+ return FALSE;
+ }
+ info->skip += count;
+ return TRUE;
+}
+
+
+/*************************************************************************
+ * FindNextFile32A (KERNEL32.126)
+ */
+BOOL32 FindNextFile32A( HANDLE32 handle, WIN32_FIND_DATA32A *data )
+{
+ return FindNextFile16( handle, data );
+}
+
+
+/*************************************************************************
+ * FindNextFile32W (KERNEL32.127)
+ */
+BOOL32 FindNextFile32W( HANDLE32 handle, WIN32_FIND_DATA32W *data )
+{
+ WIN32_FIND_DATA32A dataA;
+ if (!FindNextFile32A( handle, &dataA )) return FALSE;
+ data->dwFileAttributes = dataA.dwFileAttributes;
+ data->ftCreationTime = dataA.ftCreationTime;
+ data->ftLastAccessTime = dataA.ftLastAccessTime;
+ data->ftLastWriteTime = dataA.ftLastWriteTime;
+ data->nFileSizeHigh = dataA.nFileSizeHigh;
+ data->nFileSizeLow = dataA.nFileSizeLow;
+ lstrcpyAtoW( data->cFileName, dataA.cFileName );
+ lstrcpyAtoW( data->cAlternateFileName, dataA.cAlternateFileName );
+ return TRUE;
+}
+
+
+/*************************************************************************
+ * FindClose16 (KERNEL.415)
+ */
+BOOL16 FindClose16( HANDLE16 handle )
+{
+ FIND_FIRST_INFO *info;
+
+ if ((handle == INVALID_HANDLE_VALUE16) ||
+ !(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
+ {
+ DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk );
+ return FALSE;
+ }
+ if (info->path) HeapFree( SystemHeap, 0, info->path );
+ GlobalUnlock16( handle );
+ GlobalFree16( handle );
+ return TRUE;
+}
+
+
+/*************************************************************************
+ * FindClose32 (KERNEL32.119)
+ */
+BOOL32 FindClose32( HANDLE32 handle )
+{
+ return FindClose16( (HANDLE16)handle );
+}
+
+
/***********************************************************************
- * GetShortPathNameA (KERNEL32.271)
+ * GetShortPathName32A (KERNEL32.271)
*/
DWORD GetShortPathName32A( LPCSTR longpath, LPSTR shortpath, DWORD shortlen )
{
@@ -940,7 +1239,8 @@
/***********************************************************************
* FileTimeToDosDateTime (KERNEL32.111)
*/
-BOOL32 FileTimeToDosDateTime( LPFILETIME ft, LPWORD fatdate, LPWORD fattime)
+BOOL32 FileTimeToDosDateTime( const FILETIME *ft, LPWORD fatdate,
+ LPWORD fattime )
{
time_t unixtime = DOSFS_FileTimeToUnixTime(ft);
DOSFS_ToDosDateTime(unixtime,fatdate,fattime);
@@ -951,7 +1251,7 @@
/***********************************************************************
* LocalFileTimeToFileTime (KERNEL32.373)
*/
-BOOL32 LocalFileTimeToFileTime( LPFILETIME localft, LPFILETIME utcft )
+BOOL32 LocalFileTimeToFileTime( const FILETIME *localft, LPFILETIME utcft )
{
struct tm *xtm;
@@ -966,7 +1266,7 @@
/***********************************************************************
* FileTimeToLocalFileTime (KERNEL32.112)
*/
-BOOL32 FileTimeToLocalFileTime( LPFILETIME utcft, LPFILETIME localft )
+BOOL32 FileTimeToLocalFileTime( const FILETIME *utcft, LPFILETIME localft )
{
struct tm *xtm;
@@ -981,7 +1281,7 @@
/***********************************************************************
* FileTimeToSystemTime (KERNEL32.113)
*/
-BOOL32 FileTimeToSystemTime( LPFILETIME ft, LPSYSTEMTIME syst )
+BOOL32 FileTimeToSystemTime( const FILETIME *ft, LPSYSTEMTIME syst )
{
struct tm *xtm;
time_t xtime = DOSFS_FileTimeToUnixTime(ft);
@@ -1001,7 +1301,7 @@
/***********************************************************************
* SystemTimeToFileTime (KERNEL32.526)
*/
-BOOL32 SystemTimeToFileTime( LPSYSTEMTIME syst, LPFILETIME ft )
+BOOL32 SystemTimeToFileTime( const SYSTEMTIME *syst, LPFILETIME ft )
{
struct tm xtm;