r886 - in trunk: . platform

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Mar 31 19:44:42 EDT 2007


Author: icculus
Date: 2007-03-31 19:44:42 -0400 (Sat, 31 Mar 2007)
New Revision: 886

Modified:
   trunk/CHANGELOG.txt
   trunk/platform/windows.c
Log:
Symlink support for Windows Vista. Untested code.


Modified: trunk/CHANGELOG.txt
===================================================================
--- trunk/CHANGELOG.txt	2007-03-31 06:59:02 UTC (rev 885)
+++ trunk/CHANGELOG.txt	2007-03-31 23:44:42 UTC (rev 886)
@@ -5,7 +5,8 @@
 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
            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
            looking in a directory other than the root, instead of enumerating
            only for the root (thanks, Chris!). Minor fix for compilers that

Modified: trunk/platform/windows.c
===================================================================
--- trunk/platform/windows.c	2007-03-31 06:59:02 UTC (rev 885)
+++ trunk/platform/windows.c	2007-03-31 23:44:42 UTC (rev 886)
@@ -578,10 +578,43 @@
 } /* __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)
 {
-    /* !!! FIXME: Vista has symlinks. Recheck this. */
-    return(0);  /* no symlinks on win32. */
+    /* !!! FIXME:
+     * 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 */
 
 
@@ -686,13 +719,17 @@
     {
         do
         {
+            const DWORD attrs = entw.dwFileAttributes;
+            const DWORD tag = entw.dwReserved0;
             const WCHAR *fn = entw.cFileName;
             if ((fn[0] == '.') && (fn[1] == '\0'))
                 continue;
             if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
                 continue;
+            if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
+                continue;
 
-            utf8 = unicodeToUtf8Heap(entw.cFileName);
+            utf8 = unicodeToUtf8Heap(fn);
             if (utf8 != NULL)
             {
                 callback(callbackdata, origdir, utf8);
@@ -705,13 +742,17 @@
     {
         do
         {
+            const DWORD attrs = ent.dwFileAttributes;
+            const DWORD tag = ent.dwReserved0;
             const char *fn = ent.cFileName;
             if ((fn[0] == '.') && (fn[1] == '\0'))
                 continue;
             if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
                 continue;
+            if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
+                continue;
 
-            utf8 = codepageToUtf8Heap(ent.cFileName);
+            utf8 = codepageToUtf8Heap(fn);
             if (utf8 != NULL)
             {
                 callback(callbackdata, origdir, utf8);




More information about the physfs-commits mailing list