[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) remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x603) 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) include_directories(${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs)
spec2def(shellbtrfs.dll shellbtrfs.spec) spec2def(shellbtrfs.dll shellbtrfs.spec)

File diff suppressed because it is too large Load diff

View file

@ -26,12 +26,12 @@
class BtrfsBalance { class BtrfsBalance {
public: public:
BtrfsBalance(WCHAR* drive, BOOL RemoveDevice = FALSE, BOOL ShrinkDevice = FALSE) { BtrfsBalance(const wstring& drive, bool RemoveDevice = false, bool ShrinkDevice = false) {
removing = FALSE; removing = false;
devices = NULL; devices = nullptr;
called_from_RemoveDevice = RemoveDevice; called_from_RemoveDevice = RemoveDevice;
called_from_ShrinkDevice = ShrinkDevice; called_from_ShrinkDevice = ShrinkDevice;
wcscpy(fn, drive); fn = drive;
} }
void ShowBalance(HWND hwndDlg); void ShowBalance(HWND hwndDlg);
@ -39,22 +39,22 @@ public:
INT_PTR CALLBACK BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
private: private:
void ShowBalanceOptions(HWND hwndDlg, UINT8 type); void ShowBalanceOptions(HWND hwndDlg, uint8_t type);
void SaveBalanceOpts(HWND hwndDlg); void SaveBalanceOpts(HWND hwndDlg);
void StartBalance(HWND hwndDlg); void StartBalance(HWND hwndDlg);
void RefreshBalanceDlg(HWND hwndDlg, BOOL first); void RefreshBalanceDlg(HWND hwndDlg, bool first);
void PauseBalance(HWND hwndDlg); void PauseBalance(HWND hwndDlg);
void StopBalance(HWND hwndDlg); void StopBalance(HWND hwndDlg);
UINT32 balance_status; uint32_t balance_status;
btrfs_balance_opts data_opts, metadata_opts, system_opts; btrfs_balance_opts data_opts, metadata_opts, system_opts;
UINT8 opts_type; uint8_t opts_type;
btrfs_query_balance bqb; btrfs_query_balance bqb;
BOOL cancelling; bool cancelling;
BOOL removing; bool removing;
BOOL shrinking; bool shrinking;
WCHAR fn[MAX_PATH]; wstring fn;
btrfs_device* devices; btrfs_device* devices;
BOOL readonly; bool readonly;
BOOL called_from_RemoveDevice, called_from_ShrinkDevice; 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: public:
BtrfsContextMenu() { BtrfsContextMenu() {
refcount = 0; refcount = 0;
ignore = TRUE; ignore = true;
stgm_set = FALSE; stgm_set = false;
uacicon = NULL; uacicon = nullptr;
allow_snapshot = FALSE; allow_snapshot = false;
InterlockedIncrement(&objs_loaded); InterlockedIncrement(&objs_loaded);
} }
@ -73,13 +73,13 @@ public:
private: private:
LONG refcount; LONG refcount;
BOOL ignore, allow_snapshot; bool ignore, allow_snapshot;
BOOL bg; bool bg;
WCHAR path[MAX_PATH]; wstring path;
STGMEDIUM stgm; STGMEDIUM stgm;
BOOL stgm_set; bool stgm_set;
HBITMAP uacicon; 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(); void get_uac_icon();
}; };

File diff suppressed because it is too large Load diff

View file

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

View file

@ -39,17 +39,16 @@ HRESULT __stdcall BtrfsIconOverlay::QueryInterface(REFIID riid, void **ppObj) {
return S_OK; return S_OK;
} }
*ppObj = NULL; *ppObj = nullptr;
return E_NOINTERFACE; return E_NOINTERFACE;
} }
HRESULT __stdcall BtrfsIconOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMax, int* pIndex, DWORD* pdwFlags) { 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 (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
return E_FAIL;
if ((size_t)cchMax < wcslen(dllpath))
return E_INVALIDARG;
if (!pIndex) if (!pIndex)
return E_INVALIDARG; return E_INVALIDARG;
@ -57,7 +56,6 @@ HRESULT __stdcall BtrfsIconOverlay::GetOverlayInfo(PWSTR pwszIconFile, int cchMa
if (!pdwFlags) if (!pdwFlags)
return E_INVALIDARG; return E_INVALIDARG;
wcscpy(pwszIconFile, dllpath);
*pIndex = 0; *pIndex = 0;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX; *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
@ -74,24 +72,20 @@ HRESULT __stdcall BtrfsIconOverlay::GetPriority(int *pPriority) {
} }
HRESULT __stdcall BtrfsIconOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib) { HRESULT __stdcall BtrfsIconOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib) {
HANDLE h; win_handle h;
NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK iosb; IO_STATUS_BLOCK iosb;
btrfs_get_file_ids bgfi; 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) if (h == INVALID_HANDLE_VALUE)
return S_FALSE; 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)) { if (!NT_SUCCESS(Status))
CloseHandle(h);
return S_FALSE; return S_FALSE;
}
CloseHandle(h);
return (bgfi.inode == 0x100 && !bgfi.top) ? S_OK : S_FALSE; 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 <shlobj.h>
#include <deque> #include <deque>
#include <string>
#ifndef __REACTOS__ #ifndef __REACTOS__
#include "../btrfsioctl.h" #include "../btrfsioctl.h"
#else #else
@ -93,25 +92,27 @@ class BtrfsPropSheet : public IShellExtInit, IShellPropSheetExt {
public: public:
BtrfsPropSheet() { BtrfsPropSheet() {
refcount = 0; refcount = 0;
ignore = TRUE; ignore = true;
stgm_set = FALSE; stgm_set = false;
readonly = FALSE; readonly = false;
flags_changed = FALSE; flags_changed = false;
perms_changed = FALSE; perms_changed = false;
uid_changed = FALSE; uid_changed = false;
gid_changed = FALSE; gid_changed = false;
compress_type_changed = FALSE; compress_type_changed = false;
ro_changed = FALSE; ro_changed = false;
can_change_perms = FALSE; can_change_perms = false;
show_admin_button = FALSE; show_admin_button = false;
thread = NULL; thread = nullptr;
mode = mode_set = 0; mode = mode_set = 0;
flags = flags_set = 0; flags = flags_set = 0;
has_subvols = FALSE; has_subvols = false;
filename = L""; filename = L"";
sizes[0] = sizes[1] = sizes[2] = sizes[3] = 0; sizes[0] = sizes[1] = sizes[2] = sizes[3] = sizes[4] = 0;
totalsize = 0; totalsize = allocsize = sparsesize = 0;
size_format[0] = 0;
cr_format[0] = 0;
InterlockedIncrement(&objs_loaded); InterlockedIncrement(&objs_loaded);
} }
@ -152,43 +153,42 @@ public:
virtual HRESULT __stdcall ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam); virtual HRESULT __stdcall ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
void init_propsheet(HWND hwndDlg); 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_perm_flag(HWND hDlg, ULONG perm, UINT state);
void change_uid(HWND hDlg, UINT32 uid); void change_uid(HWND hDlg, uint32_t uid);
void change_gid(HWND hDlg, UINT32 gid); void change_gid(HWND hDlg, uint32_t gid);
void apply_changes(HWND hDlg); void apply_changes(HWND hDlg);
void set_size_on_disk(HWND hwndDlg); void set_size_on_disk(HWND hwndDlg);
void add_to_search_list(WCHAR* fn);
DWORD search_list_thread(); DWORD search_list_thread();
void do_search(WCHAR* fn); void do_search(const wstring& fn);
void update_size_details_dialog(HWND hDlg); void update_size_details_dialog(HWND hDlg);
void open_as_admin(HWND hwndDlg); void open_as_admin(HWND hwndDlg);
void set_cmdline(std::wstring cmdline); void set_cmdline(const wstring& cmdline);
BOOL readonly; bool readonly;
BOOL can_change_perms; bool can_change_perms;
BOOL can_change_nocow; bool can_change_nocow;
WCHAR size_format[255]; WCHAR size_format[255], cr_format[255];
HANDLE thread; HANDLE thread;
UINT32 min_mode, max_mode, mode, mode_set; uint32_t min_mode, max_mode, mode, mode_set;
UINT64 min_flags, max_flags, flags, flags_set; uint64_t min_flags, max_flags, flags, flags_set;
UINT64 subvol, inode, rdev; uint64_t subvol, inode, rdev;
UINT8 type, min_compression_type, max_compression_type, compress_type; uint8_t type, min_compression_type, max_compression_type, compress_type;
UINT32 uid, gid; uint32_t uid, gid;
BOOL various_subvols, various_inodes, various_types, various_uids, various_gids, compress_type_changed, has_subvols, 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; ro_subvol, various_ro, ro_changed, show_admin_button;
private: private:
LONG refcount; LONG refcount;
BOOL ignore; bool ignore;
STGMEDIUM stgm; STGMEDIUM stgm;
BOOL stgm_set; bool stgm_set;
BOOL flags_changed, perms_changed, uid_changed, gid_changed; bool flags_changed, perms_changed, uid_changed, gid_changed;
UINT64 sizes[4], totalsize; uint64_t sizes[5], totalsize, allocsize, sparsesize;
std::deque<WCHAR*> search_list; deque<wstring> search_list;
std::wstring filename; wstring filename;
void apply_changes_file(HWND hDlg, std::wstring fn); void apply_changes_file(HWND hDlg, const wstring& fn);
HRESULT check_file(std::wstring fn, UINT i, UINT num_files, UINT* sv); HRESULT check_file(const wstring& fn, UINT i, UINT num_files, UINT* sv);
HRESULT load_file_list(); HRESULT load_file_list();
}; };

File diff suppressed because it is too large Load diff

View file

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

View file

@ -196,6 +196,17 @@
#define IDS_BALANCE_CANCELLED_SHRINK 278 #define IDS_BALANCE_CANCELLED_SHRINK 278
#define IDS_BALANCE_COMPLETE_SHRINK 279 #define IDS_BALANCE_COMPLETE_SHRINK 279
#define IDS_BALANCE_FAILED_SHRINK 280 #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_UID 1001
#define IDC_GID 1002 #define IDC_GID 1002
#define IDC_USERR 1003 #define IDC_USERR 1003
@ -226,6 +237,8 @@
#define IDC_SIZE_LZO 1022 #define IDC_SIZE_LZO 1022
#define IDC_VOL_SHOW_USAGE 1022 #define IDC_VOL_SHOW_USAGE 1022
#define IDC_VOL_BALANCE 1023 #define IDC_VOL_BALANCE 1023
#define IDC_SIZE_ZSTD 1023
#define IDC_COMPRESSION_RATIO 1023
#define IDC_PROFILES 1024 #define IDC_PROFILES 1024
#define IDC_PROFILES_SINGLE 1025 #define IDC_PROFILES_SINGLE 1025
#define IDC_PROFILES_DUP 1026 #define IDC_PROFILES_DUP 1026
@ -324,7 +337,7 @@
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #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_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1073 #define _APS_NEXT_CONTROL_VALUE 1073
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -25,18 +25,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
// TEXTINCLUDE // TEXTINCLUDE
// //
1 TEXTINCLUDE 1 TEXTINCLUDE
BEGIN BEGIN
"resource.h\0" "resource.h\0"
END END
2 TEXTINCLUDE 2 TEXTINCLUDE
BEGIN BEGIN
"#include ""winres.h""\r\n" "#include ""winres.h""\r\n"
"\0" "\0"
END END
3 TEXTINCLUDE 3 TEXTINCLUDE
BEGIN BEGIN
"\r\n" "\r\n"
"\0" "\0"
@ -61,8 +61,8 @@ IDI_ICON1 ICON "subvol.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,2,0 FILEVERSION 1,1,0,0
PRODUCTVERSION 1,0,2,0 PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -78,12 +78,12 @@ BEGIN
BLOCK "080904b0" BLOCK "080904b0"
BEGIN BEGIN
VALUE "FileDescription", "WinBtrfs shell extension" VALUE "FileDescription", "WinBtrfs shell extension"
VALUE "FileVersion", "1.0.2" VALUE "FileVersion", "1.1"
VALUE "InternalName", "btrfs" VALUE "InternalName", "btrfs"
VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-18" VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-18"
VALUE "OriginalFilename", "shellbtrfs.dll" VALUE "OriginalFilename", "shellbtrfs.dll"
VALUE "ProductName", "WinBtrfs" VALUE "ProductName", "WinBtrfs"
VALUE "ProductVersion", "1.0.2" VALUE "ProductVersion", "1.1"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -98,57 +98,59 @@ END
// Dialog // 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 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Inode property sheet" CAPTION "Inode property sheet"
FONT 8, "MS Shell Dlg", 400, 0, 0x0 FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Subvolume:",IDC_STATIC,14,21,38,8 LTEXT "Subvolume:",IDC_STATIC,14,21,38,8
LTEXT "Inode:",IDC_STATIC,14,35,21,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 LTEXT "Type:",IDC_STATIC,14,49,18,8
GROUPBOX "POSIX permissions",IDC_STATIC,7,82,221,102 GROUPBOX "POSIX permissions",IDC_STATIC,7,96,221,102
LTEXT "User:",IDC_STATIC,14,97,17,8 LTEXT "User:",IDC_STATIC,14,111,17,8
LTEXT "Group:",IDC_STATIC,14,113,22,8 LTEXT "Group:",IDC_STATIC,14,127,22,8
EDITTEXT IDC_UID,94,95,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_UID,94,109,40,14,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_GID,94,111,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_GID,94,125,40,14,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "User",IDC_STATIC,14,144,15,8 LTEXT "User",IDC_STATIC,14,158,15,8
LTEXT "Group",IDC_STATIC,14,156,20,8 LTEXT "Group",IDC_STATIC,14,168,20,8
LTEXT "Others",IDC_STATIC,14,168,22,8 LTEXT "Others",IDC_STATIC,14,182,22,8
LTEXT "Read",IDC_STATIC,50,134,17,8 LTEXT "Read",IDC_STATIC,50,148,17,8
LTEXT "Write",IDC_STATIC,89,134,18,8 LTEXT "Write",IDC_STATIC,89,148,18,8
LTEXT "Execute",IDC_STATIC,129,134,30,8 LTEXT "Execute",IDC_STATIC,129,148,30,8
CONTROL "",IDC_USERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,147,16,10 CONTROL "",IDC_USERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,161,16,10
CONTROL "",IDC_GROUPR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,158,16,10 CONTROL "",IDC_GROUPR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,172,16,10
CONTROL "",IDC_OTHERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,168,16,10 CONTROL "",IDC_OTHERR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,182,16,10
CONTROL "",IDC_USERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,147,16,10 CONTROL "",IDC_USERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,161,16,10
CONTROL "",IDC_GROUPW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,158,16,10 CONTROL "",IDC_GROUPW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,172,16,10
CONTROL "",IDC_OTHERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,168,16,10 CONTROL "",IDC_OTHERW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,182,16,10
CONTROL "",IDC_USERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,147,16,10 CONTROL "",IDC_USERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,161,16,10
CONTROL "",IDC_GROUPX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,158,16,10 CONTROL "",IDC_GROUPX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,172,16,10
CONTROL "",IDC_OTHERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,168,16,10 CONTROL "",IDC_OTHERX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,182,16,10
GROUPBOX "Flags",IDC_STATIC,7,190,221,48 GROUPBOX "Flags",IDC_STATIC,7,204,221,48
CONTROL "Disable Copy-on-Write",IDC_NODATACOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,86,10 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_INODE,78,35,70,8
LTEXT "(blank)",IDC_TYPE,78,49,116,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 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 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 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,204,80,10 CONTROL "Readonly subvolume",IDC_SUBVOL_RO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,124,218,80,10
LTEXT "(blank)",IDC_SUBVOL,78,21,70,8 LTEXT "(blank)",IDC_SUBVOL,78,21,70,8
PUSHBUTTON "&Open as Admin",IDC_OPEN_ADMIN,151,21,70,14 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 UID",IDC_SETUID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,161,40,10
CONTROL "Set GID",IDC_SETGID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,158,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,168,34,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 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 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Size details" CAPTION "Size details"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,81,64,50,14 DEFPUSHBUTTON "OK",IDOK,81,77,50,14
LTEXT "Inline:",IDC_STATIC,7,7,21,8 LTEXT "Inline:",IDC_STATIC,7,7,21,8
LTEXT "Uncompressed:",IDC_STATIC,7,20,49,8 LTEXT "Uncompressed:",IDC_STATIC,7,20,49,8
LTEXT "ZLIB:",IDC_STATIC,7,33,18,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_UNCOMPRESSED,63,20,142,8
LTEXT "(blank)",IDC_SIZE_ZLIB,63,33,142,8 LTEXT "(blank)",IDC_SIZE_ZLIB,63,33,142,8
LTEXT "(blank)",IDC_SIZE_LZO,63,46,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 END
IDD_VOL_PROP_SHEET DIALOGEX 0, 0, 235, 251 IDD_VOL_PROP_SHEET DIALOGEX 0, 0, 235, 251
@ -382,7 +386,7 @@ BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 205 RIGHTMARGIN, 205
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 78 BOTTOMMARGIN, 93
END END
IDD_VOL_PROP_SHEET, DIALOG IDD_VOL_PROP_SHEET, DIALOG
@ -484,6 +488,22 @@ END
2 RT_MANIFEST "shellbtrfs.manifest" 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 // String Table
@ -575,9 +595,9 @@ BEGIN
IDS_DEVLIST_READONLY_NO "No" IDS_DEVLIST_READONLY_NO "No"
IDS_DEVLIST_ALLOC "Allocated" IDS_DEVLIST_ALLOC "Allocated"
IDS_DEVLIST_ALLOC_PC "%" IDS_DEVLIST_ALLOC_PC "%"
IDS_BALANCE_RUNNING_REMOVAL IDS_BALANCE_RUNNING_REMOVAL
"Currently removing device %llu (%llu out of %llu chunks processed, %1.1f%%)" "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%%)" "Removal of device %llu paused (%llu out of %llu chunks processed, %1.1f%%)"
IDS_BALANCE_CANCELLED_REMOVAL "Device removal cancelled." IDS_BALANCE_CANCELLED_REMOVAL "Device removal cancelled."
IDS_BALANCE_COMPLETE_REMOVAL "Device removal completed successfully." IDS_BALANCE_COMPLETE_REMOVAL "Device removal completed successfully."
@ -588,12 +608,12 @@ END
STRINGTABLE STRINGTABLE
BEGIN 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_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?" "Are you sure that you want to remove device %s, %s?"
IDS_CONFIRMATION_TITLE "Confirmation" IDS_CONFIRMATION_TITLE "Confirmation"
IDS_ADD_DEVICE_CONFIRMATION IDS_ADD_DEVICE_CONFIRMATION
"Are you sure that you want to add this device?" "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)." "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 "Balance failed (error %08x, %s)"
IDS_BALANCE_FAILED_REMOVAL "Device removal 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_FINISHED "Scrub finished."
IDS_SCRUB_PAUSED "Scrub paused (%llu out of %llu chunks processed, %1.1f%%)" 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_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." "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." "Recovered from metadata checksum error at %llx on device %llx."
END END
STRINGTABLE STRINGTABLE
BEGIN BEGIN
IDS_SCRUB_MSG_UNRECOVERABLE_DATA IDS_SCRUB_MSG_UNRECOVERABLE_DATA
"Unrecoverable data checksum error at %llx on device %llx (%.*s, offset %llx)" "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)" "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)" "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)" "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_FINISHED "Scrub finished at %s %s."
IDS_SCRUB_MSG_SUMMARY "Scrubbed %s in %llu seconds (%s/s)." IDS_SCRUB_MSG_SUMMARY "Scrubbed %s in %llu seconds (%s/s)."
IDS_BALANCE_SCRUB_RUNNING "Cannot start balance while scrub running." IDS_BALANCE_SCRUB_RUNNING "Cannot start balance while scrub running."
IDS_SCRUB_BALANCE_RUNNING "Cannot start scrub while balance 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_RECOVERABLE "Recovered from %llu error(s)."
IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE
"%llu unrecoverable error(s) found." "%llu unrecoverable error(s) found."
IDS_SCRUB_FAILED "Scrub failed with error %08x." 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_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." "Recovered from parity error at %llx on device %llx."
IDS_COMPRESS_ANY "(any)" IDS_COMPRESS_ANY "(any)"
IDS_COMPRESS_ZLIB "Zlib" IDS_COMPRESS_ZLIB "Zlib"
@ -649,12 +669,12 @@ BEGIN
IDS_RECV_UNKNOWN_COMMAND "Unrecognized command %u encountered." IDS_RECV_UNKNOWN_COMMAND "Unrecognized command %u encountered."
IDS_RECV_CANT_OPEN_PATH "Couldn't open path %s (error %u, %s)." IDS_RECV_CANT_OPEN_PATH "Couldn't open path %s (error %u, %s)."
IDS_RECV_RTLUTF8TOUNICODEN_FAILED "RtlUTF8ToUnicodeN returned %08x (%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)." "FSCTL_BTRFS_CREATE_SUBVOL returned %08x (%s)."
IDS_RECV_MISSING_PARAM "%S: could not find %s parameter." 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_SHORT_PARAM "%S: length of parameter %s was %u, expected %u."
IDS_RECV_MKNOD_FAILED "FSCTL_BTRFS_MKNOD returned %08x (%s)." 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)." "FSCTL_SET_REPARSE_POINT returned %08x (%s)."
END END
@ -663,19 +683,19 @@ BEGIN
IDS_RECV_MOVEFILE_FAILED "MoveFile (%s -> %s) failed (error %u, %s)." IDS_RECV_MOVEFILE_FAILED "MoveFile (%s -> %s) failed (error %u, %s)."
IDS_RECV_SETFILEPOINTER_FAILED "SetFilePointer failed (error %u, %s)." IDS_RECV_SETFILEPOINTER_FAILED "SetFilePointer failed (error %u, %s)."
IDS_RECV_WRITEFILE_FAILED "WriteFile 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)." "CreateHardLink (%s -> %s) failed (error %u, %s)."
IDS_RECV_SETENDOFFILE_FAILED "SetEndOfFile 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_CANT_CREATE_FILE "Couldn't create %s (error %u, %s)."
IDS_RECV_SETFILEINFO_FAILED IDS_RECV_SETFILEINFO_FAILED
"SetFileInformationByHandle failed (error %u, %s)." "SetFileInformationByHandle failed (error %u, %s)."
IDS_RECV_SETINODEINFO_FAILED IDS_RECV_SETINODEINFO_FAILED
"FSCTL_BTRFS_SET_INODE_INFO returned %08x (%s)." "FSCTL_BTRFS_SET_INODE_INFO returned %08x (%s)."
IDS_RECV_SUCCESS "Received 1 subvolume successfully." IDS_RECV_SUCCESS "Received 1 subvolume successfully."
IDS_RECV_BUTTON_OK "OK" IDS_RECV_BUTTON_OK "OK"
IDS_RECV_SETFILEATTRIBUTES_FAILED IDS_RECV_SETFILEATTRIBUTES_FAILED
"SetFileAttributes failed (error %u, %s)." "SetFileAttributes failed (error %u, %s)."
IDS_RECV_GETFILEATTRIBUTES_FAILED IDS_RECV_GETFILEATTRIBUTES_FAILED
"GetFileAttributes failed (error %u, %s)." "GetFileAttributes failed (error %u, %s)."
IDS_RECV_CSUM_ERROR "Checksum error." IDS_RECV_CSUM_ERROR "Checksum error."
IDS_RECV_NOT_A_SEND_STREAM "File was not a send stream." IDS_RECV_NOT_A_SEND_STREAM "File was not a send stream."
@ -685,28 +705,28 @@ END
STRINGTABLE STRINGTABLE
BEGIN BEGIN
IDS_RECV_RECEIVED_SUBVOL_FAILED IDS_RECV_RECEIVED_SUBVOL_FAILED
"FSCTL_BTRFS_RECEIVED_SUBVOL returned %08x (%s)." "FSCTL_BTRFS_RECEIVED_SUBVOL returned %08x (%s)."
IDS_RECV_SETSECURITYOBJECT_FAILED IDS_RECV_SETSECURITYOBJECT_FAILED
"NtSetSecurityObject returned %08x (%s)." "NtSetSecurityObject returned %08x (%s)."
IDS_RECV_SETXATTR_FAILED "FSCTL_BTRFS_SET_XATTR 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_CREATETHREAD_FAILED "CreateThread failed (error %u, %s)."
IDS_RECV_FILE_TRUNCATED "File was truncated." IDS_RECV_FILE_TRUNCATED "File was truncated."
IDS_RECV_RESERVE_SUBVOL_FAILED IDS_RECV_RESERVE_SUBVOL_FAILED
"FSCTL_BTRFS_RESERVE_SUBVOL returned %08x (%s)." "FSCTL_BTRFS_RESERVE_SUBVOL returned %08x (%s)."
IDS_RECV_CANCELLED "Receiving cancelled." IDS_RECV_CANCELLED "Receiving cancelled."
IDS_RECV_CANT_FIND_PARENT_SUBVOL "Could not find parent subvolume." 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_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)." "FSCTL_BTRFS_CREATE_SNAPSHOT returned %08x (%s)."
IDS_RECV_GETVOLUMEPATHNAME_FAILED IDS_RECV_GETVOLUMEPATHNAME_FAILED
"GetVolumePathName failed (error %u, %s)." "GetVolumePathName failed (error %u, %s)."
IDS_RECV_DELETEFILE_FAILED "DeleteFile failed for %s (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)." "RemoveDirectory failed for %s (error %u, %s)."
IDS_RECV_CANT_FIND_CLONE_SUBVOL "Could not find clone subvolume." IDS_RECV_CANT_FIND_CLONE_SUBVOL "Could not find clone subvolume."
IDS_RECV_GETFILESIZEEX_FAILED "GetFileSizeEx failed (error %u, %s)." 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)." "FSCTL_DUPLICATE_EXTENTS_TO_FILE returned %08x (%s)."
END END
@ -717,13 +737,13 @@ BEGIN
IDS_SEND_SUBVOL_HELP "Exports a subvolume so that it can be recreated on another volume." 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_FILE "Error opening file %s (error %u, %s)."
IDS_SEND_CANT_OPEN_DIR "Error opening directory %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)." "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)." "FSCTL_BTRFS_READ_SEND_BUFFER returned error %08x (%s)."
IDS_SEND_SUCCESS "Stream written successfully." IDS_SEND_SUCCESS "Stream written successfully."
IDS_SEND_WRITEFILE_FAILED "Writing to file failed (error %u, %s)." 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)." "GetFileInformationByHandle failed (error %u, %s)."
IDS_SEND_NOT_READONLY "Subvolume not readonly." IDS_SEND_NOT_READONLY "Subvolume not readonly."
IDS_NOT_SUBVOL "Directory was not a subvolume." IDS_NOT_SUBVOL "Directory was not a subvolume."
@ -739,13 +759,29 @@ BEGIN
IDS_SEND_WRITING "Writing..." IDS_SEND_WRITING "Writing..."
IDS_MISSING "(missing)" IDS_MISSING "(missing)"
IDS_RESIZE_SUCCESSFUL "Device %llx successfully resized to %s." 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%%)" "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%%)" "Shrinking of device %llu paused (%llu out of %llu chunks processed, %1.1f%%)"
IDS_BALANCE_CANCELLED_SHRINK "Device shrinking cancelled." IDS_BALANCE_CANCELLED_SHRINK "Device shrinking cancelled."
IDS_BALANCE_COMPLETE_SHRINK "Device successfully shrunk." IDS_BALANCE_COMPLETE_SHRINK "Device successfully shrunk."
IDS_BALANCE_FAILED_SHRINK "Device shrinking failed (error %08x, %s)" 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 END
#endif // English (United Kingdom) resources #endif // English (United Kingdom) resources

View file

@ -34,8 +34,11 @@
#include <winbase.h> #include <winbase.h>
#include <strsafe.h> #include <strsafe.h>
#include <ndk/iofuncs.h> #include <ndk/iofuncs.h>
#include <ndk/obfuncs.h>
#endif #endif
#include <string> #include <string>
#include <vector>
#include <stdint.h>
#ifndef __REACTOS__ #ifndef __REACTOS__
#include "../btrfs.h" #include "../btrfs.h"
#include "../btrfsioctl.h" #include "../btrfsioctl.h"
@ -44,6 +47,8 @@
#include "btrfsioctl.h" #include "btrfsioctl.h"
#endif #endif
using namespace std;
#ifndef __REACTOS__ #ifndef __REACTOS__
#define STATUS_SUCCESS (NTSTATUS)0x00000000 #define STATUS_SUCCESS (NTSTATUS)0x00000000
#define STATUS_BUFFER_OVERFLOW (NTSTATUS)0x80000005 #define STATUS_BUFFER_OVERFLOW (NTSTATUS)0x80000005
@ -79,6 +84,10 @@
#define funcname __func__ #define funcname __func__
#endif #endif
#ifdef _MSC_VER
#pragma warning(disable: 4800)
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -95,6 +104,10 @@ NTSTATUS WINAPI RtlUTF8ToUnicodeN(PWSTR UnicodeStringDestination, ULONG UnicodeS
PULONG UnicodeStringActualWCharCount, PCCH UTF8StringSource, PULONG UnicodeStringActualWCharCount, PCCH UTF8StringSource,
ULONG UTF8StringByteCount); ULONG UTF8StringByteCount);
NTSTATUS NTAPI RtlUnicodeToUTF8N(PCHAR UTF8StringDestination, ULONG UTF8StringMaxByteCount,
PULONG UTF8StringActualByteCount, PCWCH UnicodeStringSource,
ULONG UnicodeStringByteCount);
#ifndef __REACTOS__ #ifndef __REACTOS__
NTSTATUS WINAPI NtSetEaFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length); 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 #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; extern HMODULE module;
void ShowError(HWND hwnd, ULONG err); void format_size(uint64_t size, wstring& s, bool show_bytes);
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 set_dpi_aware(); void set_dpi_aware();
std::wstring format_message(ULONG last_error); wstring format_message(ULONG last_error);
std::wstring format_ntstatus(NTSTATUS Status); 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: public:
BtrfsVolPropSheet() { BtrfsVolPropSheet() {
refcount = 0; refcount = 0;
ignore = TRUE; ignore = true;
stgm_set = FALSE; stgm_set = false;
devices = NULL; devices = nullptr;
InterlockedIncrement(&objs_loaded); InterlockedIncrement(&objs_loaded);
balance = NULL; balance = nullptr;
} }
virtual ~BtrfsVolPropSheet() { virtual ~BtrfsVolPropSheet() {
@ -84,7 +84,7 @@ public:
virtual HRESULT __stdcall AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam); virtual HRESULT __stdcall AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
virtual HRESULT __stdcall ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, 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 RefreshUsage(HWND hwndDlg);
void ShowUsage(HWND hwndDlg); void ShowUsage(HWND hwndDlg);
INT_PTR CALLBACK UsageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK UsageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -93,20 +93,20 @@ public:
void ShowDevices(HWND hwndDlg); void ShowDevices(HWND hwndDlg);
void ShowScrub(HWND hwndDlg); void ShowScrub(HWND hwndDlg);
INT_PTR CALLBACK StatsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 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); void ResetStats(HWND hwndDlg);
btrfs_device* devices; btrfs_device* devices;
BOOL readonly; bool readonly;
BtrfsBalance* balance; BtrfsBalance* balance;
BTRFS_UUID uuid; BTRFS_UUID uuid;
BOOL uuid_set; bool uuid_set;
private: private:
LONG refcount; LONG refcount;
BOOL ignore; bool ignore;
STGMEDIUM stgm; STGMEDIUM stgm;
BOOL stgm_set; bool stgm_set;
WCHAR fn[MAX_PATH]; wstring fn;
UINT64 stats_dev; uint64_t stats_dev;
}; };

View file

@ -4,7 +4,7 @@
The following FSD are shared with: https://github.com/maharmstone/btrfs. The following FSD are shared with: https://github.com/maharmstone/btrfs.
reactos/drivers/filesystems/btrfs # Synced to 1.1 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 reactos/sdk/lib/fslib/btrfslib # Synced to 1.0.2
The following FSD are shared with: http://www.ext2fsd.com/ The following FSD are shared with: http://www.ext2fsd.com/