1. 10 Oct, 2018 1 commit
    • LRN's avatar
      W32: significant symlink code changes · 62d38715
      LRN authored
      Put the core readlink() code into a separate
      _g_win32_readlink_handle_raw() function that takes a file handle,
      can optionally ensure NUL-terminatedness of its output
      (for cases where we need a NUL-terminator and do *not* need
      to get the exact contents of the symlink as it is stored in FS)
      and can either fill a caller-provided buffer *or* allocate
      its own buffer, and can also read the reparse tag.
      
      Put the rest of readlink() code into separate
      functions that do UTF-16<->UTF-8, strip inconvenient prefix
      and open/close the symlink file handle as needed.
      
      Split _g_win32_stat_utf16_no_trailing_slashes() into
      two functions - the one that takes a filename and the one
      that takes a file descriptor. The part of these functions
      that would have been duplicate is now split into the
      _g_win32_fill_privatestat() funcion.
      
      Add more comments explaining what each function does.
      Only g_win32_readlink_utf8(), which is callable from outside
      via private function interface, gets a real doc-comment,
      the rest get normal, non-doc comments.
      
      Change all callers to use the new version of the private
      g_win32_readlink_utf8() function, which can now NUL-terminate
      and allocate on demand - no need to call it in a loop.
      
      Also, the new code should correctly get reparse tag when the
      caller does fstat() on a symlink. Do note that this requires
      the caller to get a FD for the symlink, not the target. Figuring
      out how to do that is up to the caller.
      
      Since symlink info (target path and reparse tag) are now always
      read directly, via DeviceIoControl(), we don't need to use
      FindFirstFileW() anymore.
      62d38715
  2. 01 Nov, 2017 1 commit
    • LRN's avatar
      W32: Add a stat() implementation for private use · 53bd6a35
      LRN authored
      This commit adds new W32-only functions to gstdio.c,
      and a new header file, gstdioprivate.h.
      These functions are:
      g_win32_stat_utf8()
      g_win32_lstat_utf8()
      g_win32_fstat()
      and they fill a private structure, GWin32PrivateStat,
      which has all the fields that normal stat has, as well as some
      extras.
      
      These functions are then used throughout glib and gio to get better
      data about the system. Specifically:
      * Full, 64-bit size, guaranteed (g_stat() is forced to use 32-bit st_size)
      * Full, 64-bit file identifier (st_ino is 0 when normal stat() is used, and still is)
      * W32 File attributes (which stat() doesn't report); in particular, this allows
        symlinks to be correctly identified
      * Full, 64-bit time, guaranteed (g_stat() uses 32-bit st_*time on 32-bit Windows)
      * Allocated file size (as a W32 replacement for the missing st_blocks)
      
      st_mode remains unchanged (thus, no S_ISLNK), so when these are given back to
      glib users (via g_stat(), for example, which is now implemented by calling g_win32_stat_utf8),
      this field does not contain anything unexpected.
      
      g_lstat() now calls g_win32_lstat_utf8(), which works on symlinks the way it's supposed to.
      
      Also adds the g_win32_readlink_utf8() function, which behaves like readlink()
      (including its inability to return 0-terminated strings and inability to say how large
      the output buffer should be; these limitations are purely for compatibility with
      existing glib code).
      
      Thus, symlink support should now be much better, although far from being complete.
      
      A new W32-only test in gio/tests/file.c highlights the following features:
      * allocated size
      * 64-bit time
      * unique file IDs
      
      https://bugzilla.gnome.org/show_bug.cgi?id=788180
      53bd6a35