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 #endif 46 #include <string> 47 #include <vector> 48 #include <stdint.h> 49 #ifndef __REACTOS__ 50 #include "../btrfs.h" 51 #include "../btrfsioctl.h" 52 #else 53 #include "btrfs.h" 54 #include "btrfsioctl.h" 55 #endif 56 57 using namespace std; 58 59 #ifndef __REACTOS__ 60 #define STATUS_SUCCESS (NTSTATUS)0x00000000 61 #define STATUS_BUFFER_OVERFLOW (NTSTATUS)0x80000005 62 #define STATUS_END_OF_FILE (NTSTATUS)0xc0000011 63 #define STATUS_MORE_PROCESSING_REQUIRED (NTSTATUS)0xc0000016 64 #define STATUS_BUFFER_TOO_SMALL (NTSTATUS)0xc0000023 65 #define STATUS_DEVICE_NOT_READY (NTSTATUS)0xc00000a3 66 #define STATUS_CANNOT_DELETE (NTSTATUS)0xc0000121 67 #define STATUS_NOT_FOUND (NTSTATUS)0xc0000225 68 #endif 69 70 #define BLOCK_FLAG_DATA 0x001 71 #define BLOCK_FLAG_SYSTEM 0x002 72 #define BLOCK_FLAG_METADATA 0x004 73 #define BLOCK_FLAG_RAID0 0x008 74 #define BLOCK_FLAG_RAID1 0x010 75 #define BLOCK_FLAG_DUPLICATE 0x020 76 #define BLOCK_FLAG_RAID10 0x040 77 #define BLOCK_FLAG_RAID5 0x080 78 #define BLOCK_FLAG_RAID6 0x100 79 80 #define BTRFS_TYPE_FILE 1 81 #define BTRFS_TYPE_DIRECTORY 2 82 #define BTRFS_TYPE_CHARDEV 3 83 #define BTRFS_TYPE_BLOCKDEV 4 84 #define BTRFS_TYPE_FIFO 5 85 #define BTRFS_TYPE_SOCKET 6 86 #define BTRFS_TYPE_SYMLINK 7 87 88 #ifdef _MSC_VER 89 #define funcname __FUNCTION__ 90 #else 91 #define funcname __func__ 92 #endif 93 94 #ifdef _MSC_VER 95 #pragma warning(disable: 4800) 96 #endif 97 98 #ifdef __cplusplus 99 extern "C" { 100 #endif 101 #ifndef __REACTOS__ 102 NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, 103 PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, 104 PVOID OutputBuffer, ULONG OutputBufferLength); 105 106 NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, 107 ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key); 108 #endif 109 110 NTSTATUS WINAPI RtlUTF8ToUnicodeN(PWSTR UnicodeStringDestination, ULONG UnicodeStringMaxWCharCount, 111 PULONG UnicodeStringActualWCharCount, PCCH UTF8StringSource, 112 ULONG UTF8StringByteCount); 113 114 NTSTATUS NTAPI RtlUnicodeToUTF8N(PCHAR UTF8StringDestination, ULONG UTF8StringMaxByteCount, 115 PULONG UTF8StringActualByteCount, PCWCH UnicodeStringSource, 116 ULONG UnicodeStringByteCount); 117 118 #ifndef __REACTOS__ 119 NTSTATUS WINAPI NtSetEaFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length); 120 121 NTSTATUS WINAPI NtSetSecurityObject(HANDLE Handle, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor); 122 123 NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass); 124 #ifdef __cplusplus 125 } 126 #endif 127 #else 128 BOOL 129 WINAPI 130 SetFileInformationByHandle(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize); 131 BOOL 132 WINAPI 133 GetFileInformationByHandleEx(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize); 134 #ifdef __cplusplus 135 } 136 #endif 137 #endif 138 139 #ifndef __REACTOS__ 140 typedef struct _REPARSE_DATA_BUFFER { 141 ULONG ReparseTag; 142 USHORT ReparseDataLength; 143 USHORT Reserved; 144 145 union { 146 struct { 147 USHORT SubstituteNameOffset; 148 USHORT SubstituteNameLength; 149 USHORT PrintNameOffset; 150 USHORT PrintNameLength; 151 ULONG Flags; 152 WCHAR PathBuffer[1]; 153 } SymbolicLinkReparseBuffer; 154 155 struct { 156 USHORT SubstituteNameOffset; 157 USHORT SubstituteNameLength; 158 USHORT PrintNameOffset; 159 USHORT PrintNameLength; 160 WCHAR PathBuffer[1]; 161 } MountPointReparseBuffer; 162 163 struct { 164 UCHAR DataBuffer[1]; 165 } GenericReparseBuffer; 166 }; 167 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 168 169 #define SYMLINK_FLAG_RELATIVE 1 170 #endif 171 172 #ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING 173 174 typedef struct _DUPLICATE_EXTENTS_DATA { 175 HANDLE FileHandle; 176 LARGE_INTEGER SourceFileOffset; 177 LARGE_INTEGER TargetFileOffset; 178 LARGE_INTEGER ByteCount; 179 } DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA; 180 181 #define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_ACCESS) 182 183 typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER { 184 WORD ChecksumAlgorithm; 185 WORD Reserved; 186 DWORD Flags; 187 DWORD ChecksumChunkSizeInBytes; 188 DWORD ClusterSizeInBytes; 189 } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER; 190 191 typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { 192 WORD ChecksumAlgorithm; 193 WORD Reserved; 194 DWORD Flags; 195 } FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER; 196 197 #define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS) 198 #define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) 199 200 #endif 201 202 class win_handle { 203 public: 204 win_handle() { 205 #ifdef __REACTOS__ 206 h = INVALID_HANDLE_VALUE; 207 #endif 208 } 209 210 win_handle(HANDLE nh) { 211 h = nh; 212 } 213 214 ~win_handle() { 215 if (h != INVALID_HANDLE_VALUE) 216 CloseHandle(h); 217 } 218 219 operator HANDLE() const { 220 return h; 221 } 222 223 win_handle& operator=(const HANDLE nh) { 224 if (h != INVALID_HANDLE_VALUE) 225 CloseHandle(h); 226 227 h = nh; 228 229 return *this; 230 } 231 232 HANDLE* operator&() { 233 return &h; 234 } 235 236 private: 237 #ifndef __REACTOS__ 238 HANDLE h = INVALID_HANDLE_VALUE; 239 #else 240 HANDLE h; 241 #endif 242 }; 243 244 class fff_handle { 245 public: 246 fff_handle() { 247 #ifdef __REACTOS__ 248 h = INVALID_HANDLE_VALUE; 249 #endif 250 } 251 252 fff_handle(HANDLE nh) { 253 h = nh; 254 } 255 256 ~fff_handle() { 257 if (h != INVALID_HANDLE_VALUE) 258 FindClose(h); 259 } 260 261 operator HANDLE() const { 262 return h; 263 } 264 265 fff_handle& operator=(const HANDLE nh) { 266 if (h != INVALID_HANDLE_VALUE) 267 FindClose(h); 268 269 h = nh; 270 271 return *this; 272 } 273 274 HANDLE* operator&() { 275 return &h; 276 } 277 278 private: 279 #ifndef __REACTOS__ 280 HANDLE h = INVALID_HANDLE_VALUE; 281 #else 282 HANDLE h; 283 #endif 284 }; 285 286 class nt_handle { 287 public: 288 nt_handle() { 289 #ifdef __REACTOS__ 290 h = INVALID_HANDLE_VALUE; 291 #endif 292 } 293 294 nt_handle(HANDLE nh) { 295 h = nh; 296 } 297 298 ~nt_handle() { 299 if (h != INVALID_HANDLE_VALUE) 300 NtClose(h); 301 } 302 303 operator HANDLE() const { 304 return h; 305 } 306 307 nt_handle& operator=(const HANDLE nh) { 308 if (h != INVALID_HANDLE_VALUE) 309 NtClose(h); 310 311 h = nh; 312 313 return *this; 314 } 315 316 HANDLE* operator&() { 317 return &h; 318 } 319 320 private: 321 #ifndef __REACTOS__ 322 HANDLE h = INVALID_HANDLE_VALUE; 323 #else 324 HANDLE h; 325 #endif 326 }; 327 328 class string_error : public exception { 329 public: 330 string_error(int resno, ...); 331 332 const char* what() const noexcept { 333 return msg.c_str(); 334 } 335 336 private: 337 string msg; 338 }; 339 340 341 class last_error : public exception { 342 public: 343 last_error(DWORD errnum); 344 345 const char* what() const noexcept { 346 return msg.c_str(); 347 } 348 349 private: 350 string msg; 351 }; 352 353 class ntstatus_error : public exception { 354 public: 355 ntstatus_error(NTSTATUS Status); 356 357 const char* what() const noexcept { 358 return msg.c_str(); 359 } 360 361 private: 362 string msg; 363 }; 364 365 #ifdef __REACTOS__ 366 inline wstring to_wstring(uint8_t a) { WCHAR buffer[16]; swprintf(buffer, L"%d", a); return wstring(buffer); } 367 inline wstring to_wstring(uint16_t a) { WCHAR buffer[16]; swprintf(buffer, L"%d", a); return wstring(buffer); } 368 inline wstring to_wstring(uint32_t a) { WCHAR buffer[32]; swprintf(buffer, L"%ld", a); return wstring(buffer); } 369 inline wstring to_wstring(uint64_t a) { WCHAR buffer[64]; swprintf(buffer, L"%I64d", a); return wstring(buffer); } 370 #endif 371 372 extern HMODULE module; 373 void format_size(uint64_t size, wstring& s, bool show_bytes); 374 void set_dpi_aware(); 375 wstring format_message(ULONG last_error); 376 wstring format_ntstatus(NTSTATUS Status); 377 bool load_string(HMODULE module, UINT id, wstring& s); 378 void wstring_sprintf(wstring& s, wstring fmt, ...); 379 void command_line_to_args(LPWSTR cmdline, vector<wstring> args); 380 void utf8_to_utf16(const string& utf8, wstring& utf16); 381 void utf16_to_utf8(const wstring& utf16, string& utf8); 382 void error_message(HWND hwnd, const char* msg); 383