https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7b718d3627d04806da5a11...
commit 7b718d3627d04806da5a11c474be103e2768b913 Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Sun Dec 16 12:04:40 2018 +0100 Commit: Pierre Schweitzer pierre@reactos.org CommitDate: Sun Dec 16 12:06:46 2018 +0100
[SHELLBTRFS] Upgrade to 1.1
CORE-15452 --- dll/shellext/shellbtrfs/CMakeLists.txt | 4 + dll/shellext/shellbtrfs/balance.cpp | 1380 +++++++++---------- dll/shellext/shellbtrfs/balance.h | 28 +- dll/shellext/shellbtrfs/contextmenu.cpp | 1549 ++++++++++------------ dll/shellext/shellbtrfs/contextmenu.h | 18 +- dll/shellext/shellbtrfs/devices.cpp | 891 ++++++------- dll/shellext/shellbtrfs/devices.h | 35 +- dll/shellext/shellbtrfs/factory.cpp | 4 +- dll/shellext/shellbtrfs/iconoverlay.cpp | 24 +- dll/shellext/shellbtrfs/main.cpp | 887 ++++++++----- dll/shellext/shellbtrfs/propsheet.cpp | 1126 ++++++++-------- dll/shellext/shellbtrfs/propsheet.h | 82 +- dll/shellext/shellbtrfs/recv.cpp | 2138 ++++++++++++------------------ dll/shellext/shellbtrfs/recv.h | 64 +- dll/shellext/shellbtrfs/resource.h | 15 +- dll/shellext/shellbtrfs/scrub.cpp | 733 +++++----- dll/shellext/shellbtrfs/scrub.h | 14 +- dll/shellext/shellbtrfs/send.cpp | 817 ++++++------ dll/shellext/shellbtrfs/send.h | 18 +- dll/shellext/shellbtrfs/shellbtrfs.rc | 180 ++- dll/shellext/shellbtrfs/shellext.h | 177 ++- dll/shellext/shellbtrfs/volpropsheet.cpp | 1591 ++++++++++------------ dll/shellext/shellbtrfs/volpropsheet.h | 24 +- media/doc/README.FSD | 2 +- 24 files changed, 5649 insertions(+), 6152 deletions(-)
diff --git a/dll/shellext/shellbtrfs/CMakeLists.txt b/dll/shellext/shellbtrfs/CMakeLists.txt index 6802f6b108..5b239ca2e1 100644 --- a/dll/shellext/shellbtrfs/CMakeLists.txt +++ b/dll/shellext/shellbtrfs/CMakeLists.txt @@ -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) diff --git a/dll/shellext/shellbtrfs/balance.cpp b/dll/shellext/shellbtrfs/balance.cpp index edcfecea51..a442a72c24 100644 --- a/dll/shellext/shellbtrfs/balance.cpp +++ b/dll/shellext/shellbtrfs/balance.cpp @@ -42,22 +42,22 @@ #include <shlwapi.h> #include <uxtheme.h>
-static UINT64 convtypes2[] = { BLOCK_FLAG_SINGLE, BLOCK_FLAG_DUPLICATE, BLOCK_FLAG_RAID0, BLOCK_FLAG_RAID1, BLOCK_FLAG_RAID5, BLOCK_FLAG_RAID6, BLOCK_FLAG_RAID10 }; +static uint64_t convtypes2[] = { BLOCK_FLAG_SINGLE, BLOCK_FLAG_DUPLICATE, BLOCK_FLAG_RAID0, BLOCK_FLAG_RAID1, BLOCK_FLAG_RAID5, BLOCK_FLAG_RAID6, BLOCK_FLAG_RAID10 };
-static WCHAR hex_digit(UINT8 u) { +static WCHAR hex_digit(uint8_t u) { if (u >= 0xa && u <= 0xf) - return u - 0xa + 'a'; + return (uint8_t)(u - 0xa + 'a'); else - return u + '0'; + return (uint8_t)(u + '0'); }
static void serialize(void* data, ULONG len, WCHAR* s) { - UINT8* d; + uint8_t* d;
- d = (UINT8*)data; + d = (uint8_t*)data;
- while (TRUE) { - *s = hex_digit(*d >> 4); s++; + while (true) { + *s = hex_digit((uint8_t)(*d >> 4)); s++; *s = hex_digit(*d & 0xf); s++;
d++; @@ -71,15 +71,18 @@ static void serialize(void* data, ULONG len, WCHAR* s) { }
void BtrfsBalance::StartBalance(HWND hwndDlg) { - WCHAR t[MAX_PATH + 600], u[600]; + wstring t; + WCHAR modfn[MAX_PATH], u[600]; SHELLEXECUTEINFOW sei; btrfs_start_balance bsb;
- t[0] = '"'; - GetModuleFileNameW(module, t + 1, (sizeof(t) / sizeof(WCHAR)) - 1); - wcscat(t, L"",StartBalance "); - wcscat(t, fn); - wcscat(t, L" "); + GetModuleFileNameW(module, modfn, sizeof(modfn) / sizeof(WCHAR)); + +#ifndef __REACTOS__ + t = L"""s + modfn + L"",StartBalance "s + fn + L" "s; +#else + t = wstring(L""") + modfn + wstring(L"",StartBalance ") + fn + wstring(L" "); +#endif
RtlCopyMemory(&bsb.opts[0], &data_opts, sizeof(btrfs_balance_opts)); RtlCopyMemory(&bsb.opts[1], &metadata_opts, sizeof(btrfs_balance_opts)); @@ -101,7 +104,8 @@ void BtrfsBalance::StartBalance(HWND hwndDlg) { bsb.opts[2].flags &= ~BTRFS_BALANCE_OPTS_ENABLED;
serialize(&bsb, sizeof(btrfs_start_balance), u); - wcscat(t, u); + + t += u;
RtlZeroMemory(&sei, sizeof(sei));
@@ -109,44 +113,46 @@ void BtrfsBalance::StartBalance(HWND hwndDlg) { sei.hwnd = hwndDlg; sei.lpVerb = L"runas"; sei.lpFile = L"rundll32.exe"; - sei.lpParameters = t; + sei.lpParameters = t.c_str(); sei.nShow = SW_SHOW; sei.fMask = SEE_MASK_NOCLOSEPROCESS;
- if (!ShellExecuteExW(&sei)) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!ShellExecuteExW(&sei)) + throw last_error(GetLastError());
- cancelling = FALSE; - removing = FALSE; - shrinking = FALSE; + cancelling = false; + removing = false; + shrinking = false; balance_status = BTRFS_BALANCE_RUNNING;
- EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATA), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), data_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), metadata_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), system_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? TRUE : FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), data_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), metadata_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), system_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? true : false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), false);
WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); }
void BtrfsBalance::PauseBalance(HWND hwndDlg) { - WCHAR t[MAX_PATH + 100]; + WCHAR modfn[MAX_PATH]; + wstring t; SHELLEXECUTEINFOW sei;
- t[0] = '"'; - GetModuleFileNameW(module, t + 1, (sizeof(t) / sizeof(WCHAR)) - 1); - wcscat(t, L"",PauseBalance "); - wcscat(t, fn); + GetModuleFileNameW(module, modfn, sizeof(modfn) / sizeof(WCHAR)); + +#ifndef __REACTOS__ + t = L"""s + modfn + L"",PauseBalance " + fn; +#else + t = wstring(L""") + modfn + wstring(L"",PauseBalance ") + fn; +#endif
RtlZeroMemory(&sei, sizeof(sei));
@@ -154,27 +160,29 @@ void BtrfsBalance::PauseBalance(HWND hwndDlg) { sei.hwnd = hwndDlg; sei.lpVerb = L"runas"; sei.lpFile = L"rundll32.exe"; - sei.lpParameters = t; + sei.lpParameters = t.c_str(); sei.nShow = SW_SHOW; sei.fMask = SEE_MASK_NOCLOSEPROCESS;
- if (!ShellExecuteExW(&sei)) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!ShellExecuteExW(&sei)) + throw last_error(GetLastError());
WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); }
void BtrfsBalance::StopBalance(HWND hwndDlg) { - WCHAR t[MAX_PATH + 100]; + WCHAR modfn[MAX_PATH]; + wstring t; SHELLEXECUTEINFOW sei;
- t[0] = '"'; - GetModuleFileNameW(module, t + 1, (sizeof(t) / sizeof(WCHAR)) - 1); - wcscat(t, L"",StopBalance "); - wcscat(t, fn); + GetModuleFileNameW(module, modfn, sizeof(modfn) / sizeof(WCHAR)); + +#ifndef __REACTOS__ + t = L"""s + modfn + L"",StopBalance " + fn; +#else + t = wstring(L""") + modfn + wstring(L"",StopBalance ") + fn; +#endif
RtlZeroMemory(&sei, sizeof(sei));
@@ -182,44 +190,37 @@ void BtrfsBalance::StopBalance(HWND hwndDlg) { sei.hwnd = hwndDlg; sei.lpVerb = L"runas"; sei.lpFile = L"rundll32.exe"; - sei.lpParameters = t; + sei.lpParameters = t.c_str(); sei.nShow = SW_SHOW; sei.fMask = SEE_MASK_NOCLOSEPROCESS;
- if (!ShellExecuteExW(&sei)) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!ShellExecuteExW(&sei)) + throw last_error(GetLastError());
- cancelling = TRUE; + cancelling = true;
WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); }
-void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, BOOL first) { - HANDLE h; - BOOL balancing = FALSE; - WCHAR s[255], t[255]; +void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, bool first) { + bool balancing = false; + wstring s, t;
- 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);
- Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_BALANCE, NULL, 0, &bqb, sizeof(btrfs_query_balance)); + if (h != INVALID_HANDLE_VALUE) { + NTSTATUS Status; + IO_STATUS_BLOCK iosb;
- if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwndDlg, Status); - CloseHandle(h); - return; - } + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_BALANCE, nullptr, 0, &bqb, sizeof(btrfs_query_balance));
- CloseHandle(h); - } else { - ShowError(hwndDlg, GetLastError()); - return; + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } else + throw last_error(GetLastError()); }
if (cancelling) @@ -231,13 +232,13 @@ void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, BOOL first) { if (first || balance_status != BTRFS_BALANCE_STOPPED) { int resid;
- EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), false); SendMessageW(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), PBM_SETSTATE, PBST_NORMAL, 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATA), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM), true);
if (balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED)) { CheckDlgButton(hwndDlg, IDC_DATA, BST_UNCHECKED); @@ -247,9 +248,9 @@ void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, BOOL first) { SendMessage(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), PBM_SETPOS, 0, 0); }
- EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED ? TRUE : FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED ? true : false);
if (bqb.status & BTRFS_BALANCE_ERROR) { if (removing) @@ -259,15 +260,12 @@ void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, BOOL first) { else resid = IDS_BALANCE_FAILED;
- if (!LoadStringW(module, resid, s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!load_string(module, resid, s)) + throw last_error(GetLastError());
- if (StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), s, bqb.error, format_ntstatus(bqb.error).c_str()) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; + wstring_sprintf(t, s, bqb.error, format_ntstatus(bqb.error).c_str());
- SetDlgItemTextW(hwndDlg, IDC_BALANCE_STATUS, t); + SetDlgItemTextW(hwndDlg, IDC_BALANCE_STATUS, t.c_str()); } else { if (cancelling) resid = removing ? IDS_BALANCE_CANCELLED_REMOVAL : (shrinking ? IDS_BALANCE_CANCELLED_SHRINK : IDS_BALANCE_CANCELLED); @@ -276,41 +274,39 @@ void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, BOOL first) { else resid = IDS_NO_BALANCE;
- if (!LoadStringW(module, resid, s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!load_string(module, resid, s)) + throw last_error(GetLastError());
- SetDlgItemTextW(hwndDlg, IDC_BALANCE_STATUS, s); + SetDlgItemTextW(hwndDlg, IDC_BALANCE_STATUS, s.c_str()); }
EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || - IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? TRUE: FALSE); + IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? true: false);
balance_status = bqb.status; - cancelling = FALSE; + cancelling = false; }
return; }
if (first || !(balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED))) { - EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATA), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), true); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM), false);
CheckDlgButton(hwndDlg, IDC_DATA, bqb.data_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_METADATA, bqb.metadata_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_SYSTEM, bqb.system_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? BST_CHECKED : BST_UNCHECKED);
- EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), bqb.data_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), bqb.metadata_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), bqb.system_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? TRUE : FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), bqb.data_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), bqb.metadata_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), bqb.system_opts.flags & BTRFS_BALANCE_OPTS_ENABLED ? true : false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), false); }
SendMessageW(GetDlgItem(hwndDlg, IDC_BALANCE_PROGRESS), PBM_SETRANGE32, 0, (LPARAM)bqb.total_chunks); @@ -324,44 +320,35 @@ void BtrfsBalance::RefreshBalanceDlg(HWND hwndDlg, BOOL first) { balance_status = bqb.status;
if (bqb.status & BTRFS_BALANCE_REMOVAL) { - if (!LoadStringW(module, balance_status & BTRFS_BALANCE_PAUSED ? IDS_BALANCE_PAUSED_REMOVAL : IDS_BALANCE_RUNNING_REMOVAL, s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!load_string(module, balance_status & BTRFS_BALANCE_PAUSED ? IDS_BALANCE_PAUSED_REMOVAL : IDS_BALANCE_RUNNING_REMOVAL, s)) + throw last_error(GetLastError());
- if (StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), s, bqb.data_opts.devid, bqb.total_chunks - bqb.chunks_left, - bqb.total_chunks, (float)(bqb.total_chunks - bqb.chunks_left) * 100.0f / (float)bqb.total_chunks) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; + wstring_sprintf(t, s, bqb.data_opts.devid, bqb.total_chunks - bqb.chunks_left, bqb.total_chunks, + (float)(bqb.total_chunks - bqb.chunks_left) * 100.0f / (float)bqb.total_chunks);
- removing = TRUE; - shrinking = FALSE; + removing = true; + shrinking = false; } else if (bqb.status & BTRFS_BALANCE_SHRINKING) { - if (!LoadStringW(module, balance_status & BTRFS_BALANCE_PAUSED ? IDS_BALANCE_PAUSED_SHRINK : IDS_BALANCE_RUNNING_SHRINK, s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!load_string(module, balance_status & BTRFS_BALANCE_PAUSED ? IDS_BALANCE_PAUSED_SHRINK : IDS_BALANCE_RUNNING_SHRINK, s)) + throw last_error(GetLastError());
- if (StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), s, bqb.data_opts.devid, bqb.total_chunks - bqb.chunks_left, - bqb.total_chunks, (float)(bqb.total_chunks - bqb.chunks_left) * 100.0f / (float)bqb.total_chunks) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; + wstring_sprintf(t, s, bqb.data_opts.devid, bqb.total_chunks - bqb.chunks_left, bqb.total_chunks, + (float)(bqb.total_chunks - bqb.chunks_left) * 100.0f / (float)bqb.total_chunks);
- removing = FALSE; - shrinking = TRUE; + removing = false; + shrinking = true; } else { - if (!LoadStringW(module, balance_status & BTRFS_BALANCE_PAUSED ? IDS_BALANCE_PAUSED : IDS_BALANCE_RUNNING, s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!load_string(module, balance_status & BTRFS_BALANCE_PAUSED ? IDS_BALANCE_PAUSED : IDS_BALANCE_RUNNING, s)) + throw last_error(GetLastError());
- if (StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), s, bqb.total_chunks - bqb.chunks_left, - bqb.total_chunks, (float)(bqb.total_chunks - bqb.chunks_left) * 100.0f / (float)bqb.total_chunks) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; + wstring_sprintf(t, s, bqb.total_chunks - bqb.chunks_left, bqb.total_chunks, + (float)(bqb.total_chunks - bqb.chunks_left) * 100.0f / (float)bqb.total_chunks);
- removing = FALSE; - shrinking = FALSE; + removing = false; + shrinking = false; }
- SetDlgItemTextW(hwndDlg, IDC_BALANCE_STATUS, t); + SetDlgItemTextW(hwndDlg, IDC_BALANCE_STATUS, t.c_str()); }
void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { @@ -411,7 +398,7 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { btrfs_device* bd = devices; int i = 0;
- while (TRUE) { + while (true) { if (i == sel) { opts->devid = bd->dev_id; break; @@ -420,7 +407,7 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { i++;
if (bd->next_entry > 0) - bd = (btrfs_device*)((UINT8*)bd + bd->next_entry); + bd = (btrfs_device*)((uint8_t*)bd + bd->next_entry); else break; } @@ -441,10 +428,8 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { GetWindowTextW(GetDlgItem(hwndDlg, IDC_DRANGE_END), s, sizeof(s) / sizeof(WCHAR)); opts->drange_end = _wtoi64(s);
- if (opts->drange_end < opts->drange_start) { - ShowStringError(hwndDlg, IDS_DRANGE_END_BEFORE_START); - return; - } + if (opts->drange_end < opts->drange_start) + throw string_error(IDS_DRANGE_END_BEFORE_START); }
if (IsDlgButtonChecked(hwndDlg, IDC_VRANGE) == BST_CHECKED) { @@ -458,10 +443,8 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { GetWindowTextW(GetDlgItem(hwndDlg, IDC_VRANGE_END), s, sizeof(s) / sizeof(WCHAR)); opts->vrange_end = _wtoi64(s);
- if (opts->vrange_end < opts->vrange_start) { - ShowStringError(hwndDlg, IDS_VRANGE_END_BEFORE_START); - return; - } + if (opts->vrange_end < opts->vrange_start) + throw string_error(IDS_VRANGE_END_BEFORE_START); }
if (IsDlgButtonChecked(hwndDlg, IDC_LIMIT) == BST_CHECKED) { @@ -475,10 +458,8 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { GetWindowTextW(GetDlgItem(hwndDlg, IDC_LIMIT_END), s, sizeof(s) / sizeof(WCHAR)); opts->limit_end = _wtoi64(s);
- if (opts->limit_end < opts->limit_start) { - ShowStringError(hwndDlg, IDS_LIMIT_END_BEFORE_START); - return; - } + if (opts->limit_end < opts->limit_start) + throw string_error(IDS_LIMIT_END_BEFORE_START); }
if (IsDlgButtonChecked(hwndDlg, IDC_STRIPES) == BST_CHECKED) { @@ -487,15 +468,13 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { opts->flags |= BTRFS_BALANCE_OPTS_STRIPES;
GetWindowTextW(GetDlgItem(hwndDlg, IDC_STRIPES_START), s, sizeof(s) / sizeof(WCHAR)); - opts->stripes_start = _wtoi(s); + opts->stripes_start = (uint8_t)_wtoi(s);
GetWindowTextW(GetDlgItem(hwndDlg, IDC_STRIPES_END), s, sizeof(s) / sizeof(WCHAR)); - opts->stripes_end = _wtoi(s); + opts->stripes_end = (uint8_t)_wtoi(s);
- if (opts->stripes_end < opts->stripes_start) { - ShowStringError(hwndDlg, IDS_STRIPES_END_BEFORE_START); - return; - } + if (opts->stripes_end < opts->stripes_start) + throw string_error(IDS_STRIPES_END_BEFORE_START); }
if (IsDlgButtonChecked(hwndDlg, IDC_USAGE) == BST_CHECKED) { @@ -504,15 +483,13 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { opts->flags |= BTRFS_BALANCE_OPTS_USAGE;
GetWindowTextW(GetDlgItem(hwndDlg, IDC_USAGE_START), s, sizeof(s) / sizeof(WCHAR)); - opts->usage_start = _wtoi(s); + opts->usage_start = (uint8_t)_wtoi(s);
GetWindowTextW(GetDlgItem(hwndDlg, IDC_USAGE_END), s, sizeof(s) / sizeof(WCHAR)); - opts->usage_end = _wtoi(s); + opts->usage_end = (uint8_t)_wtoi(s);
- if (opts->usage_end < opts->usage_start) { - ShowStringError(hwndDlg, IDS_USAGE_END_BEFORE_START); - return; - } + if (opts->usage_end < opts->usage_start) + throw string_error(IDS_USAGE_END_BEFORE_START); }
if (IsDlgButtonChecked(hwndDlg, IDC_CONVERT) == BST_CHECKED) { @@ -535,331 +512,323 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { }
INT_PTR CALLBACK BtrfsBalance::BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_INITDIALOG: - { - HWND devcb, convcb; - btrfs_device* bd; - btrfs_balance_opts* opts; - static int convtypes[] = { IDS_SINGLE2, IDS_DUP, IDS_RAID0, IDS_RAID1, IDS_RAID5, IDS_RAID6, IDS_RAID10, 0 }; - int i, num_devices = 0, num_writeable_devices = 0; - WCHAR s[255], u[255]; - BOOL balance_started = balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED); - - switch (opts_type) { - case 1: - opts = balance_started ? &bqb.data_opts : &data_opts; - break; - - case 2: - opts = balance_started ? &bqb.metadata_opts : &metadata_opts; - break; - - case 3: - opts = balance_started ? &bqb.system_opts : &system_opts; - break; - - default: - return TRUE; - } - - EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB); - - devcb = GetDlgItem(hwndDlg, IDC_DEVID_COMBO); - - if (!LoadStringW(module, IDS_DEVID_LIST, u, sizeof(u) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return TRUE; - } - - bd = devices; - while (TRUE) { - WCHAR t[255], v[255]; - - if (bd->device_number == 0xffffffff) { - memcpy(s, bd->name, bd->namelen); - s[bd->namelen / sizeof(WCHAR)] = 0; - } else if (bd->partition_number == 0) { - if (!LoadStringW(module, IDS_DISK_NUM, v, sizeof(v) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return TRUE; - } - - if (StringCchPrintfW(s, sizeof(s) / sizeof(WCHAR), v, bd->device_number) == STRSAFE_E_INSUFFICIENT_BUFFER) - break; - } else { - if (!LoadStringW(module, IDS_DISK_PART_NUM, v, sizeof(v) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return TRUE; - } - - if (StringCchPrintfW(s, sizeof(s) / sizeof(WCHAR), v, bd->device_number, bd->partition_number) == STRSAFE_E_INSUFFICIENT_BUFFER) - break; - } - - if (StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), u, bd->dev_id, s) == STRSAFE_E_INSUFFICIENT_BUFFER) + try { + switch (uMsg) { + case WM_INITDIALOG: + { + HWND devcb, convcb; + btrfs_device* bd; + btrfs_balance_opts* opts; + static int convtypes[] = { IDS_SINGLE2, IDS_DUP, IDS_RAID0, IDS_RAID1, IDS_RAID5, IDS_RAID6, IDS_RAID10, 0 }; + int i, num_devices = 0, num_writeable_devices = 0; + wstring s, u; + bool balance_started = balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED); + + switch (opts_type) { + case 1: + opts = balance_started ? &bqb.data_opts : &data_opts; break;
- SendMessage(devcb, CB_ADDSTRING, NULL, (LPARAM)t); - - if (opts->devid == bd->dev_id) - SendMessage(devcb, CB_SETCURSEL, num_devices, 0); - - num_devices++; - - if (!bd->readonly) - num_writeable_devices++; - - if (bd->next_entry > 0) - bd = (btrfs_device*)((UINT8*)bd + bd->next_entry); - else + case 2: + opts = balance_started ? &bqb.metadata_opts : &metadata_opts; break; - } - - convcb = GetDlgItem(hwndDlg, IDC_CONVERT_COMBO);
- if (num_writeable_devices == 0) - num_writeable_devices = num_devices; - - i = 0; - while (convtypes[i] != 0) { - if (!LoadStringW(module, convtypes[i], s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); + case 3: + opts = balance_started ? &bqb.system_opts : &system_opts; break; + + default: + return true; }
- SendMessage(convcb, CB_ADDSTRING, NULL, (LPARAM)s); + EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB);
- if (opts->convert == convtypes2[i]) - SendMessage(convcb, CB_SETCURSEL, i, 0); + devcb = GetDlgItem(hwndDlg, IDC_DEVID_COMBO);
- i++; + if (!load_string(module, IDS_DEVID_LIST, u)) + throw last_error(GetLastError());
- if (num_writeable_devices < 2 && i == 2) - break; - else if (num_writeable_devices < 3 && i == 4) - break; - else if (num_writeable_devices < 4 && i == 5) - break; - } + bd = devices; + while (true) { + wstring t, v;
- // profiles + if (bd->device_number == 0xffffffff) + s = wstring(bd->name, bd->namelen); + else if (bd->partition_number == 0) { + if (!load_string(module, IDS_DISK_NUM, v)) + throw last_error(GetLastError());
- CheckDlgButton(hwndDlg, IDC_PROFILES, opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_SINGLE, opts->profiles & BLOCK_FLAG_SINGLE ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_DUP, opts->profiles & BLOCK_FLAG_DUPLICATE ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_RAID0, opts->profiles & BLOCK_FLAG_RAID0 ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_RAID1, opts->profiles & BLOCK_FLAG_RAID1 ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_RAID10, opts->profiles & BLOCK_FLAG_RAID10 ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_RAID5, opts->profiles & BLOCK_FLAG_RAID5 ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PROFILES_RAID6, opts->profiles & BLOCK_FLAG_RAID6 ? BST_CHECKED : BST_UNCHECKED); + wstring_sprintf(s, v, bd->device_number); + } else { + if (!load_string(module, IDS_DISK_PART_NUM, v)) + throw last_error(GetLastError());
- EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_SINGLE), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_DUP), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID0), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID10), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID5), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID6), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES), balance_started ? FALSE : TRUE); + wstring_sprintf(s, v, bd->device_number, bd->partition_number); + }
- // usage + wstring_sprintf(t, u, bd->dev_id, s.c_str());
- CheckDlgButton(hwndDlg, IDC_USAGE, opts->flags & BTRFS_BALANCE_OPTS_USAGE ? BST_CHECKED : BST_UNCHECKED); + SendMessage(devcb, CB_ADDSTRING, 0, (LPARAM)t.c_str());
- _itow(opts->usage_start, s, 10); - SetDlgItemTextW(hwndDlg, IDC_USAGE_START, s); - SendMessageW(GetDlgItem(hwndDlg, IDC_USAGE_START_SPINNER), UDM_SETRANGE32, 0, 100); + if (opts->devid == bd->dev_id) + SendMessage(devcb, CB_SETCURSEL, num_devices, 0);
- _itow(opts->usage_end, s, 10); - SetDlgItemTextW(hwndDlg, IDC_USAGE_END, s); - SendMessageW(GetDlgItem(hwndDlg, IDC_USAGE_END_SPINNER), UDM_SETRANGE32, 0, 100); + num_devices++;
- EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE), balance_started ? FALSE : TRUE); + if (!bd->readonly) + num_writeable_devices++;
- // devid + if (bd->next_entry > 0) + bd = (btrfs_device*)((uint8_t*)bd + bd->next_entry); + else + break; + }
- if (num_devices < 2 || balance_started) - EnableWindow(GetDlgItem(hwndDlg, IDC_DEVID), FALSE); + convcb = GetDlgItem(hwndDlg, IDC_CONVERT_COMBO);
- CheckDlgButton(hwndDlg, IDC_DEVID, opts->flags & BTRFS_BALANCE_OPTS_DEVID ? BST_CHECKED : BST_UNCHECKED); - EnableWindow(devcb, (opts->flags & BTRFS_BALANCE_OPTS_DEVID && num_devices >= 2 && !balance_started) ? TRUE : FALSE); + if (num_writeable_devices == 0) + num_writeable_devices = num_devices;
- // drange + i = 0; + while (convtypes[i] != 0) { + if (!load_string(module, convtypes[i], s)) + throw last_error(GetLastError());
- CheckDlgButton(hwndDlg, IDC_DRANGE, opts->flags & BTRFS_BALANCE_OPTS_DRANGE ? BST_CHECKED : BST_UNCHECKED); + SendMessage(convcb, CB_ADDSTRING, 0, (LPARAM)s.c_str());
- _itow(opts->drange_start, s, 10); - SetDlgItemTextW(hwndDlg, IDC_DRANGE_START, s); + if (opts->convert == convtypes2[i]) + SendMessage(convcb, CB_SETCURSEL, i, 0);
- _itow(opts->drange_end, s, 10); - SetDlgItemTextW(hwndDlg, IDC_DRANGE_END, s); + i++;
- EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_DRANGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_DRANGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE), balance_started ? FALSE : TRUE); + if (num_writeable_devices < 2 && i == 2) + break; + else if (num_writeable_devices < 3 && i == 4) + break; + else if (num_writeable_devices < 4 && i == 5) + break; + }
- // vrange + // profiles
- CheckDlgButton(hwndDlg, IDC_VRANGE, opts->flags & BTRFS_BALANCE_OPTS_VRANGE ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES, opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_SINGLE, opts->profiles & BLOCK_FLAG_SINGLE ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_DUP, opts->profiles & BLOCK_FLAG_DUPLICATE ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID0, opts->profiles & BLOCK_FLAG_RAID0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID1, opts->profiles & BLOCK_FLAG_RAID1 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID10, opts->profiles & BLOCK_FLAG_RAID10 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID5, opts->profiles & BLOCK_FLAG_RAID5 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID6, opts->profiles & BLOCK_FLAG_RAID6 ? BST_CHECKED : BST_UNCHECKED);
- _itow(opts->vrange_start, s, 10); - SetDlgItemTextW(hwndDlg, IDC_VRANGE_START, s); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_SINGLE), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_DUP), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID0), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID10), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID5), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID6), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES), balance_started ? false : true);
- _itow(opts->vrange_end, s, 10); - SetDlgItemTextW(hwndDlg, IDC_VRANGE_END, s); + // usage
- EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_VRANGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_VRANGE ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE), balance_started ? FALSE : TRUE); + CheckDlgButton(hwndDlg, IDC_USAGE, opts->flags & BTRFS_BALANCE_OPTS_USAGE ? BST_CHECKED : BST_UNCHECKED);
- // limit + s = to_wstring(opts->usage_start); + SetDlgItemTextW(hwndDlg, IDC_USAGE_START, s.c_str()); + SendMessageW(GetDlgItem(hwndDlg, IDC_USAGE_START_SPINNER), UDM_SETRANGE32, 0, 100);
- CheckDlgButton(hwndDlg, IDC_LIMIT, opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? BST_CHECKED : BST_UNCHECKED); + s = to_wstring(opts->usage_end); + SetDlgItemTextW(hwndDlg, IDC_USAGE_END, s.c_str()); + SendMessageW(GetDlgItem(hwndDlg, IDC_USAGE_END_SPINNER), UDM_SETRANGE32, 0, 100);
- _itow(opts->limit_start, s, 10); - SetDlgItemTextW(hwndDlg, IDC_LIMIT_START, s); - SendMessageW(GetDlgItem(hwndDlg, IDC_LIMIT_START_SPINNER), UDM_SETRANGE32, 0, 0x7fffffff); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_USAGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE), balance_started ? false : true);
- _itow(opts->limit_end, s, 10); - SetDlgItemTextW(hwndDlg, IDC_LIMIT_END, s); - SendMessageW(GetDlgItem(hwndDlg, IDC_LIMIT_END_SPINNER), UDM_SETRANGE32, 0, 0x7fffffff); + // devid
- EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT), balance_started ? FALSE : TRUE); + if (num_devices < 2 || balance_started) + EnableWindow(GetDlgItem(hwndDlg, IDC_DEVID), false);
- // stripes + CheckDlgButton(hwndDlg, IDC_DEVID, opts->flags & BTRFS_BALANCE_OPTS_DEVID ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(devcb, (opts->flags & BTRFS_BALANCE_OPTS_DEVID && num_devices >= 2 && !balance_started) ? true : false);
- CheckDlgButton(hwndDlg, IDC_STRIPES, opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? BST_CHECKED : BST_UNCHECKED); + // drange
- _itow(opts->stripes_start, s, 10); - SetDlgItemTextW(hwndDlg, IDC_STRIPES_START, s); - SendMessageW(GetDlgItem(hwndDlg, IDC_STRIPES_START_SPINNER), UDM_SETRANGE32, 0, 0xffff); + CheckDlgButton(hwndDlg, IDC_DRANGE, opts->flags & BTRFS_BALANCE_OPTS_DRANGE ? BST_CHECKED : BST_UNCHECKED);
- _itow(opts->stripes_end, s, 10); - SetDlgItemTextW(hwndDlg, IDC_STRIPES_END, s); - SendMessageW(GetDlgItem(hwndDlg, IDC_STRIPES_END_SPINNER), UDM_SETRANGE32, 0, 0xffff); + s = to_wstring(opts->drange_start); + SetDlgItemTextW(hwndDlg, IDC_DRANGE_START, s.c_str());
- EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES), balance_started ? FALSE : TRUE); + s = to_wstring(opts->drange_end); + SetDlgItemTextW(hwndDlg, IDC_DRANGE_END, s.c_str());
- // convert + EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_DRANGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_DRANGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE), balance_started ? false : true);
- CheckDlgButton(hwndDlg, IDC_CONVERT, opts->flags & BTRFS_BALANCE_OPTS_CONVERT ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_SOFT, opts->flags & BTRFS_BALANCE_OPTS_SOFT ? BST_CHECKED : BST_UNCHECKED); + // vrange
- EnableWindow(GetDlgItem(hwndDlg, IDC_SOFT), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_CONVERT ? TRUE : FALSE); - EnableWindow(convcb, !balance_started && opts->flags & BTRFS_BALANCE_OPTS_CONVERT ? TRUE : FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CONVERT), balance_started ? FALSE : TRUE); + CheckDlgButton(hwndDlg, IDC_VRANGE, opts->flags & BTRFS_BALANCE_OPTS_VRANGE ? BST_CHECKED : BST_UNCHECKED);
- break; - } + s = to_wstring(opts->vrange_start); + SetDlgItemTextW(hwndDlg, IDC_VRANGE_START, s.c_str());
- case WM_COMMAND: - switch (HIWORD(wParam)) { - case BN_CLICKED: - switch (LOWORD(wParam)) { - case IDOK: - if (balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED)) - EndDialog(hwndDlg, 0); - else - SaveBalanceOpts(hwndDlg); - return TRUE; - - case IDCANCEL: - EndDialog(hwndDlg, 0); - return TRUE; - - case IDC_PROFILES: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_PROFILES) == BST_CHECKED ? TRUE : FALSE; - - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_SINGLE), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_DUP), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID0), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID10), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID5), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID6), enabled); - break; - } + s = to_wstring(opts->vrange_end); + SetDlgItemTextW(hwndDlg, IDC_VRANGE_END, s.c_str());
- case IDC_USAGE: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_USAGE) == BST_CHECKED ? TRUE : FALSE; + EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_VRANGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_VRANGE ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE), balance_started ? false : true);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START_SPINNER), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END_SPINNER), enabled); - break; - } + // limit
- case IDC_DEVID: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_DEVID) == BST_CHECKED ? TRUE : FALSE; + CheckDlgButton(hwndDlg, IDC_LIMIT, opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? BST_CHECKED : BST_UNCHECKED);
- EnableWindow(GetDlgItem(hwndDlg, IDC_DEVID_COMBO), enabled); - break; - } + s = to_wstring(opts->limit_start); + SetDlgItemTextW(hwndDlg, IDC_LIMIT_START, s.c_str()); + SendMessageW(GetDlgItem(hwndDlg, IDC_LIMIT_START_SPINNER), UDM_SETRANGE32, 0, 0x7fffffff);
- case IDC_DRANGE: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_DRANGE) == BST_CHECKED ? TRUE : FALSE; + s = to_wstring(opts->limit_end); + SetDlgItemTextW(hwndDlg, IDC_LIMIT_END, s.c_str()); + SendMessageW(GetDlgItem(hwndDlg, IDC_LIMIT_END_SPINNER), UDM_SETRANGE32, 0, 0x7fffffff);
- EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_START), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_END), enabled); - break; - } + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_LIMIT ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT), balance_started ? false : true);
- case IDC_VRANGE: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_VRANGE) == BST_CHECKED ? TRUE : FALSE; + // stripes
- EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_START), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_END), enabled); - break; - } + CheckDlgButton(hwndDlg, IDC_STRIPES, opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? BST_CHECKED : BST_UNCHECKED);
- case IDC_LIMIT: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_LIMIT) == BST_CHECKED ? TRUE : FALSE; + s = to_wstring(opts->stripes_start); + SetDlgItemTextW(hwndDlg, IDC_STRIPES_START, s.c_str()); + SendMessageW(GetDlgItem(hwndDlg, IDC_STRIPES_START_SPINNER), UDM_SETRANGE32, 0, 0xffff);
- EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START_SPINNER), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END_SPINNER), enabled); - break; - } + s = to_wstring(opts->stripes_end); + SetDlgItemTextW(hwndDlg, IDC_STRIPES_END, s.c_str()); + SendMessageW(GetDlgItem(hwndDlg, IDC_STRIPES_END_SPINNER), UDM_SETRANGE32, 0, 0xffff);
- case IDC_STRIPES: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_STRIPES) == BST_CHECKED ? TRUE : FALSE; + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END_SPINNER), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_STRIPES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES), balance_started ? false : true);
- EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START_SPINNER), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END_SPINNER), enabled); - break; - } + // convert
- case IDC_CONVERT: { - BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_CONVERT) == BST_CHECKED ? TRUE : FALSE; + CheckDlgButton(hwndDlg, IDC_CONVERT, opts->flags & BTRFS_BALANCE_OPTS_CONVERT ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SOFT, opts->flags & BTRFS_BALANCE_OPTS_SOFT ? BST_CHECKED : BST_UNCHECKED); + + EnableWindow(GetDlgItem(hwndDlg, IDC_SOFT), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_CONVERT ? true : false); + EnableWindow(convcb, !balance_started && opts->flags & BTRFS_BALANCE_OPTS_CONVERT ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_CONVERT), balance_started ? false : true);
- EnableWindow(GetDlgItem(hwndDlg, IDC_CONVERT_COMBO), enabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_SOFT), enabled); - break; - } - } break; } - break; + + case WM_COMMAND: + switch (HIWORD(wParam)) { + case BN_CLICKED: + switch (LOWORD(wParam)) { + case IDOK: + if (balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED)) + EndDialog(hwndDlg, 0); + else + SaveBalanceOpts(hwndDlg); + return true; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return true; + + case IDC_PROFILES: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_PROFILES) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_SINGLE), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_DUP), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID0), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID10), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID5), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID6), enabled); + break; + } + + case IDC_USAGE: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_USAGE) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_START_SPINNER), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_USAGE_END_SPINNER), enabled); + break; + } + + case IDC_DEVID: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_DEVID) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_DEVID_COMBO), enabled); + break; + } + + case IDC_DRANGE: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_DRANGE) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_START), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_DRANGE_END), enabled); + break; + } + + case IDC_VRANGE: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_VRANGE) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_START), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_VRANGE_END), enabled); + break; + } + + case IDC_LIMIT: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_LIMIT) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_START_SPINNER), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_LIMIT_END_SPINNER), enabled); + break; + } + + case IDC_STRIPES: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_STRIPES) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_START_SPINNER), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPES_END_SPINNER), enabled); + break; + } + + case IDC_CONVERT: { + bool enabled = IsDlgButtonChecked(hwndDlg, IDC_CONVERT) == BST_CHECKED ? true : false; + + EnableWindow(GetDlgItem(hwndDlg, IDC_CONVERT_COMBO), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_SOFT), enabled); + break; + } + } + break; + } + break; + } + } catch (const exception& e) { + error_message(hwndDlg, e.what()); }
- return FALSE; + return false; }
static INT_PTR CALLBACK stub_BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -875,112 +844,116 @@ static INT_PTR CALLBACK stub_BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM if (bb) return bb->BalanceOptsDlgProc(hwndDlg, uMsg, wParam, lParam); else - return FALSE; + return false; }
-void BtrfsBalance::ShowBalanceOptions(HWND hwndDlg, UINT8 type) { +void BtrfsBalance::ShowBalanceOptions(HWND hwndDlg, uint8_t type) { opts_type = type; DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_BALANCE_OPTIONS), hwndDlg, stub_BalanceOptsDlgProc, (LPARAM)this); }
INT_PTR CALLBACK BtrfsBalance::BalanceDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_INITDIALOG: - { - EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB); - - RtlZeroMemory(&data_opts, sizeof(btrfs_balance_opts)); - RtlZeroMemory(&metadata_opts, sizeof(btrfs_balance_opts)); - RtlZeroMemory(&system_opts, sizeof(btrfs_balance_opts)); - - removing = called_from_RemoveDevice; - shrinking = called_from_ShrinkDevice; - balance_status = (removing || shrinking) ? BTRFS_BALANCE_RUNNING : BTRFS_BALANCE_STOPPED; - cancelling = FALSE; - RefreshBalanceDlg(hwndDlg, TRUE); - - if (readonly) { - EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), FALSE); - } + try { + switch (uMsg) { + case WM_INITDIALOG: + { + EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB); + + RtlZeroMemory(&data_opts, sizeof(btrfs_balance_opts)); + RtlZeroMemory(&metadata_opts, sizeof(btrfs_balance_opts)); + RtlZeroMemory(&system_opts, sizeof(btrfs_balance_opts)); + + removing = called_from_RemoveDevice; + shrinking = called_from_ShrinkDevice; + balance_status = (removing || shrinking) ? BTRFS_BALANCE_RUNNING : BTRFS_BALANCE_STOPPED; + cancelling = false; + RefreshBalanceDlg(hwndDlg, true); + + if (readonly) { + EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), false); + EnableWindow(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), false); + }
- SendMessageW(GetDlgItem(hwndDlg, IDC_START_BALANCE), BCM_SETSHIELD, 0, TRUE); - SendMessageW(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), BCM_SETSHIELD, 0, TRUE); - SendMessageW(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), BCM_SETSHIELD, 0, TRUE); + SendMessageW(GetDlgItem(hwndDlg, IDC_START_BALANCE), BCM_SETSHIELD, 0, true); + SendMessageW(GetDlgItem(hwndDlg, IDC_PAUSE_BALANCE), BCM_SETSHIELD, 0, true); + SendMessageW(GetDlgItem(hwndDlg, IDC_CANCEL_BALANCE), BCM_SETSHIELD, 0, true);
- SetTimer(hwndDlg, 1, 1000, NULL); + SetTimer(hwndDlg, 1, 1000, nullptr);
- break; - } - - case WM_COMMAND: - switch (HIWORD(wParam)) { - case BN_CLICKED: - switch (LOWORD(wParam)) { - case IDOK: - case IDCANCEL: - KillTimer(hwndDlg, 1); - EndDialog(hwndDlg, 0); - return TRUE; - - case IDC_DATA: - EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED ? TRUE : FALSE); - - EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || - IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? TRUE: FALSE); - return TRUE; - - case IDC_METADATA: - EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED ? TRUE : FALSE); - - EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || - IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? TRUE: FALSE); - return TRUE; - - case IDC_SYSTEM: - EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED ? TRUE : FALSE); - - EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || - IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? TRUE: FALSE); - return TRUE; - - case IDC_DATA_OPTIONS: - ShowBalanceOptions(hwndDlg, 1); - return TRUE; - - case IDC_METADATA_OPTIONS: - ShowBalanceOptions(hwndDlg, 2); - return TRUE; - - case IDC_SYSTEM_OPTIONS: - ShowBalanceOptions(hwndDlg, 3); - return TRUE; - - case IDC_START_BALANCE: - StartBalance(hwndDlg); - return TRUE; - - case IDC_PAUSE_BALANCE: - PauseBalance(hwndDlg); - RefreshBalanceDlg(hwndDlg, FALSE); - return TRUE; - - case IDC_CANCEL_BALANCE: - StopBalance(hwndDlg); - RefreshBalanceDlg(hwndDlg, FALSE); - return TRUE; - } break; } - break;
- case WM_TIMER: - RefreshBalanceDlg(hwndDlg, FALSE); + case WM_COMMAND: + switch (HIWORD(wParam)) { + case BN_CLICKED: + switch (LOWORD(wParam)) { + case IDOK: + case IDCANCEL: + KillTimer(hwndDlg, 1); + EndDialog(hwndDlg, 0); + return true; + + case IDC_DATA: + EnableWindow(GetDlgItem(hwndDlg, IDC_DATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED ? true : false); + + EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || + IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? true: false); + return true; + + case IDC_METADATA: + EnableWindow(GetDlgItem(hwndDlg, IDC_METADATA_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED ? true : false); + + EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || + IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? true: false); + return true; + + case IDC_SYSTEM: + EnableWindow(GetDlgItem(hwndDlg, IDC_SYSTEM_OPTIONS), IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED ? true : false); + + EnableWindow(GetDlgItem(hwndDlg, IDC_START_BALANCE), !readonly && (IsDlgButtonChecked(hwndDlg, IDC_DATA) == BST_CHECKED || + IsDlgButtonChecked(hwndDlg, IDC_METADATA) == BST_CHECKED || IsDlgButtonChecked(hwndDlg, IDC_SYSTEM) == BST_CHECKED) ? true: false); + return true; + + case IDC_DATA_OPTIONS: + ShowBalanceOptions(hwndDlg, 1); + return true; + + case IDC_METADATA_OPTIONS: + ShowBalanceOptions(hwndDlg, 2); + return true; + + case IDC_SYSTEM_OPTIONS: + ShowBalanceOptions(hwndDlg, 3); + return true; + + case IDC_START_BALANCE: + StartBalance(hwndDlg); + return true; + + case IDC_PAUSE_BALANCE: + PauseBalance(hwndDlg); + RefreshBalanceDlg(hwndDlg, false); + return true; + + case IDC_CANCEL_BALANCE: + StopBalance(hwndDlg); + RefreshBalanceDlg(hwndDlg, false); + return true; + } + break; + } break; + + case WM_TIMER: + RefreshBalanceDlg(hwndDlg, false); + break; + } + } catch (const exception& e) { + error_message(hwndDlg, e.what()); }
- return FALSE; + return false; }
static INT_PTR CALLBACK stub_BalanceDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -996,70 +969,64 @@ static INT_PTR CALLBACK stub_BalanceDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wPar if (bb) return bb->BalanceDlgProc(hwndDlg, uMsg, wParam, lParam); else - return FALSE; + return false; }
void BtrfsBalance::ShowBalance(HWND hwndDlg) { - HANDLE h; btrfs_device* bd;
if (devices) { free(devices); - devices = NULL; + devices = nullptr; }
- h = CreateFileW(fn, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, 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_READ_ATTRIBUTES, 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; - ULONG devsize, i; + if (h != INVALID_HANDLE_VALUE) { + NTSTATUS Status; + IO_STATUS_BLOCK iosb; + ULONG devsize, i;
- i = 0; - devsize = 1024; + i = 0; + devsize = 1024;
- devices = (btrfs_device*)malloc(devsize); + devices = (btrfs_device*)malloc(devsize);
- while (TRUE) { - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_DEVICES, NULL, 0, devices, devsize); - if (Status == STATUS_BUFFER_OVERFLOW) { - if (i < 8) { - devsize += 1024; + while (true) { + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_DEVICES, nullptr, 0, devices, devsize); + if (Status == STATUS_BUFFER_OVERFLOW) { + if (i < 8) { + devsize += 1024;
- free(devices); - devices = (btrfs_device*)malloc(devsize); + free(devices); + devices = (btrfs_device*)malloc(devsize);
- i++; + i++; + } else + return; } else - return; - } else - break; - } - - if (!NT_SUCCESS(Status)) { - CloseHandle(h); - ShowNtStatusError(hwndDlg, Status); - return; - } + break; + }
- CloseHandle(h); - } else { - ShowError(hwndDlg, GetLastError()); - return; + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } else + throw last_error(GetLastError()); }
- readonly = TRUE; + readonly = true; bd = devices;
- while (TRUE) { + while (true) { if (!bd->readonly) { - readonly = FALSE; + readonly = false; break; }
if (bd->next_entry > 0) - bd = (btrfs_device*)((UINT8*)bd + bd->next_entry); + bd = (btrfs_device*)((uint8_t*)bd + bd->next_entry); else break; } @@ -1067,22 +1034,22 @@ void BtrfsBalance::ShowBalance(HWND hwndDlg) { DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_BALANCE), hwndDlg, stub_BalanceDlgProc, (LPARAM)this); }
-static UINT8 from_hex_digit(WCHAR c) { +static uint8_t from_hex_digit(WCHAR c) { if (c >= 'a' && c <= 'f') - return c - 'a' + 0xa; + return (uint8_t)(c - 'a' + 0xa); else if (c >= 'A' && c <= 'F') - return c - 'A' + 0xa; + return (uint8_t)(c - 'A' + 0xa); else - return c - '0'; + return (uint8_t)(c - '0'); }
static void unserialize(void* data, ULONG len, WCHAR* s) { - UINT8* d; + uint8_t* d;
- d = (UINT8*)data; + d = (uint8_t*)data;
while (s[0] != 0 && s[1] != 0 && len > 0) { - *d = from_hex_digit(s[0]) << 4 | from_hex_digit(s[1]); + *d = (uint8_t)(from_hex_digit(s[0]) << 4) | from_hex_digit(s[1]);
s += 2; d++; @@ -1095,205 +1062,156 @@ extern "C" { #endif
void CALLBACK StartBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) { - WCHAR *s, *vol, *block; - HANDLE h, token; - btrfs_start_balance bsb; - TOKEN_PRIVILEGES tp; - LUID luid; - - s = wcsstr(lpszCmdLine, L" "); - if (!s) - return; + try { + WCHAR *s, *vol, *block; + win_handle h, token; + btrfs_start_balance bsb; + TOKEN_PRIVILEGES tp; + LUID luid; + + s = wcsstr(lpszCmdLine, L" "); + if (!s) + return;
- s[0] = 0; + s[0] = 0;
- vol = lpszCmdLine; - block = &s[1]; + vol = lpszCmdLine; + block = &s[1];
- RtlZeroMemory(&bsb, sizeof(btrfs_start_balance)); - unserialize(&bsb, sizeof(btrfs_start_balance), block); + RtlZeroMemory(&bsb, sizeof(btrfs_start_balance)); + unserialize(&bsb, sizeof(btrfs_start_balance), block);
- 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(NULL, L"SeManageVolumePrivilege", &luid)) { - ShowError(hwnd, GetLastError()); - goto end; - } + 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; + 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; - } + if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr)) + throw last_error(GetLastError());
- h = CreateFileW(vol, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); + h = CreateFileW(vol, 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; + if (h != INVALID_HANDLE_VALUE) { + NTSTATUS Status; + IO_STATUS_BLOCK iosb;
- Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_START_BALANCE, &bsb, sizeof(btrfs_start_balance), NULL, 0); + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_START_BALANCE, &bsb, sizeof(btrfs_start_balance), nullptr, 0);
- if (Status == STATUS_DEVICE_NOT_READY) { - btrfs_query_scrub bqs; - NTSTATUS Status2; + if (Status == STATUS_DEVICE_NOT_READY) { + btrfs_query_scrub bqs; + NTSTATUS Status2;
- Status2 = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_SCRUB, NULL, 0, &bqs, sizeof(btrfs_query_scrub)); + Status2 = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_SCRUB, nullptr, 0, &bqs, sizeof(btrfs_query_scrub));
- if ((NT_SUCCESS(Status2) || Status2 == STATUS_BUFFER_OVERFLOW) && bqs.status != BTRFS_SCRUB_STOPPED) { - ShowStringError(hwnd, IDS_BALANCE_SCRUB_RUNNING); - CloseHandle(h); - goto end; + if ((NT_SUCCESS(Status2) || Status2 == STATUS_BUFFER_OVERFLOW) && bqs.status != BTRFS_SCRUB_STOPPED) + throw string_error(IDS_BALANCE_SCRUB_RUNNING); } - } - - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(h); - goto end; - }
- CloseHandle(h); - } else { - ShowError(hwnd, GetLastError()); - goto end; + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } else + throw last_error(GetLastError()); + } catch (const exception& e) { + error_message(hwnd, e.what()); } - -end: - CloseHandle(token); }
void CALLBACK PauseBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) { - HANDLE h, token; - TOKEN_PRIVILEGES tp; - LUID luid; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { - ShowError(hwnd, GetLastError()); - return; - } - - if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid)) { - ShowError(hwnd, GetLastError()); - goto end; + try { + win_handle h, token; + TOKEN_PRIVILEGES tp; + LUID luid; + + 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()); + + h = CreateFileW(lpszCmdLine, 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; + btrfs_query_balance bqb2; + + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_BALANCE, nullptr, 0, &bqb2, sizeof(btrfs_query_balance)); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + + if (bqb2.status & BTRFS_BALANCE_PAUSED) + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_RESUME_BALANCE, nullptr, 0, nullptr, 0); + else if (bqb2.status & BTRFS_BALANCE_RUNNING) + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_PAUSE_BALANCE, nullptr, 0, nullptr, 0); + else + return; + + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } else + throw last_error(GetLastError()); + } catch (const exception& e) { + error_message(hwnd, e.what()); } - - 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; - } - - h = CreateFileW(lpszCmdLine, 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; - btrfs_query_balance bqb2; - - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_BALANCE, NULL, 0, &bqb2, sizeof(btrfs_query_balance)); - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(h); - goto end; - } - - if (bqb2.status & BTRFS_BALANCE_PAUSED) - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_RESUME_BALANCE, NULL, 0, NULL, 0); - else if (bqb2.status & BTRFS_BALANCE_RUNNING) - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_PAUSE_BALANCE, NULL, 0, NULL, 0); - else { - CloseHandle(h); - goto end; - } - - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(h); - goto end; - } - - CloseHandle(h); - } else { - ShowError(hwnd, GetLastError()); - goto end; - } - -end: - CloseHandle(token); }
void CALLBACK StopBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) { - HANDLE h, token; - TOKEN_PRIVILEGES tp; - LUID luid; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { - ShowError(hwnd, GetLastError()); - return; - } - - 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; - } - - h = CreateFileW(lpszCmdLine, 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; - btrfs_query_balance bqb2; - - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_QUERY_BALANCE, NULL, 0, &bqb2, sizeof(btrfs_query_balance)); - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(h); - goto end; - } - - if (bqb2.status & BTRFS_BALANCE_PAUSED || bqb2.status & BTRFS_BALANCE_RUNNING) - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_STOP_BALANCE, NULL, 0, NULL, 0); - else { - CloseHandle(h); - goto end; - } - - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(h); - goto end; - } - - CloseHandle(h); - } else { - ShowError(hwnd, GetLastError()); - goto end; + try { + win_handle h, token; + TOKEN_PRIVILEGES tp; + LUID luid; + + 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()); + + h = CreateFileW(lpszCmdLine, 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; + btrfs_query_balance bqb2; + + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_QUERY_BALANCE, nullptr, 0, &bqb2, sizeof(btrfs_query_balance)); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + + if (bqb2.status & BTRFS_BALANCE_PAUSED || bqb2.status & BTRFS_BALANCE_RUNNING) + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_STOP_BALANCE, nullptr, 0, nullptr, 0); + else + return; + + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } else + throw last_error(GetLastError()); + } catch (const exception& e) { + error_message(hwnd, e.what()); } - -end: - CloseHandle(token); }
#ifdef __REACTOS__ diff --git a/dll/shellext/shellbtrfs/balance.h b/dll/shellext/shellbtrfs/balance.h index 0c07de4c2c..b6235376ea 100644 --- a/dll/shellext/shellbtrfs/balance.h +++ b/dll/shellext/shellbtrfs/balance.h @@ -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; }; diff --git a/dll/shellext/shellbtrfs/contextmenu.cpp b/dll/shellext/shellbtrfs/contextmenu.cpp index a5769be550..6e51a0f9ee 100644 --- a/dll/shellext/shellbtrfs/contextmenu.cpp +++ b/dll/shellext/shellbtrfs/contextmenu.cpp @@ -15,9 +15,6 @@ * You should have received a copy of the GNU Lesser General Public Licence * along with WinBtrfs. If not, see http://www.gnu.org/licenses/. */
-#ifndef __REACTOS__ -#define UNICODE -#endif #include "shellext.h" #ifndef __REACTOS__ #include <windows.h> @@ -35,8 +32,8 @@ #undef DeleteFile #endif #include <wincodec.h> -#include <string> #include <sstream> +#include <iostream>
#define NO_SHLWAPI_STRFCNS #include <shlwapi.h> @@ -66,6 +63,8 @@ typedef struct { USHORT Reserved; } reparse_header;
+static void path_remove_file(wstring& path); + // FIXME - don't assume subvol's top inode is 0x100
HRESULT __stdcall BtrfsContextMenu::QueryInterface(REFIID riid, void **ppObj) { @@ -79,18 +78,17 @@ HRESULT __stdcall BtrfsContextMenu::QueryInterface(REFIID riid, void **ppObj) { return S_OK; }
- *ppObj = NULL; + *ppObj = nullptr; return E_NOINTERFACE; }
HRESULT __stdcall BtrfsContextMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID) { - HANDLE h; IO_STATUS_BLOCK iosb; btrfs_get_file_ids bgfi; NTSTATUS Status;
if (!pidlFolder) { - FORMATETC format = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + FORMATETC format = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; UINT num_files, i; WCHAR fn[MAX_PATH]; HDROP hdrop; @@ -103,49 +101,47 @@ HRESULT __stdcall BtrfsContextMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDa if (FAILED(pdtobj->GetData(&format, &stgm))) return E_INVALIDARG;
- stgm_set = TRUE; + stgm_set = true;
hdrop = (HDROP)GlobalLock(stgm.hGlobal);
if (!hdrop) { ReleaseStgMedium(&stgm); - stgm_set = FALSE; + stgm_set = false; return E_INVALIDARG; }
- num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, NULL, 0); + num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
for (i = 0; i < num_files; i++) { if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) { - h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + win_handle h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (h != INVALID_HANDLE_VALUE) { - 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) && bgfi.inode == 0x100 && !bgfi.top) { - WCHAR parpath[MAX_PATH]; - HANDLE h2; - - StringCchCopyW(parpath, sizeof(parpath) / sizeof(WCHAR), fn); + wstring parpath;
- PathRemoveFileSpecW(parpath); + { + win_handle h2;
- h2 = CreateFileW(parpath, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + parpath = fn; + path_remove_file(parpath);
- if (h2 != INVALID_HANDLE_VALUE) - allow_snapshot = TRUE; + h2 = CreateFileW(parpath.c_str(), FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
- CloseHandle(h2); + if (h2 != INVALID_HANDLE_VALUE) + allow_snapshot = true; + }
- ignore = FALSE; - bg = FALSE; + ignore = false; + bg = false;
- CloseHandle(h); GlobalUnlock(hdrop); return S_OK; } - - CloseHandle(h); } } } @@ -155,36 +151,40 @@ HRESULT __stdcall BtrfsContextMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDa return S_OK; }
- if (!SHGetPathFromIDListW(pidlFolder, path)) - return E_FAIL; + { + WCHAR pathbuf[MAX_PATH]; + + if (!SHGetPathFromIDListW(pidlFolder, pathbuf)) + return E_FAIL; + + path = pathbuf; + }
- // check we have permissions to create new subdirectory + { + // check we have permissions to create new subdirectory
- h = CreateFileW(path, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + win_handle h = CreateFileW(path.c_str(), FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
- if (h == INVALID_HANDLE_VALUE) - return E_FAIL; + if (h == INVALID_HANDLE_VALUE) + return E_FAIL;
- // check is Btrfs volume + // check is Btrfs volume
- 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); - return E_FAIL; + if (!NT_SUCCESS(Status)) + return E_FAIL; }
- CloseHandle(h); - - ignore = FALSE; - bg = TRUE; + ignore = false; + bg = true;
return S_OK; }
-static BOOL get_volume_path_parent(const WCHAR* fn, WCHAR* volpath, ULONG volpathlen) { +static bool get_volume_path_parent(const WCHAR* fn, WCHAR* volpath, ULONG volpathlen) { WCHAR *f, *p; - BOOL b; + bool b;
f = PathFindFileNameW(fn);
@@ -202,53 +202,53 @@ static BOOL get_volume_path_parent(const WCHAR* fn, WCHAR* volpath, ULONG volpat return b; }
-static BOOL show_reflink_paste(WCHAR* path) { +static bool show_reflink_paste(const wstring& path) { HDROP hdrop; HANDLE lh; ULONG num_files; WCHAR fn[MAX_PATH], volpath1[255], volpath2[255];
if (!IsClipboardFormatAvailable(CF_HDROP)) - return FALSE; + return false;
- if (!GetVolumePathNameW(path, volpath1, sizeof(volpath1) / sizeof(WCHAR))) - return FALSE; + if (!GetVolumePathNameW(path.c_str(), volpath1, sizeof(volpath1) / sizeof(WCHAR))) + return false;
- if (!OpenClipboard(NULL)) - return FALSE; + if (!OpenClipboard(nullptr)) + return false;
hdrop = (HDROP)GetClipboardData(CF_HDROP);
if (!hdrop) { CloseClipboard(); - return FALSE; + return false; }
lh = GlobalLock(hdrop);
if (!lh) { CloseClipboard(); - return FALSE; + return false; }
- num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, NULL, 0); + num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, nullptr, 0);
if (num_files == 0) { GlobalUnlock(lh); CloseClipboard(); - return FALSE; + return false; }
if (!DragQueryFileW(hdrop, 0, fn, sizeof(fn) / sizeof(WCHAR))) { GlobalUnlock(lh); CloseClipboard(); - return FALSE; + return false; }
if (!get_volume_path_parent(fn, volpath2, sizeof(volpath2) / sizeof(WCHAR))) { GlobalUnlock(lh); CloseClipboard(); - return FALSE; + return false; }
GlobalUnlock(lh); @@ -276,30 +276,30 @@ static HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, void **ppvBits, HB BITMAPINFO bmi; HDC hdcUsed;
- *phBmp = NULL; + *phBmp = nullptr;
InitBitmapInfo(&bmi, sizeof(bmi), psize->cx, psize->cy, 32);
- hdcUsed = hdc ? hdc : GetDC(NULL); + hdcUsed = hdc ? hdc : GetDC(nullptr);
if (hdcUsed) { - *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0); + *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, nullptr, 0); if (hdc != hdcUsed) - ReleaseDC(NULL, hdcUsed); + ReleaseDC(nullptr, hdcUsed); }
return !*phBmp ? E_OUTOFMEMORY : S_OK; }
void BtrfsContextMenu::get_uac_icon() { - IWICImagingFactory* factory = NULL; + IWICImagingFactory* factory = nullptr; IWICBitmap* bitmap; HRESULT hr;
#ifdef __REACTOS__ - hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void **)&factory); + hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void **)&factory); #else - hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)); + hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory)); #endif
if (SUCCEEDED(hr)) { @@ -321,11 +321,11 @@ void BtrfsContextMenu::get_uac_icon() { sz.cx = (int)cx; sz.cy = -(int)cy;
- hr = Create32BitHBITMAP(NULL, &sz, (void**)&buf, &uacicon); + hr = Create32BitHBITMAP(nullptr, &sz, (void**)&buf, &uacicon); if (SUCCEEDED(hr)) { UINT stride = cx * sizeof(DWORD); UINT buflen = cy * stride; - bitmap->CopyPixels(NULL, stride, buflen, buf); + bitmap->CopyPixels(nullptr, stride, buflen, buf); } }
@@ -337,7 +337,7 @@ void BtrfsContextMenu::get_uac_icon() { }
HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { - WCHAR str[256]; + wstring str; ULONG entries = 0;
if (ignore) @@ -348,10 +348,10 @@ HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu
if (!bg) { if (allow_snapshot) { - if (LoadStringW(module, IDS_CREATE_SNAPSHOT, str, sizeof(str) / sizeof(WCHAR)) == 0) + if (load_string(module, IDS_CREATE_SNAPSHOT, str) == 0) return E_FAIL;
- if (!InsertMenuW(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, str)) + if (!InsertMenuW(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, str.c_str())) return E_FAIL;
entries = 1; @@ -360,7 +360,7 @@ HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu if (idCmdFirst + entries <= idCmdLast) { MENUITEMINFOW mii;
- if (LoadStringW(module, IDS_SEND_SUBVOL, str, sizeof(str) / sizeof(WCHAR)) == 0) + if (load_string(module, IDS_SEND_SUBVOL, str) == 0) return E_FAIL;
if (!uacicon) @@ -369,20 +369,20 @@ HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu memset(&mii, 0, sizeof(MENUITEMINFOW)); mii.cbSize = sizeof(MENUITEMINFOW); mii.fMask = MIIM_STRING | MIIM_ID | MIIM_BITMAP; - mii.dwTypeData = str; + mii.dwTypeData = (WCHAR*)str.c_str(); mii.wID = idCmdFirst + entries; mii.hbmpItem = uacicon;
- if (!InsertMenuItemW(hmenu, indexMenu + entries, TRUE, &mii)) + if (!InsertMenuItemW(hmenu, indexMenu + entries, true, &mii)) return E_FAIL;
entries++; } } else { - if (LoadStringW(module, IDS_NEW_SUBVOL, str, sizeof(str) / sizeof(WCHAR)) == 0) + if (load_string(module, IDS_NEW_SUBVOL, str) == 0) return E_FAIL;
- if (!InsertMenuW(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, str)) + if (!InsertMenuW(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, str.c_str())) return E_FAIL;
entries = 1; @@ -390,7 +390,7 @@ HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu if (idCmdFirst + 1 <= idCmdLast) { MENUITEMINFOW mii;
- if (LoadStringW(module, IDS_RECV_SUBVOL, str, sizeof(str) / sizeof(WCHAR)) == 0) + if (load_string(module, IDS_RECV_SUBVOL, str) == 0) return E_FAIL;
if (!uacicon) @@ -399,21 +399,21 @@ HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu memset(&mii, 0, sizeof(MENUITEMINFOW)); mii.cbSize = sizeof(MENUITEMINFOW); mii.fMask = MIIM_STRING | MIIM_ID | MIIM_BITMAP; - mii.dwTypeData = str; + mii.dwTypeData = (WCHAR*)str.c_str(); mii.wID = idCmdFirst + 1; mii.hbmpItem = uacicon;
- if (!InsertMenuItemW(hmenu, indexMenu + 1, TRUE, &mii)) + if (!InsertMenuItemW(hmenu, indexMenu + 1, true, &mii)) return E_FAIL;
entries++; }
if (idCmdFirst + 2 <= idCmdLast && show_reflink_paste(path)) { - if (LoadStringW(module, IDS_REFLINK_PASTE, str, sizeof(str) / sizeof(WCHAR)) == 0) + if (load_string(module, IDS_REFLINK_PASTE, str) == 0) return E_FAIL;
- if (!InsertMenuW(hmenu, indexMenu + 2, MF_BYPOSITION, idCmdFirst + 2, str)) + if (!InsertMenuW(hmenu, indexMenu + 2, MF_BYPOSITION, idCmdFirst + 2, str.c_str())) return E_FAIL;
entries++; @@ -423,119 +423,126 @@ HRESULT __stdcall BtrfsContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu return MAKE_HRESULT(SEVERITY_SUCCESS, 0, entries); }
-static void create_snapshot(HWND hwnd, WCHAR* fn) { - HANDLE h; +static void path_remove_file(wstring& path) { + size_t bs = path.rfind(L"\"); + + if (bs == string::npos) + return; + + if (bs == path.find(L"\")) { // only one backslash + path = path.substr(0, bs + 1); + return; + } + + path = path.substr(0, bs); +} + +static void path_strip_path(wstring& path) { + size_t bs = path.rfind(L"\"); + + if (bs == string::npos) { + path = L""; + return; + } + + path = path.substr(bs + 1); +} + +static void create_snapshot(HWND hwnd, const wstring& fn) { + win_handle h; NTSTATUS Status; IO_STATUS_BLOCK iosb; btrfs_get_file_ids bgfi;
- h = CreateFileW(fn, FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + h = CreateFileW(fn.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (h != INVALID_HANDLE_VALUE) { - 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) && bgfi.inode == 0x100 && !bgfi.top) { - WCHAR parpath[MAX_PATH], subvolname[MAX_PATH], templ[MAX_PATH], name[MAX_PATH], searchpath[MAX_PATH]; - HANDLE h2, fff; + wstring subvolname, parpath, searchpath, temp1, name, nameorig; + win_handle h2; btrfs_create_snapshot* bcs; - ULONG namelen, pathend; + ULONG namelen; WIN32_FIND_DATAW wfd; SYSTEMTIME time;
- StringCchCopyW(parpath, sizeof(parpath) / sizeof(WCHAR), fn); - PathRemoveFileSpecW(parpath); + parpath = fn; + path_remove_file(parpath);
- StringCchCopyW(subvolname, sizeof(subvolname) / sizeof(WCHAR), fn); - PathStripPathW(subvolname); + subvolname = fn; + path_strip_path(subvolname);
- h2 = CreateFileW(parpath, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + h2 = CreateFileW(parpath.c_str(), FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
- if (h2 == INVALID_HANDLE_VALUE) { - ShowError(hwnd, GetLastError()); - CloseHandle(h); - return; - } + if (h2 == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- if (!LoadStringW(module, IDS_SNAPSHOT_FILENAME, templ, MAX_PATH)) { - ShowError(hwnd, GetLastError()); - CloseHandle(h); - CloseHandle(h2); - return; - } + if (!load_string(module, IDS_SNAPSHOT_FILENAME, temp1)) + throw last_error(GetLastError());
GetLocalTime(&time);
- if (StringCchPrintfW(name, sizeof(name) / sizeof(WCHAR), templ, subvolname, time.wYear, time.wMonth, time.wDay) == STRSAFE_E_INSUFFICIENT_BUFFER) { - MessageBoxW(hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR); - CloseHandle(h); - CloseHandle(h2); - return; - } - - StringCchCopyW(searchpath, sizeof(searchpath) / sizeof(WCHAR), parpath); - StringCchCatW(searchpath, sizeof(searchpath) / sizeof(WCHAR), L"\"); - pathend = wcslen(searchpath); + wstring_sprintf(name, temp1, subvolname.c_str(), time.wYear, time.wMonth, time.wDay); + nameorig = name;
- StringCchCatW(searchpath, sizeof(searchpath) / sizeof(WCHAR), name); + searchpath = parpath + L"\" + name;
- fff = FindFirstFileW(searchpath, &wfd); + fff_handle fff = FindFirstFileW(searchpath.c_str(), &wfd);
if (fff != INVALID_HANDLE_VALUE) { - ULONG i = wcslen(searchpath), num = 2; + ULONG num = 2;
do { - FindClose(fff); - - searchpath[i] = 0; - if (StringCchPrintfW(searchpath, sizeof(searchpath) / sizeof(WCHAR), L"%s (%u)", searchpath, num) == STRSAFE_E_INSUFFICIENT_BUFFER) { - MessageBoxW(hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR); - CloseHandle(h); - CloseHandle(h2); - return; +#ifndef __REACTOS__ + name = nameorig + L" (" + to_wstring(num) + L")"; +#else + { + WCHAR buffer[32]; + + swprintf(buffer, L"%d", num); + name = nameorig + L" (" + buffer + L")"; } +#endif + searchpath = parpath + L"\" + name;
- fff = FindFirstFileW(searchpath, &wfd); + fff = FindFirstFileW(searchpath.c_str(), &wfd); num++; } while (fff != INVALID_HANDLE_VALUE); }
- namelen = wcslen(&searchpath[pathend]) * sizeof(WCHAR); + namelen = name.length() * sizeof(WCHAR);
bcs = (btrfs_create_snapshot*)malloc(sizeof(btrfs_create_snapshot) - 1 + namelen); - bcs->readonly = FALSE; - bcs->posix = FALSE; + bcs->readonly = false; + bcs->posix = false; bcs->subvol = h; - bcs->namelen = namelen; - memcpy(bcs->name, &searchpath[pathend], namelen); + bcs->namelen = (uint16_t)namelen; + memcpy(bcs->name, name.c_str(), namelen);
- Status = NtFsControlFile(h2, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, sizeof(btrfs_create_snapshot) - 1 + namelen, NULL, 0); + Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, sizeof(btrfs_create_snapshot) - 1 + namelen, nullptr, 0);
if (!NT_SUCCESS(Status)) - ShowNtStatusError(hwnd, Status); - - CloseHandle(h2); + throw ntstatus_error(Status); } - - CloseHandle(h); } else - ShowError(hwnd, GetLastError()); + throw last_error(GetLastError()); }
-static UINT64 __inline sector_align(UINT64 n, UINT64 a) { +static uint64_t __inline sector_align(uint64_t n, uint64_t a) { if (n & (a - 1)) n = (n + a) & ~(a - 1);
return n; }
-BOOL BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir) { - HANDLE source, dest; +void BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir) { + win_handle source, dest; WCHAR* name, volpath1[255], volpath2[255]; - std::wstring dirw, newpath; - BOOL ret = FALSE; + wstring dirw, newpath; FILE_BASIC_INFO fbi; FILETIME atime, mtime; - btrfs_inode_info bii; + btrfs_inode_info2 bii; btrfs_set_inode_info bsii; ULONG bytesret; NTSTATUS Status; @@ -555,58 +562,44 @@ BOOL BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir newpath = dirw; newpath += name;
- if (!get_volume_path_parent(fn, volpath1, sizeof(volpath1) / sizeof(WCHAR))) { - ShowError(hwnd, GetLastError()); - return FALSE; - } + if (!get_volume_path_parent(fn, volpath1, sizeof(volpath1) / sizeof(WCHAR))) + throw last_error(GetLastError());
- if (!GetVolumePathNameW(dir, volpath2, sizeof(volpath2) / sizeof(WCHAR))) { - ShowError(hwnd, GetLastError()); - return FALSE; - } + if (!GetVolumePathNameW(dir, volpath2, sizeof(volpath2) / sizeof(WCHAR))) + throw last_error(GetLastError());
if (wcscmp(volpath1, volpath2)) // different filesystems - return FALSE; + throw string_error(IDS_CANT_REFLINK_DIFFERENT_FS);
- source = CreateFileW(fn, GENERIC_READ | FILE_TRAVERSE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_OPEN_REPARSE_POINT, NULL); - if (source == INVALID_HANDLE_VALUE) { - ShowError(hwnd, GetLastError()); - return FALSE; - } + source = CreateFileW(fn, GENERIC_READ | FILE_TRAVERSE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_OPEN_REPARSE_POINT, nullptr); + if (source == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_INODE_INFO, NULL, 0, &bii, sizeof(btrfs_inode_info)); - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(source); - return FALSE; - } + Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_INODE_INFO, nullptr, 0, &bii, sizeof(btrfs_inode_info2)); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
// if subvol, do snapshot instead if (bii.inode == SUBVOL_ROOT_INODE) { btrfs_create_snapshot* bcs; - HANDLE dirh, fff; - std::wstring destname, search; + win_handle dirh; + wstring destname, search; WIN32_FIND_DATAW wfd; int num = 2;
- dirh = CreateFileW(dir, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dirh == INVALID_HANDLE_VALUE) { - ShowError(hwnd, GetLastError()); - CloseHandle(source); - return FALSE; - } + dirh = CreateFileW(dir, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (dirh == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
search = dirw; search += name; destname = name;
- fff = FindFirstFileW(search.c_str(), &wfd); + fff_handle fff = FindFirstFileW(search.c_str(), &wfd);
if (fff != INVALID_HANDLE_VALUE) { do { - std::wstringstream ss; - - FindClose(fff); + wstringstream ss;
ss << name; ss << L" ("; @@ -623,42 +616,30 @@ BOOL BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir
bcs = (btrfs_create_snapshot*)malloc(sizeof(btrfs_create_snapshot) - sizeof(WCHAR) + (destname.length() * sizeof(WCHAR))); bcs->subvol = source; - bcs->namelen = destname.length() * sizeof(WCHAR); + bcs->namelen = (uint16_t)(destname.length() * sizeof(WCHAR)); memcpy(bcs->name, destname.c_str(), destname.length() * sizeof(WCHAR));
- Status = NtFsControlFile(dirh, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, sizeof(btrfs_create_snapshot) - sizeof(WCHAR) + bcs->namelen, NULL, 0); + Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, sizeof(btrfs_create_snapshot) - sizeof(WCHAR) + bcs->namelen, nullptr, 0);
free(bcs);
- if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(source); - CloseHandle(dirh); - return FALSE; - } + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
- CloseHandle(source); - CloseHandle(dirh); - return TRUE; + return; }
- if (!GetFileInformationByHandleEx(source, FileBasicInfo, &fbi, sizeof(FILE_BASIC_INFO))) { - ShowError(hwnd, GetLastError()); - CloseHandle(source); - return FALSE; - } + if (!GetFileInformationByHandleEx(source, FileBasicInfo, &fbi, sizeof(FILE_BASIC_INFO))) + throw last_error(GetLastError());
if (bii.type == BTRFS_TYPE_CHARDEV || bii.type == BTRFS_TYPE_BLOCKDEV || bii.type == BTRFS_TYPE_FIFO || bii.type == BTRFS_TYPE_SOCKET) { - HANDLE dirh; + win_handle dirh; ULONG bmnsize; btrfs_mknod* bmn;
- dirh = CreateFileW(dir, FILE_ADD_FILE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dirh == INVALID_HANDLE_VALUE) { - ShowError(hwnd, GetLastError()); - CloseHandle(source); - return FALSE; - } + dirh = CreateFileW(dir, FILE_ADD_FILE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (dirh == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
bmnsize = offsetof(btrfs_mknod, name[0]) + (wcslen(name) * sizeof(WCHAR)); bmn = (btrfs_mknod*)malloc(bmnsize); @@ -666,43 +647,36 @@ BOOL BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir bmn->inode = 0; bmn->type = bii.type; bmn->st_rdev = bii.st_rdev; - bmn->namelen = wcslen(name) * sizeof(WCHAR); + bmn->namelen = (uint16_t)(wcslen(name) * sizeof(WCHAR)); memcpy(bmn->name, name, bmn->namelen);
- Status = NtFsControlFile(dirh, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_MKNOD, bmn, bmnsize, NULL, 0); + Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_MKNOD, bmn, bmnsize, nullptr, 0); if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - CloseHandle(dirh); - CloseHandle(source); free(bmn); - return FALSE; + throw ntstatus_error(Status); }
- CloseHandle(dirh); free(bmn);
- dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, 0, NULL); + dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, OPEN_EXISTING, 0, nullptr); } else if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (CreateDirectoryExW(fn, newpath.c_str(), NULL)) + if (CreateDirectoryExW(fn, newpath.c_str(), nullptr)) dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); else dest = INVALID_HANDLE_VALUE; } else - dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, source); + dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, source);
if (dest == INVALID_HANDLE_VALUE) { int num = 2;
- if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_ALREADY_EXISTS && wcscmp(fn, newpath.c_str())) { - ShowError(hwnd, GetLastError()); - CloseHandle(source); - return FALSE; - } + if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_ALREADY_EXISTS && wcscmp(fn, newpath.c_str())) + throw last_error(GetLastError());
do { WCHAR* ext; - std::wstringstream ss; + wstringstream ss;
ext = PathFindExtensionW(fn);
@@ -714,7 +688,7 @@ BOOL BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir ss << num; ss << L")"; } else { - std::wstring namew = name; + wstring namew = name;
ss << namew.substr(0, ext - name); ss << L" ("; @@ -725,514 +699,449 @@ BOOL BtrfsContextMenu::reflink_copy(HWND hwnd, const WCHAR* fn, const WCHAR* dir
newpath = ss.str(); if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (CreateDirectoryExW(fn, newpath.c_str(), NULL)) - dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (CreateDirectoryExW(fn, newpath.c_str(), nullptr)) + dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); else dest = INVALID_HANDLE_VALUE; } else - dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, source); + dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, source);
if (dest == INVALID_HANDLE_VALUE) { - if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_ALREADY_EXISTS) { - ShowError(hwnd, GetLastError()); - CloseHandle(source); - return FALSE; - } + if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_ALREADY_EXISTS) + throw last_error(GetLastError());
num++; } else break; - } while (TRUE); + } while (true); }
- memset(&bsii, 0, sizeof(btrfs_set_inode_info)); - - bsii.flags_changed = TRUE; - bsii.flags = bii.flags; - - if (bii.flags & BTRFS_INODE_COMPRESS) { - bsii.compression_type_changed = TRUE; - bsii.compression_type = bii.compression_type; - } + try { + memset(&bsii, 0, sizeof(btrfs_set_inode_info));
- Status = NtFsControlFile(dest, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), NULL, 0); - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - goto end; - } + bsii.flags_changed = true; + bsii.flags = bii.flags;
- if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - HANDLE h; - WIN32_FIND_DATAW fff; - std::wstring qs; + if (bii.flags & BTRFS_INODE_COMPRESS) { + bsii.compression_type_changed = true; + bsii.compression_type = bii.compression_type; + }
- qs = fn; - qs += L"\*"; + Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
- h = FindFirstFileW(qs.c_str(), &fff); - if (h != INVALID_HANDLE_VALUE) { - do { - std::wstring fn2; + if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + fff_handle h; + WIN32_FIND_DATAW fff; + wstring qs;
- if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0))) - continue; + qs = fn; + qs += L"\*";
- fn2 = fn; - fn2 += L"\"; - fn2 += fff.cFileName; + h = FindFirstFileW(qs.c_str(), &fff); + if (h != INVALID_HANDLE_VALUE) { + do { + wstring fn2;
- if (!reflink_copy(hwnd, fn2.c_str(), newpath.c_str())) - goto end; - } while (FindNextFileW(h, &fff)); + if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0))) + continue;
- FindClose(h); - } - } + fn2 = fn; + fn2 += L"\"; + fn2 += fff.cFileName;
- // CreateDirectoryExW also copies streams, no need to do it here - } else { - HANDLE h; - WIN32_FIND_STREAM_DATA fsd; - - if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - reparse_header rh; - ULONG rplen; - UINT8* rp; - - if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, NULL, 0, &rh, sizeof(reparse_header), &bytesret, NULL)) { - if (GetLastError() != ERROR_MORE_DATA) { - ShowError(hwnd, GetLastError()); - goto end; + reflink_copy(hwnd, fn2.c_str(), newpath.c_str()); + } while (FindNextFileW(h, &fff)); } }
- rplen = sizeof(reparse_header) + rh.ReparseDataLength; - rp = (UINT8*)malloc(rplen); + // CreateDirectoryExW also copies streams, no need to do it here + } else { + WIN32_FIND_STREAM_DATA fsd;
- if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, NULL, 0, rp, rplen, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - goto end; - } + if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + reparse_header rh; + ULONG rplen; + uint8_t* rp;
- if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, rplen, NULL, 0, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - goto end; - } + if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, &rh, sizeof(reparse_header), &bytesret, nullptr)) { + if (GetLastError() != ERROR_MORE_DATA) + throw last_error(GetLastError()); + }
- free(rp); - } else { - FILE_STANDARD_INFO fsi; - FILE_END_OF_FILE_INFO feofi; - FSCTL_GET_INTEGRITY_INFORMATION_BUFFER fgiib; - FSCTL_SET_INTEGRITY_INFORMATION_BUFFER fsiib; - DUPLICATE_EXTENTS_DATA ded; - UINT64 offset, alloc_size; - ULONG maxdup; - - if (!GetFileInformationByHandleEx(source, FileStandardInfo, &fsi, sizeof(FILE_STANDARD_INFO))) { - ShowError(hwnd, GetLastError()); - goto end; - } + rplen = sizeof(reparse_header) + rh.ReparseDataLength; + rp = (uint8_t*)malloc(rplen);
- if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, NULL, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - goto end; - } + if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, rp, rplen, &bytesret, nullptr)) + throw last_error(GetLastError()); + + if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, rplen, nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError());
- if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { - if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - goto end; + free(rp); + } else { + FILE_STANDARD_INFO fsi; + FILE_END_OF_FILE_INFO feofi; + FSCTL_GET_INTEGRITY_INFORMATION_BUFFER fgiib; + FSCTL_SET_INTEGRITY_INFORMATION_BUFFER fsiib; + DUPLICATE_EXTENTS_DATA ded; + uint64_t offset, alloc_size; + ULONG maxdup; + + if (!GetFileInformationByHandleEx(source, FileStandardInfo, &fsi, sizeof(FILE_STANDARD_INFO))) + throw last_error(GetLastError()); + + if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, nullptr, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, nullptr)) + throw last_error(GetLastError()); + + if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { + if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError()); } - }
- fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm; - fsiib.Reserved = 0; - fsiib.Flags = fgiib.Flags; - if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), NULL, 0, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - goto end; - } + fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm; + fsiib.Reserved = 0; + fsiib.Flags = fgiib.Flags; + if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError());
- feofi.EndOfFile = fsi.EndOfFile; - if (!SetFileInformationByHandle(dest, FileEndOfFileInfo, &feofi, sizeof(FILE_END_OF_FILE_INFO))){ - ShowError(hwnd, GetLastError()); - goto end; - } + feofi.EndOfFile = fsi.EndOfFile; + if (!SetFileInformationByHandle(dest, FileEndOfFileInfo, &feofi, sizeof(FILE_END_OF_FILE_INFO))) + throw last_error(GetLastError());
- ded.FileHandle = source; - maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1; + ded.FileHandle = source; + maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1;
- alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes); + alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes);
- offset = 0; - while (offset < alloc_size) { - ded.SourceFileOffset.QuadPart = ded.TargetFileOffset.QuadPart = offset; - ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset); - if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), NULL, 0, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - goto end; - } + offset = 0; + while (offset < alloc_size) { + ded.SourceFileOffset.QuadPart = ded.TargetFileOffset.QuadPart = offset; + ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset); + if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError());
- offset += ded.ByteCount.QuadPart; + offset += ded.ByteCount.QuadPart; + } } - }
- h = FindFirstStreamW(fn, FindStreamInfoStandard, &fsd, 0); - if (h != INVALID_HANDLE_VALUE) { - do { - std::wstring sn; + fff_handle h = FindFirstStreamW(fn, FindStreamInfoStandard, &fsd, 0); + if (h != INVALID_HANDLE_VALUE) { + do { + wstring sn;
- sn = fsd.cStreamName; + sn = fsd.cStreamName;
- if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") { - HANDLE stream; - UINT8* data = NULL; + if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") { + win_handle stream; + uint8_t* data = nullptr; + uint16_t stream_size = (uint16_t)fsd.StreamSize.QuadPart;
- if (fsd.StreamSize.QuadPart > 0) { - std::wstring fn2; + if (fsd.StreamSize.QuadPart > 0) { + wstring fn2;
- fn2 = fn; - fn2 += sn; + fn2 = fn; + fn2 += sn;
- stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
- if (stream == INVALID_HANDLE_VALUE) { - ShowError(hwnd, GetLastError()); - FindClose(h); - goto end; - } + if (stream == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- // We can get away with this because our streams are guaranteed to be below 64 KB - - // don't do this on NTFS! - data = (UINT8*)malloc(fsd.StreamSize.QuadPart); + // We can get away with this because our streams are guaranteed to be below 64 KB - + // don't do this on NTFS! + data = (uint8_t*)malloc(stream_size);
- if (!ReadFile(stream, data, fsd.StreamSize.QuadPart, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - FindClose(h); - free(data); - CloseHandle(stream); - goto end; + if (!ReadFile(stream, data, stream_size, &bytesret, nullptr)) { + free(data); + throw last_error(GetLastError()); + } }
- CloseHandle(stream); - } - - stream = CreateFileW((newpath + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, NULL); - - if (stream == INVALID_HANDLE_VALUE) { - ShowError(hwnd, GetLastError()); + stream = CreateFileW((newpath + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, nullptr);
- FindClose(h); - if (data) free(data); + if (stream == INVALID_HANDLE_VALUE) { + if (data) free(data); + throw last_error(GetLastError()); + }
- goto end; - } + if (data) { + if (!WriteFile(stream, data, stream_size, &bytesret, nullptr)) { + free(data); + throw last_error(GetLastError()); + }
- if (data) { - if (!WriteFile(stream, data, fsd.StreamSize.QuadPart, &bytesret, NULL)) { - ShowError(hwnd, GetLastError()); - FindClose(h); free(data); - CloseHandle(stream); - goto end; } - - free(data); } - - CloseHandle(stream); - } - } while (FindNextStreamW(h, &fsd)); - - FindClose(h); + } while (FindNextStreamW(h, &fsd)); + } } - }
- atime.dwLowDateTime = fbi.LastAccessTime.LowPart; - atime.dwHighDateTime = fbi.LastAccessTime.HighPart; - mtime.dwLowDateTime = fbi.LastWriteTime.LowPart; - mtime.dwHighDateTime = fbi.LastWriteTime.HighPart; - SetFileTime(dest, NULL, &atime, &mtime); + atime.dwLowDateTime = fbi.LastAccessTime.LowPart; + atime.dwHighDateTime = fbi.LastAccessTime.HighPart; + mtime.dwLowDateTime = fbi.LastWriteTime.LowPart; + mtime.dwHighDateTime = fbi.LastWriteTime.HighPart; + SetFileTime(dest, nullptr, &atime, &mtime);
- Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_XATTRS, NULL, 0, &bsxa, sizeof(btrfs_set_xattr)); + Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, &bsxa, sizeof(btrfs_set_xattr));
- if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) { - ULONG xalen = 0; - btrfs_set_xattr *xa = NULL, *xa2; + if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) { + ULONG xalen = 0; + btrfs_set_xattr *xa = nullptr, *xa2;
- do { - xalen += 1024; - - if (xa) free(xa); - xa = (btrfs_set_xattr*)malloc(xalen); + do { + xalen += 1024;
- Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_XATTRS, NULL, 0, xa, xalen); - } while (Status == STATUS_BUFFER_OVERFLOW); + if (xa) free(xa); + xa = (btrfs_set_xattr*)malloc(xalen);
- if (!NT_SUCCESS(Status)) { - free(xa); - ShowNtStatusError(hwnd, Status); - goto end; - } + Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, xa, xalen); + } while (Status == STATUS_BUFFER_OVERFLOW);
- xa2 = xa; - while (xa2->valuelen > 0) { - Status = NtFsControlFile(dest, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_SET_XATTR, xa2, - offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen, NULL, 0); if (!NT_SUCCESS(Status)) { free(xa); - ShowNtStatusError(hwnd, Status); - goto end; + throw ntstatus_error(Status); } - xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen]; - }
- free(xa); - } else if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwnd, Status); - goto end; - } - - ret = TRUE; + xa2 = xa; + while (xa2->valuelen > 0) { + Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, xa2, + offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen, nullptr, 0); + if (!NT_SUCCESS(Status)) { + free(xa); + throw ntstatus_error(Status); + } + xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen]; + }
-end: - if (!ret) { + free(xa); + } else if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } catch (...) { FILE_DISPOSITION_INFO fdi;
- fdi.DeleteFile = TRUE; + fdi.DeleteFile = true; if (!SetFileInformationByHandle(dest, FileDispositionInfo, &fdi, sizeof(FILE_DISPOSITION_INFO))) - ShowError(hwnd, GetLastError()); - } - - CloseHandle(dest); - CloseHandle(source); + throw last_error(GetLastError());
- return ret; + throw; + } }
HRESULT __stdcall BtrfsContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO picia) { LPCMINVOKECOMMANDINFOEX pici = (LPCMINVOKECOMMANDINFOEX)picia;
- if (ignore) - return E_INVALIDARG; + try { + if (ignore) + return E_INVALIDARG;
- if (!bg) { - if ((IS_INTRESOURCE(pici->lpVerb) && allow_snapshot && pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SNAPSHOT_VERBA))) { - UINT num_files, i; - WCHAR fn[MAX_PATH]; + if (!bg) { + if ((IS_INTRESOURCE(pici->lpVerb) && allow_snapshot && pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SNAPSHOT_VERBA))) { + UINT num_files, i; + WCHAR fn[MAX_PATH];
- if (!stgm_set) - return E_FAIL; + if (!stgm_set) + return E_FAIL;
- num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, NULL, 0); + num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
- if (num_files == 0) - return E_FAIL; + if (num_files == 0) + return E_FAIL;
- for (i = 0; i < num_files; i++) { - if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) { - create_snapshot(pici->hwnd, fn); + for (i = 0; i < num_files; i++) { + if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) { + create_snapshot(pici->hwnd, fn); + } } - }
- return S_OK; - } else if ((IS_INTRESOURCE(pici->lpVerb) && ((allow_snapshot && (ULONG_PTR)pici->lpVerb == 1) || (!allow_snapshot && (ULONG_PTR)pici->lpVerb == 0))) || - (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SEND_VERBA))) { - UINT num_files, i; - WCHAR dll[MAX_PATH], fn[MAX_PATH]; - std::wstring t; - SHELLEXECUTEINFOW sei; + return S_OK; + } else if ((IS_INTRESOURCE(pici->lpVerb) && ((allow_snapshot && (ULONG_PTR)pici->lpVerb == 1) || (!allow_snapshot && (ULONG_PTR)pici->lpVerb == 0))) || + (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SEND_VERBA))) { + UINT num_files, i; + WCHAR dll[MAX_PATH], fn[MAX_PATH]; + wstring t; + SHELLEXECUTEINFOW sei;
- GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR)); + GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR));
- if (!stgm_set) - return E_FAIL; + if (!stgm_set) + return E_FAIL;
- num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, NULL, 0); + num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
- if (num_files == 0) - return E_FAIL; + if (num_files == 0) + return E_FAIL;
- for (i = 0; i < num_files; i++) { - if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) { - t = L"""; - t += dll; - t += L"",SendSubvolGUI "; - t += fn; - - RtlZeroMemory(&sei, sizeof(sei)); - - sei.cbSize = sizeof(sei); - sei.hwnd = pici->hwnd; - sei.lpVerb = L"runas"; - sei.lpFile = L"rundll32.exe"; - sei.lpParameters = t.c_str(); - sei.nShow = SW_SHOW; - sei.fMask = SEE_MASK_NOCLOSEPROCESS; - - if (!ShellExecuteExW(&sei)) { - ShowError(pici->hwnd, GetLastError()); - return E_FAIL; - } + for (i = 0; i < num_files; i++) { + if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) { + t = L"""; + t += dll; + t += L"",SendSubvolGUI "; + t += fn;
- WaitForSingleObject(sei.hProcess, INFINITE); - CloseHandle(sei.hProcess); - } - } + RtlZeroMemory(&sei, sizeof(sei));
- return S_OK; - } - } else { - if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, NEW_SUBVOL_VERBA))) { - HANDLE h; - IO_STATUS_BLOCK iosb; - NTSTATUS Status; - ULONG pathlen, searchpathlen, pathend, bcslen; - WCHAR name[MAX_PATH], *searchpath; - btrfs_create_subvol* bcs; - HANDLE fff; - WIN32_FIND_DATAW wfd; + sei.cbSize = sizeof(sei); + sei.hwnd = pici->hwnd; + sei.lpVerb = L"runas"; + sei.lpFile = L"rundll32.exe"; + sei.lpParameters = t.c_str(); + sei.nShow = SW_SHOW; + sei.fMask = SEE_MASK_NOCLOSEPROCESS;
- if (!LoadStringW(module, IDS_NEW_SUBVOL_FILENAME, name, MAX_PATH)) { - ShowError(pici->hwnd, GetLastError()); - return E_FAIL; - } + if (!ShellExecuteExW(&sei)) + throw last_error(GetLastError());
- h = CreateFileW(path, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + WaitForSingleObject(sei.hProcess, INFINITE); + CloseHandle(sei.hProcess); + } + }
- if (h == INVALID_HANDLE_VALUE) { - ShowError(pici->hwnd, GetLastError()); - return E_FAIL; + return S_OK; } + } else { + if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, NEW_SUBVOL_VERBA))) { + win_handle h; + IO_STATUS_BLOCK iosb; + NTSTATUS Status; + ULONG bcslen; + wstring name, nameorig, searchpath; + btrfs_create_subvol* bcs; + WIN32_FIND_DATAW wfd;
- pathlen = wcslen(path); - - searchpathlen = pathlen + wcslen(name) + 10; - searchpath = (WCHAR*)malloc(searchpathlen * sizeof(WCHAR)); - - StringCchCopyW(searchpath, searchpathlen, path); - StringCchCatW(searchpath, searchpathlen, L"\"); - pathend = wcslen(searchpath); + if (!load_string(module, IDS_NEW_SUBVOL_FILENAME, name)) + throw last_error(GetLastError());
- StringCchCatW(searchpath, searchpathlen, name); + h = CreateFileW(path.c_str(), FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
- fff = FindFirstFileW(searchpath, &wfd); + if (h == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- if (fff != INVALID_HANDLE_VALUE) { - ULONG i = wcslen(searchpath), num = 2; + searchpath = path + L"\" + name; + nameorig = name;
- do { - FindClose(fff); + { + fff_handle fff = FindFirstFileW(searchpath.c_str(), &wfd);
- searchpath[i] = 0; - if (StringCchPrintfW(searchpath, searchpathlen, L"%s (%u)", searchpath, num) == STRSAFE_E_INSUFFICIENT_BUFFER) { - MessageBoxW(pici->hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR); - CloseHandle(h); - return E_FAIL; - } + if (fff != INVALID_HANDLE_VALUE) { + ULONG num = 2;
- fff = FindFirstFileW(searchpath, &wfd); - num++; - } while (fff != INVALID_HANDLE_VALUE); - } + do { +#ifndef __REACTOS__ + name = nameorig + L" (" + to_wstring(num) + L")"; +#else + { + WCHAR buffer[32];
- bcslen = offsetof(btrfs_create_subvol, name[0]) + (wcslen(&searchpath[pathend]) * sizeof(WCHAR)); - bcs = (btrfs_create_subvol*)malloc(bcslen); + swprintf(buffer, L"%d", num); + name = nameorig + L" (" + buffer + L")"; + } +#endif + searchpath = path + L"\" + name;
- bcs->readonly = FALSE; - bcs->posix = FALSE; - bcs->namelen = wcslen(&searchpath[pathend]) * sizeof(WCHAR); - memcpy(bcs->name, &searchpath[pathend], bcs->namelen); + fff = FindFirstFileW(searchpath.c_str(), &wfd); + num++; + } while (fff != INVALID_HANDLE_VALUE); + } + }
- Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, bcs, bcslen, NULL, 0); + bcslen = offsetof(btrfs_create_subvol, name[0]) + (name.length() * sizeof(WCHAR)); + bcs = (btrfs_create_subvol*)malloc(bcslen);
- free(searchpath); - free(bcs); + bcs->readonly = false; + bcs->posix = false; + bcs->namelen = (uint16_t)(name.length() * sizeof(WCHAR)); + memcpy(bcs->name, name.c_str(), name.length() * sizeof(WCHAR));
- if (!NT_SUCCESS(Status)) { - CloseHandle(h); - ShowNtStatusError(pici->hwnd, Status); - return E_FAIL; - } + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, bcs, bcslen, nullptr, 0);
- CloseHandle(h); + free(bcs);
- return S_OK; - } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 1) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, RECV_VERBA))) { - WCHAR dll[MAX_PATH]; - std::wstring t; - SHELLEXECUTEINFOW sei; + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
- GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR)); + return S_OK; + } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 1) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, RECV_VERBA))) { + WCHAR dll[MAX_PATH]; + wstring t; + SHELLEXECUTEINFOW sei;
- t = L"""; - t += dll; - t += L"",RecvSubvolGUI "; - t += path; + GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR));
- RtlZeroMemory(&sei, sizeof(sei)); + t = L"""; + t += dll; + t += L"",RecvSubvolGUI "; + t += path;
- sei.cbSize = sizeof(sei); - sei.hwnd = pici->hwnd; - sei.lpVerb = L"runas"; - sei.lpFile = L"rundll32.exe"; - sei.lpParameters = t.c_str(); - sei.nShow = SW_SHOW; - sei.fMask = SEE_MASK_NOCLOSEPROCESS; + RtlZeroMemory(&sei, sizeof(sei));
- if (!ShellExecuteExW(&sei)) { - ShowError(pici->hwnd, GetLastError()); - return E_FAIL; - } + sei.cbSize = sizeof(sei); + sei.hwnd = pici->hwnd; + sei.lpVerb = L"runas"; + sei.lpFile = L"rundll32.exe"; + sei.lpParameters = t.c_str(); + sei.nShow = SW_SHOW; + sei.fMask = SEE_MASK_NOCLOSEPROCESS;
- WaitForSingleObject(sei.hProcess, INFINITE); - CloseHandle(sei.hProcess); + if (!ShellExecuteExW(&sei)) + throw last_error(GetLastError());
- return S_OK; - } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 2) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, REFLINK_VERBA))) { - HDROP hdrop; + WaitForSingleObject(sei.hProcess, INFINITE); + CloseHandle(sei.hProcess);
- if (!IsClipboardFormatAvailable(CF_HDROP)) return S_OK; + } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 2) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, REFLINK_VERBA))) { + HDROP hdrop;
- if (!OpenClipboard(pici->hwnd)) { - ShowError(pici->hwnd, GetLastError()); - return E_FAIL; - } + if (!IsClipboardFormatAvailable(CF_HDROP)) + return S_OK; + + if (!OpenClipboard(pici->hwnd)) + throw last_error(GetLastError());
- hdrop = (HDROP)GetClipboardData(CF_HDROP); + try { + hdrop = (HDROP)GetClipboardData(CF_HDROP);
- if (hdrop) { - HANDLE lh; + if (hdrop) { + HANDLE lh;
- lh = GlobalLock(hdrop); + lh = GlobalLock(hdrop);
- if (lh) { - ULONG num_files, i; - WCHAR fn[MAX_PATH]; + if (lh) { + try { + ULONG num_files, i; + WCHAR fn[MAX_PATH];
- num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, NULL, 0); + num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, nullptr, 0);
- for (i = 0; i < num_files; i++) { - if (DragQueryFileW(hdrop, i, fn, sizeof(fn) / sizeof(WCHAR))) { - if (!reflink_copy(pici->hwnd, fn, pici->lpDirectoryW)) { + for (i = 0; i < num_files; i++) { + if (DragQueryFileW(hdrop, i, fn, sizeof(fn) / sizeof(WCHAR))) { + reflink_copy(pici->hwnd, fn, pici->lpDirectoryW); + } + } + } catch (...) { GlobalUnlock(lh); - CloseClipboard(); - return E_FAIL; + throw; } + + GlobalUnlock(lh); } } - - GlobalUnlock(lh); + } catch (...) { + CloseClipboard(); + throw; } - }
- CloseClipboard(); + CloseClipboard();
- return S_OK; + return S_OK; + } } + } catch (const exception& e) { + error_message(pici->hwnd, e.what()); }
return E_FAIL; @@ -1389,71 +1298,63 @@ HRESULT __stdcall BtrfsContextMenu::GetCommandString(UINT_PTR idCmd, UINT uFlags } }
-static void reflink_copy2(std::wstring srcfn, std::wstring destdir, std::wstring destname) { - HANDLE source, dest; - BOOL ret = FALSE; +static void reflink_copy2(const wstring& srcfn, const wstring& destdir, const wstring& destname) { + win_handle source, dest; FILE_BASIC_INFO fbi; FILETIME atime, mtime; - btrfs_inode_info bii; + btrfs_inode_info2 bii; btrfs_set_inode_info bsii; ULONG bytesret; NTSTATUS Status; IO_STATUS_BLOCK iosb; btrfs_set_xattr bsxa;
- source = CreateFileW(srcfn.c_str(), GENERIC_READ | FILE_TRAVERSE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_OPEN_REPARSE_POINT, NULL); + source = CreateFileW(srcfn.c_str(), GENERIC_READ | FILE_TRAVERSE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_OPEN_REPARSE_POINT, nullptr); if (source == INVALID_HANDLE_VALUE) - return; + throw last_error(GetLastError());
- Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_INODE_INFO, NULL, 0, &bii, sizeof(btrfs_inode_info)); - if (!NT_SUCCESS(Status)) { - CloseHandle(source); - return; - } + Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_INODE_INFO, nullptr, 0, &bii, sizeof(btrfs_inode_info2)); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
// if subvol, do snapshot instead if (bii.inode == SUBVOL_ROOT_INODE) { ULONG bcslen; btrfs_create_snapshot* bcs; - HANDLE dirh; + win_handle dirh;
- dirh = CreateFileW(destdir.c_str(), FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dirh == INVALID_HANDLE_VALUE) { - CloseHandle(source); - return; - } + dirh = CreateFileW(destdir.c_str(), FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (dirh == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
bcslen = offsetof(btrfs_create_snapshot, name[0]) + (destname.length() * sizeof(WCHAR)); bcs = (btrfs_create_snapshot*)malloc(bcslen); bcs->subvol = source; - bcs->namelen = destname.length() * sizeof(WCHAR); + bcs->namelen = (uint16_t)(destname.length() * sizeof(WCHAR)); memcpy(bcs->name, destname.c_str(), destname.length() * sizeof(WCHAR));
- Status = NtFsControlFile(dirh, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, bcslen, NULL, 0); + Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, bcslen, nullptr, 0); + if (!NT_SUCCESS(Status)) { + free(bcs); + throw ntstatus_error(Status); + }
free(bcs);
- CloseHandle(source); - CloseHandle(dirh); - return; }
- if (!GetFileInformationByHandleEx(source, FileBasicInfo, &fbi, sizeof(FILE_BASIC_INFO))) { - CloseHandle(source); - return; - } + if (!GetFileInformationByHandleEx(source, FileBasicInfo, &fbi, sizeof(FILE_BASIC_INFO))) + throw last_error(GetLastError());
if (bii.type == BTRFS_TYPE_CHARDEV || bii.type == BTRFS_TYPE_BLOCKDEV || bii.type == BTRFS_TYPE_FIFO || bii.type == BTRFS_TYPE_SOCKET) { - HANDLE dirh; + win_handle dirh; ULONG bmnsize; btrfs_mknod* bmn;
- dirh = CreateFileW(destdir.c_str(), FILE_ADD_FILE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dirh == INVALID_HANDLE_VALUE) { - CloseHandle(source); - return; - } + dirh = CreateFileW(destdir.c_str(), FILE_ADD_FILE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (dirh == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
bmnsize = offsetof(btrfs_mknod, name[0]) + (destname.length() * sizeof(WCHAR)); bmn = (btrfs_mknod*)malloc(bmnsize); @@ -1461,261 +1362,246 @@ static void reflink_copy2(std::wstring srcfn, std::wstring destdir, std::wstring bmn->inode = 0; bmn->type = bii.type; bmn->st_rdev = bii.st_rdev; - bmn->namelen = destname.length() * sizeof(WCHAR); + bmn->namelen = (uint16_t)(destname.length() * sizeof(WCHAR)); memcpy(bmn->name, destname.c_str(), bmn->namelen);
- Status = NtFsControlFile(dirh, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_MKNOD, bmn, bmnsize, NULL, 0); + Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_MKNOD, bmn, bmnsize, nullptr, 0); if (!NT_SUCCESS(Status)) { - CloseHandle(dirh); - CloseHandle(source); free(bmn); - return; + throw ntstatus_error(Status); }
- CloseHandle(dirh); free(bmn);
- dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, 0, NULL); + dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, OPEN_EXISTING, 0, nullptr); } else if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (CreateDirectoryExW(srcfn.c_str(), (destdir + destname).c_str(), NULL)) + if (CreateDirectoryExW(srcfn.c_str(), (destdir + destname).c_str(), nullptr)) dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - else - dest = INVALID_HANDLE_VALUE; + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + else + dest = INVALID_HANDLE_VALUE; } else - dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, source); + dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, source);
- if (dest == INVALID_HANDLE_VALUE) { - CloseHandle(source); - return; - } + if (dest == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
memset(&bsii, 0, sizeof(btrfs_set_inode_info));
- bsii.flags_changed = TRUE; + bsii.flags_changed = true; bsii.flags = bii.flags;
if (bii.flags & BTRFS_INODE_COMPRESS) { - bsii.compression_type_changed = TRUE; + bsii.compression_type_changed = true; bsii.compression_type = bii.compression_type; }
- Status = NtFsControlFile(dest, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), NULL, 0); - if (!NT_SUCCESS(Status)) - goto end; - - if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - HANDLE h; - WIN32_FIND_DATAW fff; - std::wstring qs; + try { + Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
- qs = srcfn; - qs += L"\*"; + if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + WIN32_FIND_DATAW fff; + wstring qs;
- h = FindFirstFileW(qs.c_str(), &fff); - if (h != INVALID_HANDLE_VALUE) { - do { - std::wstring fn2; + qs = srcfn; + qs += L"\*";
- if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0))) - continue; + fff_handle h = FindFirstFileW(qs.c_str(), &fff); + if (h != INVALID_HANDLE_VALUE) { + do { + wstring fn2;
- fn2 = srcfn; - fn2 += L"\"; - fn2 += fff.cFileName; + if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0))) + continue;
- reflink_copy2(fn2, destdir + destname + L"\", fff.cFileName); - } while (FindNextFileW(h, &fff)); + fn2 = srcfn; + fn2 += L"\"; + fn2 += fff.cFileName;
- FindClose(h); + reflink_copy2(fn2, destdir + destname + L"\", fff.cFileName); + } while (FindNextFileW(h, &fff)); + } } - }
- // CreateDirectoryExW also copies streams, no need to do it here - } else { - HANDLE h; - WIN32_FIND_STREAM_DATA fsd; + // CreateDirectoryExW also copies streams, no need to do it here + } else { + WIN32_FIND_STREAM_DATA fsd;
- if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - reparse_header rh; - ULONG rplen; - UINT8* rp; + if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + reparse_header rh; + ULONG rplen; + uint8_t* rp;
- if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, NULL, 0, &rh, sizeof(reparse_header), &bytesret, NULL)) { - if (GetLastError() != ERROR_MORE_DATA) - goto end; - } + if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, &rh, sizeof(reparse_header), &bytesret, nullptr)) { + if (GetLastError() != ERROR_MORE_DATA) + throw last_error(GetLastError()); + }
- rplen = sizeof(reparse_header) + rh.ReparseDataLength; - rp = (UINT8*)malloc(rplen); + rplen = sizeof(reparse_header) + rh.ReparseDataLength; + rp = (uint8_t*)malloc(rplen);
- if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, NULL, 0, rp, rplen, &bytesret, NULL)) - goto end; + try { + if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, rp, rplen, &bytesret, nullptr)) + throw last_error(GetLastError());
- if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, rplen, NULL, 0, &bytesret, NULL)) - goto end; + if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, rplen, nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError()); + } catch (...) { + free(rp); + throw; + }
- free(rp); - } else { - FILE_STANDARD_INFO fsi; - FILE_END_OF_FILE_INFO feofi; - FSCTL_GET_INTEGRITY_INFORMATION_BUFFER fgiib; - FSCTL_SET_INTEGRITY_INFORMATION_BUFFER fsiib; - DUPLICATE_EXTENTS_DATA ded; - UINT64 offset, alloc_size; - ULONG maxdup; - - if (!GetFileInformationByHandleEx(source, FileStandardInfo, &fsi, sizeof(FILE_STANDARD_INFO))) - goto end; - - if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, NULL, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, NULL)) - goto end; - - if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { - if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytesret, NULL)) - goto end; - } + free(rp); + } else { + FILE_STANDARD_INFO fsi; + FILE_END_OF_FILE_INFO feofi; + FSCTL_GET_INTEGRITY_INFORMATION_BUFFER fgiib; + FSCTL_SET_INTEGRITY_INFORMATION_BUFFER fsiib; + DUPLICATE_EXTENTS_DATA ded; + uint64_t offset, alloc_size; + ULONG maxdup; + + if (!GetFileInformationByHandleEx(source, FileStandardInfo, &fsi, sizeof(FILE_STANDARD_INFO))) + throw last_error(GetLastError()); + + if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, nullptr, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, nullptr)) + throw last_error(GetLastError()); + + if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { + if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError()); + }
- fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm; - fsiib.Reserved = 0; - fsiib.Flags = fgiib.Flags; - if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), NULL, 0, &bytesret, NULL)) - goto end; + fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm; + fsiib.Reserved = 0; + fsiib.Flags = fgiib.Flags; + if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError());
- feofi.EndOfFile = fsi.EndOfFile; - if (!SetFileInformationByHandle(dest, FileEndOfFileInfo, &feofi, sizeof(FILE_END_OF_FILE_INFO))) - goto end; + feofi.EndOfFile = fsi.EndOfFile; + if (!SetFileInformationByHandle(dest, FileEndOfFileInfo, &feofi, sizeof(FILE_END_OF_FILE_INFO))) + throw last_error(GetLastError());
- ded.FileHandle = source; - maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1; + ded.FileHandle = source; + maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1;
- alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes); + alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes);
- offset = 0; - while (offset < alloc_size) { - ded.SourceFileOffset.QuadPart = ded.TargetFileOffset.QuadPart = offset; - ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset); - if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), NULL, 0, &bytesret, NULL)) - goto end; + offset = 0; + while (offset < alloc_size) { + ded.SourceFileOffset.QuadPart = ded.TargetFileOffset.QuadPart = offset; + ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset); + if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), nullptr, 0, &bytesret, nullptr)) + throw last_error(GetLastError());
- offset += ded.ByteCount.QuadPart; + offset += ded.ByteCount.QuadPart; + } } - }
- h = FindFirstStreamW(srcfn.c_str(), FindStreamInfoStandard, &fsd, 0); - if (h != INVALID_HANDLE_VALUE) { - do { - std::wstring sn; + fff_handle h = FindFirstStreamW(srcfn.c_str(), FindStreamInfoStandard, &fsd, 0); + if (h != INVALID_HANDLE_VALUE) { + do { + wstring sn;
- sn = fsd.cStreamName; + sn = fsd.cStreamName;
- if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") { - HANDLE stream; - UINT8* data = NULL; + if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") { + win_handle stream; + uint8_t* data = nullptr;
- if (fsd.StreamSize.QuadPart > 0) { - std::wstring fn2; + if (fsd.StreamSize.QuadPart > 0) { + wstring fn2; + uint16_t stream_size = (uint16_t)fsd.StreamSize.QuadPart;
- fn2 = srcfn; - fn2 += sn; + fn2 = srcfn; + fn2 += sn;
- stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
- if (stream == INVALID_HANDLE_VALUE) - goto end; + if (stream == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- // We can get away with this because our streams are guaranteed to be below 64 KB - - // don't do this on NTFS! - data = (UINT8*)malloc(fsd.StreamSize.QuadPart); + // We can get away with this because our streams are guaranteed to be below 64 KB - + // don't do this on NTFS! + data = (uint8_t*)malloc(stream_size);
- if (!ReadFile(stream, data, fsd.StreamSize.QuadPart, &bytesret, NULL)) { - free(data); - CloseHandle(stream); - goto end; + if (!ReadFile(stream, data, stream_size, &bytesret, nullptr)) { + free(data); + throw last_error(GetLastError()); + } }
- CloseHandle(stream); - } + stream = CreateFileW((destdir + destname + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, nullptr);
- stream = CreateFileW((destdir + destname + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, NULL); + if (stream == INVALID_HANDLE_VALUE) { + if (data) free(data); + throw last_error(GetLastError()); + }
- if (stream == INVALID_HANDLE_VALUE) { - if (data) free(data); - goto end; - } + if (data) { + if (!WriteFile(stream, data, (uint32_t)fsd.StreamSize.QuadPart, &bytesret, nullptr)) { + free(data); + throw last_error(GetLastError()); + }
- if (data) { - if (!WriteFile(stream, data, fsd.StreamSize.QuadPart, &bytesret, NULL)) { free(data); - CloseHandle(stream); - goto end; } - - free(data); } - - CloseHandle(stream); - } - } while (FindNextStreamW(h, &fsd)); - - FindClose(h); + } while (FindNextStreamW(h, &fsd)); + } } - }
- atime.dwLowDateTime = fbi.LastAccessTime.LowPart; - atime.dwHighDateTime = fbi.LastAccessTime.HighPart; - mtime.dwLowDateTime = fbi.LastWriteTime.LowPart; - mtime.dwHighDateTime = fbi.LastWriteTime.HighPart; - SetFileTime(dest, NULL, &atime, &mtime); + atime.dwLowDateTime = fbi.LastAccessTime.LowPart; + atime.dwHighDateTime = fbi.LastAccessTime.HighPart; + mtime.dwLowDateTime = fbi.LastWriteTime.LowPart; + mtime.dwHighDateTime = fbi.LastWriteTime.HighPart; + SetFileTime(dest, nullptr, &atime, &mtime);
- Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_XATTRS, NULL, 0, &bsxa, sizeof(btrfs_set_xattr)); + Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, &bsxa, sizeof(btrfs_set_xattr));
- if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) { - ULONG xalen = 0; - btrfs_set_xattr *xa = NULL, *xa2; - - do { - xalen += 1024; + if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) { + ULONG xalen = 0; + btrfs_set_xattr *xa = nullptr, *xa2;
- if (xa) free(xa); - xa = (btrfs_set_xattr*)malloc(xalen); + do { + xalen += 1024;
- Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_XATTRS, NULL, 0, xa, xalen); - } while (Status == STATUS_BUFFER_OVERFLOW); + if (xa) free(xa); + xa = (btrfs_set_xattr*)malloc(xalen);
- if (!NT_SUCCESS(Status)) { - free(xa); - goto end; - } + Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, xa, xalen); + } while (Status == STATUS_BUFFER_OVERFLOW);
- xa2 = xa; - while (xa2->valuelen > 0) { - Status = NtFsControlFile(dest, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_SET_XATTR, xa2, - offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen, NULL, 0); if (!NT_SUCCESS(Status)) { free(xa); - goto end; + throw ntstatus_error(Status); } - xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen]; - } - - free(xa); - } else if (!NT_SUCCESS(Status)) - goto end;
- ret = TRUE; + xa2 = xa; + while (xa2->valuelen > 0) { + Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, xa2, + offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen, nullptr, 0); + if (!NT_SUCCESS(Status)) { + free(xa); + throw ntstatus_error(Status); + } + xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen]; + }
-end: - if (!ret) { + free(xa); + } else if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } catch (...) { FILE_DISPOSITION_INFO fdi;
- fdi.DeleteFile = TRUE; + fdi.DeleteFile = true; SetFileInformationByHandle(dest, FileDispositionInfo, &fdi, sizeof(FILE_DISPOSITION_INFO)); - }
- CloseHandle(dest); - CloseHandle(source); + throw; + } }
#ifdef __REACTOS__ @@ -1723,39 +1609,36 @@ extern "C" { #endif
void CALLBACK ReflinkCopyW(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 >= 2) { - HANDLE destdirh; - BOOL dest_is_dir = FALSE; - std::wstring dest = args[num_args - 1], destdir, destname; + if (args.size() >= 2) { + bool dest_is_dir = false; + wstring dest = args[args.size() - 1], destdir, destname; WCHAR volpath2[MAX_PATH]; - int i;
- destdirh = CreateFileW(dest.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (destdirh != INVALID_HANDLE_VALUE) { - BY_HANDLE_FILE_INFORMATION bhfi; + { + win_handle destdirh = CreateFileW(dest.c_str(), FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + + if (destdirh != INVALID_HANDLE_VALUE) { + BY_HANDLE_FILE_INFORMATION bhfi;
- if (GetFileInformationByHandle(destdirh, &bhfi) && bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - dest_is_dir = TRUE; + if (GetFileInformationByHandle(destdirh, &bhfi) && bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + dest_is_dir = true;
- destdir = dest; - if (destdir.substr(destdir.length() - 1, 1) != L"\") - destdir += L"\"; + destdir = dest; + if (destdir.substr(destdir.length() - 1, 1) != L"\") + destdir += L"\"; + } } - CloseHandle(destdirh); }
if (!dest_is_dir) { size_t found = dest.rfind(L"\");
- if (found == std::wstring::npos) { + if (found == wstring::npos) { destdir = L""; destname = dest; } else { @@ -1765,19 +1648,18 @@ void CALLBACK ReflinkCopyW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int n }
if (!GetVolumePathNameW(dest.c_str(), volpath2, sizeof(volpath2) / sizeof(WCHAR))) - goto end; + return;
- for (i = 0; i < num_args - 1; i++) { + for (unsigned int i = 0; i < args.size() - 1; i++) { WIN32_FIND_DATAW ffd; - HANDLE h;
- h = FindFirstFileW(args[i], &ffd); + fff_handle h = FindFirstFileW(args[i].c_str(), &ffd); if (h != INVALID_HANDLE_VALUE) { WCHAR volpath1[MAX_PATH]; - std::wstring path = args[i]; + wstring path = args[i]; size_t found = path.rfind(L"\");
- if (found == std::wstring::npos) + if (found == wstring::npos) path = L""; else path = path.substr(0, found); @@ -1787,18 +1669,17 @@ void CALLBACK ReflinkCopyW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int n if (get_volume_path_parent(path.c_str(), volpath1, sizeof(volpath1) / sizeof(WCHAR))) { if (!wcscmp(volpath1, volpath2)) { do { - reflink_copy2(path + ffd.cFileName, destdir, dest_is_dir ? ffd.cFileName : destname); + try { + reflink_copy2(path + ffd.cFileName, destdir, dest_is_dir ? ffd.cFileName : destname); + } catch (const exception& e) { + cerr << "Error: " << e.what() << endl; + } } while (FindNextFileW(h, &ffd)); } } - - FindClose(h); } } } - -end: - LocalFree(args); }
#ifdef __REACTOS__ diff --git a/dll/shellext/shellbtrfs/contextmenu.h b/dll/shellext/shellbtrfs/contextmenu.h index 12779f422b..fe48f9ad85 100644 --- a/dll/shellext/shellbtrfs/contextmenu.h +++ b/dll/shellext/shellbtrfs/contextmenu.h @@ -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(); }; diff --git a/dll/shellext/shellbtrfs/devices.cpp b/dll/shellext/shellbtrfs/devices.cpp index 8feb747e10..f2c297b15f 100644 --- a/dll/shellext/shellbtrfs/devices.cpp +++ b/dll/shellext/shellbtrfs/devices.cpp @@ -27,8 +27,8 @@ #include <setupapi.h> #include <strsafe.h> #include <mountmgr.h> -#include <algorithm> #ifndef __REACTOS__ +#include <algorithm> #include "../btrfs.h" #else #include <ntddstor.h> @@ -39,15 +39,15 @@
DEFINE_GUID(GUID_DEVINTERFACE_HIDDEN_VOLUME, 0x7f108a28L, 0x9833, 0x4b3b, 0xb7, 0x80, 0x2c, 0x6b, 0x5f, 0xa5, 0xc0, 0x62);
-static std::wstring get_mountdev_name(HANDLE h) { +static wstring get_mountdev_name(const nt_handle& h ) { NTSTATUS Status; IO_STATUS_BLOCK iosb; MOUNTDEV_NAME mdn, *mdn2; ULONG mdnsize; - std::wstring name; + wstring name;
- Status = NtDeviceIoControlFile(h, NULL, NULL, NULL, &iosb, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, - NULL, 0, &mdn, sizeof(MOUNTDEV_NAME)); + Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, + nullptr, 0, &mdn, sizeof(MOUNTDEV_NAME)); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) return L"";
@@ -55,26 +55,26 @@ static std::wstring get_mountdev_name(HANDLE h) {
mdn2 = (MOUNTDEV_NAME*)malloc(mdnsize);
- Status = NtDeviceIoControlFile(h, NULL, NULL, NULL, &iosb, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, - NULL, 0, mdn2, mdnsize); + Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, + nullptr, 0, mdn2, mdnsize); if (!NT_SUCCESS(Status)) { free(mdn2); return L""; }
- name = std::wstring(mdn2->Name, mdn2->NameLength / sizeof(WCHAR)); + name = wstring(mdn2->Name, mdn2->NameLength / sizeof(WCHAR));
free(mdn2);
return name; }
-static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vector<device>* device_list) { +static void find_devices(HWND hwnd, const GUID* guid, const nt_handle& mountmgr, vector<device>& device_list) { HDEVINFO h;
static WCHAR dosdevices[] = L"\DosDevices\";
- h = SetupDiGetClassDevs(guid, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + h = SetupDiGetClassDevs(guid, nullptr, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (h != INVALID_HANDLE_VALUE) { DWORD index = 0; @@ -82,7 +82,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect
did.cbSize = sizeof(did);
- if (!SetupDiEnumDeviceInterfaces(h, NULL, guid, index, &did)) + if (!SetupDiEnumDeviceInterfaces(h, nullptr, guid, index, &did)) return;
do { @@ -92,7 +92,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect
dd.cbSize = sizeof(dd);
- SetupDiGetDeviceInterfaceDetailW(h, &did, NULL, 0, &size, NULL); + SetupDiGetDeviceInterfaceDetailW(h, &did, nullptr, 0, &size, nullptr);
detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(size); memset(detail, 0, size); @@ -101,7 +101,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect
if (SetupDiGetDeviceInterfaceDetailW(h, &did, detail, size, &size, &dd)) { NTSTATUS Status; - HANDLE file; + nt_handle file; device dev; STORAGE_DEVICE_NUMBER sdn; IO_STATUS_BLOCK iosb; @@ -109,30 +109,36 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect OBJECT_ATTRIBUTES attr; GET_LENGTH_INFORMATION gli; ULONG i; - UINT8 sb[4096]; + uint8_t sb[4096];
path.Buffer = detail->DevicePath; - path.Length = path.MaximumLength = wcslen(detail->DevicePath) * sizeof(WCHAR); + path.Length = path.MaximumLength = (uint16_t)(wcslen(detail->DevicePath) * sizeof(WCHAR));
if (path.Length > 4 * sizeof(WCHAR) && path.Buffer[0] == '\' && path.Buffer[1] == '\' && path.Buffer[2] == '?' && path.Buffer[3] == '\') path.Buffer[1] = '?';
- InitializeObjectAttributes(&attr, &path, 0, NULL, NULL); + InitializeObjectAttributes(&attr, &path, 0, nullptr, nullptr);
Status = NtOpenFile(&file, FILE_GENERIC_READ, &attr, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_ALERT);
- if (!NT_SUCCESS(Status)) - goto nextitem2; + if (!NT_SUCCESS(Status)) { + free(detail); + index++; + continue; + }
dev.pnp_name = detail->DevicePath;
- Status = NtDeviceIoControlFile(file, NULL, NULL, NULL, &iosb, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(GET_LENGTH_INFORMATION)); - if (!NT_SUCCESS(Status)) - goto nextitem; + Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &gli, sizeof(GET_LENGTH_INFORMATION)); + if (!NT_SUCCESS(Status)) { + free(detail); + index++; + continue; + }
dev.size = gli.Length.QuadPart;
- Status = NtDeviceIoControlFile(file, NULL, NULL, NULL, &iosb, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER)); + Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_STORAGE_GET_DEVICE_NUMBER, nullptr, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER)); if (!NT_SUCCESS(Status)) { dev.disk_num = 0xffffffff; dev.part_num = 0xffffffff; @@ -144,9 +150,9 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect dev.friendly_name = L""; dev.drive = L""; dev.fstype = L""; - dev.has_parts = FALSE; - dev.ignore = FALSE; - dev.multi_device = FALSE; + dev.has_parts = false; + dev.ignore = false; + dev.multi_device = false;
dev.is_disk = RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) == sizeof(GUID);
@@ -160,21 +166,21 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect spq.QueryType = PropertyStandardQuery; spq.AdditionalParameters[0] = 0;
- Status = NtDeviceIoControlFile(file, NULL, NULL, NULL, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, + Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(STORAGE_PROPERTY_QUERY), &sdd, sizeof(STORAGE_DEVICE_DESCRIPTOR));
if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) { sdd2 = (STORAGE_DEVICE_DESCRIPTOR*)malloc(sdd.Size);
- Status = NtDeviceIoControlFile(file, NULL, NULL, NULL, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, - &spq, sizeof(STORAGE_PROPERTY_QUERY), sdd2, sdd.Size); + Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, + &spq, sizeof(STORAGE_PROPERTY_QUERY), sdd2, sdd.Size); if (NT_SUCCESS(Status)) { - std::string desc2; + string desc2;
desc2 = "";
if (sdd2->VendorIdOffset != 0) { - desc2 += (char*)((UINT8*)sdd2 + sdd2->VendorIdOffset); + desc2 += (char*)((uint8_t*)sdd2 + sdd2->VendorIdOffset);
while (desc2.length() > 0 && desc2[desc2.length() - 1] == ' ') desc2 = desc2.substr(0, desc2.length() - 1); @@ -184,7 +190,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect if (sdd2->VendorIdOffset != 0 && desc2.length() != 0 && desc2[desc2.length() - 1] != ' ') desc2 += " ";
- desc2 += (char*)((UINT8*)sdd2 + sdd2->ProductIdOffset); + desc2 += (char*)((uint8_t*)sdd2 + sdd2->ProductIdOffset);
while (desc2.length() > 0 && desc2[desc2.length() - 1] == ' ') desc2 = desc2.substr(0, desc2.length() - 1); @@ -193,7 +199,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect if (sdd2->VendorIdOffset != 0 || sdd2->ProductIdOffset != 0) { ULONG ss;
- ss = MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, desc2.c_str(), -1, NULL, 0); + ss = MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, desc2.c_str(), -1, nullptr, 0);
if (ss > 0) { WCHAR* desc3 = (WCHAR*)malloc(ss * sizeof(WCHAR)); @@ -210,7 +216,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect }
dlisize = 0; - dli = NULL; + dli = nullptr;
do { dlisize += 1024; @@ -220,12 +226,12 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect
dli = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(dlisize);
- Status = NtDeviceIoControlFile(file, NULL, NULL, NULL, &iosb, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, - NULL, 0, dli, dlisize); + Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, + nullptr, 0, dli, dlisize); } while (Status == STATUS_BUFFER_TOO_SMALL);
if (NT_SUCCESS(Status) && dli->PartitionCount > 0) - dev.has_parts = TRUE; + dev.has_parts = true;
free(dli); } else { @@ -242,21 +248,21 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect mmp->DeviceNameLength = path.Length; RtlCopyMemory(&mmp[1], path.Buffer, path.Length);
- Status = NtDeviceIoControlFile(mountmgr, NULL, NULL, NULL, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS, + Status = NtDeviceIoControlFile(mountmgr, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS, mmp, mmpsize, &mmps, sizeof(MOUNTMGR_MOUNT_POINTS)); if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) { MOUNTMGR_MOUNT_POINTS* mmps2;
mmps2 = (MOUNTMGR_MOUNT_POINTS*)malloc(mmps.Size);
- Status = NtDeviceIoControlFile(mountmgr, NULL, NULL, NULL, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS, + Status = NtDeviceIoControlFile(mountmgr, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS, mmp, mmpsize, mmps2, mmps.Size);
if (NT_SUCCESS(Status)) { ULONG i;
for (i = 0; i < mmps2->NumberOfMountPoints; i++) { - WCHAR* symlink = (WCHAR*)((UINT8*)mmps2 + mmps2->MountPoints[i].SymbolicLinkNameOffset); + WCHAR* symlink = (WCHAR*)((uint8_t*)mmps2 + mmps2->MountPoints[i].SymbolicLinkNameOffset);
if (mmps2->MountPoints[i].SymbolicLinkNameLength == 0x1c && RtlCompareMemory(symlink, dosdevices, wcslen(dosdevices) * sizeof(WCHAR)) == wcslen(dosdevices) * sizeof(WCHAR) && @@ -285,7 +291,7 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect LARGE_INTEGER off;
off.QuadPart = fs_ident[i].kboff * 1024; - Status = NtReadFile(file, NULL, NULL, NULL, &iosb, sb, sizeof(sb), &off, NULL); + Status = NtReadFile(file, nullptr, nullptr, nullptr, &iosb, sb, sizeof(sb), &off, nullptr); }
if (NT_SUCCESS(Status)) { @@ -307,35 +313,30 @@ static void find_devices(HWND hwnd, const GUID* guid, HANDLE mountmgr, std::vect }
if (dev.fstype == L"Btrfs" && RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) != sizeof(GUID)) { - std::wstring name; - std::wstring pref = L"\Device\Btrfs{"; + wstring name; + wstring pref = L"\Device\Btrfs{";
name = get_mountdev_name(file);
if (name.length() > pref.length() && RtlCompareMemory(name.c_str(), pref.c_str(), pref.length() * sizeof(WCHAR)) == pref.length() * sizeof(WCHAR)) - dev.ignore = TRUE; + dev.ignore = true; } }
- device_list->push_back(dev); - -nextitem: - NtClose(file); + device_list.push_back(dev); }
-nextitem2: free(detail);
index++; - } while (SetupDiEnumDeviceInterfaces(h, NULL, guid, index, &did)); + } while (SetupDiEnumDeviceInterfaces(h, nullptr, guid, index, &did));
SetupDiDestroyDeviceInfoList(h); - } else { - ShowError(hwnd, GetLastError()); - return; - } + } else + throw last_error(GetLastError()); }
+#ifndef __REACTOS__ // Disabled because building with our <algorithm> seems complex right now... static bool sort_devices(device i, device j) { if (i.disk_num < j.disk_num) return true; @@ -345,6 +346,7 @@ static bool sort_devices(device i, device j) {
return false; } +#endif
void BtrfsDeviceAdd::populate_device_tree(HWND tree) { HWND hwnd = GetParent(tree); @@ -355,68 +357,72 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { OBJECT_ATTRIBUTES attr; UNICODE_STRING us; IO_STATUS_BLOCK iosb; - HANDLE mountmgr, btrfsh; - btrfs_filesystem* bfs = NULL; + btrfs_filesystem* bfs = nullptr;
static WCHAR btrfs[] = L"\Btrfs";
device_list.clear();
- RtlInitUnicodeString(&us, MOUNTMGR_DEVICE_NAME); - InitializeObjectAttributes(&attr, &us, 0, NULL, NULL); + { + nt_handle mountmgr;
- Status = NtOpenFile(&mountmgr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, - FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT); - if (!NT_SUCCESS(Status)) { - MessageBoxW(hwnd, L"Could not get handle to mount manager.", L"Error", MB_ICONERROR); - return; - } + RtlInitUnicodeString(&us, MOUNTMGR_DEVICE_NAME); + InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr);
- us.Length = us.MaximumLength = wcslen(btrfs) * sizeof(WCHAR); - us.Buffer = btrfs; + Status = NtOpenFile(&mountmgr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, + FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT);
- InitializeObjectAttributes(&attr, &us, 0, NULL, NULL); + if (!NT_SUCCESS(Status)) + throw string_error(IDS_CANT_OPEN_MOUNTMGR);
- Status = NtOpenFile(&btrfsh, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &iosb, - FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); - if (NT_SUCCESS(Status)) { - ULONG bfssize = 0; + { + nt_handle btrfsh;
- do { - bfssize += 1024; + us.Length = us.MaximumLength = (uint16_t)(wcslen(btrfs) * sizeof(WCHAR)); + us.Buffer = btrfs;
- if (bfs) free(bfs); - bfs = (btrfs_filesystem*)malloc(bfssize); + InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr);
- Status = NtDeviceIoControlFile(btrfsh, NULL, NULL, NULL, &iosb, IOCTL_BTRFS_QUERY_FILESYSTEMS, NULL, 0, bfs, bfssize); - if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { - free(bfs); - bfs = NULL; - break; - } - } while (Status == STATUS_BUFFER_OVERFLOW); + Status = NtOpenFile(&btrfsh, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &iosb, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); + if (NT_SUCCESS(Status)) { + ULONG bfssize = 0;
- if (bfs && bfs->num_devices == 0) { // no mounted filesystems found - free(bfs); - bfs = NULL; - } - } - NtClose(btrfsh); + do { + bfssize += 1024;
- find_devices(hwnd, &GUID_DEVINTERFACE_DISK, mountmgr, &device_list); - find_devices(hwnd, &GUID_DEVINTERFACE_VOLUME, mountmgr, &device_list); - find_devices(hwnd, &GUID_DEVINTERFACE_HIDDEN_VOLUME, mountmgr, &device_list); + if (bfs) free(bfs); + bfs = (btrfs_filesystem*)malloc(bfssize);
- NtClose(mountmgr); + Status = NtDeviceIoControlFile(btrfsh, nullptr, nullptr, nullptr, &iosb, IOCTL_BTRFS_QUERY_FILESYSTEMS, nullptr, 0, bfs, bfssize); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { + free(bfs); + bfs = nullptr; + break; + } + } while (Status == STATUS_BUFFER_OVERFLOW);
- std::sort(device_list.begin(), device_list.end(), sort_devices); + if (bfs && bfs->num_devices == 0) { // no mounted filesystems found + free(bfs); + bfs = nullptr; + } + } + } + + find_devices(hwnd, &GUID_DEVINTERFACE_DISK, mountmgr, device_list); + find_devices(hwnd, &GUID_DEVINTERFACE_VOLUME, mountmgr, device_list); + find_devices(hwnd, &GUID_DEVINTERFACE_HIDDEN_VOLUME, mountmgr, device_list); + } + +#ifndef __REACTOS__ // Disabled because building with our <algorithm> seems complex right now... + sort(device_list.begin(), device_list.end(), sort_devices); +#endif
for (i = 0; i < device_list.size(); i++) { if (!device_list[i].ignore) { TVINSERTSTRUCTW tis; HTREEITEM item; - std::wstring name; - WCHAR size[255]; + wstring name, size;
if (device_list[i].disk_num != 0xffffffff && device_list[i].disk_num == last_disk_num) tis.hParent = diskitem; @@ -429,17 +435,12 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { tis.itemex.stateMask = TVIS_EXPANDED;
if (device_list[i].disk_num != 0xffffffff) { - WCHAR t[255], u[255]; + wstring t;
- if (!LoadStringW(module, device_list[i].part_num != 0 ? IDS_PARTITION : IDS_DISK_NUM, t, sizeof(t) / sizeof(WCHAR))) { - ShowError(hwnd, GetLastError()); - return; - } + if (!load_string(module, device_list[i].part_num != 0 ? IDS_PARTITION : IDS_DISK_NUM, t)) + throw last_error(GetLastError());
- if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, device_list[i].part_num != 0 ? device_list[i].part_num : device_list[i].disk_num) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; - - name = u; + wstring_sprintf(name, t, device_list[i].part_num != 0 ? device_list[i].part_num : device_list[i].disk_num); } else name = device_list[i].pnp_name;
@@ -447,7 +448,7 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { if (bfs && device_list[i].drive == L"" && device_list[i].fstype == L"Btrfs") { btrfs_filesystem* bfs2 = bfs;
- while (TRUE) { + while (true) { if (RtlCompareMemory(&bfs2->uuid, &device_list[i].fs_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { ULONG j, k; btrfs_filesystem_device* dev; @@ -456,7 +457,7 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { if (j == 0) dev = &bfs2->device; else - dev = (btrfs_filesystem_device*)((UINT8*)dev + offsetof(btrfs_filesystem_device, name[0]) + dev->name_length); + dev = (btrfs_filesystem_device*)((uint8_t*)dev + offsetof(btrfs_filesystem_device, name[0]) + dev->name_length);
if (RtlCompareMemory(&device_list[i].dev_uuid, &device_list[i].dev_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { for (k = 0; k < device_list.size(); k++) { @@ -477,7 +478,7 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { }
if (bfs2->next_entry != 0) - bfs2 = (btrfs_filesystem*)((UINT8*)bfs2 + bfs2->next_entry); + bfs2 = (btrfs_filesystem*)((uint8_t*)bfs2 + bfs2->next_entry); else break; } @@ -500,7 +501,7 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { name += L", "; }
- format_size(device_list[i].size, size, sizeof(size) / sizeof(WCHAR), FALSE); + format_size(device_list[i].size, size, false); name += size;
name += L")"; @@ -510,10 +511,8 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { tis.itemex.lParam = (LPARAM)&device_list[i];
item = (HTREEITEM)SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&tis); - if (!item) { - MessageBoxW(hwnd, L"TVM_INSERTITEM failed", L"Error", MB_ICONERROR); - return; - } + if (!item) + throw string_error(IDS_TVM_INSERTITEM_FAILED);
if (device_list[i].part_num == 0) { diskitem = item; @@ -524,12 +523,11 @@ void BtrfsDeviceAdd::populate_device_tree(HWND tree) { }
void BtrfsDeviceAdd::AddDevice(HWND hwndDlg) { - WCHAR mess[255], title[255]; + wstring mess, title; NTSTATUS Status; UNICODE_STRING vn; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK iosb; - HANDLE h, h2;
if (!sel) { EndDialog(hwndDlg, 0); @@ -537,154 +535,123 @@ void BtrfsDeviceAdd::AddDevice(HWND hwndDlg) { }
if (sel->fstype != L"") { - WCHAR s[255]; + wstring s;
- if (!LoadStringW(module, IDS_ADD_DEVICE_CONFIRMATION_FS, s, sizeof(s) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (!load_string(module, IDS_ADD_DEVICE_CONFIRMATION_FS, s)) + throw last_error(GetLastError());
- if (StringCchPrintfW(mess, sizeof(mess) / sizeof(WCHAR), s, sel->fstype.c_str()) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; + wstring_sprintf(mess, s, sel->fstype.c_str()); } else { - if (!LoadStringW(module, IDS_ADD_DEVICE_CONFIRMATION, mess, sizeof(mess) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } - } - - if (!LoadStringW(module, IDS_CONFIRMATION_TITLE, title, sizeof(title) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; + if (!load_string(module, IDS_ADD_DEVICE_CONFIRMATION, mess)) + throw last_error(GetLastError()); }
- if (MessageBoxW(hwndDlg, mess, title, MB_YESNO) != IDYES) - return; - - h = CreateFileW(cmdline, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); + if (!load_string(module, IDS_CONFIRMATION_TITLE, title)) + throw last_error(GetLastError());
- if (h == INVALID_HANDLE_VALUE) { - ShowError(hwndDlg, GetLastError()); + if (MessageBoxW(hwndDlg, mess.c_str(), title.c_str(), MB_YESNO) != IDYES) return; - }
- vn.Length = vn.MaximumLength = sel->pnp_name.length() * sizeof(WCHAR); - vn.Buffer = (WCHAR*)sel->pnp_name.c_str(); + win_handle h = CreateFileW(cmdline, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
- InitializeObjectAttributes(&attr, &vn, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); + if (h == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- Status = NtOpenFile(&h2, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT); - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwndDlg, Status); - CloseHandle(h); - return; - } + { + nt_handle h2;
- if (!sel->is_disk) { - Status = NtFsControlFile(h2, NULL, NULL, NULL, &iosb, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0); - if (!NT_SUCCESS(Status)) { - WCHAR t[255], u[255]; - - if (!LoadStringW(module, IDS_LOCK_FAILED, t, sizeof(t) / sizeof(WCHAR))) { - ShowError(hwnd, GetLastError()); - return; - } + vn.Length = vn.MaximumLength = (uint16_t)(sel->pnp_name.length() * sizeof(WCHAR)); + vn.Buffer = (WCHAR*)sel->pnp_name.c_str();
- if (StringCchPrintfW(u, sizeof(u) / sizeof(WCHAR), t, Status) == STRSAFE_E_INSUFFICIENT_BUFFER) - return; - - if (!LoadStringW(module, IDS_ERROR, title, sizeof(title) / sizeof(WCHAR))) { - ShowError(hwndDlg, GetLastError()); - return; - } + InitializeObjectAttributes(&attr, &vn, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, nullptr, nullptr);
- MessageBoxW(hwndDlg, u, title, MB_ICONERROR); + Status = NtOpenFile(&h2, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
- NtClose(h2); - CloseHandle(h); - return; + if (!sel->is_disk) { + Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0); + if (!NT_SUCCESS(Status)) + throw string_error(IDS_LOCK_FAILED, Status); } - } - - Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_ADD_DEVICE, &h2, sizeof(HANDLE), NULL, 0); - if (!NT_SUCCESS(Status)) { - ShowNtStatusError(hwndDlg, Status); - NtClose(h2); - CloseHandle(h); - return; - }
- if (!sel->is_disk) { - Status = NtFsControlFile(h2, NULL, NULL, NULL, &iosb, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0); + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_ADD_DEVICE, &h2, sizeof(HANDLE), nullptr, 0); if (!NT_SUCCESS(Status)) - ShowNtStatusError(hwndDlg, Status); + throw ntstatus_error(Status);
- Status = NtFsControlFile(h2, NULL, NULL, NULL, &iosb, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0); - if (!NT_SUCCESS(Status)) - ShowNtStatusError(hwndDlg, Status); - } + if (!sel->is_disk) { + Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status);
- NtClose(h2); - CloseHandle(h); + Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_UNLOCK_VOLUME, nullptr, 0, nullptr, 0); + if (!NT_SUCCESS(Status)) + throw ntstatus_error(Status); + } + }
EndDialog(hwndDlg, 0); }
INT_PTR CALLBACK BtrfsDeviceAdd::DeviceAddDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_INITDIALOG: - { - EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB); - populate_device_tree(GetDlgItem(hwndDlg, IDC_DEVICE_TREE)); - EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); - break; - } - - case WM_COMMAND: - switch (HIWORD(wParam)) { - case BN_CLICKED: - switch (LOWORD(wParam)) { - case IDOK: - AddDevice(hwndDlg); - return TRUE; - - case IDCANCEL: - EndDialog(hwndDlg, 0); - return TRUE; - } + try { + switch (uMsg) { + case WM_INITDIALOG: + { + EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB); + populate_device_tree(GetDlgItem(hwndDlg, IDC_DEVICE_TREE)); + EnableWindow(GetDlgItem(hwndDlg, IDOK), false); break; } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case TVN_SELCHANGEDW: - { - NMTREEVIEWW* nmtv = (NMTREEVIEWW*)lParam; - TVITEMW tvi; - BOOL enable = FALSE; - - RtlZeroMemory(&tvi, sizeof(TVITEMW)); - tvi.hItem = nmtv->itemNew.hItem; - tvi.mask = TVIF_PARAM | TVIF_HANDLE; - - if (SendMessageW(GetDlgItem(hwndDlg, IDC_DEVICE_TREE), TVM_GETITEMW, 0, (LPARAM)&tvi)) - sel = tvi.lParam == 0 ? NULL : (device*)tvi.lParam; - else - sel = NULL; - - if (sel) - enable = (!sel->is_disk || !sel->has_parts) && !sel->multi_device;
- EnableWindow(GetDlgItem(hwndDlg, IDOK), enable); + case WM_COMMAND: + switch (HIWORD(wParam)) { + case BN_CLICKED: + switch (LOWORD(wParam)) { + case IDOK: + AddDevice(hwndDlg); + return true; + + case IDCANCEL: + EndDialog(hwndDlg, 0); + return true; + } break; } - } - break; + break; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->code) { + case TVN_SELCHANGEDW: + { + NMTREEVIEWW* nmtv = (NMTREEVIEWW*)lParam; + TVITEMW tvi; + bool enable = false; + + RtlZeroMemory(&tvi, sizeof(TVITEMW)); + tvi.hItem = nmtv->itemNew.hItem; + tvi.mask = TVIF_PARAM | TVIF_HANDLE; + + if (SendMessageW(GetDlgItem(hwndDlg, IDC_DEVICE_TREE), TVM_GETITEMW, 0, (LPARAM)&tvi)) + sel = tvi.lParam == 0 ? nullptr : (device*)tvi.lParam; + else + sel = nullptr; + + if (sel) + enable = (!sel->is_disk || !sel->has_parts) && !sel->multi_device; + + EnableWindow(GetDlgItem(hwndDlg, IDOK), enable); + break; + } + } + break; + } + } catch (const exception& e) { + error_message(hwndDlg, e.what()); }
- return FALSE; + return false; }
static INT_PTR CALLBACK stub_DeviceAddDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -700,7 +667,7 @@ static INT_PTR CALLBACK stub_DeviceAddDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wP if (bda) return bda->DeviceAddDlgProc(hwndDlg, uMsg, wParam, lParam); else - return FALSE; + return false; }
void BtrfsDeviceAdd::ShowDialog() { @@ -712,182 +679,174 @@ BtrfsDeviceAdd::BtrfsDeviceAdd(HINSTANCE hinst, HWND hwnd, WCHAR* cmdline) { this->hwnd = hwnd; this->cmdline = cmdline;
- sel = NULL; + sel = nullptr; }
void BtrfsDeviceResize::do_resize(HWND hwndDlg) { - HANDLE h; NTSTATUS Status; IO_STATUS_BLOCK iosb; btrfs_resize br;
- h = CreateFileW(fn, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, 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_READ_ATTRIBUTES, 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) { - ShowError(hwndDlg, GetLastError()); - return; - } + if (h == INVALID_HANDLE_VALUE) + throw last_error(GetLastError());
- br.device = dev_id; - br.size = new_size; + br.device = dev_id; + br.size = new_size;
- Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_RESIZE, &br, sizeof(btrfs_resize), NULL, 0); + Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_RESIZE, &br, sizeof(btrfs_resize), nullptr, 0);
- if (Status != STATUS_MORE_PROCESSING_REQUIRED && !NT_SUCCESS(Status)) { - ShowNtStatusError(hwndDlg, Status); - CloseHandle(h); - return; + if (Status != STATUS_MORE_PROCESSING_REQUIRED && !NT_SUCCESS(Status)) + throw ntstatus_error(Status); }
- CloseHandle(h); - if (Status != STATUS_MORE_PROCESSING_REQUIRED) { - WCHAR s[255], t[255], u[255]; + wstring s, t, u;
- LoadStringW(module, IDS_RESIZE_SUCCESSFUL, s, sizeof(s) / sizeof(WCHAR)); - format_size(new_size, u, sizeof(u) / sizeof(WCHAR), TRUE); - StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), s, dev_id, u); - MessageBoxW(hwndDlg, t, L"", MB_OK); + load_string(module, IDS_RESIZE_SUCCESSFUL, s); + format_size(new_size, u, true); + wstring_sprintf(t, s, dev_id, u.c_str()); + MessageBoxW(hwndDlg, t.c_str(), L"", MB_OK);
EndDialog(hwndDlg, 0); } else { - BtrfsBalance* bb; HWND par;
par = GetParent(hwndDlg); EndDialog(hwndDlg, 0);
- bb = new BtrfsBalance(fn, FALSE, TRUE); - - bb->ShowBalance(par); - - delete bb; + BtrfsBalance bb(fn, false, true); + bb.ShowBalance(par); } }
INT_PTR CALLBACK BtrfsDeviceResize::DeviceResizeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_INITDIALOG: - { - HANDLE h; - WCHAR s[255], t[255], u[255]; - - EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB); - - GetDlgItemTextW(hwndDlg, IDC_RESIZE_DEVICE_ID, s, sizeof(s) / sizeof(WCHAR)); - StringCchPrintfW(t, sizeof(t) / sizeof(WCHAR), s, dev_id); - SetDlgItemTextW(hwndDlg, IDC_RESIZE_DEVICE_ID, t); - - h = CreateFileW(fn, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, 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; - btrfs_device *devices, *bd; - ULONG devsize; - BOOL found = FALSE; - HWND slider; - - devsize = 1024; ... 11587 lines suppressed ...