Symlink support for Windows Vista. Untested code.

This commit is contained in:
Ryan C. Gordon 2007-03-31 23:44:42 +00:00
parent 45967499d0
commit 9af599504d
2 changed files with 47 additions and 5 deletions

View File

@ -5,7 +5,8 @@
03312007 - Added a quick'n'dirty unpack utility to the extras directory. Moved 03312007 - Added a quick'n'dirty unpack utility to the extras directory. Moved
DIR archiver to start of the list, so we don't have to have every DIR archiver to start of the list, so we don't have to have every
other archiver fail to open a directory as a file before mounting other archiver fail to open a directory as a file before mounting
it. Fixed typos in makeos2.cmd and the Doxygen comments. it. Fixed typos in makeos2.cmd and the Doxygen comments. Added
symlink support to windows.c for use on Vista-based systems.
03282007 - Logic bug in MVL/HOG/GRP archivers: only enumerated files when 03282007 - Logic bug in MVL/HOG/GRP archivers: only enumerated files when
looking in a directory other than the root, instead of enumerating looking in a directory other than the root, instead of enumerating
only for the root (thanks, Chris!). Minor fix for compilers that only for the root (thanks, Chris!). Minor fix for compilers that

View File

@ -578,10 +578,43 @@ int __PHYSFS_platformExists(const char *fname)
} /* __PHYSFS_platformExists */ } /* __PHYSFS_platformExists */
static int isSymlinkAttrs(DWORD attr, DWORD tag)
{
return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) &&
((tag & IO_REPARSE_TAG_SYMLINK) == IO_REPARSE_TAG_SYMLINK) );
} /* isSymlinkAttrs */
int __PHYSFS_platformIsSymLink(const char *fname) int __PHYSFS_platformIsSymLink(const char *fname)
{ {
/* !!! FIXME: Vista has symlinks. Recheck this. */ /* !!! FIXME:
return(0); /* no symlinks on win32. */ * Windows Vista can have NTFS symlinks. Can older Windows releases have
* them when talking to a network file server? What happens when you
* mount a NTFS partition on XP that was plugged into a Vista install
* that made a symlink?
*/
int retval = 0;
LPWSTR wpath;
HANDLE dir;
WIN32_FIND_DATAW entw;
/* no unicode entry points? Probably no symlinks. */
BAIL_IF_MACRO(pFindFirstFileW == NULL, NULL, 0);
UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
/* !!! FIXME: filter wildcard chars? */
dir = pFindFirstFileW(wpath, &entw);
if (dir != INVALID_HANDLE_VALUE)
{
retval = isSymlinkAttrs(entw.dwFileAttributes, entw.dwReserved0);
FindClose(dir);
} /* if */
__PHYSFS_smallFree(wpath);
return(retval);
} /* __PHYSFS_platformIsSymlink */ } /* __PHYSFS_platformIsSymlink */
@ -686,13 +719,17 @@ void __PHYSFS_platformEnumerateFiles(const char *dirname,
{ {
do do
{ {
const DWORD attrs = entw.dwFileAttributes;
const DWORD tag = entw.dwReserved0;
const WCHAR *fn = entw.cFileName; const WCHAR *fn = entw.cFileName;
if ((fn[0] == '.') && (fn[1] == '\0')) if ((fn[0] == '.') && (fn[1] == '\0'))
continue; continue;
if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0')) if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
continue; continue;
if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
continue;
utf8 = unicodeToUtf8Heap(entw.cFileName); utf8 = unicodeToUtf8Heap(fn);
if (utf8 != NULL) if (utf8 != NULL)
{ {
callback(callbackdata, origdir, utf8); callback(callbackdata, origdir, utf8);
@ -705,13 +742,17 @@ void __PHYSFS_platformEnumerateFiles(const char *dirname,
{ {
do do
{ {
const DWORD attrs = ent.dwFileAttributes;
const DWORD tag = ent.dwReserved0;
const char *fn = ent.cFileName; const char *fn = ent.cFileName;
if ((fn[0] == '.') && (fn[1] == '\0')) if ((fn[0] == '.') && (fn[1] == '\0'))
continue; continue;
if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0')) if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
continue; continue;
if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
continue;
utf8 = codepageToUtf8Heap(ent.cFileName); utf8 = codepageToUtf8Heap(fn);
if (utf8 != NULL) if (utf8 != NULL)
{ {
callback(callbackdata, origdir, utf8); callback(callbackdata, origdir, utf8);