зеркало из https://github.com/microsoft/STL.git
Fix #322: <filesystem>: GetVolumePathNameW linker errors for UWP developers
This commit is contained in:
Родитель
19067f6752
Коммит
18063ce6e4
|
@ -237,6 +237,7 @@ endforeach()
|
||||||
# Objs that exist in both libcpmt[d][01].lib and msvcprt[d].lib.
|
# Objs that exist in both libcpmt[d][01].lib and msvcprt[d].lib.
|
||||||
set(IMPLIB_SOURCES
|
set(IMPLIB_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/filesystem.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/filesystem.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/filesystem_space.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/locale0_implib.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/locale0_implib.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/nothrow.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/nothrow.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/parallel_algorithms.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/parallel_algorithms.cpp
|
||||||
|
|
|
@ -168,6 +168,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
(controlled by IncludeInLink and IncludeInImportLib). -->
|
(controlled by IncludeInLink and IncludeInImportLib). -->
|
||||||
<BuildFiles Include="
|
<BuildFiles Include="
|
||||||
$(CrtRoot)\github\stl\src\filesystem.cpp;
|
$(CrtRoot)\github\stl\src\filesystem.cpp;
|
||||||
|
$(CrtRoot)\github\stl\src\filesystem_space.cpp;
|
||||||
$(CrtRoot)\github\stl\src\locale0_implib.cpp;
|
$(CrtRoot)\github\stl\src\locale0_implib.cpp;
|
||||||
$(CrtRoot)\github\stl\src\nothrow.cpp;
|
$(CrtRoot)\github\stl\src\nothrow.cpp;
|
||||||
$(CrtRoot)\github\stl\src\parallel_algorithms.cpp;
|
$(CrtRoot)\github\stl\src\parallel_algorithms.cpp;
|
||||||
|
|
|
@ -259,22 +259,6 @@ namespace {
|
||||||
|
|
||||||
return _Last_error;
|
return _Last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(uintmax_t) == sizeof(ULARGE_INTEGER) && alignof(uintmax_t) == alignof(ULARGE_INTEGER),
|
|
||||||
"Size and alignment must match for reinterpret_cast<PULARGE_INTEGER>");
|
|
||||||
|
|
||||||
[[nodiscard]] __std_win_error _Fs_space_attempt(wchar_t* const _Temp_buffer, const DWORD _Temp_buffer_characters,
|
|
||||||
const wchar_t* const _Target, uintmax_t* const _Available, uintmax_t* const _Total_bytes,
|
|
||||||
uintmax_t* const _Free_bytes) noexcept {
|
|
||||||
if (GetVolumePathNameW(_Target, _Temp_buffer, _Temp_buffer_characters)) {
|
|
||||||
if (GetDiskFreeSpaceExW(_Temp_buffer, reinterpret_cast<PULARGE_INTEGER>(_Available),
|
|
||||||
reinterpret_cast<PULARGE_INTEGER>(_Total_bytes), reinterpret_cast<PULARGE_INTEGER>(_Free_bytes))) {
|
|
||||||
return __std_win_error::_Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return __std_win_error{GetLastError()};
|
|
||||||
}
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
_EXTERN_C
|
_EXTERN_C
|
||||||
|
@ -760,43 +744,6 @@ __std_win_error __stdcall __std_fs_get_file_id(__std_fs_file_id* const _Id, cons
|
||||||
return __std_win_error::_Success;
|
return __std_win_error::_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] __std_win_error __stdcall __std_fs_space(const wchar_t* const _Target, uintmax_t* const _Available,
|
|
||||||
uintmax_t* const _Total_bytes, uintmax_t* const _Free_bytes) noexcept {
|
|
||||||
// get capacity information for the volume on which the file _Target resides
|
|
||||||
__std_win_error _Last_error;
|
|
||||||
if (GetFileAttributesW(_Target) == INVALID_FILE_ATTRIBUTES) {
|
|
||||||
_Last_error = __std_win_error{GetLastError()};
|
|
||||||
} else {
|
|
||||||
{
|
|
||||||
constexpr DWORD _Static_size = MAX_PATH;
|
|
||||||
wchar_t _Temp_buf[_Static_size];
|
|
||||||
_Last_error = _Fs_space_attempt(_Temp_buf, _Static_size, _Target, _Available, _Total_bytes, _Free_bytes);
|
|
||||||
if (_Last_error == __std_win_error::_Success) {
|
|
||||||
return __std_win_error::_Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_Last_error == __std_win_error::_Filename_exceeds_range) {
|
|
||||||
constexpr DWORD _Dynamic_size = USHRT_MAX + 1; // assuming maximum NT path fits in a UNICODE_STRING
|
|
||||||
const auto _Temp_buf = _malloc_crt_t(wchar_t, _Dynamic_size);
|
|
||||||
if (_Temp_buf) {
|
|
||||||
_Last_error =
|
|
||||||
_Fs_space_attempt(_Temp_buf.get(), _Dynamic_size, _Target, _Available, _Total_bytes, _Free_bytes);
|
|
||||||
if (_Last_error == __std_win_error::_Success) {
|
|
||||||
return __std_win_error::_Success;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_Last_error = __std_win_error::_Not_enough_memory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*_Available = ~0ull;
|
|
||||||
*_Total_bytes = ~0ull;
|
|
||||||
*_Free_bytes = ~0ull;
|
|
||||||
return _Last_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_temp_path(wchar_t* const _Target) noexcept {
|
[[nodiscard]] __std_ulong_and_error __stdcall __std_fs_get_temp_path(wchar_t* const _Target) noexcept {
|
||||||
// calls GetTempPathW
|
// calls GetTempPathW
|
||||||
// If getting the path failed, returns 0 size; otherwise, returns the size of the
|
// If getting the path failed, returns 0 size; otherwise, returns the size of the
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
// This must be as small as possible, because its contents are
|
||||||
|
// injected into the msvcprt.lib and msvcprtd.lib import libraries.
|
||||||
|
// Do not include or define anything else here.
|
||||||
|
// In particular, basic_string must not be included here.
|
||||||
|
|
||||||
|
// TRANSITION, the code in this file should be moved back to filesystem.cpp
|
||||||
|
// when a Windows 10 SDK beyond version 1903 is available (see GH-322).
|
||||||
|
|
||||||
|
#include <internal_shared.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <xfilesystem_abi.h>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static_assert(sizeof(uintmax_t) == sizeof(ULARGE_INTEGER) && alignof(uintmax_t) == alignof(ULARGE_INTEGER),
|
||||||
|
"Size and alignment must match for reinterpret_cast<PULARGE_INTEGER>");
|
||||||
|
|
||||||
|
[[nodiscard]] __std_win_error _Fs_space_attempt(wchar_t* const _Temp_buffer, const DWORD _Temp_buffer_characters,
|
||||||
|
const wchar_t* const _Target, uintmax_t* const _Available, uintmax_t* const _Total_bytes,
|
||||||
|
uintmax_t* const _Free_bytes) noexcept {
|
||||||
|
if (GetVolumePathNameW(_Target, _Temp_buffer, _Temp_buffer_characters)) {
|
||||||
|
if (GetDiskFreeSpaceExW(_Temp_buffer, reinterpret_cast<PULARGE_INTEGER>(_Available),
|
||||||
|
reinterpret_cast<PULARGE_INTEGER>(_Total_bytes), reinterpret_cast<PULARGE_INTEGER>(_Free_bytes))) {
|
||||||
|
return __std_win_error::_Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return __std_win_error{GetLastError()};
|
||||||
|
}
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
_EXTERN_C
|
||||||
|
|
||||||
|
[[nodiscard]] __std_win_error __stdcall __std_fs_space(const wchar_t* const _Target, uintmax_t* const _Available,
|
||||||
|
uintmax_t* const _Total_bytes, uintmax_t* const _Free_bytes) noexcept {
|
||||||
|
// get capacity information for the volume on which the file _Target resides
|
||||||
|
__std_win_error _Last_error;
|
||||||
|
if (GetFileAttributesW(_Target) == INVALID_FILE_ATTRIBUTES) {
|
||||||
|
_Last_error = __std_win_error{GetLastError()};
|
||||||
|
} else {
|
||||||
|
{
|
||||||
|
constexpr DWORD _Static_size = MAX_PATH;
|
||||||
|
wchar_t _Temp_buf[_Static_size];
|
||||||
|
_Last_error = _Fs_space_attempt(_Temp_buf, _Static_size, _Target, _Available, _Total_bytes, _Free_bytes);
|
||||||
|
if (_Last_error == __std_win_error::_Success) {
|
||||||
|
return __std_win_error::_Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_Last_error == __std_win_error::_Filename_exceeds_range) {
|
||||||
|
constexpr DWORD _Dynamic_size = USHRT_MAX + 1; // assuming maximum NT path fits in a UNICODE_STRING
|
||||||
|
const auto _Temp_buf = _malloc_crt_t(wchar_t, _Dynamic_size);
|
||||||
|
if (_Temp_buf) {
|
||||||
|
_Last_error =
|
||||||
|
_Fs_space_attempt(_Temp_buf.get(), _Dynamic_size, _Target, _Available, _Total_bytes, _Free_bytes);
|
||||||
|
if (_Last_error == __std_win_error::_Success) {
|
||||||
|
return __std_win_error::_Success;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_Last_error = __std_win_error::_Not_enough_memory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*_Available = ~0ull;
|
||||||
|
*_Total_bytes = ~0ull;
|
||||||
|
*_Free_bytes = ~0ull;
|
||||||
|
return _Last_error;
|
||||||
|
}
|
||||||
|
_END_EXTERN_C
|
Загрузка…
Ссылка в новой задаче