ReactOS  0.4.14-dev-583-g2a1ba2c
contextmenu.cpp File Reference
#include "shellext.h"
#include <windows.h>
#include <strsafe.h>
#include <stddef.h>
#include <winternl.h>
#include <wincodec.h>
#include <sstream>
#include <iostream>
#include <shlwapi.h>
#include "contextmenu.h"
#include "resource.h"
#include "../btrfsioctl.h"
Include dependency graph for contextmenu.cpp:

Go to the source code of this file.

Classes

struct  reparse_header
 

Macros

#define NO_SHLWAPI_STRFCNS
 
#define NEW_SUBVOL_VERBA   "newsubvol"
 
#define NEW_SUBVOL_VERBW   L"newsubvol"
 
#define SNAPSHOT_VERBA   "snapshot"
 
#define SNAPSHOT_VERBW   L"snapshot"
 
#define REFLINK_VERBA   "reflink"
 
#define REFLINK_VERBW   L"reflink"
 
#define RECV_VERBA   "recvsubvol"
 
#define RECV_VERBW   L"recvsubvol"
 
#define SEND_VERBA   "sendsubvol"
 
#define SEND_VERBW   L"sendsubvol"
 

Functions

static void path_remove_file (wstring &path)
 
static bool get_volume_path_parent (const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
 
static bool show_reflink_paste (const wstring &path)
 
static void InitBitmapInfo (BITMAPINFO *pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp)
 
static HRESULT Create32BitHBITMAP (HDC hdc, const SIZE *psize, void **ppvBits, HBITMAP *phBmp)
 
static void path_strip_path (wstring &path)
 
static void create_snapshot (HWND hwnd, const wstring &fn)
 
static uint64_t __inline sector_align (uint64_t n, uint64_t a)
 
static void reflink_copy2 (const wstring &srcfn, const wstring &destdir, const wstring &destname)
 
void CALLBACK ReflinkCopyW (HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
 

Macro Definition Documentation

◆ NEW_SUBVOL_VERBA

#define NEW_SUBVOL_VERBA   "newsubvol"

Definition at line 49 of file contextmenu.cpp.

◆ NEW_SUBVOL_VERBW

#define NEW_SUBVOL_VERBW   L"newsubvol"

Definition at line 50 of file contextmenu.cpp.

◆ NO_SHLWAPI_STRFCNS

#define NO_SHLWAPI_STRFCNS

Definition at line 38 of file contextmenu.cpp.

◆ RECV_VERBA

#define RECV_VERBA   "recvsubvol"

Definition at line 55 of file contextmenu.cpp.

◆ RECV_VERBW

#define RECV_VERBW   L"recvsubvol"

Definition at line 56 of file contextmenu.cpp.

◆ REFLINK_VERBA

#define REFLINK_VERBA   "reflink"

Definition at line 53 of file contextmenu.cpp.

◆ REFLINK_VERBW

#define REFLINK_VERBW   L"reflink"

Definition at line 54 of file contextmenu.cpp.

◆ SEND_VERBA

#define SEND_VERBA   "sendsubvol"

Definition at line 57 of file contextmenu.cpp.

◆ SEND_VERBW

#define SEND_VERBW   L"sendsubvol"

Definition at line 58 of file contextmenu.cpp.

◆ SNAPSHOT_VERBA

#define SNAPSHOT_VERBA   "snapshot"

Definition at line 51 of file contextmenu.cpp.

◆ SNAPSHOT_VERBW

#define SNAPSHOT_VERBW   L"snapshot"

Definition at line 52 of file contextmenu.cpp.

Function Documentation

◆ Create32BitHBITMAP()

static HRESULT Create32BitHBITMAP ( HDC  hdc,
const SIZE psize,
void **  ppvBits,
HBITMAP phBmp 
)
static

Definition at line 275 of file contextmenu.cpp.

275  {
276  BITMAPINFO bmi;
277  HDC hdcUsed;
278 
279  *phBmp = nullptr;
280 
281  InitBitmapInfo(&bmi, sizeof(bmi), psize->cx, psize->cy, 32);
282 
283  hdcUsed = hdc ? hdc : GetDC(nullptr);
284 
285  if (hdcUsed) {
286  *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, nullptr, 0);
287  if (hdc != hdcUsed)
288  ReleaseDC(nullptr, hdcUsed);
289  }
290 
291  return !*phBmp ? E_OUTOFMEMORY : S_OK;
292 }
_Must_inspect_result_ _Out_ LPSIZE psize
Definition: ntgdi.h:1569
HDC WINAPI GetDC(_In_opt_ HWND)
static HDC
Definition: imagelist.c:92
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
LONG cx
Definition: windef.h:334
HDC hdc
Definition: main.c:9
#define S_OK
Definition: intsafe.h:59
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:197
static void InitBitmapInfo(BITMAPINFO *pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp)
#define DIB_RGB_COLORS
Definition: wingdi.h:366
LONG cy
Definition: windef.h:335

Referenced by BtrfsContextMenu::get_uac_icon().

◆ create_snapshot()

static void create_snapshot ( HWND  hwnd,
const wstring &  fn 
)
static

Definition at line 451 of file contextmenu.cpp.

451  {
452  win_handle h;
455  btrfs_get_file_ids bgfi;
456 
458 
459  if (h != INVALID_HANDLE_VALUE) {
460  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_FILE_IDS, nullptr, 0, &bgfi, sizeof(btrfs_get_file_ids));
461 
462  if (NT_SUCCESS(Status) && bgfi.inode == 0x100 && !bgfi.top) {
463  wstring subvolname, parpath, searchpath, temp1, name, nameorig;
464  win_handle h2;
465  WIN32_FIND_DATAW wfd;
467 
468  parpath = fn;
469  path_remove_file(parpath);
470 
471  subvolname = fn;
472  path_strip_path(subvolname);
473 
475 
476  if (h2 == INVALID_HANDLE_VALUE)
477  throw last_error(GetLastError());
478 
480  throw last_error(GetLastError());
481 
482  GetLocalTime(&time);
483 
484  wstring_sprintf(name, temp1, subvolname.c_str(), time.wYear, time.wMonth, time.wDay);
485  nameorig = name;
486 
487  searchpath = parpath + L"\\" + name;
488 
489  fff_handle fff = FindFirstFileW(searchpath.c_str(), &wfd);
490 
491  if (fff != INVALID_HANDLE_VALUE) {
492  ULONG num = 2;
493 
494  do {
495 #ifndef __REACTOS__
496  name = nameorig + L" (" + to_wstring(num) + L")";
497 #else
498  {
499  WCHAR buffer[32];
500 
501  swprintf(buffer, L"%d", num);
502  name = nameorig + L" (" + buffer + L")";
503  }
504 #endif
505  searchpath = parpath + L"\\" + name;
506 
507  fff = FindFirstFileW(searchpath.c_str(), &wfd);
508  num++;
509  } while (fff != INVALID_HANDLE_VALUE);
510  }
511 
512  size_t namelen = name.length() * sizeof(WCHAR);
513 
514  auto bcs = (btrfs_create_snapshot*)malloc(sizeof(btrfs_create_snapshot) - 1 + namelen);
515  bcs->readonly = false;
516  bcs->posix = false;
517  bcs->subvol = h;
518  bcs->namelen = (uint16_t)namelen;
519  memcpy(bcs->name, name.c_str(), namelen);
520 
521  Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs,
522  (ULONG)(sizeof(btrfs_create_snapshot) - 1 + namelen), nullptr, 0);
523 
524  if (!NT_SUCCESS(Status))
525  throw ntstatus_error(Status);
526  }
527  } else
528  throw last_error(GetLastError());
529 }
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define IDS_SNAPSHOT_FILENAME
Definition: resource.h:14
LONG NTSTATUS
Definition: precomp.h:26
#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)
__u16 time
Definition: mkdosfs.c:366
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define uint16_t
Definition: nsiface.idl:60
GLint namelen
Definition: glext.h:7232
#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
#define FSCTL_BTRFS_CREATE_SNAPSHOT
Definition: btrfsioctl.h:9
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
#define OPEN_EXISTING
Definition: compat.h:434
void wstring_sprintf(wstring &s, wstring fmt,...)
Definition: main.cpp:225
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf(buf, format,...)
Definition: sprintf.c:56
GLuint GLuint num
Definition: glext.h:9618
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define FSCTL_BTRFS_GET_FILE_IDS
Definition: btrfsioctl.h:7
Status
Definition: gdiplustypes.h:24
static void path_remove_file(wstring &path)
static void path_strip_path(wstring &path)
static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
Definition: muireg.c:10
#define CreateFileW
Definition: compat.h:408
Definition: name.c:38
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
unsigned int ULONG
Definition: retypes.h:1
#define malloc
Definition: debug_ros.c:4
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 BtrfsContextMenu::InvokeCommand().

◆ get_volume_path_parent()

static bool get_volume_path_parent ( const WCHAR fn,
WCHAR volpath,
ULONG  volpathlen 
)
static

Definition at line 185 of file contextmenu.cpp.

185  {
186  WCHAR *f, *p;
187  bool b;
188 
190 
191  if (f == fn)
192  return GetVolumePathNameW(fn, volpath, volpathlen);
193 
194  p = (WCHAR*)malloc((f - fn + 1) * sizeof(WCHAR));
195  memcpy(p, fn, (f - fn) * sizeof(WCHAR));
196  p[f - fn] = 0;
197 
198  b = GetVolumePathNameW(p, volpath, volpathlen);
199 
200  free(p);
201 
202  return b;
203 }
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define free
Definition: debug_ros.c:5
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:815
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:389
#define b
Definition: ke_i.h:79
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define f
Definition: ke_i.h:83
#define malloc
Definition: debug_ros.c:4
GLfloat GLfloat p
Definition: glext.h:8902

Referenced by BtrfsContextMenu::reflink_copy(), ReflinkCopyW(), and show_reflink_paste().

◆ InitBitmapInfo()

static void InitBitmapInfo ( BITMAPINFO pbmi,
ULONG  cbInfo,
LONG  cx,
LONG  cy,
WORD  bpp 
)
static

Definition at line 264 of file contextmenu.cpp.

264  {
265  ZeroMemory(pbmi, cbInfo);
267  pbmi->bmiHeader.biPlanes = 1;
269 
273 }
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1475
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
#define ZeroMemory
Definition: winbase.h:1642
DWORD biCompression
Definition: amvideo.idl:35
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
_Out_opt_ int * cx
Definition: commctrl.h:581
DWORD bpp
Definition: surface.c:181
#define BI_RGB
Definition: precomp.h:34

Referenced by Create32BitHBITMAP().

◆ path_remove_file()

static void path_remove_file ( wstring &  path)
static

Definition at line 426 of file contextmenu.cpp.

426  {
427  size_t bs = path.rfind(L"\\");
428 
429  if (bs == string::npos)
430  return;
431 
432  if (bs == path.find(L"\\")) { // only one backslash
433  path = path.substr(0, bs + 1);
434  return;
435  }
436 
437  path = path.substr(0, bs);
438 }
static const size_t npos
Definition: _string_npos.h:26
static const WCHAR L[]
Definition: oid.c:1250
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539

Referenced by create_snapshot(), and BtrfsContextMenu::Initialize().

◆ path_strip_path()

static void path_strip_path ( wstring &  path)
static

Definition at line 440 of file contextmenu.cpp.

440  {
441  size_t bs = path.rfind(L"\\");
442 
443  if (bs == string::npos) {
444  path = L"";
445  return;
446  }
447 
448  path = path.substr(bs + 1);
449 }
static const size_t npos
Definition: _string_npos.h:26
static const WCHAR L[]
Definition: oid.c:1250
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539

Referenced by create_snapshot().

◆ reflink_copy2()

static void reflink_copy2 ( const wstring &  srcfn,
const wstring &  destdir,
const wstring &  destname 
)
static

Definition at line 1320 of file contextmenu.cpp.

1320  {
1322  FILE_BASIC_INFO fbi;
1323  FILETIME atime, mtime;
1324  btrfs_inode_info bii;
1325  btrfs_set_inode_info bsii;
1326  ULONG bytesret;
1327  NTSTATUS Status;
1329  btrfs_set_xattr bsxa;
1330 
1333  throw last_error(GetLastError());
1334 
1335  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_INODE_INFO, nullptr, 0, &bii, sizeof(btrfs_inode_info));
1336  if (!NT_SUCCESS(Status))
1337  throw ntstatus_error(Status);
1338 
1339  // if subvol, do snapshot instead
1340  if (bii.inode == SUBVOL_ROOT_INODE) {
1341  btrfs_create_snapshot* bcs;
1342  win_handle dirh;
1343 
1345  if (dirh == INVALID_HANDLE_VALUE)
1346  throw last_error(GetLastError());
1347 
1348  size_t bcslen = offsetof(btrfs_create_snapshot, name[0]) + (destname.length() * sizeof(WCHAR));
1349  bcs = (btrfs_create_snapshot*)malloc(bcslen);
1350  bcs->subvol = source;
1351  bcs->namelen = (uint16_t)(destname.length() * sizeof(WCHAR));
1352  memcpy(bcs->name, destname.c_str(), destname.length() * sizeof(WCHAR));
1353 
1354  Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, (ULONG)bcslen, nullptr, 0);
1355  if (!NT_SUCCESS(Status)) {
1356  free(bcs);
1357  throw ntstatus_error(Status);
1358  }
1359 
1360  free(bcs);
1361 
1362  return;
1363  }
1364 
1365  Status = NtQueryInformationFile(source, &iosb, &fbi, sizeof(FILE_BASIC_INFO), FileBasicInformation);
1366  if (!NT_SUCCESS(Status))
1367  throw ntstatus_error(Status);
1368 
1369  if (bii.type == BTRFS_TYPE_CHARDEV || bii.type == BTRFS_TYPE_BLOCKDEV || bii.type == BTRFS_TYPE_FIFO || bii.type == BTRFS_TYPE_SOCKET) {
1370  win_handle dirh;
1371  btrfs_mknod* bmn;
1372 
1374  if (dirh == INVALID_HANDLE_VALUE)
1375  throw last_error(GetLastError());
1376 
1377  size_t bmnsize = offsetof(btrfs_mknod, name[0]) + (destname.length() * sizeof(WCHAR));
1378  bmn = (btrfs_mknod*)malloc(bmnsize);
1379 
1380  bmn->inode = 0;
1381  bmn->type = bii.type;
1382  bmn->st_rdev = bii.st_rdev;
1383  bmn->namelen = (uint16_t)(destname.length() * sizeof(WCHAR));
1384  memcpy(bmn->name, destname.c_str(), bmn->namelen);
1385 
1386  Status = NtFsControlFile(dirh, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_MKNOD, bmn, (ULONG)bmnsize, nullptr, 0);
1387  if (!NT_SUCCESS(Status)) {
1388  free(bmn);
1389  throw ntstatus_error(Status);
1390  }
1391 
1392  free(bmn);
1393 
1394  dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
1395  } else if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1396  if (CreateDirectoryExW(srcfn.c_str(), (destdir + destname).c_str(), nullptr))
1398  nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
1399  else
1401  } else
1402  dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, source);
1403 
1404  if (dest == INVALID_HANDLE_VALUE)
1405  throw last_error(GetLastError());
1406 
1407  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
1408 
1409  bsii.flags_changed = true;
1410  bsii.flags = bii.flags;
1411 
1412  if (bii.flags & BTRFS_INODE_COMPRESS) {
1413  bsii.compression_type_changed = true;
1415  }
1416 
1417  try {
1418  Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0);
1419  if (!NT_SUCCESS(Status))
1420  throw ntstatus_error(Status);
1421 
1422  if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1423  if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1424  WIN32_FIND_DATAW fff;
1425  wstring qs;
1426 
1427  qs = srcfn;
1428  qs += L"\\*";
1429 
1430  fff_handle h = FindFirstFileW(qs.c_str(), &fff);
1431  if (h != INVALID_HANDLE_VALUE) {
1432  do {
1433  wstring fn2;
1434 
1435  if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0)))
1436  continue;
1437 
1438  fn2 = srcfn;
1439  fn2 += L"\\";
1440  fn2 += fff.cFileName;
1441 
1442  reflink_copy2(fn2, destdir + destname + L"\\", fff.cFileName);
1443  } while (FindNextFileW(h, &fff));
1444  }
1445  }
1446 
1447  // CreateDirectoryExW also copies streams, no need to do it here
1448  } else {
1449  if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1450  reparse_header rh;
1451  uint8_t* rp;
1452 
1453  if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, &rh, sizeof(reparse_header), &bytesret, nullptr)) {
1454  if (GetLastError() != ERROR_MORE_DATA)
1455  throw last_error(GetLastError());
1456  }
1457 
1458  size_t rplen = sizeof(reparse_header) + rh.ReparseDataLength;
1459  rp = (uint8_t*)malloc(rplen);
1460 
1461  try {
1462  if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, nullptr, 0, rp, (DWORD)rplen, &bytesret, nullptr))
1463  throw last_error(GetLastError());
1464 
1465  if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, (DWORD)rplen, nullptr, 0, &bytesret, nullptr))
1466  throw last_error(GetLastError());
1467  } catch (...) {
1468  free(rp);
1469  throw;
1470  }
1471 
1472  free(rp);
1473  } else {
1474  FILE_STANDARD_INFO fsi;
1475  FILE_END_OF_FILE_INFO feofi;
1479  uint64_t offset, alloc_size;
1480  ULONG maxdup;
1481 
1482  Status = NtQueryInformationFile(source, &iosb, &fsi, sizeof(FILE_STANDARD_INFO), FileStandardInformation);
1483  if (!NT_SUCCESS(Status))
1484  throw ntstatus_error(Status);
1485 
1486  if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, nullptr, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, nullptr))
1487  throw last_error(GetLastError());
1488 
1489  if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) {
1490  if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &bytesret, nullptr))
1491  throw last_error(GetLastError());
1492  }
1493 
1494  fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm;
1495  fsiib.Reserved = 0;
1496  fsiib.Flags = fgiib.Flags;
1497  if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), nullptr, 0, &bytesret, nullptr))
1498  throw last_error(GetLastError());
1499 
1500  feofi.EndOfFile = fsi.EndOfFile;
1501  Status = NtSetInformationFile(dest, &iosb, &feofi, sizeof(FILE_END_OF_FILE_INFO), FileEndOfFileInformation);
1502  if (!NT_SUCCESS(Status))
1503  throw ntstatus_error(Status);
1504 
1505  ded.FileHandle = source;
1506  maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1;
1507 
1508  alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes);
1509 
1510  offset = 0;
1511  while (offset < alloc_size) {
1513  ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset);
1514  if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), nullptr, 0, &bytesret, nullptr))
1515  throw last_error(GetLastError());
1516 
1517  offset += ded.ByteCount.QuadPart;
1518  }
1519  }
1520 
1521  ULONG streambufsize = 0;
1522  vector<char> streambuf;
1523 
1524  do {
1525  streambufsize += 0x1000;
1526  streambuf.resize(streambufsize);
1527 
1528  memset(streambuf.data(), 0, streambufsize);
1529 
1531  } while (Status == STATUS_BUFFER_OVERFLOW);
1532 
1533  if (!NT_SUCCESS(Status))
1534  throw ntstatus_error(Status);
1535 
1536  auto fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(streambuf.data());
1537 
1538  while (true) {
1539  if (fsi->StreamNameLength > 0) {
1540  wstring sn = wstring(fsi->StreamName, fsi->StreamNameLength / sizeof(WCHAR));
1541 
1542  if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") {
1544  uint8_t* data = nullptr;
1545  auto stream_size = (uint16_t)fsi->StreamSize.QuadPart;
1546 
1547  if (stream_size > 0) {
1548  wstring fn2;
1549 
1550  fn2 = srcfn;
1551  fn2 += sn;
1552 
1553  stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
1554 
1556  throw last_error(GetLastError());
1557 
1558  // We can get away with this because our streams are guaranteed to be below 64 KB -
1559  // don't do this on NTFS!
1561 
1562  if (!ReadFile(stream, data, stream_size, &bytesret, nullptr)) {
1563  free(data);
1564  throw last_error(GetLastError());
1565  }
1566  }
1567 
1568  stream = CreateFileW((destdir + destname + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, nullptr);
1569 
1570  if (stream == INVALID_HANDLE_VALUE) {
1571  if (data) free(data);
1572  throw last_error(GetLastError());
1573  }
1574 
1575  if (data) {
1576  if (!WriteFile(stream, data, stream_size, &bytesret, nullptr)) {
1577  free(data);
1578  throw last_error(GetLastError());
1579  }
1580 
1581  free(data);
1582  }
1583  }
1584 
1585  }
1586 
1587  if (fsi->NextEntryOffset == 0)
1588  break;
1589 
1590  fsi = reinterpret_cast<FILE_STREAM_INFORMATION*>(reinterpret_cast<char*>(fsi) + fsi->NextEntryOffset);
1591  }
1592  }
1593 
1594  atime.dwLowDateTime = fbi.LastAccessTime.LowPart;
1595  atime.dwHighDateTime = fbi.LastAccessTime.HighPart;
1596  mtime.dwLowDateTime = fbi.LastWriteTime.LowPart;
1597  mtime.dwHighDateTime = fbi.LastWriteTime.HighPart;
1598  SetFileTime(dest, nullptr, &atime, &mtime);
1599 
1600  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, &bsxa, sizeof(btrfs_set_xattr));
1601 
1602  if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) {
1603  ULONG xalen = 0;
1604  btrfs_set_xattr *xa = nullptr, *xa2;
1605 
1606  do {
1607  xalen += 1024;
1608 
1609  if (xa) free(xa);
1610  xa = (btrfs_set_xattr*)malloc(xalen);
1611 
1612  Status = NtFsControlFile(source, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_GET_XATTRS, nullptr, 0, xa, xalen);
1613  } while (Status == STATUS_BUFFER_OVERFLOW);
1614 
1615  if (!NT_SUCCESS(Status)) {
1616  free(xa);
1617  throw ntstatus_error(Status);
1618  }
1619 
1620  xa2 = xa;
1621  while (xa2->valuelen > 0) {
1622  Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, xa2,
1623  (ULONG)(offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen), nullptr, 0);
1624  if (!NT_SUCCESS(Status)) {
1625  free(xa);
1626  throw ntstatus_error(Status);
1627  }
1628  xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen];
1629  }
1630 
1631  free(xa);
1632  } else if (!NT_SUCCESS(Status))
1633  throw ntstatus_error(Status);
1634  } catch (...) {
1635  FILE_DISPOSITION_INFO fdi;
1636 
1637  fdi.DeleteFile = true;
1638  Status = NtSetInformationFile(dest, &iosb, &fdi, sizeof(FILE_DISPOSITION_INFO), FileDispositionInformation);
1639  if (!NT_SUCCESS(Status))
1640  throw ntstatus_error(Status);
1641 
1642  throw;
1643  }
1644 }
#define FSCTL_SET_SPARSE
Definition: winioctl.h:100
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
uint16_t namelen
Definition: btrfsioctl.h:239
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
#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)
#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
#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)
int const char int stream_size
Definition: zlib.h:813
uint64_t st_rdev
Definition: btrfsioctl.h:76
#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
unsigned long DWORD
Definition: ntddk_ex.h:95
#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
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 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:38
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
static void reflink_copy2(const wstring &srcfn, const wstring &destdir, const wstring &destname)
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
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
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

Referenced by ReflinkCopyW().

◆ ReflinkCopyW()

void CALLBACK ReflinkCopyW ( HWND  hwnd,
HINSTANCE  hinst,
LPWSTR  lpszCmdLine,
int  nCmdShow 
)

Definition at line 1650 of file contextmenu.cpp.

1650  {
1652 
1653  command_line_to_args(lpszCmdLine, args);
1654 
1655  if (args.size() >= 2) {
1656  bool dest_is_dir = false;
1657  wstring dest = args[args.size() - 1], destdir, destname;
1658  WCHAR volpath2[MAX_PATH];
1659 
1660  {
1662  nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
1663 
1664  if (destdirh != INVALID_HANDLE_VALUE) {
1666 
1667  if (GetFileInformationByHandle(destdirh, &bhfi) && bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1668  dest_is_dir = true;
1669 
1670  destdir = dest;
1671  if (destdir.substr(destdir.length() - 1, 1) != L"\\")
1672  destdir += L"\\";
1673  }
1674  }
1675  }
1676 
1677  if (!dest_is_dir) {
1678  size_t found = dest.rfind(L"\\");
1679 
1680  if (found == wstring::npos) {
1681  destdir = L"";
1682  destname = dest;
1683  } else {
1684  destdir = dest.substr(0, found);
1685  destname = dest.substr(found + 1);
1686  }
1687  }
1688 
1689  if (!GetVolumePathNameW(dest.c_str(), volpath2, sizeof(volpath2) / sizeof(WCHAR)))
1690  return;
1691 
1692  for (unsigned int i = 0; i < args.size() - 1; i++) {
1693  WIN32_FIND_DATAW ffd;
1694 
1695  fff_handle h = FindFirstFileW(args[i].c_str(), &ffd);
1696  if (h != INVALID_HANDLE_VALUE) {
1697  WCHAR volpath1[MAX_PATH];
1698  wstring path = args[i];
1699  size_t found = path.rfind(L"\\");
1700 
1701  if (found == wstring::npos)
1702  path = L"";
1703  else
1704  path = path.substr(0, found);
1705 
1706  path += L"\\";
1707 
1708  if (get_volume_path_parent(path.c_str(), volpath1, sizeof(volpath1) / sizeof(WCHAR))) {
1709  if (!wcscmp(volpath1, volpath2)) {
1710  do {
1711  try {
1712  reflink_copy2(path + ffd.cFileName, destdir, dest_is_dir ? ffd.cFileName : destname);
1713  } catch (const exception& e) {
1714  cerr << "Error: " << e.what() << endl;
1715  }
1716  } while (FindNextFileW(h, &ffd));
1717  }
1718  }
1719  }
1720  }
1721  }
1722 }
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
static const size_t npos
Definition: _string_npos.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
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
Definition: match.c:390
#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
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
#define e
Definition: ke_i.h:82
int length
Definition: match.c:394
#define OPEN_EXISTING
Definition: compat.h:434
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:608
__wchar_t WCHAR
Definition: xmlstorage.h:180
_STLP_DECLSPEC _Stl_aligned_buffer< ostream > cerr
Definition: iostream.cpp:102
static bool get_volume_path_parent(const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
#define MAX_PATH
Definition: compat.h:26
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
void command_line_to_args(LPWSTR cmdline, vector< wstring > &args)
Definition: main.cpp:647
#define CreateFileW
Definition: compat.h:408
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
static void reflink_copy2(const wstring &srcfn, const wstring &destdir, const wstring &destname)
static char * dest
Definition: rtl.c:135
#define args
Definition: format.c:66
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320

◆ sector_align()

◆ show_reflink_paste()

static bool show_reflink_paste ( const wstring &  path)
static

Definition at line 205 of file contextmenu.cpp.

205  {
206  HDROP hdrop;
207  HANDLE lh;
208  ULONG num_files;
209  WCHAR fn[MAX_PATH], volpath1[255], volpath2[255];
210 
212  return false;
213 
214  if (!GetVolumePathNameW(path.c_str(), volpath1, sizeof(volpath1) / sizeof(WCHAR)))
215  return false;
216 
217  if (!OpenClipboard(nullptr))
218  return false;
219 
220  hdrop = (HDROP)GetClipboardData(CF_HDROP);
221 
222  if (!hdrop) {
223  CloseClipboard();
224  return false;
225  }
226 
227  lh = GlobalLock(hdrop);
228 
229  if (!lh) {
230  CloseClipboard();
231  return false;
232  }
233 
234  num_files = DragQueryFileW(hdrop, 0xFFFFFFFF, nullptr, 0);
235 
236  if (num_files == 0) {
237  GlobalUnlock(lh);
238  CloseClipboard();
239  return false;
240  }
241 
242  if (!DragQueryFileW(hdrop, 0, fn, sizeof(fn) / sizeof(WCHAR))) {
243  GlobalUnlock(lh);
244  CloseClipboard();
245  return false;
246  }
247 
248  if (!get_volume_path_parent(fn, volpath2, sizeof(volpath2) / sizeof(WCHAR))) {
249  GlobalUnlock(lh);
250  CloseClipboard();
251  return false;
252  }
253 
254  GlobalUnlock(lh);
255 
256  CloseClipboard();
257 
258  return !wcscmp(volpath1, volpath2);
259 }
BOOL WINAPI IsClipboardFormatAvailable(_In_ UINT)
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:815
#define CF_HDROP
Definition: constants.h:410
__wchar_t WCHAR
Definition: xmlstorage.h:180
static bool get_volume_path_parent(const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
#define MAX_PATH
Definition: compat.h:26
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HANDLE WINAPI GetClipboardData(_In_ UINT)
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:627

Referenced by BtrfsContextMenu::QueryContextMenu().