110#define MAX_SEND_WRITE 0xc000
111#define SEND_BUFFER_LENGTH 0x100000
155 *tmp = (
num % 10) +
'0';
161 return &
buf[tmp2 +
sizeof(tmp2) - tmp];
191 ERR(
"find_item returned %08lx\n",
Status);
201 ERR(
"find_item returned %08lx\n",
Status);
221 while (le != &
context->orphans) {
247 ERR(
"find_item returned %08lx\n",
Status);
265 WARN(
"symlink data was not inline, returning blank string\n");
297 context->lastinode.deleting =
true;
316 context->lastinode.deleting =
false;
326 context->lastinode.file =
false;
350 context->lastinode.file =
true;
352 context->lastinode.new =
false;
355 while (le != &
context->orphans) {
374 ERR(
"find_send_dir returned %08lx\n",
Status);
395 while (le != &
context->orphans) {
424 context->lastinode.file =
true;
431 ERR(
"get_orphan_name returned %08lx\n",
Status);
449 ERR(
"send_read_symlink returned %08lx\n",
Status);
461 ERR(
"find_send_dir returned %08lx\n",
Status);
473 ERR(
"out of memory\n");
484 if (!
context->lastinode.path) {
485 ERR(
"out of memory\n");
502 ERR(
"out of memory\n");
519 ERR(
"out of memory\n");
619 if (
context->lastinode.o->sd) {
620 if (
context->lastinode.o->sd->name)
624 if (!
context->lastinode.o->sd->name) {
625 ERR(
"out of memory\n");
639 if (!
context->lastinode.path) {
640 ERR(
"out of memory\n");
645 context->lastinode.path[pathlen] = 0;
685 *added_dummy =
false;
696 ERR(
"send_add_dir returned %08lx\n",
Status);
701 *added_dummy =
false;
712 searchkey.
offset = 0xffffffffffffffff;
716 ERR(
"find_item returned %08lx\n",
Status);
734 ERR(
"find_send_dir returned %08lx\n",
Status);
741 ERR(
"send_add_dir returned %08lx\n",
Status);
746 *added_dummy =
false;
754 ERR(
"get_orphan_name returned %08lx\n",
Status);
760 ERR(
"send_add_dir returned %08lx\n",
Status);
793 ERR(
"find_send_dir returned %08lx\n",
Status);
802 while (le != &
context->orphans) {
827 ERR(
"out of memory\n");
855 ERR(
"out of memory\n");
902 ERR(
"find_send_dir returned %08lx\n",
Status);
911 while (le != &
context->orphans) {
935 ERR(
"out of memory\n");
952 ERR(
"out of memory\n");
1074 ERR(
"find_item returned %08lx\n",
Status);
1109 ERR(
"out of memory\n");
1116 le =
context->pending_rmdirs.Flink;
1117 while (le != &
context->pending_rmdirs) {
1146 ERR(
"find_item returned %08lx\n",
Status);
1188 ERR(
"out of memory\n");
1192 dc->namelen =
r->namelen;
1198 while (le != &
context->orphans) {
1217 ERR(
"get_orphan_name returned %08lx\n",
Status);
1224 ERR(
"find_send_dir returned %08lx\n",
Status);
1243 ERR(
"out of memory\n");
1261 ERR(
"out of memory\n");
1283 if (or && !
context->lastinode.o) {
1287 if (!
context->lastinode.path) {
1288 ERR(
"out of memory\n");
1298 ERR(
"find_send_dir returned %08lx\n",
Status);
1310 ERR(
"look_for_collision returned %08lx\n",
Status);
1317 ERR(
"make_file_orphan returned %08lx\n",
Status);
1325 ERR(
"found_path returned %08lx\n",
Status);
1345 if (
context->lastinode.sd->name)
1349 if (!
context->lastinode.sd->name) {
1350 ERR(
"out of memory\n");
1355 context->lastinode.sd->parent =
r->sd;
1362 if (!
context->lastinode.path) {
1363 ERR(
"out of memory\n");
1370 }
else if (
r && !or) {
1373 ERR(
"found_path returned %08lx\n",
Status);
1384 ERR(
"get_dir_last_child returned %08lx\n",
Status);
1388 if (last_inode <= context->
lastinode.inode) {
1399 ERR(
"get_orphan_name returned %08lx\n",
Status);
1408 if (
context->lastinode.sd->name)
1412 if (!
context->lastinode.sd->name) {
1413 ERR(
"out of memory\n");
1419 context->lastinode.sd->dummy =
true;
1426 ERR(
"add_pending_rmdir returned %08lx\n",
Status);
1449 if (!
context->lastinode.path) {
1450 ERR(
"out of memory\n");
1460 le =
context->lastinode.oldrefs.Flink;
1461 while (le != &
context->lastinode.oldrefs) {
1464 bool matched =
false;
1466 le2 =
context->lastinode.refs.Flink;
1467 while (le2 != &
context->lastinode.refs) {
1498 ERR(
"look_for_collision returned %08lx\n",
Status);
1505 ERR(
"make_file_orphan returned %08lx\n",
Status);
1514 ERR(
"wait_for_flush returned %08lx\n",
Status);
1518 if (
context->send->cancelling)
1524 ERR(
"found_path returned %08lx\n",
Status);
1531 if (nameref && !nameref2)
1539 bool deleted =
false;
1559 ERR(
"wait_for_flush returned %08lx\n",
Status);
1563 if (
context->send->cancelling)
1569 ERR(
"send_unlink_command returned %08lx\n",
Status);
1577 if (or == nameref && nameref2) {
1584 if (!
context->lastinode.path) {
1585 ERR(
"out of memory\n");
1589 find_path(
context->lastinode.path, nameref2->sd, nameref2->name, nameref2->namelen);
1620 if (
context->send->cancelling)
1626 ERR(
"find_item returned %08lx\n",
Status);
1631 ERR(
"readonly subvolume changed\n");
1639 ERR(
"find_item returned %08lx\n",
Status);
1644 ERR(
"readonly subvolume changed\n");
1657 while (le !=
exts) {
1660 if (
ext->offset > lastoff) {
1665 ERR(
"out of memory\n");
1671 ext2->offset = lastoff;
1681 lastoff =
ext->offset +
ext->data.decoded_size;
1690 if (
size > lastoff) {
1695 ERR(
"out of memory\n");
1701 ext2->offset = lastoff;
1722 ERR(
"out of memory\n");
1728 ext2->data.decoded_size =
ext->data.decoded_size -
len;
1729 ext2->data.compression =
ext->data.compression;
1730 ext2->data.encryption =
ext->data.encryption;
1731 ext2->data.encoding =
ext->data.encoding;
1732 ext2->data.type =
ext->data.type;
1738 ext->data.decoded_size =
len;
1749 ERR(
"out of memory\n");
1758 ext2->data.compression =
ext->data.compression;
1759 ext2->data.encryption =
ext->data.encryption;
1760 ext2->data.encoding =
ext->data.encoding;
1761 ext2->data.type =
ext->data.type;
1764 if (ed2a->
size == 0) {
1766 ext->data.decoded_size =
len;
1770 ext2->data.decoded_size =
ext->data.decoded_size;
1805 ERR(
"divide_ext returned %08lx\n",
Status);
1808 }
else if (len2 < len1) {
1811 ERR(
"divide_ext returned %08lx\n",
Status);
1816 if (
ext1->list_entry.Flink == &
context->lastinode.exts ||
ext2->list_entry.Flink == &
context->lastinode.oldexts)
1828 ERR(
"divide_ext returned %08lx\n",
Status);
1834 ERR(
"divide_ext returned %08lx\n",
Status);
1854 searchkey.
offset = 0xffffffffffffffff;
1858 ERR(
"find_item returned %08lx\n",
Status);
1863 ERR(
"could not find INODE_REF for inode %I64x\n", searchkey.
obj_id);
1901 searchkey.
offset = 0xffffffffffffffff;
1905 ERR(
"find_item returned %08lx\n",
Status);
1910 ERR(
"could not find INODE_REF for inode %I64x\n", searchkey.
obj_id);
1947 if (!
r &&
context->num_clones > 0) {
1967 ERR(
"find_item returned %08lx\n",
Status);
1991 if ((clone_offset & (
context->Vcb->superblock.sector_size - 1)) == 0 && (clone_len & (
context->Vcb->superblock.sector_size - 1)) == 0) {
2042 ERR(
"find_item returned %08lx\n",
Status);
2069 if (sectlen >
len) {
2093 if (rc >= ei->refcount)
2101 ERR(
"find_item returned %08lx\n",
Status);
2136 ERR(
"add_ext_holes returned %08lx\n",
Status);
2142 ERR(
"add_ext_holes returned %08lx\n",
Status);
2148 ERR(
"sync_ext_cutoff_points returned %08lx\n",
Status);
2200 ERR(
"zlib_decompress returned %08lx\n",
Status);
2207 ERR(
"extent data was truncated\n");
2216 ERR(
"lzo_decompress returned %08lx\n",
Status);
2224 ERR(
"zlib_decompress returned %08lx\n",
Status);
2254 if (ed2->
size == 0) {
2263 ERR(
"wait_for_flush returned %08lx\n",
Status);
2269 if (
context->send->cancelling) {
2296 ERR(
"out of memory\n");
2311 ERR(
"wait_for_flush returned %08lx\n",
Status);
2318 if (
context->send->cancelling) {
2326 skip_start =
addr & (
context->Vcb->superblock.sector_size - 1);
2338 ERR(
"out of memory\n");
2347 ERR(
"load_csum returned %08lx\n",
Status);
2359 ERR(
"read_data returned %08lx\n",
Status);
2393 ERR(
"out of memory\n");
2401 ERR(
"out of memory\n");
2417 ERR(
"out of memory\n");
2427 ERR(
"load_csum returned %08lx\n",
Status);
2437 Status =
read_data(
context->Vcb, ed2->
address, (
uint32_t)ed2->
size,
csum,
false, compbuf,
NULL,
NULL,
NULL, 0,
false,
NormalPagePriority);
2439 ERR(
"read_data returned %08lx\n",
Status);
2454 ERR(
"zlib_decompress returned %08lx\n",
Status);
2464 ERR(
"lzo_decompress returned %08lx\n",
Status);
2474 ERR(
"zstd_decompress returned %08lx\n",
Status);
2492 ERR(
"wait_for_flush returned %08lx\n",
Status);
2499 if (
context->send->cancelling) {
2538 ERR(
"flush_refs returned %08lx\n",
Status);
2542 if (
context->send->cancelling)
2546 if (!
context->lastinode.deleting) {
2547 if (
context->lastinode.file) {
2550 ERR(
"flush_extents returned %08lx\n",
Status);
2554 if (
context->send->cancelling)
2579 le =
context->pending_rmdirs.Flink;
2581 while (le != &
context->pending_rmdirs) {
2611 if (
context->lastinode.path) {
2628 ERR(
"flush_refs returned %08lx\n",
Status);
2632 if (
context->send->cancelling)
2687 ERR(
"out of memory\n");
2746 ERR(
"out of memory\n");
2777 ERR(
"flush_refs returned %08lx\n",
Status);
2781 if (
context->send->cancelling)
2822 }
else if (!
tp && tp2) {
2826 len = tp2->item->size;
2833 ERR(
"(%I64x,%x,%I64x) was truncated\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset);
2866 ERR(
"out of memory\n");
2875 xa->namelen = di->
n;
2876 xa->name = di->
name;
2877 xa->value1len = di->
m;
2878 xa->value1 = di->
name + di->
n;
2888 len = tp2->item->size;
2897 ERR(
"(%I64x,%x,%I64x) was truncated\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset);
2902 while (le != &xattrs) {
2906 xa->value2len = di->
m;
2907 xa->value2 = di->
name + di->
n;
2918 ERR(
"out of memory\n");
2927 xa->namelen = di->
n;
2928 xa->name = di->
name;
2931 xa->value2len = di->
m;
2932 xa->value2 = di->
name + di->
n;
3005 ERR(
"do_write returned %08lx\n",
Status);
3017 ERR(
"find_item returned %08lx\n",
Status);
3023 bool ended1 =
false, ended2 =
false;
3026 ERR(
"find_item returned %08lx\n",
Status);
3043 if (
context->send->cancelling)
3051 ERR(
"find_item returned %08lx\n",
Status);
3057 ERR(
"readonly subvolume changed\n");
3067 ERR(
"find_item returned %08lx\n",
Status);
3073 ERR(
"readonly subvolume changed\n");
3084 ERR(
"skip_to_difference returned %08lx\n",
Status);
3091 bool no_next =
false, no_next2 =
false;
3098 ERR(
"finish_inode returned %08lx\n",
Status);
3103 if (
context->send->cancelling) {
3143 ERR(
"send_inode returned %08lx\n",
Status);
3162 ERR(
"send_inode_ref returned %08lx\n",
Status);
3169 ERR(
"send_inode_extref returned %08lx\n",
Status);
3178 ERR(
"finish_inode returned %08lx\n",
Status);
3183 if (
context->send->cancelling) {
3192 ERR(
"send_inode returned %08lx\n",
Status);
3199 ERR(
"send_inode returned %08lx\n",
Status);
3207 ERR(
"send_inode_ref returned %08lx\n",
Status);
3214 ERR(
"send_inode_ref returned %08lx\n",
Status);
3221 ERR(
"send_inode_extref returned %08lx\n",
Status);
3228 ERR(
"send_inode_extref returned %08lx\n",
Status);
3235 ERR(
"send_extent_data returned %08lx\n",
Status);
3240 if (
context->send->cancelling) {
3247 ERR(
"send_xattr returned %08lx\n",
Status);
3252 if (
context->send->cancelling) {
3277 ERR(
"finish_inode returned %08lx\n",
Status);
3282 if (
context->send->cancelling) {
3291 ERR(
"send_inode returned %08lx\n",
Status);
3298 ERR(
"send_inode_ref returned %08lx\n",
Status);
3305 ERR(
"send_inode_extref returned %08lx\n",
Status);
3312 ERR(
"send_extent_data returned %08lx\n",
Status);
3317 if (
context->send->cancelling) {
3324 ERR(
"send_xattr returned %08lx\n",
Status);
3329 if (
context->send->cancelling) {
3345 ERR(
"finish_inode returned %08lx\n",
Status);
3350 if (
context->send->cancelling) {
3359 ERR(
"send_inode returned %08lx\n",
Status);
3366 ERR(
"send_inode_ref returned %08lx\n",
Status);
3373 ERR(
"send_inode_extref returned %08lx\n",
Status);
3380 ERR(
"send_extent_data returned %08lx\n",
Status);
3385 if (
context->send->cancelling) {
3392 ERR(
"send_xattr returned %08lx\n",
Status);
3397 if (
context->send->cancelling) {
3408 }
while (!ended1 || !ended2);
3422 if (
context->send->cancelling)
3429 ERR(
"find_item returned %08lx\n",
Status);
3435 ERR(
"readonly subvolume changed\n");
3445 ERR(
"finish_inode returned %08lx\n",
Status);
3450 if (
context->send->cancelling) {
3459 ERR(
"send_inode returned %08lx\n",
Status);
3466 ERR(
"send_inode_ref returned %08lx\n",
Status);
3473 ERR(
"send_inode_extref returned %08lx\n",
Status);
3480 ERR(
"send_extent_data returned %08lx\n",
Status);
3485 if (
context->send->cancelling) {
3492 ERR(
"send_xattr returned %08lx\n",
Status);
3497 if (
context->send->cancelling) {
3510 if (
context->lastinode.inode != 0) {
3513 ERR(
"finish_inode returned %08lx\n",
Status);
3520 if (
context->send->cancelling)
3600 ULONG num_clones = 0;
3624 if (IoIs32bitProcess(
Irp)) {
3655 struct _fcb* parfcb;
3659 ERR(
"ObReferenceObjectByHandle returned %08lx\n",
Status);
3663 if (fileobj->DeviceObject !=
FileObject->DeviceObject) {
3668 parfcb = fileobj->FsContext;
3675 parsubvol = parfcb->
subvol;
3685 if (num_clones > 0) {
3690 ERR(
"out of memory\n");
3694 for (
i = 0;
i < num_clones;
i++) {
3697 struct _fcb* clonefcb;
3700 if (IoIs32bitProcess(
Irp)) {
3703 h = Handle32ToHandle(bss32->
clones[
i]);
3710 ERR(
"ObReferenceObjectByHandle returned %08lx\n",
Status);
3715 if (fileobj->DeviceObject !=
FileObject->DeviceObject) {
3721 clonefcb = fileobj->FsContext;
3743 WARN(
"send operation already running\n");
3750 ERR(
"out of memory\n");
3769 context->num_clones = num_clones;
3791 ERR(
"out of memory\n");
3811 send->cancelling =
false;
3819 ERR(
"PsCreateSystemThread returned %08lx\n",
Status);
3868 if (datalen < context->
datalen) {
#define STATUS_PRIVILEGE_NOT_HELD
ACPI_SIZE strlen(const char *String)
char * strcpy(char *DstString, const char *SrcString)
unsigned short int uint16_t
#define InterlockedIncrement
#define InterlockedDecrement
static __inline uint32_t get_extent_data_refcount(uint8_t type, void *data)
void void void NTSTATUS void NTSTATUS skip_to_difference(device_extension *Vcb, traverse_ptr *tp, traverse_ptr *tp2, bool *ended1, bool *ended2) __attribute__((nonnull(1
#define keycmp(key1, key2)
NTSTATUS zlib_decompress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen)
NTSTATUS zstd_decompress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen)
NTSTATUS lzo_decompress(uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, uint32_t outlen, uint32_t inpageoff)
void flush_subvol_fcbs(root *subvol)
NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, void *csum, uint64_t start, uint64_t length, PIRP Irp)
NTSTATUS do_write(device_extension *Vcb, PIRP Irp)
#define makedev(major, minor)
NTSTATUS NTSTATUS bool bool void free_trees(device_extension *Vcb) __attribute__((nonnull(1)))
static __inline uint16_t get_extent_data_len(uint8_t type)
NTSTATUS NTSTATUS bool find_next_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, const traverse_ptr *tp, traverse_ptr *next_tp, bool ignore, PIRP Irp) __attribute__((nonnull(1
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define STATUS_NOT_IMPLEMENTED
#define NT_SUCCESS(StatCode)
static const WCHAR *const ext[]
static LONG find_item(PropertyBag *This, LPCOLESTR name)
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
_In_ uint64_t _In_ uint64_t _In_ uint64_t generation
#define BTRFS_COMPRESSION_LZO
#define BTRFS_SEND_CMD_RMDIR
#define BTRFS_SEND_TLV_PATH
#define BTRFS_SEND_TLV_CLONE_UUID
#define BTRFS_SEND_CMD_SET_XATTR
#define BTRFS_SEND_CMD_MKFILE
#define TYPE_EXTENT_DATA_REF
#define BTRFS_SEND_TLV_CLONE_OFFSET
#define TYPE_INODE_EXTREF
#define BTRFS_SEND_TLV_XATTR_DATA
#define BTRFS_COMPRESSION_ZLIB
#define BTRFS_COMPRESSION_ZSTD
#define BTRFS_SEND_CMD_WRITE
#define BTRFS_SEND_CMD_UTIMES
#define BTRFS_SEND_CMD_CHMOD
#define BTRFS_SUBVOL_READONLY
#define BTRFS_ENCODING_NONE
#define BTRFS_SEND_CMD_LINK
#define BTRFS_SEND_CMD_RENAME
#define BTRFS_SEND_TLV_TRANSID
#define BTRFS_SEND_TLV_UUID
#define BTRFS_SEND_TLV_GID
#define BTRFS_SEND_TLV_DATA
#define BTRFS_SEND_CMD_MKFIFO
#define BTRFS_SEND_CMD_SUBVOL
#define BTRFS_SEND_TLV_MODE
#define BTRFS_SEND_CMD_SNAPSHOT
#define BTRFS_SEND_TLV_UID
#define BTRFS_SEND_CMD_TRUNCATE
#define EXTENT_TYPE_INLINE
#define BTRFS_SEND_TLV_XATTR_NAME
#define BTRFS_SEND_TLV_MTIME
#define BTRFS_SEND_TLV_CLONE_PATH
#define BTRFS_SEND_TLV_CLONE_LENGTH
#define EXTENT_TYPE_REGULAR
#define BTRFS_SEND_TLV_OFFSET
#define BTRFS_COMPRESSION_NONE
#define BTRFS_SEND_CMD_CHOWN
#define BTRFS_SEND_TLV_CLONE_CTRANSID
#define BTRFS_SEND_CMD_MKNOD
#define BTRFS_SEND_TLV_SIZE
#define BTRFS_SEND_CMD_UNLINK
#define BTRFS_SEND_CMD_REMOVE_XATTR
#define BTRFS_SEND_CMD_SYMLINK
#define BTRFS_SEND_CMD_CLONE
#define BTRFS_SEND_CMD_MKSOCK
#define BTRFS_SEND_TLV_PATH_LINK
#define BTRFS_ENCRYPTION_NONE
#define BTRFS_SEND_TLV_INODE
#define BTRFS_SEND_TLV_ATIME
#define BTRFS_SEND_TLV_CTIME
#define BTRFS_SEND_TLV_RDEV
#define BTRFS_SEND_TLV_PATH_TO
#define BTRFS_SEND_CMD_MKDIR
static NTSTATUS get_orphan_name(send_context *context, uint64_t inode, uint64_t generation, char *name)
static NTSTATUS sync_ext_cutoff_points(send_context *context)
static NTSTATUS wait_for_flush(send_context *context, traverse_ptr *tp1, traverse_ptr *tp2)
static __inline uint16_t find_path_len(send_dir *parent, uint16_t namelen)
static void add_orphan(send_context *context, orphan *o)
static NTSTATUS send_inode(send_context *context, traverse_ptr *tp, traverse_ptr *tp2)
static void find_path(char *path, send_dir *parent, char *name, ULONG namelen)
static bool try_clone(send_context *context, send_ext *se)
static void send_chown_command(send_context *context, char *path, uint64_t uid, uint64_t gid)
static void send_chmod_command(send_context *context, char *path, uint64_t mode)
NTSTATUS send_subvol(device_extension *Vcb, void *data, ULONG datalen, PFILE_OBJECT FileObject, PIRP Irp)
static NTSTATUS divide_ext(send_ext *ext, uint64_t len, bool trunc)
static NTSTATUS send_inode_extref(send_context *context, traverse_ptr *tp, bool tree2)
static void send_command_finish(send_context *context, ULONG pos)
static void send_truncate_command(send_context *context, char *path, uint64_t size)
static NTSTATUS find_send_dir(send_context *context, uint64_t dir, uint64_t generation, send_dir **psd, bool *added_dummy)
static NTSTATUS send_inode_ref(send_context *context, traverse_ptr *tp, bool tree2)
static NTSTATUS send_read_symlink(send_context *context, uint64_t inode, char **link, uint16_t *linklen)
#define SEND_BUFFER_LENGTH
static NTSTATUS flush_extents(send_context *context, traverse_ptr *tp1, traverse_ptr *tp2)
static NTSTATUS send_add_dir(send_context *context, uint64_t inode, send_dir *parent, char *name, uint16_t namelen, bool dummy, LIST_ENTRY *lastentry, send_dir **psd)
static void send_utimes_command(send_context *context, char *path, BTRFS_TIME *atime, BTRFS_TIME *mtime, BTRFS_TIME *ctime)
static void send_command(send_context *context, uint16_t cmd)
static NTSTATUS make_file_orphan(send_context *context, uint64_t inode, bool dir, uint64_t generation, ref *r)
static void send_add_tlv_path(send_context *context, uint16_t type, send_dir *parent, char *name, uint16_t namelen)
static void send_subvol_header(send_context *context, root *r, file_ref *fr)
static void send_utimes_command_dir(send_context *context, send_dir *sd, BTRFS_TIME *atime, BTRFS_TIME *mtime, BTRFS_TIME *ctime)
static NTSTATUS look_for_collision(send_context *context, send_dir *sd, char *name, ULONG namelen, uint64_t *inode, bool *dir)
NTSTATUS read_send_buffer(device_extension *Vcb, PFILE_OBJECT FileObject, void *data, ULONG datalen, ULONG_PTR *retlen, KPROCESSOR_MODE processor_mode)
static NTSTATUS send_extent_data(send_context *context, traverse_ptr *tp, traverse_ptr *tp2)
static NTSTATUS flush_refs(send_context *context, traverse_ptr *tp1, traverse_ptr *tp2)
static NTSTATUS send_xattr(send_context *context, traverse_ptr *tp, traverse_ptr *tp2)
static NTSTATUS finish_inode(send_context *context, traverse_ptr *tp1, traverse_ptr *tp2)
static NTSTATUS add_ext_holes(device_extension *Vcb, LIST_ENTRY *exts, uint64_t size)
static bool try_clone_edr(send_context *context, send_ext *se, EXTENT_DATA_REF *edr)
static bool send_add_tlv_clone_path(send_context *context, root *r, uint64_t inode)
static NTSTATUS get_dir_last_child(send_context *context, uint64_t *last_inode)
static void send_rmdir_command(send_context *context, uint16_t pathlen, char *path)
static char * uint64_to_char(uint64_t num, char *buf)
static void send_add_tlv(send_context *context, uint16_t type, void *data, uint16_t length)
static NTSTATUS add_pending_rmdir(send_context *context, uint64_t last_inode)
static NTSTATUS found_path(send_context *context, send_dir *parent, char *name, uint16_t namelen)
static NTSTATUS send_unlink_command(send_context *context, send_dir *parent, uint16_t namelen, char *name)
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define IsListEmpty(ListHead)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define RtlCompareMemory(s1, s2, l)
#define KeInitializeEvent(pEvt, foo, foo2)
#define ExConvertExclusiveToSharedLite(res)
#define KeSetEvent(pEvt, foo, foo2)
#define ExAcquireResourceExclusiveLite(res, wait)
#define RemoveHeadList(ListHead)
#define InitializeListHead(ListHead)
#define ExAcquireResourceSharedLite(res, wait)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
GLuint GLuint GLsizei GLenum type
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble r
GLenum GLuint GLenum GLsizei const GLchar * buf
GLuint GLsizei GLsizei * length
GLenum const GLvoid * addr
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
GLfloat GLfloat GLfloat GLfloat h
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
#define OBJ_KERNEL_HANDLE
POBJECT_TYPE IoFileObjectType
int const JOCTET unsigned int datalen
double __cdecl trunc(double)
#define memcpy(s1, s2, n)
#define SE_MANAGE_VOLUME_PRIVILEGE
static const struct encodedExtensions exts[]
#define InitializeObjectAttributes(p, n, a, r, s)
static IBindStatusCallbackEx bsc
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define _Function_class_(n)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
#define STATUS_INTERNAL_ERROR
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
#define BTRFS_INODE_NODATASUM
#define offsetof(TYPE, MEMBER)
static DWORD WINAPI send_thread(LPVOID lpParameter)
#define SUBVOL_ROOT_INODE
#define STATUS_DEVICE_NOT_READY
#define STATUS_END_OF_FILE
#define BTRFS_TYPE_DIRECTORY
struct _LIST_ENTRY * Blink
struct _LIST_ENTRY * Flink
void *POINTER_32 clones[1]
uint64_t last_child_inode
LIST_ENTRY pending_rmdirs
LIST_ENTRY deleted_children
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define RtlMoveMemory(Destination, Source, Length)
#define CONTAINING_RECORD(address, type, field)
#define STATUS_INVALID_PARAMETER
#define STATUS_OBJECT_NAME_COLLISION
#define STATUS_INSUFFICIENT_RESOURCES
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
#define ObDereferenceObject