// xfilesystem_abi.h internal header (core) // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #pragma once #ifndef _XFILESYSTEM_ABI_H #define _XFILESYSTEM_ABI_H #include #if _STL_COMPILER_PREPROCESSOR #include #include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) #pragma warning(disable : _STL_DISABLED_WARNINGS) _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new inline constexpr size_t __std_fs_max_path = 260; // #define MAX_PATH 260 inline constexpr size_t __std_fs_temp_path_max = __std_fs_max_path + 1; inline constexpr long long __std_fs_file_time_epoch_adjustment = 0x19DB1DED53E8000LL; // TRANSITION, ABI enum class __std_win_error : unsigned long { _Success = 0, // #define ERROR_SUCCESS 0L _Invalid_function = 1, // #define ERROR_INVALID_FUNCTION 1L _File_not_found = 2, // #define ERROR_FILE_NOT_FOUND 2L _Path_not_found = 3, // #define ERROR_PATH_NOT_FOUND 3L _Access_denied = 5, // #define ERROR_ACCESS_DENIED 5L _Not_enough_memory = 8, // #define ERROR_NOT_ENOUGH_MEMORY 8L _No_more_files = 18, // #define ERROR_NO_MORE_FILES 18L _Sharing_violation = 32, // #define ERROR_SHARING_VIOLATION 32L _Not_supported = 50, // #define ERROR_NOT_SUPPORTED 50L _Error_bad_netpath = 53, // #define ERROR_BAD_NETPATH 53L _File_exists = 80, // #define ERROR_FILE_EXISTS 80L _Invalid_parameter = 87, // #define ERROR_INVALID_PARAMETER 87L _Insufficient_buffer = 122, // #define ERROR_INSUFFICIENT_BUFFER 122L _Invalid_name = 123, // #define ERROR_INVALID_NAME 123L _Directory_not_empty = 145, // #define ERROR_DIR_NOT_EMPTY 145L _Already_exists = 183, // #define ERROR_ALREADY_EXISTS 183L _Filename_exceeds_range = 206, // #define ERROR_FILENAME_EXCED_RANGE 206L _Directory_name_is_invalid = 267, // #define ERROR_DIRECTORY 267L _Max = ~0UL // sentinel not used by Win32 }; // FUNCTION __std_is_file_not_found #pragma warning(push) #pragma warning(disable : 4061) // enumerator not explicitly handled by switch label _NODISCARD inline bool __std_is_file_not_found(const __std_win_error _Error) noexcept { switch (_Error) { case __std_win_error::_File_not_found: case __std_win_error::_Path_not_found: case __std_win_error::_Error_bad_netpath: case __std_win_error::_Invalid_name: return true; default: return false; } } #pragma warning(pop) enum class __std_fs_dir_handle : intptr_t { _Invalid = -1 }; enum class __std_fs_file_attr : unsigned long { _Readonly = 0x00000001, // #define FILE_ATTRIBUTE_READONLY 0x00000001 _Hidden = 0x00000002, // #define FILE_ATTRIBUTE_HIDDEN 0x00000002 _System = 0x00000004, // #define FILE_ATTRIBUTE_SYSTEM 0x00000004 _Directory = 0x00000010, // #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 _Archive = 0x00000020, // #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 _Device = 0x00000040, // #define FILE_ATTRIBUTE_DEVICE 0x00000040 _Normal = 0x00000080, // #define FILE_ATTRIBUTE_NORMAL 0x00000080 _Temporary = 0x00000100, // #define FILE_ATTRIBUTE_TEMPORARY 0x00000100 _Sparse_file = 0x00000200, // #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 _Reparse_point = 0x00000400, // #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 _Invalid = 0xFFFFFFFF, // #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) }; _BITMASK_OPS(__std_fs_file_attr) enum class __std_fs_reparse_tag : unsigned long { _None = 0, _Mount_point = (0xA0000003L), // #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) _Symlink = (0xA000000CL), // #define IO_REPARSE_TAG_SYMLINK (0xA000000CL) }; struct __std_fs_filetime { // typedef struct _FILETIME { unsigned long _Low; // DWORD dwLowDateTime; unsigned long _High; // DWORD dwHighDateTime; }; // } FILETIME, *PFILETIME, *LPFILETIME; struct __std_fs_find_data { // typedef struct _WIN32_FIND_DATAW { __std_fs_file_attr _Attributes; // DWORD dwFileAttributes; __std_fs_filetime _Creation_time; // FILETIME ftCreationTime; __std_fs_filetime _Last_access_time; // FILETIME ftLastAccessTime; __std_fs_filetime _Last_write_time; // FILETIME ftLastWriteTime; unsigned long _File_size_high; // DWORD nFileSizeHigh; unsigned long _File_size_low; // DWORD nFileSizeLow; // MSDN: dwReserved0 specifies the reparse point tag if // MSDN: (dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 __std_fs_reparse_tag _Reparse_point_tag; // DWORD dwReserved0; unsigned long _Reserved1; // DWORD dwReserved1; wchar_t _File_name[__std_fs_max_path]; // _Field_z_ WCHAR cFileName[ MAX_PATH ]; wchar_t _Short_file_name[14]; // _Field_z_ WCHAR cAlternateFileName[ 14 ]; }; // } WIN32_FIND_DATAW, ... ; enum class __std_fs_stats_flags : unsigned long { _None = 0, _Follow_symlinks = 0x01, // resolve symlink _Attributes = 0x02, // read/has attributes _Reparse_tag = 0x04, // read/has reparse_tag; may not be combined with _Follow_symlinks _File_size = 0x08, // read/has file size _Link_count = 0x10, // read/has link count _Last_write_time = 0x20, // read/has last write time _All_data = _Attributes | _Reparse_tag | _File_size | _Link_count | _Last_write_time }; _BITMASK_OPS(__std_fs_stats_flags) struct __std_fs_stats { long long _Last_write_time; unsigned long long _File_size; __std_fs_file_attr _Attributes; __std_fs_reparse_tag _Reparse_point_tag; unsigned long _Link_count; __std_fs_stats_flags _Available; // which fields are available _NODISCARD __std_fs_file_attr _Symlink_hint_attributes() const noexcept { if (_Bitmask_includes(_Available, __std_fs_stats_flags::_Attributes)) { return _Attributes; } return __std_fs_file_attr::_Invalid; } }; struct __std_fs_reparse_data_buffer { // typedef struct _REPARSE_DATA_BUFFER unsigned long _Reparse_tag; unsigned short _Reparse_data_length; unsigned short _Reserved; union { struct { unsigned short _Substitute_name_offset; unsigned short _Substitute_name_length; unsigned short _Print_name_offset; unsigned short _Print_name_length; unsigned long _Flags; wchar_t _Path_buffer[1]; } _Symbolic_link_reparse_buffer; struct { unsigned short _Substitute_name_offset; unsigned short _Substitute_name_length; unsigned short _Print_name_offset; unsigned short _Print_name_length; wchar_t _Path_buffer[1]; } _Mount_point_reparse_buffer; struct { unsigned char _Data_buffer[1]; } _Generic_reparse_buffer; }; }; struct __std_ulong_and_error { unsigned long _Size; __std_win_error _Error; }; enum class __std_fs_volume_name_kind : unsigned long { _Dos = 0, // #define VOLUME_NAME_DOS 0x0 _Guid = 1, // #define VOLUME_NAME_GUID 0x1 _Nt = 2, // #define VOLUME_NAME_NT 0x2 _None = 4 // #define VOLUME_NAME_NONE 0x4 }; enum class __std_access_rights : unsigned long { _Delete = 0x00010000, // #define DELETE (0x00010000L) _File_read_attributes = 0x0080, // #define FILE_READ_ATTRIBUTES ( 0x0080 ) _File_write_attributes = 0x0100, // #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // #define READ_CONTROL (0x00020000L) // #define STANDARD_RIGHTS_WRITE (READ_CONTROL) // #define FILE_WRITE_DATA (0x0002) // #define FILE_WRITE_ATTRIBUTES (0x0100) // #define FILE_WRITE_EA (0x0010) // #define FILE_APPEND_DATA (0x0004) // #define SYNCHRONIZE (0x00100000L) // #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES // | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE) _File_generic_write = 0x00120116, }; _BITMASK_OPS(__std_access_rights) enum class __std_fs_file_flags : unsigned long { _None = 0, _Backup_semantics = 0x02000000, // #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000 _Open_reparse_point = 0x00200000, // #define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000 }; _BITMASK_OPS(__std_fs_file_flags) enum class __std_fs_file_handle : intptr_t { _Invalid = -1 }; enum class __std_code_page : unsigned int { _Utf8 = 65001 }; struct __std_fs_convert_result { int _Len; __std_win_error _Err; }; struct __std_fs_file_id { // typedef struct _FILE_ID_INFO { unsigned long long _Volume_serial_number; // ULONGLONG VolumeSerialNumber; unsigned char _Id[16]; // FILE_ID_128 FileId; }; // } FILE_ID_INFO, ...; enum class __std_fs_copy_options { _None = 0x0, _Existing_mask = 0xF, _Skip_existing = 0x1, _Overwrite_existing = 0x2, _Update_existing = 0x4, }; _BITMASK_OPS(__std_fs_copy_options) _EXTERN_C _NODISCARD __std_ulong_and_error __stdcall __std_fs_get_full_path_name(_In_z_ const wchar_t* _Source, _In_ unsigned long _Target_size, _Out_writes_z_(_Target_size) wchar_t* _Target) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_open_handle(_Out_ __std_fs_file_handle* _Handle, _In_z_ const wchar_t* _File_name, _In_ __std_access_rights _Desired_access, _In_ __std_fs_file_flags _Flags) noexcept; void __stdcall __std_fs_close_handle(__std_fs_file_handle _Handle) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_get_file_attributes_by_handle( _In_ __std_fs_file_handle _Handle, _Out_ unsigned long* _File_attributes) noexcept; _NODISCARD __std_ulong_and_error __stdcall __std_fs_get_final_path_name_by_handle(_In_ __std_fs_file_handle _Handle, _Out_writes_z_(_Target_size) wchar_t* _Target, _In_ unsigned long _Target_size, _In_ __std_fs_volume_name_kind _Flags) noexcept; struct __std_fs_copy_file_result { bool _Copied; __std_win_error _Error; }; _NODISCARD __std_fs_copy_file_result __stdcall __std_fs_copy_file( _In_z_ const wchar_t* _Source, _In_z_ const wchar_t* _Target, _In_ __std_fs_copy_options _Options) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_directory_iterator_open(_In_z_ const wchar_t* _Path_spec, _Inout_ __std_fs_dir_handle* _Handle, _Out_ __std_fs_find_data* _Results) noexcept; void __stdcall __std_fs_directory_iterator_close(_In_ __std_fs_dir_handle _Handle) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_get_stats(_In_z_ const wchar_t* _Path, _Out_ __std_fs_stats* _Stats, _In_ __std_fs_stats_flags _Flags, _In_ __std_fs_file_attr _Symlink_attribute_hint = __std_fs_file_attr::_Invalid) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_directory_iterator_advance( _In_ __std_fs_dir_handle _Handle, _Out_ __std_fs_find_data* _Results) noexcept; _NODISCARD __std_code_page __stdcall __std_fs_code_page() noexcept; _NODISCARD __std_fs_convert_result __stdcall __std_fs_convert_narrow_to_wide(_In_ __std_code_page _Code_page, _In_reads_(_Input_len) const char* _Input_str, _In_ int _Input_len, _Out_writes_opt_(_Output_len) wchar_t* _Output_str, _In_ int _Output_len) noexcept; _NODISCARD __std_fs_convert_result __stdcall __std_fs_convert_wide_to_narrow(_In_ __std_code_page _Code_page, _In_reads_(_Input_len) const wchar_t* _Input_str, _In_ int _Input_len, _Out_writes_opt_(_Output_len) char* _Output_str, _In_ int _Output_len) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_get_file_id( _Out_ __std_fs_file_id* _Id, _In_z_ const wchar_t* _Path) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_set_last_write_time( _In_ long long _Last_write_filetime, _In_z_ const wchar_t* _Path) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_change_permissions( _In_z_ const wchar_t* _Path, _In_ bool _Follow_symlinks, _In_ bool _Readonly) noexcept; _NODISCARD __std_ulong_and_error __stdcall __std_fs_get_temp_path( _Out_writes_z_(__std_fs_temp_path_max) wchar_t* _Target) noexcept; _NODISCARD __std_ulong_and_error __stdcall __std_fs_get_current_path( _In_ unsigned long _Target_size, _Out_writes_z_(_Target_size) wchar_t* _Target) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_set_current_path(_In_z_ const wchar_t* _Target) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_create_directory_symbolic_link( _In_z_ const wchar_t* _Symlink_file_name, _In_z_ const wchar_t* _Target_file_name) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_create_hard_link( _In_z_ const wchar_t* _File_name, _In_z_ const wchar_t* _Existing_file_name) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_create_symbolic_link( _In_z_ const wchar_t* _Symlink_file_name, _In_z_ const wchar_t* _Target_file_name) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_read_reparse_data_buffer(_In_ __std_fs_file_handle _Handle, _Out_writes_bytes_(_Buffer_size) void* _Buffer, _In_ unsigned long _Buffer_size) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_read_name_from_reparse_data_buffer( _In_ __std_fs_reparse_data_buffer* _Handle, _Out_ wchar_t** _Offset, _Out_ unsigned short* _Length) noexcept; struct __std_fs_create_directory_result { bool _Created; __std_win_error _Error; }; _NODISCARD __std_fs_create_directory_result __stdcall __std_fs_create_directory( _In_z_ const wchar_t* _New_directory) noexcept; struct __std_fs_remove_result { bool _Removed; __std_win_error _Error; }; _NODISCARD __std_fs_remove_result __stdcall __std_fs_remove(_In_z_ const wchar_t* _Target) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_rename( _In_z_ const wchar_t* _Source, _In_z_ const wchar_t* _Target) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_resize_file(_In_z_ const wchar_t* _Target, uintmax_t _New_size) noexcept; _NODISCARD __std_win_error __stdcall __std_fs_space(_In_z_ const wchar_t* _Target, _Out_ uintmax_t* _Available, _Out_ uintmax_t* _Total_bytes, _Out_ uintmax_t* _Free_bytes) noexcept; _END_EXTERN_C _STD_BEGIN struct _Fs_file { __std_fs_file_handle _Raw; explicit _Fs_file(void* const _Handle) : _Raw{reinterpret_cast(_Handle)} {} _Fs_file(const wchar_t* const _File_name, const __std_access_rights _Desired_access, const __std_fs_file_flags _Flags, __std_win_error* const _Err) { *_Err = __std_fs_open_handle(&_Raw, _File_name, _Desired_access, _Flags); } _Fs_file(const _Fs_file&) = delete; _Fs_file& operator=(const _Fs_file&) = delete; ~_Fs_file() { __std_fs_close_handle(_Raw); } _NODISCARD void* _Get() const { return reinterpret_cast(_Raw); } }; // FUNCTION OBJECT _Is_slash struct _Is_slash_oper { // predicate testing if input is a preferred-separator or fallback-separator _NODISCARD constexpr bool operator()( const wchar_t _Ch) const { // test if _Ch is a preferred-separator or fallback-separator return _Ch == L'\\' || _Ch == L'/'; } }; inline constexpr _Is_slash_oper _Is_slash{}; _STD_END #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) #pragma pack(pop) #endif // _STL_COMPILER_PREPROCESSOR #endif // _XFILESYSTEM_ABI_H