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 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");
323 fcb->
subvol->root_item.ctransid =
Vcb->superblock.generation;
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");
821 ERR(
"SeAssignSecurity returned %08lx\n",
Status);
827 ERR(
"SeAssignSecurity returned NULL security descriptor\n");
833 ERR(
"RtlGetOwnerSecurityDescriptor returned %08lx\n",
Status);
848 fcb->
Header.ValidDataLength.QuadPart = 0;
860 ERR(
"out of memory\n");
868 ERR(
"out of memory\n");
874 acquire_fcb_lock_exclusive(
Vcb);
878 release_fcb_lock(
Vcb);
907 ERR(
"out of memory\n");
932 ERR(
"add_children_to_move_list returned %08lx\n",
Status);
953 bool inserted =
false;
960 ERR(
"duplicate_fcb returned %08lx\n",
Status);
1028 ERR(
"get_chunk_from_address(%I64x) failed\n",
ed2->
address);
1034 ERR(
"update_changed_extent_ref returned %08lx\n",
Status);
1056 while (le3 != &destdir->
fcb->
subvol->fcbs) {
1123 bool name_changed =
false;
1129 ERR(
"out of memory\n");
1139 ERR(
"create_directory_fcb returned %08lx\n",
Status);
1160 name_changed =
true;
1165 ERR(
"out of memory\n");
1218 ERR(
"out of memory\n");
1228 ERR(
"out of memory\n");
1238 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
1273 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);
1275 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);
1319 ERR(
"delete_fileref returned %08lx\n",
Status);
1327 ERR(
"out of memory\n");
1338 ERR(
"out of memory\n");
1349 ERR(
"out of memory\n");
1375 ERR(
"delete_fileref returned %08lx\n",
Status);
1383 destdir->
fcb->
subvol->root_item.ctransid = destdir->
fcb->
Vcb->superblock.generation;
1442 if (dc2->
hash >
dc->hash) {
1459 if (dc2->
hash >
dc->hash)
1463 c =
dc->hash_uc >> 24;
1517 WARN(
"trying to rename stream on readonly file\n");
1522 WARN(
"insufficient permissions\n");
1534 WARN(
"trying to overwrite open file\n");
1539 WARN(
"can only overwrite existing stream if it is zero-length\n");
1545 ERR(
"out of memory\n");
1690 if (adsdata.
Length > 0) {
1691 bool make_inline = adsdata.
Length <=
Vcb->options.max_inline;
1696 ERR(
"out of memory\n");
1715 ERR(
"add_extent_to_fcb returned %08lx\n",
Status);
1722 }
else if (adsdata.
Length %
Vcb->superblock.sector_size) {
1725 ERR(
"out of memory\n");
1743 ERR(
"do_write_file returned %08lx\n",
Status);
1758 if (
dc->utf8.Buffer)
1761 if (
dc->name.Buffer)
1764 if (
dc->name_uc.Buffer)
1803 static const WCHAR datasuf[] =
L":$DATA";
1804 static const char xapref[] =
"user.";
1807 ERR(
"fileref not set\n");
1812 ERR(
"fileref->parent not set\n");
1817 WARN(
"filename too short\n");
1822 WARN(
"destination filename must begin with a colon\n");
1827 WARN(
"insufficient permissions\n");
1835 if (
fn.Length >=
sizeof(datasuf) -
sizeof(
WCHAR) &&
1837 fn.Length -=
sizeof(datasuf) -
sizeof(
WCHAR);
1843 WARN(
"invalid stream name %.*S\n", (
int)(
fn.Length /
sizeof(
WCHAR)),
fn.Buffer);
1848 WARN(
"trying to rename stream on readonly file\n");
1867 WARN(
"trying to overwrite open file\n");
1873 WARN(
"can only overwrite existing stream if it is zero-length\n");
1880 ERR(
"delete_fileref returned %08lx\n",
Status);
1885 ERR(
"open_fileref_child returned %08lx\n",
Status);
1897 ERR(
"out of memory\n");
1911 ERR(
"out of memory\n");
1935 ERR(
"out of memory\n");
1947 if (newmaxlen < adsxattr.
Length) {
1948 WARN(
"cannot rename as data too long\n");
1956 newmaxlen -= adsxattr.
Length;
1959 WARN(
"cannot rename as data too long\n");
1969 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
1980 ERR(
"out of memory\n");
2042 static const WCHAR datasuf[] =
L":$DATA";
2043 static const char xapref[] =
"user.";
2046 ERR(
"fileref not set\n");
2051 WARN(
"filename too short\n");
2056 WARN(
"destination filename must begin with a colon\n");
2061 WARN(
"insufficient permissions\n");
2072 if (
fn.Length >=
sizeof(datasuf) -
sizeof(
WCHAR) &&
2074 fn.Length -=
sizeof(datasuf) -
sizeof(
WCHAR);
2076 if (
fn.Length == 0) {
2077 WARN(
"not allowing overwriting file with itself\n");
2082 WARN(
"invalid stream name %.*S\n", (
int)(
fn.Length /
sizeof(
WCHAR)),
fn.Buffer);
2087 WARN(
"trying to rename stream on readonly file\n");
2106 WARN(
"trying to overwrite open file\n");
2112 WARN(
"can only overwrite existing stream if it is zero-length\n");
2119 ERR(
"delete_fileref returned %08lx\n",
Status);
2124 ERR(
"open_fileref_child returned %08lx\n",
Status);
2136 ERR(
"out of memory\n");
2150 ERR(
"out of memory\n");
2174 ERR(
"out of memory\n");
2186 if (newmaxlen < adsxattr.
Length) {
2187 WARN(
"cannot rename as data too long\n");
2195 newmaxlen -= adsxattr.
Length;
2198 WARN(
"cannot rename as data too long\n");
2208 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
2224 ERR(
"out of memory\n");
2235 ERR(
"out of memory\n");
2246 ERR(
"short read\n");
2260 ERR(
"short read\n");
2277 ERR(
"duplicate_fcb returned %08lx\n",
Status);
2293 ERR(
"out of memory\n");
2321 ERR(
"excise_extents returned %08lx\n",
Status);
2426 dc->name_uc = utf16uc;
2460 ULONG fnlen, utf8len, origutf8len;
2482 TRACE(
"tfo = %p\n", tfo);
2492 ERR(
"no fileref set and no directory given\n");
2498 while (fnlen > 0 && (fri->
FileName[fnlen - 1] ==
'/' || fri->
FileName[fnlen - 1] ==
'\\'))
2504 for (
i = fnlen - 1;
i >= 0;
i--) {
2518 WARN(
"not allowing \\$Root to be renamed\n");
2537 }
else if (fnlen >= 1 &&
fn[0] ==
':') {
2559 for (
unsigned int i = 0 ;
i < fnus.
Length /
sizeof(
WCHAR);
i++) {
2564 TRACE(
"colon in filename\n");
2579 ERR(
"out of memory\n");
2588 if (tfo && tfo->FsContext2) {
2589 struct _ccb* relatedccb = tfo->FsContext2;
2591 related = relatedccb->
fileref;
2601 TRACE(
"destination file already exists\n");
2607 }
else if (
fileref == oldfileref) {
2611 WARN(
"trying to overwrite open file\n");
2615 WARN(
"trying to overwrite readonly file\n");
2619 WARN(
"trying to overwrite directory\n");
2635 ERR(
"open_fileref returned %08lx\n",
Status);
2640 if (related->fcb ==
Vcb->dummy_fcb) {
2650 TRACE(
"SeAccessCheck failed, returning %08lx\n",
Status);
2657 WARN(
"trying to rename file with open children\n");
2668 TRACE(
"SeAccessCheck failed, returning %08lx\n",
Status);
2675 oldfileref->delete_on_close =
true;
2676 oldfileref->posix_delete =
true;
2681 ERR(
"delete_fileref returned %08lx\n",
Status);
2689 ERR(
"move_across_subvols returned %08lx\n",
Status);
2697 ULONG reqlen, oldutf8len;
2703 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2709 ERR(
"out of memory\n");
2718 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2728 ERR(
"out of memory\n");
2750 ERR(
"out of memory\n");
2762 ERR(
"out of memory\n");
2774 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
2794 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2801 ERR(
"out of memory\n");
2811 ERR(
"fileref_get_filename returned %08lx\n",
Status);
2833 related->fcb->inode_item.transid =
Vcb->superblock.generation;
2834 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) was %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
2835 related->fcb->inode_item.st_size = related->fcb->inode_item.st_size + (2 * utf8.
Length) - (2* oldutf8len);
2836 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) now %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
2837 related->fcb->inode_item.sequence++;
2838 related->fcb->inode_item.st_ctime =
now;
2839 related->fcb->inode_item.st_mtime =
now;
2841 related->fcb->inode_item_changed =
true;
2870 fr2->deleted =
true;
2875 if (!fr2->oldutf8.Buffer) {
2877 if (!fr2->oldutf8.Buffer) {
2878 ERR(
"out of memory\n");
2889 fr2->fcb->fileref = fr2;
2924 ERR(
"out of memory\n");
2934 ERR(
"out of memory\n");
2944 ERR(
"RtlUpcaseUnicodeString returned %08lx\n",
Status);
2955 if (
IsListEmpty(&related->fcb->dir_children_index))
2977 ERR(
"out of memory\n");
2982 hl->
parent = related->fcb->inode;
2989 ERR(
"out of memory\n");
3001 ERR(
"out of memory\n");
3019 if (hl->
parent == fr2->parent->fcb->inode && hl->
index == fr2->oldindex) {
3053 related->fcb->inode_item.transid =
Vcb->superblock.generation;
3054 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) was %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
3055 related->fcb->inode_item.st_size += 2 * utf8len;
3056 TRACE(
"related->fcb->inode_item.st_size (inode %I64x) now %I64x\n", related->fcb->inode, related->fcb->inode_item.st_size);
3057 related->fcb->inode_item.sequence++;
3058 related->fcb->inode_item.st_ctime =
now;
3059 related->fcb->inode_item.st_mtime =
now;
3061 related->fcb->inode_item_changed =
true;
3066 fr2->parent->fcb->inode_item.transid =
Vcb->superblock.generation;
3067 TRACE(
"fr2->parent->fcb->inode_item.st_size (inode %I64x) was %I64x\n", fr2->parent->fcb->inode, fr2->parent->fcb->inode_item.st_size);
3068 fr2->parent->fcb->inode_item.st_size -= 2 * origutf8len;
3069 TRACE(
"fr2->parent->fcb->inode_item.st_size (inode %I64x) now %I64x\n", fr2->parent->fcb->inode, fr2->parent->fcb->inode_item.st_size);
3070 fr2->parent->fcb->inode_item.sequence++;
3071 fr2->parent->fcb->inode_item.st_ctime =
now;
3072 fr2->parent->fcb->inode_item.st_mtime =
now;
3076 fr2->parent->fcb->inode_item_changed =
true;
3114 ERR(
"no fileref for stream\n");
3122 TRACE(
"truncating stream to %x bytes\n",
end);
3126 TRACE(
"extending stream to %x bytes\n",
end);
3136 ERR(
"out of memory\n");
3171 fileref->
parent->fcb->subvol->root_item.ctransid =
Vcb->superblock.generation;
3190 ERR(
"fileref is NULL\n");
3243 TRACE(
"FileObject: AllocationSize = %I64x, FileSize = %I64x, ValidDataLength = %I64x\n",
3263 ERR(
"error - truncate_file failed\n");
3271 ERR(
"error - extend_file failed\n");
3314 ERR(
"CcSetFileSizes threw exception %08lx\n",
Status);
3340 ULONG fnlen, utf8len;
3373 ERR(
"no fileref set and no directory given\n");
3382 tfofcb = tfo->FsContext;
3385 while (fnlen > 0 && (fli->
FileName[fnlen - 1] ==
'/' || fli->
FileName[fnlen - 1] ==
'\\'))
3391 for (
i = fnlen - 1;
i >= 0;
i--) {