ReactOS 0.4.15-dev-8241-g63935f8
main.cpp
Go to the documentation of this file.
1/* Copyright (c) Mark Harmstone 2016-17
2 *
3 * This file is part of WinBtrfs.
4 *
5 * WinBtrfs is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public Licence as published by
7 * the Free Software Foundation, either version 3 of the Licence, or
8 * (at your option) any later version.
9 *
10 * WinBtrfs is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public Licence for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public Licence
16 * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17
18#include "shellext.h"
19#include <windows.h>
20#include <commctrl.h>
21#include <strsafe.h>
22#include <stddef.h>
23#include <stdexcept>
24#include "factory.h"
25#include "resource.h"
26
27static const GUID CLSID_ShellBtrfsIconHandler = { 0x2690b74f, 0xf353, 0x422d, { 0xbb, 0x12, 0x40, 0x15, 0x81, 0xee, 0xf8, 0xf0 } };
28static const GUID CLSID_ShellBtrfsContextMenu = { 0x2690b74f, 0xf353, 0x422d, { 0xbb, 0x12, 0x40, 0x15, 0x81, 0xee, 0xf8, 0xf1 } };
29static const GUID CLSID_ShellBtrfsPropSheet = { 0x2690b74f, 0xf353, 0x422d, { 0xbb, 0x12, 0x40, 0x15, 0x81, 0xee, 0xf8, 0xf2 } };
30static const GUID CLSID_ShellBtrfsVolPropSheet = { 0x2690b74f, 0xf353, 0x422d, { 0xbb, 0x12, 0x40, 0x15, 0x81, 0xee, 0xf8, 0xf3 } };
31
32#define COM_DESCRIPTION_ICON_HANDLER L"WinBtrfs shell extension (icon handler)"
33#define COM_DESCRIPTION_CONTEXT_MENU L"WinBtrfs shell extension (context menu)"
34#define COM_DESCRIPTION_PROP_SHEET L"WinBtrfs shell extension (property sheet)"
35#define COM_DESCRIPTION_VOL_PROP_SHEET L"WinBtrfs shell extension (volume property sheet)"
36#define ICON_OVERLAY_NAME L"WinBtrfs"
37
43
46
49
51 _SetProcessDpiAwareness SetProcessDpiAwareness;
52 HMODULE shcore = LoadLibraryW(L"shcore.dll");
53
54 if (!shcore)
55 return;
56
57 SetProcessDpiAwareness = (_SetProcessDpiAwareness)GetProcAddress(shcore, "SetProcessDpiAwareness");
58
59 if (!SetProcessDpiAwareness)
60 return;
61
62 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
63}
64
65void format_size(uint64_t size, wstring& s, bool show_bytes) {
66 wstring t, bytes, kb, nb;
67 WCHAR nb2[255];
68 ULONG sr;
69 float f;
71 WCHAR dec[2], thou[4], grouping[64], *c;
72#ifdef __REACTOS__
73 WCHAR buffer[64];
74#endif
75
76#ifndef __REACTOS__
77 nb = to_wstring(size);
78#else
79 swprintf(buffer, L"%I64d", size);
80 nb = wstring(buffer);
81#endif
82
83 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thou, sizeof(thou) / sizeof(WCHAR));
84
85 dec[0] = '.'; dec[1] = 0; // not used, but silences gcc warning
86
87 fmt.NumDigits = 0;
88 fmt.LeadingZero = 1;
89 fmt.lpDecimalSep = dec;
90 fmt.lpThousandSep = thou;
91 fmt.NegativeOrder = 0;
92
93 // Grouping code copied from dlls/shlwapi/string.c in Wine - thank you
94
95 fmt.Grouping = 0;
96 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, grouping, sizeof(grouping) / sizeof(WCHAR));
97
98 c = grouping;
99 while (*c) {
100 if (*c >= '0' && *c < '9') {
101 fmt.Grouping *= 10;
102 fmt.Grouping += *c - '0';
103 }
104
105 c++;
106 }
107
108 if (fmt.Grouping % 10 == 0)
109 fmt.Grouping /= 10;
110 else
111 fmt.Grouping *= 10;
112
113 GetNumberFormatW(LOCALE_USER_DEFAULT, 0, nb.c_str(), &fmt, nb2, sizeof(nb2) / sizeof(WCHAR));
114
115 if (size < 1024) {
117 throw last_error(GetLastError());
118
119 wstring_sprintf(s, t, nb2);
120 return;
121 }
122
123 if (show_bytes) {
125 throw last_error(GetLastError());
126
127 wstring_sprintf(bytes, t, nb2);
128 }
129
130 if (size >= 1152921504606846976) {
131 sr = IDS_SIZE_EB;
132 f = (float)size / 1152921504606846976.0f;
133 } else if (size >= 1125899906842624) {
134 sr = IDS_SIZE_PB;
135 f = (float)size / 1125899906842624.0f;
136 } else if (size >= 1099511627776) {
137 sr = IDS_SIZE_TB;
138 f = (float)size / 1099511627776.0f;
139 } else if (size >= 1073741824) {
140 sr = IDS_SIZE_GB;
141 f = (float)size / 1073741824.0f;
142 } else if (size >= 1048576) {
143 sr = IDS_SIZE_MB;
144 f = (float)size / 1048576.0f;
145 } else {
146 sr = IDS_SIZE_KB;
147 f = (float)size / 1024.0f;
148 }
149
150 if (!load_string(module, sr, t))
151 throw last_error(GetLastError());
152
153 if (show_bytes) {
154 wstring_sprintf(kb, t, f);
155
157 throw last_error(GetLastError());
158
159 wstring_sprintf(s, t, kb.c_str(), bytes.c_str());
160 } else
161 wstring_sprintf(s, t, f);
162}
163
165 WCHAR* buf;
166 wstring s;
167
169 last_error, 0, (WCHAR*)&buf, 0, nullptr) == 0) {
170 return L"(error retrieving message)";
171 }
172
173 s = buf;
174
175 LocalFree(buf);
176
177 // remove trailing newline
178 while (s.length() > 0 && (s.substr(s.length() - 1, 1) == L"\r" || s.substr(s.length() - 1, 1) == L"\n"))
179 s = s.substr(0, s.length() - 1);
180
181 return s;
182}
183
186 wstring s;
187 HMODULE ntdll = LoadLibraryW(L"ntdll.dll");
188
189 if (!ntdll)
190 return L"(error loading ntdll.dll)";
191
192 RtlNtStatusToDosError = (_RtlNtStatusToDosError)GetProcAddress(ntdll, "RtlNtStatusToDosError");
193
195 FreeLibrary(ntdll);
196 return L"(error loading RtlNtStatusToDosError)";
197 }
198
200
201 FreeLibrary(ntdll);
202
203 return s;
204}
205
206bool load_string(HMODULE module, UINT id, wstring& s) {
207 int len;
208 LPWSTR retstr = nullptr;
209
210 len = LoadStringW(module, id, (LPWSTR)&retstr, 0);
211
212 if (len == 0)
213 return false;
214
215 s = wstring(retstr, len);
216
217 return true;
218}
219
220#ifdef _MSC_VER
221#pragma warning(push)
222#pragma warning(disable: 4996)
223#endif
224
225void wstring_sprintf(wstring& s, wstring fmt, ...) {
226 int len;
228
229 va_start(args, fmt);
230 len = _vsnwprintf(nullptr, 0, fmt.c_str(), args);
231
232 if (len == 0)
233 s = L"";
234 else {
235 s.resize(len);
236 _vsnwprintf((wchar_t*)s.c_str(), len, fmt.c_str(), args);
237 }
238
239 va_end(args);
240}
241
242#ifdef _MSC_VER
243#pragma warning(pop)
244#endif
245
247 return objs_loaded == 0 ? S_OK : S_FALSE;
248}
249
251 if (rclsid == CLSID_ShellBtrfsIconHandler) {
252 Factory* fact = new Factory;
253 if (!fact)
254 return E_OUTOFMEMORY;
255 else {
256 fact->type = FactoryIconHandler;
257
258 return fact->QueryInterface(riid, ppv);
259 }
260 } else if (rclsid == CLSID_ShellBtrfsContextMenu) {
261 Factory* fact = new Factory;
262 if (!fact)
263 return E_OUTOFMEMORY;
264 else {
265 fact->type = FactoryContextMenu;
266
267 return fact->QueryInterface(riid, ppv);
268 }
269 } else if (rclsid == CLSID_ShellBtrfsPropSheet) {
270 Factory* fact = new Factory;
271 if (!fact)
272 return E_OUTOFMEMORY;
273 else {
274 fact->type = FactoryPropSheet;
275
276 return fact->QueryInterface(riid, ppv);
277 }
278 } else if (rclsid == CLSID_ShellBtrfsVolPropSheet) {
279 Factory* fact = new Factory;
280 if (!fact)
281 return E_OUTOFMEMORY;
282 else {
284
285 return fact->QueryInterface(riid, ppv);
286 }
287 }
288
290}
291
292static void write_reg_key(HKEY root, const wstring& keyname, const WCHAR* val, const wstring& data) {
293 LONG l;
294 HKEY hk;
296
297 l = RegCreateKeyExW(root, keyname.c_str(), 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &hk, &dispos);
298 if (l != ERROR_SUCCESS)
300
301 l = RegSetValueExW(hk, val, 0, REG_SZ, (const BYTE*)data.c_str(), (DWORD)((data.length() + 1) * sizeof(WCHAR)));
302 if (l != ERROR_SUCCESS)
304
305 l = RegCloseKey(hk);
306 if (l != ERROR_SUCCESS)
308}
309
310static void register_clsid(const GUID clsid, const WCHAR* description) {
311 WCHAR* clsidstring;
312 wstring inproc, clsidkeyname;
314
315 StringFromCLSID(clsid, &clsidstring);
316
317 try {
318#ifndef __REACTOS__
319 inproc = L"CLSID\\"s + clsidstring + L"\\InprocServer32"s;
320 clsidkeyname = L"CLSID\\"s + clsidstring;
321#else
322 inproc = wstring(L"CLSID\\") + clsidstring + wstring(L"\\InprocServer32");
323 clsidkeyname = wstring(L"CLSID\\") + clsidstring;
324#endif
325
326 write_reg_key(HKEY_CLASSES_ROOT, clsidkeyname, nullptr, description);
327
328 GetModuleFileNameW(module, dllpath, sizeof(dllpath) / sizeof(WCHAR));
329
330 write_reg_key(HKEY_CLASSES_ROOT, inproc, nullptr, dllpath);
331
332 write_reg_key(HKEY_CLASSES_ROOT, inproc, L"ThreadingModel", L"Apartment");
333 } catch (...) {
334 CoTaskMemFree(clsidstring);
335 throw;
336 }
337
338 CoTaskMemFree(clsidstring);
339}
340
341// implementation of RegDeleteTreeW, only available from Vista on
342static void reg_delete_tree(HKEY hkey, const wstring& keyname) {
343 HKEY k;
344 LSTATUS ret;
345
346 ret = RegOpenKeyExW(hkey, keyname.c_str(), 0, KEY_READ, &k);
347
348 if (ret != ERROR_SUCCESS)
349 throw last_error(ret);
350
351 try {
352 WCHAR* buf;
354
355 ret = RegQueryInfoKeyW(k, nullptr, nullptr, nullptr, nullptr, &bufsize, nullptr,
356 nullptr, nullptr, nullptr, nullptr, nullptr);
357 if (ret != ERROR_SUCCESS)
358 throw last_error(ret);
359
360 bufsize++;
361 buf = new WCHAR[bufsize];
362
363 try {
364 do {
366
367 ret = RegEnumKeyExW(k, 0, buf, &size, nullptr, nullptr, nullptr, nullptr);
368
370 break;
371 else if (ret != ERROR_SUCCESS)
372 throw last_error(ret);
373
375 } while (true);
376
377 ret = RegDeleteKeyW(hkey, keyname.c_str());
378 if (ret != ERROR_SUCCESS)
379 throw last_error(ret);
380 } catch (...) {
381 delete[] buf;
382 throw;
383 }
384
385 delete[] buf;
386 } catch (...) {
387 RegCloseKey(k);
388 throw;
389 }
390
391 RegCloseKey(k);
392}
393
394static void unregister_clsid(const GUID clsid) {
395 WCHAR* clsidstring;
396
397 StringFromCLSID(clsid, &clsidstring);
398
399 try {
400#ifndef __REACTOS__
401 reg_delete_tree(HKEY_CLASSES_ROOT, L"CLSID\\"s + clsidstring);
402#else
403 wstring path = wstring(L"CLSID\\") + clsidstring;
405#endif
406 } catch (...) {
407 CoTaskMemFree(clsidstring);
408 throw;
409 }
410
411 CoTaskMemFree(clsidstring);
412}
413
414static void reg_icon_overlay(const GUID clsid, const wstring& name) {
415 WCHAR* clsidstring;
416
417 StringFromCLSID(clsid, &clsidstring);
418
419 try {
420#ifndef __REACTOS__
421 wstring path = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\"s + name;
422#else
423 wstring path = wstring(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\") + name;
424#endif
425
426 write_reg_key(HKEY_LOCAL_MACHINE, path, nullptr, clsidstring);
427 } catch (...) {
428 CoTaskMemFree(clsidstring);
429 throw;
430 }
431
432 CoTaskMemFree(clsidstring);
433}
434
435static void unreg_icon_overlay(const wstring& name) {
436#ifndef __REACTOS__
437 reg_delete_tree(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\"s + name);
438#else
439 wstring path = wstring(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\\") + name;
441#endif
442}
443
444static void reg_context_menu_handler(const GUID clsid, const wstring& filetype, const wstring& name) {
445 WCHAR* clsidstring;
446
447 StringFromCLSID(clsid, &clsidstring);
448
449 try {
450#ifndef __REACTOS__
451 wstring path = filetype + L"\\ShellEx\\ContextMenuHandlers\\"s + name;
452#else
453 wstring path = filetype + wstring(L"\\ShellEx\\ContextMenuHandlers\\") + name;
454#endif
455
456 write_reg_key(HKEY_CLASSES_ROOT, path, nullptr, clsidstring);
457 } catch (...) {
458 CoTaskMemFree(clsidstring);
459 throw;
460 }
461}
462
463static void unreg_context_menu_handler(const wstring& filetype, const wstring& name) {
464#ifndef __REACTOS__
465 reg_delete_tree(HKEY_CLASSES_ROOT, filetype + L"\\ShellEx\\ContextMenuHandlers\\"s + name);
466#else
467 wstring path = filetype + wstring(L"\\ShellEx\\ContextMenuHandlers\\") + name;
469#endif
470}
471
472static void reg_prop_sheet_handler(const GUID clsid, const wstring& filetype, const wstring& name) {
473 WCHAR* clsidstring;
474
475 StringFromCLSID(clsid, &clsidstring);
476
477 try {
478#ifndef __REACTOS__
479 wstring path = filetype + L"\\ShellEx\\PropertySheetHandlers\\"s + name;
480#else
481 wstring path = filetype + wstring(L"\\ShellEx\\PropertySheetHandlers\\") + name;
482#endif
483
484 write_reg_key(HKEY_CLASSES_ROOT, path, nullptr, clsidstring);
485 } catch (...) {
486 CoTaskMemFree(clsidstring);
487 throw;
488 }
489}
490
491static void unreg_prop_sheet_handler(const wstring& filetype, const wstring& name) {
492#ifndef __REACTOS__
493 reg_delete_tree(HKEY_CLASSES_ROOT, filetype + L"\\ShellEx\\PropertySheetHandlers\\"s + name);
494#else
495 wstring path = filetype + wstring(L"\\ShellEx\\PropertySheetHandlers\\") + name;
497#endif
498}
499
501 try {
506
508
511
515 } catch (const exception& e) {
516 error_message(nullptr, e.what());
517 return E_FAIL;
518 }
519
520 return S_OK;
521}
522
524 try {
529 unreg_context_menu_handler(L"Directory\\Background", ICON_OVERLAY_NAME);
531
536 } catch (const exception& e) {
537 error_message(nullptr, e.what());
538 return E_FAIL;
539 }
540
541 return S_OK;
542}
543
544STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine) {
545 if (bInstall)
546 return DllRegisterServer();
547 else
548 return DllUnregisterServer();
549}
550
551extern "C" BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) {
554
555 return true;
556}
557
558static void create_subvol(const wstring& fn) {
559 size_t found = fn.rfind(L"\\");
560 wstring path, file;
564
565 if (found == wstring::npos) {
566 path = L"";
567 file = fn;
568 } else {
569 path = fn.substr(0, found);
570 file = fn.substr(found + 1);
571 }
572 path += L"\\";
573
575
576 if (h == INVALID_HANDLE_VALUE)
577 return;
578
579 size_t bcslen = offsetof(btrfs_create_subvol, name[0]) + (file.length() * sizeof(WCHAR));
580 bcs = (btrfs_create_subvol*)malloc(bcslen);
581
582 bcs->readonly = false;
583 bcs->posix = false;
584 bcs->namelen = (uint16_t)(file.length() * sizeof(WCHAR));
585 memcpy(bcs->name, file.c_str(), bcs->namelen);
586
587 NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, bcs, (ULONG)bcslen, nullptr, 0);
588}
589
590extern "C" void CALLBACK CreateSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
592
593 command_line_to_args(lpszCmdLine, args);
594
595 if (args.size() >= 1)
597}
598
599static void create_snapshot2(const wstring& source, const wstring& fn) {
600 size_t found = fn.rfind(L"\\");
601 wstring path, file;
605
606 if (found == wstring::npos) {
607 path = L"";
608 file = fn;
609 } else {
610 path = fn.substr(0, found);
611 file = fn.substr(found + 1);
612 }
613 path += L"\\";
614
617 return;
618
620
621 if (h == INVALID_HANDLE_VALUE)
622 return;
623
624 size_t bcslen = offsetof(btrfs_create_snapshot, name[0]) + (file.length() * sizeof(WCHAR));
625 bcs = (btrfs_create_snapshot*)malloc(bcslen);
626
627 bcs->readonly = false;
628 bcs->posix = false;
629 bcs->namelen = (uint16_t)(file.length() * sizeof(WCHAR));
630 memcpy(bcs->name, file.c_str(), bcs->namelen);
631 bcs->subvol = src;
632
633 NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, (ULONG)bcslen, nullptr, 0);
634}
635
636extern "C" void CALLBACK CreateSnapshotW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
638
639 command_line_to_args(lpszCmdLine, args);
640
641 if (args.size() >= 2)
642 create_snapshot2(args[0], args[1]);
643}
644
646 LPWSTR* l;
647 int num_args;
648
649 args.clear();
650
651 l = CommandLineToArgvW(cmdline, &num_args);
652
653 if (!l)
654 return;
655
656 try {
657 args.reserve(num_args);
658
659 for (unsigned int i = 0; i < (unsigned int)num_args; i++) {
660 args.push_back(l[i]);
661 }
662 } catch (...) {
663 LocalFree(l);
664 throw;
665 }
666
667 LocalFree(l);
668}
669
670static string utf16_to_utf8(const wstring_view& utf16) {
671 string utf8;
672 char* buf;
673
674 if (utf16.empty())
675 return "";
676
677 auto utf8len = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.length()), nullptr, 0, nullptr, nullptr);
678
679 if (utf8len == 0)
680 throw last_error(GetLastError());
681
682 buf = (char*)malloc(utf8len + sizeof(char));
683
684 if (!buf)
686
687 if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.length()), buf, utf8len, nullptr, nullptr) == 0) {
688 auto le = GetLastError();
689 free(buf);
690 throw last_error(le);
691 }
692
693 buf[utf8len] = 0;
694
695 utf8 = buf;
696
697 free(buf);
698
699 return utf8;
700}
701
702#ifdef _MSC_VER
703#pragma warning(push)
704#pragma warning(disable: 4996)
705#endif
706
708 wstring fmt, s;
709 int len;
711
712 if (!load_string(module, resno, fmt))
713 throw runtime_error("LoadString failed."); // FIXME
714
715 va_start(args, resno);
716 len = _vsnwprintf(nullptr, 0, fmt.c_str(), args);
717
718 if (len == 0)
719 s = L"";
720 else {
721 s.resize(len);
722 _vsnwprintf((wchar_t*)s.c_str(), len, fmt.c_str(), args);
723 }
724
725 va_end(args);
726
728}
729
730#ifdef _MSC_VER
731#pragma warning(pop)
732#endif
733
734wstring utf8_to_utf16(const string_view& utf8) {
735 wstring ret;
736 WCHAR* buf;
737
738 if (utf8.empty())
739 return L"";
740
741 auto utf16len = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), (int)utf8.length(), nullptr, 0);
742
743 if (utf16len == 0)
744 throw last_error(GetLastError());
745
746 buf = (WCHAR*)malloc((utf16len + 1) * sizeof(WCHAR));
747
748 if (!buf)
750
751 if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), (int)utf8.length(), buf, utf16len) == 0) {
752 auto le = GetLastError();
753 free(buf);
754 throw last_error(le);
755 }
756
757 buf[utf16len] = 0;
758
759 ret = buf;
760
761 free(buf);
762
763 return ret;
764}
765
767 WCHAR* buf;
768
770 errnum, 0, (WCHAR*)&buf, 0, nullptr) == 0)
771 throw runtime_error("FormatMessage failed");
772
773 try {
775 } catch (...) {
776 LocalFree(buf);
777 throw;
778 }
779
780 LocalFree(buf);
781}
782
783void error_message(HWND hwnd, const char* msg) {
784 wstring title;
785
787
788 auto wmsg = utf8_to_utf16(msg);
789
790 MessageBoxW(hwnd, wmsg.c_str(), title.c_str(), MB_ICONERROR);
791}
792
795 HMODULE ntdll = LoadLibraryW(L"ntdll.dll");
796 WCHAR* buf;
797
798 if (!ntdll)
799 throw runtime_error("Error loading ntdll.dll.");
800
801 try {
802 RtlNtStatusToDosError = (_RtlNtStatusToDosError)GetProcAddress(ntdll, "RtlNtStatusToDosError");
803
805 throw runtime_error("Error loading RtlNtStatusToDosError in ntdll.dll.");
806
808 RtlNtStatusToDosError(Status), 0, (WCHAR*)&buf, 0, nullptr) == 0)
809 throw runtime_error("FormatMessage failed");
810
811 try {
813 } catch (...) {
814 LocalFree(buf);
815 throw;
816 }
817
818 LocalFree(buf);
819 } catch (...) {
820 FreeLibrary(ntdll);
821 throw;
822 }
823
824 FreeLibrary(ntdll);
825}
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define msg(x)
Definition: auth_time.c:54
#define IDS_ERROR
Definition: resource.h:18
#define IDS_OUT_OF_MEMORY
Definition: resource.h:5
LONG NTSTATUS
Definition: precomp.h:26
DWORD dwReason
Definition: misc.cpp:154
#define STDAPI
Definition: basetyps.h:41
#define RegCloseKey(hKey)
Definition: registry.h:49
#define FSCTL_BTRFS_CREATE_SNAPSHOT
Definition: btrfsioctl.h:9
#define FSCTL_BTRFS_CREATE_SUBVOL
Definition: btrfsioctl.h:8
r l[0]
Definition: byte_order.h:168
HRESULT __stdcall QueryInterface(REFIID riid, void **ppObj)
Definition: factory.cpp:26
factory_type type
Definition: factory.h:64
string msg
Definition: shellext.h:374
last_error(DWORD errnum)
Definition: main.cpp:766
ntstatus_error(NTSTATUS Status)
Definition: main.cpp:793
string msg
Definition: shellext.h:388
string msg
Definition: shellext.h:361
string_error(int resno,...)
Definition: main.cpp:707
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
UINT64 uint64_t
Definition: types.h:77
#define APIENTRY
Definition: api.h:79
STDAPI DllRegisterServer(void)
Definition: main.cpp:500
static const GUID CLSID_ShellBtrfsIconHandler
Definition: main.cpp:27
static void create_snapshot2(const wstring &source, const wstring &fn)
Definition: main.cpp:599
#define COM_DESCRIPTION_ICON_HANDLER
Definition: main.cpp:32
HRESULT(WINAPI * _SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value)
Definition: main.cpp:45
static void reg_delete_tree(HKEY hkey, const wstring &keyname)
Definition: main.cpp:342
STDAPI DllUnregisterServer(void)
Definition: main.cpp:523
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void *lpReserved)
Definition: main.cpp:551
#define ICON_OVERLAY_NAME
Definition: main.cpp:36
static void unreg_icon_overlay(const wstring &name)
Definition: main.cpp:435
HMODULE module
Definition: main.cpp:47
static void reg_icon_overlay(const GUID clsid, const wstring &name)
Definition: main.cpp:414
_PROCESS_DPI_AWARENESS
Definition: main.cpp:38
@ PROCESS_SYSTEM_DPI_AWARE
Definition: main.cpp:40
@ PROCESS_PER_MONITOR_DPI_AWARE
Definition: main.cpp:41
@ PROCESS_DPI_UNAWARE
Definition: main.cpp:39
static const GUID CLSID_ShellBtrfsVolPropSheet
Definition: main.cpp:30
bool load_string(HMODULE module, UINT id, wstring &s)
Definition: main.cpp:206
static void unreg_context_menu_handler(const wstring &filetype, const wstring &name)
Definition: main.cpp:463
LONG objs_loaded
Definition: main.cpp:48
void set_dpi_aware()
Definition: main.cpp:50
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
Definition: main.cpp:250
wstring format_message(ULONG last_error)
Definition: main.cpp:164
void error_message(HWND hwnd, const char *msg)
Definition: main.cpp:783
void CALLBACK CreateSnapshotW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
Definition: main.cpp:636
STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
Definition: main.cpp:544
static void unregister_clsid(const GUID clsid)
Definition: main.cpp:394
static void reg_context_menu_handler(const GUID clsid, const wstring &filetype, const wstring &name)
Definition: main.cpp:444
wstring format_ntstatus(NTSTATUS Status)
Definition: main.cpp:184
#define COM_DESCRIPTION_PROP_SHEET
Definition: main.cpp:34
void wstring_sprintf(wstring &s, wstring fmt,...)
Definition: main.cpp:225
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:670
static void unreg_prop_sheet_handler(const wstring &filetype, const wstring &name)
Definition: main.cpp:491
void format_size(uint64_t size, wstring &s, bool show_bytes)
Definition: main.cpp:65
static void register_clsid(const GUID clsid, const WCHAR *description)
Definition: main.cpp:310
void CALLBACK CreateSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
Definition: main.cpp:590
enum _PROCESS_DPI_AWARENESS PROCESS_DPI_AWARENESS
static void reg_prop_sheet_handler(const GUID clsid, const wstring &filetype, const wstring &name)
Definition: main.cpp:472
static void create_subvol(const wstring &fn)
Definition: main.cpp:558
#define COM_DESCRIPTION_CONTEXT_MENU
Definition: main.cpp:33
void command_line_to_args(LPWSTR cmdline, vector< wstring > &args)
Definition: main.cpp:645
static const GUID CLSID_ShellBtrfsContextMenu
Definition: main.cpp:28
wstring utf8_to_utf16(const string_view &utf8)
Definition: main.cpp:734
STDAPI DllCanUnloadNow(void)
Definition: main.cpp:246
ULONG(WINAPI * _RtlNtStatusToDosError)(NTSTATUS Status)
Definition: main.cpp:44
#define COM_DESCRIPTION_VOL_PROP_SHEET
Definition: main.cpp:35
static void write_reg_key(HKEY root, const wstring &keyname, const WCHAR *val, const wstring &data)
Definition: main.cpp:292
static const GUID CLSID_ShellBtrfsPropSheet
Definition: main.cpp:29
#define IDS_SIZE_LARGE
Definition: resource.h:42
#define IDS_SIZE_PB
Definition: resource.h:36
#define IDS_SIZE_BYTE
Definition: resource.h:30
#define IDS_SIZE_GB
Definition: resource.h:34
#define IDS_REGCLOSEKEY_FAILED
Definition: resource.h:203
#define IDS_SIZE_KB
Definition: resource.h:32
#define IDS_SIZE_TB
Definition: resource.h:35
#define IDS_REGCREATEKEY_FAILED
Definition: resource.h:201
#define IDS_SIZE_MB
Definition: resource.h:33
#define IDS_SIZE_BYTES
Definition: resource.h:31
#define IDS_REGSETVALUEEX_FAILED
Definition: resource.h:202
#define IDS_SIZE_EB
Definition: resource.h:37
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
HMODULE hModule
Definition: animate.c:44
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define OPEN_EXISTING
Definition: compat.h:775
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define LoadLibraryW(x)
Definition: compat.h:747
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1665
HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR *idstr)
Definition: compobj.c:2412
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define swprintf
Definition: precomp.h:40
@ FactoryContextMenu
Definition: factory.h:25
@ FactoryIconHandler
Definition: factory.h:24
@ FactoryVolPropSheet
Definition: factory.h:27
@ FactoryPropSheet
Definition: factory.h:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
_CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest, size_t _Count, const wchar_t *_Format, va_list _Args)
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define S_OK
Definition: intsafe.h:52
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define c
Definition: ke_i.h:80
#define REG_SZ
Definition: layer.c:22
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1212
WCHAR dllpath[MAX_PATH]
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
static HINSTANCE hinst
Definition: edit.c:551
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:132
static float(__cdecl *square_half_float)(float x
int k
Definition: mpi.c:3369
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
#define uint16_t
Definition: nsiface.idl:60
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define LOCALE_USER_DEFAULT
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
static char title[]
Definition: ps.c:92
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define offsetof(TYPE, MEMBER)
#define CP_UTF8
Definition: nls.h:20
LOCAL char * filetype(int t)
Definition: tree.c:114
LPWSTR *WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int *numargs)
Definition: shell32_main.c:80
bool load_string(HMODULE module, UINT id, wstring &s)
Definition: main.cpp:206
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: match.c:390
Definition: fci.c:127
Definition: dsound.c:943
Definition: name.c:39
HANDLE HMODULE
Definition: typedefs.h:77
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
int ret
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
const char * description
Definition: directx.c:2497
#define S_FALSE
Definition: winerror.h:2357
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:2663
#define LOCALE_SGROUPING
Definition: winnls.h:44
#define LOCALE_STHOUSAND
Definition: winnls.h:43
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:787
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193