Ticket #12164: uwp_filesystem.patch

File uwp_filesystem.patch, 16.3 KB (added by Yury Kirpichev <ykirpichev@…>, 6 years ago)

support windows runtime by filesystem

  • boost/filesystem/path.hpp

    diff --git boost/filesystem/path.hpp boost/filesystem/path.hpp
    index af5bfcc..9a93eba 100644
    namespace filesystem  
    455455    //  Experimental generic function returning generic formatted path (i.e. separators
    456456    //  are forward slashes). Motivation: simpler than a family of generic_*string
    457457    //  functions.
    458     path generic() const
     458    path generic_path() const
    459459    {
    460460#   ifdef BOOST_WINDOWS_API
    461461      path tmp;
  • libs/filesystem/src/operations.cpp

    diff --git libs/filesystem/src/operations.cpp libs/filesystem/src/operations.cpp
    index b5e0f66..e85da67 100644
     
    1010
    1111//--------------------------------------------------------------------------------------//
    1212
     13
    1314//  define 64-bit offset macros BEFORE including boost/config.hpp (see ticket #5355)
    1415#if !(defined(__HP_aCC) && defined(_ILP32) && !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
    1516#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
    typedef struct _REPARSE_DATA_BUFFER {  
    172173#   define IO_REPARSE_TAG_SYMLINK (0xA000000CL)       
    173174# endif
    174175
     176#if BOOST_PLAT_WINDOWS_RUNTIME == 0
    175177inline std::wstring wgetenv(const wchar_t* name)
    176178{
    177179  // use vector since for C++03 basic_string is not required to be contiguous
     180
    178181  std::vector<wchar_t> buf(::GetEnvironmentVariableW(name, NULL, 0));
    179182
    180183  // C++03 vector does not have data() so use &buf[0]
    inline std::wstring wgetenv(const wchar_t* name)  
    182185    || ::GetEnvironmentVariableW(name, &buf[0], static_cast<DWORD>(buf.size())) == 0)
    183186    ? std::wstring() : std::wstring(&buf[0]);
    184187}
    185 
     188# endif  // BOOST_PLAT_WINDOWS_RUNTIME
    186189# endif  // BOOST_WINDOWS_API
    187190
    188191//  BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
    typedef DWORD err_t;  
    237240#   define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(create_symbolic_link_api(F, T, Flag)!= 0)
    238241#   define BOOST_REMOVE_DIRECTORY(P)(::RemoveDirectoryW(P)!= 0)
    239242#   define BOOST_DELETE_FILE(P)(::DeleteFileW(P)!= 0)
     243#if BOOST_PLAT_WINDOWS_RUNTIME == 0
    240244#   define BOOST_COPY_DIRECTORY(F,T)(::CreateDirectoryExW(F, T, 0)!= 0)
    241245#   define BOOST_COPY_FILE(F,T,FailIfExistsBool)(::CopyFileW(F, T, FailIfExistsBool)!= 0)
     246#else
     247#   define BOOST_COPY_DIRECTORY(F,T)(::CreateDirectoryW(F, T)!= 0)
     248#   define BOOST_COPY_FILE(F,T,FailIfExistsBool)(::CopyFile(F, T, FailIfExistsBool)!= 0)
     249#endif
    242250#   define BOOST_MOVE_FILE(OLD,NEW)(::MoveFileExW(OLD, NEW, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED)!= 0)
    243251#   define BOOST_RESIZE_FILE(P,SZ)(resize_file_api(P, SZ)!= 0)
    244252#   define BOOST_READ_SYMLINK(P,T)
    namespace  
    578586    DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
    579587    HANDLE hTemplateFile)
    580588  {
     589#if BOOST_PLAT_WINDOWS_RUNTIME
     590    CREATEFILE2_EXTENDED_PARAMETERS extParams = {};
     591    extParams.hTemplateFile = hTemplateFile;
     592    extParams.lpSecurityAttributes = lpSecurityAttributes;
     593    return ::CreateFile2(p.c_str(), dwDesiredAccess, dwShareMode,
     594      dwCreationDisposition, &extParams);
     595#else
    581596    return ::CreateFileW(p.c_str(), dwDesiredAccess, dwShareMode,
    582597      lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
    583598      hTemplateFile);
     599#endif
    584600  }
    585601
    586602  bool is_reparse_point_a_symlink(const path& p)
    587603  {
     604#if BOOST_PLAT_WINDOWS_RUNTIME
     605    return false;
     606#else
    588607    handle_wrapper h(create_file_handle(p, FILE_READ_EA,
    589608      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
    590609      FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL));
    namespace  
    610629        // with "mklink /j junction-name target-path".
    611630      || reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get())->ReparseTag
    612631        == IO_REPARSE_TAG_MOUNT_POINT;  // aka "directory junction" or "junction"
     632#endif
    613633  }
    614634
    615635  inline std::size_t get_full_path_name(
    namespace  
    643663  //  _detail_directory_symlink, as required on Windows by remove() and its helpers.
    644664  fs::file_type query_file_type(const path& p, error_code* ec)
    645665  {
    646     DWORD attr(::GetFileAttributesW(p.c_str()));
    647     if (attr == 0xFFFFFFFF)
     666    DWORD attr;
     667    WIN32_FILE_ATTRIBUTE_DATA fileData;
     668
     669    if (::GetFileAttributesExW(p.c_str(), GetFileExInfoStandard, &fileData) == 0)
    648670    {
    649671      return process_status_failure(p, ec).type();
    650672    }
     673    attr = fileData.dwFileAttributes;
    651674
    652675    if (ec != 0) ec->clear();
    653676
    namespace  
    667690
    668691  BOOL resize_file_api(const wchar_t* p, boost::uintmax_t size)
    669692  {
     693#if BOOST_PLAT_WINDOWS_RUNTIME
     694    CREATEFILE2_EXTENDED_PARAMETERS extParams = {};
     695
     696    handle_wrapper h(::CreateFile2(p, GENERIC_WRITE, 0,
     697      FILE_ATTRIBUTE_NORMAL, &extParams));
     698    return false;
     699#else
    670700    handle_wrapper h(CreateFileW(p, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
    671701                                FILE_ATTRIBUTE_NORMAL, 0));
     702
    672703    LARGE_INTEGER sz;
    673704    sz.QuadPart = size;
    674705    return h.handle != INVALID_HANDLE_VALUE
    675706      && ::SetFilePointerEx(h.handle, sz, 0, FILE_BEGIN)
    676707      && ::SetEndOfFile(h.handle);
     708#endif
    677709  }
    678710
    679711  //  Windows kernel32.dll functions that may or may not be present
    namespace  
    685717    /*__reserved*/ LPSECURITY_ATTRIBUTES lpSecurityAttributes
    686718   );
    687719
    688   PtrCreateHardLinkW create_hard_link_api = PtrCreateHardLinkW(
    689     ::GetProcAddress(
    690       ::GetModuleHandle(TEXT("kernel32.dll")), "CreateHardLinkW"));
    691 
    692720  typedef BOOLEAN (WINAPI *PtrCreateSymbolicLinkW)(
    693721    /*__in*/ LPCWSTR lpSymlinkFileName,
    694722    /*__in*/ LPCWSTR lpTargetFileName,
    695723    /*__in*/ DWORD dwFlags
    696724   );
    697725
     726#if BOOST_PLAT_WINDOWS_RUNTIME
     727  PtrCreateHardLinkW create_hard_link_api =  nullptr;
     728
     729  PtrCreateSymbolicLinkW create_symbolic_link_api = nullptr;
     730#else
     731  PtrCreateHardLinkW create_hard_link_api =  PtrCreateHardLinkW(
     732    ::GetProcAddress(
     733      ::GetModuleHandle(TEXT("kernel32.dll")), "CreateHardLinkW"));
     734
    698735  PtrCreateSymbolicLinkW create_symbolic_link_api = PtrCreateSymbolicLinkW(
    699736    ::GetProcAddress(
    700737      ::GetModuleHandle(TEXT("kernel32.dll")), "CreateSymbolicLinkW"));
     738#endif
    701739
    702740#endif
    703741
    namespace detail  
    906944#   ifdef BOOST_POSIX_API
    907945    struct stat from_stat;
    908946#   endif
    909     error(!BOOST_COPY_DIRECTORY(from.c_str(), to.c_str()) ? BOOST_ERRNO : 0,
     947    error(!BOOST_COPY_DIRECTORY(from.c_str(), 0) ? BOOST_ERRNO : 0,
    910948      from, to, ec, "boost::filesystem::copy_directory");
    911949  }
    912950
    913951  BOOST_FILESYSTEM_DECL
    914952  void copy_file(const path& from, const path& to, copy_option option, error_code* ec)
    915953  {
     954#if BOOST_PLAT_WINDOWS_RUNTIME
     955    COPYFILE2_EXTENDED_PARAMETERS params = {};
     956    params.dwCopyFlags = option == fail_if_exists ? COPY_FILE_FAIL_IF_EXISTS : 0;
     957    error(!CopyFile2(from.c_str(), to.c_str(),
     958      &params) ? BOOST_ERRNO : 0,
     959        from, to, ec, "boost::filesystem::copy_file");
     960#else
    916961    error(!BOOST_COPY_FILE(from.c_str(), to.c_str(),
    917962      option == fail_if_exists) ? BOOST_ERRNO : 0,
    918963        from, to, ec, "boost::filesystem::copy_file");
     964#endif
    919965  }
    920966
    921967  BOOST_FILESYSTEM_DECL
    namespace detail  
    10131059  void create_directory_symlink(const path& to, const path& from,
    10141060                                 system::error_code* ec)
    10151061  {
    1016 #   if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
     1062#   if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 || BOOST_PLAT_WINDOWS_RUNTIME // SDK earlier than Vista and Server 2008
    10171063
    10181064    error(BOOST_ERROR_NOT_SUPPORTED, to, from, ec,
    10191065      "boost::filesystem::create_directory_symlink");
    namespace detail  
    11861232      return false;
    11871233    }
    11881234
     1235#if BOOST_PLAT_WINDOWS_RUNTIME
    11891236    // at this point, both handles are known to be valid
     1237    {
     1238      FILE_STANDARD_INFO info1, info2;
     1239      if (error(!::GetFileInformationByHandleEx(h1.handle, FileStandardInfo ,
     1240        &info1, sizeof(info1)) ? BOOST_ERRNO : 0, p1, p2, ec, "boost::filesystem::equivalent"))
     1241          return  false;
     1242
     1243      if (error(!::GetFileInformationByHandleEx(h2.handle, FileStandardInfo ,
     1244        &info2, sizeof(info2)) ? BOOST_ERRNO : 0, p1, p2, ec, "boost::filesystem::equivalent"))
     1245          return  false;
     1246
     1247      if (info1.AllocationSize.QuadPart != info2.AllocationSize.QuadPart ||
     1248          info1.NumberOfLinks != info2.NumberOfLinks) {
     1249          return false;
     1250      }
     1251    }
     1252    {
     1253      FILE_BASIC_INFO info1, info2;
     1254      if (error(!::GetFileInformationByHandleEx(h1.handle, FileBasicInfo ,
     1255        &info1, sizeof(info1)) ? BOOST_ERRNO : 0, p1, p2, ec, "boost::filesystem::equivalent"))
     1256          return  false;
     1257
     1258      if (error(!::GetFileInformationByHandleEx(h2.handle, FileBasicInfo ,
     1259        &info2, sizeof(info2)) ? BOOST_ERRNO : 0, p1, p2, ec, "boost::filesystem::equivalent"))
     1260          return  false;
    11901261
     1262      if (info1.LastWriteTime.QuadPart != info2.LastWriteTime.QuadPart) {
     1263          return false;
     1264      }
     1265    }
     1266    return true;
     1267#else
    11911268    BY_HANDLE_FILE_INFORMATION info1, info2;
    11921269
    11931270    if (error(!::GetFileInformationByHandle(h1.handle, &info1) ? BOOST_ERRNO : 0,
    namespace detail  
    12111288          == info2.ftLastWriteTime.dwLowDateTime
    12121289        && info1.ftLastWriteTime.dwHighDateTime
    12131290          == info2.ftLastWriteTime.dwHighDateTime;
    1214 
     1291#endif
    12151292#   endif
    12161293  }
    12171294
    namespace detail  
    12611338           : static_cast<boost::uintmax_t>(path_stat.st_nlink);
    12621339
    12631340#   else // Windows
    1264 
     1341#if BOOST_PLAT_WINDOWS_RUNTIME
     1342    // at this point, both handles are known to be valid
     1343    {
     1344      FILE_STANDARD_INFO info;
     1345      handle_wrapper h(create_file_handle(p.c_str(), 0,
     1346            FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
     1347            OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
     1348
     1349      return
     1350        !error(h.handle == INVALID_HANDLE_VALUE ?
     1351               BOOST_ERRNO : 0, p, ec, "boost::filesystem::hard_link_count")
     1352        &&
     1353        !error(::GetFileInformationByHandleEx(h.handle, FileStandardInfo, &info, sizeof(info))== 0
     1354               ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::hard_link_count")
     1355        ? info.NumberOfLinks : 0;
     1356    }
     1357#else
    12651358    // Link count info is only available through GetFileInformationByHandle
    12661359    BY_HANDLE_FILE_INFORMATION info;
    12671360    handle_wrapper h(
    namespace detail  
    12751368                 p, ec, "boost::filesystem::hard_link_count")
    12761369           ? info.nNumberOfLinks
    12771370           : 0;
     1371#endif
    12781372#   endif
    12791373  }
    12801374
    namespace detail  
    14551549      || (prms & (owner_write|group_write|others_write))))
    14561550      return;
    14571551
    1458     DWORD attr = ::GetFileAttributesW(p.c_str());
     1552    WIN32_FILE_ATTRIBUTE_DATA attrs;
     1553    DWORD res = ::GetFileAttributesExW(p.c_str(), GetFileExInfoStandard, &attrs);
    14591554
    1460     if (error(attr == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::permissions"))
     1555    if (error(res == 0 ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::permissions"))
    14611556      return;
    14621557
    14631558    if (prms & add_perms)
    1464       attr &= ~FILE_ATTRIBUTE_READONLY;
     1559      attrs.dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
    14651560    else if (prms & remove_perms)
    1466       attr |= FILE_ATTRIBUTE_READONLY;
     1561      attrs.dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
    14671562    else if (prms & (owner_write|group_write|others_write))
    1468       attr &= ~FILE_ATTRIBUTE_READONLY;
     1563      attrs.dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
    14691564    else
    1470       attr |= FILE_ATTRIBUTE_READONLY;
     1565      attrs.dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
    14711566
    1472     error(::SetFileAttributesW(p.c_str(), attr) == 0 ? BOOST_ERRNO : 0,
     1567    error(::SetFileAttributesW(p.c_str(), attrs.dwFileAttributes) == 0 ? BOOST_ERRNO : 0,
    14731568      p, ec, "boost::filesystem::permissions");
    14741569# endif
    14751570  }
    namespace detail  
    15041599      }
    15051600    }
    15061601
    1507 #   elif _WIN32_WINNT < 0x0600  // SDK earlier than Vista and Server 2008
     1602#   elif _WIN32_WINNT < 0x0600  || BOOST_PLAT_WINDOWS_RUNTIME // SDK earlier than Vista and Server 2008
    15081603    error(BOOST_ERROR_NOT_SUPPORTED, p, ec,
    15091604          "boost::filesystem::read_symlink");
    15101605#   else  // Vista and Server 2008 SDK, or later
    namespace detail  
    16811776    return fs::file_status(fs::type_unknown);
    16821777
    16831778#   else  // Windows
     1779    DWORD attr;
     1780    WIN32_FILE_ATTRIBUTE_DATA fileData;
    16841781
    1685     DWORD attr(::GetFileAttributesW(p.c_str()));
    1686     if (attr == 0xFFFFFFFF)
     1782    if (::GetFileAttributesExW(p.c_str(), GetFileExInfoStandard, &fileData) == 0)
    16871783    {
    16881784      return process_status_failure(p, ec);
    16891785    }
     1786    attr = fileData.dwFileAttributes;
    16901787
    16911788    //  reparse point handling;
    16921789    //    since GetFileAttributesW does not resolve symlinks, try to open a file
    namespace detail  
    17641861    return fs::file_status(fs::type_unknown);
    17651862
    17661863#   else  // Windows
     1864    DWORD attr;
     1865    WIN32_FILE_ATTRIBUTE_DATA fileData;
    17671866
    1768     DWORD attr(::GetFileAttributesW(p.c_str()));
    1769     if (attr == 0xFFFFFFFF)
     1867    if (::GetFileAttributesExW(p.c_str(), GetFileExInfoStandard, &fileData) == 0)
    17701868    {
    17711869      return process_status_failure(p, ec);
    17721870    }
     1871    attr = fileData.dwFileAttributes;
    17731872
    17741873    if (ec != 0) ec->clear();
    17751874
    namespace detail  
    18131912      return p;
    18141913     
    18151914#   else  // Windows
    1816 
     1915#if BOOST_PLAT_WINDOWS_RUNTIME
     1916      return L"TEMP";
     1917#else
    18171918      const wchar_t* tmp_env = L"TMP";
    18181919      const wchar_t* temp_env = L"TEMP";
    18191920      const wchar_t* localappdata_env = L"LOCALAPPDATA";
    namespace detail  
    18521953        p /= L"Temp";
    18531954      }
    18541955      return p;
    1855 
     1956#   endif
    18561957#   endif
    18571958  }
    18581959 
    namespace  
    21312232        && dirpath[dirpath.size()-1] != L':'))? L"\\*" : L"*";
    21322233
    21332234    WIN32_FIND_DATAW data;
    2134     if ((handle = ::FindFirstFileW(dirpath.c_str(), &data))
    2135       == INVALID_HANDLE_VALUE)
    2136     { 
     2235    if ((handle = ::FindFirstFileExW(dirpath.c_str(), FindExInfoStandard,
     2236            &data, FindExSearchNameMatch, nullptr, 0)) == INVALID_HANDLE_VALUE)
     2237    {
    21372238      handle = 0;  // signal eof
    21382239      return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND
    21392240                       // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551                                           
    2140                        || ::GetLastError() == ERROR_NO_MORE_FILES) 
     2241                       || ::GetLastError() == ERROR_NO_MORE_FILES)
    21412242        ? 0 : ::GetLastError(), system_category() );
    21422243    }
    21432244    target = data.cFileName;
  • libs/filesystem/src/unique_path.cpp

    diff --git libs/filesystem/src/unique_path.cpp libs/filesystem/src/unique_path.cpp
    index d88cbb8..3b35690 100644
    void fail(int err, boost::system::error_code* ec)  
    4444  return;
    4545}
    4646
    47 #ifdef BOOST_WINDOWS_API
     47#if defined(BOOST_WINDOWS_API) && BOOST_PLAT_WINDOWS_RUNTIME == 0
    4848
    4949int acquire_crypt_handle(HCRYPTPROV& handle)
    5050{
    void system_crypt_random(void* buf, std::size_t len, boost::system::error_code*  
    104104
    105105# else // BOOST_WINDOWS_API
    106106
     107#if BOOST_PLAT_WINDOWS_RUNTIME
     108  using namespace Windows::Security::Cryptography;
     109  Windows::Storage::Streams::IBuffer^ buffer = CryptographicBuffer::GenerateRandom(len);
     110  Platform::Array<unsigned char>^ value;
     111  CryptographicBuffer::CopyToByteArray(buffer, &value);
     112  std::copy(value->begin(), value->end(), static_cast<unsigned char*>(buf));
     113#else
    107114  HCRYPTPROV handle;
    108115  int errval = acquire_crypt_handle(handle);
    109116
    void system_crypt_random(void* buf, std::size_t len, boost::system::error_code*  
    118125  if (!errval) return;
    119126
    120127  fail(errval, ec);
     128#endif
    121129# endif
    122130}
    123131
  • libs/filesystem/src/windows_file_codecvt.cpp

    diff --git libs/filesystem/src/windows_file_codecvt.cpp libs/filesystem/src/windows_file_codecvt.cpp
    index 998db60..03095ed 100644
     
    1616#ifndef BOOST_SYSTEM_NO_DEPRECATED
    1717# define BOOST_SYSTEM_NO_DEPRECATED
    1818#endif
    19 
     19#include <boost/predef.h>
    2020#include <boost/filesystem/config.hpp>
    2121#include <cwchar>  // for mbstate_t
    2222
     
    3636    const char* from, const char* from_end, const char*& from_next,
    3737    wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const
    3838  {
     39#if BOOST_PLAT_WINDOWS_RUNTIME
     40    UINT codepage = CP_OEMCP;
     41#else
    3942    UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
     43#endif
    4044
    4145    int count;
    4246    if ((count = ::MultiByteToWideChar(codepage, MB_PRECOMPOSED, from,
     
    5660    const wchar_t* from, const wchar_t* from_end, const wchar_t*  & from_next,
    5761    char* to, char* to_end, char* & to_next) const
    5862  {
     63#if BOOST_PLAT_WINDOWS_RUNTIME
     64    UINT codepage = CP_OEMCP;
     65#else
    5966    UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
     67#endif
    6068
    6169    int count;
    6270    if ((count = ::WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, from,