2017-09-08 11:59:42 +00:00
|
|
|
/* Copyright (c) Mark Harmstone 2016-17
|
|
|
|
*
|
|
|
|
* This file is part of WinBtrfs.
|
|
|
|
*
|
|
|
|
* WinBtrfs is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public Licence as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the Licence, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* WinBtrfs is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public Licence for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public Licence
|
|
|
|
* along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
2017-11-26 13:16:29 +00:00
|
|
|
#pragma once
|
|
|
|
|
2018-12-16 16:20:37 +00:00
|
|
|
/* C++ backwards-compatibility */
|
|
|
|
#ifdef __REACTOS__
|
|
|
|
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
|
|
#define noexcept
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2017-09-08 11:59:42 +00:00
|
|
|
#define ISOLATION_AWARE_ENABLED 1
|
|
|
|
#define STRSAFE_NO_DEPRECATE
|
|
|
|
|
|
|
|
#ifndef __REACTOS__
|
|
|
|
#define WINVER 0x0A00 // Windows 10
|
|
|
|
#define _WIN32_WINNT 0x0A00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __REACTOS__
|
|
|
|
#include <windows.h>
|
|
|
|
#include <winternl.h>
|
|
|
|
#else
|
|
|
|
#define WIN32_NO_STATUS
|
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
#include <strsafe.h>
|
|
|
|
#include <ndk/iofuncs.h>
|
2018-12-16 11:04:40 +00:00
|
|
|
#include <ndk/obfuncs.h>
|
2019-11-12 20:52:16 +00:00
|
|
|
#include <ndk/rtlfuncs.h>
|
2017-09-08 11:59:42 +00:00
|
|
|
#endif
|
|
|
|
#include <string>
|
2019-11-12 20:45:49 +00:00
|
|
|
#ifdef __REACTOS__
|
|
|
|
#define string_view string
|
|
|
|
#define wstring_view wstring
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <stdint.h>
|
2017-09-08 11:59:42 +00:00
|
|
|
#ifndef __REACTOS__
|
|
|
|
#include "../btrfs.h"
|
|
|
|
#include "../btrfsioctl.h"
|
|
|
|
#else
|
|
|
|
#include "btrfs.h"
|
|
|
|
#include "btrfsioctl.h"
|
|
|
|
#endif
|
|
|
|
|
2018-12-16 11:04:40 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2017-09-08 11:59:42 +00:00
|
|
|
#ifndef __REACTOS__
|
|
|
|
#define STATUS_SUCCESS (NTSTATUS)0x00000000
|
|
|
|
#define STATUS_BUFFER_OVERFLOW (NTSTATUS)0x80000005
|
|
|
|
#define STATUS_END_OF_FILE (NTSTATUS)0xc0000011
|
|
|
|
#define STATUS_MORE_PROCESSING_REQUIRED (NTSTATUS)0xc0000016
|
|
|
|
#define STATUS_BUFFER_TOO_SMALL (NTSTATUS)0xc0000023
|
|
|
|
#define STATUS_DEVICE_NOT_READY (NTSTATUS)0xc00000a3
|
|
|
|
#define STATUS_CANNOT_DELETE (NTSTATUS)0xc0000121
|
|
|
|
#define STATUS_NOT_FOUND (NTSTATUS)0xc0000225
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define BLOCK_FLAG_DATA 0x001
|
|
|
|
#define BLOCK_FLAG_SYSTEM 0x002
|
|
|
|
#define BLOCK_FLAG_METADATA 0x004
|
|
|
|
#define BLOCK_FLAG_RAID0 0x008
|
|
|
|
#define BLOCK_FLAG_RAID1 0x010
|
|
|
|
#define BLOCK_FLAG_DUPLICATE 0x020
|
|
|
|
#define BLOCK_FLAG_RAID10 0x040
|
|
|
|
#define BLOCK_FLAG_RAID5 0x080
|
|
|
|
#define BLOCK_FLAG_RAID6 0x100
|
|
|
|
|
|
|
|
#define BTRFS_TYPE_FILE 1
|
|
|
|
#define BTRFS_TYPE_DIRECTORY 2
|
|
|
|
#define BTRFS_TYPE_CHARDEV 3
|
|
|
|
#define BTRFS_TYPE_BLOCKDEV 4
|
|
|
|
#define BTRFS_TYPE_FIFO 5
|
|
|
|
#define BTRFS_TYPE_SOCKET 6
|
|
|
|
#define BTRFS_TYPE_SYMLINK 7
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define funcname __FUNCTION__
|
|
|
|
#else
|
|
|
|
#define funcname __func__
|
|
|
|
#endif
|
|
|
|
|
2018-12-16 11:04:40 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(disable: 4800)
|
|
|
|
#endif
|
|
|
|
|
2017-09-08 11:59:42 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
#ifndef __REACTOS__
|
|
|
|
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
|
|
|
|
PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength,
|
|
|
|
PVOID OutputBuffer, ULONG OutputBufferLength);
|
|
|
|
|
|
|
|
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
|
|
|
|
ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
|
|
|
|
|
|
|
|
NTSTATUS WINAPI NtSetEaFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length);
|
|
|
|
|
|
|
|
NTSTATUS WINAPI NtSetSecurityObject(HANDLE Handle, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
|
|
|
|
|
|
|
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass);
|
2019-11-12 20:45:49 +00:00
|
|
|
|
|
|
|
NTSTATUS NTAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass);
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define FileBasicInformation (FILE_INFORMATION_CLASS)4
|
|
|
|
#define FileStandardInformation (FILE_INFORMATION_CLASS)5
|
|
|
|
#define FileDispositionInformation (FILE_INFORMATION_CLASS)13
|
|
|
|
#define FileEndOfFileInformation (FILE_INFORMATION_CLASS)20
|
|
|
|
#define FileStreamInformation (FILE_INFORMATION_CLASS)22
|
|
|
|
|
|
|
|
typedef enum _FSINFOCLASS {
|
|
|
|
FileFsVolumeInformation = 1,
|
|
|
|
FileFsLabelInformation,
|
|
|
|
FileFsSizeInformation,
|
|
|
|
FileFsDeviceInformation,
|
|
|
|
FileFsAttributeInformation,
|
|
|
|
FileFsControlInformation,
|
|
|
|
FileFsFullSizeInformation,
|
|
|
|
FileFsObjectIdInformation,
|
|
|
|
FileFsDriverPathInformation,
|
|
|
|
FileFsVolumeFlagsInformation,
|
|
|
|
FileFsSectorSizeInformation,
|
|
|
|
FileFsDataCopyInformation,
|
|
|
|
FileFsMetadataSizeInformation,
|
|
|
|
FileFsFullSizeInformationEx,
|
|
|
|
FileFsMaximumInformation
|
|
|
|
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
|
|
|
|
|
|
|
|
typedef struct _FILE_STREAM_INFORMATION {
|
|
|
|
ULONG NextEntryOffset;
|
|
|
|
ULONG StreamNameLength;
|
|
|
|
LARGE_INTEGER StreamSize;
|
|
|
|
LARGE_INTEGER StreamAllocationSize;
|
|
|
|
WCHAR StreamName[1];
|
|
|
|
} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length,
|
|
|
|
FS_INFORMATION_CLASS FsInformationClass);
|
2017-09-08 11:59:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-10-01 12:56:00 +00:00
|
|
|
#ifndef __REACTOS__
|
2017-09-08 11:59:42 +00:00
|
|
|
typedef struct _REPARSE_DATA_BUFFER {
|
|
|
|
ULONG ReparseTag;
|
|
|
|
USHORT ReparseDataLength;
|
|
|
|
USHORT Reserved;
|
|
|
|
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
USHORT SubstituteNameOffset;
|
|
|
|
USHORT SubstituteNameLength;
|
|
|
|
USHORT PrintNameOffset;
|
|
|
|
USHORT PrintNameLength;
|
|
|
|
ULONG Flags;
|
|
|
|
WCHAR PathBuffer[1];
|
|
|
|
} SymbolicLinkReparseBuffer;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
USHORT SubstituteNameOffset;
|
|
|
|
USHORT SubstituteNameLength;
|
|
|
|
USHORT PrintNameOffset;
|
|
|
|
USHORT PrintNameLength;
|
|
|
|
WCHAR PathBuffer[1];
|
|
|
|
} MountPointReparseBuffer;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
UCHAR DataBuffer[1];
|
|
|
|
} GenericReparseBuffer;
|
|
|
|
};
|
|
|
|
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
|
|
|
|
|
|
|
#define SYMLINK_FLAG_RELATIVE 1
|
2017-10-01 12:56:00 +00:00
|
|
|
#endif
|
2017-09-08 11:59:42 +00:00
|
|
|
|
|
|
|
#ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING
|
|
|
|
|
|
|
|
typedef struct _DUPLICATE_EXTENTS_DATA {
|
|
|
|
HANDLE FileHandle;
|
|
|
|
LARGE_INTEGER SourceFileOffset;
|
|
|
|
LARGE_INTEGER TargetFileOffset;
|
|
|
|
LARGE_INTEGER ByteCount;
|
|
|
|
} DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA;
|
|
|
|
|
|
|
|
#define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
|
|
|
|
|
|
|
typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER {
|
|
|
|
WORD ChecksumAlgorithm;
|
|
|
|
WORD Reserved;
|
|
|
|
DWORD Flags;
|
|
|
|
DWORD ChecksumChunkSizeInBytes;
|
|
|
|
DWORD ClusterSizeInBytes;
|
|
|
|
} FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER;
|
|
|
|
|
|
|
|
typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
|
|
|
|
WORD ChecksumAlgorithm;
|
|
|
|
WORD Reserved;
|
|
|
|
DWORD Flags;
|
|
|
|
} FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER;
|
|
|
|
|
|
|
|
#define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
|
|
#define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2018-12-16 11:04:40 +00:00
|
|
|
class win_handle {
|
|
|
|
public:
|
|
|
|
win_handle() {
|
2018-12-16 16:20:37 +00:00
|
|
|
#ifdef __REACTOS__
|
|
|
|
h = INVALID_HANDLE_VALUE;
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
win_handle(HANDLE nh) {
|
|
|
|
h = nh;
|
|
|
|
}
|
|
|
|
|
|
|
|
~win_handle() {
|
|
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle(h);
|
|
|
|
}
|
|
|
|
|
|
|
|
operator HANDLE() const {
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
win_handle& operator=(const HANDLE nh) {
|
|
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle(h);
|
|
|
|
|
|
|
|
h = nh;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
HANDLE* operator&() {
|
|
|
|
return &h;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-12-16 16:20:37 +00:00
|
|
|
#ifndef __REACTOS__
|
2018-12-16 11:04:40 +00:00
|
|
|
HANDLE h = INVALID_HANDLE_VALUE;
|
2018-12-16 16:20:37 +00:00
|
|
|
#else
|
|
|
|
HANDLE h;
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class fff_handle {
|
|
|
|
public:
|
|
|
|
fff_handle() {
|
2018-12-16 16:20:37 +00:00
|
|
|
#ifdef __REACTOS__
|
|
|
|
h = INVALID_HANDLE_VALUE;
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fff_handle(HANDLE nh) {
|
|
|
|
h = nh;
|
|
|
|
}
|
|
|
|
|
|
|
|
~fff_handle() {
|
|
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
|
|
FindClose(h);
|
|
|
|
}
|
|
|
|
|
|
|
|
operator HANDLE() const {
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
fff_handle& operator=(const HANDLE nh) {
|
|
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
|
|
FindClose(h);
|
|
|
|
|
|
|
|
h = nh;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
HANDLE* operator&() {
|
|
|
|
return &h;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-12-16 16:20:37 +00:00
|
|
|
#ifndef __REACTOS__
|
2018-12-16 11:04:40 +00:00
|
|
|
HANDLE h = INVALID_HANDLE_VALUE;
|
2018-12-16 16:20:37 +00:00
|
|
|
#else
|
|
|
|
HANDLE h;
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class nt_handle {
|
|
|
|
public:
|
|
|
|
nt_handle() {
|
2018-12-16 16:20:37 +00:00
|
|
|
#ifdef __REACTOS__
|
|
|
|
h = INVALID_HANDLE_VALUE;
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nt_handle(HANDLE nh) {
|
|
|
|
h = nh;
|
|
|
|
}
|
|
|
|
|
|
|
|
~nt_handle() {
|
|
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
|
|
NtClose(h);
|
|
|
|
}
|
|
|
|
|
|
|
|
operator HANDLE() const {
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
nt_handle& operator=(const HANDLE nh) {
|
|
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
|
|
NtClose(h);
|
|
|
|
|
|
|
|
h = nh;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
HANDLE* operator&() {
|
|
|
|
return &h;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-12-16 16:20:37 +00:00
|
|
|
#ifndef __REACTOS__
|
2018-12-16 11:04:40 +00:00
|
|
|
HANDLE h = INVALID_HANDLE_VALUE;
|
2018-12-16 16:20:37 +00:00
|
|
|
#else
|
|
|
|
HANDLE h;
|
|
|
|
#endif
|
2018-12-16 11:04:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class string_error : public exception {
|
|
|
|
public:
|
|
|
|
string_error(int resno, ...);
|
|
|
|
|
|
|
|
const char* what() const noexcept {
|
|
|
|
return msg.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
string msg;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class last_error : public exception {
|
|
|
|
public:
|
|
|
|
last_error(DWORD errnum);
|
|
|
|
|
|
|
|
const char* what() const noexcept {
|
|
|
|
return msg.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
string msg;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ntstatus_error : public exception {
|
|
|
|
public:
|
|
|
|
ntstatus_error(NTSTATUS Status);
|
|
|
|
|
|
|
|
const char* what() const noexcept {
|
|
|
|
return msg.c_str();
|
|
|
|
}
|
|
|
|
|
2019-11-12 20:45:49 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
2018-12-16 11:04:40 +00:00
|
|
|
private:
|
|
|
|
string msg;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef __REACTOS__
|
|
|
|
inline wstring to_wstring(uint8_t a) { WCHAR buffer[16]; swprintf(buffer, L"%d", a); return wstring(buffer); }
|
|
|
|
inline wstring to_wstring(uint16_t a) { WCHAR buffer[16]; swprintf(buffer, L"%d", a); return wstring(buffer); }
|
|
|
|
inline wstring to_wstring(uint32_t a) { WCHAR buffer[32]; swprintf(buffer, L"%ld", a); return wstring(buffer); }
|
|
|
|
inline wstring to_wstring(uint64_t a) { WCHAR buffer[64]; swprintf(buffer, L"%I64d", a); return wstring(buffer); }
|
|
|
|
#endif
|
|
|
|
|
2017-09-08 11:59:42 +00:00
|
|
|
extern HMODULE module;
|
2018-12-16 11:04:40 +00:00
|
|
|
void format_size(uint64_t size, wstring& s, bool show_bytes);
|
2017-09-08 11:59:42 +00:00
|
|
|
void set_dpi_aware();
|
2018-12-16 11:04:40 +00:00
|
|
|
wstring format_message(ULONG last_error);
|
|
|
|
wstring format_ntstatus(NTSTATUS Status);
|
|
|
|
bool load_string(HMODULE module, UINT id, wstring& s);
|
|
|
|
void wstring_sprintf(wstring& s, wstring fmt, ...);
|
2019-11-12 20:45:49 +00:00
|
|
|
void command_line_to_args(LPWSTR cmdline, vector<wstring>& args);
|
|
|
|
wstring utf8_to_utf16(const string_view& utf8);
|
2018-12-16 11:04:40 +00:00
|
|
|
void error_message(HWND hwnd, const char* msg);
|