@@ -27,97 +27,102 @@ Distributed under the Boost Software License, Version 1.0.
27
27
#if defined(_WIN32) && _HAS_CXX20
28
28
#include " ../include/llfio/v2.0/detail/impl/windows/import.hpp"
29
29
30
- #include < variant>
30
+ namespace path_view_openat_example
31
+ {
32
+ using namespace LLFIO_V2_NAMESPACE ;
33
+ using namespace LLFIO_V2_NAMESPACE ::windows_nt_kernel;
34
+ using namespace std ;
31
35
32
- using namespace LLFIO_V2_NAMESPACE ;
33
- using namespace LLFIO_V2_NAMESPACE ::windows_nt_kernel;
34
- using namespace std ;
36
+ using LLFIO_V2_NAMESPACE::windows_nt_kernel::IO_STATUS_BLOCK;
37
+ using LLFIO_V2_NAMESPACE::windows_nt_kernel::NtCreateFile;
38
+ using LLFIO_V2_NAMESPACE::windows_nt_kernel::OBJECT_ATTRIBUTES;
39
+ using LLFIO_V2_NAMESPACE::windows_nt_kernel::UNICODE_STRING;
35
40
36
- HANDLE openat (HANDLE base, path_view path)
37
- {
38
- static constexpr DWORD access = GENERIC_READ;
39
- static constexpr DWORD share =
40
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
41
- static constexpr DWORD creation = OPEN_EXISTING;
42
- static constexpr DWORD flags = FILE_ATTRIBUTE_NORMAL;
43
- return visit (
44
- [&](auto sv) -> HANDLE
41
+ HANDLE openat (HANDLE base, path_view path)
45
42
{
46
- using type = typename decltype (sv)::value_type;
47
- if constexpr (is_same_v<type, byte>)
43
+ static constexpr DWORD access = GENERIC_READ;
44
+ static constexpr DWORD share =
45
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
46
+ static constexpr DWORD creation = OPEN_EXISTING;
47
+ static constexpr DWORD flags = FILE_ATTRIBUTE_NORMAL;
48
+ return visit (
49
+ [&](auto sv) -> HANDLE
48
50
{
49
- if (sv.size () == 16 )
51
+ using type = typename decltype (sv)::value_type;
52
+ if constexpr (is_same_v<type, byte>)
50
53
{
51
- FILE_ID_DESCRIPTOR fid{};
52
- fid.dwSize = sizeof (fid);
53
- fid.Type = 1 ;
54
- memcpy (&fid.ObjectId , sv.data (), 16 );
55
- return OpenFileById (base, &fid, access, share, nullptr , flags);
54
+ if (sv.size () == 16 )
55
+ {
56
+ FILE_ID_DESCRIPTOR fid{};
57
+ fid.dwSize = sizeof (fid);
58
+ fid.Type = 1 ;
59
+ memcpy (&fid.ObjectId , sv.data (), 16 );
60
+ return OpenFileById (base, &fid, access, share, nullptr , flags);
61
+ }
62
+ throw std::runtime_error (" binary key must be exactly 16 bytes long" );
56
63
}
57
- throw std::runtime_error (" binary key must be exactly 16 bytes long" );
58
- }
59
- // A "\!!\" or "\??\" prefix enables direct use of the NT kernel API
60
- // or setting base, as the Win32 doesn't support paths relative to a base
61
- const bool is_ntpath =
62
- sv.size () >= 4 && sv[0 ] == ' \\ ' && sv[3 ] == ' \\ ' &&
63
- ((sv[1 ] == ' !' && sv[2 ] == ' !' ) || (sv[1 ] == ' ?' && sv[2 ] == ' ?' ));
64
- if (base != nullptr || is_ntpath)
65
- {
66
- // The NT kernel always takes the system wide encoding
67
- auto zpath = path.render_unterminated <wchar_t >(path);
68
- UNICODE_STRING _path{};
69
- _path.Buffer = const_cast <wchar_t *>(zpath.data ());
70
- _path.MaximumLength =
71
- (_path.Length = static_cast <USHORT>(zpath.size () * sizeof (wchar_t ))) +
72
- sizeof (wchar_t );
73
- // The "\!!\" prefix is library local and the NT kernel doesn't
74
- // understand it, so strip it off
75
- if (zpath.size () >= 4 && _path.Buffer [0 ] == ' \\ ' &&
76
- _path.Buffer [1 ] == ' !' && _path.Buffer [2 ] == ' !' &&
77
- _path.Buffer [3 ] == ' \\ ' )
64
+ // A "\!!\" or "\??\" prefix enables direct use of the NT kernel API
65
+ // or setting base, as the Win32 API doesn't support paths relative to a
66
+ // base
67
+ const bool is_ntpath =
68
+ sv.size () >= 4 && sv[0 ] == ' \\ ' && sv[3 ] == ' \\ ' &&
69
+ ((sv[1 ] == ' !' && sv[2 ] == ' !' ) || (sv[1 ] == ' ?' && sv[2 ] == ' ?' ));
70
+ if (base != nullptr || is_ntpath)
78
71
{
79
- _path.Buffer += 3 ;
80
- _path.Length -= 3 * sizeof (wchar_t );
81
- _path.MaximumLength -= 3 * sizeof (wchar_t );
82
- }
72
+ // The NT kernel always takes the system wide encoding
73
+ auto zpath = path.render_unterminated <wchar_t >(path);
74
+ UNICODE_STRING _path{};
75
+ _path.Buffer = const_cast <wchar_t *>(zpath.data ());
76
+ _path.MaximumLength =
77
+ (_path.Length = static_cast <USHORT>(zpath.size () * sizeof (wchar_t ))) +
78
+ sizeof (wchar_t );
79
+ // The "\!!\" prefix is library local and the NT kernel doesn't
80
+ // understand it unlike "\??\", so strip it off
81
+ if (zpath.size () >= 4 && _path.Buffer [0 ] == ' \\ ' &&
82
+ _path.Buffer [1 ] == ' !' && _path.Buffer [2 ] == ' !' &&
83
+ _path.Buffer [3 ] == ' \\ ' )
84
+ {
85
+ _path.Buffer += 3 ;
86
+ _path.Length -= 3 * sizeof (wchar_t );
87
+ _path.MaximumLength -= 3 * sizeof (wchar_t );
88
+ }
83
89
84
- OBJECT_ATTRIBUTES oa{};
85
- oa.Length = sizeof (OBJECT_ATTRIBUTES);
86
- oa.ObjectName = &_path;
87
- oa.RootDirectory = base;
88
- oa.Attributes = 0 ;
90
+ OBJECT_ATTRIBUTES oa{};
91
+ oa.Length = sizeof (OBJECT_ATTRIBUTES);
92
+ oa.ObjectName = &_path;
93
+ oa.RootDirectory = base;
94
+ oa.Attributes = 0 ;
89
95
90
- IO_STATUS_BLOCK isb{};
91
- LARGE_INTEGER AllocationSize{};
92
- HANDLE ret = INVALID_HANDLE_VALUE;
93
- NTSTATUS ntstat =
94
- NtCreateFile (&ret, access, &oa, &isb, &AllocationSize, 0 , share,
95
- FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, nullptr , 0 );
96
- if (ntstat < 0 )
97
- {
98
- // Might want to call RtlNtStatusToDosError(ntstat)?
96
+ IO_STATUS_BLOCK isb{};
97
+ LARGE_INTEGER AllocationSize{};
98
+ HANDLE ret = INVALID_HANDLE_VALUE;
99
+ NTSTATUS ntstat =
100
+ NtCreateFile (&ret, access, &oa, &isb, &AllocationSize, 0 , share,
101
+ FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, nullptr , 0 );
102
+ if (ntstat < 0 )
103
+ {
104
+ // Might want to call RtlNtStatusToDosError(ntstat)?
105
+ }
106
+ return ret;
99
107
}
100
- return ret;
101
- }
102
- else
103
- {
104
108
if constexpr (is_same_v<type, char >)
105
109
{
106
110
// Render to the system narrow encoding null terminated
107
111
auto zpath = path.render_null_terminated <char >(path);
108
112
return CreateFileA (zpath.c_str (), access, share, nullptr , creation,
109
113
flags, nullptr );
110
114
}
111
- // Render to the system wide encoding null terminated
112
- auto zpath = path.render_null_terminated <wchar_t >(path);
113
- return CreateFileW (zpath.c_str (), access, share, nullptr , creation,
114
- flags, nullptr );
115
- }
116
- // Should never reach here
117
- std::terminate ();
118
- },
119
- path);
120
- }
115
+ else // char8_t, char16_t, wchar_t
116
+ {
117
+ // Render to the system wide encoding null terminated
118
+ auto zpath = path.render_null_terminated <wchar_t >(path);
119
+ return CreateFileW (zpath.c_str (), access, share, nullptr , creation,
120
+ flags, nullptr );
121
+ }
122
+ },
123
+ path);
124
+ }
125
+ } // namespace path_view_openat_example
121
126
#endif
122
127
123
128
// clang-format off
0 commit comments