// xfilesystem_abi.h internal header (core) // Copyright (c) Microsoft Corporation. All rights reserved. #pragma once #ifndef _XFILESYSTEM_ABI_H #define _XFILESYSTEM_ABI_H #ifndef RC_INVOKED #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_VAR constexpr size_t __std_fs_max_path = 260; // #define MAX_PATH 260 _INLINE_VAR constexpr size_t __std_fs_temp_path_max = __std_fs_max_path + 1; _INLINE_VAR constexpr long long __std_fs_file_time_epoch_adjustment = 0x19DB1DED53E8000LL; // TRANSITION, ABI enum class __std_win_error : unsigned long { // #defines are copied unmodified from winerror.h, hence spaces in the comments. _Success = 0, // #define ERROR_SUCCESS 0L _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 _File_exists = 80, // #define ERROR_FILE_EXISTS 80L _Invalid_parameter = 87, // #define ERROR_INVALID_PARAMETER 87L _Directory_not_empty = 145, // #define ERROR_DIR_NOT_EMPTY 145L _Already_exists = 183, // #define ERROR_ALREADY_EXISTS 183L _Directory_name_is_invalid = 267, // #define ERROR_DIRECTORY 267L _Max = ~0UL // sentinel not used by Win32 }; 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 }; 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 ) }; _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; _NODISCARD __std_fs_create_directory_result __stdcall __std_fs_create_directory_template( _In_z_ const wchar_t * _Template_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_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_VAR constexpr _Is_slash_oper _Is_slash{}; _STD_END #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) #pragma pack(pop) #endif /* RC_INVOKED */ #endif /* _XFILESYSTEM_ABI_H */