ReactOS  0.4.14-dev-358-gbef841c
BtrfsContextMenu Class Reference

#include <contextmenu.h>

Inheritance diagram for BtrfsContextMenu:
Collaboration diagram for BtrfsContextMenu:

Public Member Functions

 BtrfsContextMenu ()
 
virtual ~BtrfsContextMenu ()
 
HRESULT __stdcall QueryInterface (REFIID riid, void **ppObj)
 
ULONG __stdcall AddRef ()
 
ULONG __stdcall Release ()
 
virtual HRESULT __stdcall Initialize (PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID)
 
virtual HRESULT __stdcall QueryContextMenu (HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
 
virtual HRESULT __stdcall InvokeCommand (LPCMINVOKECOMMANDINFO pici)
 
virtual HRESULT __stdcall GetCommandString (UINT_PTR idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax)
 

Private Member Functions

void reflink_copy (HWND hwnd, const WCHAR *fn, const WCHAR *dir)
 
void get_uac_icon ()
 

Private Attributes

LONG refcount
 
bool ignore
 
bool allow_snapshot
 
bool bg
 
wstring path
 
STGMEDIUM stgm
 
bool stgm_set
 
HBITMAP uacicon
 
- Private Attributes inherited from IContextMenu
CMIC_MASK_NOZONECHECKS typedef IContextMenuLPCONTEXTMENU
 

Additional Inherited Members

- Public Types inherited from IShellExtInit
typedef IShellExtInitLPSHELLEXTINIT
 
- Public Types inherited from IUnknown
typedef IUnknownLPUNKNOWN
 
- Private Types inherited from IContextMenu
typedef struct IContextMenu::tagCMINVOKECOMMANDINFO CMINVOKECOMMANDINFO
 
typedef struct IContextMenu::tagCMINVOKECOMMANDINFOLPCMINVOKECOMMANDINFO
 
typedef struct IContextMenu::tagCMInvokeCommandInfoEx CMINVOKECOMMANDINFOEX
 
typedef struct IContextMenu::tagCMInvokeCommandInfoExLPCMINVOKECOMMANDINFOEX
 
- Private Types inherited from IUnknown
typedef IUnknownLPUNKNOWN
 
- Static Private Attributes inherited from IContextMenu
static CMDSTR_VIEWDETAILSW(const WCHAR []) const WCHAR CMDSTR_NEWFOLDERW [] = {'N','e','w','F','o','l','d','e','r',0}
 
static const WCHAR CMDSTR_VIEWLISTW [] = {'V','i','e','w','L','i','s','t',0}
 
static const WCHAR CMDSTR_VIEWDETAILSW [] = {'V','i','e','w','D','e','t','a','i','l','s',0}
 

Detailed Description

Definition at line 24 of file contextmenu.h.

Constructor & Destructor Documentation

◆ BtrfsContextMenu()

BtrfsContextMenu::BtrfsContextMenu ( )
inline

Definition at line 26 of file contextmenu.h.

26  {
27  refcount = 0;
28  ignore = true;
29  stgm_set = false;
30  uacicon = nullptr;
31  allow_snapshot = false;
33  }
#define InterlockedIncrement
Definition: armddk.h:53
LONG objs_loaded
Definition: main.cpp:48

◆ ~BtrfsContextMenu()

virtual BtrfsContextMenu::~BtrfsContextMenu ( )
inlinevirtual

Definition at line 35 of file contextmenu.h.

35  {
36  if (stgm_set) {
37  GlobalUnlock(stgm.hGlobal);
39  }
40 
41  if (uacicon)
43 
45  }
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
STGMEDIUM stgm
Definition: contextmenu.h:79
#define InterlockedDecrement
Definition: armddk.h:52
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
LONG objs_loaded
Definition: main.cpp:48

Member Function Documentation

◆ AddRef()

ULONG __stdcall BtrfsContextMenu::AddRef ( void  )
inline

Implements IUnknown.

Definition at line 51 of file contextmenu.h.

51  {
53  }
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by QueryInterface().

◆ get_uac_icon()

void BtrfsContextMenu::get_uac_icon ( )
private

Definition at line 294 of file contextmenu.cpp.

294  {
295  IWICImagingFactory* factory = nullptr;
297  HRESULT hr;
298 
299 #ifdef __REACTOS__
300  hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void **)&factory);
301 #else
302  hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory));
303 #endif
304 
305  if (SUCCEEDED(hr)) {
306  HANDLE icon;
307 
308  // We can't use IDI_SHIELD, as that will only give us the full-size icon
309  icon = LoadImageW(GetModuleHandleW(L"user32.dll"), MAKEINTRESOURCEW(106)/* UAC shield */, IMAGE_ICON,
311 
312  hr = factory->CreateBitmapFromHICON((HICON)icon, &bitmap);
313  if (SUCCEEDED(hr)) {
314  UINT cx, cy;
315 
316  hr = bitmap->GetSize(&cx, &cy);
317  if (SUCCEEDED(hr)) {
318  SIZE sz;
319  BYTE* buf;
320 
321  sz.cx = (int)cx;
322  sz.cy = -(int)cy;
323 
324  hr = Create32BitHBITMAP(nullptr, &sz, (void**)&buf, &uacicon);
325  if (SUCCEEDED(hr)) {
326  UINT stride = (UINT)(cx * sizeof(DWORD));
327  UINT buflen = cy * stride;
328  bitmap->CopyPixels(nullptr, stride, buflen, buf);
329  }
330  }
331 
332  bitmap->Release();
333  }
334 
335  factory->Release();
336  }
337 }
static HICON
Definition: imagelist.c:84
#define IMAGE_ICON
Definition: winuser.h:212
HRESULT hr
Definition: shlfolder.c:183
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define SM_CYSMICON
Definition: winuser.h:1003
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2172
Definition: main.c:440
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
LONG cx
Definition: windef.h:319
static HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, void **ppvBits, HBITMAP *phBmp)
Definition: uimain.c:88
GLsizei stride
Definition: glext.h:5848
LONG HRESULT
Definition: typedefs.h:77
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SM_CXSMICON
Definition: winuser.h:1002
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: mem.h:68
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
unsigned int UINT
Definition: ndis.h:50
_Out_opt_ int * cx
Definition: commctrl.h:581
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
static HBITMAP bitmap
Definition: clipboard.c:1344
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define LR_DEFAULTCOLOR
Definition: winuser.h:1077
LONG cy
Definition: windef.h:320
#define SUCCEEDED(hr)
Definition: intsafe.h:57
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by QueryContextMenu().

◆ GetCommandString()

HRESULT __stdcall BtrfsContextMenu::GetCommandString ( UINT_PTR  idCmd,
UINT  uFlags,
UINT pwReserved,
LPSTR  pszName,
UINT  cchMax 
)
virtual

Implements IContextMenu.

Definition at line 1179 of file contextmenu.cpp.

1179  {
1180  if (ignore)
1181  return E_INVALIDARG;
1182 
1183  if (idCmd != 0)
1184  return E_INVALIDARG;
1185 
1186  if (!bg) {
1187  if (idCmd == 0) {
1188  switch (uFlags) {
1189  case GCS_HELPTEXTA:
1191  return S_OK;
1192  else
1193  return E_FAIL;
1194 
1195  case GCS_HELPTEXTW:
1197  return S_OK;
1198  else
1199  return E_FAIL;
1200 
1201  case GCS_VALIDATEA:
1202  case GCS_VALIDATEW:
1203  return S_OK;
1204 
1205  case GCS_VERBA:
1206  return StringCchCopyA(pszName, cchMax, SNAPSHOT_VERBA);
1207 
1208  case GCS_VERBW:
1210 
1211  default:
1212  return E_INVALIDARG;
1213  }
1214  } else if (idCmd == 1) {
1215  switch (uFlags) {
1216  case GCS_HELPTEXTA:
1218  return S_OK;
1219  else
1220  return E_FAIL;
1221 
1222  case GCS_HELPTEXTW:
1224  return S_OK;
1225  else
1226  return E_FAIL;
1227 
1228  case GCS_VALIDATEA:
1229  case GCS_VALIDATEW:
1230  return S_OK;
1231 
1232  case GCS_VERBA:
1233  return StringCchCopyA(pszName, cchMax, SEND_VERBA);
1234 
1235  case GCS_VERBW:
1236  return StringCchCopyW((STRSAFE_LPWSTR)pszName, cchMax, SEND_VERBW);
1237 
1238  default:
1239  return E_INVALIDARG;
1240  }
1241  } else
1242  return E_INVALIDARG;
1243  } else {
1244  if (idCmd == 0) {
1245  switch (uFlags) {
1246  case GCS_HELPTEXTA:
1248  return S_OK;
1249  else
1250  return E_FAIL;
1251 
1252  case GCS_HELPTEXTW:
1254  return S_OK;
1255  else
1256  return E_FAIL;
1257 
1258  case GCS_VALIDATEA:
1259  case GCS_VALIDATEW:
1260  return S_OK;
1261 
1262  case GCS_VERBA:
1263  return StringCchCopyA(pszName, cchMax, NEW_SUBVOL_VERBA);
1264 
1265  case GCS_VERBW:
1267 
1268  default:
1269  return E_INVALIDARG;
1270  }
1271  } else if (idCmd == 1) {
1272  switch (uFlags) {
1273  case GCS_HELPTEXTA:
1275  return S_OK;
1276  else
1277  return E_FAIL;
1278 
1279  case GCS_HELPTEXTW:
1281  return S_OK;
1282  else
1283  return E_FAIL;
1284 
1285  case GCS_VALIDATEA:
1286  case GCS_VALIDATEW:
1287  return S_OK;
1288 
1289  case GCS_VERBA:
1290  return StringCchCopyA(pszName, cchMax, RECV_VERBA);
1291 
1292  case GCS_VERBW:
1293  return StringCchCopyW((STRSAFE_LPWSTR)pszName, cchMax, RECV_VERBW);
1294 
1295  default:
1296  return E_INVALIDARG;
1297  }
1298  } else if (idCmd == 2) {
1299  switch (uFlags) {
1300  case GCS_HELPTEXTA:
1302  return S_OK;
1303  else
1304  return E_FAIL;
1305 
1306  case GCS_HELPTEXTW:
1308  return S_OK;
1309  else
1310  return E_FAIL;
1311 
1312  case GCS_VALIDATEA:
1313  case GCS_VALIDATEW:
1314  return S_OK;
1315 
1316  case GCS_VERBA:
1317  return StringCchCopyA(pszName, cchMax, REFLINK_VERBA);
1318 
1319  case GCS_VERBW:
1321 
1322  default:
1323  return E_INVALIDARG;
1324  }
1325  } else
1326  return E_INVALIDARG;
1327  }
1328 }
#define SEND_VERBW
Definition: contextmenu.cpp:58
#define NEW_SUBVOL_VERBW
Definition: contextmenu.cpp:50
int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPSTR lpBuffer, _In_ int cchBufferMax)
#define RECV_VERBW
Definition: contextmenu.cpp:56
wchar_t * STRSAFE_LPWSTR
Definition: ntstrsafe.h:53
UINT uFlags
Definition: api.c:59
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define IDS_RECV_SUBVOL_HELP
Definition: resource.h:131
#define SEND_VERBA
Definition: contextmenu.cpp:57
#define SNAPSHOT_VERBA
Definition: contextmenu.cpp:51
#define IDS_SEND_SUBVOL_HELP
Definition: resource.h:175
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define IDS_NEW_SUBVOL_HELP_TEXT
Definition: resource.h:6
#define E_INVALIDARG
Definition: ddrawi.h:101
#define RECV_VERBA
Definition: contextmenu.cpp:55
#define IDS_REFLINK_PASTE_HELP
Definition: resource.h:129
#define REFLINK_VERBA
Definition: contextmenu.cpp:53
UINT cchMax
#define SNAPSHOT_VERBW
Definition: contextmenu.cpp:52
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
#define NEW_SUBVOL_VERBA
Definition: contextmenu.cpp:49
#define S_OK
Definition: intsafe.h:59
#define REFLINK_VERBW
Definition: contextmenu.cpp:54
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDS_CREATE_SNAPSHOT_HELP_TEXT
Definition: resource.h:12

◆ Initialize()

HRESULT __stdcall BtrfsContextMenu::Initialize ( PCIDLIST_ABSOLUTE  pidlFolder,
IDataObject pdtobj,
HKEY  hkeyProgID 
)
virtual

Implements IShellExtInit.

Definition at line 85 of file contextmenu.cpp.

85  {
87  btrfs_get_file_ids bgfi;
89 
90  if (!pidlFolder) {
91  FORMATETC format = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
92  UINT num_files, i;
93  WCHAR fn[MAX_PATH];
94  HDROP hdrop;
95 
96  if (!pdtobj)
97  return E_FAIL;
98 
99  stgm.tymed = TYMED_HGLOBAL;
100 
101  if (FAILED(pdtobj->GetData(&format, &stgm)))
102  return E_INVALIDARG;
103 
104  stgm_set = true;
105 
106  hdrop = (HDROP)GlobalLock(stgm.hGlobal);
107 
108  if (!hdrop) {
110  stgm_set = false;
111  return E_INVALIDARG;
112  }
113 
114  num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
115 
116  for (i = 0; i < num_files; i++) {
117  if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) {
119 
120  if (h != INVALID_HANDLE_VALUE) {
121  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_FILE_IDS, nullptr, 0, &bgfi, sizeof(btrfs_get_file_ids));
122 
123  if (NT_SUCCESS(Status) && bgfi.inode == 0x100 && !bgfi.top) {
124  wstring parpath;
125 
126  {
127  win_handle h2;
128 
129  parpath = fn;
130  path_remove_file(parpath);
131 
134 
135  if (h2 != INVALID_HANDLE_VALUE)
136  allow_snapshot = true;
137  }
138 
139  ignore = false;
140  bg = false;
141 
142  GlobalUnlock(hdrop);
143  return S_OK;
144  }
145  }
146  }
147  }
148 
149  GlobalUnlock(hdrop);
150 
151  return S_OK;
152  }
153 
154  {
155  WCHAR pathbuf[MAX_PATH];
156 
157  if (!SHGetPathFromIDListW(pidlFolder, pathbuf))
158  return E_FAIL;
159 
160  path = pathbuf;
161  }
162 
163  {
164  // check we have permissions to create new subdirectory
165 
167 
168  if (h == INVALID_HANDLE_VALUE)
169  return E_FAIL;
170 
171  // check is Btrfs volume
172 
173  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_FILE_IDS, nullptr, 0, &bgfi, sizeof(btrfs_get_file_ids));
174 
175  if (!NT_SUCCESS(Status))
176  return E_FAIL;
177  }
178 
179  ignore = false;
180  bg = true;
181 
182  return S_OK;
183 }
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
LONG NTSTATUS
Definition: precomp.h:26
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1280
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define E_FAIL
Definition: ddrawi.h:102
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define FILE_SHARE_READ
Definition: compat.h:125
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define FILE_TRAVERSE
Definition: nt_native.h:643
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
#define E_INVALIDARG
Definition: ddrawi.h:101
#define CF_HDROP
Definition: constants.h:410
#define OPEN_EXISTING
Definition: compat.h:434
STGMEDIUM stgm
Definition: contextmenu.h:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FSCTL_BTRFS_GET_FILE_IDS
Definition: btrfsioctl.h:7
Status
Definition: gdiplustypes.h:24
static void path_remove_file(wstring &path)
#define S_OK
Definition: intsafe.h:59
Definition: services.c:325
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define CreateFileW
Definition: compat.h:408
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:627

◆ InvokeCommand()

HRESULT __stdcall BtrfsContextMenu::InvokeCommand ( LPCMINVOKECOMMANDINFO  pici)
virtual

Implements IContextMenu.

Definition at line 964 of file contextmenu.cpp.

964  {
966 
967  try {
968  if (ignore)
969  return E_INVALIDARG;
970 
971  if (!bg) {
972  if ((IS_INTRESOURCE(pici->lpVerb) && allow_snapshot && pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SNAPSHOT_VERBA))) {
973  UINT num_files, i;
974  WCHAR fn[MAX_PATH];
975 
976  if (!stgm_set)
977  return E_FAIL;
978 
979  num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
980 
981  if (num_files == 0)
982  return E_FAIL;
983 
984  for (i = 0; i < num_files; i++) {
985  if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) {
986  create_snapshot(pici->hwnd, fn);
987  }
988  }
989 
990  return S_OK;
991  } else if ((IS_INTRESOURCE(pici->lpVerb) && ((allow_snapshot && (ULONG_PTR)pici->lpVerb == 1) || (!allow_snapshot && (ULONG_PTR)pici->lpVerb == 0))) ||
992  (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SEND_VERBA))) {
993  UINT num_files, i;
995  wstring t;
996  SHELLEXECUTEINFOW sei;
997 
998  GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR));
999 
1000  if (!stgm_set)
1001  return E_FAIL;
1002 
1003  num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
1004 
1005  if (num_files == 0)
1006  return E_FAIL;
1007 
1008  for (i = 0; i < num_files; i++) {
1009  if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) {
1010  t = L"\"";
1011  t += dll;
1012  t += L"\",SendSubvolGUI ";
1013  t += fn;
1014 
1015  RtlZeroMemory(&sei, sizeof(sei));
1016 
1017  sei.cbSize = sizeof(sei);
1018  sei.hwnd = pici->hwnd;
1019  sei.lpVerb = L"runas";
1020  sei.lpFile = L"rundll32.exe";
1021  sei.lpParameters = t.c_str();
1022  sei.nShow = SW_SHOW;
1024 
1025  if (!ShellExecuteExW(&sei))
1026  throw last_error(GetLastError());
1027 
1029  CloseHandle(sei.hProcess);
1030  }
1031  }
1032 
1033  return S_OK;
1034  }
1035  } else {
1036  if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, NEW_SUBVOL_VERBA))) {
1037  win_handle h;
1039  NTSTATUS Status;
1040  wstring name, nameorig, searchpath;
1041  btrfs_create_subvol* bcs;
1042  WIN32_FIND_DATAW wfd;
1043 
1045  throw last_error(GetLastError());
1046 
1048 
1049  if (h == INVALID_HANDLE_VALUE)
1050  throw last_error(GetLastError());
1051 
1052  searchpath = path + L"\\" + name;
1053  nameorig = name;
1054 
1055  {
1056  fff_handle fff = FindFirstFileW(searchpath.c_str(), &wfd);
1057 
1058  if (fff != INVALID_HANDLE_VALUE) {
1059  ULONG num = 2;
1060 
1061  do {
1062 #ifndef __REACTOS__
1063  name = nameorig + L" (" + to_wstring(num) + L")";
1064 #else
1065  {
1066  WCHAR buffer[32];
1067 
1068  swprintf(buffer, L"%d", num);
1069  name = nameorig + L" (" + buffer + L")";
1070  }
1071 #endif
1072  searchpath = path + L"\\" + name;
1073 
1074  fff = FindFirstFileW(searchpath.c_str(), &wfd);
1075  num++;
1076  } while (fff != INVALID_HANDLE_VALUE);
1077  }
1078  }
1079 
1080  size_t bcslen = offsetof(btrfs_create_subvol, name[0]) + (name.length() * sizeof(WCHAR));
1081  bcs = (btrfs_create_subvol*)malloc(bcslen);
1082 
1083  bcs->readonly = false;
1084  bcs->posix = false;
1085  bcs->namelen = (uint16_t)(name.length() * sizeof(WCHAR));
1086  memcpy(bcs->name, name.c_str(), name.length() * sizeof(WCHAR));
1087 
1088  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, bcs, (ULONG)bcslen, nullptr, 0);
1089 
1090  free(bcs);
1091 
1092  if (!NT_SUCCESS(Status))
1093  throw ntstatus_error(Status);
1094 
1095  return S_OK;
1096  } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 1) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, RECV_VERBA))) {
1097  WCHAR dll[MAX_PATH];
1098  wstring t;
1099  SHELLEXECUTEINFOW sei;
1100 
1101  GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR));
1102 
1103  t = L"\"";
1104  t += dll;
1105  t += L"\",RecvSubvolGUI ";
1106  t += path;
1107 
1108  RtlZeroMemory(&sei, sizeof(sei));
1109 
1110  sei.cbSize = sizeof(sei);
1111  sei.hwnd = pici->hwnd;
1112  sei.lpVerb = L"runas";
1113  sei.lpFile = L"rundll32.exe";
1114  sei.lpParameters = t.c_str();
1115  sei.nShow = SW_SHOW;
1117 
1118  if (!ShellExecuteExW(&sei))
1119  throw last_error(GetLastError());
1120 
1122  CloseHandle(sei.hProcess);
1123 
1124  return S_OK;
1125  } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 2) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, REFLINK_VERBA))) {
1126  HDROP hdrop;
1127 
1129  return S_OK;
1130 
1131  if (!OpenClipboard(pici->hwnd))
1132  throw last_error(GetLastError());
1133 
1134  try {
1135  hdrop = (HDROP)GetClipboardData(CF_HDROP);
1136 
1137  if (hdrop) {
1138  HANDLE lh;
1139 
1140  lh = GlobalLock(hdrop);
1141 
1142  if (lh) {
1143  try {
1144  ULONG num_files, i;
1145  WCHAR fn[MAX_PATH];
1146 
1147  num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, nullptr, 0);
1148 
1149  for (i = 0; i < num_files; i++) {
1150  if (DragQueryFileW(hdrop, i, fn, sizeof(fn) / sizeof(WCHAR))) {
1151  reflink_copy(pici->hwnd, fn, pici->lpDirectoryW);
1152  }
1153  }
1154  } catch (...) {
1155  GlobalUnlock(lh);
1156  throw;
1157  }
1158 
1159  GlobalUnlock(lh);
1160  }
1161  }
1162  } catch (...) {
1163  CloseClipboard();
1164  throw;
1165  }
1166 
1167  CloseClipboard();
1168 
1169  return S_OK;
1170  }
1171  }
1172  } catch (const exception& e) {
1173  error_message(pici->hwnd, e.what());
1174  }
1175 
1176  return E_FAIL;
1177 }
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:609
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define CloseHandle
Definition: compat.h:406
BOOL WINAPI IsClipboardFormatAvailable(_In_ UINT)
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
#define free
Definition: debug_ros.c:5
LONG NTSTATUS
Definition: precomp.h:26
static void create_snapshot(HWND hwnd, const wstring &fn)
GLdouble GLdouble t
Definition: gl.h:2047
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLuint buffer
Definition: glext.h:5915
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define uint16_t
Definition: nsiface.idl:60
#define E_FAIL
Definition: ddrawi.h:102
void reflink_copy(HWND hwnd, const WCHAR *fn, const WCHAR *dir)
#define SEND_VERBA
Definition: contextmenu.cpp:57
#define FILE_SHARE_READ
Definition: compat.h:125
#define SNAPSHOT_VERBA
Definition: contextmenu.cpp:51
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
uint32_t ULONG_PTR
Definition: typedefs.h:63
static HMODULE dll
Definition: str.c:188
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
void error_message(HWND hwnd, const char *msg)
Definition: main.cpp:785
#define e
Definition: ke_i.h:82
#define E_INVALIDARG
Definition: ddrawi.h:101
#define offsetof(TYPE, MEMBER)
#define CF_HDROP
Definition: constants.h:410
#define RECV_VERBA
Definition: contextmenu.cpp:55
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2235
#define SW_SHOW
Definition: winuser.h:769
#define OPEN_EXISTING
Definition: compat.h:434
#define FSCTL_BTRFS_CREATE_SUBVOL
Definition: btrfsioctl.h:8
STGMEDIUM stgm
Definition: contextmenu.h:79
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define REFLINK_VERBA
Definition: contextmenu.cpp:53
#define MAX_PATH
Definition: compat.h:26
#define swprintf(buf, format,...)
Definition: sprintf.c:56
GLuint GLuint num
Definition: glext.h:9618
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Status
Definition: gdiplustypes.h:24
#define NEW_SUBVOL_VERBA
Definition: contextmenu.cpp:49
#define S_OK
Definition: intsafe.h:59
struct IContextMenu::tagCMInvokeCommandInfoEx * LPCMINVOKECOMMANDINFOEX
LPCWSTR lpParameters
Definition: shellapi.h:331
Definition: services.c:325
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
Definition: muireg.c:10
HANDLE WINAPI GetClipboardData(_In_ UINT)
#define CreateFileW
Definition: compat.h:408
Definition: name.c:36
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define malloc
Definition: debug_ros.c:4
#define IDS_NEW_SUBVOL_FILENAME
Definition: resource.h:9
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
#define INFINITE
Definition: serial.h:102
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:627
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
GLuint const GLchar * name
Definition: glext.h:6031

◆ QueryContextMenu()

HRESULT __stdcall BtrfsContextMenu::QueryContextMenu ( HMENU  hmenu,
UINT  indexMenu,
UINT  idCmdFirst,
UINT  idCmdLast,
UINT  uFlags 
)
virtual

Implements IContextMenu.

Definition at line 339 of file contextmenu.cpp.

339  {
340  wstring str;
341  ULONG entries = 0;
342 
343  if (ignore)
344  return E_INVALIDARG;
345 
346  if (uFlags & CMF_DEFAULTONLY)
347  return S_OK;
348 
349  if (!bg) {
350  if (allow_snapshot) {
352  return E_FAIL;
353 
354  if (!InsertMenuW(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, str.c_str()))
355  return E_FAIL;
356 
357  entries = 1;
358  }
359 
360  if (idCmdFirst + entries <= idCmdLast) {
361  MENUITEMINFOW mii;
362 
364  return E_FAIL;
365 
366  if (!uacicon)
367  get_uac_icon();
368 
369  memset(&mii, 0, sizeof(MENUITEMINFOW));
370  mii.cbSize = sizeof(MENUITEMINFOW);
372  mii.dwTypeData = (WCHAR*)str.c_str();
373  mii.wID = idCmdFirst + entries;
374  mii.hbmpItem = uacicon;
375 
376  if (!InsertMenuItemW(hmenu, indexMenu + entries, true, &mii))
377  return E_FAIL;
378 
379  entries++;
380  }
381  } else {
382  if (load_string(module, IDS_NEW_SUBVOL, str) == 0)
383  return E_FAIL;
384 
385  if (!InsertMenuW(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst, str.c_str()))
386  return E_FAIL;
387 
388  entries = 1;
389 
390  if (idCmdFirst + 1 <= idCmdLast) {
391  MENUITEMINFOW mii;
392 
394  return E_FAIL;
395 
396  if (!uacicon)
397  get_uac_icon();
398 
399  memset(&mii, 0, sizeof(MENUITEMINFOW));
400  mii.cbSize = sizeof(MENUITEMINFOW);
402  mii.dwTypeData = (WCHAR*)str.c_str();
403  mii.wID = idCmdFirst + 1;
404  mii.hbmpItem = uacicon;
405 
406  if (!InsertMenuItemW(hmenu, indexMenu + 1, true, &mii))
407  return E_FAIL;
408 
409  entries++;
410  }
411 
412  if (idCmdFirst + 2 <= idCmdLast && show_reflink_paste(path)) {
414  return E_FAIL;
415 
416  if (!InsertMenuW(hmenu, indexMenu + 2, MF_BYPOSITION, idCmdFirst + 2, str.c_str()))
417  return E_FAIL;
418 
419  entries++;
420  }
421  }
422 
423  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, entries);
424 }
static HMENU hmenu
Definition: win.c:66
BOOL WINAPI InsertMenuW(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
LPWSTR dwTypeData
Definition: winuser.h:3243
UINT uFlags
Definition: api.c:59
#define E_FAIL
Definition: ddrawi.h:102
#define MIIM_BITMAP
Definition: winuser.h:723
#define SEVERITY_SUCCESS
Definition: winerror.h:64
#define MF_BYPOSITION
Definition: winuser.h:203
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
#define IDS_CREATE_SNAPSHOT
Definition: resource.h:10
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
#define MIIM_ID
Definition: winuser.h:717
static bool show_reflink_paste(const wstring &path)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IDS_RECV_SUBVOL
Definition: resource.h:130
#define IDS_SEND_SUBVOL
Definition: resource.h:174
#define MIIM_STRING
Definition: winuser.h:722
#define S_OK
Definition: intsafe.h:59
Definition: services.c:325
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
Definition: muireg.c:10
#define IDS_NEW_SUBVOL
Definition: resource.h:7
unsigned int ULONG
Definition: retypes.h:1
#define memset(x, y, z)
Definition: compat.h:39
#define IDS_REFLINK_PASTE
Definition: resource.h:128
struct tagMENUITEMINFOW MENUITEMINFOW

◆ QueryInterface()

HRESULT __stdcall BtrfsContextMenu::QueryInterface ( REFIID  riid,
void **  ppObj 
)

Implements IUnknown.

Definition at line 70 of file contextmenu.cpp.

70  {
71  if (riid == IID_IUnknown || riid == IID_IContextMenu) {
72  *ppObj = static_cast<IContextMenu*>(this);
73  AddRef();
74  return S_OK;
75  } else if (riid == IID_IShellExtInit) {
76  *ppObj = static_cast<IShellExtInit*>(this);
77  AddRef();
78  return S_OK;
79  }
80 
81  *ppObj = nullptr;
82  return E_NOINTERFACE;
83 }
ULONG __stdcall AddRef()
Definition: contextmenu.h:51
#define E_NOINTERFACE
Definition: winerror.h:2364
REFIID riid
Definition: precomp.h:44
const GUID IID_IUnknown
#define S_OK
Definition: intsafe.h:59

Referenced by Factory::CreateInstance().

◆ reflink_copy()

void BtrfsContextMenu::reflink_copy ( HWND  hwnd,
const WCHAR fn,
const WCHAR dir 
)
private

Definition at line 538 of file contextmenu.cpp.

538  {
540  WCHAR* name, volpath1[255], volpath2[255];
541  wstring dirw, newpath;
542  FILE_BASIC_INFO fbi;
543  FILETIME atime, mtime;
544  btrfs_inode_info bii;
546  ULONG bytesret;
549  btrfs_set_xattr bsxa;
550 
551  // Thanks to 0xbadfca11, whose version of reflink for Windows provided a few pointers on what
552  // to do here - https://github.com/0xbadfca11/reflink
553 
555 
556  dirw = dir;
557 
558  if (dir[0] != 0 && dir[wcslen(dir) - 1] != '\\')
559  dirw += L"\\";
560 
561  newpath = dirw;
562  newpath += name;
563 
564  if (!get_volume_path_parent(fn, volpath1, sizeof(volpath1) / sizeof(WCHAR)))
565  throw last_error(GetLastError());
566 
567  if (!GetVolumePathNameW(dir, volpath2, sizeof(volpath2) / sizeof(WCHAR)))
568  throw last_error(GetLastError());
569 
570  if (wcscmp(volpath1, volpath2)) // different filesystems
572 
575  throw last_error(GetLastError());
576 
577  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_INODE_INFO, nullptr, 0, &bii, sizeof(btrfs_inode_info));
578  if (!NT_SUCCESS(Status))
579  throw ntstatus_error(Status);
580 
581  // if subvol, do snapshot instead
582  if (bii.inode == SUBVOL_ROOT_INODE) {
584  win_handle dirh;
585  wstring destname, search;
586  WIN32_FIND_DATAW wfd;
587  int num = 2;
588 
590  if (dirh == INVALID_HANDLE_VALUE)
591  throw last_error(GetLastError());
592 
593  search = dirw;
594  search += name;
595  destname = name;
596 
597  fff_handle fff = FindFirstFileW(search.c_str(), &wfd);
598 
599  if (fff != INVALID_HANDLE_VALUE) {
600  do {
602 
603  ss << name;
604  ss << L" (";
605  ss << num;
606  ss << L")";
607  destname = ss.str();
608 
609  search = dirw + destname;
610 
611  fff = FindFirstFileW(search.c_str(), &wfd);
612  num++;
613  } while (fff != INVALID_HANDLE_VALUE);
614  }
615 
616  bcs = (btrfs_create_snapshot*)malloc(sizeof(btrfs_create_snapshot) - sizeof(WCHAR) + (destname.length() * sizeof(WCHAR)));
617  bcs->subvol = source;
618  bcs->namelen = (uint16_t)(destname.length() * sizeof(WCHAR));
619  memcpy(bcs->name, destname.c_str(), destname.length() * sizeof(WCHAR));
620 
621  Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs,
622  (ULONG)(sizeof(btrfs_create_snapshot) - sizeof(WCHAR) + bcs->namelen), nullptr, 0);
623 
624  free(bcs);
625 
626  if (!NT_SUCCESS(Status))
627  throw ntstatus_error(Status);
628 
629  return;
630  }
631 
632  Status = NtQueryInformationFile(source, &iosb, &fbi, sizeof(FILE_BASIC_INFO), FileBasicInformation);
633  if (!NT_SUCCESS(Status))
634  throw ntstatus_error(Status);
635 
636  if (bii.type == BTRFS_TYPE_CHARDEV || bii.type == BTRFS_TYPE_BLOCKDEV || bii.type == BTRFS_TYPE_FIFO || bii.type == BTRFS_TYPE_SOCKET) {
637  win_handle dirh;
638  btrfs_mknod* bmn;
639 
641  if (dirh == INVALID_HANDLE_VALUE)
642  throw last_error(GetLastError());
643 
644  size_t bmnsize = offsetof(btrfs_mknod, name[0]) + (wcslen(name) * sizeof(WCHAR));
645  bmn = (btrfs_mknod*)malloc(bmnsize);
646 
647  bmn->inode = 0;
648  bmn->type = bii.type;
649  bmn->st_rdev = bii.st_rdev;
650  bmn->namelen = (uint16_t)(wcslen(name) * sizeof(WCHAR));
651  memcpy(bmn->name, name, bmn->namelen);
652 
653  Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_MKNOD, bmn, (ULONG)bmnsize, nullptr, 0);
654  if (!NT_SUCCESS(Status)) {
655  free(bmn);
656  throw ntstatus_error(Status);
657  }
658 
659  free(bmn);
660 
661  dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
662  } else if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
663  if (CreateDirectoryExW(fn, newpath.c_str(), nullptr))
665  nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
666  else
668  } else
669  dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, source);
670 
671  if (dest == INVALID_HANDLE_VALUE) {
672  int num = 2;
673 
674  if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_ALREADY_EXISTS && wcscmp(fn, newpath.c_str()))
675  throw last_error(GetLastError());
676 
677  do {
678  WCHAR* ext;
680 
682 
683  ss << dirw;
684 
685  if (*ext == 0) {
686  ss << name;
687  ss << L" (";
688  ss << num;
689  ss << L")";
690  } else {
691  wstring namew = name;
692 
693  ss << namew.substr(0, ext - name);
694  ss << L" (";
695  ss << num;
696  ss << L")";
697  ss << ext;
698  }
699 
700  newpath = ss.str();
701  if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
702  if (CreateDirectoryExW(fn, newpath.c_str(), nullptr))
703  dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
704  else
706  } else
707  dest = CreateFileW(newpath.c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, source);
708 
709  if (dest == INVALID_HANDLE_VALUE) {
711  throw last_error(GetLastError());
712 
713  num++;
714  } else
715  break;
716  } while (true);
717  }
718 
719  try {
720  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
721 
722  bsii.flags_changed = true;
723  bsii.flags = bii.flags;
724 
725  if (bii.flags & BTRFS_INODE_COMPRESS) {
726  bsii.compression_type_changed = true;
728  }
729 
730  Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0);
731  if (!NT_SUCCESS(Status))
732  throw ntstatus_error(Status);
733 
734  if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
735  if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
736  fff_handle h;
737  WIN32_FIND_DATAW fff;
738  wstring qs;
739 
740  qs = fn;
741  qs += L"\\*";
742 
743  h = FindFirstFileW(qs.c_str(), &fff);
744  if (h != INVALID_HANDLE_VALUE) {
745  do {
746  wstring fn2;
747 
748  if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0)))
749  continue;
750 
751  fn2 = fn;
752  fn2 += L"\\";
753  fn2 += fff.cFileName;
754 
755  reflink_copy(hwnd, fn2.c_str(), newpath.c_str());
756  } while (FindNextFileW(h, &fff));
757  }
758  }
759 
760  // CreateDirectoryExW also copies streams, no need to do it here
761  } else {
762  if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
763  reparse_header rh;
764  uint8_t* rp;
765 
766  if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, &rh, sizeof(reparse_header), &bytesret, nullptr)) {
767  if (GetLastError() != ERROR_MORE_DATA)
768  throw last_error(GetLastError());
769  }
770 
771  size_t rplen = sizeof(reparse_header) + rh.ReparseDataLength;
772  rp = (uint8_t*)malloc(rplen);
773 
774  if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, rp, (ULONG)rplen, &bytesret, nullptr))
775  throw last_error(GetLastError());
776 
777  if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, (ULONG)rplen, nullptr, 0, &bytesret, nullptr))
778  throw last_error(GetLastError());
779 
780  free(rp);
781  } else {
782  FILE_STANDARD_INFO fsi;
783  FILE_END_OF_FILE_INFO feofi;
787  uint64_t offset, alloc_size;
788  ULONG maxdup;
789 
790  Status = NtQueryInformationFile(source, &iosb, &fsi, sizeof(FILE_STANDARD_INFO), FileStandardInformation);
791  if (!NT_SUCCESS(Status))
792  throw ntstatus_error(Status);
793 
794  if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, nullptr, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, nullptr))
795  throw last_error(GetLastError());
796 
797  if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) {
798  if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &bytesret, nullptr))
799  throw last_error(GetLastError());
800  }
801 
802  fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm;
803  fsiib.Reserved = 0;
804  fsiib.Flags = fgiib.Flags;
805  if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), nullptr, 0, &bytesret, nullptr))
806  throw last_error(GetLastError());
807 
808  feofi.EndOfFile = fsi.EndOfFile;
809  Status = NtSetInformationFile(dest, &iosb, &feofi, sizeof(FILE_END_OF_FILE_INFO), FileEndOfFileInformation);
810  if (!NT_SUCCESS(Status))
811  throw ntstatus_error(Status);
812 
813  ded.FileHandle = source;
814  maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1;
815 
816  alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes);
817 
818  offset = 0;
819  while (offset < alloc_size) {
821  ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset);
822  if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), nullptr, 0, &bytesret, nullptr))
823  throw last_error(GetLastError());
824 
825  offset += ded.ByteCount.QuadPart;
826  }
827  }
828 
829  ULONG streambufsize = 0;
830  vector<char> streambuf;
831 
832  do {
833  streambufsize += 0x1000;
834  streambuf.resize(streambufsize);
835 
836 #ifndef __REACTOS__
837  memset(streambuf.data(), 0, streambufsize);
838 
840 #else
841  memset(&streambuf[0], 0, streambufsize);
842 
844 #endif
845  } while (Status == STATUS_BUFFER_OVERFLOW);
846 
847  if (!NT_SUCCESS(Status))
848  throw ntstatus_error(Status);
849 
850 #ifndef __REACTOS__
851  auto fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(streambuf.data());
852 #else
853  auto fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(&streambuf[0]);
854 #endif
855 
856  while (true) {
857  if (fsi->StreamNameLength > 0) {
858  wstring sn = wstring(fsi->StreamName, fsi->StreamNameLength / sizeof(WCHAR));
859 
860  if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") {
862  uint8_t* data = nullptr;
863  auto stream_size = (uint16_t)fsi->StreamSize.QuadPart;
864 
865 
866  if (stream_size > 0) {
867  wstring fn2;
868 
869  fn2 = fn;
870  fn2 += sn;
871 
872  stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
873 
875  throw last_error(GetLastError());
876 
877  // We can get away with this because our streams are guaranteed to be below 64 KB -
878  // don't do this on NTFS!
880 
881  if (!ReadFile(stream, data, stream_size, &bytesret, nullptr)) {
882  free(data);
883  throw last_error(GetLastError());
884  }
885  }
886 
887  stream = CreateFileW((newpath + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, nullptr);
888 
889  if (stream == INVALID_HANDLE_VALUE) {
890  if (data) free(data);
891  throw last_error(GetLastError());
892  }
893 
894  if (data) {
895  if (!WriteFile(stream, data, stream_size, &bytesret, nullptr)) {
896  free(data);
897  throw last_error(GetLastError());
898  }
899 
900  free(data);
901  }
902  }
903  }
904 
905  if (fsi->NextEntryOffset == 0)
906  break;
907 
908  fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(reinterpret_cast<char*>(fsi) + fsi->NextEntryOffset);
909  }
910  }
911 
912  atime.dwLowDateTime = fbi.LastAccessTime.LowPart;
913  atime.dwHighDateTime = fbi.LastAccessTime.HighPart;
914  mtime.dwLowDateTime = fbi.LastWriteTime.LowPart;
915  mtime.dwHighDateTime = fbi.LastWriteTime.HighPart;
916  SetFileTime(dest, nullptr, &atime, &mtime);
917 
918  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, &bsxa, sizeof(btrfs_set_xattr));
919 
920  if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) {
921  ULONG xalen = 0;
922  btrfs_set_xattr *xa = nullptr, *xa2;
923 
924  do {
925  xalen += 1024;
926 
927  if (xa) free(xa);
928  xa = (btrfs_set_xattr*)malloc(xalen);
929 
930  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, xa, xalen);
931  } while (Status == STATUS_BUFFER_OVERFLOW);
932 
933  if (!NT_SUCCESS(Status)) {
934  free(xa);
935  throw ntstatus_error(Status);
936  }
937 
938  xa2 = xa;
939  while (xa2->valuelen > 0) {
940  Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, xa2,
941  (ULONG)(offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen), nullptr, 0);
942  if (!NT_SUCCESS(Status)) {
943  free(xa);
944  throw ntstatus_error(Status);
945  }
946  xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen];
947  }
948 
949  free(xa);
950  } else if (!NT_SUCCESS(Status))
951  throw ntstatus_error(Status);
952  } catch (...) {
953  FILE_DISPOSITION_INFO fdi;
954 
955  fdi.DeleteFile = true;
956  Status = NtSetInformationFile(dest, &iosb, &fdi, sizeof(FILE_DISPOSITION_INFO), FileDispositionInformation);
957  if (!NT_SUCCESS(Status))
958  throw ntstatus_error(Status);
959 
960  throw;
961  }
962 }
#define FSCTL_SET_SPARSE
Definition: winioctl.h:100
static short search(int val, const short *table, int size)
Definition: msg711.c:255
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
uint16_t namelen
Definition: btrfsioctl.h:239
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
NTSTATUS NTAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define FILE_ATTRIBUTE_SPARSE_FILE
Definition: ntifs_ex.h:380
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
uint8_t compression_type
Definition: btrfsioctl.h:97
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
#define free
Definition: debug_ros.c:5
LONG NTSTATUS
Definition: precomp.h:26
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
GLintptr offset
Definition: glext.h:5920
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:815
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define uint16_t
Definition: nsiface.idl:60
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
void reflink_copy(HWND hwnd, const WCHAR *fn, const WCHAR *dir)
#define FILE_SHARE_READ
Definition: compat.h:125
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
BOOL WINAPI SetFileTime(IN HANDLE hFile, CONST FILETIME *lpCreationTime OPTIONAL, CONST FILETIME *lpLastAccessTime OPTIONAL, CONST FILETIME *lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:1098
#define FILE_TRAVERSE
Definition: nt_native.h:643
DWORD dwHighDateTime
Definition: mapidefs.h:66
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FSCTL_BTRFS_CREATE_SNAPSHOT
Definition: btrfsioctl.h:9
#define BTRFS_INODE_COMPRESS
Definition: propsheet.h:87
#define GENERIC_WRITE
Definition: nt_native.h:90
#define offsetof(TYPE, MEMBER)
char ext[3]
Definition: mkdosfs.c:358
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:389
int const char int stream_size
Definition: zlib.h:813
uint64_t st_rdev
Definition: btrfsioctl.h:76
unsigned int dir
Definition: maze.c:112
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:442
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define OPEN_EXISTING
Definition: compat.h:434
USHORT ReparseDataLength
Definition: contextmenu.cpp:62
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
LARGE_INTEGER SourceFileOffset
Definition: shellext.h:200
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static bool get_volume_path_parent(const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
GLuint GLuint num
Definition: glext.h:9618
#define FSCTL_BTRFS_GET_XATTRS
Definition: btrfsioctl.h:32
uint64_t flags
Definition: btrfsioctl.h:77
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOL compression_type_changed
Definition: btrfsioctl.h:98
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
#define FSCTL_BTRFS_MKNOD
Definition: btrfsioctl.h:30
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
uint64_t inode
Definition: btrfsioctl.h:70
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GENERIC_READ
Definition: compat.h:124
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define FSCTL_BTRFS_SET_INODE_INFO
Definition: btrfsioctl.h:11
#define ERROR_MORE_DATA
Definition: dderror.h:13
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
uint64_t st_rdev
Definition: btrfsioctl.h:238
uint8_t type
Definition: btrfsioctl.h:237
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
UINT64 uint64_t
Definition: types.h:77
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
#define FSCTL_BTRFS_GET_INODE_INFO
Definition: btrfsioctl.h:10
BOOL WINAPI CreateDirectoryExW(IN LPCWSTR lpTemplateDirectory, IN LPCWSTR lpNewDirectory, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:193
LARGE_INTEGER TargetFileOffset
Definition: shellext.h:201
#define IDS_CANT_REFLINK_DIFFERENT_FS
Definition: resource.h:202
#define FileStandardInformation
Definition: propsheet.cpp:61
#define CreateFileW
Definition: compat.h:408
#define FSCTL_GET_INTEGRITY_INFORMATION
Definition: shellext.h:221
uint64_t inode
Definition: btrfsioctl.h:236
Definition: name.c:36
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
WCHAR name[1]
Definition: btrfsioctl.h:240
uint8_t compression_type
Definition: btrfsioctl.h:82
#define FSCTL_BTRFS_SET_XATTR
Definition: btrfsioctl.h:33
unsigned int ULONG
Definition: retypes.h:1
basic_streambuf< char, char_traits< char > > streambuf
Definition: _iosfwd.h:123
#define malloc
Definition: debug_ros.c:4
static char * dest
Definition: rtl.c:135
#define FSCTL_SET_INTEGRITY_INFORMATION
Definition: shellext.h:222
#define CREATE_NEW
Definition: disk.h:69
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:98
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define ss
Definition: i386-dis.c:432
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define memset(x, y, z)
Definition: compat.h:39
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
LARGE_INTEGER ByteCount
Definition: shellext.h:202
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD dwLowDateTime
Definition: mapidefs.h:65
#define DELETE
Definition: nt_native.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
#define FSCTL_DUPLICATE_EXTENTS_TO_FILE
Definition: shellext.h:205
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by InvokeCommand().

◆ Release()

ULONG __stdcall BtrfsContextMenu::Release ( void  )
inline

Implements IUnknown.

Definition at line 55 of file contextmenu.h.

55  {
57 
58  if (rc == 0)
59  delete this;
60 
61  return rc;
62  }
long LONG
Definition: pedump.c:60
#define InterlockedDecrement
Definition: armddk.h:52

Member Data Documentation

◆ allow_snapshot

bool BtrfsContextMenu::allow_snapshot
private

Definition at line 76 of file contextmenu.h.

Referenced by BtrfsContextMenu(), Initialize(), InvokeCommand(), and QueryContextMenu().

◆ bg

bool BtrfsContextMenu::bg
private

Definition at line 77 of file contextmenu.h.

Referenced by GetCommandString(), Initialize(), InvokeCommand(), and QueryContextMenu().

◆ ignore

bool BtrfsContextMenu::ignore
private

◆ path

wstring BtrfsContextMenu::path
private

Definition at line 78 of file contextmenu.h.

Referenced by InvokeCommand().

◆ refcount

LONG BtrfsContextMenu::refcount
private

Definition at line 75 of file contextmenu.h.

Referenced by AddRef(), BtrfsContextMenu(), and Release().

◆ stgm

STGMEDIUM BtrfsContextMenu::stgm
private

Definition at line 79 of file contextmenu.h.

Referenced by Initialize(), InvokeCommand(), and ~BtrfsContextMenu().

◆ stgm_set

bool BtrfsContextMenu::stgm_set
private

Definition at line 80 of file contextmenu.h.

Referenced by BtrfsContextMenu(), Initialize(), InvokeCommand(), and ~BtrfsContextMenu().

◆ uacicon

HBITMAP BtrfsContextMenu::uacicon
private

Definition at line 81 of file contextmenu.h.

Referenced by BtrfsContextMenu(), get_uac_icon(), QueryContextMenu(), and ~BtrfsContextMenu().


The documentation for this class was generated from the following files: