1 /* Copyright (c) Mark Harmstone 2016-17 2 * 3 * This file is part of WinBtrfs. 4 * 5 * WinBtrfs is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public Licence as published by 7 * the Free Software Foundation, either version 3 of the Licence, or 8 * (at your option) any later version. 9 * 10 * WinBtrfs is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public Licence for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public Licence 16 * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #pragma once 19 20 /* C++ backwards-compatibility */ 21 #ifdef __REACTOS__ 22 #if defined(_MSC_VER) && (_MSC_VER < 1900) 23 #define noexcept 24 #endif 25 #endif 26 27 #define ISOLATION_AWARE_ENABLED 1 28 #define STRSAFE_NO_DEPRECATE 29 30 #ifndef __REACTOS__ 31 #define WINVER 0x0A00 // Windows 10 32 #define _WIN32_WINNT 0x0A00 33 #endif 34 35 #ifndef __REACTOS__ 36 #include <windows.h> 37 #include <winternl.h> 38 #else 39 #define WIN32_NO_STATUS 40 #include <windef.h> 41 #include <winbase.h> 42 #include <strsafe.h> 43 #include <ndk/iofuncs.h> 44 #include <ndk/obfuncs.h> 45 #include <ndk/rtlfuncs.h> 46 #endif 47 #include <string> 48 #ifdef __REACTOS__ 49 #define string_view string 50 #define wstring_view wstring 51 #endif 52 #include <vector> 53 #include <stdint.h> 54 #ifndef __REACTOS__ 55 #include "../btrfs.h" 56 #include "../btrfsioctl.h" 57 #else 58 #include "btrfs.h" 59 #include "btrfsioctl.h" 60 #endif 61 62 using namespace std; 63 64 #ifndef __REACTOS__ 65 #define STATUS_SUCCESS (NTSTATUS)0x00000000 66 #define STATUS_BUFFER_OVERFLOW (NTSTATUS)0x80000005 67 #define STATUS_END_OF_FILE (NTSTATUS)0xc0000011 68 #define STATUS_MORE_PROCESSING_REQUIRED (NTSTATUS)0xc0000016 69 #define STATUS_BUFFER_TOO_SMALL (NTSTATUS)0xc0000023 70 #define STATUS_DEVICE_NOT_READY (NTSTATUS)0xc00000a3 71 #define STATUS_CANNOT_DELETE (NTSTATUS)0xc0000121 72 #define STATUS_NOT_FOUND (NTSTATUS)0xc0000225 73 #endif 74 75 #define BLOCK_FLAG_DATA 0x001 76 #define BLOCK_FLAG_SYSTEM 0x002 77 #define BLOCK_FLAG_METADATA 0x004 78 #define BLOCK_FLAG_RAID0 0x008 79 #define BLOCK_FLAG_RAID1 0x010 80 #define BLOCK_FLAG_DUPLICATE 0x020 81 #define BLOCK_FLAG_RAID10 0x040 82 #define BLOCK_FLAG_RAID5 0x080 83 #define BLOCK_FLAG_RAID6 0x100 84 85 #define BTRFS_TYPE_FILE 1 86 #define BTRFS_TYPE_DIRECTORY 2 87 #define BTRFS_TYPE_CHARDEV 3 88 #define BTRFS_TYPE_BLOCKDEV 4 89 #define BTRFS_TYPE_FIFO 5 90 #define BTRFS_TYPE_SOCKET 6 91 #define BTRFS_TYPE_SYMLINK 7 92 93 #ifdef _MSC_VER 94 #define funcname __FUNCTION__ 95 #else 96 #define funcname __func__ 97 #endif 98 99 #ifdef _MSC_VER 100 #pragma warning(disable: 4800) 101 #endif 102 103 #ifdef __cplusplus 104 extern "C" { 105 #endif 106 #ifndef __REACTOS__ 107 NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, 108 ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key); 109 110 NTSTATUS WINAPI NtSetEaFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length); 111 112 NTSTATUS WINAPI NtSetSecurityObject(HANDLE Handle, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor); 113 114 #ifdef _MSC_VER 115 NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, 116 PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, 117 PVOID OutputBuffer, ULONG OutputBufferLength); 118 119 NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass); 120 121 NTSTATUS NTAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass); 122 123 #define FileBasicInformation (FILE_INFORMATION_CLASS)4 124 #define FileStandardInformation (FILE_INFORMATION_CLASS)5 125 #define FileDispositionInformation (FILE_INFORMATION_CLASS)13 126 #define FileEndOfFileInformation (FILE_INFORMATION_CLASS)20 127 #define FileStreamInformation (FILE_INFORMATION_CLASS)22 128 129 typedef enum _FSINFOCLASS { 130 FileFsVolumeInformation = 1, 131 FileFsLabelInformation, 132 FileFsSizeInformation, 133 FileFsDeviceInformation, 134 FileFsAttributeInformation, 135 FileFsControlInformation, 136 FileFsFullSizeInformation, 137 FileFsObjectIdInformation, 138 FileFsDriverPathInformation, 139 FileFsVolumeFlagsInformation, 140 FileFsSectorSizeInformation, 141 FileFsDataCopyInformation, 142 FileFsMetadataSizeInformation, 143 FileFsFullSizeInformationEx, 144 FileFsMaximumInformation 145 } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; 146 147 typedef struct _FILE_STREAM_INFORMATION { 148 ULONG NextEntryOffset; 149 ULONG StreamNameLength; 150 LARGE_INTEGER StreamSize; 151 LARGE_INTEGER StreamAllocationSize; 152 WCHAR StreamName[1]; 153 } FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION; 154 #endif 155 156 NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, 157 FS_INFORMATION_CLASS FsInformationClass); 158 #endif 159 #ifdef __cplusplus 160 } 161 #endif 162 163 #ifndef __REACTOS__ 164 typedef struct _REPARSE_DATA_BUFFER { 165 ULONG ReparseTag; 166 USHORT ReparseDataLength; 167 USHORT Reserved; 168 169 union { 170 struct { 171 USHORT SubstituteNameOffset; 172 USHORT SubstituteNameLength; 173 USHORT PrintNameOffset; 174 USHORT PrintNameLength; 175 ULONG Flags; 176 WCHAR PathBuffer[1]; 177 } SymbolicLinkReparseBuffer; 178 179 struct { 180 USHORT SubstituteNameOffset; 181 USHORT SubstituteNameLength; 182 USHORT PrintNameOffset; 183 USHORT PrintNameLength; 184 WCHAR PathBuffer[1]; 185 } MountPointReparseBuffer; 186 187 struct { 188 UCHAR DataBuffer[1]; 189 } GenericReparseBuffer; 190 }; 191 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 192 193 #define SYMLINK_FLAG_RELATIVE 1 194 #endif 195 196 #ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING 197 198 typedef struct _DUPLICATE_EXTENTS_DATA { 199 HANDLE FileHandle; 200 LARGE_INTEGER SourceFileOffset; 201 LARGE_INTEGER TargetFileOffset; 202 LARGE_INTEGER ByteCount; 203 } DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA; 204 205 #define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_ACCESS) 206 207 typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER { 208 WORD ChecksumAlgorithm; 209 WORD Reserved; 210 DWORD Flags; 211 DWORD ChecksumChunkSizeInBytes; 212 DWORD ClusterSizeInBytes; 213 } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER; 214 215 typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { 216 WORD ChecksumAlgorithm; 217 WORD Reserved; 218 DWORD Flags; 219 } FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER; 220 221 #define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS) 222 #define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) 223 224 #endif 225 226 class win_handle { 227 public: 228 win_handle() { 229 #ifdef __REACTOS__ 230 h = INVALID_HANDLE_VALUE; 231 #endif 232 } 233 234 win_handle(HANDLE nh) { 235 h = nh; 236 } 237 238 ~win_handle() { 239 if (h != INVALID_HANDLE_VALUE) 240 CloseHandle(h); 241 } 242 243 operator HANDLE() const { 244 return h; 245 } 246 247 win_handle& operator=(const HANDLE nh) { 248 if (h != INVALID_HANDLE_VALUE) 249 CloseHandle(h); 250 251 h = nh; 252 253 return *this; 254 } 255 256 HANDLE* operator&() { 257 return &h; 258 } 259 260 private: 261 #ifndef __REACTOS__ 262 HANDLE h = INVALID_HANDLE_VALUE; 263 #else 264 HANDLE h; 265 #endif 266 }; 267 268 class fff_handle { 269 public: 270 fff_handle() { 271 #ifdef __REACTOS__ 272 h = INVALID_HANDLE_VALUE; 273 #endif 274 } 275 276 fff_handle(HANDLE nh) { 277 h = nh; 278 } 279 280 ~fff_handle() { 281 if (h != INVALID_HANDLE_VALUE) 282 FindClose(h); 283 } 284 285 operator HANDLE() const { 286 return h; 287 } 288 289 fff_handle& operator=(const HANDLE nh) { 290 if (h != INVALID_HANDLE_VALUE) 291 FindClose(h); 292 293 h = nh; 294 295 return *this; 296 } 297 298 HANDLE* operator&() { 299 return &h; 300 } 301 302 private: 303 #ifndef __REACTOS__ 304 HANDLE h = INVALID_HANDLE_VALUE; 305 #else 306 HANDLE h; 307 #endif 308 }; 309 310 class nt_handle { 311 public: 312 nt_handle() { 313 #ifdef __REACTOS__ 314 h = INVALID_HANDLE_VALUE; 315 #endif 316 } 317 318 nt_handle(HANDLE nh) { 319 h = nh; 320 } 321 322 ~nt_handle() { 323 if (h != INVALID_HANDLE_VALUE) 324 NtClose(h); 325 } 326 327 operator HANDLE() const { 328 return h; 329 } 330 331 nt_handle& operator=(const HANDLE nh) { 332 if (h != INVALID_HANDLE_VALUE) 333 NtClose(h); 334 335 h = nh; 336 337 return *this; 338 } 339 340 HANDLE* operator&() { 341 return &h; 342 } 343 344 private: 345 #ifndef __REACTOS__ 346 HANDLE h = INVALID_HANDLE_VALUE; 347 #else 348 HANDLE h; 349 #endif 350 }; 351 352 class string_error : public exception { 353 public: 354 string_error(int resno, ...); 355 356 const char* what() const noexcept { 357 return msg.c_str(); 358 } 359 360 private: 361 string msg; 362 }; 363 364 365 class last_error : public exception { 366 public: 367 last_error(DWORD errnum); 368 369 const char* what() const noexcept { 370 return msg.c_str(); 371 } 372 373 private: 374 string msg; 375 }; 376 377 class ntstatus_error : public exception { 378 public: 379 ntstatus_error(NTSTATUS Status); 380 381 const char* what() const noexcept { 382 return msg.c_str(); 383 } 384 385 NTSTATUS Status; 386 387 private: 388 string msg; 389 }; 390 391 #ifdef __REACTOS__ 392 inline wstring to_wstring(uint8_t a) { WCHAR buffer[16]; swprintf(buffer, L"%d", a); return wstring(buffer); } 393 inline wstring to_wstring(uint16_t a) { WCHAR buffer[16]; swprintf(buffer, L"%d", a); return wstring(buffer); } 394 inline wstring to_wstring(uint32_t a) { WCHAR buffer[32]; swprintf(buffer, L"%ld", a); return wstring(buffer); } 395 inline wstring to_wstring(uint64_t a) { WCHAR buffer[64]; swprintf(buffer, L"%I64d", a); return wstring(buffer); } 396 #endif 397 398 extern HMODULE module; 399 void format_size(uint64_t size, wstring& s, bool show_bytes); 400 void set_dpi_aware(); 401 wstring format_message(ULONG last_error); 402 wstring format_ntstatus(NTSTATUS Status); 403 bool load_string(HMODULE module, UINT id, wstring& s); 404 void wstring_sprintf(wstring& s, wstring fmt, ...); 405 void command_line_to_args(LPWSTR cmdline, vector<wstring>& args); 406 wstring utf8_to_utf16(const string_view& utf8); 407 void error_message(HWND hwnd, const char* msg); 408