CVS: winex/files dos_fs.c,1.39,1.40
[email protected] 29 Aug 2007 11:55:15 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/files dos_fs.c,1.39,1.40Update of /var/lib/cvsd/cvsroot/winex/files
In directory agravaine:/tmp/cvs-serv28532/files
Modified Files:
dos_fs.c
Log Message:
Ensure FindFirstFile*() always have . and .. as the first two items examined, as some games depend on this (even though MSDN states not to)
Index: dos_fs.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/files/dos_fs.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- dos_fs.c 31 Jul 2007 20:01:04 -0000 1.39
+++ dos_fs.c 29 Aug 2007 11:55:13 -0000 1.40
@@ -100,10 +100,14 @@
#define GET_DRIVE(path) \
(((path)[1] == ':') ? FILE_toupper((path)[0]) - 'A' : DOSFS_CurDrive)
+typedef enum {RDSTATE_START, RDSTATE_DOT, RDSTATE_DOTDOT,
+ RDSTATE_REST} ReadDirState_t;
+
/* Directory info for DOSFS_ReadDir */
typedef struct
{
DIR *dir;
+ ReadDirState_t state;
#ifdef VFAT_IOCTL_READDIR_BOTH
int fd;
char short_name[12];
@@ -123,6 +127,7 @@
DOS_DIR *dir; /* only used by DOSFS_FindNext() */
#ifdef CACHE_DIR_ENTRY
off_t cur_dir_entry;
+ ReadDirState_t state;
#endif
} FIND_FIRST_INFO;
@@ -420,6 +425,8 @@
directory and mask in several other places */
if (!*path) path = "/";
+ dir->state = RDSTATE_START;
+
#ifdef VFAT_IOCTL_READDIR_BOTH
/* Check if the VFAT ioctl is supported on this directory */
@@ -472,6 +479,26 @@
{
struct dirent *dirent;
+ /* Why this? Some games depend on the returned list of names starting
+ with . and .., and this isn't guaranteed by UNIX filesystems
+ (although it normally is the case) */
+ if (dir->state == RDSTATE_START)
+ {
+ *long_name = ".";
+ *short_name = NULL;
+ dir->state = RDSTATE_DOT;
+ return TRUE;
+ }
+ else if (dir->state == RDSTATE_DOT)
+ {
+ *long_name = "..";
+ *short_name = NULL;
+ dir->state = RDSTATE_DOTDOT;
+ return TRUE;
+ }
+ else if (dir->state == RDSTATE_DOTDOT)
+ dir->state = RDSTATE_REST;
+
#ifdef VFAT_IOCTL_READDIR_BOTH
if (dir->fd != -1)
{
@@ -676,6 +703,10 @@
while ((ret = DOSFS_ReadDir( dir, &long_name, &short_name )))
{
+ if ((dir->state == RDSTATE_REST) &&
+ (!strcmp (long_name, ".") || !strcmp (long_name, "..")))
+ continue;
+
/* Apple's case-insensitive, so this will have been caught by
the earlier stat optimization */
#ifndef __APPLE__
@@ -1530,6 +1561,7 @@
{
DOS_DIR *pDir = DOSFS_OpenDir (pInfo->path);
+ pDir->state = pInfo->state;
/* Seek to the place where we were at before, since we no longer
* cache the directory pointer with FindFirstFile and friends.
@@ -1574,6 +1606,8 @@
*/
static void DOSFS_FindNextEx_CloseDir(FIND_FIRST_INFO *pInfo, DOS_DIR *pDir)
{
+ pInfo->state = pDir->state;
+
/* Cache the current directory pointer location. This has a different semantics
* depending on whether we are dealing with a DIR* or an fd */
if (!pInfo->dir)
@@ -1671,6 +1705,10 @@
while (DOSFS_ReadDir( DirPtr, &long_name, &short_name ))
{
+ if ((DirPtr->state == RDSTATE_REST) &&
+ (!strcmp (long_name, ".") || !strcmp (long_name, "..")))
+ continue;
+
info->cur_pos++;
/* Don't return '.' and '..' in the root of the drive */
@@ -1789,6 +1827,7 @@
info.cur_pos = 0;
#ifdef CACHE_DIR_ENTRY
info.cur_dir_entry = -1;
+ info.state = RDSTATE_START;
#endif
info.dir = DOSFS_OpenDir( info.path );
}
@@ -1879,6 +1918,7 @@
#ifdef CACHE_DIR_ENTRY
info->dir = NULL;
info->cur_dir_entry = 0;
+ info->state = RDSTATE_START;
#else
info->dir = DOSFS_OpenDir (info->path);
#endif
@@ -2544,6 +2584,7 @@
info->cur_pos = 0;
#ifdef CACHE_DIR_ENTRY
info->dir = NULL;
+ info->state = RDSTATE_START;
#else
info->dir = DOSFS_OpenDir (info->path);
#endif