7 #include <winapi/file.hpp>
8 #include <winapi/handle.hpp>
9 #include <winapi/path.hpp>
10 #include <winapi/utf8.hpp>
21 std::wstring to_system_path(
const std::string& path) {
25 std::wstring to_system_path(
const CanonicalPath& path) {
26 return widen(R
"(\\?\)" + path.get());
29 struct CreateFileParams {
30 static CreateFileParams read() {
31 CreateFileParams params;
32 params.dwDesiredAccess = GENERIC_READ;
33 params.dwShareMode = FILE_SHARE_READ;
34 params.dwCreationDisposition = OPEN_EXISTING;
38 static CreateFileParams read_attributes() {
40 params.dwDesiredAccess = FILE_READ_ATTRIBUTES;
41 params.dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
45 static CreateFileParams write() {
46 CreateFileParams params;
47 params.dwDesiredAccess = GENERIC_WRITE;
48 params.dwShareMode = FILE_SHARE_READ;
49 params.dwCreationDisposition = OPEN_ALWAYS;
53 DWORD dwDesiredAccess = 0;
54 DWORD dwShareMode = 0;
55 DWORD dwCreationDisposition = 0;
58 CreateFileParams() =
default;
61 File open_file(
const std::wstring& path,
const CreateFileParams& params) {
62 SECURITY_ATTRIBUTES attributes;
63 std::memset(&attributes, 0,
sizeof(attributes));
64 attributes.nLength =
sizeof(attributes);
65 attributes.bInheritHandle = TRUE;
67 const auto handle = ::CreateFileW(path.c_str(),
68 params.dwDesiredAccess,
71 params.dwCreationDisposition,
72 FILE_ATTRIBUTE_NORMAL,
75 if (handle == INVALID_HANDLE_VALUE) {
76 throw error::windows(GetLastError(),
"CreateFileW");
79 return File{Handle{handle}};
82 void remove_file(
const std::wstring& path) {
83 const auto ret = ::DeleteFileW(path.c_str());
86 throw error::windows(GetLastError(),
"DeleteFileW");
93 return open_file(to_system_path(path), CreateFileParams::read());
97 return open_file(to_system_path(path), CreateFileParams::read());
101 return open_file(to_system_path(path), CreateFileParams::read_attributes());
105 return open_file(to_system_path(path), CreateFileParams::read_attributes());
109 return open_file(to_system_path(path), CreateFileParams::write());
113 return open_file(to_system_path(path), CreateFileParams::write());
117 remove_file(to_system_path(path));
121 remove_file(to_system_path(path));
127 if (!GetFileSizeEx(get(), &size))
128 throw error::windows(GetLastError(),
"GetFileSizeEx");
130 if (size.QuadPart < 0 || size.QuadPart > SIZE_MAX)
131 throw std::runtime_error{
"invalid file size"};
132 return static_cast<std::size_t
>(size.QuadPart);
135 bool operator==(
const FILE_ID_128& a,
const FILE_ID_128& b) {
136 return 0 == std::memcmp(a.Identifier, b.Identifier,
sizeof(a.Identifier));
142 if (!GetFileInformationByHandleEx(get(), FileIdInfo, &
id,
sizeof(
id)))
143 throw error::windows(GetLastError(),
"GetFileInformationByHandleEx");
Absolute, canonical path.
static File open_w(const std::string &)
static void remove(const std::string &)
static File open_read_attributes(const std::string &)
static File open_r(const std::string &)
std::size_t get_size() const
Make std::system_error work with GetLastError().