Use a better method of identifying files on w32
authorJohn Darrington <john@darrington.wattle.id.au>
Sun, 25 Oct 2015 19:14:55 +0000 (20:14 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Wed, 28 Oct 2015 19:49:16 +0000 (20:49 +0100)
src/data/file-name.c

index b5cc43deaa2c81b8e5137f5b6a6340c1d7a3acc1..dfdfa6d223c89c3821cee5002e3370364f5edb2d 100644 (file)
@@ -262,12 +262,40 @@ fn_get_identity (const char *file_name)
       free (dir);
     }
 #else /* Windows */
-  char cname[PATH_MAX];
-  int ok = GetFullPathName (file_name, sizeof cname, cname, NULL);
-  identity->device = 0;
-  identity->inode = 0;
-  identity->name = xstrdup (ok ? cname : file_name);
-  str_lowercase (identity->name);
+  bool ok = false;
+  HANDLE h = CreateFile (file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+  if (h != INVALID_HANDLE_VALUE)
+  {
+    BY_HANDLE_FILE_INFORMATION fi;
+    ok = GetFileInformationByHandle (h, &fi);
+    if (ok)
+      {
+       identity->device = fi.dwVolumeSerialNumber;
+       identity->inode = fi.nFileIndexHigh << 16 | fi.nFileIndexLow;
+       identity->name = 0;
+      }
+    CloseHandle (h);
+  }
+
+  if (!ok)
+    {
+      identity->device = 0;
+      identity->inode = 0;
+
+      size_t bufsize;
+      size_t pathlen = 255;
+      char *cname = NULL;
+      do 
+      {
+       bufsize = pathlen;
+       cname = xrealloc (cname, bufsize);
+       pathlen = GetFullPathName (file_name, bufsize, cname, NULL);
+      }
+      while (pathlen > bufsize);
+      identity->name = xstrdup (cname);
+      free (cname);
+      str_lowercase (identity->name);
+    }
 #endif /* Windows */
 
   return identity;