Skip to content

Commit

Permalink
unfinished: nt pipe
Browse files Browse the repository at this point in the history
  • Loading branch information
MacroModel committed Nov 13, 2024
1 parent de98b15 commit b32b70a
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 27 deletions.
45 changes: 44 additions & 1 deletion include/fast_io_core_impl/allocation/nt_rtlheapalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ inline peb *nt_get_current_peb() noexcept
#endif
#elif defined(_MSC_VER)
#if defined(_M_ARM64) || defined(_M_ARM64EC)
return reinterpret_cast<::fast_io::win32::nt::teb *>(::fast_io::intrinsics::msvc::arm::__getReg(18))->ProcessEnvironmentBlock;
return reinterpret_cast<::fast_io::win32::nt::peb *>(::fast_io::intrinsics::msvc::arm::__getReg(18))->ProcessEnvironmentBlock;
#elif defined(_M_AMD64)
return reinterpret_cast<::fast_io::win32::nt::peb *>(::fast_io::intrinsics::msvc::x86::__readgsqword(0x60));
#elif defined(_M_IX86)
Expand All @@ -241,6 +241,49 @@ inline peb *nt_get_current_peb() noexcept
#endif
}

#if __has_cpp_attribute(__gnu__::__const__)
[[__gnu__::__const__]]
#endif
inline teb *nt_current_teb() noexcept
{
#if (defined(__GNUC__) || defined(__clang__))
#if defined(__aarch64__) || defined(__arm64ec__)
return ::fast_io::win32::nt::fast_io_nt_current_teb;
#elif defined(__i386__) || defined(__x86_64__)
if constexpr (sizeof(::std::size_t) == sizeof(::std::uint_least64_t))
{
teb *pteb;
__asm__("{movq\t%%gs:0x48, %0|mov\t%0, %%gs:[0x48]}" : "=r"(pteb));
return pteb;
}
else if constexpr (sizeof(::std::size_t) == sizeof(::std::uint_least32_t))
{
teb *pteb;
__asm__("{movl\t%%fs:0x48, %0|mov\t%0, %%fs:[0x48]}" : "=r"(pteb));
return pteb;
}
else
{
::fast_io::fast_terminate();
}
#else
::fast_io::fast_terminate();
#endif
#elif defined(_MSC_VER)
#if defined(_M_ARM64) || defined(_M_ARM64EC)
return reinterpret_cast<::fast_io::win32::nt::teb *>(::fast_io::intrinsics::msvc::arm::__getReg(18));
#elif defined(_M_AMD64)
return reinterpret_cast<::fast_io::win32::nt::teb *>(::fast_io::intrinsics::msvc::x86::__readgsqword(48));
#elif defined(_M_IX86)
return reinterpret_cast<::fast_io::win32::nt::teb *>(::fast_io::intrinsics::msvc::x86::__readfsdword(24));
#else
return reinterpret_cast<::fast_io::win32::nt::teb *>(::fast_io::intrinsics::msvc::arm::_MoveFromCoprocessor(15, 0, 13, 0, 2));
#endif
#else
::fast_io::fast_terminate();
#endif
}

#if __has_cpp_attribute(__gnu__::__always_inline__)
[[__gnu__::__always_inline__]]
#elif __has_cpp_attribute(msvc::forceinline)
Expand Down
4 changes: 3 additions & 1 deletion include/fast_io_core_impl/intrinsics/msvc/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace fast_io::intrinsics::msvc::arm
extern "C"
{
unsigned __int64 __getReg(int);

unsigned int _MoveFromCoprocessor(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int);
}

} // namespace fast_io::intrinsics::msvc::arm
} // namespace fast_io::intrinsics::msvc::arm
1 change: 1 addition & 0 deletions include/fast_io_hosted/platforms/native_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ inline constexpr ::std::uint_least32_t win32_stderr_number(static_cast<::std::ui

} // namespace fast_io
#include "win32_code.h"
#include "win32_io_redirection.h"
#include "nt/impl.h"
#include "win32_error.h"

Expand Down
91 changes: 87 additions & 4 deletions include/fast_io_hosted/platforms/nt.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ inline constexpr nt_open_mode calculate_nt_open_mode(open_mode_perms ompm) noexc
nt_open_mode mode;

constexpr auto default_write_attribute{0x00020000L /*READ_CONTROL*/ | 0x0002 /*FILE_WRITE_DATA*/ | 0x0004 /*FILE_APPEND_DATA*/};
constexpr auto default_read_attribute{0x00020000L/*READ_CONTROL*/ | 0x0001 /*FILE_READ_DATA*/};
constexpr auto default_read_attribute{0x00020000L /*READ_CONTROL*/ | 0x0001 /*FILE_READ_DATA*/};

mode.DesiredAccess |= 0x00100000L /*SYNCHRONIZE*/ | 0x0080 /*FILE_READ_ATTRIBUTES*/;

Expand All @@ -97,12 +97,12 @@ inline constexpr nt_open_mode calculate_nt_open_mode(open_mode_perms ompm) noexc
}
else if ((value & open_mode::out) != open_mode::none)
{
mode.DesiredAccess |= default_write_attribute;
mode.DesiredAccess |= default_write_attribute;
generic_write = true;
}
if (((value & open_mode::in) != open_mode::none) || ((value & open_mode::app) != open_mode::none))
{
mode.DesiredAccess |= default_read_attribute;
mode.DesiredAccess |= default_read_attribute;
if ((value & open_mode::out) != open_mode::none &&
((value & open_mode::app) != open_mode::none && (value & open_mode::trunc) != open_mode::none))
{
Expand Down Expand Up @@ -257,7 +257,7 @@ inline constexpr nt_open_mode calculate_nt_open_mode(open_mode_perms ompm) noexc
if (mode.CreateDisposition == 0)
{
mode.DesiredAccess |= default_read_attribute; // FILE_GENERIC_READ
mode.CreateDisposition = 0x00000001; // OPEN_EXISTING
mode.CreateDisposition = 0x00000001; // OPEN_EXISTING
}
mode.CreateOptions |= 0x00004000; // FILE_OPEN_FOR_BACKUP_INTENT
mode.CreateOptions |= 0x00000001; // FILE_DIRECTORY_FILE
Expand Down Expand Up @@ -1420,26 +1420,101 @@ class basic_nt_family_file : public basic_nt_family_io_observer<family, ch_type>
}
};

namespace win32::nt::details
{
template <bool zw>
inline void nt_create_pipe(void **hReadPipe, void **hWritePipe)
{
constexpr ::std::size_t size_of_buffer{64};
char16_t buffer[size_of_buffer];
::fast_io::u16obuffer_view buf_view{buffer, buffer + size_of_buffer};
//auto peb{::fast_io::win32::nt::nt_get_current_peb()};
//auto uniprocess{peb->ClientId.UniqueProcess};
}
} // namespace win32::nt::details

template <nt_family family, ::std::integral ch_type>
class basic_nt_family_pipe
{
public:
using char_type = ch_type;
basic_nt_family_file<family, ch_type> pipes[2];
basic_nt_family_pipe()
{
win32::nt::details::nt_create_pipe(__builtin_addressof(pipes[0].handle), __builtin_addressof(pipes[1].handle));
}
constexpr auto &in() noexcept
{
return *pipes;
}
constexpr auto &out() noexcept
{
return pipes[1];
}
};

template <nt_family family, ::std::integral ch_type>
inline constexpr win32_io_redirection redirect(basic_nt_family_pipe<family, ch_type> &hd)
{
return {.win32_pipe_in_handle = hd.in().handle, .win32_pipe_out_handle = hd.out().handle};
}

template <nt_family family, ::std::integral ch_type>
inline constexpr basic_nt_family_io_observer<family, ch_type>
input_stream_ref_define(basic_nt_family_pipe<family, ch_type> &pp) noexcept
{
return {pp.in().handle};
}

template <nt_family family, ::std::integral ch_type>
inline constexpr basic_nt_family_io_observer<family, char>
input_bytes_stream_ref_define(basic_nt_family_pipe<family, ch_type> &pp) noexcept
{
return {pp.in().handle};
}

template <nt_family family, ::std::integral ch_type>
inline constexpr basic_nt_family_io_observer<family, ch_type>
output_stream_ref_define(basic_nt_family_pipe<family, ch_type> &pp) noexcept
{
return {pp.out().handle};
}

template <nt_family family, ::std::integral ch_type>
inline constexpr basic_nt_family_io_observer<family, char>
output_bytes_stream_ref_define(basic_nt_family_pipe<family, ch_type> &pp) noexcept
{
return {pp.out().handle};
}

template <::std::integral char_type>
using basic_nt_io_observer = basic_nt_family_io_observer<nt_family::nt, char_type>;

template <::std::integral char_type>
using basic_nt_file = basic_nt_family_file<nt_family::nt, char_type>;

template <::std::integral char_type>
using basic_nt_pipe = basic_nt_family_pipe<nt_family::nt, char_type>;

using nt_io_observer = basic_nt_io_observer<char>;
using nt_file = basic_nt_file<char>;
using nt_pipe = basic_nt_pipe<char>;

using wnt_io_observer = basic_nt_io_observer<wchar_t>;
using wnt_file = basic_nt_file<wchar_t>;
using wnt_pipe = basic_nt_pipe<wchar_t>;

using u8nt_io_observer = basic_nt_io_observer<char8_t>;
using u8nt_file = basic_nt_file<char8_t>;
using u8nt_pipe = basic_nt_pipe<char8_t>;

using u16nt_io_observer = basic_nt_io_observer<char16_t>;
using u16nt_file = basic_nt_file<char16_t>;
using u16nt_pipe = basic_nt_pipe<char16_t>;

using u32nt_io_observer = basic_nt_io_observer<char32_t>;
using u32nt_file = basic_nt_file<char32_t>;
using u32nt_pipe = basic_nt_pipe<char32_t>;

namespace details
{
Expand Down Expand Up @@ -1494,20 +1569,28 @@ using basic_zw_io_observer = basic_nt_family_io_observer<nt_family::zw, char_typ
template <::std::integral char_type>
using basic_zw_file = basic_nt_family_file<nt_family::zw, char_type>;

template <::std::integral char_type>
using basic_zw_pipe = basic_nt_family_pipe<nt_family::zw, char_type>;

using zw_io_observer = basic_zw_io_observer<char>;
using zw_file = basic_zw_file<char>;
using zw_pipe = basic_zw_pipe<char>;

using wzw_io_observer = basic_zw_io_observer<wchar_t>;
using wzw_file = basic_zw_file<wchar_t>;
using wzw_pipe = basic_zw_pipe<wchar_t>;

using u8zw_io_observer = basic_zw_io_observer<char8_t>;
using u8zw_file = basic_zw_file<char8_t>;
using u8zw_pipe = basic_zw_pipe<char8_t>;

using u16zw_io_observer = basic_zw_io_observer<char16_t>;
using u16zw_file = basic_zw_file<char16_t>;
using u16zw_pipe = basic_zw_pipe<char16_t>;

using u32zw_io_observer = basic_zw_io_observer<char32_t>;
using u32zw_file = basic_zw_file<char32_t>;
using u32zw_pipe = basic_zw_pipe<char32_t>;

template <::std::integral char_type = char>
inline basic_zw_io_observer<char_type> zw_stdin() noexcept
Expand Down
69 changes: 69 additions & 0 deletions include/fast_io_hosted/platforms/nt/nt_linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -2650,5 +2650,74 @@ inline ::std::uint_least32_t nt_fs_control_file(Args... args) noexcept
}
}

#if defined(_MSC_VER) && !defined(__clang__)
__declspec(dllimport)
#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__))
[[__gnu__::__dllimport__]]
#endif
#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__))
[[__gnu__::__stdcall__]]
#endif
extern ::std::uint_least32_t
#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER)
__stdcall
#endif
NtCreateNamedPipeFile(void **__restrict, ::std::uint_least32_t, object_attributes *__restrict, io_status_block *__restrict,
::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least8_t, ::std::uint_least8_t,
::std::uint_least8_t, ::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least64_t*) noexcept
#if defined(__clang__) || defined(__GNUC__)
#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__))
#if !defined(__clang__)
__asm__("NtCreateNamedPipeFile@56")
#else
__asm__("_NtCreateNamedPipeFile@56")
#endif
#else
__asm__("NtCreateNamedPipeFile")
#endif
#endif
;

#if defined(_MSC_VER) && !defined(__clang__)
__declspec(dllimport)
#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__))
[[__gnu__::__dllimport__]]
#endif
#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__))
[[__gnu__::__stdcall__]]
#endif
extern ::std::uint_least32_t
#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER)
__stdcall
#endif
ZwCreateNamedPipeFile(void **__restrict, ::std::uint_least32_t, object_attributes *__restrict, io_status_block *__restrict,
::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least8_t, ::std::uint_least8_t,
::std::uint_least8_t, ::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least32_t, ::std::uint_least64_t *) noexcept
#if defined(__clang__) || defined(__GNUC__)
#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__))
#if !defined(__clang__)
__asm__("ZwCreateNamedPipeFile@56")
#else
__asm__("_ZwCreateNamedPipeFile@56")
#endif
#else
__asm__("ZwCreateNamedPipeFile")
#endif
#endif
;

template <bool zw, typename... Args>
requires(sizeof...(Args) == 14)
inline ::std::uint_least32_t nt_create_named_pipe_file(Args... args) noexcept
{
if constexpr (zw)
{
return ZwCreateNamedPipeFile(args...);
}
else
{
return NtCreateNamedPipeFile(args...);
}
}

} // namespace fast_io::win32::nt
8 changes: 3 additions & 5 deletions include/fast_io_hosted/platforms/posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -1399,14 +1399,12 @@ inline constexpr basic_posix_family_io_observer<family, char> output_bytes_strea
}

#if (defined(_WIN32) && !defined(__WINE__) && !defined(__BIONIC__)) && !defined(__CYGWIN__)
#if 0
template<::fast_io::posix_family family, ::std::integral ch_type>
inline ::fast_io::freestanding::array<int*,2> redirect_handle(basic_posix_family_pipe<family,ch_type>& h)
template <::fast_io::posix_family family, ::std::integral ch_type>
inline constexpr win32_io_redirection redirect_handle(basic_posix_family_pipe<family, ch_type> &h)
{
return {__builtin_addressof(h.in().fd),
__builtin_addressof(h.out().fd)};
__builtin_addressof(h.out().fd)};
}
#endif
#else
template <::fast_io::posix_family family, ::std::integral ch_type>
inline constexpr posix_io_redirection redirect(basic_posix_family_pipe<family, ch_type> &h) noexcept
Expand Down
22 changes: 6 additions & 16 deletions include/fast_io_hosted/platforms/win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,14 +544,6 @@ inline void *win32_create_file_at_fs_dirent_impl(void *directory_handle, char_ty
}
} // namespace details

struct win32_io_redirection
{
void *win32_pipe_in_handle{};
void *win32_pipe_out_handle{};
void *win32_handle{};
bool is_dev_null{};
};

struct win32_io_redirection_std : win32_io_redirection
{
constexpr win32_io_redirection_std() noexcept = default;
Expand Down Expand Up @@ -1696,29 +1688,27 @@ class basic_win32_family_pipe
basic_win32_family_pipe()
{
win32::security_attributes sec_attr{sizeof(win32::security_attributes), nullptr, true};
if (!::fast_io::win32::CreatePipe(__builtin_addressof(pipes.front().handle),
__builtin_addressof(pipes.back().handle), __builtin_addressof(sec_attr), 0))
if (!::fast_io::win32::CreatePipe(__builtin_addressof(pipes[0].handle),
__builtin_addressof(pipes[1].handle), __builtin_addressof(sec_attr), 0))
{
throw_win32_error();
}
}
constexpr auto &in() noexcept
{
return *pipes;
return pipes[0];
}
constexpr auto &out() noexcept
{
return pipes[1];
}
};

#if 0
template<win32_family family,::std::integral ch_type>
inline ::fast_io::freestanding::array<void*,2> redirect(basic_win32_family_pipe<family,ch_type>& hd)
template <win32_family family, ::std::integral ch_type>
inline constexpr win32_io_redirection redirect(basic_win32_family_pipe<family, ch_type> &hd)
{
return {hd.in().handle,hd.out().handle};
return {.win32_pipe_in_handle = hd.in().handle, .win32_pipe_out_handle = hd.out().handle};
}
#endif

template <win32_family family, ::std::integral ch_type>
inline void clear_screen(basic_win32_family_io_observer<family, ch_type> wiob)
Expand Down
2 changes: 2 additions & 0 deletions include/fast_io_hosted/platforms/win32/msvc_linker_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@
#pragma comment(linker,"/alternatename:__imp_?ZwQueryVolumeInformationFile@nt@win32@fast_io@@YAIPIAXPIAUio_status_block@123@0IW4fs_information_class@123@@Z=__imp_ZwQueryVolumeInformationFile")
#pragma comment(linker,"/alternatename:__imp_?NtFsControlFile@nt@win32@fast_io@@YAIPIAX0PIAP6AXPAXPAUio_status_block@123@I@_E12I1I1I@Z=__imp_NtFsControlFile")
#pragma comment(linker,"/alternatename:__imp_?ZwFsControlFile@nt@win32@fast_io@@YAIPIAX0PIAP6AXPAXPAUio_status_block@123@I@_E12I1I1I@Z=__imp_ZwFsControlFile")
#pragma comment(linker,"/alternatename:__imp_?NtCreateNamedPipeFile@nt@win32@fast_io@@YAIPIAPAXIPIAUobject_attributes@123@PIAUio_status_block@123@IIIEEEIIIPA_K@Z=__imp_NtCreateNamedPipeFile")
#pragma comment(linker,"/alternatename:__imp_?ZwCreateNamedPipeFile@nt@win32@fast_io@@YAIPIAPAXIPIAUobject_attributes@123@PIAUio_status_block@123@IIIEEEIIIPA_K@Z=__imp_ZwCreateNamedPipeFile")
//msvc
#pragma comment(linker,"/alternatename:__imp_?msvc__RTtypeid@msvc@fast_io@@YAPAXPAX@Z=__imp___RTtypeid")
#pragma comment(linker,"/alternatename:?msvc__RTtypeid@msvc@fast_io@@YAPAXPAX@Z=__RTtypeid")
Expand Down
Loading

0 comments on commit b32b70a

Please sign in to comment.