ReactOS  0.4.15-dev-439-g292f67a
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:438
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
LONG cx
Definition: windef.h:334
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:78
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: xxhash.c:193
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:838
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:335
#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 1169 of file contextmenu.cpp.

1169  {
1170  if (ignore)
1171  return E_INVALIDARG;
1172 
1173  if (idCmd != 0)
1174  return E_INVALIDARG;
1175 
1176  if (!bg) {
1177  if (idCmd == 0) {
1178  switch (uFlags) {
1179  case GCS_HELPTEXTA:
1181  return S_OK;
1182  else
1183  return E_FAIL;
1184 
1185  case GCS_HELPTEXTW:
1187  return S_OK;
1188  else
1189  return E_FAIL;
1190 
1191  case GCS_VALIDATEA:
1192  case GCS_VALIDATEW:
1193  return S_OK;
1194 
1195  case GCS_VERBA:
1196  return StringCchCopyA(pszName, cchMax, SNAPSHOT_VERBA);
1197 
1198  case GCS_VERBW:
1200 
1201  default:
1202  return E_INVALIDARG;
1203  }
1204  } else if (idCmd == 1) {
1205  switch (uFlags) {
1206  case GCS_HELPTEXTA:
1208  return S_OK;
1209  else
1210  return E_FAIL;
1211 
1212  case GCS_HELPTEXTW:
1214  return S_OK;
1215  else
1216  return E_FAIL;
1217 
1218  case GCS_VALIDATEA:
1219  case GCS_VALIDATEW:
1220  return S_OK;
1221 
1222  case GCS_VERBA:
1223  return StringCchCopyA(pszName, cchMax, SEND_VERBA);
1224 
1225  case GCS_VERBW:
1226  return StringCchCopyW((STRSAFE_LPWSTR)pszName, cchMax, SEND_VERBW);
1227 
1228  default:
1229  return E_INVALIDARG;
1230  }
1231  } else
1232  return E_INVALIDARG;
1233  } else {
1234  if (idCmd == 0) {
1235  switch (uFlags) {
1236  case GCS_HELPTEXTA:
1238  return S_OK;
1239  else
1240  return E_FAIL;
1241 
1242  case GCS_HELPTEXTW:
1244  return S_OK;
1245  else
1246  return E_FAIL;
1247 
1248  case GCS_VALIDATEA:
1249  case GCS_VALIDATEW:
1250  return S_OK;
1251 
1252  case GCS_VERBA:
1253  return StringCchCopyA(pszName, cchMax, NEW_SUBVOL_VERBA);
1254 
1255  case GCS_VERBW:
1257 
1258  default:
1259  return E_INVALIDARG;
1260  }
1261  } else if (idCmd == 1) {
1262  switch (uFlags) {
1263  case GCS_HELPTEXTA:
1265  return S_OK;
1266  else
1267  return E_FAIL;
1268 
1269  case GCS_HELPTEXTW:
1271  return S_OK;
1272  else
1273  return E_FAIL;
1274 
1275  case GCS_VALIDATEA:
1276  case GCS_VALIDATEW:
1277  return S_OK;
1278 
1279  case GCS_VERBA:
1280  return StringCchCopyA(pszName, cchMax, RECV_VERBA);
1281 
1282  case GCS_VERBW:
1283  return StringCchCopyW((STRSAFE_LPWSTR)pszName, cchMax, RECV_VERBW);
1284 
1285  default:
1286  return E_INVALIDARG;
1287  }
1288  } else if (idCmd == 2) {
1289  switch (uFlags) {
1290  case GCS_HELPTEXTA:
1292  return S_OK;
1293  else
1294  return E_FAIL;
1295 
1296  case GCS_HELPTEXTW:
1298  return S_OK;
1299  else
1300  return E_FAIL;
1301 
1302  case GCS_VALIDATEA:
1303  case GCS_VALIDATEW:
1304  return S_OK;
1305 
1306  case GCS_VERBA:
1307  return StringCchCopyA(pszName, cchMax, REFLINK_VERBA);
1308 
1309  case GCS_VERBW:
1311 
1312  default:
1313  return E_INVALIDARG;
1314  }
1315  } else
1316  return E_INVALIDARG;
1317  }
1318 }
#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:177
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:1288
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
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:435
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
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define CreateFileW
Definition: compat.h:409
#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 954 of file contextmenu.cpp.

954  {
956 
957  try {
958  if (ignore)
959  return E_INVALIDARG;
960 
961  if (!bg) {
962  if ((IS_INTRESOURCE(pici->lpVerb) && allow_snapshot && pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SNAPSHOT_VERBA))) {
963  UINT num_files, i;
964  WCHAR fn[MAX_PATH];
965 
966  if (!stgm_set)
967  return E_FAIL;
968 
969  num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
970 
971  if (num_files == 0)
972  return E_FAIL;
973 
974  for (i = 0; i < num_files; i++) {
975  if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) {
976  create_snapshot(pici->hwnd, fn);
977  }
978  }
979 
980  return S_OK;
981  } else if ((IS_INTRESOURCE(pici->lpVerb) && ((allow_snapshot && (ULONG_PTR)pici->lpVerb == 1) || (!allow_snapshot && (ULONG_PTR)pici->lpVerb == 0))) ||
982  (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, SEND_VERBA))) {
983  UINT num_files, i;
985  wstring t;
986  SHELLEXECUTEINFOW sei;
987 
988  GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR));
989 
990  if (!stgm_set)
991  return E_FAIL;
992 
993  num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, nullptr, 0);
994 
995  if (num_files == 0)
996  return E_FAIL;
997 
998  for (i = 0; i < num_files; i++) {
999  if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(WCHAR))) {
1000  t = L"\"";
1001  t += dll;
1002  t += L"\",SendSubvolGUI ";
1003  t += fn;
1004 
1005  RtlZeroMemory(&sei, sizeof(sei));
1006 
1007  sei.cbSize = sizeof(sei);
1008  sei.hwnd = pici->hwnd;
1009  sei.lpVerb = L"runas";
1010  sei.lpFile = L"rundll32.exe";
1011  sei.lpParameters = t.c_str();
1012  sei.nShow = SW_SHOW;
1014 
1015  if (!ShellExecuteExW(&sei))
1016  throw last_error(GetLastError());
1017 
1019  CloseHandle(sei.hProcess);
1020  }
1021  }
1022 
1023  return S_OK;
1024  }
1025  } else {
1026  if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 0) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, NEW_SUBVOL_VERBA))) {
1027  win_handle h;
1029  NTSTATUS Status;
1030  wstring name, nameorig, searchpath;
1031  btrfs_create_subvol* bcs;
1032  WIN32_FIND_DATAW wfd;
1033 
1035  throw last_error(GetLastError());
1036 
1038 
1039  if (h == INVALID_HANDLE_VALUE)
1040  throw last_error(GetLastError());
1041 
1042  searchpath = path + L"\\" + name;
1043  nameorig = name;
1044 
1045  {
1046  fff_handle fff = FindFirstFileW(searchpath.c_str(), &wfd);
1047 
1048  if (fff != INVALID_HANDLE_VALUE) {
1049  ULONG num = 2;
1050 
1051  do {
1052 #ifndef __REACTOS__
1053  name = nameorig + L" (" + to_wstring(num) + L")";
1054 #else
1055  {
1056  WCHAR buffer[32];
1057 
1058  swprintf(buffer, L"%d", num);
1059  name = nameorig + L" (" + buffer + L")";
1060  }
1061 #endif
1062  searchpath = path + L"\\" + name;
1063 
1064  fff = FindFirstFileW(searchpath.c_str(), &wfd);
1065  num++;
1066  } while (fff != INVALID_HANDLE_VALUE);
1067  }
1068  }
1069 
1070  size_t bcslen = offsetof(btrfs_create_subvol, name[0]) + (name.length() * sizeof(WCHAR));
1071  bcs = (btrfs_create_subvol*)malloc(bcslen);
1072 
1073  bcs->readonly = false;
1074  bcs->posix = false;
1075  bcs->namelen = (uint16_t)(name.length() * sizeof(WCHAR));
1076  memcpy(bcs->name, name.c_str(), name.length() * sizeof(WCHAR));
1077 
1078  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, bcs, (ULONG)bcslen, nullptr, 0);
1079 
1080  free(bcs);
1081 
1082  if (!NT_SUCCESS(Status))
1083  throw ntstatus_error(Status);
1084 
1085  return S_OK;
1086  } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 1) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, RECV_VERBA))) {
1087  WCHAR dll[MAX_PATH];
1088  wstring t;
1089  SHELLEXECUTEINFOW sei;
1090 
1091  GetModuleFileNameW(module, dll, sizeof(dll) / sizeof(WCHAR));
1092 
1093  t = L"\"";
1094  t += dll;
1095  t += L"\",RecvSubvolGUI ";
1096  t += path;
1097 
1098  RtlZeroMemory(&sei, sizeof(sei));
1099 
1100  sei.cbSize = sizeof(sei);
1101  sei.hwnd = pici->hwnd;
1102  sei.lpVerb = L"runas";
1103  sei.lpFile = L"rundll32.exe";
1104  sei.lpParameters = t.c_str();
1105  sei.nShow = SW_SHOW;
1107 
1108  if (!ShellExecuteExW(&sei))
1109  throw last_error(GetLastError());
1110 
1112  CloseHandle(sei.hProcess);
1113 
1114  return S_OK;
1115  } else if ((IS_INTRESOURCE(pici->lpVerb) && (ULONG_PTR)pici->lpVerb == 2) || (!IS_INTRESOURCE(pici->lpVerb) && !strcmp(pici->lpVerb, REFLINK_VERBA))) {
1116  HDROP hdrop;
1117 
1119  return S_OK;
1120 
1121  if (!OpenClipboard(pici->hwnd))
1122  throw last_error(GetLastError());
1123 
1124  try {
1125  hdrop = (HDROP)GetClipboardData(CF_HDROP);
1126 
1127  if (hdrop) {
1128  HANDLE lh;
1129 
1130  lh = GlobalLock(hdrop);
1131 
1132  if (lh) {
1133  try {
1134  ULONG num_files, i;
1135  WCHAR fn[MAX_PATH];
1136 
1137  num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, nullptr, 0);
1138 
1139  for (i = 0; i < num_files; i++) {
1140  if (DragQueryFileW(hdrop, i, fn, sizeof(fn) / sizeof(WCHAR))) {
1141  reflink_copy(pici->hwnd, fn, pici->lpDirectoryW);
1142  }
1143  }
1144  } catch (...) {
1145  GlobalUnlock(lh);
1146  throw;
1147  }
1148 
1149  GlobalUnlock(lh);
1150  }
1151  }
1152  } catch (...) {
1153  CloseClipboard();
1154  throw;
1155  }
1156 
1157  CloseClipboard();
1158 
1159  return S_OK;
1160  }
1161  }
1162  } catch (const exception& e) {
1163  error_message(pici->hwnd, e.what());
1164  }
1165 
1166  return E_FAIL;
1167 }
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define CloseHandle
Definition: compat.h:407
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:400
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:64
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:2263
#define SW_SHOW
Definition: winuser.h:769
#define OPEN_EXISTING
Definition: compat.h:435
#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
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:409
Definition: name.c:38
#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:3244
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:176
#define MIIM_STRING
Definition: winuser.h:722
#define S_OK
Definition: intsafe.h:59
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  memset(streambuf.data(), 0, streambufsize);
837 
839  } while (Status == STATUS_BUFFER_OVERFLOW);
840 
841  if (!NT_SUCCESS(Status))
842  throw ntstatus_error(Status);
843 
844  auto fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(streambuf.data());
845 
846  while (true) {
847  if (fsi->StreamNameLength > 0) {
848  wstring sn = wstring(fsi->StreamName, fsi->StreamNameLength / sizeof(WCHAR));
849 
850  if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") {
852  uint8_t* data = nullptr;
853  auto stream_size = (uint16_t)fsi->StreamSize.QuadPart;
854 
855 
856  if (stream_size > 0) {
857  wstring fn2;
858 
859  fn2 = fn;
860  fn2 += sn;
861 
862  stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
863 
865  throw last_error(GetLastError());
866 
867  // We can get away with this because our streams are guaranteed to be below 64 KB -
868  // don't do this on NTFS!
870 
871  if (!ReadFile(stream, data, stream_size, &bytesret, nullptr)) {
872  free(data);
873  throw last_error(GetLastError());
874  }
875  }
876 
877  stream = CreateFileW((newpath + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, nullptr);
878 
879  if (stream == INVALID_HANDLE_VALUE) {
880  if (data) free(data);
881  throw last_error(GetLastError());
882  }
883 
884  if (data) {
885  if (!WriteFile(stream, data, stream_size, &bytesret, nullptr)) {
886  free(data);
887  throw last_error(GetLastError());
888  }
889 
890  free(data);
891  }
892  }
893  }
894 
895  if (fsi->NextEntryOffset == 0)
896  break;
897 
898  fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(reinterpret_cast<char*>(fsi) + fsi->NextEntryOffset);
899  }
900  }
901 
902  atime.dwLowDateTime = fbi.LastAccessTime.LowPart;
903  atime.dwHighDateTime = fbi.LastAccessTime.HighPart;
904  mtime.dwLowDateTime = fbi.LastWriteTime.LowPart;
905  mtime.dwHighDateTime = fbi.LastWriteTime.HighPart;
906  SetFileTime(dest, nullptr, &atime, &mtime);
907 
908  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, &bsxa, sizeof(btrfs_set_xattr));
909 
910  if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) {
911  ULONG xalen = 0;
912  btrfs_set_xattr *xa = nullptr, *xa2;
913 
914  do {
915  xalen += 1024;
916 
917  if (xa) free(xa);
918  xa = (btrfs_set_xattr*)malloc(xalen);
919 
920  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, xa, xalen);
921  } while (Status == STATUS_BUFFER_OVERFLOW);
922 
923  if (!NT_SUCCESS(Status)) {
924  free(xa);
925  throw ntstatus_error(Status);
926  }
927 
928  xa2 = xa;
929  while (xa2->valuelen > 0) {
930  Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, xa2,
931  (ULONG)(offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen), nullptr, 0);
932  if (!NT_SUCCESS(Status)) {
933  free(xa);
934  throw ntstatus_error(Status);
935  }
936  xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen];
937  }
938 
939  free(xa);
940  } else if (!NT_SUCCESS(Status))
941  throw ntstatus_error(Status);
942  } catch (...) {
943  FILE_DISPOSITION_INFO fdi;
944 
945  fdi.DeleteFile = true;
946  Status = NtSetInformationFile(dest, &iosb, &fdi, sizeof(FILE_DISPOSITION_INFO), FileDispositionInformation);
947  if (!NT_SUCCESS(Status))
948  throw ntstatus_error(Status);
949 
950  throw;
951  }
952 }
#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:400
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:435
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:204
#define FileStandardInformation
Definition: propsheet.cpp:61
#define CreateFileW
Definition: compat.h:409
#define FSCTL_GET_INTEGRITY_INFORMATION
Definition: shellext.h:221
uint64_t inode
Definition: btrfsioctl.h:236
Definition: name.c:38
#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:113
#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: