summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/win32/emu.cpp48
-rw-r--r--lib/win32/emu.h38
2 files changed, 52 insertions, 34 deletions
diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp
index 2c1fb0df..ef237671 100644
--- a/lib/win32/emu.cpp
+++ b/lib/win32/emu.cpp
@@ -1,8 +1,5 @@
// Box Backup Win32 native port by Nick Knight
-// Need at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW
-#define WINVER 0x0500
-
#include "emu.h"
#ifdef WIN32
@@ -1080,9 +1077,10 @@ DIR *opendir(const char *name)
return NULL;
}
- pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info));
+ pDir->fd = FindFirstFileW(pDir->name, &pDir->info);
+ DWORD tmp = GetLastError();
- if (pDir->fd == -1)
+ if (pDir->fd == INVALID_HANDLE_VALUE)
{
delete [] pDir->name;
delete pDir;
@@ -1111,26 +1109,37 @@ struct dirent *readdir(DIR *dp)
{
struct dirent *den = NULL;
- if (dp && dp->fd != -1)
+ if (dp && dp->fd != INVALID_HANDLE_VALUE)
{
- if (!dp->result.d_name ||
- _wfindnext(dp->fd, &dp->info) != -1)
+ // first time around, when dp->result.d_name == NULL, use
+ // the values returned by FindFirstFile. After that, call
+ // FindNextFileW to return new ones.
+ if (!dp->result.d_name ||
+ FindNextFileW(dp->fd, &dp->info) != 0)
{
den = &dp->result;
- std::wstring input(dp->info.name);
+ std::wstring input(dp->info.cFileName);
memset(tempbuff, 0, sizeof(tempbuff));
- WideCharToMultiByte(CP_UTF8, 0, dp->info.name,
+ WideCharToMultiByte(CP_UTF8, 0, dp->info.cFileName,
-1, &tempbuff[0], sizeof (tempbuff),
NULL, NULL);
//den->d_name = (char *)dp->info.name;
den->d_name = &tempbuff[0];
- if (dp->info.attrib & FILE_ATTRIBUTE_DIRECTORY)
+ den->d_type = dp->info.dwFileAttributes;
+ }
+ else // FindNextFileW failed
+ {
+ // Why did it fail? No more files?
+ winerrno = GetLastError();
+ den = NULL;
+
+ if (winerrno == ERROR_NO_MORE_FILES)
{
- den->d_type = S_IFDIR;
+ errno = 0; // no more files
}
else
{
- den->d_type = S_IFREG;
+ errno = ENOSYS;
}
}
}
@@ -1138,6 +1147,7 @@ struct dirent *readdir(DIR *dp)
{
errno = EBADF;
}
+
return den;
}
catch (...)
@@ -1159,24 +1169,26 @@ int closedir(DIR *dp)
{
try
{
- int finres = -1;
+ BOOL finres = false;
+
if (dp)
{
- if(dp->fd != -1)
+ if(dp->fd != INVALID_HANDLE_VALUE)
{
- finres = _findclose(dp->fd);
+ finres = FindClose(dp->fd);
}
delete [] dp->name;
delete dp;
}
- if (finres == -1) // errors go to EBADF
+ if (finres == FALSE) // errors go to EBADF
{
+ winerrno = GetLastError();
errno = EBADF;
}
- return finres;
+ return (finres == TRUE) ? 0 : -1;
}
catch (...)
{
diff --git a/lib/win32/emu.h b/lib/win32/emu.h
index 1ebd45c2..151fa2cb 100644
--- a/lib/win32/emu.h
+++ b/lib/win32/emu.h
@@ -50,22 +50,30 @@
#define __MSVCRT_VERSION__ 0x0601
#endif
+// We need WINVER at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW,
+// and 0x0501 for FindFirstFile(W) for opendir/readdir.
+//
// WIN32_WINNT versions 0x0600 (Vista) and higher enable WSAPoll() in
// winsock2.h, whose struct pollfd conflicts with ours below, so for
-// now we just set it lower than that, to Windows 2000.
+// now we just set it lower than that, to Windows XP (0x0501).
+
#ifdef WINVER
- #if WINVER != 0x0500
- #error Must include emu.h before setting WINVER
- #endif
+# if WINVER != 0x0501
+// provoke a redefinition warning to track down the offender
+# define WINVER 0x0501
+# error Must include emu.h before setting WINVER
+# endif
#endif
-#define WINVER 0x0500
+#define WINVER 0x0501
#ifdef _WIN32_WINNT
- #if _WIN32_WINNT != 0x0500
- #error Must include emu.h before setting _WIN32_WINNT
- #endif
+# if _WIN32_WINNT != 0x0501
+// provoke a redefinition warning to track down the offender
+# define _WIN32_WINNT 0x0501
+# error Must include emu.h before setting _WIN32_WINNT
+# endif
#endif
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0501
// Windows headers
@@ -237,17 +245,15 @@ inline int strcasecmp(const char *s1, const char *s2)
struct dirent
{
char *d_name;
- unsigned long d_type;
+ DWORD d_type; // file attributes
};
struct DIR
{
- intptr_t fd; // filedescriptor
- // struct _finddata_t info;
- struct _wfinddata_t info;
- // struct _finddata_t info;
- struct dirent result; // d_name (first time null)
- wchar_t *name; // null-terminated byte string
+ HANDLE fd; // the HANDLE returned by FindFirstFile
+ WIN32_FIND_DATAW info;
+ struct dirent result; // d_name (first time null)
+ wchar_t* name; // null-terminated byte string
};
DIR *opendir(const char *name);