[SHELLBTRFS] Upgrade to 1.1

CORE-15452
This commit is contained in:
Pierre Schweitzer 2018-12-16 12:04:40 +01:00
parent eb7fbc253f
commit 7b718d3627
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
24 changed files with 5979 additions and 6482 deletions

View file

@ -3,6 +3,10 @@ set_cpp(WITH_RUNTIME WITH_EXCEPTIONS WITH_STL)
remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x603)
if(NOT MSVC)
add_compile_flags_language("-std=c++11" "CXX")
endif()
include_directories(${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs)
spec2def(shellbtrfs.dll shellbtrfs.spec)

File diff suppressed because it is too large Load diff

View file

@ -26,12 +26,12 @@
class BtrfsBalance {
public:
BtrfsBalance(WCHAR* drive, BOOL RemoveDevice = FALSE, BOOL ShrinkDevice = FALSE) {
removing = FALSE;
devices = NULL;
BtrfsBalance(const wstring& drive, bool RemoveDevice = false, bool ShrinkDevice = false) {
removing = false;
devices = nullptr;
called_from_RemoveDevice = RemoveDevice;
called_from_ShrinkDevice = ShrinkDevice;
wcscpy(fn, drive);
fn = drive;
}
void ShowBalance(HWND hwndDlg);
@ -39,22 +39,22 @@ public:
INT_PTR CALLBACK BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
void ShowBalanceOptions(HWND hwndDlg, UINT8 type);
void ShowBalanceOptions(HWND hwndDlg, uint8_t type);
void SaveBalanceOpts(HWND hwndDlg);
void StartBalance(HWND hwndDlg);
void RefreshBalanceDlg(HWND hwndDlg, BOOL first);
void RefreshBalanceDlg(HWND hwndDlg, bool first);
void PauseBalance(HWND hwndDlg);
void StopBalance(HWND hwndDlg);
UINT32 balance_status;
uint32_t balance_status;
btrfs_balance_opts data_opts, metadata_opts, system_opts;
UINT8 opts_type;
uint8_t opts_type;
btrfs_query_balance bqb;
BOOL cancelling;
BOOL removing;
BOOL shrinking;
WCHAR fn[MAX_PATH];
bool cancelling;
bool removing;
bool shrinking;
wstring fn;
btrfs_device* devices;
BOOL readonly;
BOOL called_from_RemoveDevice, called_from_ShrinkDevice;
bool readonly;
bool called_from_RemoveDevice, called_from_ShrinkDevice;
};

File diff suppressed because it is too large Load diff

View file

@ -25,10 +25,10 @@ class BtrfsContextMenu : public IShellExtInit, IContextMenu {
public:
BtrfsContextMenu() {
refcount = 0;
ignore = TRUE;
stgm_set = FALSE;
uacicon = NULL;
allow_snapshot = FALSE;
ignore = true;
stgm_set = false;
uacicon = nullptr;
allow_snapshot = false;
InterlockedIncrement(&objs_loaded);
}
@ -73,13 +73,13 @@ public:
private:
LONG refcount;
BOOL ignore, allow_snapshot;
BOOL bg;
WCHAR path[MAX_PATH];
bool ignore, allow_snapshot;
bool bg;
wstring path;
STGMEDIUM stgm;
BOOL stgm_set;
bool stgm_set;
HBITMAP uacicon;
BOOL reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir);
void reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir);
void get_uac_icon();
};

File diff suppressed because it is too large Load diff

View file

@ -28,8 +28,6 @@
#include <ndk/iotypes.h>
#endif
#include <shlobj.h>
#include <vector>
#include <string>
#ifndef __REACTOS__
#include "../btrfsioctl.h"
#else
@ -37,27 +35,27 @@
#endif
typedef struct {
std::wstring pnp_name;
std::wstring friendly_name;
std::wstring drive;
std::wstring fstype;
wstring pnp_name;
wstring friendly_name;
wstring drive;
wstring fstype;
ULONG disk_num;
ULONG part_num;
UINT64 size;
BOOL has_parts;
uint64_t size;
bool has_parts;
BTRFS_UUID fs_uuid;
BTRFS_UUID dev_uuid;
BOOL ignore;
BOOL multi_device;
BOOL is_disk;
bool ignore;
bool multi_device;
bool is_disk;
} device;
typedef struct {
const WCHAR* name;
const char* magic;
ULONG magiclen;
UINT32 sboff;
UINT32 kboff;
uint32_t sboff;
uint32_t kboff;
} fs_identifier;
// This list is compiled from information in libblkid, part of util-linux
@ -135,7 +133,7 @@ const static fs_identifier fs_ident[] = {
{ L"FAT", "\353", 1, 0, 0 },
{ L"FAT", "\351", 1, 0, 0},
{ L"FAT", "\125\252", 2, 0x1fe, 0 },
{ NULL, 0, 0, 0 }
{ nullptr, 0, 0, 0 }
};
class BtrfsDeviceAdd {
@ -152,18 +150,19 @@ private:
HWND hwnd;
WCHAR* cmdline;
device* sel;
std::vector<device> device_list;
vector<device> device_list;
};
class BtrfsDeviceResize {
public:
INT_PTR CALLBACK DeviceResizeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void ShowDialog(HWND hwnd, WCHAR* fn, UINT64 dev_id);
void ShowDialog(HWND hwnd, const wstring& fn, uint64_t dev_id);
private:
void do_resize(HWND hwndDlg);
UINT64 dev_id, new_size;
WCHAR fn[MAX_PATH], new_size_text[255];
uint64_t dev_id, new_size;
wstring fn;
WCHAR new_size_text[255];
btrfs_device dev_info;
};

View file

@ -27,7 +27,7 @@ HRESULT __stdcall Factory::QueryInterface(const IID& iid, void** ppv) {
if (iid == IID_IUnknown || iid == IID_IClassFactory) {
*ppv = static_cast<IClassFactory*>(this);
} else {
*ppv = NULL;
*ppv = nullptr;
return E_NOINTERFACE;
}
@ -89,6 +89,6 @@ HRESULT __stdcall Factory::CreateInstance(IUnknown* pUnknownOuter, const IID& ii
break;
}
*ppv = NULL;
*ppv = nullptr;
return E_NOINTERFACE;
}

View file

@ -39,17 +39,16 @@ HRESULT __stdcall BtrfsIconOverlay::QueryInterface(REFIID riid, void **ppObj) {
return S_OK;
}
*ppObj = NULL;
*ppObj = nullptr;
return E_NOINTERFACE;
}
HRESULT __stdcall BtrfsIconOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int* pIndex, DWORD* pdwFlags) {
WCHAR dllpath[MAX_PATH];
if (GetModuleFileNameW(module, pwszIconFile, cchMax) == 0)
return E_FAIL;
GetModuleFileNameW(module, dllpath, sizeof(dllpath));
if ((size_t)cchMax < wcslen(dllpath))
return E_INVALIDARG;
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
return E_FAIL;
if (!pIndex)
return E_INVALIDARG;
@ -57,7 +56,6 @@ HRESULT __stdcall BtrfsIconOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMa
if (!pdwFlags)
return E_INVALIDARG;
wcscpy(pwszIconFile, dllpath);
*pIndex = 0;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
@ -74,24 +72,20 @@ HRESULT __stdcall BtrfsIconOverlay::GetPriority(int *pPriority) {
}
HRESULT __stdcall BtrfsIconOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib) {
HANDLE h;
win_handle h;
NTSTATUS Status;
IO_STATUS_BLOCK iosb;
btrfs_get_file_ids bgfi;
h = CreateFileW(pwszPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
h = CreateFileW(pwszPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
if (h == INVALID_HANDLE_VALUE)
return S_FALSE;
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_FILE_IDS, NULL, 0, &bgfi, sizeof(btrfs_get_file_ids));
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_FILE_IDS, nullptr, 0, &bgfi, sizeof(btrfs_get_file_ids));
if (!NT_SUCCESS(Status)) {
CloseHandle(h);
if (!NT_SUCCESS(Status))
return S_FALSE;
}
CloseHandle(h);
return (bgfi.inode == 0x100 && !bgfi.top) ? S_OK : S_FALSE;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,6 @@
#include <shlobj.h>
#include <deque>
#include <string>
#ifndef __REACTOS__
#include "../btrfsioctl.h"
#else
@ -93,25 +92,27 @@ class BtrfsPropSheet : public IShellExtInit, IShellPropSheetExt {
public:
BtrfsPropSheet() {
refcount = 0;
ignore = TRUE;
stgm_set = FALSE;
readonly = FALSE;
flags_changed = FALSE;
perms_changed = FALSE;
uid_changed = FALSE;
gid_changed = FALSE;
compress_type_changed = FALSE;
ro_changed = FALSE;
can_change_perms = FALSE;
show_admin_button = FALSE;
thread = NULL;
ignore = true;
stgm_set = false;
readonly = false;
flags_changed = false;
perms_changed = false;
uid_changed = false;
gid_changed = false;
compress_type_changed = false;
ro_changed = false;
can_change_perms = false;
show_admin_button = false;
thread = nullptr;
mode = mode_set = 0;
flags = flags_set = 0;
has_subvols = FALSE;
has_subvols = false;
filename = L"";
sizes[0] = sizes[1] = sizes[2] = sizes[3] = 0;
totalsize = 0;
sizes[0] = sizes[1] = sizes[2] = sizes[3] = sizes[4] = 0;
totalsize = allocsize = sparsesize = 0;
size_format[0] = 0;
cr_format[0] = 0;
InterlockedIncrement(&objs_loaded);
}
@ -152,43 +153,42 @@ public:
virtual HRESULT __stdcall ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
void init_propsheet(HWND hwndDlg);
void change_inode_flag(HWND hDlg, UINT64 flag, UINT state);
void change_inode_flag(HWND hDlg, uint64_t flag, UINT state);
void change_perm_flag(HWND hDlg, ULONG perm, UINT state);
void change_uid(HWND hDlg, UINT32 uid);
void change_gid(HWND hDlg, UINT32 gid);
void change_uid(HWND hDlg, uint32_t uid);
void change_gid(HWND hDlg, uint32_t gid);
void apply_changes(HWND hDlg);
void set_size_on_disk(HWND hwndDlg);
void add_to_search_list(WCHAR* fn);
DWORD search_list_thread();
void do_search(WCHAR* fn);
void do_search(const wstring& fn);
void update_size_details_dialog(HWND hDlg);
void open_as_admin(HWND hwndDlg);
void set_cmdline(std::wstring cmdline);
void set_cmdline(const wstring& cmdline);
BOOL readonly;
BOOL can_change_perms;
BOOL can_change_nocow;
WCHAR size_format[255];
bool readonly;
bool can_change_perms;
bool can_change_nocow;
WCHAR size_format[255], cr_format[255];
HANDLE thread;
UINT32 min_mode, max_mode, mode, mode_set;
UINT64 min_flags, max_flags, flags, flags_set;
UINT64 subvol, inode, rdev;
UINT8 type, min_compression_type, max_compression_type, compress_type;
UINT32 uid, gid;
BOOL various_subvols, various_inodes, various_types, various_uids, various_gids, compress_type_changed, has_subvols,
uint32_t min_mode, max_mode, mode, mode_set;
uint64_t min_flags, max_flags, flags, flags_set;
uint64_t subvol, inode, rdev;
uint8_t type, min_compression_type, max_compression_type, compress_type;
uint32_t uid, gid;
bool various_subvols, various_inodes, various_types, various_uids, various_gids, compress_type_changed, has_subvols,
ro_subvol, various_ro, ro_changed, show_admin_button;
private:
LONG refcount;
BOOL ignore;
bool ignore;
STGMEDIUM stgm;
BOOL stgm_set;
BOOL flags_changed, perms_changed, uid_changed, gid_changed;
UINT64 sizes[4], totalsize;
std::deque<WCHAR*> search_list;
std::wstring filename;
bool stgm_set;
bool flags_changed, perms_changed, uid_changed, gid_changed;
uint64_t sizes[5], totalsize, allocsize, sparsesize;
deque<wstring> search_list;
wstring filename;
void apply_changes_file(HWND hDlg, std::wstring fn);
HRESULT check_file(std::wstring fn, UINT i, UINT num_files, UINT* sv);
void apply_changes_file(HWND hDlg, const wstring& fn);
HRESULT check_file(const wstring& fn, UINT i, UINT num_files, UINT* sv);
HRESULT load_file_list();
};

File diff suppressed because it is too large Load diff

View file

@ -18,8 +18,6 @@
#pragma once
#include <shlobj.h>
#include <string>
#include <vector>
#ifndef __REACTOS__
#include "../btrfs.h"
#else
@ -30,21 +28,21 @@ extern LONG objs_loaded;
typedef struct {
BTRFS_UUID uuid;
UINT64 transid;
std::wstring path;
uint64_t transid;
wstring path;
} subvol_cache;
class BtrfsRecv {
public:
BtrfsRecv() {
thread = NULL;
thread = nullptr;
master = INVALID_HANDLE_VALUE;
dir = INVALID_HANDLE_VALUE;
running = FALSE;
cancelling = FALSE;
running = false;
cancelling = false;
stransid = 0;
num_received = 0;
hwnd = NULL;
hwnd = nullptr;
cache.clear();
}
@ -52,39 +50,37 @@ public:
cache.clear();
}
void Open(HWND hwnd, WCHAR* file, WCHAR* path, BOOL quiet);
void Open(HWND hwnd, const wstring& file, const wstring& path, bool quiet);
DWORD recv_thread();
INT_PTR CALLBACK RecvProgressDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
BOOL cmd_subvol(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_snapshot(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_mkfile(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_rename(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_link(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_unlink(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_rmdir(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_setxattr(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_removexattr(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_write(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_clone(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_truncate(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_chmod(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_chown(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
BOOL cmd_utimes(HWND hwnd, btrfs_send_command* cmd, UINT8* data);
void add_cache_entry(BTRFS_UUID* uuid, UINT64 transid, std::wstring path);
BOOL utf8_to_utf16(HWND hwnd, char* utf8, ULONG utf8len, std::wstring* utf16);
void ShowRecvError(int resid, ...);
BOOL find_tlv(UINT8* data, ULONG datalen, UINT16 type, void** value, ULONG* len);
BOOL do_recv(HANDLE f, UINT64* pos, UINT64 size);
void cmd_subvol(HWND hwnd, btrfs_send_command* cmd, uint8_t* data, const win_handle& parent);
void cmd_snapshot(HWND hwnd, btrfs_send_command* cmd, uint8_t* data, const win_handle& parent);
void cmd_mkfile(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_rename(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_link(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_unlink(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_rmdir(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_setxattr(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_removexattr(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_write(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_clone(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_truncate(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_chmod(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_chown(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void cmd_utimes(HWND hwnd, btrfs_send_command* cmd, uint8_t* data);
void add_cache_entry(BTRFS_UUID* uuid, uint64_t transid, const wstring& path);
bool find_tlv(uint8_t* data, ULONG datalen, uint16_t type, void** value, ULONG* len);
void do_recv(const win_handle& f, uint64_t* pos, uint64_t size, const win_handle& parent);
HANDLE dir, parent, master, thread, lastwritefile;
HANDLE dir, master, thread, lastwritefile;
HWND hwnd;
std::wstring streamfile, dirpath, subvolpath, lastwritepath;
wstring streamfile, dirpath, subvolpath, lastwritepath;
DWORD lastwriteatt;
ULONG num_received;
UINT64 stransid;
uint64_t stransid;
BTRFS_UUID subvol_uuid;
BOOL running, cancelling;
std::vector<subvol_cache> cache;
bool running, cancelling;
vector<subvol_cache> cache;
};

View file

@ -196,6 +196,17 @@
#define IDS_BALANCE_CANCELLED_SHRINK 278
#define IDS_BALANCE_COMPLETE_SHRINK 279
#define IDS_BALANCE_FAILED_SHRINK 280
#define IDS_COMPRESS_ZSTD 281
#define IDS_RECV_RTLUNICODETOUTF8N_FAILED 282
#define IDS_REGCREATEKEY_FAILED 283
#define IDS_REGSETVALUEEX_FAILED 284
#define IDS_REGCLOSEKEY_FAILED 285
#define IDS_REGDELETETREE_FAILED 286
#define IDS_CANT_REFLINK_DIFFERENT_FS 287
#define IDS_INITCOMMONCONTROLSEX_FAILED 288
#define IDS_CANT_OPEN_MOUNTMGR 289
#define IDS_TVM_INSERTITEM_FAILED 290
#define IDS_RECV_PATH_TOO_LONG 291
#define IDC_UID 1001
#define IDC_GID 1002
#define IDC_USERR 1003
@ -226,6 +237,8 @@
#define IDC_SIZE_LZO 1022
#define IDC_VOL_SHOW_USAGE 1022
#define IDC_VOL_BALANCE 1023
#define IDC_SIZE_ZSTD 1023
#define IDC_COMPRESSION_RATIO 1023
#define IDC_PROFILES 1024
#define IDC_PROFILES_SINGLE 1025
#define IDC_PROFILES_DUP 1026
@ -324,7 +337,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 173
#define _APS_NEXT_RESOURCE_VALUE 175
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1073
#define _APS_NEXT_SYMED_VALUE 101

View file

@ -37,345 +37,287 @@
#include <ndk/iofuncs.h>
#include <ndk/iotypes.h>
#endif
#include <string>
#define NO_SHLWAPI_STRFCNS
#include <shlwapi.h>
#include <uxtheme.h>
void BtrfsScrub::UpdateTextBox(HWND hwndDlg, btrfs_query_scrub* bqs) {
btrfs_query_scrub* bqs2 = NULL;
BOOL alloc_bqs2 = FALSE;
btrfs_query_scrub* bqs2 = nullptr;
bool alloc_bqs2 = false;
NTSTATUS Status;
std::wstring s;
WCHAR t[255], u[255], dt[255], tm[255];
wstring s, t, u;
WCHAR dt[255], tm[255];
FILETIME filetime;
SYSTEMTIME systime;
UINT64 recoverable_errors = 0, unrecoverable_errors = 0;
uint64_t recoverable_errors = 0, unrecoverable_errors = 0;
if (bqs->num_errors > 0) {
HANDLE h;
IO_STATUS_BLOCK iosb;
ULONG len;
try {
if (bqs->num_errors > 0) {
win_handle h;
IO_STATUS_BLOCK iosb;
ULONG len;
h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h == INVALID_HANDLE_VALUE) {
ShowError(hwndDlg, GetLastError());
return;
}
h = CreateFileW(fn.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
if (h == INVALID_HANDLE_VALUE)
throw last_error(GetLastError());
len = 0;
len = 0;
do {
len += 1024;
try {
do {
len += 1024;
if (bqs2)
free(bqs2);
if (bqs2) {
free(bqs2);
bqs2 = nullptr;
}
bqs2 = (btrfs_query_scrub*)malloc(len);
bqs2 = (btrfs_query_scrub*)malloc(len);
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_SCRUB, NULL, 0, bqs2, len);
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_SCRUB, nullptr, 0, bqs2, len);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) {
ShowNtStatusError(hwndDlg, Status);
CloseHandle(h);
free(bqs2);
return;
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
throw ntstatus_error(Status);
} while (Status == STATUS_BUFFER_OVERFLOW);
} catch (...) {
if (bqs2)
free(bqs2);
throw;
}
} while (Status == STATUS_BUFFER_OVERFLOW);
alloc_bqs2 = TRUE;
alloc_bqs2 = true;
} else
bqs2 = bqs;
CloseHandle(h);
} else
bqs2 = bqs;
// "scrub started"
if (bqs2->start_time.QuadPart > 0) {
filetime.dwLowDateTime = bqs2->start_time.LowPart;
filetime.dwHighDateTime = bqs2->start_time.HighPart;
s[0] = 0;
if (!FileTimeToSystemTime(&filetime, &systime))
throw last_error(GetLastError());
// "scrub started"
if (bqs2->start_time.QuadPart > 0) {
filetime.dwLowDateTime = bqs2->start_time.LowPart;
filetime.dwHighDateTime = bqs2->start_time.HighPart;
if (!SystemTimeToTzSpecificLocalTime(nullptr, &systime, &systime))
throw last_error(GetLastError());
if (!FileTimeToSystemTime(&filetime, &systime)) {
ShowError(hwndDlg, GetLastError());
goto end;
if (!load_string(module, IDS_SCRUB_MSG_STARTED, t))
throw last_error(GetLastError());
if (!GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime, nullptr, dt, sizeof(dt) / sizeof(WCHAR)))
throw last_error(GetLastError());
if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systime, nullptr, tm, sizeof(tm) / sizeof(WCHAR)))
throw last_error(GetLastError());
wstring_sprintf(u, t, dt, tm);
s += u;
s += L"\r\n";
}
if (!SystemTimeToTzSpecificLocalTime(NULL, &systime, &systime)) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!LoadStringW(module, IDS_SCRUB_MSG_STARTED, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime, NULL, dt, sizeof(dt) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systime, NULL, tm, sizeof(tm) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, dt, tm) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
s += u;
s += L"\r\n";
}
// errors
if (bqs2->num_errors > 0) {
btrfs_scrub_error* bse = &bqs2->errors;
do {
if (bse->recovered)
recoverable_errors++;
else
unrecoverable_errors++;
if (bse->parity) {
if (!LoadStringW(module, IDS_SCRUB_MSG_RECOVERABLE_PARITY, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
} else if (bse->is_metadata) {
int message;
// errors
if (bqs2->num_errors > 0) {
btrfs_scrub_error* bse = &bqs2->errors;
do {
if (bse->recovered)
message = IDS_SCRUB_MSG_RECOVERABLE_METADATA;
else if (bse->metadata.firstitem.obj_id == 0 && bse->metadata.firstitem.obj_type == 0 && bse->metadata.firstitem.offset == 0)
message = IDS_SCRUB_MSG_UNRECOVERABLE_METADATA;
recoverable_errors++;
else
message = IDS_SCRUB_MSG_UNRECOVERABLE_METADATA_FIRSTITEM;
unrecoverable_errors++;
if (!LoadStringW(module, message, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (bse->parity) {
if (!load_string(module, IDS_SCRUB_MSG_RECOVERABLE_PARITY, t))
throw last_error(GetLastError());
if (bse->recovered) {
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
} else if (bse->metadata.firstitem.obj_id == 0 && bse->metadata.firstitem.obj_type == 0 && bse->metadata.firstitem.offset == 0) {
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device,
bse->metadata.root, bse->metadata.level) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
wstring_sprintf(u, t, bse->address, bse->device);
} else if (bse->is_metadata) {
int message;
if (bse->recovered)
message = IDS_SCRUB_MSG_RECOVERABLE_METADATA;
else if (bse->metadata.firstitem.obj_id == 0 && bse->metadata.firstitem.obj_type == 0 && bse->metadata.firstitem.offset == 0)
message = IDS_SCRUB_MSG_UNRECOVERABLE_METADATA;
else
message = IDS_SCRUB_MSG_UNRECOVERABLE_METADATA_FIRSTITEM;
if (!load_string(module, message, t))
throw last_error(GetLastError());
if (bse->recovered)
wstring_sprintf(u, t, bse->address, bse->device);
else if (bse->metadata.firstitem.obj_id == 0 && bse->metadata.firstitem.obj_type == 0 && bse->metadata.firstitem.offset == 0)
wstring_sprintf(u, t, bse->address, bse->device, bse->metadata.root, bse->metadata.level);
else
wstring_sprintf(u, t, bse->address, bse->device, bse->metadata.root, bse->metadata.level, bse->metadata.firstitem.obj_id,
bse->metadata.firstitem.obj_type, bse->metadata.firstitem.offset);
} else {
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device,
bse->metadata.root, bse->metadata.level, bse->metadata.firstitem.obj_id, bse->metadata.firstitem.obj_type,
bse->metadata.firstitem.offset) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
}
} else {
int message;
int message;
if (bse->recovered)
message = IDS_SCRUB_MSG_RECOVERABLE_DATA;
else if (bse->data.subvol != 0)
message = IDS_SCRUB_MSG_UNRECOVERABLE_DATA_SUBVOL;
if (bse->recovered)
message = IDS_SCRUB_MSG_RECOVERABLE_DATA;
else if (bse->data.subvol != 0)
message = IDS_SCRUB_MSG_UNRECOVERABLE_DATA_SUBVOL;
else
message = IDS_SCRUB_MSG_UNRECOVERABLE_DATA;
if (!load_string(module, message, t))
throw last_error(GetLastError());
if (bse->recovered)
wstring_sprintf(u, t, bse->address, bse->device);
else if (bse->data.subvol != 0)
wstring_sprintf(u, t, bse->address, bse->device, bse->data.subvol,
bse->data.filename_length / sizeof(WCHAR), bse->data.filename, bse->data.offset);
else
wstring_sprintf(u, t, bse->address, bse->device, bse->data.filename_length / sizeof(WCHAR),
bse->data.filename, bse->data.offset);
}
s += u;
s += L"\r\n";
if (bse->next_entry == 0)
break;
else
message = IDS_SCRUB_MSG_UNRECOVERABLE_DATA;
bse = (btrfs_scrub_error*)((uint8_t*)bse + bse->next_entry);
} while (true);
}
if (!LoadStringW(module, message, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (bqs2->finish_time.QuadPart > 0) {
wstring d1, d2;
float speed;
if (bse->recovered) {
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
} else if (bse->data.subvol != 0) {
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device, bse->data.subvol,
bse->data.filename_length / sizeof(WCHAR), bse->data.filename, bse->data.offset) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
} else {
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, bse->address, bse->device, bse->data.filename_length / sizeof(WCHAR),
bse->data.filename, bse->data.offset) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
}
}
// "scrub finished"
filetime.dwLowDateTime = bqs2->finish_time.LowPart;
filetime.dwHighDateTime = bqs2->finish_time.HighPart;
if (!FileTimeToSystemTime(&filetime, &systime))
throw last_error(GetLastError());
if (!SystemTimeToTzSpecificLocalTime(nullptr, &systime, &systime))
throw last_error(GetLastError());
if (!load_string(module, IDS_SCRUB_MSG_FINISHED, t))
throw last_error(GetLastError());
if (!GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime, nullptr, dt, sizeof(dt) / sizeof(WCHAR)))
throw last_error(GetLastError());
if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systime, nullptr, tm, sizeof(tm) / sizeof(WCHAR)))
throw last_error(GetLastError());
wstring_sprintf(u, t, dt, tm);
s += u;
s += L"\r\n";
if (bse->next_entry == 0)
break;
else
bse = (btrfs_scrub_error*)((UINT8*)bse + bse->next_entry);
} while (TRUE);
// summary
if (!load_string(module, IDS_SCRUB_MSG_SUMMARY, t))
throw last_error(GetLastError());
format_size(bqs2->data_scrubbed, d1, false);
speed = (float)bqs2->data_scrubbed / ((float)bqs2->duration / 10000000.0f);
format_size((uint64_t)speed, d2, false);
wstring_sprintf(u, t, d1.c_str(), bqs2->duration / 10000000, d2.c_str());
s += u;
s += L"\r\n";
// recoverable errors
if (!load_string(module, IDS_SCRUB_MSG_SUMMARY_ERRORS_RECOVERABLE, t))
throw last_error(GetLastError());
wstring_sprintf(u, t, recoverable_errors);
s += u;
s += L"\r\n";
// unrecoverable errors
if (!load_string(module, IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE, t))
throw last_error(GetLastError());
wstring_sprintf(u, t, unrecoverable_errors);
s += u;
s += L"\r\n";
}
SetWindowTextW(GetDlgItem(hwndDlg, IDC_SCRUB_INFO), s.c_str());
} catch (...) {
if (alloc_bqs2)
free(bqs2);
throw;
}
if (bqs2->finish_time.QuadPart > 0) {
WCHAR d1[255], d2[255];
float speed;
// "scrub finished"
filetime.dwLowDateTime = bqs2->finish_time.LowPart;
filetime.dwHighDateTime = bqs2->finish_time.HighPart;
if (!FileTimeToSystemTime(&filetime, &systime)) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!SystemTimeToTzSpecificLocalTime(NULL, &systime, &systime)) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!LoadStringW(module, IDS_SCRUB_MSG_FINISHED, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime, NULL, dt, sizeof(dt) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systime, NULL, tm, sizeof(tm) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, dt, tm) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
s += u;
s += L"\r\n";
// summary
if (!LoadStringW(module, IDS_SCRUB_MSG_SUMMARY, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
format_size(bqs2->data_scrubbed, d1, sizeof(d1) / sizeof(WCHAR), FALSE);
speed = (float)bqs2->data_scrubbed / ((float)bqs2->duration / 10000000.0f);
format_size((UINT64)speed, d2, sizeof(d2) / sizeof(WCHAR), FALSE);
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, d1, bqs2->duration / 10000000, d2) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
s += u;
s += L"\r\n";
// recoverable errors
if (!LoadStringW(module, IDS_SCRUB_MSG_SUMMARY_ERRORS_RECOVERABLE, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, recoverable_errors) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
s += u;
s += L"\r\n";
// unrecoverable errors
if (!LoadStringW(module, IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
goto end;
}
if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, unrecoverable_errors) == STRSAFE_E_INSUFFICIENT_BUFFER)
goto end;
s += u;
s += L"\r\n";
}
SetWindowTextW(GetDlgItem(hwndDlg, IDC_SCRUB_INFO), s.c_str());
end:
if (alloc_bqs2)
free(bqs2);
}
void BtrfsScrub::RefreshScrubDlg(HWND hwndDlg, BOOL first_time) {
HANDLE h;
void BtrfsScrub::RefreshScrubDlg(HWND hwndDlg, bool first_time) {
btrfs_query_scrub bqs;
h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h != INVALID_HANDLE_VALUE) {
NTSTATUS Status;
IO_STATUS_BLOCK iosb;
{
win_handle h = CreateFileW(fn.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
if (h != INVALID_HANDLE_VALUE) {
NTSTATUS Status;
IO_STATUS_BLOCK iosb;
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_SCRUB, NULL, 0, &bqs, sizeof(btrfs_query_scrub));
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_SCRUB, nullptr, 0, &bqs, sizeof(btrfs_query_scrub));
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) {
ShowNtStatusError(hwndDlg, Status);
CloseHandle(h);
return;
}
CloseHandle(h);
} else {
ShowError(hwndDlg, GetLastError());
return;
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
throw ntstatus_error(Status);
} else
throw last_error(GetLastError());
}
if (first_time || status != bqs.status || chunks_left != bqs.chunks_left) {
WCHAR s[255];
wstring s;
if (bqs.status == BTRFS_SCRUB_STOPPED) {
EnableWindow(GetDlgItem(hwndDlg, IDC_START_SCRUB), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_SCRUB), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_SCRUB), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_START_SCRUB), true);
EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_SCRUB), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_SCRUB), false);
if (bqs.error != STATUS_SUCCESS) {
WCHAR t[255];
wstring t;
if (!LoadStringW(module, IDS_SCRUB_FAILED, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
return;
}
if (!load_string(module, IDS_SCRUB_FAILED, t))
throw last_error(GetLastError());
if (StringCchPrintfW(s, sizeof(s) / sizeof(WCHAR), t, bqs.error) == STRSAFE_E_INSUFFICIENT_BUFFER)
return;
wstring_sprintf(s, t, bqs.error);
} else {
if (!LoadStringW(module, bqs.total_chunks == 0 ? IDS_NO_SCRUB : IDS_SCRUB_FINISHED, s, sizeof(s) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
return;
}
if (!load_string(module, bqs.total_chunks == 0 ? IDS_NO_SCRUB : IDS_SCRUB_FINISHED, s))
throw last_error(GetLastError());
}
} else {
WCHAR t[255];
wstring t;
float pc;
EnableWindow(GetDlgItem(hwndDlg, IDC_START_SCRUB), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_SCRUB), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_SCRUB), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_START_SCRUB), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_SCRUB), true);
EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_SCRUB), true);
if (!LoadStringW(module, bqs.status == BTRFS_SCRUB_PAUSED ? IDS_SCRUB_PAUSED : IDS_SCRUB_RUNNING, t, sizeof(t) / sizeof(WCHAR))) {
ShowError(hwndDlg, GetLastError());
return;
}
if (!load_string(module, bqs.status == BTRFS_SCRUB_PAUSED ? IDS_SCRUB_PAUSED : IDS_SCRUB_RUNNING, t))
throw last_error(GetLastError());
pc = ((float)(bqs.total_chunks - bqs.chunks_left) / (float)bqs.total_chunks) * 100.0f;
if (StringCchPrintfW(s, sizeof(s) / sizeof(WCHAR), t, bqs.total_chunks - bqs.chunks_left, bqs.total_chunks, pc) == STRSAFE_E_INSUFFICIENT_BUFFER)
return;
wstring_sprintf(s, t, bqs.total_chunks - bqs.chunks_left, bqs.total_chunks, pc);
}
SetDlgItemTextW(hwndDlg, IDC_SCRUB_STATUS, s);
SetDlgItemTextW(hwndDlg, IDC_SCRUB_STATUS, s.c_str());
if (first_time || status != bqs.status) {
EnableWindow(GetDlgItem(hwndDlg, IDC_SCRUB_PROGRESS), bqs.status != BTRFS_SCRUB_STOPPED);
@ -412,142 +354,117 @@ void BtrfsScrub::RefreshScrubDlg(HWND hwndDlg, BOOL first_time) {
}
void BtrfsScrub::StartScrub(HWND hwndDlg) {
HANDLE h;
win_handle h = CreateFileW(fn.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h != INVALID_HANDLE_VALUE) {
NTSTATUS Status;
IO_STATUS_BLOCK iosb;
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_START_SCRUB, NULL, 0, NULL, 0);
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_START_SCRUB, nullptr, 0, nullptr, 0);
if (Status == STATUS_DEVICE_NOT_READY) {
btrfs_query_balance bqb;
NTSTATUS Status2;
Status2 = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_BALANCE, NULL, 0, &bqb, sizeof(btrfs_query_balance));
Status2 = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_BALANCE, nullptr, 0, &bqb, sizeof(btrfs_query_balance));
if (NT_SUCCESS(Status2) && bqb.status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED)) {
ShowStringError(hwndDlg, IDS_SCRUB_BALANCE_RUNNING);
CloseHandle(h);
return;
}
if (NT_SUCCESS(Status2) && bqb.status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED))
throw string_error(IDS_SCRUB_BALANCE_RUNNING);
}
if (!NT_SUCCESS(Status)) {
ShowNtStatusError(hwndDlg, Status);
CloseHandle(h);
return;
}
if (!NT_SUCCESS(Status))
throw ntstatus_error(Status);
RefreshScrubDlg(hwndDlg, TRUE);
CloseHandle(h);
} else {
ShowError(hwndDlg, GetLastError());
return;
}
RefreshScrubDlg(hwndDlg, true);
} else
throw last_error(GetLastError());
}
void BtrfsScrub::PauseScrub(HWND hwndDlg) {
HANDLE h;
btrfs_query_scrub bqs;
h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
win_handle h = CreateFileW(fn.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
if (h != INVALID_HANDLE_VALUE) {
NTSTATUS Status;
IO_STATUS_BLOCK iosb;
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_SCRUB, NULL, 0, &bqs, sizeof(btrfs_query_scrub));
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_SCRUB, nullptr, 0, &bqs, sizeof(btrfs_query_scrub));
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) {
ShowNtStatusError(hwndDlg, Status);
CloseHandle(h);
return;
}
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
throw ntstatus_error(Status);
if (bqs.status == BTRFS_SCRUB_PAUSED)
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_RESUME_SCRUB, NULL, 0, NULL, 0);
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_RESUME_SCRUB, nullptr, 0, nullptr, 0);
else
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_PAUSE_SCRUB, NULL, 0, NULL, 0);
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_PAUSE_SCRUB, nullptr, 0, nullptr, 0);
if (!NT_SUCCESS(Status)) {
ShowNtStatusError(hwndDlg, Status);
CloseHandle(h);
return;
}
CloseHandle(h);
} else {
ShowError(hwndDlg, GetLastError());
return;
}
if (!NT_SUCCESS(Status))
throw ntstatus_error(Status);
} else
throw last_error(GetLastError());
}
void BtrfsScrub::StopScrub(HWND hwndDlg) {
HANDLE h;
win_handle h = CreateFileW(fn.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (h != INVALID_HANDLE_VALUE) {
NTSTATUS Status;
IO_STATUS_BLOCK iosb;
Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_STOP_SCRUB, NULL, 0, NULL, 0);
Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_STOP_SCRUB, nullptr, 0, nullptr, 0);
if (!NT_SUCCESS(Status)) {
ShowNtStatusError(hwndDlg, Status);
CloseHandle(h);
return;
}
CloseHandle(h);
} else {
ShowError(hwndDlg, GetLastError());
return;
}
if (!NT_SUCCESS(Status))
throw ntstatus_error(Status);
} else
throw last_error(GetLastError());
}
INT_PTR CALLBACK BtrfsScrub::ScrubDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_INITDIALOG:
RefreshScrubDlg(hwndDlg, TRUE);
SetTimer(hwndDlg, 1, 1000, NULL);
break;
try {
switch (uMsg) {
case WM_INITDIALOG:
RefreshScrubDlg(hwndDlg, true);
SetTimer(hwndDlg, 1, 1000, nullptr);
break;
case WM_COMMAND:
switch (HIWORD(wParam)) {
case BN_CLICKED:
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hwndDlg, 0);
return TRUE;
case WM_COMMAND:
switch (HIWORD(wParam)) {
case BN_CLICKED:
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hwndDlg, 0);
return true;
case IDC_START_SCRUB:
StartScrub(hwndDlg);
return TRUE;
case IDC_START_SCRUB:
StartScrub(hwndDlg);
return true;
case IDC_PAUSE_SCRUB:
PauseScrub(hwndDlg);
return TRUE;
case IDC_PAUSE_SCRUB:
PauseScrub(hwndDlg);
return true;
case IDC_CANCEL_SCRUB:
StopScrub(hwndDlg);
return TRUE;
}
break;
}
break;
case IDC_CANCEL_SCRUB:
StopScrub(hwndDlg);
return true;
}
break;
}
break;
case WM_TIMER:
RefreshScrubDlg(hwndDlg, FALSE);
break;
case WM_TIMER:
RefreshScrubDlg(hwndDlg, false);
break;
}
} catch (const exception& e) {
error_message(hwndDlg, e.what());
}
return FALSE;
return false;
}
static INT_PTR CALLBACK stub_ScrubDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
@ -563,7 +480,7 @@ static INT_PTR CALLBACK stub_ScrubDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam
if (bs)
return bs->ScrubDlgProc(hwndDlg, uMsg, wParam, lParam);
else
return FALSE;
return false;
}
#ifdef __REACTOS__
@ -571,132 +488,104 @@ extern "C" {
#endif
void CALLBACK ShowScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
HANDLE token;
TOKEN_PRIVILEGES tp;
LUID luid;
BtrfsScrub* scrub;
try {
win_handle token;
TOKEN_PRIVILEGES tp;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
ShowError(hwnd, GetLastError());
return;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
throw last_error(GetLastError());
if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid))
throw last_error(GetLastError());
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
throw last_error(GetLastError());
set_dpi_aware();
BtrfsScrub scrub(lpszCmdLine);
DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_SCRUB), hwnd, stub_ScrubDlgProc, (LPARAM)&scrub);
} catch (const exception& e) {
error_message(hwnd, e.what());
}
if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid)) {
ShowError(hwnd, GetLastError());
goto end;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
ShowError(hwnd, GetLastError());
goto end;
}
set_dpi_aware();
scrub = new BtrfsScrub(lpszCmdLine);
DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_SCRUB), hwnd, stub_ScrubDlgProc, (LPARAM)scrub);
delete scrub;
end:
CloseHandle(token);
}
void CALLBACK StartScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
LPWSTR* args;
int num_args;
vector<wstring> args;
args = CommandLineToArgvW(lpszCmdLine, &num_args);
command_line_to_args(lpszCmdLine, args);
if (!args)
return;
if (num_args >= 1) {
HANDLE h, token;
if (args.size() >= 1) {
LUID luid;
TOKEN_PRIVILEGES tp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
goto end;
{
win_handle token;
if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid)) {
CloseHandle(token);
goto end;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
return;
if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid))
return;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
return;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
CloseHandle(token);
goto end;
}
CloseHandle(token);
h = CreateFileW(args[0], FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
win_handle h = CreateFileW(args[0].c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
if (h != INVALID_HANDLE_VALUE) {
IO_STATUS_BLOCK iosb;
NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_START_SCRUB, NULL, 0, NULL, 0);
CloseHandle(h);
NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_START_SCRUB, nullptr, 0, nullptr, 0);
}
}
end:
LocalFree(args);
}
void CALLBACK StopScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
LPWSTR* args;
int num_args;
vector<wstring> args;
args = CommandLineToArgvW(lpszCmdLine, &num_args);
command_line_to_args(lpszCmdLine, args);
if (!args)
return;
if (num_args >= 1) {
HANDLE h, token;
if (args.size() >= 1) {
LUID luid;
TOKEN_PRIVILEGES tp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
goto end;
{
win_handle token;
if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid))
goto end;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
return;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid))
return;
if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
goto end;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
CloseHandle(token);
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
return;
}
h = CreateFileW(args[0], FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
win_handle h = CreateFileW(args[0].c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
if (h != INVALID_HANDLE_VALUE) {
IO_STATUS_BLOCK iosb;
NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_STOP_SCRUB, NULL, 0, NULL, 0);
CloseHandle(h);
NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_STOP_SCRUB, nullptr, 0, nullptr, 0);
}
}
end:
LocalFree(args);
}
#ifdef __REACTOS__

View file

@ -28,21 +28,21 @@
class BtrfsScrub {
public:
BtrfsScrub(WCHAR* drive) {
wcscpy(fn, drive);
BtrfsScrub(const wstring& drive) {
fn = drive;
}
INT_PTR CALLBACK ScrubDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
void RefreshScrubDlg(HWND hwndDlg, BOOL first_time);
void RefreshScrubDlg(HWND hwndDlg, bool first_time);
void UpdateTextBox(HWND hwndDlg, btrfs_query_scrub* bqs);
void StartScrub(HWND hwndDlg);
void PauseScrub(HWND hwndDlg);
void StopScrub(HWND hwndDlg);
WCHAR fn[MAX_PATH];
UINT32 status;
UINT64 chunks_left;
UINT32 num_errors;
wstring fn;
uint32_t status;
uint64_t chunks_left;
uint32_t num_errors;
};

File diff suppressed because it is too large Load diff

View file

@ -19,23 +19,20 @@
#ifdef __REACTOS__
#include "btrfs.h"
#include <stdlib.h>
#else
#include "../btrfs.h"
#endif
#include <string>
#include <vector>
class BtrfsSend {
public:
BtrfsSend() {
started = FALSE;
started = false;
file[0] = 0;
dirh = INVALID_HANDLE_VALUE;
stream = INVALID_HANDLE_VALUE;
subvol = L"";
buf = NULL;
incremental = FALSE;
buf = nullptr;
incremental = false;
}
~BtrfsSend() {
@ -53,14 +50,13 @@ private:
void BrowseParent(HWND hwnd);
void AddClone(HWND hwnd);
void RemoveClone(HWND hwnd);
void ShowSendError(UINT msg, ...);
BOOL started;
BOOL incremental;
bool started;
bool incremental;
WCHAR file[MAX_PATH], closetext[255];
HANDLE thread, dirh, stream;
HWND hwnd;
std::wstring subvol;
wstring subvol;
char* buf;
std::vector <std::wstring> clones;
vector <wstring> clones;
};

View file

@ -25,18 +25,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
// TEXTINCLUDE
//
1 TEXTINCLUDE
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@ -61,8 +61,8 @@ IDI_ICON1 ICON "subvol.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,2,0
PRODUCTVERSION 1,0,2,0
FILEVERSION 1,1,0,0
PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -78,12 +78,12 @@ BEGIN
BLOCK "080904b0"
BEGIN
VALUE "FileDescription", "WinBtrfs shell extension"
VALUE "FileVersion", "1.0.2"
VALUE "FileVersion", "1.1"
VALUE "InternalName", "btrfs"
VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-18"
VALUE "OriginalFilename", "shellbtrfs.dll"
VALUE "ProductName", "WinBtrfs"
VALUE "ProductVersion", "1.0.2"
VALUE "ProductVersion", "1.1"
END
END
BLOCK "VarFileInfo"
@ -98,57 +98,59 @@ END
// Dialog
//
IDD_PROP_SHEET DIALOGEX 0, 0, 235, 245
IDD_PROP_SHEET DIALOGEX 0, 0, 235, 257
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Inode property sheet"
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
LTEXT "Subvolume:",IDC_STATIC,14,21,38,8
LTEXT "Inode:",IDC_STATIC,14,35,21,8
GROUPBOX "Information",IDC_GROUP_INFORMATION,7,7,221,71
GROUPBOX "Information",IDC_GROUP_INFORMATION,7,7,221,85
LTEXT "Type:",IDC_STATIC,14,49,18,8
GROUPBOX "POSIX permissions",IDC_STATIC,7,82,221,102
LTEXT "User:",IDC_STATIC,14,97,17,8
LTEXT "Group:",IDC_STATIC,14,113,22,8
EDITTEXT IDC_UID,94,95,40,14,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_GID,94,111,40,14,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "User",IDC_STATIC,14,144,15,8
LTEXT "Group",IDC_STATIC,14,156,20,8
LTEXT "Others",IDC_STATIC,14,168,22,8
LTEXT "Read",IDC_STATIC,50,134,17,8
LTEXT "Write",IDC_STATIC,89,134,18,8
LTEXT "Execute",IDC_STATIC,129,134,30,8
CONTROL "",IDC_USERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,147,16,10
CONTROL "",IDC_GROUPR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,158,16,10
CONTROL "",IDC_OTHERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,168,16,10
CONTROL "",IDC_USERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,147,16,10
CONTROL "",IDC_GROUPW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,158,16,10
CONTROL "",IDC_OTHERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,168,16,10
CONTROL "",IDC_USERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,147,16,10
CONTROL "",IDC_GROUPX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,158,16,10
CONTROL "",IDC_OTHERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,168,16,10
GROUPBOX "Flags",IDC_STATIC,7,190,221,48
CONTROL "Disable Copy-on-Write",IDC_NODATACOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,86,10
GROUPBOX "POSIX permissions",IDC_STATIC,7,96,221,102
LTEXT "User:",IDC_STATIC,14,111,17,8
LTEXT "Group:",IDC_STATIC,14,127,22,8
EDITTEXT IDC_UID,94,109,40,14,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_GID,94,125,40,14,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "User",IDC_STATIC,14,158,15,8
LTEXT "Group",IDC_STATIC,14,168,20,8
LTEXT "Others",IDC_STATIC,14,182,22,8
LTEXT "Read",IDC_STATIC,50,148,17,8
LTEXT "Write",IDC_STATIC,89,148,18,8
LTEXT "Execute",IDC_STATIC,129,148,30,8
CONTROL "",IDC_USERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,161,16,10
CONTROL "",IDC_GROUPR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,172,16,10
CONTROL "",IDC_OTHERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,182,16,10
CONTROL "",IDC_USERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,161,16,10
CONTROL "",IDC_GROUPW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,172,16,10
CONTROL "",IDC_OTHERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,182,16,10
CONTROL "",IDC_USERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,161,16,10
CONTROL "",IDC_GROUPX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,172,16,10
CONTROL "",IDC_OTHERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,182,16,10
GROUPBOX "Flags",IDC_STATIC,7,204,221,48
CONTROL "Disable Copy-on-Write",IDC_NODATACOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,218,86,10
LTEXT "(blank)",IDC_INODE,78,35,70,8
LTEXT "(blank)",IDC_TYPE,78,49,116,8
CONTROL "Compress",IDC_COMPRESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,218,46,10
CONTROL "Compress",IDC_COMPRESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,232,46,10
LTEXT "Size on disk:",IDC_STATIC,14,63,61,8
CONTROL "%s (<a>Details</a>)",IDC_SIZE_ON_DISK,"SysLink",WS_TABSTOP,78,63,142,8
COMBOBOX IDC_COMPRESS_TYPE,63,217,48,13,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
CONTROL "Readonly subvolume",IDC_SUBVOL_RO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,124,204,80,10
COMBOBOX IDC_COMPRESS_TYPE,63,231,48,13,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
CONTROL "Readonly subvolume",IDC_SUBVOL_RO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,124,218,80,10
LTEXT "(blank)",IDC_SUBVOL,78,21,70,8
PUSHBUTTON "&Open as Admin",IDC_OPEN_ADMIN,151,21,70,14
CONTROL "Set UID",IDC_SETUID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,147,40,10
CONTROL "Set GID",IDC_SETGID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,158,40,10
CONTROL "Sticky",IDC_STICKY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,168,34,10
CONTROL "Set UID",IDC_SETUID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,161,40,10
CONTROL "Set GID",IDC_SETGID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,172,40,10
CONTROL "Sticky",IDC_STICKY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,182,34,10
LTEXT "Compression ratio:",IDC_STATIC,14,77,61,8
LTEXT "%1.1f%%",IDC_COMPRESSION_RATIO,78,77,116,8
END
IDD_SIZE_DETAILS DIALOGEX 0, 0, 212, 85
IDD_SIZE_DETAILS DIALOGEX 0, 0, 212, 98
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Size details"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,81,64,50,14
DEFPUSHBUTTON "OK",IDOK,81,77,50,14
LTEXT "Inline:",IDC_STATIC,7,7,21,8
LTEXT "Uncompressed:",IDC_STATIC,7,20,49,8
LTEXT "ZLIB:",IDC_STATIC,7,33,18,8
@ -157,6 +159,8 @@ BEGIN
LTEXT "(blank)",IDC_SIZE_UNCOMPRESSED,63,20,142,8
LTEXT "(blank)",IDC_SIZE_ZLIB,63,33,142,8
LTEXT "(blank)",IDC_SIZE_LZO,63,46,142,8
LTEXT "Zstd:",IDC_STATIC,7,59,16,8
LTEXT "(blank)",IDC_SIZE_ZSTD,63,59,142,8
END
IDD_VOL_PROP_SHEET DIALOGEX 0, 0, 235, 251
@ -382,7 +386,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 205
TOPMARGIN, 7
BOTTOMMARGIN, 78
BOTTOMMARGIN, 93
END
IDD_VOL_PROP_SHEET, DIALOG
@ -484,6 +488,22 @@ END
2 RT_MANIFEST "shellbtrfs.manifest"
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_SIZE_DETAILS AFX_DIALOG_LAYOUT
BEGIN
0
END
IDD_PROP_SHEET AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
@ -575,9 +595,9 @@ BEGIN
IDS_DEVLIST_READONLY_NO "No"
IDS_DEVLIST_ALLOC "Allocated"
IDS_DEVLIST_ALLOC_PC "%"
IDS_BALANCE_RUNNING_REMOVAL
IDS_BALANCE_RUNNING_REMOVAL
"Currently removing device %llu (%llu out of %llu chunks processed, %1.1f%%)"
IDS_BALANCE_PAUSED_REMOVAL
IDS_BALANCE_PAUSED_REMOVAL
"Removal of device %llu paused (%llu out of %llu chunks processed, %1.1f%%)"
IDS_BALANCE_CANCELLED_REMOVAL "Device removal cancelled."
IDS_BALANCE_COMPLETE_REMOVAL "Device removal completed successfully."
@ -588,12 +608,12 @@ END
STRINGTABLE
BEGIN
IDS_CANNOT_REMOVE_RAID "The current RAID levels do not allow this device to be removed. You must do a conversion balance before you will be able to proceed."
IDS_REMOVE_DEVICE_CONFIRMATION
IDS_REMOVE_DEVICE_CONFIRMATION
"Are you sure that you want to remove device %s, %s?"
IDS_CONFIRMATION_TITLE "Confirmation"
IDS_ADD_DEVICE_CONFIRMATION
IDS_ADD_DEVICE_CONFIRMATION
"Are you sure that you want to add this device?"
IDS_ADD_DEVICE_CONFIRMATION_FS
IDS_ADD_DEVICE_CONFIRMATION_FS
"Are you sure that you want to add this device? It already appears to contain a filesystem (%s)."
IDS_BALANCE_FAILED "Balance failed (error %08x, %s)"
IDS_BALANCE_FAILED_REMOVAL "Device removal failed (error %08x, %s)"
@ -604,32 +624,32 @@ BEGIN
IDS_SCRUB_FINISHED "Scrub finished."
IDS_SCRUB_PAUSED "Scrub paused (%llu out of %llu chunks processed, %1.1f%%)"
IDS_SCRUB_MSG_STARTED "Scrub started at %s %s."
IDS_SCRUB_MSG_RECOVERABLE_DATA
IDS_SCRUB_MSG_RECOVERABLE_DATA
"Recovered from data checksum error at %llx on device %llx."
IDS_SCRUB_MSG_RECOVERABLE_METADATA
IDS_SCRUB_MSG_RECOVERABLE_METADATA
"Recovered from metadata checksum error at %llx on device %llx."
END
STRINGTABLE
BEGIN
IDS_SCRUB_MSG_UNRECOVERABLE_DATA
IDS_SCRUB_MSG_UNRECOVERABLE_DATA
"Unrecoverable data checksum error at %llx on device %llx (%.*s, offset %llx)"
IDS_SCRUB_MSG_UNRECOVERABLE_DATA_SUBVOL
IDS_SCRUB_MSG_UNRECOVERABLE_DATA_SUBVOL
"Unrecoverable data checksum error at %llx on device %llx (subvol %llx, %.*s, offset %llx)"
IDS_SCRUB_MSG_UNRECOVERABLE_METADATA
IDS_SCRUB_MSG_UNRECOVERABLE_METADATA
"Unrecoverable metadata checksum error at %llx on device %llx (root %llx, level %x)"
IDS_SCRUB_MSG_UNRECOVERABLE_METADATA_FIRSTITEM
IDS_SCRUB_MSG_UNRECOVERABLE_METADATA_FIRSTITEM
"Unrecoverable metadata checksum error at %llx on device %llx (root %llx, level %x, first item %llx,%x,%llx)"
IDS_SCRUB_MSG_FINISHED "Scrub finished at %s %s."
IDS_SCRUB_MSG_SUMMARY "Scrubbed %s in %llu seconds (%s/s)."
IDS_BALANCE_SCRUB_RUNNING "Cannot start balance while scrub running."
IDS_SCRUB_BALANCE_RUNNING "Cannot start scrub while balance running."
IDS_SCRUB_MSG_SUMMARY_ERRORS_RECOVERABLE "Recovered from %llu error(s)."
IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE
IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE
"%llu unrecoverable error(s) found."
IDS_SCRUB_FAILED "Scrub failed with error %08x."
IDS_LOCK_FAILED "Unable to lock volume: error %08x. Make sure that there are no files open, and that you have closed any Explorer windows."
IDS_SCRUB_MSG_RECOVERABLE_PARITY
IDS_SCRUB_MSG_RECOVERABLE_PARITY
"Recovered from parity error at %llx on device %llx."
IDS_COMPRESS_ANY "(any)"
IDS_COMPRESS_ZLIB "Zlib"
@ -649,12 +669,12 @@ BEGIN
IDS_RECV_UNKNOWN_COMMAND "Unrecognized command %u encountered."
IDS_RECV_CANT_OPEN_PATH "Couldn't open path %s (error %u, %s)."
IDS_RECV_RTLUTF8TOUNICODEN_FAILED "RtlUTF8ToUnicodeN returned %08x (%s)."
IDS_RECV_CREATE_SUBVOL_FAILED
IDS_RECV_CREATE_SUBVOL_FAILED
"FSCTL_BTRFS_CREATE_SUBVOL returned %08x (%s)."
IDS_RECV_MISSING_PARAM "%S: could not find %s parameter."
IDS_RECV_SHORT_PARAM "%S: length of parameter %s was %u, expected %u."
IDS_RECV_MKNOD_FAILED "FSCTL_BTRFS_MKNOD returned %08x (%s)."
IDS_RECV_SET_REPARSE_POINT_FAILED
IDS_RECV_SET_REPARSE_POINT_FAILED
"FSCTL_SET_REPARSE_POINT returned %08x (%s)."
END
@ -663,19 +683,19 @@ BEGIN
IDS_RECV_MOVEFILE_FAILED "MoveFile (%s -> %s) failed (error %u, %s)."
IDS_RECV_SETFILEPOINTER_FAILED "SetFilePointer failed (error %u, %s)."
IDS_RECV_WRITEFILE_FAILED "WriteFile failed (error %u, %s)."
IDS_RECV_CREATEHARDLINK_FAILED
IDS_RECV_CREATEHARDLINK_FAILED
"CreateHardLink (%s -> %s) failed (error %u, %s)."
IDS_RECV_SETENDOFFILE_FAILED "SetEndOfFile failed (error %u, %s)."
IDS_RECV_CANT_CREATE_FILE "Couldn't create %s (error %u, %s)."
IDS_RECV_SETFILEINFO_FAILED
IDS_RECV_SETFILEINFO_FAILED
"SetFileInformationByHandle failed (error %u, %s)."
IDS_RECV_SETINODEINFO_FAILED
IDS_RECV_SETINODEINFO_FAILED
"FSCTL_BTRFS_SET_INODE_INFO returned %08x (%s)."
IDS_RECV_SUCCESS "Received 1 subvolume successfully."
IDS_RECV_BUTTON_OK "OK"
IDS_RECV_SETFILEATTRIBUTES_FAILED
IDS_RECV_SETFILEATTRIBUTES_FAILED
"SetFileAttributes failed (error %u, %s)."
IDS_RECV_GETFILEATTRIBUTES_FAILED
IDS_RECV_GETFILEATTRIBUTES_FAILED
"GetFileAttributes failed (error %u, %s)."
IDS_RECV_CSUM_ERROR "Checksum error."
IDS_RECV_NOT_A_SEND_STREAM "File was not a send stream."
@ -685,28 +705,28 @@ END
STRINGTABLE
BEGIN
IDS_RECV_RECEIVED_SUBVOL_FAILED
IDS_RECV_RECEIVED_SUBVOL_FAILED
"FSCTL_BTRFS_RECEIVED_SUBVOL returned %08x (%s)."
IDS_RECV_SETSECURITYOBJECT_FAILED
IDS_RECV_SETSECURITYOBJECT_FAILED
"NtSetSecurityObject returned %08x (%s)."
IDS_RECV_SETXATTR_FAILED "FSCTL_BTRFS_SET_XATTR returned %08x (%s)."
IDS_RECV_CREATETHREAD_FAILED "CreateThread failed (error %u, %s)."
IDS_RECV_FILE_TRUNCATED "File was truncated."
IDS_RECV_RESERVE_SUBVOL_FAILED
IDS_RECV_RESERVE_SUBVOL_FAILED
"FSCTL_BTRFS_RESERVE_SUBVOL returned %08x (%s)."
IDS_RECV_CANCELLED "Receiving cancelled."
IDS_RECV_CANT_FIND_PARENT_SUBVOL "Could not find parent subvolume."
IDS_RECV_FIND_SUBVOL_FAILED "FSCTL_BTRFS_FIND_SUBVOL returned %08x (%s)."
IDS_RECV_CREATE_SNAPSHOT_FAILED
IDS_RECV_CREATE_SNAPSHOT_FAILED
"FSCTL_BTRFS_CREATE_SNAPSHOT returned %08x (%s)."
IDS_RECV_GETVOLUMEPATHNAME_FAILED
IDS_RECV_GETVOLUMEPATHNAME_FAILED
"GetVolumePathName failed (error %u, %s)."
IDS_RECV_DELETEFILE_FAILED "DeleteFile failed for %s (error %u, %s)."
IDS_RECV_REMOVEDIRECTORY_FAILED
IDS_RECV_REMOVEDIRECTORY_FAILED
"RemoveDirectory failed for %s (error %u, %s)."
IDS_RECV_CANT_FIND_CLONE_SUBVOL "Could not find clone subvolume."
IDS_RECV_GETFILESIZEEX_FAILED "GetFileSizeEx failed (error %u, %s)."
IDS_RECV_DUPLICATE_EXTENTS_FAILED
IDS_RECV_DUPLICATE_EXTENTS_FAILED
"FSCTL_DUPLICATE_EXTENTS_TO_FILE returned %08x (%s)."
END
@ -717,13 +737,13 @@ BEGIN
IDS_SEND_SUBVOL_HELP "Exports a subvolume so that it can be recreated on another volume."
IDS_SEND_CANT_OPEN_FILE "Error opening file %s (error %u, %s)."
IDS_SEND_CANT_OPEN_DIR "Error opening directory %s (error %u, %s)."
IDS_SEND_FSCTL_BTRFS_SEND_SUBVOL_FAILED
IDS_SEND_FSCTL_BTRFS_SEND_SUBVOL_FAILED
"FSCTL_BTRFS_SEND_SUBVOL returned error %08x (%s)."
IDS_SEND_FSCTL_BTRFS_READ_SEND_BUFFER_FAILED
IDS_SEND_FSCTL_BTRFS_READ_SEND_BUFFER_FAILED
"FSCTL_BTRFS_READ_SEND_BUFFER returned error %08x (%s)."
IDS_SEND_SUCCESS "Stream written successfully."
IDS_SEND_WRITEFILE_FAILED "Writing to file failed (error %u, %s)."
IDS_SEND_GET_FILE_INFO_FAILED
IDS_SEND_GET_FILE_INFO_FAILED
"GetFileInformationByHandle failed (error %u, %s)."
IDS_SEND_NOT_READONLY "Subvolume not readonly."
IDS_NOT_SUBVOL "Directory was not a subvolume."
@ -739,13 +759,29 @@ BEGIN
IDS_SEND_WRITING "Writing..."
IDS_MISSING "(missing)"
IDS_RESIZE_SUCCESSFUL "Device %llx successfully resized to %s."
IDS_BALANCE_RUNNING_SHRINK
IDS_BALANCE_RUNNING_SHRINK
"Currently shrinking device %llu (%llu out of %llu chunks processed, %1.1f%%)"
IDS_BALANCE_PAUSED_SHRINK
IDS_BALANCE_PAUSED_SHRINK
"Shrinking of device %llu paused (%llu out of %llu chunks processed, %1.1f%%)"
IDS_BALANCE_CANCELLED_SHRINK "Device shrinking cancelled."
IDS_BALANCE_COMPLETE_SHRINK "Device successfully shrunk."
IDS_BALANCE_FAILED_SHRINK "Device shrinking failed (error %08x, %s)"
IDS_COMPRESS_ZSTD "Zstd"
IDS_RECV_RTLUNICODETOUTF8N_FAILED "RtlUnicodeToUTF8N returned %08x (%s)."
IDS_REGCREATEKEY_FAILED "RegCreateKey returned %08x"
IDS_REGSETVALUEEX_FAILED "RegSetValueEx returned %08x"
IDS_REGCLOSEKEY_FAILED "RegCloseKey returned %08x"
IDS_REGDELETETREE_FAILED "RegDeleteTree returned %08x"
IDS_CANT_REFLINK_DIFFERENT_FS
"Cannot create a reflink between two different filesystems."
END
STRINGTABLE
BEGIN
IDS_INITCOMMONCONTROLSEX_FAILED "InitCommonControlsEx failed."
IDS_CANT_OPEN_MOUNTMGR "Could not get a handle to mount manager."
IDS_TVM_INSERTITEM_FAILED "TVM_INSERTITEM failed."
IDS_RECV_PATH_TOO_LONG "%S: path was too long."
END
#endif // English (United Kingdom) resources

View file

@ -34,8 +34,11 @@
#include <winbase.h>
#include <strsafe.h>
#include <ndk/iofuncs.h>
#include <ndk/obfuncs.h>
#endif
#include <string>
#include <vector>
#include <stdint.h>
#ifndef __REACTOS__
#include "../btrfs.h"
#include "../btrfsioctl.h"
@ -44,6 +47,8 @@
#include "btrfsioctl.h"
#endif
using namespace std;
#ifndef __REACTOS__
#define STATUS_SUCCESS (NTSTATUS)0x00000000
#define STATUS_BUFFER_OVERFLOW (NTSTATUS)0x80000005
@ -79,6 +84,10 @@
#define funcname __func__
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4800)
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -95,6 +104,10 @@ NTSTATUS WINAPI RtlUTF8ToUnicodeN(PWSTR UnicodeStringDestination, ULONG UnicodeS
PULONG UnicodeStringActualWCharCount, PCCH UTF8StringSource,
ULONG UTF8StringByteCount);
NTSTATUS NTAPI RtlUnicodeToUTF8N(PCHAR UTF8StringDestination, ULONG UTF8StringMaxByteCount,
PULONG UTF8StringActualByteCount, PCWCH UnicodeStringSource,
ULONG UnicodeStringByteCount);
#ifndef __REACTOS__
NTSTATUS WINAPI NtSetEaFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length);
@ -179,11 +192,163 @@ typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {
#endif
class win_handle {
public:
win_handle() {
}
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:
HANDLE h = INVALID_HANDLE_VALUE;
};
class fff_handle {
public:
fff_handle() {
}
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:
HANDLE h = INVALID_HANDLE_VALUE;
};
class nt_handle {
public:
nt_handle() {
}
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:
HANDLE h = INVALID_HANDLE_VALUE;
};
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();
}
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
extern HMODULE module;
void ShowError(HWND hwnd, ULONG err);
void ShowNtStatusError(HWND hwnd, NTSTATUS Status);
void ShowStringError(HWND hwndDlg, int num, ...);
void format_size(UINT64 size, WCHAR* s, ULONG len, BOOL show_bytes);
void format_size(uint64_t size, wstring& s, bool show_bytes);
void set_dpi_aware();
std::wstring format_message(ULONG last_error);
std::wstring format_ntstatus(NTSTATUS Status);
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, ...);
void command_line_to_args(LPWSTR cmdline, vector<wstring> args);
void utf8_to_utf16(const string& utf8, wstring& utf16);
void utf16_to_utf8(const wstring& utf16, string& utf8);
void error_message(HWND hwnd, const char* msg);

File diff suppressed because it is too large Load diff

View file

@ -34,13 +34,13 @@ class BtrfsVolPropSheet : public IShellExtInit, IShellPropSheetExt {
public:
BtrfsVolPropSheet() {
refcount = 0;
ignore = TRUE;
stgm_set = FALSE;
devices = NULL;
ignore = true;
stgm_set = false;
devices = nullptr;
InterlockedIncrement(&objs_loaded);
balance = NULL;
balance = nullptr;
}
virtual ~BtrfsVolPropSheet() {
@ -84,7 +84,7 @@ public:
virtual HRESULT __stdcall AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
virtual HRESULT __stdcall ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
void FormatUsage(HWND hwndDlg, WCHAR* s, ULONG size, btrfs_usage* usage);
void FormatUsage(HWND hwndDlg, wstring& s, btrfs_usage* usage);
void RefreshUsage(HWND hwndDlg);
void ShowUsage(HWND hwndDlg);
INT_PTR CALLBACK UsageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -93,20 +93,20 @@ public:
void ShowDevices(HWND hwndDlg);
void ShowScrub(HWND hwndDlg);
INT_PTR CALLBACK StatsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void ShowStats(HWND hwndDlg, UINT64 devid);
void ShowStats(HWND hwndDlg, uint64_t devid);
void ResetStats(HWND hwndDlg);
btrfs_device* devices;
BOOL readonly;
bool readonly;
BtrfsBalance* balance;
BTRFS_UUID uuid;
BOOL uuid_set;
bool uuid_set;
private:
LONG refcount;
BOOL ignore;
bool ignore;
STGMEDIUM stgm;
BOOL stgm_set;
WCHAR fn[MAX_PATH];
UINT64 stats_dev;
bool stgm_set;
wstring fn;
uint64_t stats_dev;
};

View file

@ -4,7 +4,7 @@
The following FSD are shared with: https://github.com/maharmstone/btrfs.
reactos/drivers/filesystems/btrfs # Synced to 1.1
reactos/dll/shellext/shellbtrfs # Synced to 1.0.2
reactos/dll/shellext/shellbtrfs # Synced to 1.1
reactos/sdk/lib/fslib/btrfslib # Synced to 1.0.2
The following FSD are shared with: http://www.ext2fsd.com/