Opened 11 years ago

Last modified 9 years ago

#5649 new Bugs

create_directories() fails with NTFS mounted volumes

Reported by: Tomas Kazmar <tomash.kazmar@…> Owned by: Beman Dawes
Milestone: To Be Determined Component: filesystem
Version: Boost 1.46.1 Severity: Problem
Keywords: Cc:

Description

When there is an NTFS mounted volume at some level in the path which is passed to create_directories. The function fails because of the first two checks:

BOOST_FILESYSTEM_DECL
bool create_directories(const path& p, system::error_code* ec)
{
  if (p.empty() || exists(p))
  {
    if (!p.empty() && !is_directory(p))
    {
      ...throws/returns an error...

For a mounted volume path p is not empty, it exists, but is_directory(p) fails. This happens because a mounted volume directory is reported by status(p) as file_type::reparse_file.

Probably is_directory() should be changed to accept existing NTFS mounted volumes as already existing directories along the path which is to be created.

Windows 7 64bit, Boost 1.46.1, filesystem v3, MSVC 9

Change History (3)

comment:1 by Michel MORIN <mimomorin@…>, 11 years ago

Component: Nonefilesystem
Owner: set to Beman Dawes

comment:2 by anonymous, 11 years ago

cmd> mkdir d:/bar cmd> mklink /J d:/foo d:/bar cmd> Verbindung erstellt für d:\foo <<===>> d:\bar

boost::filesystem::create_directories("d:/foo"); throws boost::filesystem::create_directories: File exists: "d:/foo"

comment:3 by anonymous, 9 years ago

in /libs/filesystem/src/operations.cpp (lines 1654-1672)

    //  reparse point handling;
    //    since GetFileAttributesW does not resolve symlinks, try to open a file
    //    handle to discover if the file exists
    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
    {
      handle_wrapper h(
        create_file_handle(
            p.c_str(),
            0,  // dwDesiredAccess; attributes only
            FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
            0,  // lpSecurityAttributes
            OPEN_EXISTING,
            FILE_FLAG_BACKUP_SEMANTICS,
            0)); // hTemplateFile
      if (h.handle == INVALID_HANDLE_VALUE)
      {
        return process_status_failure(p, ec);
      }

      if (!is_reparse_point_a_symlink(p))
        return file_status(reparse_file, make_permissions(p, attr));
    }

changing

return file_status(reparse_file, make_permissions(p, attr));

to:

return file_status(directory_file, make_permissions(p, attr));

seems to fix this problem...of course i have no idea what new problems it might cause.

Note: See TracTickets for help on using tickets.