windows: (re)added support for symbolic links.
This commit is contained in:
parent
3e5f92d756
commit
84231feb0f
|
@ -62,8 +62,6 @@ Other stuff I thought of...
|
||||||
- Doxygen replacement? (manpages suck.)
|
- Doxygen replacement? (manpages suck.)
|
||||||
- Fix coding standards to match.
|
- Fix coding standards to match.
|
||||||
- See if we can ditch some #include lines...
|
- See if we can ditch some #include lines...
|
||||||
- We lost Vista symlink support when removing isSymLink(). Pull it back from
|
|
||||||
revision control.
|
|
||||||
- PHYSFS_exists() fails if you mountIo with a NULL filename. We need to decide
|
- PHYSFS_exists() fails if you mountIo with a NULL filename. We need to decide
|
||||||
how this API should work.
|
how this API should work.
|
||||||
- ZIP64 support?
|
- ZIP64 support?
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#define PHYSFS_INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
|
#define PHYSFS_INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
|
||||||
|
|
||||||
/* Not defined before the Vista SDK. */
|
/* Not defined before the Vista SDK. */
|
||||||
|
#define PHYSFS_FILE_ATTRIBUTE_REPARSE_POINT 0x400
|
||||||
#define PHYSFS_IO_REPARSE_TAG_SYMLINK 0xA000000C
|
#define PHYSFS_IO_REPARSE_TAG_SYMLINK 0xA000000C
|
||||||
|
|
||||||
|
|
||||||
|
@ -866,17 +867,47 @@ static PHYSFS_sint64 FileTimeToPhysfsTime(const FILETIME *ft)
|
||||||
} /* FileTimeToPhysfsTime */
|
} /* FileTimeToPhysfsTime */
|
||||||
|
|
||||||
|
|
||||||
|
/* check for symlinks. These exist in NTFS 3.1 (WinXP), even though
|
||||||
|
they aren't really available to userspace before Vista. I wonder
|
||||||
|
what would happen if you put an NTFS disk with a symlink on it
|
||||||
|
into an XP machine, though; would this flag get set?
|
||||||
|
NTFS symlinks are a form of "reparse point" (junction, volume mount,
|
||||||
|
etc), so if the REPARSE_POINT attribute is set, check for the symlink
|
||||||
|
tag thereafter. This assumes you already read in the file attributes. */
|
||||||
|
static int isSymlink(const WCHAR *wpath, const DWORD attr)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATAW w32dw;
|
||||||
|
HANDLE h;
|
||||||
|
|
||||||
|
if ((attr & PHYSFS_FILE_ATTRIBUTE_REPARSE_POINT) == 0)
|
||||||
|
return 0; /* not a reparse point? Definitely not a symlink. */
|
||||||
|
|
||||||
|
h = FindFirstFileW(wpath, &w32dw);
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
return 0; /* ...maybe the file just vanished...? */
|
||||||
|
|
||||||
|
FindClose(h);
|
||||||
|
return (w32dw.dwReserved == PHYSFS_IO_REPARSE_TAG_SYMLINK);
|
||||||
|
} /* isSymlink */
|
||||||
|
|
||||||
|
|
||||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
||||||
{
|
{
|
||||||
WIN32_FILE_ATTRIBUTE_DATA winstat;
|
WIN32_FILE_ATTRIBUTE_DATA winstat;
|
||||||
WCHAR *wstr = NULL;
|
WCHAR *wstr = NULL;
|
||||||
DWORD err = 0;
|
DWORD err = 0;
|
||||||
BOOL rc = 0;
|
BOOL rc = 0;
|
||||||
|
int issymlink = 0;
|
||||||
|
|
||||||
UTF8_TO_UNICODE_STACK(wstr, filename);
|
UTF8_TO_UNICODE_STACK(wstr, filename);
|
||||||
BAIL_IF(!wstr, PHYSFS_ERR_OUT_OF_MEMORY, 0);
|
BAIL_IF(!wstr, PHYSFS_ERR_OUT_OF_MEMORY, 0);
|
||||||
rc = GetFileAttributesExW(wstr, GetFileExInfoStandard, &winstat);
|
rc = GetFileAttributesExW(wstr, GetFileExInfoStandard, &winstat);
|
||||||
err = (!rc) ? GetLastError() : 0;
|
|
||||||
|
if (!rc)
|
||||||
|
err = GetLastError();
|
||||||
|
else /* check for symlink while wstr is still available */
|
||||||
|
issymlink = isSymlink(wstr, winstat.dwFileAttributes);
|
||||||
|
|
||||||
__PHYSFS_smallFree(wstr);
|
__PHYSFS_smallFree(wstr);
|
||||||
BAIL_IF(!rc, errcodeFromWinApiError(err), 0);
|
BAIL_IF(!rc, errcodeFromWinApiError(err), 0);
|
||||||
|
|
||||||
|
@ -884,22 +915,25 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
||||||
st->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
|
st->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
|
||||||
st->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);
|
st->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);
|
||||||
|
|
||||||
if(winstat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (issymlink)
|
||||||
{
|
{
|
||||||
st->filetype = PHYSFS_FILETYPE_DIRECTORY;
|
st->filetype = PHYSFS_FILETYPE_SYMLINK;
|
||||||
st->filesize = 0;
|
st->filesize = 0;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
else if(winstat.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_DEVICE))
|
else if (winstat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
st->filetype = PHYSFS_FILETYPE_DIRECTORY;
|
||||||
|
st->filesize = 0;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if (winstat.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_DEVICE))
|
||||||
{
|
{
|
||||||
/* !!! FIXME: what are reparse points? */
|
|
||||||
st->filetype = PHYSFS_FILETYPE_OTHER;
|
st->filetype = PHYSFS_FILETYPE_OTHER;
|
||||||
/* !!! FIXME: don't rely on this */
|
/* !!! FIXME: don't rely on this */
|
||||||
st->filesize = 0;
|
st->filesize = 0;
|
||||||
} /* else if */
|
} /* else if */
|
||||||
|
|
||||||
/* !!! FIXME: check for symlinks on Vista. */
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
st->filetype = PHYSFS_FILETYPE_REGULAR;
|
st->filetype = PHYSFS_FILETYPE_REGULAR;
|
||||||
|
|
Loading…
Reference in New Issue