From 51fbb2dcb69070222c188adc78a287189833804b Mon Sep 17 00:00:00 2001 From: MacroModel <33865334+MacroModel@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:27:47 +0800 Subject: [PATCH] support nt_linkat --- include/fast_io_hosted/filesystem/nt_at.h | 95 ++++++++++--------- include/fast_io_hosted/filesystem/win9x.h | 2 +- .../platforms/nt/nt_definitions.h | 5 +- 3 files changed, 56 insertions(+), 46 deletions(-) diff --git a/include/fast_io_hosted/filesystem/nt_at.h b/include/fast_io_hosted/filesystem/nt_at.h index 0119d3af..5f7983a0 100644 --- a/include/fast_io_hosted/filesystem/nt_at.h +++ b/include/fast_io_hosted/filesystem/nt_at.h @@ -114,47 +114,51 @@ inline void nt_renameat_impl(void *olddirhd, char16_t const *oldpath_c_str, ::st { constexpr nt_open_mode md{ .DesiredAccess = 0x00100000 | 0x0080 | 0x00010000, // SYNCHRONIZE | FILE_READ_ATTRIBUTES | DELETE - .FileAttributes = 0x80, // FILE_READ_ATTRIBUTES - .ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE - .CreateDisposition = 0x00000001, // OPEN_EXISTING => FILE_OPEN + .FileAttributes = 0x80, // FILE_READ_ATTRIBUTES + .ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE + .CreateDisposition = 0x00000001, // OPEN_EXISTING => FILE_OPEN }; - basic_nt_family_file file( + ::fast_io::basic_nt_family_file file( nt_call_callback(olddirhd, oldpath_c_str, oldpath_size, nt_create_callback{md})); - char16_t const *pth_cstr{newpath_c_str}; - ::std::uint_least32_t pth_size2{static_cast<::std::uint_least32_t>(newpath_size) * sizeof(char16_t)}; - ::fast_io::details::local_operator_new_array_ptr buffer(sizeof(::fast_io::win32::nt::file_rename_information) + pth_size2 + sizeof(char16_t)); + nt_call_callback( + newdirhd, newpath_c_str, newpath_size, + [&](void *directory_hd, win32::nt::unicode_string const *ustr) { + char16_t const *pth_cstr{ustr->Buffer}; + ::std::uint_least32_t pth_size2{ustr->Length}; + ::fast_io::details::local_operator_new_array_ptr buffer(sizeof(::fast_io::win32::nt::file_rename_information) + pth_size2 + sizeof(char16_t)); - using file_rename_information_may_alias_ptr + using file_rename_information_may_alias_ptr #if __has_cpp_attribute(__gnu__::__may_alias__) - [[__gnu__::__may_alias__]] + [[__gnu__::__may_alias__]] #endif - = file_rename_information *; - - ::fast_io::win32::nt::file_rename_information *info{reinterpret_cast(buffer.get())}; - info->ReplaceIfExists = 1; - info->RootDirectory = newdirhd; - info->FileNameLength = pth_size2; - ::fast_io::freestanding::non_overlapped_copy_n(newpath_c_str, newpath_size + 1, static_cast(info->FileName)); - - ::fast_io::win32::nt::io_status_block block; - ::std::uint_least32_t status{::fast_io::win32::nt::nt_set_information_file( - file.handle, __builtin_addressof(block), info, - static_cast<::std::uint_least32_t>(sizeof(::fast_io::win32::nt::file_rename_information) + pth_size2 + sizeof(char16_t)), file_information_class::FileRenameInformation)}; - if (status) [[unlikely]] - { - throw_nt_error(status); - } + = file_rename_information *; + + ::fast_io::win32::nt::file_rename_information *info{reinterpret_cast(buffer.get())}; + info->ReplaceIfExists = 1; + info->RootDirectory = directory_hd; + info->FileNameLength = pth_size2; + ::fast_io::freestanding::my_memcpy(info->FileName, pth_cstr, pth_size2 + sizeof(char16_t)); + + ::fast_io::win32::nt::io_status_block block; + ::std::uint_least32_t status{::fast_io::win32::nt::nt_set_information_file( + file.handle, __builtin_addressof(block), info, + static_cast<::std::uint_least32_t>(sizeof(::fast_io::win32::nt::file_rename_information) + pth_size2 + sizeof(char16_t)), file_information_class::FileRenameInformation)}; + if (status) [[unlikely]] + { + throw_nt_error(status); + } + }); } inline constexpr nt_open_mode calculate_nt_link_flag(nt_at_flags flags) noexcept { nt_open_mode mode{ - .DesiredAccess = 0x00100000 | 0x0100 | 0x0080, // SYNCHRONIZE | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES - .FileAttributes = 0x80, // FILE_READ_ATTRIBUTES - .ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE - .CreateDisposition = 0x00200000 | 0x00000020, /*OPEN_EXISTING => FILE_OPEN*/ + .DesiredAccess = 0x00100000 | 0x0080, // SYNCHRONIZE | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES + .FileAttributes = 0x80, // FILE_READ_ATTRIBUTES + .ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE + .CreateDisposition = 0x00000001, /*OPEN_EXISTING => FILE_OPEN*/ }; if ((flags & nt_at_flags::symlink_nofollow) != nt_at_flags::symlink_nofollow) { @@ -168,33 +172,38 @@ inline void nt_linkat_impl(void *olddirhd, char16_t const *oldpath_c_str, ::std: char16_t const *newpath_c_str, ::std::size_t newpath_size, nt_at_flags flags) { nt_open_mode const md{calculate_nt_link_flag(flags)}; - basic_nt_family_file<(zw ? (nt_family::zw) : (nt_family::nt)), char> file( + ::fast_io::basic_nt_family_file file( nt_call_callback(olddirhd, oldpath_c_str, oldpath_size, nt_create_callback{md})); nt_call_callback( newdirhd, newpath_c_str, newpath_size, [&](void *directory_hd, win32::nt::unicode_string const *ustr) { char16_t const *pth_cstr{ustr->Buffer}; ::std::uint_least32_t pth_size2{ustr->Length}; - ::fast_io::details::local_operator_new_array_ptr buffer(sizeof(::fast_io::win32::nt::file_link_information) + pth_size2); - ::fast_io::win32::nt::file_link_information info{.ReplaceIfExists = false, - .RootDirectory = directory_hd, - .FileNameLength = static_cast<::std::uint_least32_t>(pth_size2)}; + ::fast_io::details::local_operator_new_array_ptr buffer(sizeof(::fast_io::win32::nt::file_link_information) + pth_size2 + sizeof(char16_t)); - ::fast_io::details::my_memcpy(buffer.ptr, __builtin_addressof(info), sizeof(::fast_io::win32::nt::file_link_information)); - ::fast_io::details::my_memcpy(buffer.ptr + sizeof(::fast_io::win32::nt::file_link_information), pth_cstr, pth_size2); - - ::fast_io::win32::nt::io_status_block block; using file_link_information_may_alias_ptr #if __has_cpp_attribute(__gnu__::__may_alias__) [[__gnu__::__may_alias__]] #endif = file_link_information *; + + ::fast_io::win32::nt::file_link_information *info{reinterpret_cast(buffer.get())}; + info->ReplaceIfExists = 0; + info->RootDirectory = directory_hd; + info->FileNameLength = pth_size2; + + ::fast_io::freestanding::my_memcpy(info->FileName, pth_cstr, pth_size2 + sizeof(char16_t)); + + ::fast_io::win32::nt::io_status_block block; + ::std::uint_least32_t status{::fast_io::win32::nt::nt_set_information_file( - file.handle, __builtin_addressof(block), - reinterpret_cast(buffer.ptr), - static_cast<::std::uint_least32_t>(sizeof(info)), file_information_class::FileLinkInformation)}; - if (status) + file.handle, __builtin_addressof(block), info, + static_cast<::std::uint_least32_t>(sizeof(::fast_io::win32::nt::file_link_information) + pth_size2 + sizeof(char16_t)), file_information_class::FileLinkInformation)}; + + if (status) [[unlikely]] + { throw_nt_error(status); + } }); } @@ -364,7 +373,7 @@ template <::fast_io::constructible_to_os_c_str path_type> inline void native_fchownat(nt_at_entry, path_type &&, ::std::size_t, ::std::size_t, [[maybe_unused]] nt_at_flags flags = nt_at_flags::symlink_nofollow) { - // windows does not use POSIX user group system. stub it and it is perfectly fine. But nt_fchownat,zw_fchownat will + // windows does not use POSIX user group system. stub it and it is perfectly fine. But nt_fchownat, zw_fchownat will // not be provided since they do not exist. } diff --git a/include/fast_io_hosted/filesystem/win9x.h b/include/fast_io_hosted/filesystem/win9x.h index 29307900..3c200652 100644 --- a/include/fast_io_hosted/filesystem/win9x.h +++ b/include/fast_io_hosted/filesystem/win9x.h @@ -9,7 +9,7 @@ struct win9x_dirent ::fast_io::win9x_dir_handle d_handle{}; file_type d_type{}; - ::std::uint_least64_t d_ino{}; + [[maybe_unused]] ::std::uint_least64_t d_ino{}; ::fast_io::u8string filename{}; ~win9x_dirent() diff --git a/include/fast_io_hosted/platforms/nt/nt_definitions.h b/include/fast_io_hosted/platforms/nt/nt_definitions.h index 3ced6fa2..69542fc7 100644 --- a/include/fast_io_hosted/platforms/nt/nt_definitions.h +++ b/include/fast_io_hosted/platforms/nt/nt_definitions.h @@ -842,9 +842,10 @@ struct file_fs_volume_information struct file_link_information { - ::std::uint_least32_t ReplaceIfExists; - void *RootDirectory; + ::std::uint_least8_t ReplaceIfExists; + void* RootDirectory; ::std::uint_least32_t FileNameLength; + char16_t FileName[1]; }; struct file_rename_information