21 #if (NTDDI_VERSION >= NTDDI_WIN10) 24 #define FileIdInformation (enum _FILE_INFORMATION_CLASS)59 25 #define FileHardLinkFullIdInformation (enum _FILE_INFORMATION_CLASS)62 26 #define FileDispositionInformationEx (enum _FILE_INFORMATION_CLASS)64 27 #define FileRenameInformationEx (enum _FILE_INFORMATION_CLASS)65 28 #define FileStatInformation (enum _FILE_INFORMATION_CLASS)68 29 #define FileStatLxInformation (enum _FILE_INFORMATION_CLASS)70 30 #define FileCaseSensitiveInformation (enum _FILE_INFORMATION_CLASS)71 31 #define FileLinkInformationEx (enum _FILE_INFORMATION_CLASS)72 32 #define FileStorageReserveIdInformation (enum _FILE_INFORMATION_CLASS)74 73 #define LX_FILE_METADATA_HAS_UID 0x01 74 #define LX_FILE_METADATA_HAS_GID 0x02 75 #define LX_FILE_METADATA_HAS_MODE 0x04 76 #define LX_FILE_METADATA_HAS_DEVICE_ID 0x08 77 #define LX_FILE_CASE_SENSITIVE_DIR 0x10 120 #define FILE_RENAME_REPLACE_IF_EXISTS 0x001 121 #define FILE_RENAME_POSIX_SEMANTICS 0x002 122 #define FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE 0x004 123 #define FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE 0x008 124 #define FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE 0x010 125 #define FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE 0x020 126 #define FILE_RENAME_IGNORE_READONLY_ATTRIBUTE 0x040 127 #define FILE_RENAME_FORCE_RESIZE_TARGET_SR 0x080 128 #define FILE_RENAME_FORCE_RESIZE_SOURCE_SR 0x100 130 #define FILE_DISPOSITION_DELETE 0x1 131 #define FILE_DISPOSITION_POSIX_SEMANTICS 0x2 132 #define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK 0x4 133 #define FILE_DISPOSITION_ON_CLOSE 0x8 135 #define FILE_LINK_REPLACE_IF_EXISTS 0x001 136 #define FILE_LINK_POSIX_SEMANTICS 0x002 137 #define FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE 0x008 138 #define FILE_LINK_NO_INCREASE_AVAILABLE_SPACE 0x010 139 #define FILE_LINK_NO_DECREASE_AVAILABLE_SPACE 0x020 140 #define FILE_LINK_IGNORE_READONLY_ATTRIBUTE 0x040 141 #define FILE_LINK_FORCE_RESIZE_TARGET_SR 0x080 142 #define FILE_LINK_FORCE_RESIZE_SOURCE_SR 0x100 146 #define FILE_RENAME_INFORMATION_EX FILE_RENAME_INFORMATION 147 #define FILE_LINK_INFORMATION_EX FILE_LINK_INFORMATION 177 #define FILE_RENAME_REPLACE_IF_EXISTS 0x001 178 #define FILE_RENAME_POSIX_SEMANTICS 0x002 179 #define FILE_RENAME_IGNORE_READONLY_ATTRIBUTE 0x040 181 #define FILE_DISPOSITION_DELETE 0x1 182 #define FILE_DISPOSITION_POSIX_SEMANTICS 0x2 183 #define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK 0x4 185 #define FILE_LINK_REPLACE_IF_EXISTS 0x001 186 #define FILE_LINK_POSIX_SEMANTICS 0x002 187 #define FILE_LINK_IGNORE_READONLY_ATTRIBUTE 0x040 196 bool inode_item_changed =
false;
200 if (fileref && fileref->
parent)
203 ERR(
"stream did not have fileref\n");
209 ERR(
"ccb was NULL\n");
218 WARN(
"attempted to set FILE_ATTRIBUTE_DIRECTORY on non-directory\n");
254 inode_item_changed =
true;
264 inode_item_changed =
true;
274 inode_item_changed =
true;
284 inode_item_changed =
true;
323 fcb->
subvol->root_item.ctransid =
Vcb->superblock.generation;
333 inode_item_changed =
true;
338 if (inode_item_changed) {
385 ERR(
"no fileref for stream\n");
395 TRACE(
"not allowing readonly file to be deleted\n");
401 WARN(
"not allowing \\$Root to be deleted\n");
408 TRACE(
"directory not empty\n");
415 TRACE(
"trying to delete file which is being mapped as an image\n");
451 if (
c->open_count > 0)
472 ERR(
"out of memory\n");
496 ERR(
"out of memory\n");
510 ERR(
"out of memory\n");
527 ERR(
"out of memory\n");
538 while (le != &oldfcb->
extents) {
545 ERR(
"out of memory\n");
553 if (
ext2->datalen > 0)
556 ext2->unique =
false;
557 ext2->ignore =
false;
558 ext2->inserted =
true;
573 ERR(
"out of memory\n");
595 ERR(
"out of memory\n");
601 hl2->index = hl->
index;
603 hl2->name.Length = hl2->name.MaximumLength = hl->
name.
Length;
606 if (!hl2->name.Buffer) {
607 ERR(
"out of memory\n");
615 hl2->utf8.Length = hl2->utf8.MaximumLength = hl->
utf8.
Length;
618 if (!hl2->utf8.Buffer) {
619 ERR(
"out of memory\n");
638 ERR(
"out of memory\n");
651 ERR(
"out of memory\n");
662 while (le != &oldfcb->
xattrs) {
671 ERR(
"out of memory\n");
717 ERR(
"open_fileref_child returned %08lx\n",
Status);
724 ERR(
"out of memory\n");
755 if (dc2->
hash >> 24 ==
c)
764 c =
dc->hash_uc >> 24;
793 ERR(
"out of memory\n");
822 ERR(
"SeAssignSecurity returned %08lx\n",
Status);
828 ERR(
"SeAssignSecurity returned NULL security descriptor\n");
834 ERR(
"RtlGetOwnerSecurityDescriptor returned %08lx\n",
Status);
849 fcb->
Header.ValidDataLength.QuadPart = 0;
861 ERR(
"out of memory\n");
869 ERR(
"out of memory\n");
875 acquire_fcb_lock_exclusive(
Vcb);
879 release_fcb_lock(
Vcb);
965 acquire_fcb_lock_exclusive(
fileref->fcb->Vcb);
970 ERR(
"out of memory\n");
995 ERR(
"add_children_to_move_list returned %08lx\n",
Status);
1022 ERR(
"duplicate_fcb returned %08lx\n",
Status);
1092 ERR(
"get_chunk_from_address(%I64x) failed\n", ed2->
address);
1098 ERR(
"update_changed_extent_ref returned %08lx\n",
Status);
1168 fileref->fcb->subvol->root_item.ctransid =
fileref->fcb->Vcb->superblock.generation;
1176 bool name_changed =
false;
1182 ERR(
"out of memory\n");
1192 ERR(
"create_directory_fcb returned %08lx\n",
Status);
1213 name_changed =
true;
1218 ERR(
"out of memory\n");
1271 ERR(
"out of memory\n");
1281 ERR(
"out of memory\n");
1291 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
1326 TRACE(
"me->fileref->parent->fcb->inode_item.st_size (inode %I64x) was %I64x\n", me->
fileref->
parent->fcb->inode, me->
fileref->
parent->fcb->inode_item.st_size);
1328 TRACE(
"me->fileref->parent->fcb->inode_item.st_size (inode %I64x) now %I64x\n", me->
fileref->
parent->fcb->inode, me->
fileref->
parent->fcb->inode_item.st_size);
1372 ERR(
"delete_fileref returned %08lx\n",
Status);
1380 ERR(
"out of memory\n");
1391 ERR(
"out of memory\n");
1402 ERR(
"out of memory\n");
1428 ERR(
"delete_fileref returned %08lx\n",
Status);
1436 destdir->
fcb->
subvol->root_item.ctransid = destdir->
fcb->
Vcb->superblock.generation;
1463 fileref->fcb->subvol->fcbs_version++;
1465 release_fcb_lock(
fileref->fcb->Vcb);
1495 if (dc2->
hash >
dc->hash) {
1512 if (dc2->
hash >
dc->hash)
1516 c =
dc->hash_uc >> 24;
1570 WARN(
"trying to rename stream on readonly file\n");
1575 WARN(
"insufficient permissions\n");
1587 WARN(
"trying to overwrite open file\n");
1592 WARN(
"can only overwrite existing stream if it is zero-length\n");
1598 ERR(
"out of memory\n");
1630 fileref->fcb->inode_item_changed =
true;
1663 fileref->fcb->extents_changed =
true;
1671 if (
fileref->fcb->adsxattr.Buffer) {
1673 fileref->fcb->adsxattr.Length =
fileref->fcb->adsxattr.MaximumLength = 0;
1680 fileref->fcb->adsdata.Length =
fileref->fcb->adsdata.MaximumLength = 0;
1682 acquire_fcb_lock_exclusive(
Vcb);
1692 release_fcb_lock(
Vcb);
1755 ERR(
"out of memory\n");
1774 ERR(
"add_extent_to_fcb returned %08lx\n",
Status);
1784 ERR(
"out of memory\n");
1802 ERR(
"do_write_file returned %08lx\n",
Status);
1812 fileref->fcb->inode_item_changed =
true;
1817 if (
dc->utf8.Buffer)
1820 if (
dc->name.Buffer)
1823 if (
dc->name_uc.Buffer)
1838 dummyfcb->
ads =
true;
1841 acquire_fcb_lock_exclusive(
Vcb);
1844 dummyfcb->
subvol->fcbs_version++;
1845 release_fcb_lock(
Vcb);
1869 static const WCHAR datasuf[] =
L":$DATA";
1870 static const char xapref[] =
"user.";
1873 ERR(
"fileref not set\n");
1878 ERR(
"fileref->parent not set\n");
1883 WARN(
"filename too short\n");
1888 WARN(
"destination filename must begin with a colon\n");
1893 WARN(
"insufficient permissions\n");
1901 if (
fn.Length >=
sizeof(datasuf) -
sizeof(
WCHAR) &&
1903 fn.Length -=
sizeof(datasuf) -
sizeof(
WCHAR);
1910 WARN(
"invalid stream name %.*S\n", (
int)(
fn.Length /
sizeof(
WCHAR)),
fn.Buffer);
1915 WARN(
"trying to rename stream on readonly file\n");
1934 WARN(
"trying to overwrite open file\n");
1940 WARN(
"can only overwrite existing stream if it is zero-length\n");
1947 ERR(
"delete_fileref returned %08lx\n",
Status);
1952 ERR(
"open_fileref_child returned %08lx\n",
Status);
1964 ERR(
"out of memory\n");
1978 ERR(
"out of memory\n");
2002 ERR(
"out of memory\n");
2015 WARN(
"cannot rename as data too long\n");
2026 WARN(
"cannot rename as data too long\n");
2036 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
2047 ERR(
"out of memory\n");
2062 dummyfcb->
ads =
true;
2065 acquire_fcb_lock_exclusive(
Vcb);
2068 dummyfcb->
subvol->fcbs_version++;
2069 release_fcb_lock(
Vcb);
2079 fileref->dc->name_uc = utf16uc;
2085 fileref->fcb->adsmaxlen = newmaxlen;
2116 static const WCHAR datasuf[] =
L":$DATA";
2117 static const char xapref[] =
"user.";
2120 ERR(
"fileref not set\n");
2125 WARN(
"filename too short\n");
2130 WARN(
"destination filename must begin with a colon\n");
2135 WARN(
"insufficient permissions\n");
2146 if (
fn.Length >=
sizeof(datasuf) -
sizeof(
WCHAR) &&
2148 fn.Length -=
sizeof(datasuf) -
sizeof(
WCHAR);
2150 if (
fn.Length == 0) {
2151 WARN(
"not allowing overwriting file with itself\n");
2157 WARN(
"invalid stream name %.*S\n", (
int)(
fn.Length /
sizeof(
WCHAR)),
fn.Buffer);
2162 WARN(
"trying to rename stream on readonly file\n");
2181 WARN(
"trying to overwrite open file\n");
2187 WARN(
"can only overwrite existing stream if it is zero-length\n");
2194 ERR(
"delete_fileref returned %08lx\n",
Status);
2199 ERR(
"open_fileref_child returned %08lx\n",
Status);
2211 ERR(
"out of memory\n");
2225 ERR(
"out of memory\n");
2249 ERR(
"out of memory\n");
2262 WARN(
"cannot rename as data too long\n");
2273 WARN(
"cannot rename as data too long\n");
2283 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
2292 if (
fileref->fcb->inode_item.st_size > 0) {
2299 ERR(
"out of memory\n");
2310 ERR(
"out of memory\n");
2321 ERR(
"short read\n");
2335 ERR(
"out of memory\n");
2352 ERR(
"duplicate_fcb returned %08lx\n",
Status);
2367 if (!dummyfileref) {
2368 ERR(
"out of memory\n");
2385 dummyfileref->
fcb = dummyfcb;
2392 if (
fileref->fcb->inode_item.st_size > 0) {
2396 ERR(
"excise_extents returned %08lx\n",
Status);
2411 dummyfcb->
Header.AllocationSize.QuadPart = 0;
2412 dummyfcb->
Header.FileSize.QuadPart = 0;
2413 dummyfcb->
Header.ValidDataLength.QuadPart = 0;
2420 le =
fileref->fcb->extents.Flink;
2421 while (le != &
fileref->fcb->extents) {
2445 if (
fileref->fcb->subvol->fcbs_ptrs[dummyfcb->
hash >> 24] == &
fileref->fcb->list_entry)
2468 fr->
parent = dummyfileref;
2480 dummyfileref->
dc->
fileref = dummyfileref;
2499 dc->name_uc = utf16uc;
2505 fileref->parent = dummyfileref;
2511 fileref->fcb->adsmaxlen = newmaxlen;
2533 ULONG fnlen, utf8len, origutf8len;
2552 TRACE(
"tfo = %p\n", tfo);
2562 ERR(
"no fileref set and no directory given\n");
2568 while (fnlen > 0 && (fri->
FileName[fnlen - 1] ==
'/' || fri->
FileName[fnlen - 1] ==
'\\')) {
2575 for (
i = fnlen - 1;
i >= 0;
i--) {
2589 WARN(
"not allowing \\$Root to be renamed\n");
2608 }
else if (fnlen >= 1 &&
fn[0] ==
':') {
2633 origutf8len =
fileref->dc->utf8.Length;
2642 ERR(
"out of memory\n");
2651 if (tfo && tfo->FsContext2) {
2652 struct _ccb* relatedccb = tfo->FsContext2;
2654 related = relatedccb->
fileref;
2664 TRACE(
"destination file already exists\n");
2670 }
else if (
fileref == oldfileref) {
2674 WARN(
"trying to overwrite open file\n");
2678 WARN(
"trying to overwrite readonly file\n");
2682 WARN(
"trying to overwrite directory\n");
2698 ERR(
"open_fileref returned %08lx\n",
Status);
2703 if (related->fcb ==
Vcb->dummy_fcb) {
2713 TRACE(
"SeAccessCheck failed, returning %08lx\n",
Status);
2720 WARN(
"trying to rename file with open children\n");
2731 TRACE(
"SeAccessCheck failed, returning %08lx\n",
Status);
2738 oldfileref->delete_on_close =
true;
2739 oldfileref->posix_delete =
true;
2744 ERR(
"delete_fileref returned %08lx\n",
Status);
2752 ERR(
"move_across_subvols returned %08lx\n",
Status);
2760 ULONG reqlen, oldutf8len;
2766 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2772 ERR(
"out of memory\n");
2781 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2791 ERR(
"out of memory\n");
2813 ERR(
"out of memory\n");
2825 ERR(
"out of memory\n");
2837 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
2857 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2864 ERR(
"out of memory\n");
2874 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2896 related->fcb->inode_item.transid =
Vcb->superblock.generation;
2897 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) was %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
2898 related->fcb->inode_item.st_size = related->fcb->inode_item.st_size + (2 * utf8.
Length) - (2* oldutf8len);
2899 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) now %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
2900 related->fcb->inode_item.sequence++;
2901 related->fcb->inode_item.st_ctime =
now;
2902 related->fcb->inode_item.st_mtime =
now;
2904 related->fcb->inode_item_changed =
true;
2933 fr2->deleted =
true;
2938 if (!fr2->oldutf8.Buffer) {
2940 if (!fr2->oldutf8.Buffer) {
2941 ERR(
"out of memory\n");
2952 fr2->fcb->fileref = fr2;
2987 ERR(
"out of memory\n");
2997 ERR(
"out of memory\n");
3007 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
3018 if (
IsListEmpty(&related->fcb->dir_children_index))
3040 ERR(
"out of memory\n");
3045 hl->
parent = related->fcb->inode;
3052 ERR(
"out of memory\n");
3064 ERR(
"out of memory\n");
3082 if (hl->
parent == fr2->parent->fcb->inode && hl->
index == fr2->oldindex) {
3116 related->fcb->inode_item.transid =
Vcb->superblock.generation;
3117 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) was %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
3118 related->fcb->inode_item.st_size += 2 * utf8len;
3119 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) now %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
3120 related->fcb->inode_item.sequence++;
3121 related->fcb->inode_item.st_ctime =
now;
3122 related->fcb->inode_item.st_mtime =
now;
3124 related->fcb->inode_item_changed =
true;
3129 fr2->parent->fcb->inode_item.transid =
Vcb->superblock.generation;
3130 TRACE(
"fr2->parent->fcb->inode_item.st_size (inode %I64x) was %I64x\n", fr2->parent->fcb->inode, fr2->parent->fcb->inode_item.st_size);
3131 fr2->parent->fcb->inode_item.st_size -= 2 * origutf8len;
3132 TRACE(
"fr2->parent->fcb->inode_item.st_size (inode %I64x) now %I64x\n", fr2->parent->fcb->inode, fr2->parent->fcb->inode_item.st_size);
3133 fr2->parent->fcb->inode_item.sequence++;
3134 fr2->parent->fcb->inode_item.st_ctime =
now;
3135 fr2->parent->fcb->inode_item.st_mtime =
now;
3139 fr2->parent->fcb->inode_item_changed =
true;
3177 ERR(
"no fileref for stream\n");
3185 TRACE(
"truncating stream to %x bytes\n",
end);
3189 TRACE(
"extending stream to %x bytes\n",
end);
3199 ERR(
"out of memory\n");
3234 fileref->
parent->fcb->subvol->root_item.ctransid =
Vcb->superblock.generation;
3253 ERR(
"fileref is NULL\n");
3306 TRACE(
"FileObject: AllocationSize = %I64x, FileSize = %I64x, ValidDataLength = %I64x\n",
3326 ERR(
"error - truncate_file failed\n");
3334 ERR(
"error - extend_file failed\n");
3377 ERR(
"CcSetFileSizes threw exception %08lx\n",
Status);
3403 ULONG fnlen, utf8len;
3436 ERR(
"no fileref set and no directory given\n");
3445 tfofcb = tfo->FsContext;
3448 while (fnlen > 0 && (fli->
FileName[fnlen - 1] ==
'/' || fli->
FileName[fnlen - 1] ==
'\\')) {
3455 for (
i = fnlen - 1;
i >= 0;
i--) {
3469 WARN(
"tried to create hard link on directory\n");
3475 WARN(
"tried to create hard link on stream\n");