ReactOS  0.4.15-dev-5131-g311fcc6
recv.cpp
Go to the documentation of this file.
1 /* Copyright (c) Mark Harmstone 2017
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "shellext.h"
19 #include <windows.h>
20 #include <strsafe.h>
21 #include <stddef.h>
22 #include <sys/stat.h>
23 #include <iostream>
24 #include "recv.h"
25 #include "resource.h"
26 #include "crc32c.h"
27 
28 
29 #ifndef _MSC_VER
30 #include <cpuid.h>
31 #else
32 #include <intrin.h>
33 #endif
34 
35 
36 const string EA_NTACL = "security.NTACL";
37 const string EA_DOSATTRIB = "user.DOSATTRIB";
38 const string EA_REPARSE = "user.reparse";
39 const string EA_EA = "user.EA";
40 const string XATTR_USER = "user.";
41 
43  size_t off = 0;
44 
45  while (off < datalen) {
46  btrfs_send_tlv* tlv = (btrfs_send_tlv*)(data + off);
47  uint8_t* payload = data + off + sizeof(btrfs_send_tlv);
48 
49  if (off + sizeof(btrfs_send_tlv) + tlv->length > datalen) // file is truncated
50  return false;
51 
52  if (tlv->type == type) {
53  *value = payload;
54  *len = tlv->length;
55  return true;
56  }
57 
58  off += sizeof(btrfs_send_tlv) + tlv->length;
59  }
60 
61  return false;
62 }
63 
65  string name;
67  uint64_t* gen;
68  ULONG uuidlen, genlen;
72 
73  {
74  char* namebuf;
75  ULONG namelen;
76 
77  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&namebuf, &namelen))
79 
80  name = string(namebuf, namelen);
81  }
82 
83  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_UUID, (void**)&uuid, &uuidlen))
85 
86  if (uuidlen < sizeof(BTRFS_UUID))
87  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"uuid", uuidlen, sizeof(BTRFS_UUID));
88 
89  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_TRANSID, (void**)&gen, &genlen))
91 
92  if (genlen < sizeof(uint64_t))
93  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"transid", genlen, sizeof(uint64_t));
94 
95  this->subvol_uuid = *uuid;
96  this->stransid = *gen;
97 
98  auto nameu = utf8_to_utf16(name);
99 
100  size_t bcslen = offsetof(btrfs_create_subvol, name[0]) + (nameu.length() * sizeof(WCHAR));
101  bcs = (btrfs_create_subvol*)malloc(bcslen);
102 
103  bcs->readonly = true;
104  bcs->posix = true;
105  bcs->namelen = (uint16_t)(nameu.length() * sizeof(WCHAR));
106  memcpy(bcs->name, nameu.c_str(), bcs->namelen);
107 
108  Status = NtFsControlFile(parent, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, bcs, (ULONG)bcslen, nullptr, 0);
109  if (!NT_SUCCESS(Status))
111 
113  subvolpath += L"\\";
114  subvolpath += nameu;
115 
116  if (dir != INVALID_HANDLE_VALUE)
117  CloseHandle(dir);
118 
121 
126 
127  Status = NtFsControlFile(master, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_RESERVE_SUBVOL, bcs, (ULONG)bcslen, nullptr, 0);
128  if (!NT_SUCCESS(Status))
130 
134  if (dir == INVALID_HANDLE_VALUE)
136 
137  subvolpath += L"\\";
138 
139  add_cache_entry(&this->subvol_uuid, this->stransid, subvolpath);
140 
141  num_received++;
142 }
143 
144 void BtrfsRecv::add_cache_entry(BTRFS_UUID* uuid, uint64_t transid, const wstring& path) {
145  subvol_cache sc;
146 
147  sc.uuid = *uuid;
148  sc.transid = transid;
149  sc.path = path;
150 
151  cache.push_back(sc);
152 }
153 
155  string name;
156  BTRFS_UUID *uuid, *parent_uuid;
157  uint64_t *gen, *parent_transid;
158  ULONG uuidlen, genlen, paruuidlen, partransidlen;
162  wstring parpath;
163  btrfs_find_subvol bfs;
164  WCHAR parpathw[MAX_PATH], volpathw[MAX_PATH];
165  size_t bcslen;
166 
167  {
168  char* namebuf;
169  ULONG namelen;
170 
171  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&namebuf, &namelen))
173 
174  name = string(namebuf, namelen);
175  }
176 
177  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_UUID, (void**)&uuid, &uuidlen))
179 
180  if (uuidlen < sizeof(BTRFS_UUID))
181  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"uuid", uuidlen, sizeof(BTRFS_UUID));
182 
183  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_TRANSID, (void**)&gen, &genlen))
184  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"transid");
185 
186  if (genlen < sizeof(uint64_t))
187  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"transid", genlen, sizeof(uint64_t));
188 
189  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_UUID, (void**)&parent_uuid, &paruuidlen))
190  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_uuid");
191 
192  if (paruuidlen < sizeof(BTRFS_UUID))
193  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"clone_uuid", paruuidlen, sizeof(BTRFS_UUID));
194 
195  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_CTRANSID, (void**)&parent_transid, &partransidlen))
196  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_ctransid");
197 
198  if (partransidlen < sizeof(uint64_t))
199  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"clone_ctransid", partransidlen, sizeof(uint64_t));
200 
201  this->subvol_uuid = *uuid;
202  this->stransid = *gen;
203 
204  auto nameu = utf8_to_utf16(name);
205 
206  bfs.uuid = *parent_uuid;
207  bfs.ctransid = *parent_transid;
208 
209  Status = NtFsControlFile(parent, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_FIND_SUBVOL, &bfs, sizeof(btrfs_find_subvol),
210  parpathw, sizeof(parpathw));
211  if (Status == STATUS_NOT_FOUND)
213  else if (!NT_SUCCESS(Status))
215 
216  if (!GetVolumePathNameW(dirpath.c_str(), volpathw, (sizeof(volpathw) / sizeof(WCHAR)) - 1))
218 
219  parpath = volpathw;
220  if (parpath.substr(parpath.length() - 1) == L"\\")
221  parpath = parpath.substr(0, parpath.length() - 1);
222 
223  parpath += parpathw;
224 
225  {
227  nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
228  if (subvol == INVALID_HANDLE_VALUE)
229  throw string_error(IDS_RECV_CANT_OPEN_PATH, parpath.c_str(), GetLastError(), format_message(GetLastError()).c_str());
230 
231  bcslen = offsetof(btrfs_create_snapshot, name[0]) + (nameu.length() * sizeof(WCHAR));
232  bcs = (btrfs_create_snapshot*)malloc(bcslen);
233 
234  bcs->readonly = true;
235  bcs->posix = true;
236  bcs->subvol = subvol;
237  bcs->namelen = (uint16_t)(nameu.length() * sizeof(WCHAR));
238  memcpy(bcs->name, nameu.c_str(), bcs->namelen);
239 
240  Status = NtFsControlFile(parent, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_CREATE_SNAPSHOT, bcs, (ULONG)bcslen, nullptr, 0);
241  if (!NT_SUCCESS(Status))
243  }
244 
246  subvolpath += L"\\";
247  subvolpath += nameu;
248 
249  if (dir != INVALID_HANDLE_VALUE)
250  CloseHandle(dir);
251 
254 
259 
260  Status = NtFsControlFile(master, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_RESERVE_SUBVOL, bcs, (ULONG)bcslen, nullptr, 0);
261  if (!NT_SUCCESS(Status))
263 
267  if (dir == INVALID_HANDLE_VALUE)
269 
270  subvolpath += L"\\";
271 
272  add_cache_entry(&this->subvol_uuid, this->stransid, subvolpath);
273 
274  num_received++;
275 }
276 
278  uint64_t *inode, *rdev = nullptr, *mode = nullptr;
279  ULONG inodelen;
282  btrfs_mknod* bmn;
283  wstring nameu, pathlinku;
284 
285  {
286  char* name;
287  ULONG namelen;
288 
289  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&name, &namelen))
291 
292  nameu = utf8_to_utf16(string(name, namelen));
293  }
294 
295  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_INODE, (void**)&inode, &inodelen))
297 
298  if (inodelen < sizeof(uint64_t))
299  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"inode", inodelen, sizeof(uint64_t));
300 
301  if (cmd->cmd == BTRFS_SEND_CMD_MKNOD || cmd->cmd == BTRFS_SEND_CMD_MKFIFO || cmd->cmd == BTRFS_SEND_CMD_MKSOCK) {
302  ULONG rdevlen, modelen;
303 
304  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_RDEV, (void**)&rdev, &rdevlen))
306 
307  if (rdevlen < sizeof(uint64_t))
308  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"rdev", rdev, sizeof(uint64_t));
309 
310  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_MODE, (void**)&mode, &modelen))
312 
313  if (modelen < sizeof(uint64_t))
314  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"mode", modelen, sizeof(uint64_t));
315  } else if (cmd->cmd == BTRFS_SEND_CMD_SYMLINK) {
316  char* pathlink;
317  ULONG pathlinklen;
318 
319  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH_LINK, (void**)&pathlink, &pathlinklen))
320  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"path_link");
321 
322  pathlinku = utf8_to_utf16(string(pathlink, pathlinklen));
323  }
324 
325  size_t bmnsize = sizeof(btrfs_mknod) - sizeof(WCHAR) + (nameu.length() * sizeof(WCHAR));
326  bmn = (btrfs_mknod*)malloc(bmnsize);
327 
328  bmn->inode = *inode;
329 
330  if (cmd->cmd == BTRFS_SEND_CMD_MKDIR)
331  bmn->type = BTRFS_TYPE_DIRECTORY;
332  else if (cmd->cmd == BTRFS_SEND_CMD_MKNOD)
334  else if (cmd->cmd == BTRFS_SEND_CMD_MKFIFO)
335  bmn->type = BTRFS_TYPE_FIFO;
336  else if (cmd->cmd == BTRFS_SEND_CMD_MKSOCK)
337  bmn->type = BTRFS_TYPE_SOCKET;
338  else
339  bmn->type = BTRFS_TYPE_FILE;
340 
341  bmn->st_rdev = rdev ? *rdev : 0;
342  bmn->namelen = (uint16_t)(nameu.length() * sizeof(WCHAR));
343  memcpy(bmn->name, nameu.c_str(), bmn->namelen);
344 
345  Status = NtFsControlFile(dir, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_MKNOD, bmn, (ULONG)bmnsize, nullptr, 0);
346  if (!NT_SUCCESS(Status)) {
347  free(bmn);
349  }
350 
351  free(bmn);
352 
353  if (cmd->cmd == BTRFS_SEND_CMD_SYMLINK) {
354  REPARSE_DATA_BUFFER* rdb;
356 
357  size_t rdblen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]) + (2 * pathlinku.length() * sizeof(WCHAR));
358 
359  if (rdblen >= 0x10000)
361 
362  rdb = (REPARSE_DATA_BUFFER*)malloc(rdblen);
363 
365  rdb->ReparseDataLength = (uint16_t)(rdblen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
366  rdb->Reserved = 0;
367  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
368  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = (uint16_t)(pathlinku.length() * sizeof(WCHAR));
369  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = (uint16_t)(pathlinku.length() * sizeof(WCHAR));
370  rdb->SymbolicLinkReparseBuffer.PrintNameLength = (uint16_t)(pathlinku.length() * sizeof(WCHAR));
372 
373  memcpy(rdb->SymbolicLinkReparseBuffer.PathBuffer, pathlinku.c_str(), rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
374  memcpy(rdb->SymbolicLinkReparseBuffer.PathBuffer + (rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)),
375  pathlinku.c_str(), rdb->SymbolicLinkReparseBuffer.PrintNameLength);
376 
379  if (h == INVALID_HANDLE_VALUE) {
380  free(rdb);
382  }
383 
384  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_SET_REPARSE_POINT, rdb, (ULONG)rdblen, nullptr, 0);
385  if (!NT_SUCCESS(Status)) {
386  free(rdb);
388  }
389 
390  free(rdb);
391 
392  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
393 
394  bsii.mode_changed = true;
395  bsii.st_mode = 0777;
396 
397  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0);
398  if (!NT_SUCCESS(Status))
400  } else if (cmd->cmd == BTRFS_SEND_CMD_MKNOD || cmd->cmd == BTRFS_SEND_CMD_MKFIFO || cmd->cmd == BTRFS_SEND_CMD_MKSOCK) {
401  uint64_t* mode;
402  ULONG modelen;
403 
404  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_MODE, (void**)&mode, &modelen)) {
406 
407  if (modelen < sizeof(uint64_t))
408  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"mode", modelen, sizeof(uint64_t));
409 
412  if (h == INVALID_HANDLE_VALUE)
414 
415  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
416 
417  bsii.mode_changed = true;
418  bsii.st_mode = (uint32_t)*mode;
419 
420  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0);
421  if (!NT_SUCCESS(Status))
423  }
424  }
425 }
426 
428  wstring pathu, path_tou;
429 
430  {
431  char* path;
432  ULONG path_len;
433 
434  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &path_len))
436 
437  pathu = utf8_to_utf16(string(path, path_len));
438  }
439 
440  {
441  char* path_to;
442  ULONG path_to_len;
443 
444  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH_TO, (void**)&path_to, &path_to_len))
445  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"path_to");
446 
447  path_tou = utf8_to_utf16(string(path_to, path_to_len));
448  }
449 
450  if (!MoveFileW((subvolpath + pathu).c_str(), (subvolpath + path_tou).c_str()))
451  throw string_error(IDS_RECV_MOVEFILE_FAILED, pathu.c_str(), path_tou.c_str(), GetLastError(), format_message(GetLastError()).c_str());
452 }
453 
455  wstring pathu, path_linku;
456 
457  {
458  char* path;
459  ULONG path_len;
460 
461  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &path_len))
463 
464  pathu = utf8_to_utf16(string(path, path_len));
465  }
466 
467  {
468  char* path_link;
469  ULONG path_link_len;
470 
471  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH_LINK, (void**)&path_link, &path_link_len))
472  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"path_link");
473 
474  path_linku = utf8_to_utf16(string(path_link, path_link_len));
475  }
476 
477  if (!CreateHardLinkW((subvolpath + pathu).c_str(), (subvolpath + path_linku).c_str(), nullptr))
478  throw string_error(IDS_RECV_CREATEHARDLINK_FAILED, pathu.c_str(), path_linku.c_str(), GetLastError(), format_message(GetLastError()).c_str());
479 }
480 
482  wstring pathu;
483  ULONG att;
484 
485  {
486  char* path;
487  ULONG pathlen;
488 
489  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
491 
492  pathu = utf8_to_utf16(string(path, pathlen));
493  }
494 
495  att = GetFileAttributesW((subvolpath + pathu).c_str());
496  if (att == INVALID_FILE_ATTRIBUTES)
498 
499  if (att & FILE_ATTRIBUTE_READONLY) {
500  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att & ~FILE_ATTRIBUTE_READONLY))
502  }
503 
504  if (!DeleteFileW((subvolpath + pathu).c_str()))
506 }
507 
509  wstring pathu;
510  ULONG att;
511 
512  {
513  char* path;
514  ULONG pathlen;
515 
516  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
518 
519  pathu = utf8_to_utf16(string(path, pathlen));
520  }
521 
522  att = GetFileAttributesW((subvolpath + pathu).c_str());
523  if (att == INVALID_FILE_ATTRIBUTES)
525 
526  if (att & FILE_ATTRIBUTE_READONLY) {
527  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att & ~FILE_ATTRIBUTE_READONLY))
529  }
530 
531  if (!RemoveDirectoryW((subvolpath + pathu).c_str()))
533 }
534 
536  string xattrname;
537  uint8_t* xattrdata;
538  ULONG xattrdatalen;
539  wstring pathu;
540 
541  {
542  char* path;
543  ULONG pathlen;
544 
545  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
547 
548  pathu = utf8_to_utf16(string(path, pathlen));
549  }
550 
551  {
552  char* xattrnamebuf;
553  ULONG xattrnamelen;
554 
555  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_XATTR_NAME, (void**)&xattrnamebuf, &xattrnamelen))
556  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"xattr_name");
557 
558  xattrname = string(xattrnamebuf, xattrnamelen);
559  }
560 
561  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_XATTR_DATA, (void**)&xattrdata, &xattrdatalen))
562  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"xattr_data");
563 
564  if (xattrname.length() > XATTR_USER.length() && xattrname.substr(0, XATTR_USER.length()) == XATTR_USER &&
565  xattrname != EA_DOSATTRIB && xattrname != EA_EA && xattrname != EA_REPARSE) {
566  ULONG att;
567 
568  auto streamname = utf8_to_utf16(xattrname);
569 
570  att = GetFileAttributesW((subvolpath + pathu).c_str());
571  if (att == INVALID_FILE_ATTRIBUTES)
573 
574  if (att & FILE_ATTRIBUTE_READONLY) {
575  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att & ~FILE_ATTRIBUTE_READONLY))
577  }
578 
579  streamname = streamname.substr(XATTR_USER.length());
580 
581  win_handle h = CreateFileW((subvolpath + pathu + L":" + streamname).c_str(), GENERIC_WRITE, 0,
582  nullptr, CREATE_ALWAYS, FILE_FLAG_POSIX_SEMANTICS, nullptr);
583  if (h == INVALID_HANDLE_VALUE)
584  throw string_error(IDS_RECV_CANT_CREATE_FILE, (pathu + L":" + streamname).c_str(), GetLastError(), format_message(GetLastError()).c_str());
585 
586  if (xattrdatalen > 0) {
587  if (!WriteFile(h, xattrdata, xattrdatalen, nullptr, nullptr))
589  }
590 
591  if (att & FILE_ATTRIBUTE_READONLY) {
592  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att))
594  }
595  } else {
599  btrfs_set_xattr* bsxa;
600 
601  if (xattrname == EA_NTACL)
602  perms |= WRITE_DAC | WRITE_OWNER;
603  else if (xattrname == EA_EA)
604  perms |= FILE_WRITE_EA;
605 
608  if (h == INVALID_HANDLE_VALUE)
610 
611  size_t bsxalen = offsetof(btrfs_set_xattr, data[0]) + xattrname.length() + xattrdatalen;
612  bsxa = (btrfs_set_xattr*)malloc(bsxalen);
613  if (!bsxa)
615 
616  bsxa->namelen = (uint16_t)xattrname.length();
617  bsxa->valuelen = (uint16_t)xattrdatalen;
618  memcpy(bsxa->data, xattrname.c_str(), xattrname.length());
619  memcpy(&bsxa->data[xattrname.length()], xattrdata, xattrdatalen);
620 
621  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, bsxa, (ULONG)bsxalen, nullptr, 0);
622  if (!NT_SUCCESS(Status)) {
623  free(bsxa);
625  }
626 
627  free(bsxa);
628  }
629 }
630 
632  wstring pathu;
633  string xattrname;
634 
635  {
636  char* path;
637  ULONG pathlen;
638 
639  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
641 
642  pathu = utf8_to_utf16(string(path, pathlen));
643  }
644 
645  {
646  char* xattrnamebuf;
647  ULONG xattrnamelen;
648 
649  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_XATTR_NAME, (void**)&xattrnamebuf, &xattrnamelen))
650  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"xattr_name");
651 
652  xattrname = string(xattrnamebuf, xattrnamelen);
653  }
654 
655  if (xattrname.length() > XATTR_USER.length() && xattrname.substr(0, XATTR_USER.length()) == XATTR_USER && xattrname != EA_DOSATTRIB && xattrname != EA_EA) { // deleting stream
656  ULONG att;
657 
658  auto streamname = utf8_to_utf16(xattrname);
659 
660  streamname = streamname.substr(XATTR_USER.length());
661 
662  att = GetFileAttributesW((subvolpath + pathu).c_str());
663  if (att == INVALID_FILE_ATTRIBUTES)
665 
666  if (att & FILE_ATTRIBUTE_READONLY) {
667  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att & ~FILE_ATTRIBUTE_READONLY))
669  }
670 
671  if (!DeleteFileW((subvolpath + pathu + L":" + streamname).c_str()))
672  throw string_error(IDS_RECV_DELETEFILE_FAILED, (pathu + L":" + streamname).c_str(), GetLastError(), format_message(GetLastError()).c_str());
673 
674  if (att & FILE_ATTRIBUTE_READONLY) {
675  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att))
677  }
678  } else {
682  btrfs_set_xattr* bsxa;
683 
684  if (xattrname == EA_NTACL)
685  perms |= WRITE_DAC | WRITE_OWNER;
686  else if (xattrname == EA_EA)
687  perms |= FILE_WRITE_EA;
688 
691  if (h == INVALID_HANDLE_VALUE)
693 
694  size_t bsxalen = offsetof(btrfs_set_xattr, data[0]) + xattrname.length();
695  bsxa = (btrfs_set_xattr*)malloc(bsxalen);
696  if (!bsxa)
698 
699  bsxa->namelen = (uint16_t)(xattrname.length());
700  bsxa->valuelen = 0;
701  memcpy(bsxa->data, xattrname.c_str(), xattrname.length());
702 
703  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_XATTR, bsxa, (ULONG)bsxalen, nullptr, 0);
704  if (!NT_SUCCESS(Status)) {
705  free(bsxa);
707  }
708 
709  free(bsxa);
710  }
711 }
712 
714  uint64_t* offset;
715  uint8_t* writedata;
716  ULONG offsetlen, datalen;
717  wstring pathu;
718  HANDLE h;
719  LARGE_INTEGER offli;
722 
723  {
724  char* path;
725  ULONG pathlen;
726 
727  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
729 
730  pathu = utf8_to_utf16(string(path, pathlen));
731  }
732 
733  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_OFFSET, (void**)&offset, &offsetlen))
735 
736  if (offsetlen < sizeof(uint64_t))
737  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"offset", offsetlen, sizeof(uint64_t));
738 
739  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_DATA, (void**)&writedata, &datalen))
741 
742  if (lastwritepath != pathu) {
743  FILE_BASIC_INFO fbi;
744 
748  }
749 
751 
752  lastwriteatt = GetFileAttributesW((subvolpath + pathu).c_str());
755 
759  }
760 
761  h = CreateFileW((subvolpath + pathu).c_str(), FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, 0, nullptr, OPEN_EXISTING,
763  if (h == INVALID_HANDLE_VALUE)
765 
766  lastwritepath = pathu;
767  lastwritefile = h;
768 
769  memset(&fbi, 0, sizeof(FILE_BASIC_INFO));
770 
771  fbi.LastWriteTime.QuadPart = -1;
772 
773  Status = NtSetInformationFile(h, &iosb, &fbi, sizeof(FILE_BASIC_INFO), FileBasicInformation);
774  if (!NT_SUCCESS(Status))
775  throw ntstatus_error(Status);
776  } else
777  h = lastwritefile;
778 
779  offli.QuadPart = *offset;
780 
783 
784  if (!WriteFile(h, writedata, datalen, nullptr, nullptr))
786 }
787 
789  uint64_t *offset, *cloneoffset, *clonetransid, *clonelen;
790  BTRFS_UUID* cloneuuid;
791  ULONG i, offsetlen, cloneoffsetlen, cloneuuidlen, clonetransidlen, clonelenlen;
792  wstring pathu, clonepathu, clonepar;
793  btrfs_find_subvol bfs;
796  WCHAR cloneparw[MAX_PATH];
798  LARGE_INTEGER filesize;
799  bool found = false;
800 
801  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_OFFSET, (void**)&offset, &offsetlen))
803 
804  if (offsetlen < sizeof(uint64_t))
805  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"offset", offsetlen, sizeof(uint64_t));
806 
807  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_LENGTH, (void**)&clonelen, &clonelenlen))
808  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_len");
809 
810  if (clonelenlen < sizeof(uint64_t))
811  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"clone_len", clonelenlen, sizeof(uint64_t));
812 
813  {
814  char* path;
815  ULONG pathlen;
816 
817  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
819 
820  pathu = utf8_to_utf16(string(path, pathlen));
821  }
822 
823  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_UUID, (void**)&cloneuuid, &cloneuuidlen))
824  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_uuid");
825 
826  if (cloneuuidlen < sizeof(BTRFS_UUID))
827  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"clone_uuid", cloneuuidlen, sizeof(BTRFS_UUID));
828 
829  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_CTRANSID, (void**)&clonetransid, &clonetransidlen))
830  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_ctransid");
831 
832  if (clonetransidlen < sizeof(uint64_t))
833  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"clone_ctransid", clonetransidlen, sizeof(uint64_t));
834 
835  {
836  char* clonepath;
837  ULONG clonepathlen;
838 
839  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_PATH, (void**)&clonepath, &clonepathlen))
840  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_path");
841 
842  clonepathu = utf8_to_utf16(string(clonepath, clonepathlen));
843  }
844 
845  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_CLONE_OFFSET, (void**)&cloneoffset, &cloneoffsetlen))
846  throw string_error(IDS_RECV_MISSING_PARAM, funcname, L"clone_offset");
847 
848  if (cloneoffsetlen < sizeof(uint64_t))
849  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"clone_offset", cloneoffsetlen, sizeof(uint64_t));
850 
851  for (i = 0; i < cache.size(); i++) {
852  if (!memcmp(cloneuuid, &cache[i].uuid, sizeof(BTRFS_UUID)) && *clonetransid == cache[i].transid) {
853  clonepar = cache[i].path;
854  found = true;
855  break;
856  }
857  }
858 
859  if (!found) {
860  WCHAR volpathw[MAX_PATH];
861 
862  bfs.uuid = *cloneuuid;
863  bfs.ctransid = *clonetransid;
864 
865  Status = NtFsControlFile(dir, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_FIND_SUBVOL, &bfs, sizeof(btrfs_find_subvol),
866  cloneparw, sizeof(cloneparw));
867  if (Status == STATUS_NOT_FOUND)
869  else if (!NT_SUCCESS(Status))
871 
872  if (!GetVolumePathNameW(dirpath.c_str(), volpathw, (sizeof(volpathw) / sizeof(WCHAR)) - 1))
874 
875  clonepar = volpathw;
876  if (clonepar.substr(clonepar.length() - 1) == L"\\")
877  clonepar = clonepar.substr(0, clonepar.length() - 1);
878 
879  clonepar += cloneparw;
880  clonepar += L"\\";
881 
882  add_cache_entry(cloneuuid, *clonetransid, clonepar);
883  }
884 
885  {
888  if (src == INVALID_HANDLE_VALUE)
889  throw string_error(IDS_RECV_CANT_OPEN_FILE, funcname, (clonepar + clonepathu).c_str(), GetLastError(), format_message(GetLastError()).c_str());
890 
893  if (dest == INVALID_HANDLE_VALUE)
895 
896  if (!GetFileSizeEx(dest, &filesize))
898 
899  if ((uint64_t)filesize.QuadPart < *offset + *clonelen) {
900  LARGE_INTEGER sizeli;
901 
902  sizeli.QuadPart = *offset + *clonelen;
903 
906 
907  if (!SetEndOfFile(dest))
909  }
910 
911  ded.FileHandle = src;
912  ded.SourceFileOffset.QuadPart = *cloneoffset;
914  ded.ByteCount.QuadPart = *clonelen;
915 
916  Status = NtFsControlFile(dest, nullptr, nullptr, nullptr, &iosb, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &ded, sizeof(DUPLICATE_EXTENTS_DATA),
917  nullptr, 0);
918  if (!NT_SUCCESS(Status))
920  }
921 }
922 
924  uint64_t* size;
925  ULONG sizelen;
926  wstring pathu;
927  LARGE_INTEGER sizeli;
928  DWORD att;
929 
930  {
931  char* path;
932  ULONG pathlen;
933 
934  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
936 
937  pathu = utf8_to_utf16(string(path, pathlen));
938  }
939 
940  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_SIZE, (void**)&size, &sizelen))
942 
943  if (sizelen < sizeof(uint64_t))
944  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"size", sizelen, sizeof(uint64_t));
945 
946  att = GetFileAttributesW((subvolpath + pathu).c_str());
947  if (att == INVALID_FILE_ATTRIBUTES)
949 
950  if (att & FILE_ATTRIBUTE_READONLY) {
951  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att & ~FILE_ATTRIBUTE_READONLY))
953  }
954 
955  {
956  win_handle h = CreateFileW((subvolpath + pathu).c_str(), FILE_WRITE_DATA, 0, nullptr, OPEN_EXISTING,
958 
959  if (h == INVALID_HANDLE_VALUE)
961 
962  sizeli.QuadPart = *size;
963 
966 
967  if (!SetEndOfFile(h))
969  }
970 
971  if (att & FILE_ATTRIBUTE_READONLY) {
972  if (!SetFileAttributesW((subvolpath + pathu).c_str(), att))
974  }
975 }
976 
978  win_handle h;
979  uint32_t* mode;
980  ULONG modelen;
981  wstring pathu;
985 
986  {
987  char* path;
988  ULONG pathlen;
989 
990  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
992 
993  pathu = utf8_to_utf16(string(path, pathlen));
994  }
995 
996  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_MODE, (void**)&mode, &modelen))
998 
999  if (modelen < sizeof(uint32_t))
1000  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"mode", modelen, sizeof(uint32_t));
1001 
1002  h = CreateFileW((subvolpath + pathu).c_str(), WRITE_DAC, 0, nullptr, OPEN_EXISTING,
1004  if (h == INVALID_HANDLE_VALUE)
1006 
1007  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
1008 
1009  bsii.mode_changed = true;
1010  bsii.st_mode = *mode;
1011 
1012  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0);
1013  if (!NT_SUCCESS(Status))
1015 }
1016 
1018  win_handle h;
1019  uint32_t *uid, *gid;
1020  ULONG uidlen, gidlen;
1021  wstring pathu;
1022  btrfs_set_inode_info bsii;
1023 
1024  {
1025  char* path;
1026  ULONG pathlen;
1027 
1028  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
1030 
1031  pathu = utf8_to_utf16(string(path, pathlen));
1032  }
1033 
1034  h = CreateFileW((subvolpath + pathu).c_str(), FILE_WRITE_ATTRIBUTES | WRITE_OWNER | WRITE_DAC, 0, nullptr, OPEN_EXISTING,
1036  if (h == INVALID_HANDLE_VALUE)
1038 
1039  memset(&bsii, 0, sizeof(btrfs_set_inode_info));
1040 
1041  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_UID, (void**)&uid, &uidlen)) {
1042  if (uidlen < sizeof(uint32_t))
1043  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"uid", uidlen, sizeof(uint32_t));
1044 
1045  bsii.uid_changed = true;
1046  bsii.st_uid = *uid;
1047  }
1048 
1049  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_GID, (void**)&gid, &gidlen)) {
1050  if (gidlen < sizeof(uint32_t))
1051  throw string_error(IDS_RECV_SHORT_PARAM, funcname, L"gid", gidlen, sizeof(uint32_t));
1052 
1053  bsii.gid_changed = true;
1054  bsii.st_gid = *gid;
1055  }
1056 
1057  if (bsii.uid_changed || bsii.gid_changed) {
1058  NTSTATUS Status;
1060 
1061  Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_SET_INODE_INFO, &bsii, sizeof(btrfs_set_inode_info), nullptr, 0);
1062  if (!NT_SUCCESS(Status))
1064  }
1065 }
1066 
1068  return (t->seconds * 10000000) + (t->nanoseconds / 100) + 116444736000000000;
1069 }
1070 
1072  wstring pathu;
1073  win_handle h;
1074  FILE_BASIC_INFO fbi;
1075  BTRFS_TIME* time;
1076  ULONG timelen;
1078  NTSTATUS Status;
1079 
1080  {
1081  char* path;
1082  ULONG pathlen;
1083 
1084  if (!find_tlv(data, cmd->length, BTRFS_SEND_TLV_PATH, (void**)&path, &pathlen))
1086 
1087  pathu = utf8_to_utf16(string(path, pathlen));
1088  }
1089 
1090  h = CreateFileW((subvolpath + pathu).c_str(), FILE_WRITE_ATTRIBUTES, 0, nullptr, OPEN_EXISTING,
1092  if (h == INVALID_HANDLE_VALUE)
1094 
1095  memset(&fbi, 0, sizeof(FILE_BASIC_INFO));
1096 
1097  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_OTIME, (void**)&time, &timelen) && timelen >= sizeof(BTRFS_TIME))
1098  fbi.CreationTime.QuadPart = unix_time_to_win(time);
1099 
1100  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_ATIME, (void**)&time, &timelen) && timelen >= sizeof(BTRFS_TIME))
1101  fbi.LastAccessTime.QuadPart = unix_time_to_win(time);
1102 
1103  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_MTIME, (void**)&time, &timelen) && timelen >= sizeof(BTRFS_TIME))
1104  fbi.LastWriteTime.QuadPart = unix_time_to_win(time);
1105 
1106  if (find_tlv(data, cmd->length, BTRFS_SEND_TLV_CTIME, (void**)&time, &timelen) && timelen >= sizeof(BTRFS_TIME))
1107  fbi.ChangeTime.QuadPart = unix_time_to_win(time);
1108 
1109  Status = NtSetInformationFile(h, &iosb, &fbi, sizeof(FILE_BASIC_INFO), FileBasicInformation);
1110  if (!NT_SUCCESS(Status))
1111  throw ntstatus_error(Status);
1112 }
1113 
1114 static void delete_directory(const wstring& dir) {
1115  WIN32_FIND_DATAW fff;
1116 
1117  fff_handle h = FindFirstFileW((dir + L"*").c_str(), &fff);
1118 
1119  if (h == INVALID_HANDLE_VALUE)
1120  return;
1121 
1122  do {
1123  wstring file;
1124 
1125  file = fff.cFileName;
1126 
1127  if (file != L"." && file != L"..") {
1128  if (fff.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1129  SetFileAttributesW((dir + file).c_str(), fff.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
1130 
1131  if (fff.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1132  if (!(fff.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
1133  delete_directory(dir + file + L"\\");
1134  else
1135  RemoveDirectoryW((dir + file).c_str());
1136  } else
1137  DeleteFileW((dir + file).c_str());
1138  }
1139  } while (FindNextFileW(h, &fff));
1140 
1141  RemoveDirectoryW(dir.c_str());
1142 }
1143 
1145  uint32_t crc32 = cmd->csum, calc;
1146 
1147  cmd->csum = 0;
1148 
1149  calc = calc_crc32c(0, (uint8_t*)cmd, sizeof(btrfs_send_command));
1150 
1151  if (cmd->length > 0)
1152  calc = calc_crc32c(calc, data, cmd->length);
1153 
1154  return calc == crc32 ? true : false;
1155 }
1156 
1158  try {
1160  bool ended = false;
1161 
1162  if (!ReadFile(f, &header, sizeof(btrfs_send_header), nullptr, nullptr))
1164 
1165  *pos += sizeof(btrfs_send_header);
1166 
1167  if (memcmp(header.magic, BTRFS_SEND_MAGIC, sizeof(header.magic)))
1169 
1170  if (header.version > 1)
1172 
1174 
1176  lastwritepath = L"";
1177  lastwriteatt = 0;
1178 
1179  while (true) {
1181  uint8_t* data = nullptr;
1182  ULONG progress;
1183 
1184  if (cancelling)
1185  break;
1186 
1187  progress = (ULONG)((float)*pos * 65536.0f / (float)size);
1189 
1190  if (!ReadFile(f, &cmd, sizeof(btrfs_send_command), nullptr, nullptr)) {
1191  if (GetLastError() != ERROR_HANDLE_EOF)
1193 
1194  break;
1195  }
1196 
1197  *pos += sizeof(btrfs_send_command);
1198 
1199  if (cmd.length > 0) {
1200  if (*pos + cmd.length > size)
1202 
1203  data = (uint8_t*)malloc(cmd.length);
1204  if (!data)
1206  }
1207 
1208  try {
1209  if (data) {
1210  if (!ReadFile(f, data, cmd.length, nullptr, nullptr))
1212 
1213  *pos += cmd.length;
1214  }
1215 
1216  if (!check_csum(&cmd, data))
1218 
1219  if (cmd.cmd == BTRFS_SEND_CMD_END) {
1220  ended = true;
1221  break;
1222  }
1223 
1228  }
1229 
1231 
1233  lastwritepath = L"";
1234  lastwriteatt = 0;
1235  }
1236 
1237  switch (cmd.cmd) {
1238  case BTRFS_SEND_CMD_SUBVOL:
1239  cmd_subvol(hwnd, &cmd, data, parent);
1240  break;
1241 
1244  break;
1245 
1246  case BTRFS_SEND_CMD_MKFILE:
1247  case BTRFS_SEND_CMD_MKDIR:
1248  case BTRFS_SEND_CMD_MKNOD:
1249  case BTRFS_SEND_CMD_MKFIFO:
1250  case BTRFS_SEND_CMD_MKSOCK:
1252  cmd_mkfile(hwnd, &cmd, data);
1253  break;
1254 
1255  case BTRFS_SEND_CMD_RENAME:
1256  cmd_rename(hwnd, &cmd, data);
1257  break;
1258 
1259  case BTRFS_SEND_CMD_LINK:
1260  cmd_link(hwnd, &cmd, data);
1261  break;
1262 
1263  case BTRFS_SEND_CMD_UNLINK:
1264  cmd_unlink(hwnd, &cmd, data);
1265  break;
1266 
1267  case BTRFS_SEND_CMD_RMDIR:
1268  cmd_rmdir(hwnd, &cmd, data);
1269  break;
1270 
1272  cmd_setxattr(hwnd, &cmd, data);
1273  break;
1274 
1277  break;
1278 
1279  case BTRFS_SEND_CMD_WRITE:
1280  cmd_write(hwnd, &cmd, data);
1281  break;
1282 
1283  case BTRFS_SEND_CMD_CLONE:
1284  cmd_clone(hwnd, &cmd, data);
1285  break;
1286 
1288  cmd_truncate(hwnd, &cmd, data);
1289  break;
1290 
1291  case BTRFS_SEND_CMD_CHMOD:
1292  cmd_chmod(hwnd, &cmd, data);
1293  break;
1294 
1295  case BTRFS_SEND_CMD_CHOWN:
1296  cmd_chown(hwnd, &cmd, data);
1297  break;
1298 
1299  case BTRFS_SEND_CMD_UTIMES:
1300  cmd_utimes(hwnd, &cmd, data);
1301  break;
1302 
1304  // does nothing
1305  break;
1306 
1307  default:
1309  }
1310  } catch (...) {
1311  if (data) free(data);
1312  throw;
1313  }
1314 
1315  if (data) free(data);
1316  }
1317 
1322  }
1323 
1325  }
1326 
1327  if (!ended && !cancelling)
1329 
1330  if (!cancelling) {
1331  NTSTATUS Status;
1334 
1335  brs.generation = stransid;
1336  brs.uuid = subvol_uuid;
1337 
1338  Status = NtFsControlFile(dir, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_RECEIVED_SUBVOL, &brs, sizeof(btrfs_received_subvol),
1339  nullptr, 0);
1340  if (!NT_SUCCESS(Status))
1342  }
1343 
1344  CloseHandle(dir);
1345 
1348  } catch (...) {
1349  if (subvolpath != L"") {
1350  ULONG attrib;
1351 
1352  attrib = GetFileAttributesW(subvolpath.c_str());
1353  attrib &= ~FILE_ATTRIBUTE_READONLY;
1354 
1355  if (SetFileAttributesW(subvolpath.c_str(), attrib))
1357  }
1358 
1359  throw;
1360  }
1361 }
1362 
1363 #if defined(_X86_) || defined(_AMD64_)
1364 static void check_cpu() {
1365  bool have_sse42 = false;
1366 
1367 #ifndef _MSC_VER
1368  {
1369  uint32_t eax, ebx, ecx, edx;
1370 
1371  __cpuid(1, eax, ebx, ecx, edx);
1372 
1373  if (__get_cpuid(1, &eax, &ebx, &ecx, &edx))
1374  have_sse42 = ecx & bit_SSE4_2;
1375  }
1376 #else
1377  {
1378  int cpu_info[4];
1379 
1380  __cpuid(cpu_info, 1);
1381  have_sse42 = (unsigned int)cpu_info[2] & (1 << 20);
1382  }
1383 #endif
1384 
1385  if (have_sse42)
1386  calc_crc32c = calc_crc32c_hw;
1387 }
1388 #endif
1389 
1392  uint64_t pos = 0;
1393  bool b = true;
1394 
1395  running = true;
1396 
1397  try {
1398  win_handle f = CreateFileW(streamfile.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
1399  if (f == INVALID_HANDLE_VALUE)
1401 
1402  if (!GetFileSizeEx(f, &size))
1404 
1405  {
1410 
1411  do {
1412  do_recv(f, &pos, size.QuadPart, parent);
1413  } while (pos < (uint64_t)size.QuadPart);
1414  }
1415  } catch (const exception& e) {
1416  auto msg = utf8_to_utf16(e.what());
1417 
1418  SetDlgItemTextW(hwnd, IDC_RECV_MSG, msg.c_str());
1419 
1420  SendMessageW(GetDlgItem(hwnd, IDC_RECV_PROGRESS), PBM_SETSTATE, PBST_ERROR, 0);
1421 
1422  b = false;
1423  }
1424 
1425  if (b && hwnd) {
1426  wstring s;
1427 
1429 
1430  if (num_received == 1) {
1432  SetDlgItemTextW(hwnd, IDC_RECV_MSG, s.c_str());
1433  } else {
1434  wstring t;
1435 
1437 
1439 
1440  SetDlgItemTextW(hwnd, IDC_RECV_MSG, t.c_str());
1441  }
1442 
1444 
1445  SetDlgItemTextW(hwnd, IDCANCEL, s.c_str());
1446  }
1447 
1448  thread = nullptr;
1449  running = false;
1450 
1451  return 0;
1452 }
1453 
1454 static DWORD WINAPI global_recv_thread(LPVOID lpParameter) {
1455  BtrfsRecv* br = (BtrfsRecv*)lpParameter;
1456 
1457  return br->recv_thread();
1458 }
1459 
1461  switch (uMsg) {
1462  case WM_INITDIALOG:
1463  try {
1464  this->hwnd = hwndDlg;
1465  thread = CreateThread(nullptr, 0, global_recv_thread, this, 0, nullptr);
1466 
1467  if (!thread)
1469  } catch (const exception& e) {
1470  auto msg = utf8_to_utf16(e.what());
1471 
1472  SetDlgItemTextW(hwnd, IDC_RECV_MSG, msg.c_str());
1473 
1474  SendMessageW(GetDlgItem(hwnd, IDC_RECV_PROGRESS), PBM_SETSTATE, PBST_ERROR, 0);
1475  }
1476  break;
1477 
1478  case WM_COMMAND:
1479  switch (HIWORD(wParam)) {
1480  case BN_CLICKED:
1481  switch (LOWORD(wParam)) {
1482  case IDOK:
1483  case IDCANCEL:
1484  if (running) {
1485  wstring s;
1486 
1487  cancelling = true;
1488 
1490  throw last_error(GetLastError());
1491 
1492  SetDlgItemTextW(hwnd, IDC_RECV_MSG, s.c_str());
1494 
1496  throw last_error(GetLastError());
1497 
1498  SetDlgItemTextW(hwnd, IDCANCEL, s.c_str());
1499  } else
1500  EndDialog(hwndDlg, 1);
1501 
1502  return true;
1503  }
1504  break;
1505  }
1506  break;
1507  }
1508 
1509  return false;
1510 }
1511 
1513  BtrfsRecv* br;
1514 
1515  if (uMsg == WM_INITDIALOG) {
1517  br = (BtrfsRecv*)lParam;
1518  } else {
1519  br = (BtrfsRecv*)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA);
1520  }
1521 
1522  if (br)
1523  return br->RecvProgressDlgProc(hwndDlg, uMsg, wParam, lParam);
1524  else
1525  return false;
1526 }
1527 
1528 void BtrfsRecv::Open(HWND hwnd, const wstring& file, const wstring& path, bool quiet) {
1529  streamfile = file;
1530  dirpath = path;
1531  subvolpath = L"";
1532 
1533 #if defined(_X86_) || defined(_AMD64_)
1534  check_cpu();
1535 #endif
1536 
1537  if (quiet)
1538  recv_thread();
1539  else {
1541  throw last_error(GetLastError());
1542  }
1543 }
1544 
1545 extern "C" void CALLBACK RecvSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
1546  try {
1548  WCHAR file[MAX_PATH];
1549  win_handle token;
1551  LUID luid;
1552  ULONG tplen;
1553 
1554  set_dpi_aware();
1555 
1557  throw last_error(GetLastError());
1558 
1559  tplen = offsetof(TOKEN_PRIVILEGES, Privileges[0]) + (3 * sizeof(LUID_AND_ATTRIBUTES));
1560  tp = (TOKEN_PRIVILEGES*)malloc(tplen);
1561  if (!tp)
1563 
1564  tp->PrivilegeCount = 3;
1565 
1566 #ifdef __clang__
1567 #pragma clang diagnostic push
1568 #pragma clang diagnostic ignored "-Warray-bounds"
1569 #endif // __clang__
1570 
1571  if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid)) {
1572  free(tp);
1573  throw last_error(GetLastError());
1574  }
1575 
1576  tp->Privileges[0].Luid = luid;
1577  tp->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1578 
1579  if (!LookupPrivilegeValueW(nullptr, L"SeSecurityPrivilege", &luid)) {
1580  free(tp);
1581  throw last_error(GetLastError());
1582  }
1583 
1584  tp->Privileges[1].Luid = luid;
1585  tp->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
1586 
1587  if (!LookupPrivilegeValueW(nullptr, L"SeRestorePrivilege", &luid)) {
1588  free(tp);
1589  throw last_error(GetLastError());
1590  }
1591 
1592  tp->Privileges[2].Luid = luid;
1593  tp->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED;
1594 
1595  if (!AdjustTokenPrivileges(token, false, tp, tplen, nullptr, nullptr)) {
1596  free(tp);
1597  throw last_error(GetLastError());
1598  }
1599 
1600 #ifdef __clang__
1601  #pragma clang diagnostic pop
1602 #endif // __clang__
1603 
1604  file[0] = 0;
1605 
1606  memset(&ofn, 0, sizeof(OPENFILENAMEW));
1607  ofn.lStructSize = sizeof(OPENFILENAMEW);
1608  ofn.hwndOwner = hwnd;
1609  ofn.hInstance = module;
1610  ofn.lpstrFile = file;
1611  ofn.nMaxFile = sizeof(file) / sizeof(WCHAR);
1613 
1614  if (GetOpenFileNameW(&ofn)) {
1615  BtrfsRecv recv;
1616 
1617  recv.Open(hwnd, file, lpszCmdLine, false);
1618  }
1619 
1620  free(tp);
1621  } catch (const exception& e) {
1622  error_message(hwnd, e.what());
1623  }
1624 }
1625 
1626 extern "C" void CALLBACK RecvSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
1627  try {
1629 
1630  command_line_to_args(lpszCmdLine, args);
1631 
1632  if (args.size() >= 2) {
1633  win_handle token;
1635  ULONG tplen;
1636  LUID luid;
1637 
1639  return;
1640 
1641  tplen = offsetof(TOKEN_PRIVILEGES, Privileges[0]) + (3 * sizeof(LUID_AND_ATTRIBUTES));
1642  tp = (TOKEN_PRIVILEGES*)malloc(tplen);
1643  if (!tp)
1644  return;
1645 
1646  tp->PrivilegeCount = 3;
1647 
1648 #ifdef __clang__
1649 #pragma clang diagnostic push
1650 #pragma clang diagnostic ignored "-Warray-bounds"
1651 #endif // __clang__
1652 
1653  if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid)) {
1654  free(tp);
1655  return;
1656  }
1657 
1658  tp->Privileges[0].Luid = luid;
1659  tp->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1660 
1661  if (!LookupPrivilegeValueW(nullptr, L"SeSecurityPrivilege", &luid)) {
1662  free(tp);
1663  return;
1664  }
1665 
1666  tp->Privileges[1].Luid = luid;
1667  tp->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
1668 
1669  if (!LookupPrivilegeValueW(nullptr, L"SeRestorePrivilege", &luid)) {
1670  free(tp);
1671  return;
1672  }
1673 
1674  tp->Privileges[2].Luid = luid;
1675  tp->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED;
1676 
1677 #ifdef __clang__
1678 #pragma clang diagnostic pop
1679 #endif // __clang__
1680 
1681  if (!AdjustTokenPrivileges(token, false, tp, tplen, nullptr, nullptr)) {
1682  free(tp);
1683  return;
1684  }
1685 
1686  free(tp);
1687 
1688  BtrfsRecv br;
1689  br.Open(nullptr, args[0], args[1], true);
1690  }
1691  } catch (const exception& e) {
1692  cerr << "Error: " << e.what() << endl;
1693  }
1694 }
#define IDS_RECV_MKNOD_FAILED
Definition: resource.h:141
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
#define BTRFS_SEND_TLV_OFFSET
Definition: btrfs.h:585
#define OFN_FILEMUSTEXIST
Definition: commdlg.h:106
#define IDS_OUT_OF_MEMORY
Definition: resource.h:5
#define OFN_EXPLORER
Definition: commdlg.h:104
Definition: cache.c:48
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:240
#define BTRFS_SEND_CMD_LINK
Definition: btrfs.h:554
#define FILE_WRITE_EA
Definition: nt_native.h:640
ULONG num_received
Definition: recv.h:81
#define IDS_RECV_CANT_FIND_PARENT_SUBVOL
Definition: resource.h:166
#define PBM_SETRANGE32
Definition: commctrl.h:2188
Definition: pdh_main.c:93
#define IDS_RECV_FILE_TRUNCATED
Definition: resource.h:163
#define IDOK
Definition: winuser.h:824
#define CloseHandle
Definition: compat.h:598
HMODULE module
Definition: main.cpp:47
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
#define BTRFS_SEND_TLV_UID
Definition: btrfs.h:573
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define IDS_RECV_GETFILESIZEEX_FAILED
Definition: resource.h:173
#define BTRFS_SEND_TLV_GID
Definition: btrfs.h:574
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BTRFS_UUID uuid
Definition: recv.h:30
#define args
Definition: format.c:66
void cmd_chown(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:1017
wstring format_ntstatus(NTSTATUS Status)
Definition: main.cpp:184
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
Definition: recv.h:35
void CALLBACK RecvSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
Definition: recv.cpp:1626
#define BTRFS_SEND_TLV_PATH_TO
Definition: btrfs.h:583
#define BTRFS_SEND_TLV_DATA
Definition: btrfs.h:586
bool running
Definition: recv.h:84
#define IDS_RECV_CANCELLED
Definition: resource.h:165
HWND hwndOwner
Definition: commdlg.h:330
Definition: ftp_var.h:139
static void delete_directory(const wstring &dir)
Definition: recv.cpp:1114
HANDLE dir
Definition: recv.h:77
GLsizei const GLchar ** path
Definition: glext.h:7234
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
uint64_t transid
Definition: recv.h:31
#define IDS_RECV_RECEIVED_SUBVOL_FAILED
Definition: resource.h:159
#define FILE_FLAG_POSIX_SEMANTICS
Definition: disk.h:40
#define free
Definition: debug_ros.c:5
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
#define IDS_RECV_CSUM_ERROR
Definition: resource.h:155
LONG NTSTATUS
Definition: precomp.h:26
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
#define CALLBACK
Definition: compat.h:35
void cmd_chmod(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:977
#define IDS_RECV_SUCCESS_PLURAL
Definition: resource.h:175
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
#define IDS_RECV_READFILE_FAILED
Definition: resource.h:133
GLdouble GLdouble t
Definition: gl.h:2047
OPENFILENAME ofn
Definition: main.cpp:37
#define BTRFS_SEND_CMD_SET_XATTR
Definition: btrfs.h:557
#define IDS_RECV_SETINODEINFO_FAILED
Definition: resource.h:150
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
void cmd_snapshot(HWND hwnd, btrfs_send_command *cmd, uint8_t *data, const win_handle &parent)
Definition: recv.cpp:154
#define PBM_SETPOS
Definition: commctrl.h:2184
#define IDS_RECV_CANT_FIND_CLONE_SUBVOL
Definition: resource.h:172
void cmd_unlink(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:481
char * cmd
Definition: vfdcmd.c:85
#define BTRFS_SEND_TLV_XATTR_NAME
Definition: btrfs.h:580
BOOL WINAPI GetVolumePathNameW(IN LPCWSTR lpszFileName, IN LPWSTR lpszVolumePathName, IN DWORD cchBufferLength)
Definition: volume.c:815
UINT_PTR WPARAM
Definition: windef.h:207
#define GetWindowLongPtrW
Definition: winuser.h:4819
#define FILE_BEGIN
Definition: compat.h:620
#define BTRFS_SEND_TLV_MTIME
Definition: btrfs.h:577
#define BTRFS_SEND_CMD_UPDATE_EXTENT
Definition: btrfs.h:566
__u16 time
Definition: mkdosfs.c:366
#define WRITE_OWNER
Definition: nt_native.h:60
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
unsigned short int uint16_t
Definition: acefiex.h:54
#define uint16_t
Definition: nsiface.idl:60
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
int32_t INT_PTR
Definition: typedefs.h:64
#define IDS_RECV_UNKNOWN_COMMAND
Definition: resource.h:135
#define BTRFS_SEND_TLV_XATTR_DATA
Definition: btrfs.h:581
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1030
void cmd_truncate(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:923
struct _REPARSE_DATA_BUFFER::@303::@305 SymbolicLinkReparseBuffer
GLint namelen
Definition: glext.h:7232
Definition: match.c:390
#define BTRFS_SEND_TLV_INODE
Definition: btrfs.h:570
static DWORD WINAPI global_recv_thread(LPVOID lpParameter)
Definition: recv.cpp:1454
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
WPARAM wParam
Definition: combotst.c:138
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_SHARE_READ
Definition: compat.h:136
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
DWORD nMaxFile
Definition: commdlg.h:337
#define BTRFS_SEND_CMD_UTIMES
Definition: btrfs.h:564
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
Definition: fs.h:78
#define IDS_RECV_SHORT_PARAM
Definition: resource.h:140
#define BTRFS_SEND_CMD_MKFIFO
Definition: btrfs.h:550
#define FILE_TRAVERSE
Definition: nt_native.h:643
WCHAR PathBuffer[1]
Definition: shellext.h:176
#define IDC_RECV_PROGRESS
Definition: resource.h:264
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
BTRFS_UUID subvol_uuid
Definition: recv.h:83
#define L(x)
Definition: ntvdm.h:50
void error_message(HWND hwnd, const char *msg)
Definition: main.cpp:783
#define IDS_RECV_CREATETHREAD_FAILED
Definition: resource.h:162
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define BTRFS_SEND_TLV_TRANSID
Definition: btrfs.h:569
void do_recv(const win_handle &f, uint64_t *pos, uint64_t size, const win_handle &parent)
Definition: recv.cpp:1157
#define FSCTL_BTRFS_CREATE_SNAPSHOT
Definition: btrfsioctl.h:9
#define IDS_RECV_UNSUPPORTED_VERSION
Definition: resource.h:157
#define BTRFS_SEND_CMD_SUBVOL
Definition: btrfs.h:545
#define e
Definition: ke_i.h:82
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
#define BTRFS_SEND_TLV_CLONE_PATH
Definition: btrfs.h:589
#define FILE_READ_DATA
Definition: nt_native.h:628
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 token
Definition: glfuncs.h:210
#define GENERIC_WRITE
Definition: nt_native.h:90
#define IDS_RECV_GETFILEATTRIBUTES_FAILED
Definition: resource.h:154
BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn)
Definition: filedlg.c:4677
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1044
#define BTRFS_SEND_CMD_TRUNCATE
Definition: btrfs.h:561
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
void cmd_rmdir(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:508
#define GWLP_USERDATA
Definition: treelist.c:63
#define BTRFS_SEND_TLV_OTIME
Definition: btrfs.h:579
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
BTRFS_UUID uuid
Definition: btrfsioctl.h:263
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define IDS_RECV_REMOVEDIRECTORY_FAILED
Definition: resource.h:171
#define offsetof(TYPE, MEMBER)
DWORD recv_thread()
Definition: recv.cpp:1390
LONG_PTR LPARAM
Definition: windef.h:208
#define BTRFS_SEND_CMD_MKSOCK
Definition: btrfs.h:551
#define BTRFS_SEND_CMD_CHOWN
Definition: btrfs.h:563
HINSTANCE hInstance
Definition: commdlg.h:331
wstring streamfile
Definition: recv.h:79
unsigned int dir
Definition: maze.c:112
typedef uuid
#define IDD_RECV_PROGRESS
Definition: resource.h:86
void cmd_clone(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:788
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
#define IDS_RECV_BUTTON_OK
Definition: resource.h:152
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define OPEN_EXISTING
Definition: compat.h:634
static __inline uint64_t unix_time_to_win(BTRFS_TIME *t)
Definition: recv.cpp:1067
#define FSCTL_BTRFS_CREATE_SUBVOL
Definition: btrfsioctl.h:8
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
const string EA_NTACL
Definition: recv.cpp:36
#define IDS_RECV_SETXATTR_FAILED
Definition: resource.h:161
#define BTRFS_SEND_TLV_SIZE
Definition: btrfs.h:571
#define IDS_RECV_SUCCESS
Definition: resource.h:151
Status
Definition: gdiplustypes.h:24
#define BTRFS_SEND_TLV_PATH_LINK
Definition: btrfs.h:584
void wstring_sprintf(wstring &s, wstring fmt,...)
Definition: main.cpp:225
bool cancelling
Definition: recv.h:84
#define IDS_RECV_WRITEFILE_FAILED
Definition: resource.h:145
LARGE_INTEGER SourceFileOffset
Definition: shellext.h:200
#define STATUS_NOT_FOUND
Definition: shellext.h:72
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizeiptr size
Definition: glext.h:5919
#define IDS_RECV_SET_REPARSE_POINT_FAILED
Definition: resource.h:142
#define IDS_RECV_FIND_SUBVOL_FAILED
Definition: resource.h:167
#define TOKEN_QUERY
Definition: setypes.h:924
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
r parent
Definition: btrfs.c:3010
#define BTRFS_SEND_CMD_REMOVE_XATTR
Definition: btrfs.h:558
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_STLP_DECLSPEC _Stl_aligned_buffer< ostream > cerr
Definition: iostream.cpp:102
#define IDS_RECV_NOT_A_SEND_STREAM
Definition: resource.h:156
HANDLE thread
Definition: recv.h:77
GLintptr offset
Definition: glext.h:5920
#define FSCTL_BTRFS_RESERVE_SUBVOL
Definition: btrfsioctl.h:34
#define BTRFS_SEND_TLV_CLONE_LENGTH
Definition: btrfs.h:591
#define funcname
Definition: shellext.h:96
wstring utf8_to_utf16(const string_view &utf8)
Definition: main.cpp:734
#define MAX_PATH
Definition: compat.h:34
DWORD lStructSize
Definition: commdlg.h:329
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define BN_CLICKED
Definition: winuser.h:1915
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WRITE_DAC
Definition: nt_native.h:59
const string EA_DOSATTRIB
Definition: recv.cpp:37
HANDLE lastwritefile
Definition: recv.h:77
Definition: stddef.h:6
void cmd_mkfile(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:277
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl ebx
Definition: synth_sse3d.h:83
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define IDS_RECV_CREATE_SUBVOL_FAILED
Definition: resource.h:138
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
const string XATTR_USER
Definition: recv.cpp:40
#define IDS_RECV_DELETEFILE_FAILED
Definition: resource.h:170
#define BTRFS_SEND_CMD_WRITE
Definition: btrfs.h:559
wstring dirpath
Definition: recv.h:79
void cmd_utimes(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:1071
#define BTRFS_SEND_TLV_PATH
Definition: btrfs.h:582
void Open(HWND hwnd, const wstring &file, const wstring &path, bool quiet)
Definition: recv.cpp:1528
#define FSCTL_BTRFS_FIND_SUBVOL
Definition: btrfsioctl.h:35
#define GetFileSizeEx
Definition: compat.h:616
void cmd_removexattr(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:631
static INT_PTR CALLBACK stub_RecvProgressDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: recv.cpp:1512
#define BTRFS_SEND_TLV_RDEV
Definition: btrfs.h:575
USHORT ReparseDataLength
Definition: shellext.h:166
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define BTRFS_SEND_CMD_CLONE
Definition: btrfs.h:560
#define IDS_RECV_SETFILEPOINTER_FAILED
Definition: resource.h:144
struct tagOFNW OPENFILENAMEW
#define BTRFS_SEND_CMD_MKNOD
Definition: btrfs.h:549
#define FSCTL_BTRFS_MKNOD
Definition: btrfsioctl.h:30
#define BTRFS_SEND_TLV_CTIME
Definition: btrfs.h:576
void cmd_link(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:454
void CALLBACK RecvSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
Definition: recv.cpp:1545
void cmd_subvol(HWND hwnd, btrfs_send_command *cmd, uint8_t *data, const win_handle &parent)
Definition: recv.cpp:64
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
ULONG LowPart
Definition: typedefs.h:106
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
crc_func calc_crc32c
Definition: crc32c.c:23
#define OFN_HIDEREADONLY
Definition: commdlg.h:107
format_message(j_common_ptr cinfo, char *buffer)
Definition: jerror.c:158
GLdouble s
Definition: gl.h:2039
#define GetCurrentProcess()
Definition: compat.h:618
#define GENERIC_READ
Definition: compat.h:135
GLenum src
Definition: glext.h:6340
#define WM_COMMAND
Definition: winuser.h:1730
HANDLE master
Definition: recv.h:77
#define BTRFS_SEND_CMD_END
Definition: btrfs.h:565
#define FSCTL_BTRFS_SET_INODE_INFO
Definition: btrfsioctl.h:11
GLenum mode
Definition: glext.h:6217
BYTE uint8_t
Definition: msvideo1.c:66
#define BTRFS_SEND_CMD_CHMOD
Definition: btrfs.h:562
#define IDS_RECV_MISSING_PARAM
Definition: resource.h:139
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define BTRFS_SEND_CMD_RENAME
Definition: btrfs.h:553
char string[160]
Definition: util.h:11
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:376
#define BTRFS_SEND_MAGIC
Definition: btrfs.h:593
#define S_IFCHR
Definition: ext2fs.h:359
uint64_t st_rdev
Definition: btrfsioctl.h:239
uint8_t type
Definition: btrfsioctl.h:238
void cmd_setxattr(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:535
INT_PTR CALLBACK RecvProgressDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: recv.cpp:1460
#define BTRFS_SEND_TLV_CLONE_UUID
Definition: btrfs.h:587
#define IDS_RECV_CANT_CREATE_FILE
Definition: resource.h:148
#define BTRFS_SEND_TLV_MODE
Definition: btrfs.h:572
#define CREATE_ALWAYS
Definition: disk.h:72
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
const string EA_EA
Definition: recv.cpp:39
UINT64 uint64_t
Definition: types.h:77
static DWORD path_len
Definition: batch.c:31
#define INVALID_SET_FILE_POINTER
Definition: compat.h:591
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
static int quiet
Definition: xmllint.c:168
LPSTR lpstrFile
Definition: commdlg.h:336
static float(__cdecl *square_half_float)(float x
DWORD lastwriteatt
Definition: recv.h:80
static bool check_csum(btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:1144
#define IDS_RECV_DUPLICATE_EXTENTS_FAILED
Definition: resource.h:174
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
wstring lastwritepath
Definition: recv.h:79
void command_line_to_args(LPWSTR cmdline, vector< wstring > &args)
Definition: main.cpp:645
uint64_t stransid
Definition: recv.h:82
void cmd_rename(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:427
#define IDS_RECV_CREATE_SNAPSHOT_FAILED
Definition: resource.h:168
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
#define BTRFS_SEND_CMD_MKFILE
Definition: btrfs.h:547
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
const string EA_REPARSE
Definition: recv.cpp:38
#define BTRFS_SEND_CMD_RMDIR
Definition: btrfs.h:556
LARGE_INTEGER TargetFileOffset
Definition: shellext.h:201
static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
Definition: muireg.c:10
UINT32 uint32_t
Definition: types.h:75
cd_progress_ptr progress
Definition: cdjpeg.h:152
#define CreateFileW
Definition: compat.h:600
#define crc32(crc, buf, len)
Definition: inflate.c:1081
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define msg(x)
Definition: auth_time.c:54
#define IDS_RECV_SETFILEATTRIBUTES_FAILED
Definition: resource.h:153
uint64_t inode
Definition: btrfsioctl.h:237
#define IDS_RECV_CANT_OPEN_PATH
Definition: resource.h:136
wstring path
Definition: recv.h:32
#define FSCTL_BTRFS_RECEIVED_SUBVOL
Definition: btrfsioctl.h:31
Definition: name.c:38
uint16_t type
Definition: btrfs.h:607
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
WCHAR name[1]
Definition: btrfsioctl.h:241
uint16_t length
Definition: btrfs.h:608
#define IDS_RECV_MOVEFILE_FAILED
Definition: resource.h:143
#define FSCTL_BTRFS_SET_XATTR
Definition: btrfsioctl.h:33
#define HIWORD(l)
Definition: typedefs.h:247
Definition: msctf.idl:510
#define BTRFS_SEND_CMD_MKDIR
Definition: btrfs.h:548
unsigned int ULONG
Definition: retypes.h:1
static HINSTANCE hinst
Definition: edit.c:551
#define ERROR_HANDLE_EOF
Definition: winerror.h:140
#define malloc
Definition: debug_ros.c:4
#define BTRFS_SEND_TLV_CLONE_CTRANSID
Definition: btrfs.h:588
#define IDS_RECV_CANT_OPEN_FILE
Definition: resource.h:132
static char * dest
Definition: rtl.c:135
#define BTRFS_SEND_CMD_SNAPSHOT
Definition: btrfs.h:546
#define SetWindowLongPtrW
Definition: winuser.h:5336
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:98
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define IDS_RECV_RESERVE_SUBVOL_FAILED
Definition: resource.h:164
#define BTRFS_SEND_TLV_UUID
Definition: btrfs.h:568
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx
Definition: synth_sse3d.h:85
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDCANCEL
Definition: winuser.h:825
#define BTRFS_SEND_CMD_UNLINK
Definition: btrfs.h:555
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#define uint32_t
Definition: nsiface.idl:61
#define IDS_RECV_SETENDOFFILE_FAILED
Definition: resource.h:147
calc_t calc
Definition: winmain.c:247
#define memset(x, y, z)
Definition: compat.h:39
void add_cache_entry(BTRFS_UUID *uuid, uint64_t transid, const wstring &path)
Definition: recv.cpp:144
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:926
#define IDC_RECV_MSG
Definition: resource.h:325
void set_dpi_aware()
Definition: main.cpp:50
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define WM_INITDIALOG
Definition: winuser.h:1729
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
LARGE_INTEGER ByteCount
Definition: shellext.h:202
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
uint64_t ctransid
Definition: btrfsioctl.h:264
struct CFHEADER header
Definition: fdi.c:101
void cmd_write(HWND hwnd, btrfs_send_command *cmd, uint8_t *data)
Definition: recv.cpp:713
#define SetFilePointer
Definition: compat.h:602
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
wstring subvolpath
Definition: recv.h:79
#define BTRFS_SEND_TLV_CLONE_OFFSET
Definition: btrfs.h:590
#define IDS_RECV_PATH_TOO_LONG
Definition: resource.h:208
LONGLONG QuadPart
Definition: typedefs.h:114
#define BTRFS_SEND_CMD_SYMLINK
Definition: btrfs.h:552
#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
#define BTRFS_SEND_TLV_ATIME
Definition: btrfs.h:578
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define IDS_RECV_CREATEHARDLINK_FAILED
Definition: resource.h:146
DWORD Flags
Definition: commdlg.h:342
Definition: fci.c:126
bool find_tlv(uint8_t *data, ULONG datalen, uint16_t type, void **value, ULONG *len)
Definition: recv.cpp:42
#define IDS_RECV_GETVOLUMEPATHNAME_FAILED
Definition: resource.h:169
GLuint const GLchar * name
Definition: glext.h:6031