ReactOS  r76032
contextmenu.cpp File Reference
#include "shellext.h"
#include <windows.h>
#include <strsafe.h>
#include <stddef.h>
#include <winternl.h>
#include <wincodec.h>
#include <string>
#include <sstream>
#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 UNICODE
 
#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 BOOL get_volume_path_parent (const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
 
static BOOL show_reflink_paste (WCHAR *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 create_snapshot (HWND hwnd, WCHAR *fn)
 
static UINT64 __inline sector_align (UINT64 n, UINT64 a)
 
static void reflink_copy2 (std::wstring srcfn, std::wstring destdir, std::wstring destname)
 
void CALLBACK ReflinkCopyW (HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
 

Macro Definition Documentation

#define NEW_SUBVOL_VERBA   "newsubvol"
#define NEW_SUBVOL_VERBW   L"newsubvol"

Definition at line 53 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::GetCommandString().

#define NO_SHLWAPI_STRFCNS

Definition at line 41 of file contextmenu.cpp.

#define RECV_VERBA   "recvsubvol"
#define RECV_VERBW   L"recvsubvol"

Definition at line 59 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::GetCommandString().

#define REFLINK_VERBA   "reflink"
#define REFLINK_VERBW   L"reflink"

Definition at line 57 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::GetCommandString().

#define SEND_VERBA   "sendsubvol"
#define SEND_VERBW   L"sendsubvol"

Definition at line 61 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::GetCommandString().

#define SNAPSHOT_VERBA   "snapshot"
#define SNAPSHOT_VERBW   L"snapshot"

Definition at line 55 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::GetCommandString().

Definition at line 19 of file contextmenu.cpp.

Function Documentation

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

Definition at line 275 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::get_uac_icon().

275  {
276  BITMAPINFO bmi;
277  HDC hdcUsed;
278 
279  *phBmp = NULL;
280 
281  InitBitmapInfo(&bmi, sizeof(bmi), psize->cx, psize->cy, 32);
282 
283  hdcUsed = hdc ? hdc : GetDC(NULL);
284 
285  if (hdcUsed) {
286  *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0);
287  if (hdc != hdcUsed)
288  ReleaseDC(NULL, hdcUsed);
289  }
290 
291  return !*phBmp ? E_OUTOFMEMORY : S_OK;
292 }
#define HDC
Definition: msvc.h:22
HDC WINAPI GetDC(_In_opt_ HWND)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC hdc
Definition: msvc.h:53
smooth NULL
Definition: ftsmooth.c:557
LONG cx
Definition: windef.h:347
#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:365
LONG cy
Definition: windef.h:348
static void create_snapshot ( HWND  hwnd,
WCHAR fn 
)
static

Definition at line 426 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::InvokeCommand().

426  {
427  HANDLE h;
430  btrfs_get_file_ids bgfi;
431 
433 
434  if (h != INVALID_HANDLE_VALUE) {
435  Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_FILE_IDS, NULL, 0, &bgfi, sizeof(btrfs_get_file_ids));
436 
437  if (NT_SUCCESS(Status) && bgfi.inode == 0x100 && !bgfi.top) {
438  WCHAR parpath[MAX_PATH], subvolname[MAX_PATH], templ[MAX_PATH], name[MAX_PATH], searchpath[MAX_PATH];
439  HANDLE h2, fff;
441  ULONG namelen, pathend;
442  WIN32_FIND_DATAW wfd;
444 
445  StringCchCopyW(parpath, sizeof(parpath) / sizeof(WCHAR), fn);
446  PathRemoveFileSpecW(parpath);
447 
448  StringCchCopyW(subvolname, sizeof(subvolname) / sizeof(WCHAR), fn);
449  PathStripPathW(subvolname);
450 
452 
453  if (h2 == INVALID_HANDLE_VALUE) {
455  CloseHandle(h);
456  return;
457  }
458 
461  CloseHandle(h);
462  CloseHandle(h2);
463  return;
464  }
465 
466  GetLocalTime(&time);
467 
468  if (StringCchPrintfW(name, sizeof(name) / sizeof(WCHAR), templ, subvolname, time.wYear, time.wMonth, time.wDay) == STRSAFE_E_INSUFFICIENT_BUFFER) {
469  MessageBoxW(hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR);
470  CloseHandle(h);
471  CloseHandle(h2);
472  return;
473  }
474 
475  StringCchCopyW(searchpath, sizeof(searchpath) / sizeof(WCHAR), parpath);
476  StringCchCatW(searchpath, sizeof(searchpath) / sizeof(WCHAR), L"\\");
477  pathend = wcslen(searchpath);
478 
479  StringCchCatW(searchpath, sizeof(searchpath) / sizeof(WCHAR), name);
480 
481  fff = FindFirstFileW(searchpath, &wfd);
482 
483  if (fff != INVALID_HANDLE_VALUE) {
484  ULONG i = wcslen(searchpath), num = 2;
485 
486  do {
487  FindClose(fff);
488 
489  searchpath[i] = 0;
490  if (StringCchPrintfW(searchpath, sizeof(searchpath) / sizeof(WCHAR), L"%s (%u)", searchpath, num) == STRSAFE_E_INSUFFICIENT_BUFFER) {
491  MessageBoxW(hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR);
492  CloseHandle(h);
493  CloseHandle(h2);
494  return;
495  }
496 
497  fff = FindFirstFileW(searchpath, &wfd);
498  num++;
499  } while (fff != INVALID_HANDLE_VALUE);
500  }
501 
502  namelen = wcslen(&searchpath[pathend]) * sizeof(WCHAR);
503 
505  bcs->readonly = FALSE;
506  bcs->posix = FALSE;
507  bcs->subvol = h;
508  bcs->namelen = namelen;
509  memcpy(bcs->name, &searchpath[pathend], namelen);
510 
511  Status = NtFsControlFile(h2, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, sizeof(btrfs_create_snapshot) - 1 + namelen, NULL, 0);
512 
513  if (!NT_SUCCESS(Status))
514  ShowNtStatusError(hwnd, Status);
515 
516  CloseHandle(h2);
517  }
518 
519  CloseHandle(h);
520  } else
522 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:598
#define CloseHandle
Definition: compat.h:398
void WINAPI PathStripPathW(LPWSTR lpszPath)
Definition: path.c:663
Definition: bidi.c:75
USHORT wMonth
Definition: rtltypes.h:1568
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IDS_SNAPSHOT_FILENAME
Definition: resource.h:14
void ShowNtStatusError(HWND hwnd, NTSTATUS Status)
Definition: main.cpp:89
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1056
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
void ShowError(HWND hwnd, ULONG err)
Definition: main.cpp:49
#define WCHAR
Definition: msvc.h:43
GLint namelen
Definition: glext.h:7232
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define STRSAFE_E_INSUFFICIENT_BUFFER
Definition: strsafe.h:103
#define FILE_SHARE_READ
Definition: compat.h:125
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
#define FILE_TRAVERSE
Definition: nt_native.h:643
USHORT wYear
Definition: rtltypes.h:1567
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define FALSE
Definition: types.h:117
#define FSCTL_BTRFS_CREATE_SNAPSHOT
Definition: btrfsioctl.h:10
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
smooth NULL
Definition: ftsmooth.c:557
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:276
#define OPEN_EXISTING
Definition: compat.h:426
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define MAX_PATH
Definition: compat.h:26
GLuint GLuint num
Definition: glext.h:9618
static PIO_STATUS_BLOCK iosb
Definition: file.c:95
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define MB_ICONERROR
Definition: winuser.h:781
#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:8
Status
Definition: gdiplustypes.h:24
USHORT wDay
Definition: rtltypes.h:1570
DWORD *typedef HANDLE
Definition: winlogon.h:52
LONG NTSTATUS
Definition: DriverTester.h:11
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define CreateFileW
Definition: compat.h:400
Definition: name.c:23
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
unsigned int ULONG
Definition: retypes.h:1
#define malloc
Definition: debug_ros.c:4
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:318
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:500
static BOOL get_volume_path_parent ( const WCHAR fn,
WCHAR volpath,
ULONG  volpathlen 
)
static

Definition at line 185 of file contextmenu.cpp.

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

185  {
186  WCHAR *f, *p;
187  BOOL b;
188 
189  f = PathFindFileNameW(fn);
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define free
Definition: debug_ros.c:5
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:811
#define WCHAR
Definition: msvc.h:43
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:371
#define b
Definition: ke_i.h:79
unsigned int BOOL
Definition: ntddk_ex.h:94
#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
static void InitBitmapInfo ( BITMAPINFO pbmi,
ULONG  cbInfo,
LONG  cx,
LONG  cy,
WORD  bpp 
)
static

Definition at line 264 of file contextmenu.cpp.

Referenced by Create32BitHBITMAP().

264  {
265  ZeroMemory(pbmi, cbInfo);
266  pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
267  pbmi->bmiHeader.biPlanes = 1;
269 
270  pbmi->bmiHeader.biWidth = cx;
271  pbmi->bmiHeader.biHeight = cy;
272  pbmi->bmiHeader.biBitCount = bpp;
273 }
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1453
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
#define ZeroMemory
Definition: winbase.h:1621
DWORD biCompression
Definition: amvideo.idl:35
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
_Out_opt_ int * cx
Definition: commctrl.h:570
DWORD bpp
Definition: surface.c:174
#define BI_RGB
Definition: precomp.h:35
static void reflink_copy2 ( std::wstring  srcfn,
std::wstring  destdir,
std::wstring  destname 
)
static

Definition at line 1388 of file contextmenu.cpp.

Referenced by ReflinkCopyW().

1388  {
1389  HANDLE source, dest;
1390  BOOL ret = FALSE;
1391  FILE_BASIC_INFO fbi;
1392  FILETIME atime, mtime;
1393  btrfs_inode_info bii;
1394  btrfs_set_inode_info bsii;
1395  ULONG bytesret;
1396  NTSTATUS Status;
1398  btrfs_set_xattr bsxa;
1399 
1401  if (source == INVALID_HANDLE_VALUE)
1402  return;
1403 
1404  Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_INODE_INFO, NULL, 0, &bii, sizeof(btrfs_inode_info));
1405  if (!NT_SUCCESS(Status)) {
1406  CloseHandle(source);
1407  return;
1408  }
1409 
1410  // if subvol, do snapshot instead
1411  if (bii.inode == SUBVOL_ROOT_INODE) {
1412  ULONG bcslen;
1413  btrfs_create_snapshot* bcs;
1414  HANDLE dirh;
1415 
1417  if (dirh == INVALID_HANDLE_VALUE) {
1418  CloseHandle(source);
1419  return;
1420  }
1421 
1422  bcslen = offsetof(btrfs_create_snapshot, name[0]) + (destname.length() * sizeof(WCHAR));
1423  bcs = (btrfs_create_snapshot*)malloc(bcslen);
1424  bcs->subvol = source;
1425  bcs->namelen = destname.length() * sizeof(WCHAR);
1426  memcpy(bcs->name, destname.c_str(), destname.length() * sizeof(WCHAR));
1427 
1428  Status = NtFsControlFile(dirh, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, bcslen, NULL, 0);
1429 
1430  free(bcs);
1431 
1432  CloseHandle(source);
1433  CloseHandle(dirh);
1434 
1435  return;
1436  }
1437 
1438  if (!GetFileInformationByHandleEx(source, FileBasicInfo, &fbi, sizeof(FILE_BASIC_INFO))) {
1439  CloseHandle(source);
1440  return;
1441  }
1442 
1443  if (bii.type == BTRFS_TYPE_CHARDEV || bii.type == BTRFS_TYPE_BLOCKDEV || bii.type == BTRFS_TYPE_FIFO || bii.type == BTRFS_TYPE_SOCKET) {
1444  HANDLE dirh;
1445  ULONG bmnsize;
1446  btrfs_mknod* bmn;
1447 
1449  if (dirh == INVALID_HANDLE_VALUE) {
1450  CloseHandle(source);
1451  return;
1452  }
1453 
1454  bmnsize = offsetof(btrfs_mknod, name[0]) + (destname.length() * sizeof(WCHAR));
1455  bmn = (btrfs_mknod*)malloc(bmnsize);
1456 
1457  bmn->inode = 0;
1458  bmn->type = bii.type;
1459  bmn->st_rdev = bii.st_rdev;
1460  bmn->namelen = destname.length() * sizeof(WCHAR);
1461  memcpy(bmn->name, destname.c_str(), bmn->namelen);
1462 
1463  Status = NtFsControlFile(dirh, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_MKNOD, bmn, bmnsize, NULL, 0);
1464  if (!NT_SUCCESS(Status)) {
1465  CloseHandle(dirh);
1466  CloseHandle(source);
1467  free(bmn);
1468  return;
1469  }
1470 
1471  CloseHandle(dirh);
1472  free(bmn);
1473 
1474  dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, 0, NULL);
1475  } else if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1476  if (CreateDirectoryExW(srcfn.c_str(), (destdir + destname).c_str(), NULL))
1477  dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1478  NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1479  else
1480  dest = INVALID_HANDLE_VALUE;
1481  } else
1482  dest = CreateFileW((destdir + destname).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, source);
1483 
1484  if (dest == INVALID_HANDLE_VALUE) {
1485  CloseHandle(source);
1486  return;
1487  }
1488 
1489  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
1490 
1491  bsii.flags_changed = TRUE;
1492  bsii.flags = bii.flags;
1493 
1494  if (bii.flags & BTRFS_INODE_COMPRESS) {
1497  }
1498 
1499  Status = NtFsControlFile(dest, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), NULL, 0);
1500  if (!NT_SUCCESS(Status))
1501  goto end;
1502 
1503  if (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1504  if (!(fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1505  HANDLE h;
1506  WIN32_FIND_DATAW fff;
1507  std::wstring qs;
1508 
1509  qs = srcfn;
1510  qs += L"\\*";
1511 
1512  h = FindFirstFileW(qs.c_str(), &fff);
1513  if (h != INVALID_HANDLE_VALUE) {
1514  do {
1515  std::wstring fn2;
1516 
1517  if (fff.cFileName[0] == '.' && (fff.cFileName[1] == 0 || (fff.cFileName[1] == '.' && fff.cFileName[2] == 0)))
1518  continue;
1519 
1520  fn2 = srcfn;
1521  fn2 += L"\\";
1522  fn2 += fff.cFileName;
1523 
1524  reflink_copy2(fn2, destdir + destname + L"\\", fff.cFileName);
1525  } while (FindNextFileW(h, &fff));
1526 
1527  FindClose(h);
1528  }
1529  }
1530 
1531  // CreateDirectoryExW also copies streams, no need to do it here
1532  } else {
1533  HANDLE h;
1534  WIN32_FIND_STREAM_DATA fsd;
1535 
1536  if (fbi.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1537  reparse_header rh;
1538  ULONG rplen;
1539  UINT8* rp;
1540 
1541  if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, NULL, 0, &rh, sizeof(reparse_header), &bytesret, NULL)) {
1542  if (GetLastError() != ERROR_MORE_DATA)
1543  goto end;
1544  }
1545 
1546  rplen = sizeof(reparse_header) + rh.ReparseDataLength;
1547  rp = (UINT8*)malloc(rplen);
1548 
1549  if (!DeviceIoControl(source, FSCTL_GET_REPARSE_POINT, NULL, 0, rp, rplen, &bytesret, NULL))
1550  goto end;
1551 
1552  if (!DeviceIoControl(dest, FSCTL_SET_REPARSE_POINT, rp, rplen, NULL, 0, &bytesret, NULL))
1553  goto end;
1554 
1555  free(rp);
1556  } else {
1557  FILE_STANDARD_INFO fsi;
1558  FILE_END_OF_FILE_INFO feofi;
1562  UINT64 offset, alloc_size;
1563  ULONG maxdup;
1564 
1565  if (!GetFileInformationByHandleEx(source, FileStandardInfo, &fsi, sizeof(FILE_STANDARD_INFO)))
1566  goto end;
1567 
1568  if (!DeviceIoControl(source, FSCTL_GET_INTEGRITY_INFORMATION, NULL, 0, &fgiib, sizeof(FSCTL_GET_INTEGRITY_INFORMATION_BUFFER), &bytesret, NULL))
1569  goto end;
1570 
1571  if (fbi.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) {
1572  if (!DeviceIoControl(dest, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytesret, NULL))
1573  goto end;
1574  }
1575 
1576  fsiib.ChecksumAlgorithm = fgiib.ChecksumAlgorithm;
1577  fsiib.Reserved = 0;
1578  fsiib.Flags = fgiib.Flags;
1579  if (!DeviceIoControl(dest, FSCTL_SET_INTEGRITY_INFORMATION, &fsiib, sizeof(FSCTL_SET_INTEGRITY_INFORMATION_BUFFER), NULL, 0, &bytesret, NULL))
1580  goto end;
1581 
1582  feofi.EndOfFile = fsi.EndOfFile;
1583  if (!SetFileInformationByHandle(dest, FileEndOfFileInfo, &feofi, sizeof(FILE_END_OF_FILE_INFO)))
1584  goto end;
1585 
1586  ded.FileHandle = source;
1587  maxdup = 0xffffffff - fgiib.ClusterSizeInBytes + 1;
1588 
1589  alloc_size = sector_align(fsi.EndOfFile.QuadPart, fgiib.ClusterSizeInBytes);
1590 
1591  offset = 0;
1592  while (offset < alloc_size) {
1594  ded.ByteCount.QuadPart = maxdup < (alloc_size - offset) ? maxdup : (alloc_size - offset);
1595  if (!DeviceIoControl(dest, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA), NULL, 0, &bytesret, NULL))
1596  goto end;
1597 
1598  offset += ded.ByteCount.QuadPart;
1599  }
1600  }
1601 
1602  h = FindFirstStreamW(srcfn.c_str(), FindStreamInfoStandard, &fsd, 0);
1603  if (h != INVALID_HANDLE_VALUE) {
1604  do {
1605  std::wstring sn;
1606 
1607  sn = fsd.cStreamName;
1608 
1609  if (sn != L"::$DATA" && sn.length() > 6 && sn.substr(sn.length() - 6, 6) == L":$DATA") {
1610  HANDLE stream;
1611  UINT8* data = NULL;
1612 
1613  if (fsd.StreamSize.QuadPart > 0) {
1614  std::wstring fn2;
1615 
1616  fn2 = srcfn;
1617  fn2 += sn;
1618 
1619  stream = CreateFileW(fn2.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
1620 
1621  if (stream == INVALID_HANDLE_VALUE)
1622  goto end;
1623 
1624  // We can get away with this because our streams are guaranteed to be below 64 KB -
1625  // don't do this on NTFS!
1626  data = (UINT8*)malloc(fsd.StreamSize.QuadPart);
1627 
1628  if (!ReadFile(stream, data, fsd.StreamSize.QuadPart, &bytesret, NULL)) {
1629  free(data);
1630  CloseHandle(stream);
1631  goto end;
1632  }
1633 
1634  CloseHandle(stream);
1635  }
1636 
1637  stream = CreateFileW((destdir + destname + sn).c_str(), GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_NEW, 0, NULL);
1638 
1639  if (stream == INVALID_HANDLE_VALUE) {
1640  if (data) free(data);
1641  goto end;
1642  }
1643 
1644  if (data) {
1645  if (!WriteFile(stream, data, fsd.StreamSize.QuadPart, &bytesret, NULL)) {
1646  free(data);
1647  CloseHandle(stream);
1648  goto end;
1649  }
1650 
1651  free(data);
1652  }
1653 
1654  CloseHandle(stream);
1655  }
1656  } while (FindNextStreamW(h, &fsd));
1657 
1658  FindClose(h);
1659  }
1660  }
1661 
1662  atime.dwLowDateTime = fbi.LastAccessTime.LowPart;
1663  atime.dwHighDateTime = fbi.LastAccessTime.HighPart;
1664  mtime.dwLowDateTime = fbi.LastWriteTime.LowPart;
1665  mtime.dwHighDateTime = fbi.LastWriteTime.HighPart;
1666  SetFileTime(dest, NULL, &atime, &mtime);
1667 
1668  Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_XATTRS, NULL, 0, &bsxa, sizeof(btrfs_set_xattr));
1669 
1670  if (Status == STATUS_BUFFER_OVERFLOW || (NT_SUCCESS(Status) && bsxa.valuelen > 0)) {
1671  ULONG xalen = 0;
1672  btrfs_set_xattr *xa = NULL, *xa2;
1673 
1674  do {
1675  xalen += 1024;
1676 
1677  if (xa) free(xa);
1678  xa = (btrfs_set_xattr*)malloc(xalen);
1679 
1680  Status = NtFsControlFile(source, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_GET_XATTRS, NULL, 0, xa, xalen);
1681  } while (Status == STATUS_BUFFER_OVERFLOW);
1682 
1683  if (!NT_SUCCESS(Status)) {
1684  free(xa);
1685  goto end;
1686  }
1687 
1688  xa2 = xa;
1689  while (xa2->valuelen > 0) {
1690  Status = NtFsControlFile(dest, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_SET_XATTR, xa2,
1691  offsetof(btrfs_set_xattr, data[0]) + xa2->namelen + xa2->valuelen, NULL, 0);
1692  if (!NT_SUCCESS(Status)) {
1693  free(xa);
1694  goto end;
1695  }
1696  xa2 = (btrfs_set_xattr*)&xa2->data[xa2->namelen + xa2->valuelen];
1697  }
1698 
1699  free(xa);
1700  } else if (!NT_SUCCESS(Status))
1701  goto end;
1702 
1703  ret = TRUE;
1704 
1705 end:
1706  if (!ret) {
1707  FILE_DISPOSITION_INFO fdi;
1708 
1709  fdi.DeleteFile = TRUE;
1710  SetFileInformationByHandle(dest, FileDispositionInfo, &fdi, sizeof(FILE_DISPOSITION_INFO));
1711  }
1712 
1713  CloseHandle(dest);
1714  CloseHandle(source);
1715 }
#define FSCTL_SET_SPARSE
Definition: winioctl.h:100
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:380
static UINT64 __inline sector_align(UINT64 n, UINT64 a)
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define FILE_ATTRIBUTE_SPARSE_FILE
Definition: ntifs_ex.h:380
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:71
Definition: bidi.c:75
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:69
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
#define free
Definition: debug_ros.c:5
UINT64 st_rdev
Definition: btrfsioctl.h:232
#define BTRFS_TYPE_FIFO
Definition: shellext.h:70
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1056
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)
GLuint GLuint end
Definition: gl.h:1545
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:68
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
#define WCHAR
Definition: msvc.h:43
#define FILE_SHARE_READ
Definition: compat.h:125
GLuint GLuint stream
Definition: glext.h:7522
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:1078
UINT16 namelen
Definition: btrfsioctl.h:233
UINT8 type
Definition: btrfsioctl.h:231
#define FILE_TRAVERSE
Definition: nt_native.h:643
DWORD dwHighDateTime
Definition: mapidefs.h:66
static void reflink_copy2(std::wstring srcfn, std::wstring destdir, std::wstring destname)
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FALSE
Definition: types.h:117
#define FSCTL_BTRFS_CREATE_SNAPSHOT
Definition: btrfsioctl.h:10
#define BTRFS_INODE_COMPRESS
Definition: propsheet.h:86
#define GENERIC_WRITE
Definition: nt_native.h:90
smooth NULL
Definition: ftsmooth.c:557
#define offsetof(TYPE, MEMBER)
UINT8 compression_type
Definition: btrfsioctl.h:79
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define OPEN_EXISTING
Definition: compat.h:426
USHORT ReparseDataLength
Definition: contextmenu.cpp:65
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
LARGE_INTEGER SourceFileOffset
Definition: shellext.h:154
unsigned int BOOL
Definition: ntddk_ex.h:94
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
GLfloat CONST GLvector4f CONST GLfloat GLvector4f * dest
Definition: m_xform.h:122
BOOL WINAPI GetFileInformationByHandleEx(HANDLE handle, FILE_INFO_BY_HANDLE_CLASS class, LPVOID info, DWORD size)
#define FSCTL_BTRFS_GET_XATTRS
Definition: btrfsioctl.h:33
static PIO_STATUS_BLOCK iosb
Definition: file.c:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
UINT64 inode
Definition: btrfsioctl.h:230
BOOL compression_type_changed
Definition: btrfsioctl.h:92
int ret
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FSCTL_BTRFS_MKNOD
Definition: btrfsioctl.h:31
#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
#define FSCTL_BTRFS_SET_INODE_INFO
Definition: btrfsioctl.h:12
#define ERROR_MORE_DATA
Definition: dderror.h:13
Status
Definition: gdiplustypes.h:24
HANDLE WINAPI FindFirstStreamW(IN LPCWSTR lpFileName, IN STREAM_INFO_LEVELS InfoLevel, OUT LPVOID lpFindStreamData, IN DWORD dwFlags)
Definition: find.c:954
DWORD *typedef HANDLE
Definition: winlogon.h:52
LONG NTSTATUS
Definition: DriverTester.h:11
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:47
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
#define FSCTL_BTRFS_GET_INODE_INFO
Definition: btrfsioctl.h:11
BOOL WINAPI CreateDirectoryExW(IN LPCWSTR lpTemplateDirectory, IN LPCWSTR lpNewDirectory, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:193
LARGE_INTEGER TargetFileOffset
Definition: shellext.h:155
BOOL WINAPI FindNextStreamW(IN HANDLE hFindStream, OUT LPVOID lpFindStreamData)
Definition: find.c:1112
#define CreateFileW
Definition: compat.h:400
#define FSCTL_GET_INTEGRITY_INFORMATION
Definition: shellext.h:175
BOOL WINAPI SetFileInformationByHandle(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize)
Definition: reactos.cpp:177
Definition: name.c:23
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
WCHAR name[1]
Definition: btrfsioctl.h:234
#define FSCTL_BTRFS_SET_XATTR
Definition: btrfsioctl.h:34
unsigned int ULONG
Definition: retypes.h:1
#define malloc
Definition: debug_ros.c:4
#define FSCTL_SET_INTEGRITY_INFORMATION
Definition: shellext.h:176
#define CREATE_NEW
Definition: disk.h:69
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:98
unsigned long long UINT64
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
unsigned char UINT8
#define memset(x, y, z)
Definition: compat.h:39
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
LARGE_INTEGER ByteCount
Definition: shellext.h:156
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:159
GLintptr offset
Definition: glext.h:5920
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:318
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:500
void CALLBACK ReflinkCopyW ( HWND  hwnd,
HINSTANCE  hinst,
LPWSTR  lpszCmdLine,
int  nCmdShow 
)

Definition at line 1717 of file contextmenu.cpp.

1717  {
1718  LPWSTR* args;
1719  int num_args;
1720 
1721  args = CommandLineToArgvW(lpszCmdLine, &num_args);
1722 
1723  if (!args)
1724  return;
1725 
1726  if (num_args >= 2) {
1727  HANDLE destdirh;
1728  BOOL dest_is_dir = FALSE;
1729  std::wstring dest = args[num_args - 1], destdir, destname;
1730  WCHAR volpath2[MAX_PATH];
1731  int i;
1732 
1734  if (destdirh != INVALID_HANDLE_VALUE) {
1736 
1737  if (GetFileInformationByHandle(destdirh, &bhfi) && bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1738  dest_is_dir = TRUE;
1739 
1740  destdir = dest;
1741  if (destdir.substr(destdir.length() - 1, 1) != L"\\")
1742  destdir += L"\\";
1743  }
1744  CloseHandle(destdirh);
1745  }
1746 
1747  if (!dest_is_dir) {
1748  size_t found = dest.rfind(L"\\");
1749 
1750  if (found == std::wstring::npos) {
1751  destdir = L"";
1752  destname = dest;
1753  } else {
1754  destdir = dest.substr(0, found);
1755  destname = dest.substr(found + 1);
1756  }
1757  }
1758 
1759  if (!GetVolumePathNameW(dest.c_str(), volpath2, sizeof(volpath2) / sizeof(WCHAR)))
1760  goto end;
1761 
1762  for (i = 0; i < num_args - 1; i++) {
1763  WIN32_FIND_DATAW ffd;
1764  HANDLE h;
1765 
1766  h = FindFirstFileW(args[i], &ffd);
1767  if (h != INVALID_HANDLE_VALUE) {
1768  WCHAR volpath1[MAX_PATH];
1769  std::wstring path = args[i];
1770  size_t found = path.rfind(L"\\");
1771 
1772  if (found == std::wstring::npos)
1773  path = L"";
1774  else
1775  path = path.substr(0, found);
1776 
1777  path += L"\\";
1778 
1779  if (get_volume_path_parent(path.c_str(), volpath1, sizeof(volpath1) / sizeof(WCHAR))) {
1780  if (!wcscmp(volpath1, volpath2)) {
1781  do {
1782  reflink_copy2(path + ffd.cFileName, destdir, dest_is_dir ? ffd.cFileName : destname);
1783  } while (FindNextFileW(h, &ffd));
1784  }
1785  }
1786 
1787  FindClose(h);
1788  }
1789  }
1790  }
1791 
1792 end:
1793  LocalFree(args);
1794 }
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:380
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
Definition: bidi.c:75
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const size_t npos
Definition: _string_npos.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:811
GLuint GLuint end
Definition: gl.h:1545
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#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
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static void reflink_copy2(std::wstring srcfn, std::wstring destdir, std::wstring destname)
#define FALSE
Definition: types.h:117
int length
Definition: match.c:394
LPWSTR *WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int *numargs)
Definition: shell32_main.c:75
smooth NULL
Definition: ftsmooth.c:557
#define OPEN_EXISTING
Definition: compat.h:426
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:588
#define MAX_PATH
Definition: compat.h:26
GLfloat CONST GLvector4f CONST GLfloat GLvector4f * dest
Definition: m_xform.h:122
static BOOL get_volume_path_parent(const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
DWORD *typedef HANDLE
Definition: winlogon.h:52
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
Definition: services.c:311
#define CreateFileW
Definition: compat.h:400
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define args
Definition: format.c:66
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:318
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:500
static BOOL show_reflink_paste ( WCHAR path)
static

Definition at line 205 of file contextmenu.cpp.

Referenced by BtrfsContextMenu::QueryContextMenu().

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, volpath1, sizeof(volpath1) / sizeof(WCHAR)))
215  return FALSE;
216 
217  if (!OpenClipboard(NULL))
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, NULL, 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
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:811
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:557
#define CF_HDROP
Definition: constants.h:410
#define MAX_PATH
Definition: compat.h:26
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
static BOOL get_volume_path_parent(const WCHAR *fn, WCHAR *volpath, ULONG volpathlen)
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)
DWORD *typedef HANDLE
Definition: winlogon.h:52
Definition: services.c:311
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