ReactOS 0.4.16-dev-340-g0540c21
fileinfo.c File Reference
#include "btrfs_drv.h"
#include "crc32c.h"
Include dependency graph for fileinfo.c:

Go to the source code of this file.

Classes

struct  _FILE_ID_INFORMATION
 
struct  _FILE_STAT_INFORMATION
 
struct  _FILE_STAT_LX_INFORMATION
 
struct  _FILE_RENAME_INFORMATION_EX
 
struct  _FILE_DISPOSITION_INFORMATION_EX
 
struct  _FILE_LINK_INFORMATION_EX
 
struct  _FILE_CASE_SENSITIVE_INFORMATION
 
struct  _FILE_LINK_ENTRY_FULL_ID_INFORMATION
 
struct  _FILE_LINKS_FULL_ID_INFORMATION
 
struct  _move_entry
 

Macros

#define FileIdInformation   (enum _FILE_INFORMATION_CLASS)59
 
#define FileHardLinkFullIdInformation   (enum _FILE_INFORMATION_CLASS)62
 
#define FileDispositionInformationEx   (enum _FILE_INFORMATION_CLASS)64
 
#define FileRenameInformationEx   (enum _FILE_INFORMATION_CLASS)65
 
#define FileStatInformation   (enum _FILE_INFORMATION_CLASS)68
 
#define FileStatLxInformation   (enum _FILE_INFORMATION_CLASS)70
 
#define FileCaseSensitiveInformation   (enum _FILE_INFORMATION_CLASS)71
 
#define FileLinkInformationEx   (enum _FILE_INFORMATION_CLASS)72
 
#define FileStorageReserveIdInformation   (enum _FILE_INFORMATION_CLASS)74
 
#define LX_FILE_METADATA_HAS_UID   0x01
 
#define LX_FILE_METADATA_HAS_GID   0x02
 
#define LX_FILE_METADATA_HAS_MODE   0x04
 
#define LX_FILE_METADATA_HAS_DEVICE_ID   0x08
 
#define LX_FILE_CASE_SENSITIVE_DIR   0x10
 
#define FILE_RENAME_REPLACE_IF_EXISTS   0x001
 
#define FILE_RENAME_POSIX_SEMANTICS   0x002
 
#define FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE   0x004
 
#define FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE   0x008
 
#define FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE   0x010
 
#define FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE   0x020
 
#define FILE_RENAME_IGNORE_READONLY_ATTRIBUTE   0x040
 
#define FILE_RENAME_FORCE_RESIZE_TARGET_SR   0x080
 
#define FILE_RENAME_FORCE_RESIZE_SOURCE_SR   0x100
 
#define FILE_DISPOSITION_DELETE   0x1
 
#define FILE_DISPOSITION_POSIX_SEMANTICS   0x2
 
#define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK   0x4
 
#define FILE_DISPOSITION_ON_CLOSE   0x8
 
#define FILE_LINK_REPLACE_IF_EXISTS   0x001
 
#define FILE_LINK_POSIX_SEMANTICS   0x002
 
#define FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE   0x008
 
#define FILE_LINK_NO_INCREASE_AVAILABLE_SPACE   0x010
 
#define FILE_LINK_NO_DECREASE_AVAILABLE_SPACE   0x020
 
#define FILE_LINK_IGNORE_READONLY_ATTRIBUTE   0x040
 
#define FILE_LINK_FORCE_RESIZE_TARGET_SR   0x080
 
#define FILE_LINK_FORCE_RESIZE_SOURCE_SR   0x100
 

Typedefs

typedef struct _FILE_ID_INFORMATION FILE_ID_INFORMATION
 
typedef struct _FILE_ID_INFORMATIONPFILE_ID_INFORMATION
 
typedef struct _FILE_STAT_INFORMATION FILE_STAT_INFORMATION
 
typedef struct _FILE_STAT_INFORMATIONPFILE_STAT_INFORMATION
 
typedef struct _FILE_STAT_LX_INFORMATION FILE_STAT_LX_INFORMATION
 
typedef struct _FILE_STAT_LX_INFORMATIONPFILE_STAT_LX_INFORMATION
 
typedef struct _FILE_RENAME_INFORMATION_EX FILE_RENAME_INFORMATION_EX
 
typedef struct _FILE_RENAME_INFORMATION_EXPFILE_RENAME_INFORMATION_EX
 
typedef struct _FILE_DISPOSITION_INFORMATION_EX FILE_DISPOSITION_INFORMATION_EX
 
typedef struct _FILE_DISPOSITION_INFORMATION_EXPFILE_DISPOSITION_INFORMATION_EX
 
typedef struct _FILE_LINK_INFORMATION_EX FILE_LINK_INFORMATION_EX
 
typedef struct _FILE_LINK_INFORMATION_EXPFILE_LINK_INFORMATION_EX
 
typedef struct _FILE_CASE_SENSITIVE_INFORMATION FILE_CASE_SENSITIVE_INFORMATION
 
typedef struct _FILE_CASE_SENSITIVE_INFORMATIONPFILE_CASE_SENSITIVE_INFORMATION
 
typedef struct _FILE_LINK_ENTRY_FULL_ID_INFORMATION FILE_LINK_ENTRY_FULL_ID_INFORMATION
 
typedef struct _FILE_LINK_ENTRY_FULL_ID_INFORMATIONPFILE_LINK_ENTRY_FULL_ID_INFORMATION
 
typedef struct _FILE_LINKS_FULL_ID_INFORMATION FILE_LINKS_FULL_ID_INFORMATION
 
typedef struct _FILE_LINKS_FULL_ID_INFORMATIONPFILE_LINKS_FULL_ID_INFORMATION
 
typedef struct _move_entry move_entry
 

Functions

static NTSTATUS set_basic_information (device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject)
 
static NTSTATUS set_disposition_information (device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, bool ex)
 
bool has_open_children (file_ref *fileref)
 
static NTSTATUS duplicate_fcb (fcb *oldfcb, fcb **pfcb)
 
static NTSTATUS add_children_to_move_list (device_extension *Vcb, move_entry *me, PIRP Irp)
 
void remove_dir_child_from_hash_lists (fcb *fcb, dir_child *dc)
 
static NTSTATUS create_directory_fcb (device_extension *Vcb, root *r, fcb *parfcb, fcb **pfcb)
 
void add_fcb_to_subvol (_In_ _Requires_exclusive_lock_held_(_Curr_->Vcb->fcb_lock) fcb *fcb)
 
void remove_fcb_from_subvol (_In_ _Requires_exclusive_lock_held_(_Curr_->Vcb->fcb_lock) fcb *fcb)
 
static NTSTATUS move_across_subvols (file_ref *fileref, ccb *ccb, file_ref *destdir, PANSI_STRING utf8, PUNICODE_STRING fnus, PIRP Irp, LIST_ENTRY *rollback)
 
void insert_dir_child_into_hash_lists (fcb *fcb, dir_child *dc)
 
static NTSTATUS rename_stream_to_file (device_extension *Vcb, file_ref *fileref, ccb *ccb, ULONG flags, PIRP Irp, LIST_ENTRY *rollback)
 
static NTSTATUS rename_stream (device_extension *Vcb, file_ref *fileref, ccb *ccb, FILE_RENAME_INFORMATION_EX *fri, ULONG flags, PIRP Irp, LIST_ENTRY *rollback)
 
static NTSTATUS rename_file_to_stream (device_extension *Vcb, file_ref *fileref, ccb *ccb, FILE_RENAME_INFORMATION_EX *fri, ULONG flags, PIRP Irp, LIST_ENTRY *rollback)
 
static NTSTATUS set_rename_information (device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, PFILE_OBJECT tfo, bool ex)
 
NTSTATUS stream_set_end_of_file_information (device_extension *Vcb, uint16_t end, fcb *fcb, file_ref *fileref, bool advance_only)
 
static NTSTATUS set_end_of_file_information (device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, bool advance_only, bool prealloc)
 
static NTSTATUS set_position_information (PFILE_OBJECT FileObject, PIRP Irp)
 
static NTSTATUS set_link_information (device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, PFILE_OBJECT tfo, bool ex)
 
static NTSTATUS set_valid_data_length_information (device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject)
 
static NTSTATUS set_case_sensitive_information (PIRP Irp)
 
 _Dispatch_type_ (IRP_MJ_SET_INFORMATION)
 
static NTSTATUS fill_in_file_basic_information (FILE_BASIC_INFORMATION *fbi, INODE_ITEM *ii, LONG *length, fcb *fcb, file_ref *fileref)
 
static NTSTATUS fill_in_file_network_open_information (FILE_NETWORK_OPEN_INFORMATION *fnoi, fcb *fcb, file_ref *fileref, LONG *length)
 
static NTSTATUS fill_in_file_standard_information (FILE_STANDARD_INFORMATION *fsi, fcb *fcb, file_ref *fileref, LONG *length)
 
static NTSTATUS fill_in_file_internal_information (FILE_INTERNAL_INFORMATION *fii, fcb *fcb, LONG *length)
 
static NTSTATUS fill_in_file_ea_information (FILE_EA_INFORMATION *eai, fcb *fcb, LONG *length)
 
static NTSTATUS fill_in_file_position_information (FILE_POSITION_INFORMATION *fpi, PFILE_OBJECT FileObject, LONG *length)
 
NTSTATUS fileref_get_filename (file_ref *fileref, PUNICODE_STRING fn, USHORT *name_offset, ULONG *preqlen)
 
static NTSTATUS fill_in_file_name_information (FILE_NAME_INFORMATION *fni, fcb *fcb, file_ref *fileref, LONG *length)
 
static NTSTATUS fill_in_file_attribute_information (FILE_ATTRIBUTE_TAG_INFORMATION *ati, fcb *fcb, ccb *ccb, LONG *length)
 
static NTSTATUS fill_in_file_stream_information (FILE_STREAM_INFORMATION *fsi, file_ref *fileref, LONG *length)
 
static NTSTATUS fill_in_file_standard_link_information (FILE_STANDARD_LINK_INFORMATION *fsli, fcb *fcb, file_ref *fileref, LONG *length)
 
static NTSTATUS fill_in_hard_link_information (FILE_LINKS_INFORMATION *fli, file_ref *fileref, PIRP Irp, LONG *length)
 
static NTSTATUS fill_in_hard_link_full_id_information (FILE_LINKS_FULL_ID_INFORMATION *flfii, file_ref *fileref, PIRP Irp, LONG *length)
 
static NTSTATUS fill_in_file_id_information (FILE_ID_INFORMATION *fii, fcb *fcb, LONG *length)
 
static NTSTATUS fill_in_file_stat_information (FILE_STAT_INFORMATION *fsi, fcb *fcb, ccb *ccb, LONG *length)
 
static NTSTATUS fill_in_file_stat_lx_information (FILE_STAT_LX_INFORMATION *fsli, fcb *fcb, ccb *ccb, LONG *length)
 
static NTSTATUS fill_in_file_case_sensitive_information (FILE_CASE_SENSITIVE_INFORMATION *fcsi, fcb *fcb, LONG *length)
 
static NTSTATUS fill_in_file_compression_information (FILE_COMPRESSION_INFORMATION *fci, LONG *length, fcb *fcb)
 
static NTSTATUS query_info (device_extension *Vcb, PFILE_OBJECT FileObject, PIRP Irp)
 
 _Dispatch_type_ (IRP_MJ_QUERY_INFORMATION)
 
 _Dispatch_type_ (IRP_MJ_QUERY_EA)
 
 _Dispatch_type_ (IRP_MJ_SET_EA)
 

Macro Definition Documentation

◆ FILE_DISPOSITION_DELETE

#define FILE_DISPOSITION_DELETE   0x1

Definition at line 130 of file fileinfo.c.

◆ FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK

#define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK   0x4

Definition at line 132 of file fileinfo.c.

◆ FILE_DISPOSITION_ON_CLOSE

#define FILE_DISPOSITION_ON_CLOSE   0x8

Definition at line 133 of file fileinfo.c.

◆ FILE_DISPOSITION_POSIX_SEMANTICS

#define FILE_DISPOSITION_POSIX_SEMANTICS   0x2

Definition at line 131 of file fileinfo.c.

◆ FILE_LINK_FORCE_RESIZE_SOURCE_SR

#define FILE_LINK_FORCE_RESIZE_SOURCE_SR   0x100

Definition at line 142 of file fileinfo.c.

◆ FILE_LINK_FORCE_RESIZE_TARGET_SR

#define FILE_LINK_FORCE_RESIZE_TARGET_SR   0x080

Definition at line 141 of file fileinfo.c.

◆ FILE_LINK_IGNORE_READONLY_ATTRIBUTE

#define FILE_LINK_IGNORE_READONLY_ATTRIBUTE   0x040

Definition at line 140 of file fileinfo.c.

◆ FILE_LINK_NO_DECREASE_AVAILABLE_SPACE

#define FILE_LINK_NO_DECREASE_AVAILABLE_SPACE   0x020

Definition at line 139 of file fileinfo.c.

◆ FILE_LINK_NO_INCREASE_AVAILABLE_SPACE

#define FILE_LINK_NO_INCREASE_AVAILABLE_SPACE   0x010

Definition at line 138 of file fileinfo.c.

◆ FILE_LINK_POSIX_SEMANTICS

#define FILE_LINK_POSIX_SEMANTICS   0x002

Definition at line 136 of file fileinfo.c.

◆ FILE_LINK_REPLACE_IF_EXISTS

#define FILE_LINK_REPLACE_IF_EXISTS   0x001

Definition at line 135 of file fileinfo.c.

◆ FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE

#define FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE   0x008

Definition at line 137 of file fileinfo.c.

◆ FILE_RENAME_FORCE_RESIZE_SOURCE_SR

#define FILE_RENAME_FORCE_RESIZE_SOURCE_SR   0x100

Definition at line 128 of file fileinfo.c.

◆ FILE_RENAME_FORCE_RESIZE_TARGET_SR

#define FILE_RENAME_FORCE_RESIZE_TARGET_SR   0x080

Definition at line 127 of file fileinfo.c.

◆ FILE_RENAME_IGNORE_READONLY_ATTRIBUTE

#define FILE_RENAME_IGNORE_READONLY_ATTRIBUTE   0x040

Definition at line 126 of file fileinfo.c.

◆ FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE

#define FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE   0x020

Definition at line 125 of file fileinfo.c.

◆ FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE

#define FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE   0x010

Definition at line 124 of file fileinfo.c.

◆ FILE_RENAME_POSIX_SEMANTICS

#define FILE_RENAME_POSIX_SEMANTICS   0x002

Definition at line 121 of file fileinfo.c.

◆ FILE_RENAME_REPLACE_IF_EXISTS

#define FILE_RENAME_REPLACE_IF_EXISTS   0x001

Definition at line 120 of file fileinfo.c.

◆ FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE

#define FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE   0x004

Definition at line 122 of file fileinfo.c.

◆ FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE

#define FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE   0x008

Definition at line 123 of file fileinfo.c.

◆ FileCaseSensitiveInformation

#define FileCaseSensitiveInformation   (enum _FILE_INFORMATION_CLASS)71

Definition at line 30 of file fileinfo.c.

◆ FileDispositionInformationEx

#define FileDispositionInformationEx   (enum _FILE_INFORMATION_CLASS)64

Definition at line 26 of file fileinfo.c.

◆ FileHardLinkFullIdInformation

#define FileHardLinkFullIdInformation   (enum _FILE_INFORMATION_CLASS)62

Definition at line 25 of file fileinfo.c.

◆ FileIdInformation

#define FileIdInformation   (enum _FILE_INFORMATION_CLASS)59

Definition at line 24 of file fileinfo.c.

◆ FileLinkInformationEx

#define FileLinkInformationEx   (enum _FILE_INFORMATION_CLASS)72

Definition at line 31 of file fileinfo.c.

◆ FileRenameInformationEx

#define FileRenameInformationEx   (enum _FILE_INFORMATION_CLASS)65

Definition at line 27 of file fileinfo.c.

◆ FileStatInformation

#define FileStatInformation   (enum _FILE_INFORMATION_CLASS)68

Definition at line 28 of file fileinfo.c.

◆ FileStatLxInformation

#define FileStatLxInformation   (enum _FILE_INFORMATION_CLASS)70

Definition at line 29 of file fileinfo.c.

◆ FileStorageReserveIdInformation

#define FileStorageReserveIdInformation   (enum _FILE_INFORMATION_CLASS)74

Definition at line 32 of file fileinfo.c.

◆ LX_FILE_CASE_SENSITIVE_DIR

#define LX_FILE_CASE_SENSITIVE_DIR   0x10

Definition at line 77 of file fileinfo.c.

◆ LX_FILE_METADATA_HAS_DEVICE_ID

#define LX_FILE_METADATA_HAS_DEVICE_ID   0x08

Definition at line 76 of file fileinfo.c.

◆ LX_FILE_METADATA_HAS_GID

#define LX_FILE_METADATA_HAS_GID   0x02

Definition at line 74 of file fileinfo.c.

◆ LX_FILE_METADATA_HAS_MODE

#define LX_FILE_METADATA_HAS_MODE   0x04

Definition at line 75 of file fileinfo.c.

◆ LX_FILE_METADATA_HAS_UID

#define LX_FILE_METADATA_HAS_UID   0x01

Definition at line 73 of file fileinfo.c.

Typedef Documentation

◆ FILE_CASE_SENSITIVE_INFORMATION

◆ FILE_DISPOSITION_INFORMATION_EX

◆ FILE_ID_INFORMATION

◆ FILE_LINK_ENTRY_FULL_ID_INFORMATION

◆ FILE_LINK_INFORMATION_EX

◆ FILE_LINKS_FULL_ID_INFORMATION

◆ FILE_RENAME_INFORMATION_EX

◆ FILE_STAT_INFORMATION

◆ FILE_STAT_LX_INFORMATION

◆ move_entry

◆ PFILE_CASE_SENSITIVE_INFORMATION

◆ PFILE_DISPOSITION_INFORMATION_EX

◆ PFILE_ID_INFORMATION

◆ PFILE_LINK_ENTRY_FULL_ID_INFORMATION

◆ PFILE_LINK_INFORMATION_EX

◆ PFILE_LINKS_FULL_ID_INFORMATION

◆ PFILE_RENAME_INFORMATION_EX

◆ PFILE_STAT_INFORMATION

◆ PFILE_STAT_LX_INFORMATION

Function Documentation

◆ _Dispatch_type_() [1/4]

_Dispatch_type_ ( IRP_MJ_QUERY_EA  )

Definition at line 5466 of file fileinfo.c.

5468 {
5470 bool top_level;
5471 device_extension* Vcb = DeviceObject->DeviceExtension;
5474 fcb* fcb;
5475 ccb* ccb;
5477 ULONG retlen = 0;
5478
5480
5481 TRACE("(%p, %p)\n", DeviceObject, Irp);
5482
5483 top_level = is_top_level(Irp);
5484
5485 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5487 goto end;
5488 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
5490 goto end;
5491 }
5492
5494 if (!ffei) {
5495 ERR("could not get output buffer\n");
5497 goto end;
5498 }
5499
5500 if (!FileObject) {
5501 ERR("no file object\n");
5503 goto end;
5504 }
5505
5506 fcb = FileObject->FsContext;
5507
5508 if (!fcb) {
5509 ERR("no fcb\n");
5511 goto end;
5512 }
5513
5514 if (fcb == fcb->Vcb->volume_fcb) {
5516 goto end;
5517 }
5518
5519 ccb = FileObject->FsContext2;
5520
5521 if (!ccb) {
5522 ERR("no ccb\n");
5524 goto end;
5525 }
5526
5527 if (Irp->RequestorMode == UserMode && !(ccb->access & (FILE_READ_EA | FILE_WRITE_EA))) {
5528 WARN("insufficient privileges\n");
5530 goto end;
5531 }
5532
5533 if (fcb->ads)
5534 fcb = ccb->fileref->parent->fcb;
5535
5536 ExAcquireResourceSharedLite(fcb->Header.Resource, true);
5537
5538 if (fcb->ea_xattr.Length == 0) {
5540 goto end2;
5541 }
5542
5544
5545 if (IrpSp->Parameters.QueryEa.EaList) {
5548
5549 in = IrpSp->Parameters.QueryEa.EaList;
5550 do {
5551 STRING s;
5552
5553 s.Length = s.MaximumLength = in->EaNameLength;
5554 s.Buffer = in->EaName;
5555
5556 RtlUpperString(&s, &s);
5557
5558 if (in->NextEntryOffset == 0)
5559 break;
5560
5561 in = (FILE_GET_EA_INFORMATION*)(((uint8_t*)in) + in->NextEntryOffset);
5562 } while (true);
5563
5565 out = NULL;
5566
5567 do {
5568 bool found = false;
5569
5570 in = IrpSp->Parameters.QueryEa.EaList;
5571 do {
5572 if (in->EaNameLength == ea->EaNameLength &&
5573 RtlCompareMemory(in->EaName, ea->EaName, in->EaNameLength) == in->EaNameLength) {
5574 found = true;
5575 break;
5576 }
5577
5578 if (in->NextEntryOffset == 0)
5579 break;
5580
5581 in = (FILE_GET_EA_INFORMATION*)(((uint8_t*)in) + in->NextEntryOffset);
5582 } while (true);
5583
5584 if (found) {
5585 uint8_t padding = retlen % 4 > 0 ? (4 - (retlen % 4)) : 0;
5586
5587 if (offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + ea->EaNameLength + 1 + ea->EaValueLength > IrpSp->Parameters.QueryEa.Length - retlen - padding) {
5589 retlen = 0;
5590 goto end2;
5591 }
5592
5593 retlen += padding;
5594
5595 if (out) {
5596 out->NextEntryOffset = (ULONG)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + out->EaNameLength + 1 + out->EaValueLength + padding;
5597 out = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)out) + out->NextEntryOffset);
5598 } else
5599 out = ffei;
5600
5601 out->NextEntryOffset = 0;
5602 out->Flags = ea->Flags;
5603 out->EaNameLength = ea->EaNameLength;
5604 out->EaValueLength = ea->EaValueLength;
5605 RtlCopyMemory(out->EaName, ea->EaName, ea->EaNameLength + ea->EaValueLength + 1);
5606
5607 retlen += (ULONG)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + ea->EaNameLength + 1 + ea->EaValueLength;
5608
5610 break;
5611 }
5612
5613 if (ea->NextEntryOffset == 0)
5614 break;
5615
5616 ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
5617 } while (true);
5618 } else {
5620 ULONG index;
5621
5623 // The index is 1-based
5624 if (IrpSp->Parameters.QueryEa.EaIndex == 0) {
5626 goto end2;
5627 } else
5628 index = IrpSp->Parameters.QueryEa.EaIndex - 1;
5629 } else if (IrpSp->Flags & SL_RESTART_SCAN)
5630 index = ccb->ea_index = 0;
5631 else
5632 index = ccb->ea_index;
5633
5635
5636 if (index > 0) {
5637 ULONG i;
5638
5639 for (i = 0; i < index; i++) {
5640 if (ea->NextEntryOffset == 0) { // last item
5642 goto end2;
5643 }
5644
5645 ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
5646 }
5647 }
5648
5649 out = NULL;
5650
5651 do {
5652 uint8_t padding = retlen % 4 > 0 ? (4 - (retlen % 4)) : 0;
5653
5654 if (offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + ea->EaNameLength + 1 + ea->EaValueLength > IrpSp->Parameters.QueryEa.Length - retlen - padding) {
5656 goto end2;
5657 }
5658
5659 retlen += padding;
5660
5661 if (out) {
5662 out->NextEntryOffset = (ULONG)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + out->EaNameLength + 1 + out->EaValueLength + padding;
5663 out = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)out) + out->NextEntryOffset);
5664 } else
5665 out = ffei;
5666
5667 out->NextEntryOffset = 0;
5668 out->Flags = ea->Flags;
5669 out->EaNameLength = ea->EaNameLength;
5670 out->EaValueLength = ea->EaValueLength;
5671 RtlCopyMemory(out->EaName, ea->EaName, ea->EaNameLength + ea->EaValueLength + 1);
5672
5673 retlen += (ULONG)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + ea->EaNameLength + 1 + ea->EaValueLength;
5674
5675 if (!(IrpSp->Flags & SL_INDEX_SPECIFIED))
5676 ccb->ea_index++;
5677
5679 break;
5680
5681 ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
5682 } while (true);
5683 }
5684
5685end2:
5686 ExReleaseResourceLite(fcb->Header.Resource);
5687
5688end:
5689 TRACE("returning %08lx\n", Status);
5690
5691 Irp->IoStatus.Status = Status;
5692 Irp->IoStatus.Information = NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW ? retlen : 0;
5693
5695
5696 if (top_level)
5698
5700
5701 return Status;
5702}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:689
struct _fcb fcb
Definition: btrfs_drv.h:1364
#define VCB_TYPE_FS
Definition: btrfs_drv.h:687
struct _ccb ccb
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:977
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:278
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
std::wstring STRING
Definition: fontsub.cpp:33
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint index
Definition: glext.h:6031
GLuint in
Definition: glext.h:9616
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
if(dx< 0)
Definition: linetemp.h:194
@ NormalPagePriority
Definition: imports.h:54
static const DWORD padding[]
Definition: mciwnd.c:89
BYTE uint8_t
Definition: msvideo1.c:66
#define UserMode
Definition: asm.h:35
#define FILE_READ_EA
Definition: nt_native.h:638
NTSYSAPI VOID NTAPI RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
#define FILE_WRITE_EA
Definition: nt_native.h:640
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_NONEXISTENT_EA_ENTRY
Definition: ntstatus.h:317
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:318
#define STATUS_NO_MORE_EAS
Definition: ntstatus.h:198
#define Vcb
Definition: cdprocs.h:1415
static FILE * out
Definition: regtests2xml.c:44
#define offsetof(TYPE, MEMBER)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TRACE(s)
Definition: solgame.cpp:4
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@3991 QueryEa
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
ACCESS_MASK access
Definition: btrfs_drv.h:382
file_ref * fileref
Definition: btrfs_drv.h:383
ULONG ea_index
Definition: btrfs_drv.h:385
bool ads
Definition: btrfs_drv.h:330
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
ANSI_STRING ea_xattr
Definition: btrfs_drv.h:302
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
struct _file_ref * parent
Definition: btrfs_drv.h:352
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
* PFILE_OBJECT
Definition: iotypes.h:1998
#define SL_RESTART_SCAN
Definition: iotypes.h:1835

◆ _Dispatch_type_() [2/4]

_Dispatch_type_ ( IRP_MJ_QUERY_INFORMATION  )

Definition at line 5418 of file fileinfo.c.

5420 {
5423 fcb* fcb;
5424 device_extension* Vcb = DeviceObject->DeviceExtension;
5425 bool top_level;
5426
5428
5429 top_level = is_top_level(Irp);
5430
5431 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5433 goto end;
5434 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
5436 goto end;
5437 }
5438
5439 Irp->IoStatus.Information = 0;
5440
5441 TRACE("query information\n");
5442
5444
5445 fcb = IrpSp->FileObject->FsContext;
5446 TRACE("fcb = %p\n", fcb);
5447 TRACE("fcb->subvol = %p\n", fcb->subvol);
5448
5450
5451end:
5452 TRACE("returning %08lx\n", Status);
5453
5454 Irp->IoStatus.Status = Status;
5455
5457
5458 if (top_level)
5460
5462
5463 return Status;
5464}
static NTSTATUS query_info(device_extension *Vcb, PFILE_OBJECT FileObject, PIRP Irp)
Definition: fileinfo.c:5042
struct _root * subvol
Definition: btrfs_drv.h:288

◆ _Dispatch_type_() [3/4]

_Dispatch_type_ ( IRP_MJ_SET_EA  )

Definition at line 5704 of file fileinfo.c.

5706 {
5707 device_extension* Vcb = DeviceObject->DeviceExtension;
5709 bool top_level;
5712 fcb* fcb;
5713 ccb* ccb;
5714 file_ref* fileref;
5716 ULONG offset;
5717 LIST_ENTRY ealist;
5718 ea_item* item;
5720 LIST_ENTRY* le;
5723
5725
5726 TRACE("(%p, %p)\n", DeviceObject, Irp);
5727
5728 top_level = is_top_level(Irp);
5729
5730 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5732 goto end;
5733 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
5735 goto end;
5736 }
5737
5738 if (Vcb->readonly) {
5740 goto end;
5741 }
5742
5744 if (!ffei) {
5745 ERR("could not get output buffer\n");
5747 goto end;
5748 }
5749
5751 if (!NT_SUCCESS(Status)) {
5752 ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset);
5753 goto end;
5754 }
5755
5756 if (!FileObject) {
5757 ERR("no file object\n");
5759 goto end;
5760 }
5761
5762 fcb = FileObject->FsContext;
5763
5764 if (!fcb) {
5765 ERR("no fcb\n");
5767 goto end;
5768 }
5769
5770 if (fcb == fcb->Vcb->volume_fcb) {
5772 goto end;
5773 }
5774
5775 ccb = FileObject->FsContext2;
5776
5777 if (!ccb) {
5778 ERR("no ccb\n");
5780 goto end;
5781 }
5782
5783 if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_EA)) {
5784 WARN("insufficient privileges\n");
5786 goto end;
5787 }
5788
5789 if (fcb->ads) {
5790 fileref = ccb->fileref->parent;
5791 fcb = fileref->fcb;
5792 } else
5793 fileref = ccb->fileref;
5794
5795 InitializeListHead(&ealist);
5796
5797 ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
5798
5799 if (fcb->ea_xattr.Length > 0) {
5801
5802 do {
5804 if (!item) {
5805 ERR("out of memory\n");
5807 goto end2;
5808 }
5809
5810 item->name.Length = item->name.MaximumLength = ea->EaNameLength;
5811 item->name.Buffer = ea->EaName;
5812
5813 item->value.Length = item->value.MaximumLength = ea->EaValueLength;
5814 item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
5815
5816 item->flags = ea->Flags;
5817
5818 InsertTailList(&ealist, &item->list_entry);
5819
5820 if (ea->NextEntryOffset == 0)
5821 break;
5822
5823 ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
5824 } while (true);
5825 }
5826
5827 ea = ffei;
5828
5829 do {
5830 STRING s;
5831 bool found = false;
5832
5833 s.Length = s.MaximumLength = ea->EaNameLength;
5834 s.Buffer = ea->EaName;
5835
5836 RtlUpperString(&s, &s);
5837
5838 le = ealist.Flink;
5839 while (le != &ealist) {
5841
5842 if (item->name.Length == s.Length &&
5843 RtlCompareMemory(item->name.Buffer, s.Buffer, s.Length) == s.Length) {
5844 item->flags = ea->Flags;
5845 item->value.Length = item->value.MaximumLength = ea->EaValueLength;
5846 item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
5847 found = true;
5848 break;
5849 }
5850
5851 le = le->Flink;
5852 }
5853
5854 if (!found) {
5856 if (!item) {
5857 ERR("out of memory\n");
5859 goto end2;
5860 }
5861
5862 item->name.Length = item->name.MaximumLength = ea->EaNameLength;
5863 item->name.Buffer = ea->EaName;
5864
5865 item->value.Length = item->value.MaximumLength = ea->EaValueLength;
5866 item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
5867
5868 item->flags = ea->Flags;
5869
5870 InsertTailList(&ealist, &item->list_entry);
5871 }
5872
5873 if (ea->NextEntryOffset == 0)
5874 break;
5875
5876 ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
5877 } while (true);
5878
5879 // remove entries with zero-length value
5880 le = ealist.Flink;
5881 while (le != &ealist) {
5882 LIST_ENTRY* le2 = le->Flink;
5883
5885
5886 if (item->value.Length == 0) {
5887 RemoveEntryList(&item->list_entry);
5889 }
5890
5891 le = le2;
5892 }
5893
5894 // handle LXSS values
5895 le = ealist.Flink;
5896 while (le != &ealist) {
5897 LIST_ENTRY* le2 = le->Flink;
5898
5900
5901 if (item->name.Length == sizeof(lxuid) - 1 && RtlCompareMemory(item->name.Buffer, lxuid, item->name.Length) == item->name.Length) {
5902 if (item->value.Length < sizeof(uint32_t)) {
5903 ERR("uid value was shorter than expected\n");
5905 goto end2;
5906 }
5907
5908 if (Irp->RequestorMode == KernelMode || ccb->access & FILE_WRITE_ATTRIBUTES) {
5909 RtlCopyMemory(&fcb->inode_item.st_uid, item->value.Buffer, sizeof(uint32_t));
5910 fcb->sd_dirty = true;
5911 fcb->sd_deleted = false;
5912 }
5913
5914 RemoveEntryList(&item->list_entry);
5916 } else if (item->name.Length == sizeof(lxgid) - 1 && RtlCompareMemory(item->name.Buffer, lxgid, item->name.Length) == item->name.Length) {
5917 if (item->value.Length < sizeof(uint32_t)) {
5918 ERR("gid value was shorter than expected\n");
5920 goto end2;
5921 }
5922
5923 if (Irp->RequestorMode == KernelMode || ccb->access & FILE_WRITE_ATTRIBUTES)
5924 RtlCopyMemory(&fcb->inode_item.st_gid, item->value.Buffer, sizeof(uint32_t));
5925
5926 RemoveEntryList(&item->list_entry);
5928 } else if (item->name.Length == sizeof(lxmod) - 1 && RtlCompareMemory(item->name.Buffer, lxmod, item->name.Length) == item->name.Length) {
5929 if (item->value.Length < sizeof(uint32_t)) {
5930 ERR("mode value was shorter than expected\n");
5932 goto end2;
5933 }
5934
5935 if (Irp->RequestorMode == KernelMode || ccb->access & FILE_WRITE_ATTRIBUTES) {
5937 uint32_t val;
5938
5939 RtlCopyMemory(&val, item->value.Buffer, sizeof(uint32_t));
5940
5941 fcb->inode_item.st_mode &= ~allowed;
5942 fcb->inode_item.st_mode |= val & allowed;
5943 }
5944
5945 RemoveEntryList(&item->list_entry);
5947 }
5948
5949 le = le2;
5950 }
5951
5952 if (IsListEmpty(&ealist)) {
5953 fcb->ealen = 0;
5954
5955 if (fcb->ea_xattr.Buffer)
5957
5960 } else {
5961 uint16_t size = 0;
5962 char *buf, *oldbuf;
5963
5964 le = ealist.Flink;
5965 while (le != &ealist) {
5967
5968 if (size % 4 > 0)
5969 size += 4 - (size % 4);
5970
5971 size += (uint16_t)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + item->name.Length + 1 + item->value.Length;
5972
5973 le = le->Flink;
5974 }
5975
5977 if (!buf) {
5978 ERR("out of memory\n");
5980 goto end2;
5981 }
5982
5983 oldbuf = fcb->ea_xattr.Buffer;
5984
5987
5988 fcb->ealen = 4;
5989 ea = NULL;
5990
5991 le = ealist.Flink;
5992 while (le != &ealist) {
5994
5995 if (ea) {
5997
5998 if (ea->NextEntryOffset % 4 > 0)
5999 ea->NextEntryOffset += 4 - (ea->NextEntryOffset % 4);
6000
6001 ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
6002 } else
6004
6005 ea->NextEntryOffset = 0;
6006 ea->Flags = item->flags;
6007 ea->EaNameLength = (UCHAR)item->name.Length;
6008 ea->EaValueLength = item->value.Length;
6009
6010 RtlCopyMemory(ea->EaName, item->name.Buffer, item->name.Length);
6011 ea->EaName[item->name.Length] = 0;
6012 RtlCopyMemory(&ea->EaName[item->name.Length + 1], item->value.Buffer, item->value.Length);
6013
6014 fcb->ealen += 5 + item->name.Length + item->value.Length;
6015
6016 le = le->Flink;
6017 }
6018
6019 if (oldbuf)
6020 ExFreePool(oldbuf);
6021 }
6022
6023 fcb->ea_changed = true;
6024
6027
6028 fcb->inode_item.transid = Vcb->superblock.generation;
6030
6033
6034 fcb->inode_item_changed = true;
6036
6038
6040
6041end2:
6042 ExReleaseResourceLite(fcb->Header.Resource);
6043
6044 while (!IsListEmpty(&ealist)) {
6045 le = RemoveHeadList(&ealist);
6046
6048
6050 }
6051
6052end:
6053 TRACE("returning %08lx\n", Status);
6054
6055 Irp->IoStatus.Status = Status;
6056 Irp->IoStatus.Information = 0;
6057
6059
6060 if (top_level)
6062
6064
6065 return Status;
6066}
unsigned short int uint16_t
Definition: acefiex.h:54
static const char lxgid[]
Definition: btrfs_drv.h:1288
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:989
#define ALLOC_TAG
Definition: btrfs_drv.h:87
static const char lxmod[]
Definition: btrfs_drv.h:1289
static const char lxuid[]
Definition: btrfs_drv.h:1287
UINT32 uint32_t
Definition: types.h:75
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1695
void send_notification_fileref(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1517
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
time_t now
Definition: finger.c:65
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLintptr offset
Definition: glext.h:5920
__u16 time
Definition: mkdosfs.c:8
static ATOM item
Definition: dde.c:856
#define KernelMode
Definition: asm.h:34
#define uint16_t
Definition: nsiface.idl:60
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
#define S_IXGRP
Definition: propsheet.h:49
#define S_IROTH
Definition: propsheet.h:53
#define S_ISUID
Definition: propsheet.h:65
#define S_IXOTH
Definition: propsheet.h:61
#define S_IRGRP
Definition: propsheet.h:41
#define S_IWOTH
Definition: propsheet.h:57
#define S_IRUSR
Definition: propsheet.h:29
#define S_ISVTX
Definition: propsheet.h:73
#define S_ISGID
Definition: propsheet.h:69
#define S_IWUSR
Definition: propsheet.h:33
#define S_IWGRP
Definition: propsheet.h:45
#define S_IXUSR
Definition: propsheet.h:37
uint32_t st_mode
Definition: btrfs.h:295
uint32_t st_uid
Definition: btrfs.h:293
uint64_t sequence
Definition: btrfs.h:299
BTRFS_TIME st_ctime
Definition: btrfs.h:302
uint64_t transid
Definition: btrfs.h:288
uint32_t st_gid
Definition: btrfs.h:294
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _IO_STACK_LOCATION::@3980::@3992 SetEa
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
bool user_set_change_time
Definition: btrfs_drv.h:390
ULONG ealen
Definition: btrfs_drv.h:303
bool sd_dirty
Definition: btrfs_drv.h:321
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
bool sd_deleted
Definition: btrfs_drv.h:321
bool ea_changed
Definition: btrfs_drv.h:325
bool inode_item_changed
Definition: btrfs_drv.h:306
fcb * fcb
Definition: btrfs_drv.h:342
Definition: list.h:27
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FILE_ACTION_MODIFIED
#define FILE_NOTIFY_CHANGE_EA
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ _Dispatch_type_() [4/4]

_Dispatch_type_ ( IRP_MJ_SET_INFORMATION  )

Definition at line 3889 of file fileinfo.c.

3891 {
3894 device_extension* Vcb = DeviceObject->DeviceExtension;
3895 fcb* fcb = IrpSp->FileObject->FsContext;
3896 ccb* ccb = IrpSp->FileObject->FsContext2;
3897 bool top_level;
3898
3900
3901 top_level = is_top_level(Irp);
3902
3903 Irp->IoStatus.Information = 0;
3904
3905 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
3907 goto end;
3908 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
3910 goto end;
3911 }
3912
3913 if (!(Vcb->Vpb->Flags & VPB_MOUNTED)) {
3915 goto end;
3916 }
3917
3918 if (Vcb->readonly && IrpSp->Parameters.SetFile.FileInformationClass != FilePositionInformation) {
3920 goto end;
3921 }
3922
3923 if (!fcb) {
3924 ERR("no fcb\n");
3926 goto end;
3927 }
3928
3929 if (!ccb) {
3930 ERR("no ccb\n");
3932 goto end;
3933 }
3934
3935 if (fcb != Vcb->dummy_fcb && is_subvol_readonly(fcb->subvol, Irp) && IrpSp->Parameters.SetFile.FileInformationClass != FilePositionInformation &&
3936#ifndef __REACTOS__
3937 (fcb->inode != SUBVOL_ROOT_INODE || (IrpSp->Parameters.SetFile.FileInformationClass != FileBasicInformation && IrpSp->Parameters.SetFile.FileInformationClass != FileRenameInformation && IrpSp->Parameters.SetFile.FileInformationClass != FileRenameInformationEx))) {
3938#else
3939 (fcb->inode != SUBVOL_ROOT_INODE || (IrpSp->Parameters.SetFile.FileInformationClass != FileBasicInformation && IrpSp->Parameters.SetFile.FileInformationClass != FileRenameInformation))) {
3940#endif
3942 goto end;
3943 }
3944
3946
3947 TRACE("set information\n");
3948
3950
3951 switch (IrpSp->Parameters.SetFile.FileInformationClass) {
3953 {
3954 TRACE("FileAllocationInformation\n");
3955
3956 if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_DATA)) {
3957 WARN("insufficient privileges\n");
3959 break;
3960 }
3961
3963 break;
3964 }
3965
3967 {
3968 TRACE("FileBasicInformation\n");
3969
3970 if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_ATTRIBUTES)) {
3971 WARN("insufficient privileges\n");
3973 break;
3974 }
3975
3977
3978 break;
3979 }
3980
3982 {
3983 TRACE("FileDispositionInformation\n");
3984
3985 if (Irp->RequestorMode == UserMode && !(ccb->access & DELETE)) {
3986 WARN("insufficient privileges\n");
3988 break;
3989 }
3990
3992
3993 break;
3994 }
3995
3997 {
3998 TRACE("FileEndOfFileInformation\n");
3999
4000 if (Irp->RequestorMode == UserMode && !(ccb->access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
4001 WARN("insufficient privileges\n");
4003 break;
4004 }
4005
4007
4008 break;
4009 }
4010
4012 TRACE("FileLinkInformation\n");
4014 break;
4015
4017 TRACE("FilePositionInformation\n");
4019 break;
4020
4022 TRACE("FileRenameInformation\n");
4024 break;
4025
4027 {
4028 TRACE("FileValidDataLengthInformation\n");
4029
4030 if (Irp->RequestorMode == UserMode && !(ccb->access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
4031 WARN("insufficient privileges\n");
4033 break;
4034 }
4035
4037
4038 break;
4039 }
4040
4041#ifndef __REACTOS__
4042#ifndef _MSC_VER
4043#pragma GCC diagnostic push
4044#pragma GCC diagnostic ignored "-Wswitch"
4045#endif
4047 {
4048 TRACE("FileDispositionInformationEx\n");
4049
4050 if (Irp->RequestorMode == UserMode && !(ccb->access & DELETE)) {
4051 WARN("insufficient privileges\n");
4053 break;
4054 }
4055
4057
4058 break;
4059 }
4060
4062 TRACE("FileRenameInformationEx\n");
4064 break;
4065
4067 TRACE("FileLinkInformationEx\n");
4069 break;
4070
4072 TRACE("FileCaseSensitiveInformation\n");
4073
4074 if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_ATTRIBUTES)) {
4075 WARN("insufficient privileges\n");
4077 break;
4078 }
4079
4081 break;
4082
4084 WARN("unimplemented FileInformationClass FileStorageReserveIdInformation\n");
4085 break;
4086
4087#ifndef _MSC_VER
4088#pragma GCC diagnostic pop
4089#endif
4090#endif
4091
4092 default:
4093 WARN("unknown FileInformationClass %u\n", IrpSp->Parameters.SetFile.FileInformationClass);
4094 }
4095
4096end:
4097 Irp->IoStatus.Status = Status;
4098
4099 TRACE("returning %08lx\n", Status);
4100
4102
4103 if (top_level)
4105
4107
4108 return Status;
4109}
static __inline POPLOCK fcb_oplock(fcb *fcb)
Definition: btrfs_drv.h:1677
static __inline bool is_subvol_readonly(root *r, PIRP Irp)
Definition: btrfs_drv.h:1033
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static NTSTATUS set_link_information(device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, PFILE_OBJECT tfo, bool ex)
Definition: fileinfo.c:3406
#define FileStorageReserveIdInformation
Definition: fileinfo.c:32
#define FileCaseSensitiveInformation
Definition: fileinfo.c:30
static NTSTATUS set_end_of_file_information(device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, bool advance_only, bool prealloc)
Definition: fileinfo.c:3240
#define FileRenameInformationEx
Definition: fileinfo.c:27
#define FileDispositionInformationEx
Definition: fileinfo.c:26
static NTSTATUS set_case_sensitive_information(PIRP Irp)
Definition: fileinfo.c:3856
static NTSTATUS set_rename_information(device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, PFILE_OBJECT tfo, bool ex)
Definition: fileinfo.c:2527
static NTSTATUS set_valid_data_length_information(device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject)
Definition: fileinfo.c:3760
static NTSTATUS set_disposition_information(device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject, bool ex)
Definition: fileinfo.c:357
#define FileLinkInformationEx
Definition: fileinfo.c:31
static NTSTATUS set_basic_information(device_extension *Vcb, PIRP Irp, PFILE_OBJECT FileObject)
Definition: fileinfo.c:190
static NTSTATUS set_position_information(PFILE_OBJECT FileObject, PIRP Irp)
Definition: fileinfo.c:3394
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileValidDataLengthInformation
Definition: from_kernel.h:100
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define DELETE
Definition: nt_native.h:57
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1170
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
struct _IO_STACK_LOCATION::@3980::@3990 SetFile
uint64_t inode
Definition: btrfs_drv.h:289
#define VPB_MOUNTED
Definition: iotypes.h:1807

◆ add_children_to_move_list()

static NTSTATUS add_children_to_move_list ( device_extension Vcb,
move_entry me,
PIRP  Irp 
)
static

Definition at line 701 of file fileinfo.c.

701 {
703 LIST_ENTRY* le;
704
705 ExAcquireResourceSharedLite(&me->fileref->fcb->nonpaged->dir_children_lock, true);
706
708
709 while (le != &me->fileref->fcb->dir_children_index) {
710 dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_index);
711 file_ref* fr;
712 move_entry* me2;
713
714 Status = open_fileref_child(Vcb, me->fileref, &dc->name, true, true, dc->index == 0 ? true : false, PagedPool, &fr, Irp);
715
716 if (!NT_SUCCESS(Status)) {
717 ERR("open_fileref_child returned %08lx\n", Status);
718 ExReleaseResourceLite(&me->fileref->fcb->nonpaged->dir_children_lock);
719 return Status;
720 }
721
723 if (!me2) {
724 ERR("out of memory\n");
725 ExReleaseResourceLite(&me->fileref->fcb->nonpaged->dir_children_lock);
727 }
728
729 me2->fileref = fr;
730 me2->dummyfcb = NULL;
731 me2->dummyfileref = NULL;
732 me2->parent = me;
733
735
736 le = le->Flink;
737 }
738
739 ExReleaseResourceLite(&me->fileref->fcb->nonpaged->dir_children_lock);
740
741 return STATUS_SUCCESS;
742}
NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _In_ file_ref *sf, _In_ PUNICODE_STRING name, _In_ bool case_sensitive, _In_ bool lastpart, _In_ bool streampart, _In_ POOL_TYPE pooltype, _Out_ file_ref **psf2, _In_opt_ PIRP Irp)
Definition: create.c:1459
#define InsertHeadList(ListHead, Entry)
static const WCHAR dc[]
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:314
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
Definition: fileinfo.c:693
fcb * dummyfcb
Definition: fileinfo.c:695
LIST_ENTRY list_entry
Definition: fileinfo.c:698
file_ref * dummyfileref
Definition: fileinfo.c:696
file_ref * fileref
Definition: fileinfo.c:694
struct _move_entry * parent
Definition: fileinfo.c:697

Referenced by move_across_subvols().

◆ add_fcb_to_subvol()

void add_fcb_to_subvol ( _In_ _Requires_exclusive_lock_held_(_Curr_->Vcb->fcb_lock) fcb fcb)

Definition at line 888 of file fileinfo.c.

888 {
889 LIST_ENTRY* lastle = NULL;
891
892 if (fcb->subvol->fcbs_ptrs[hash >> 24]) {
893 LIST_ENTRY* le = fcb->subvol->fcbs_ptrs[hash >> 24];
894
895 while (le != &fcb->subvol->fcbs) {
896 struct _fcb* fcb2 = CONTAINING_RECORD(le, struct _fcb, list_entry);
897
898 if (fcb2->hash > hash) {
899 lastle = le->Blink;
900 break;
901 }
902
903 le = le->Flink;
904 }
905 }
906
907 if (!lastle) {
908 uint8_t c = hash >> 24;
909
910 if (c != 0xff) {
911 uint8_t d = c + 1;
912
913 do {
914 if (fcb->subvol->fcbs_ptrs[d]) {
915 lastle = fcb->subvol->fcbs_ptrs[d]->Blink;
916 break;
917 }
918
919 d++;
920 } while (d != 0);
921 }
922 }
923
924 if (lastle) {
925 InsertHeadList(lastle, &fcb->list_entry);
926
927 if (lastle == &fcb->subvol->fcbs || (CONTAINING_RECORD(lastle, struct _fcb, list_entry)->hash >> 24) != (hash >> 24))
928 fcb->subvol->fcbs_ptrs[hash >> 24] = &fcb->list_entry;
929 } else {
931
932 if (fcb->list_entry.Blink == &fcb->subvol->fcbs || (CONTAINING_RECORD(fcb->list_entry.Blink, struct _fcb, list_entry)->hash >> 24) != (hash >> 24))
933 fcb->subvol->fcbs_ptrs[hash >> 24] = &fcb->list_entry;
934 }
935}
const GLubyte * c
Definition: glext.h:8905
#define d
Definition: ke_i.h:81
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
LIST_ENTRY list_entry
Definition: btrfs_drv.h:336
uint32_t hash
Definition: btrfs_drv.h:290
Definition: _hash_fun.h:40

Referenced by allocate_cache_chunk(), create_directory_fcb(), create_subvol(), mknod(), move_across_subvols(), rename_stream(), and rename_stream_to_file().

◆ create_directory_fcb()

static NTSTATUS create_directory_fcb ( device_extension Vcb,
root r,
fcb parfcb,
fcb **  pfcb 
)
static

Definition at line 782 of file fileinfo.c.

782 {
784 fcb* fcb;
786 PSID owner;
787 BOOLEAN defaulted;
790
792 if (!fcb) {
793 ERR("out of memory\n");
795 }
796
799
800 fcb->Vcb = Vcb;
801
802 fcb->subvol = r;
803 fcb->inode = InterlockedIncrement64(&r->lastinode);
804 fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&fcb->inode, sizeof(uint64_t));
806
807 fcb->inode_item.generation = Vcb->superblock.generation;
808 fcb->inode_item.transid = Vcb->superblock.generation;
810 fcb->inode_item.st_mode = __S_IFDIR | inherit_mode(parfcb, true);
813
814 fcb->atts = get_file_attributes(Vcb, fcb->subvol, fcb->inode, fcb->type, false, true, NULL);
815
816 SeCaptureSubjectContext(&subjcont);
817
818 Status = SeAssignSecurity(parfcb->sd, NULL, (void**)&fcb->sd, true, &subjcont, IoGetFileObjectGenericMapping(), PagedPool);
819
820 if (!NT_SUCCESS(Status)) {
821 reap_fcb(fcb);
822 ERR("SeAssignSecurity returned %08lx\n", Status);
823 return Status;
824 }
825
826 if (!fcb->sd) {
827 reap_fcb(fcb);
828 ERR("SeAssignSecurity returned NULL security descriptor\n");
830 }
831
832 Status = RtlGetOwnerSecurityDescriptor(fcb->sd, &owner, &defaulted);
833 if (!NT_SUCCESS(Status)) {
834 ERR("RtlGetOwnerSecurityDescriptor returned %08lx\n", Status);
836 fcb->sd_dirty = true;
837 } else {
840 }
841
842 find_gid(fcb, parfcb, &subjcont);
843
844 fcb->inode_item_changed = true;
845
846 fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
847 fcb->Header.AllocationSize.QuadPart = 0;
848 fcb->Header.FileSize.QuadPart = 0;
849 fcb->Header.ValidDataLength.QuadPart = 0;
850
851 fcb->created = true;
852
855
858
860 if (!fcb->hash_ptrs) {
861 ERR("out of memory\n");
863 }
864
865 RtlZeroMemory(fcb->hash_ptrs, sizeof(LIST_ENTRY*) * 256);
866
868 if (!fcb->hash_ptrs_uc) {
869 ERR("out of memory\n");
871 }
872
873 RtlZeroMemory(fcb->hash_ptrs_uc, sizeof(LIST_ENTRY*) * 256);
874
875 acquire_fcb_lock_exclusive(Vcb);
877 InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
878 r->fcbs_version++;
879 release_fcb_lock(Vcb);
880
882
883 *pfcb = fcb;
884
885 return STATUS_SUCCESS;
886}
unsigned char BOOLEAN
#define GID_NOBODY
Definition: btrfs_drv.h:91
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1684
#define UID_NOBODY
Definition: btrfs_drv.h:90
#define __S_IFDIR
Definition: btrfs_drv.h:1754
uint32_t sid_to_uid(PSID sid)
Definition: security.c:310
uint32_t inherit_mode(fcb *parfcb, bool is_dir)
Definition: create.c:1948
void find_gid(struct _fcb *fcb, struct _fcb *parfcb, PSECURITY_SUBJECT_CONTEXT subjcont)
Definition: security.c:924
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:91
@ PropCompression_None
Definition: btrfs_drv.h:268
crc_func calc_crc32c
Definition: crc32c.c:23
UINT64 uint64_t
Definition: types.h:77
ULONG get_file_attributes(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_ uint64_t inode, _In_ uint8_t type, _In_ bool dotfile, _In_ bool ignore_xa, _In_opt_ PIRP Irp)
Definition: btrfs.c:2664
void reap_fcb(fcb *fcb)
Definition: btrfs.c:1743
void add_fcb_to_subvol(_In_ _Requires_exclusive_lock_held_(_Curr_->Vcb->fcb_lock) fcb *fcb)
Definition: fileinfo.c:888
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
NTSYSAPI NTSTATUS NTAPI RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PBOOLEAN OwnerDefaulted)
Definition: sd.c:257
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define BTRFS_INODE_COMPRESS
Definition: propsheet.h:87
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
uint32_t st_nlink
Definition: btrfs.h:292
uint32_t flags
Definition: btrfs.h:297
BTRFS_TIME otime
Definition: btrfs.h:304
BTRFS_TIME st_mtime
Definition: btrfs.h:303
BTRFS_TIME st_atime
Definition: btrfs.h:301
uint64_t generation
Definition: btrfs.h:287
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:337
ULONG atts
Definition: btrfs_drv.h:297
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:293
bool created
Definition: btrfs_drv.h:328
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:318
uint8_t type
Definition: btrfs_drv.h:291
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:317
enum prop_compression_type prop_compression
Definition: btrfs_drv.h:307
bool prop_compression_changed
Definition: btrfs_drv.h:326
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by move_across_subvols().

◆ duplicate_fcb()

static NTSTATUS duplicate_fcb ( fcb oldfcb,
fcb **  pfcb 
)
static

Definition at line 463 of file fileinfo.c.

463 {
464 device_extension* Vcb = oldfcb->Vcb;
465 fcb* fcb;
466 LIST_ENTRY* le;
467
468 // FIXME - we can skip a lot of this if the inode is about to be deleted
469
470 fcb = create_fcb(Vcb, PagedPool); // FIXME - what if we duplicate the paging file?
471 if (!fcb) {
472 ERR("out of memory\n");
474 }
475
476 fcb->Vcb = Vcb;
477
478 fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
479 fcb->Header.AllocationSize = oldfcb->Header.AllocationSize;
480 fcb->Header.FileSize = oldfcb->Header.FileSize;
481 fcb->Header.ValidDataLength = oldfcb->Header.ValidDataLength;
482
483 fcb->type = oldfcb->type;
484
485 if (oldfcb->ads) {
486 fcb->ads = true;
487 fcb->adshash = oldfcb->adshash;
488 fcb->adsmaxlen = oldfcb->adsmaxlen;
489
490 if (oldfcb->adsxattr.Buffer && oldfcb->adsxattr.Length > 0) {
491 fcb->adsxattr.Length = oldfcb->adsxattr.Length;
494
495 if (!fcb->adsxattr.Buffer) {
496 ERR("out of memory\n");
497 free_fcb(fcb);
499 }
500
503 }
504
505 if (oldfcb->adsdata.Buffer && oldfcb->adsdata.Length > 0) {
508
509 if (!fcb->adsdata.Buffer) {
510 ERR("out of memory\n");
511 free_fcb(fcb);
513 }
514
516 }
517
518 goto end;
519 }
520
521 RtlCopyMemory(&fcb->inode_item, &oldfcb->inode_item, sizeof(INODE_ITEM));
522 fcb->inode_item_changed = true;
523
524 if (oldfcb->sd && RtlLengthSecurityDescriptor(oldfcb->sd) > 0) {
526 if (!fcb->sd) {
527 ERR("out of memory\n");
528 free_fcb(fcb);
530 }
531
533 }
534
535 fcb->atts = oldfcb->atts;
536
537 le = oldfcb->extents.Flink;
538 while (le != &oldfcb->extents) {
540
541 if (!ext->ignore) {
542 extent* ext2 = ExAllocatePoolWithTag(PagedPool, offsetof(extent, extent_data) + ext->datalen, ALLOC_TAG);
543
544 if (!ext2) {
545 ERR("out of memory\n");
546 free_fcb(fcb);
548 }
549
550 ext2->offset = ext->offset;
551 ext2->datalen = ext->datalen;
552
553 if (ext2->datalen > 0)
554 RtlCopyMemory(&ext2->extent_data, &ext->extent_data, ext2->datalen);
555
556 ext2->unique = false;
557 ext2->ignore = false;
558 ext2->inserted = true;
559
560 if (ext->csum) {
561 ULONG len;
562 EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ext->extent_data.data;
563
564 if (ext->extent_data.compression == BTRFS_COMPRESSION_NONE)
565 len = (ULONG)ed2->num_bytes;
566 else
567 len = (ULONG)ed2->size;
568
569 len = (len * sizeof(uint32_t)) >> Vcb->sector_shift;
570
572 if (!ext2->csum) {
573 ERR("out of memory\n");
574 free_fcb(fcb);
576 }
577
578 RtlCopyMemory(ext2->csum, ext->csum, len);
579 } else
580 ext2->csum = NULL;
581
582 InsertTailList(&fcb->extents, &ext2->list_entry);
583 }
584
585 le = le->Flink;
586 }
587
588 le = oldfcb->hardlinks.Flink;
589 while (le != &oldfcb->hardlinks) {
591
593
594 if (!hl2) {
595 ERR("out of memory\n");
596 free_fcb(fcb);
598 }
599
600 hl2->parent = hl->parent;
601 hl2->index = hl->index;
602
603 hl2->name.Length = hl2->name.MaximumLength = hl->name.Length;
604 hl2->name.Buffer = ExAllocatePoolWithTag(PagedPool, hl2->name.MaximumLength, ALLOC_TAG);
605
606 if (!hl2->name.Buffer) {
607 ERR("out of memory\n");
608 ExFreePool(hl2);
609 free_fcb(fcb);
611 }
612
613 RtlCopyMemory(hl2->name.Buffer, hl->name.Buffer, hl->name.Length);
614
615 hl2->utf8.Length = hl2->utf8.MaximumLength = hl->utf8.Length;
616 hl2->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, hl2->utf8.MaximumLength, ALLOC_TAG);
617
618 if (!hl2->utf8.Buffer) {
619 ERR("out of memory\n");
620 ExFreePool(hl2->name.Buffer);
621 ExFreePool(hl2);
622 free_fcb(fcb);
624 }
625
626 RtlCopyMemory(hl2->utf8.Buffer, hl->utf8.Buffer, hl->utf8.Length);
627
628 InsertTailList(&fcb->hardlinks, &hl2->list_entry);
629
630 le = le->Flink;
631 }
632
633 if (oldfcb->reparse_xattr.Buffer && oldfcb->reparse_xattr.Length > 0) {
635
637 if (!fcb->reparse_xattr.Buffer) {
638 ERR("out of memory\n");
639 free_fcb(fcb);
641 }
642
644 }
645
646 if (oldfcb->ea_xattr.Buffer && oldfcb->ea_xattr.Length > 0) {
648
650 if (!fcb->ea_xattr.Buffer) {
651 ERR("out of memory\n");
652 free_fcb(fcb);
654 }
655
657 }
658
660
661 le = oldfcb->xattrs.Flink;
662 while (le != &oldfcb->xattrs) {
664
665 if (xa->valuelen > 0) {
666 xattr* xa2;
667
669
670 if (!xa2) {
671 ERR("out of memory\n");
672 free_fcb(fcb);
674 }
675
676 xa2->namelen = xa->namelen;
677 xa2->valuelen = xa->valuelen;
678 xa2->dirty = xa->dirty;
679 memcpy(xa2->data, xa->data, xa->namelen + xa->valuelen);
680
682 }
683
684 le = le->Flink;
685 }
686
687end:
688 *pfcb = fcb;
689
690 return STATUS_SUCCESS;
691}
static const WCHAR *const ext[]
Definition: module.c:53
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1734
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const BYTE ext2[]
Definition: encode.c:2699
#define uint32_t
Definition: nsiface.idl:61
uint64_t num_bytes
Definition: btrfs.h:371
uint64_t size
Definition: btrfs.h:369
LIST_ENTRY xattrs
Definition: btrfs_drv.h:308
LIST_ENTRY hardlinks
Definition: btrfs_drv.h:304
LIST_ENTRY extents
Definition: btrfs_drv.h:300
ANSI_STRING adsdata
Definition: btrfs_drv.h:334
ANSI_STRING adsxattr
Definition: btrfs_drv.h:333
ULONG adsmaxlen
Definition: btrfs_drv.h:332
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
uint32_t adshash
Definition: btrfs_drv.h:331
char * name
Definition: compiler.c:66
bool dirty
Definition: btrfs_drv.h:278
USHORT namelen
Definition: btrfs_drv.h:276
char data[1]
Definition: btrfs_drv.h:279
USHORT valuelen
Definition: btrfs_drv.h:277
LIST_ENTRY list_entry
Definition: btrfs_drv.h:275

Referenced by move_across_subvols(), and rename_file_to_stream().

◆ fileref_get_filename()

NTSTATUS fileref_get_filename ( file_ref fileref,
PUNICODE_STRING  fn,
USHORT name_offset,
ULONG preqlen 
)

Definition at line 4245 of file fileinfo.c.

4245 {
4246 file_ref* fr;
4248 ULONG reqlen = 0;
4249 USHORT offset;
4250 bool overflow = false;
4251
4252 // FIXME - we need a lock on filerefs' filepart
4253
4254 if (fileref == fileref->fcb->Vcb->root_fileref) {
4255 if (fn->MaximumLength >= sizeof(WCHAR)) {
4256 fn->Buffer[0] = '\\';
4257 fn->Length = sizeof(WCHAR);
4258
4259 if (name_offset)
4260 *name_offset = 0;
4261
4262 return STATUS_SUCCESS;
4263 } else {
4264 if (preqlen)
4265 *preqlen = sizeof(WCHAR);
4266 fn->Length = 0;
4267
4269 }
4270 }
4271
4272 fr = fileref;
4273 offset = 0;
4274
4275 while (fr->parent) {
4276 USHORT movelen;
4277
4278 if (!fr->dc)
4279 return STATUS_INTERNAL_ERROR;
4280
4281 if (!overflow) {
4282 if (fr->dc->name.Length + sizeof(WCHAR) + fn->Length > fn->MaximumLength)
4283 overflow = true;
4284 }
4285
4286 if (overflow)
4287 movelen = fn->MaximumLength - fr->dc->name.Length - sizeof(WCHAR);
4288 else
4289 movelen = fn->Length;
4290
4291 if ((!overflow || fn->MaximumLength > fr->dc->name.Length + sizeof(WCHAR)) && movelen > 0) {
4292 RtlMoveMemory(&fn->Buffer[(fr->dc->name.Length / sizeof(WCHAR)) + 1], fn->Buffer, movelen);
4293 offset += fr->dc->name.Length + sizeof(WCHAR);
4294 }
4295
4296 if (fn->MaximumLength >= sizeof(WCHAR)) {
4297 fn->Buffer[0] = fr->fcb->ads ? ':' : '\\';
4298 fn->Length += sizeof(WCHAR);
4299
4300 if (fn->MaximumLength > sizeof(WCHAR)) {
4301 RtlCopyMemory(&fn->Buffer[1], fr->dc->name.Buffer, min(fr->dc->name.Length, fn->MaximumLength - sizeof(WCHAR)));
4302 fn->Length += fr->dc->name.Length;
4303 }
4304
4305 if (fn->Length > fn->MaximumLength) {
4306 fn->Length = fn->MaximumLength;
4307 overflow = true;
4308 }
4309 }
4310
4311 reqlen += sizeof(WCHAR) + fr->dc->name.Length;
4312
4313 fr = fr->parent;
4314 }
4315
4316 offset += sizeof(WCHAR);
4317
4318 if (overflow) {
4319 if (preqlen)
4320 *preqlen = reqlen;
4322 } else {
4323 if (name_offset)
4324 *name_offset = offset;
4325
4327 }
4328
4329 return Status;
4330}
#define min(a, b)
Definition: monoChain.cc:55
unsigned short USHORT
Definition: pedump.c:61
dir_child * dc
Definition: btrfs_drv.h:353
UNICODE_STRING name
Definition: btrfs_drv.h:256
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by fill_in_file_name_information(), get_subvol_path(), notify_change_directory(), send_notification_fcb(), send_notification_fileref(), and set_rename_information().

◆ fill_in_file_attribute_information()

static NTSTATUS fill_in_file_attribute_information ( FILE_ATTRIBUTE_TAG_INFORMATION ati,
fcb fcb,
ccb ccb,
LONG length 
)
static

Definition at line 4389 of file fileinfo.c.

4389 {
4391
4392 if (fcb->ads) {
4393 if (!ccb->fileref || !ccb->fileref->parent) {
4394 ERR("no fileref for stream\n");
4395 return STATUS_INTERNAL_ERROR;
4396 }
4397
4398 ati->FileAttributes = ccb->fileref->parent->fcb->atts;
4399 } else
4400 ati->FileAttributes = fcb->atts;
4401
4403 ati->ReparseTag = 0;
4404 else
4406
4407 return STATUS_SUCCESS;
4408}
ULONG get_reparse_tag_fcb(fcb *fcb)
Definition: dirctrl.c:83
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
struct _FILE_ATTRIBUTE_TAG_INFORMATION FILE_ATTRIBUTE_TAG_INFORMATION
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381

Referenced by query_info().

◆ fill_in_file_basic_information()

static NTSTATUS fill_in_file_basic_information ( FILE_BASIC_INFORMATION fbi,
INODE_ITEM ii,
LONG length,
fcb fcb,
file_ref fileref 
)
static

Definition at line 4111 of file fileinfo.c.

4111 {
4113
4114 *length -= sizeof(FILE_BASIC_INFORMATION);
4115
4116 if (fcb == fcb->Vcb->dummy_fcb) {
4118
4120 fbi->CreationTime = fbi->LastAccessTime = fbi->LastWriteTime = fbi->ChangeTime = time;
4121 } else {
4126 }
4127
4128 if (fcb->ads) {
4129 if (!fileref || !fileref->parent) {
4130 ERR("no fileref for stream\n");
4131 return STATUS_INTERNAL_ERROR;
4132 } else
4133 fbi->FileAttributes = fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fileref->parent->fcb->atts;
4134 } else
4136
4137 return STATUS_SUCCESS;
4138}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
static __inline uint64_t unix_time_to_win(BTRFS_TIME *t)
Definition: recv.cpp:1070
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by query_info().

◆ fill_in_file_case_sensitive_information()

static NTSTATUS fill_in_file_case_sensitive_information ( FILE_CASE_SENSITIVE_INFORMATION fcsi,
fcb fcb,
LONG length 
)
static

Definition at line 5019 of file fileinfo.c.

5019 {
5021
5023
5024 return STATUS_SUCCESS;
5025}
#define FILE_CS_FLAG_CASE_SENSITIVE_DIR
Definition: btrfs_drv.h:165
struct _FILE_CASE_SENSITIVE_INFORMATION FILE_CASE_SENSITIVE_INFORMATION
bool case_sensitive
Definition: btrfs_drv.h:310

Referenced by query_info().

◆ fill_in_file_compression_information()

static NTSTATUS fill_in_file_compression_information ( FILE_COMPRESSION_INFORMATION fci,
LONG length,
fcb fcb 
)
static

Definition at line 5029 of file fileinfo.c.

5029 {
5031
5032 memset(fci, 0, sizeof(FILE_COMPRESSION_INFORMATION));
5033
5034 if (fcb->ads)
5036 else if (!S_ISDIR(fcb->inode_item.st_mode))
5038
5039 return STATUS_SUCCESS;
5040}
#define S_ISDIR(mode)
Definition: various.h:18
#define memset(x, y, z)
Definition: compat.h:39
uint64_t st_size
Definition: btrfs.h:289
LARGE_INTEGER CompressedFileSize
Definition: iotypes.h:5849
struct _FILE_COMPRESSION_INFORMATION FILE_COMPRESSION_INFORMATION

Referenced by query_info().

◆ fill_in_file_ea_information()

static NTSTATUS fill_in_file_ea_information ( FILE_EA_INFORMATION eai,
fcb fcb,
LONG length 
)
static

Definition at line 4222 of file fileinfo.c.

4222 {
4223 *length -= sizeof(FILE_EA_INFORMATION);
4224
4225 /* This value appears to be the size of the structure NTFS stores on disk, and not,
4226 * as might be expected, the size of FILE_FULL_EA_INFORMATION (which is what we store).
4227 * The formula is 4 bytes as a header, followed by 5 + NameLength + ValueLength for each
4228 * item. */
4229
4230 eai->EaSize = fcb->ealen;
4231
4232 return STATUS_SUCCESS;
4233}
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION

Referenced by query_info().

◆ fill_in_file_id_information()

static NTSTATUS fill_in_file_id_information ( FILE_ID_INFORMATION fii,
fcb fcb,
LONG length 
)
static

Definition at line 4875 of file fileinfo.c.

4875 {
4876 RtlCopyMemory(&fii->VolumeSerialNumber, &fcb->Vcb->superblock.uuid.uuid[8], sizeof(uint64_t));
4877 RtlCopyMemory(&fii->FileId.Identifier[0], &fcb->inode, sizeof(uint64_t));
4878 RtlCopyMemory(&fii->FileId.Identifier[sizeof(uint64_t)], &fcb->subvol->id, sizeof(uint64_t));
4879
4880 *length -= sizeof(FILE_ID_INFORMATION);
4881
4882 return STATUS_SUCCESS;
4883}
struct _FILE_ID_INFORMATION FILE_ID_INFORMATION
UCHAR Identifier[16]
Definition: btrfs_drv.h:162
FILE_ID_128 FileId
Definition: fileinfo.c:36
ULONGLONG VolumeSerialNumber
Definition: fileinfo.c:35

Referenced by query_info().

◆ fill_in_file_internal_information()

static NTSTATUS fill_in_file_internal_information ( FILE_INTERNAL_INFORMATION fii,
fcb fcb,
LONG length 
)
static

Definition at line 4214 of file fileinfo.c.

4214 {
4216
4218
4219 return STATUS_SUCCESS;
4220}
static __inline uint64_t make_file_id(root *r, uint64_t inode)
Definition: btrfs_drv.h:1012
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION

Referenced by query_info().

◆ fill_in_file_name_information()

static NTSTATUS fill_in_file_name_information ( FILE_NAME_INFORMATION fni,
fcb fcb,
file_ref fileref,
LONG length 
)
static

Definition at line 4332 of file fileinfo.c.

4332 {
4333 ULONG reqlen;
4336 static const WCHAR datasuf[] = {':','$','D','A','T','A',0};
4337 uint16_t datasuflen = sizeof(datasuf) - sizeof(WCHAR);
4338
4339 if (!fileref) {
4340 ERR("called without fileref\n");
4342 }
4343
4345
4346 TRACE("maximum length is %li\n", *length);
4347 fni->FileNameLength = 0;
4348
4349 fni->FileName[0] = 0;
4350
4351 fn.Buffer = fni->FileName;
4352 fn.Length = 0;
4353 fn.MaximumLength = (uint16_t)*length;
4354
4355 Status = fileref_get_filename(fileref, &fn, NULL, &reqlen);
4357 ERR("fileref_get_filename returned %08lx\n", Status);
4358 return Status;
4359 }
4360
4361 if (fcb->ads) {
4363 reqlen += datasuflen;
4364 else {
4365 if (fn.Length + datasuflen > fn.MaximumLength) {
4366 RtlCopyMemory(&fn.Buffer[fn.Length / sizeof(WCHAR)], datasuf, fn.MaximumLength - fn.Length);
4367 reqlen += datasuflen;
4369 } else {
4370 RtlCopyMemory(&fn.Buffer[fn.Length / sizeof(WCHAR)], datasuf, datasuflen);
4371 fn.Length += datasuflen;
4372 }
4373 }
4374 }
4375
4377 *length = -1;
4378 fni->FileNameLength = reqlen;
4379 TRACE("%.*S (truncated)\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer);
4380 } else {
4381 *length -= fn.Length;
4382 fni->FileNameLength = fn.Length;
4383 TRACE("%.*S\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer);
4384 }
4385
4386 return Status;
4387}
NTSTATUS fileref_get_filename(file_ref *fileref, PUNICODE_STRING fn, USHORT *name_offset, ULONG *preqlen)
Definition: fileinfo.c:4245
long LONG
Definition: pedump.c:60

Referenced by query_info().

◆ fill_in_file_network_open_information()

static NTSTATUS fill_in_file_network_open_information ( FILE_NETWORK_OPEN_INFORMATION fnoi,
fcb fcb,
file_ref fileref,
LONG length 
)
static

Definition at line 4140 of file fileinfo.c.

4140 {
4141 INODE_ITEM* ii;
4142
4143 if (*length < (LONG)sizeof(FILE_NETWORK_OPEN_INFORMATION)) {
4144 WARN("overflow\n");
4146 }
4147
4149
4151
4152 if (fcb->ads) {
4153 if (!fileref || !fileref->parent) {
4154 ERR("no fileref for stream\n");
4155 return STATUS_INTERNAL_ERROR;
4156 }
4157
4158 ii = &fileref->parent->fcb->inode_item;
4159 } else
4160 ii = &fcb->inode_item;
4161
4162 if (fcb == fcb->Vcb->dummy_fcb) {
4164
4166 fnoi->CreationTime = fnoi->LastAccessTime = fnoi->LastWriteTime = fnoi->ChangeTime = time;
4167 } else {
4172 }
4173
4174 if (fcb->ads) {
4176 fnoi->FileAttributes = fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fileref->parent->fcb->atts;
4177 } else {
4181 }
4182
4183 return STATUS_SUCCESS;
4184}
static __inline uint64_t fcb_alloc_size(fcb *fcb)
Definition: btrfs_drv.h:1824
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION

Referenced by query_info().

◆ fill_in_file_position_information()

static NTSTATUS fill_in_file_position_information ( FILE_POSITION_INFORMATION fpi,
PFILE_OBJECT  FileObject,
LONG length 
)
static

Definition at line 4235 of file fileinfo.c.

4235 {
4237
4239
4240 fpi->CurrentByteOffset = FileObject->CurrentByteOffset;
4241
4242 return STATUS_SUCCESS;
4243}
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:955

Referenced by query_info().

◆ fill_in_file_standard_information()

static NTSTATUS fill_in_file_standard_information ( FILE_STANDARD_INFORMATION fsi,
fcb fcb,
file_ref fileref,
LONG length 
)
static

Definition at line 4186 of file fileinfo.c.

4186 {
4188
4190
4191 if (fcb->ads) {
4192 if (!fileref || !fileref->parent) {
4193 ERR("no fileref for stream\n");
4194 return STATUS_INTERNAL_ERROR;
4195 }
4196
4198 fsi->NumberOfLinks = fileref->parent->fcb->inode_item.st_nlink;
4199 fsi->Directory = false;
4200 } else {
4205 }
4206
4207 TRACE("length = %I64u\n", fsi->EndOfFile.QuadPart);
4208
4209 fsi->DeletePending = fileref ? fileref->delete_on_close : false;
4210
4211 return STATUS_SUCCESS;
4212}
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
bool delete_on_close
Definition: btrfs_drv.h:345

Referenced by query_info().

◆ fill_in_file_standard_link_information()

static NTSTATUS fill_in_file_standard_link_information ( FILE_STANDARD_LINK_INFORMATION fsli,
fcb fcb,
file_ref fileref,
LONG length 
)
static

Definition at line 4520 of file fileinfo.c.

4520 {
4521 TRACE("FileStandardLinkInformation\n");
4522
4523 // FIXME - NumberOfAccessibleLinks should subtract open links which have been marked as delete_on_close
4524
4527 fsli->DeletePending = fileref ? fileref->delete_on_close : false;
4528 fsli->Directory = (!fcb->ads && fcb->type == BTRFS_TYPE_DIRECTORY) ? true : false;
4529
4531
4532 return STATUS_SUCCESS;
4533}
struct _FILE_STANDARD_LINK_INFORMATION FILE_STANDARD_LINK_INFORMATION

Referenced by query_info().

◆ fill_in_file_stat_information()

static NTSTATUS fill_in_file_stat_information ( FILE_STAT_INFORMATION fsi,
fcb fcb,
ccb ccb,
LONG length 
)
static

Definition at line 4885 of file fileinfo.c.

4885 {
4886 INODE_ITEM* ii;
4887
4889
4890 if (fcb->ads)
4891 ii = &ccb->fileref->parent->fcb->inode_item;
4892 else
4893 ii = &fcb->inode_item;
4894
4895 if (fcb == fcb->Vcb->dummy_fcb) {
4897
4899 fsi->CreationTime = fsi->LastAccessTime = fsi->LastWriteTime = fsi->ChangeTime = time;
4900 } else {
4905 }
4906
4907 if (fcb->ads) {
4909 fsi->FileAttributes = ccb->fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : ccb->fileref->parent->fcb->atts;
4910 } else {
4914 }
4915
4916 if (fcb->type == BTRFS_TYPE_SOCKET)
4918 else if (fcb->type == BTRFS_TYPE_FIFO)
4920 else if (fcb->type == BTRFS_TYPE_CHARDEV)
4922 else if (fcb->type == BTRFS_TYPE_BLOCKDEV)
4925 fsi->ReparseTag = 0;
4926 else
4928
4931
4932 if (fcb->ads)
4933 fsi->NumberOfLinks = ccb->fileref->parent->fcb->inode_item.st_nlink;
4934 else
4936
4937 fsi->EffectiveAccess = ccb->access;
4938
4939 *length -= sizeof(FILE_STAT_INFORMATION);
4940
4941 return STATUS_SUCCESS;
4942}
#define IO_REPARSE_TAG_AF_UNIX
Definition: btrfs_drv.h:120
#define IO_REPARSE_TAG_LX_CHR
Definition: btrfs_drv.h:122
#define IO_REPARSE_TAG_LX_BLK
Definition: btrfs_drv.h:123
#define IO_REPARSE_TAG_LX_FIFO
Definition: btrfs_drv.h:121
struct _FILE_STAT_INFORMATION FILE_STAT_INFORMATION
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
LARGE_INTEGER AllocationSize
Definition: fileinfo.c:45
LARGE_INTEGER LastAccessTime
Definition: fileinfo.c:42
ACCESS_MASK EffectiveAccess
Definition: fileinfo.c:50
LARGE_INTEGER ChangeTime
Definition: fileinfo.c:44
LARGE_INTEGER FileId
Definition: fileinfo.c:40
LARGE_INTEGER EndOfFile
Definition: fileinfo.c:46
LARGE_INTEGER LastWriteTime
Definition: fileinfo.c:43
LARGE_INTEGER CreationTime
Definition: fileinfo.c:41

Referenced by query_info().

◆ fill_in_file_stat_lx_information()

static NTSTATUS fill_in_file_stat_lx_information ( FILE_STAT_LX_INFORMATION fsli,
fcb fcb,
ccb ccb,
LONG length 
)
static

Definition at line 4944 of file fileinfo.c.

4944 {
4945 INODE_ITEM* ii;
4946
4948
4949 if (fcb->ads)
4950 ii = &ccb->fileref->parent->fcb->inode_item;
4951 else
4952 ii = &fcb->inode_item;
4953
4954 if (fcb == fcb->Vcb->dummy_fcb) {
4956
4958 fsli->CreationTime = fsli->LastAccessTime = fsli->LastWriteTime = fsli->ChangeTime = time;
4959 } else {
4964 }
4965
4966 if (fcb->ads) {
4968 fsli->FileAttributes = ccb->fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : ccb->fileref->parent->fcb->atts;
4969 } else {
4973 }
4974
4975 if (fcb->type == BTRFS_TYPE_SOCKET)
4977 else if (fcb->type == BTRFS_TYPE_FIFO)
4979 else if (fcb->type == BTRFS_TYPE_CHARDEV)
4981 else if (fcb->type == BTRFS_TYPE_BLOCKDEV)
4983 else if (!(fsli->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
4984 fsli->ReparseTag = 0;
4985 else
4987
4990
4991 if (fcb->ads)
4992 fsli->NumberOfLinks = ccb->fileref->parent->fcb->inode_item.st_nlink;
4993 else
4995
4996 fsli->EffectiveAccess = ccb->access;
4998
4999 if (fcb->case_sensitive)
5001
5002 fsli->LxUid = ii->st_uid;
5003 fsli->LxGid = ii->st_gid;
5004 fsli->LxMode = ii->st_mode;
5005
5006 if (ii->st_mode & __S_IFBLK || ii->st_mode & __S_IFCHR) {
5007 fsli->LxDeviceIdMajor = (ii->st_rdev & 0xFFFFFFFFFFF00000) >> 20;
5008 fsli->LxDeviceIdMinor = (ii->st_rdev & 0xFFFFF);
5009 } else {
5010 fsli->LxDeviceIdMajor = 0;
5011 fsli->LxDeviceIdMinor = 0;
5012 }
5013
5014 *length -= sizeof(FILE_STAT_LX_INFORMATION);
5015
5016 return STATUS_SUCCESS;
5017}
#define __S_IFBLK
Definition: btrfs_drv.h:1756
#define __S_IFCHR
Definition: btrfs_drv.h:1755
#define LX_FILE_METADATA_HAS_DEVICE_ID
Definition: fileinfo.c:76
#define LX_FILE_METADATA_HAS_UID
Definition: fileinfo.c:73
#define LX_FILE_CASE_SENSITIVE_DIR
Definition: fileinfo.c:77
struct _FILE_STAT_LX_INFORMATION FILE_STAT_LX_INFORMATION
#define LX_FILE_METADATA_HAS_GID
Definition: fileinfo.c:74
#define LX_FILE_METADATA_HAS_MODE
Definition: fileinfo.c:75
uint64_t st_rdev
Definition: btrfs.h:296
LARGE_INTEGER ChangeTime
Definition: fileinfo.c:58
LARGE_INTEGER CreationTime
Definition: fileinfo.c:55
LARGE_INTEGER FileId
Definition: fileinfo.c:54
LARGE_INTEGER EndOfFile
Definition: fileinfo.c:60
LARGE_INTEGER LastWriteTime
Definition: fileinfo.c:57
LARGE_INTEGER AllocationSize
Definition: fileinfo.c:59
ACCESS_MASK EffectiveAccess
Definition: fileinfo.c:64
LARGE_INTEGER LastAccessTime
Definition: fileinfo.c:56

Referenced by query_info().

◆ fill_in_file_stream_information()

static NTSTATUS fill_in_file_stream_information ( FILE_STREAM_INFORMATION fsi,
file_ref fileref,
LONG length 
)
static

Definition at line 4410 of file fileinfo.c.

4410 {
4411 LONG reqsize;
4412 LIST_ENTRY* le;
4413 FILE_STREAM_INFORMATION *entry, *lastentry;
4415
4416 static const WCHAR datasuf[] = L":$DATA";
4417 UNICODE_STRING suf;
4418
4419 if (!fileref) {
4420 ERR("fileref was NULL\n");
4422 }
4423
4424 suf.Buffer = (WCHAR*)datasuf;
4425 suf.Length = suf.MaximumLength = sizeof(datasuf) - sizeof(WCHAR);
4426
4427 if (fileref->fcb->type != BTRFS_TYPE_DIRECTORY)
4428 reqsize = sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR) + suf.Length + sizeof(WCHAR);
4429 else
4430 reqsize = 0;
4431
4432 ExAcquireResourceSharedLite(&fileref->fcb->nonpaged->dir_children_lock, true);
4433
4434 le = fileref->fcb->dir_children_index.Flink;
4435 while (le != &fileref->fcb->dir_children_index) {
4436 dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_index);
4437
4438 if (dc->index == 0) {
4439 reqsize = (ULONG)sector_align(reqsize, sizeof(LONGLONG));
4440 reqsize += sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR) + suf.Length + sizeof(WCHAR) + dc->name.Length;
4441 } else
4442 break;
4443
4444 le = le->Flink;
4445 }
4446
4447 TRACE("length = %li, reqsize = %lu\n", *length, reqsize);
4448
4449 if (reqsize > *length) {
4451 goto end;
4452 }
4453
4454 entry = fsi;
4455 lastentry = NULL;
4456
4457 if (fileref->fcb->type != BTRFS_TYPE_DIRECTORY) {
4458 ULONG off;
4459
4460 entry->NextEntryOffset = 0;
4461 entry->StreamNameLength = suf.Length + sizeof(WCHAR);
4462 entry->StreamSize.QuadPart = fileref->fcb->inode_item.st_size;
4463 entry->StreamAllocationSize.QuadPart = fcb_alloc_size(fileref->fcb);
4464
4465 entry->StreamName[0] = ':';
4466 RtlCopyMemory(&entry->StreamName[1], suf.Buffer, suf.Length);
4467
4468 off = (ULONG)sector_align(sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR) + suf.Length + sizeof(WCHAR), sizeof(LONGLONG));
4469
4470 lastentry = entry;
4472 }
4473
4474 le = fileref->fcb->dir_children_index.Flink;
4475 while (le != &fileref->fcb->dir_children_index) {
4476 dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_index);
4477
4478 if (dc->index == 0) {
4479 ULONG off;
4480
4481 entry->NextEntryOffset = 0;
4482 entry->StreamNameLength = dc->name.Length + suf.Length + sizeof(WCHAR);
4483
4484 if (dc->fileref)
4485 entry->StreamSize.QuadPart = dc->fileref->fcb->adsdata.Length;
4486 else
4487 entry->StreamSize.QuadPart = dc->size;
4488
4489 entry->StreamAllocationSize.QuadPart = entry->StreamSize.QuadPart;
4490
4491 entry->StreamName[0] = ':';
4492
4493 RtlCopyMemory(&entry->StreamName[1], dc->name.Buffer, dc->name.Length);
4494 RtlCopyMemory(&entry->StreamName[1 + (dc->name.Length / sizeof(WCHAR))], suf.Buffer, suf.Length);
4495
4496 if (lastentry)
4497 lastentry->NextEntryOffset = (uint32_t)((uint8_t*)entry - (uint8_t*)lastentry);
4498
4499 off = (ULONG)sector_align(sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR) + suf.Length + sizeof(WCHAR) + dc->name.Length, sizeof(LONGLONG));
4500
4501 lastentry = entry;
4503 } else
4504 break;
4505
4506 le = le->Flink;
4507 }
4508
4509 *length -= reqsize;
4510
4512
4513end:
4514 ExReleaseResourceLite(&fileref->fcb->nonpaged->dir_children_lock);
4515
4516 return Status;
4517}
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
struct _FILE_STREAM_INFORMATION FILE_STREAM_INFORMATION
uint32_t entry
Definition: isohybrid.c:63
#define L(x)
Definition: ntvdm.h:50
USHORT MaximumLength
Definition: env_spec_w32.h:370
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by query_info().

◆ fill_in_hard_link_full_id_information()

static NTSTATUS fill_in_hard_link_full_id_information ( FILE_LINKS_FULL_ID_INFORMATION flfii,
file_ref fileref,
PIRP  Irp,
LONG length 
)
static

Definition at line 4704 of file fileinfo.c.

4704 {
4706 LIST_ENTRY* le;
4707 LONG bytes_needed;
4709 bool overflow = false;
4710 fcb* fcb = fileref->fcb;
4711 ULONG len;
4712
4713 if (fcb->ads)
4715
4718
4719 RtlZeroMemory(flfii, *length);
4720
4722 len = bytes_needed;
4723 flefii = NULL;
4724
4725 ExAcquireResourceSharedLite(fcb->Header.Resource, true);
4726
4727 if (fcb->inode == SUBVOL_ROOT_INODE) {
4728 ULONG namelen;
4729
4730 if (fcb == fcb->Vcb->root_fileref->fcb)
4731 namelen = sizeof(WCHAR);
4732 else
4733 namelen = fileref->dc->name.Length;
4734
4736
4737 if (bytes_needed > *length)
4738 overflow = true;
4739
4740 if (!overflow) {
4741 flefii = &flfii->Entry;
4742
4743 flefii->NextEntryOffset = 0;
4744
4745 if (fcb == fcb->Vcb->root_fileref->fcb) {
4746 RtlZeroMemory(&flefii->ParentFileId.Identifier[0], sizeof(FILE_ID_128));
4747 flefii->FileNameLength = 1;
4748 flefii->FileName[0] = '.';
4749 } else {
4750 RtlCopyMemory(&flefii->ParentFileId.Identifier[0], &fileref->parent->fcb->inode, sizeof(uint64_t));
4751 RtlCopyMemory(&flefii->ParentFileId.Identifier[sizeof(uint64_t)], &fileref->parent->fcb->subvol->id, sizeof(uint64_t));
4752
4753 flefii->FileNameLength = fileref->dc->name.Length / sizeof(WCHAR);
4754 RtlCopyMemory(flefii->FileName, fileref->dc->name.Buffer, fileref->dc->name.Length);
4755 }
4756
4757 flfii->EntriesReturned++;
4758
4759 len = bytes_needed;
4760 }
4761 } else {
4762 ExAcquireResourceExclusiveLite(&fcb->Vcb->fileref_lock, true);
4763
4764 if (IsListEmpty(&fcb->hardlinks)) {
4765 bytes_needed += offsetof(FILE_LINK_ENTRY_FULL_ID_INFORMATION, FileName[0]) + fileref->dc->name.Length;
4766
4767 if (bytes_needed > *length)
4768 overflow = true;
4769
4770 if (!overflow) {
4771 flefii = &flfii->Entry;
4772
4773 flefii->NextEntryOffset = 0;
4774
4775 RtlCopyMemory(&flefii->ParentFileId.Identifier[0], &fileref->parent->fcb->inode, sizeof(uint64_t));
4776 RtlCopyMemory(&flefii->ParentFileId.Identifier[sizeof(uint64_t)], &fileref->parent->fcb->subvol->id, sizeof(uint64_t));
4777
4778 flefii->FileNameLength = fileref->dc->name.Length / sizeof(WCHAR);
4779 RtlCopyMemory(flefii->FileName, fileref->dc->name.Buffer, fileref->dc->name.Length);
4780
4781 flfii->EntriesReturned++;
4782
4783 len = bytes_needed;
4784 }
4785 } else {
4786 le = fcb->hardlinks.Flink;
4787 while (le != &fcb->hardlinks) {
4789 file_ref* parfr;
4790
4791 TRACE("parent %I64x, index %I64x, name %.*S\n", hl->parent, hl->index, (int)(hl->name.Length / sizeof(WCHAR)), hl->name.Buffer);
4792
4793 Status = open_fileref_by_inode(fcb->Vcb, fcb->subvol, hl->parent, &parfr, Irp);
4794
4795 if (!NT_SUCCESS(Status)) {
4796 ERR("open_fileref_by_inode returned %08lx\n", Status);
4797 } else if (!parfr->deleted) {
4798 LIST_ENTRY* le2;
4799 bool found = false, deleted = false;
4801
4802 le2 = parfr->children.Flink;
4803 while (le2 != &parfr->children) {
4805
4806 if (fr2->dc->index == hl->index) {
4807 found = true;
4808 deleted = fr2->deleted;
4809
4810 if (!deleted)
4811 fn = &fr2->dc->name;
4812
4813 break;
4814 }
4815
4816 le2 = le2->Flink;
4817 }
4818
4819 if (!found)
4820 fn = &hl->name;
4821
4822 if (!deleted) {
4823 TRACE("fn = %.*S (found = %u)\n", (int)(fn->Length / sizeof(WCHAR)), fn->Buffer, found);
4824
4825 if (flefii)
4826 bytes_needed = (LONG)sector_align(bytes_needed, 8);
4827
4828 bytes_needed += offsetof(FILE_LINK_ENTRY_FULL_ID_INFORMATION, FileName[0]) + fn->Length;
4829
4830 if (bytes_needed > *length)
4831 overflow = true;
4832
4833 if (!overflow) {
4834 if (flefii) {
4836 flefii = (FILE_LINK_ENTRY_FULL_ID_INFORMATION*)((uint8_t*)flefii + flefii->NextEntryOffset);
4837 } else
4838 flefii = &flfii->Entry;
4839
4840 flefii->NextEntryOffset = 0;
4841
4842 RtlCopyMemory(&flefii->ParentFileId.Identifier[0], &parfr->fcb->inode, sizeof(uint64_t));
4843 RtlCopyMemory(&flefii->ParentFileId.Identifier[sizeof(uint64_t)], &parfr->fcb->subvol->id, sizeof(uint64_t));
4844
4845 flefii->FileNameLength = fn->Length / sizeof(WCHAR);
4846 RtlCopyMemory(flefii->FileName, fn->Buffer, fn->Length);
4847
4848 flfii->EntriesReturned++;
4849
4850 len = bytes_needed;
4851 }
4852 }
4853
4854 free_fileref(parfr);
4855 }
4856
4857 le = le->Flink;
4858 }
4859 }
4860
4861 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
4862 }
4863
4864 flfii->BytesNeeded = bytes_needed;
4865
4866 *length -= len;
4867
4869
4870 ExReleaseResourceLite(fcb->Header.Resource);
4871
4872 return Status;
4873}
NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, root *subvol, uint64_t inode, file_ref **pfr, PIRP Irp)
Definition: create.c:4136
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1856
GLint namelen
Definition: glext.h:7232
base of all file and directory entries
Definition: entries.h:83
Definition: fileinfo.c:107
WCHAR FileName[1]
Definition: fileinfo.c:111
FILE_ID_128 ParentFileId
Definition: fileinfo.c:109
ULONG NextEntryOffset
Definition: fileinfo.c:108
ULONG FileNameLength
Definition: fileinfo.c:110
bool deleted
Definition: btrfs_drv.h:347
LIST_ENTRY children
Definition: btrfs_drv.h:349
uint64_t index
Definition: btrfs_drv.h:252

Referenced by query_info().

◆ fill_in_hard_link_information()

static NTSTATUS fill_in_hard_link_information ( FILE_LINKS_INFORMATION fli,
file_ref fileref,
PIRP  Irp,
LONG length 
)
static

Definition at line 4535 of file fileinfo.c.

4535 {
4537 LIST_ENTRY* le;
4538 LONG bytes_needed;
4540 bool overflow = false;
4541 fcb* fcb = fileref->fcb;
4542 ULONG len;
4543
4544 if (fcb->ads)
4546
4549
4550 RtlZeroMemory(fli, *length);
4551
4552 bytes_needed = offsetof(FILE_LINKS_INFORMATION, Entry);
4553 len = bytes_needed;
4554 feli = NULL;
4555
4556 ExAcquireResourceSharedLite(fcb->Header.Resource, true);
4557
4558 if (fcb->inode == SUBVOL_ROOT_INODE) {
4559 ULONG namelen;
4560
4561 if (fcb == fcb->Vcb->root_fileref->fcb)
4562 namelen = sizeof(WCHAR);
4563 else
4564 namelen = fileref->dc->name.Length;
4565
4566 bytes_needed += sizeof(FILE_LINK_ENTRY_INFORMATION) - sizeof(WCHAR) + namelen;
4567
4568 if (bytes_needed > *length)
4569 overflow = true;
4570
4571 if (!overflow) {
4572 feli = &fli->Entry;
4573
4574 feli->NextEntryOffset = 0;
4575 feli->ParentFileId = 0; // we use an inode of 0 to mean the parent of a subvolume
4576
4577 if (fcb == fcb->Vcb->root_fileref->fcb) {
4578 feli->FileNameLength = 1;
4579 feli->FileName[0] = '.';
4580 } else {
4581 feli->FileNameLength = fileref->dc->name.Length / sizeof(WCHAR);
4582 RtlCopyMemory(feli->FileName, fileref->dc->name.Buffer, fileref->dc->name.Length);
4583 }
4584
4585 fli->EntriesReturned++;
4586
4587 len = bytes_needed;
4588 }
4589 } else {
4590 ExAcquireResourceExclusiveLite(&fcb->Vcb->fileref_lock, true);
4591
4592 if (IsListEmpty(&fcb->hardlinks)) {
4593 if (!fileref->dc) {
4594 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
4596 goto end;
4597 }
4598
4599 bytes_needed += sizeof(FILE_LINK_ENTRY_INFORMATION) + fileref->dc->name.Length - sizeof(WCHAR);
4600
4601 if (bytes_needed > *length)
4602 overflow = true;
4603
4604 if (!overflow) {
4605 feli = &fli->Entry;
4606
4607 feli->NextEntryOffset = 0;
4608 feli->ParentFileId = fileref->parent->fcb->inode;
4609 feli->FileNameLength = fileref->dc->name.Length / sizeof(WCHAR);
4610 RtlCopyMemory(feli->FileName, fileref->dc->name.Buffer, fileref->dc->name.Length);
4611
4612 fli->EntriesReturned++;
4613
4614 len = bytes_needed;
4615 }
4616 } else {
4617 le = fcb->hardlinks.Flink;
4618 while (le != &fcb->hardlinks) {
4620 file_ref* parfr;
4621
4622 TRACE("parent %I64x, index %I64x, name %.*S\n", hl->parent, hl->index, (int)(hl->name.Length / sizeof(WCHAR)), hl->name.Buffer);
4623
4624 Status = open_fileref_by_inode(fcb->Vcb, fcb->subvol, hl->parent, &parfr, Irp);
4625
4626 if (!NT_SUCCESS(Status)) {
4627 ERR("open_fileref_by_inode returned %08lx\n", Status);
4628 } else if (!parfr->deleted) {
4629 LIST_ENTRY* le2;
4630 bool found = false, deleted = false;
4632
4633 le2 = parfr->children.Flink;
4634 while (le2 != &parfr->children) {
4636
4637 if (fr2->dc && fr2->dc->index == hl->index) {
4638 found = true;
4639 deleted = fr2->deleted;
4640
4641 if (!deleted)
4642 fn = &fr2->dc->name;
4643
4644 break;
4645 }
4646
4647 le2 = le2->Flink;
4648 }
4649
4650 if (!found)
4651 fn = &hl->name;
4652
4653 if (!deleted) {
4654 TRACE("fn = %.*S (found = %u)\n", (int)(fn->Length / sizeof(WCHAR)), fn->Buffer, found);
4655
4656 if (feli)
4657 bytes_needed = (LONG)sector_align(bytes_needed, 8);
4658
4659 bytes_needed += sizeof(FILE_LINK_ENTRY_INFORMATION) + fn->Length - sizeof(WCHAR);
4660
4661 if (bytes_needed > *length)
4662 overflow = true;
4663
4664 if (!overflow) {
4665 if (feli) {
4666 feli->NextEntryOffset = (ULONG)sector_align(sizeof(FILE_LINK_ENTRY_INFORMATION) + ((feli->FileNameLength - 1) * sizeof(WCHAR)), 8);
4667 feli = (FILE_LINK_ENTRY_INFORMATION*)((uint8_t*)feli + feli->NextEntryOffset);
4668 } else
4669 feli = &fli->Entry;
4670
4671 feli->NextEntryOffset = 0;
4672 feli->ParentFileId = parfr->fcb->inode;
4673 feli->FileNameLength = fn->Length / sizeof(WCHAR);
4674 RtlCopyMemory(feli->FileName, fn->Buffer, fn->Length);
4675
4676 fli->EntriesReturned++;
4677
4678 len = bytes_needed;
4679 }
4680 }
4681
4682 free_fileref(parfr);
4683 }
4684
4685 le = le->Flink;
4686 }
4687 }
4688
4689 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
4690 }
4691
4692 fli->BytesNeeded = bytes_needed;
4693
4694 *length -= len;
4695
4697
4698end:
4699 ExReleaseResourceLite(fcb->Header.Resource);
4700
4701 return Status;
4702}
Definition: iotypes.h:5937
WCHAR FileName[1]
Definition: iotypes.h:5941
ULONG NextEntryOffset
Definition: iotypes.h:5938
ULONG FileNameLength
Definition: iotypes.h:5940
LONGLONG ParentFileId
Definition: iotypes.h:5939
struct _FILE_LINK_ENTRY_INFORMATION FILE_LINK_ENTRY_INFORMATION

Referenced by query_info().

◆ has_open_children()

bool has_open_children ( file_ref fileref)

Definition at line 442 of file fileinfo.c.

442 {
443 LIST_ENTRY* le = fileref->children.Flink;
444
445 if (IsListEmpty(&fileref->children))
446 return false;
447
448 while (le != &fileref->children) {
450
451 if (c->open_count > 0)
452 return true;
453
454 if (has_open_children(c))
455 return true;
456
457 le = le->Flink;
458 }
459
460 return false;
461}
bool has_open_children(file_ref *fileref)
Definition: fileinfo.c:442

Referenced by has_open_children(), lock_volume(), pnp_query_remove_device(), set_link_information(), and set_rename_information().

◆ insert_dir_child_into_hash_lists()

void insert_dir_child_into_hash_lists ( fcb fcb,
dir_child dc 
)

Definition at line 1470 of file fileinfo.c.

1470 {
1471 bool inserted;
1472 LIST_ENTRY* le;
1473 uint8_t c, d;
1474
1475 c = dc->hash >> 24;
1476
1477 inserted = false;
1478
1479 d = c;
1480 do {
1481 le = fcb->hash_ptrs[d];
1482
1483 if (d == 0)
1484 break;
1485
1486 d--;
1487 } while (!le);
1488
1489 if (!le)
1491
1492 while (le != &fcb->dir_children_hash) {
1493 dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash);
1494
1495 if (dc2->hash > dc->hash) {
1496 InsertHeadList(le->Blink, &dc->list_entry_hash);
1497 inserted = true;
1498 break;
1499 }
1500
1501 le = le->Flink;
1502 }
1503
1504 if (!inserted)
1505 InsertTailList(&fcb->dir_children_hash, &dc->list_entry_hash);
1506
1507 if (!fcb->hash_ptrs[c])
1508 fcb->hash_ptrs[c] = &dc->list_entry_hash;
1509 else {
1510 dir_child* dc2 = CONTAINING_RECORD(fcb->hash_ptrs[c], dir_child, list_entry_hash);
1511
1512 if (dc2->hash > dc->hash)
1513 fcb->hash_ptrs[c] = &dc->list_entry_hash;
1514 }
1515
1516 c = dc->hash_uc >> 24;
1517
1518 inserted = false;
1519
1520 d = c;
1521 do {
1522 le = fcb->hash_ptrs_uc[d];
1523
1524 if (d == 0)
1525 break;
1526
1527 d--;
1528 } while (!le);
1529
1530 if (!le)
1532
1533 while (le != &fcb->dir_children_hash_uc) {
1534 dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
1535
1536 if (dc2->hash_uc > dc->hash_uc) {
1537 InsertHeadList(le->Blink, &dc->list_entry_hash_uc);
1538 inserted = true;
1539 break;
1540 }
1541
1542 le = le->Flink;
1543 }
1544
1545 if (!inserted)
1546 InsertTailList(&fcb->dir_children_hash_uc, &dc->list_entry_hash_uc);
1547
1548 if (!fcb->hash_ptrs_uc[c])
1549 fcb->hash_ptrs_uc[c] = &dc->list_entry_hash_uc;
1550 else {
1551 dir_child* dc2 = CONTAINING_RECORD(fcb->hash_ptrs_uc[c], dir_child, list_entry_hash_uc);
1552
1553 if (dc2->hash_uc > dc->hash_uc)
1554 fcb->hash_ptrs_uc[c] = &dc->list_entry_hash_uc;
1555 }
1556}
#define c
Definition: ke_i.h:80
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:315
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:316
uint32_t hash
Definition: btrfs_drv.h:255
uint32_t hash_uc
Definition: btrfs_drv.h:257

Referenced by add_dir_child(), load_dir_children(), move_across_subvols(), and set_rename_information().

◆ move_across_subvols()

static NTSTATUS move_across_subvols ( file_ref fileref,
ccb ccb,
file_ref destdir,
PANSI_STRING  utf8,
PUNICODE_STRING  fnus,
PIRP  Irp,
LIST_ENTRY rollback 
)
static

Definition at line 950 of file fileinfo.c.

950 {
953 move_entry* me;
956 file_ref* origparent;
957
958 // FIXME - make sure me->dummyfileref and me->dummyfcb get freed properly
959
961
964
965 acquire_fcb_lock_exclusive(fileref->fcb->Vcb);
966
968
969 if (!me) {
970 ERR("out of memory\n");
972 goto end;
973 }
974
975 origparent = fileref->parent;
976
977 me->fileref = fileref;
979 me->dummyfcb = NULL;
980 me->dummyfileref = NULL;
981 me->parent = NULL;
982
984
985 le = move_list.Flink;
986 while (le != &move_list) {
988
989 ExAcquireResourceSharedLite(me->fileref->fcb->Header.Resource, true);
990
991 if (!me->fileref->fcb->ads && me->fileref->fcb->subvol == origparent->fcb->subvol) {
992 Status = add_children_to_move_list(fileref->fcb->Vcb, me, Irp);
993
994 if (!NT_SUCCESS(Status)) {
995 ERR("add_children_to_move_list returned %08lx\n", Status);
996 ExReleaseResourceLite(me->fileref->fcb->Header.Resource);
997 goto end;
998 }
999 }
1000
1001 ExReleaseResourceLite(me->fileref->fcb->Header.Resource);
1002
1003 le = le->Flink;
1004 }
1005
1007
1008 // loop through list and create new inodes
1009
1010 le = move_list.Flink;
1011 while (le != &move_list) {
1013
1014 if (me->fileref->fcb->inode != SUBVOL_ROOT_INODE && me->fileref->fcb != fileref->fcb->Vcb->dummy_fcb) {
1015 if (!me->dummyfcb) {
1016 ULONG defda;
1017
1018 ExAcquireResourceExclusiveLite(me->fileref->fcb->Header.Resource, true);
1019
1020 Status = duplicate_fcb(me->fileref->fcb, &me->dummyfcb);
1021 if (!NT_SUCCESS(Status)) {
1022 ERR("duplicate_fcb returned %08lx\n", Status);
1023 ExReleaseResourceLite(me->fileref->fcb->Header.Resource);
1024 goto end;
1025 }
1026
1027 me->dummyfcb->subvol = me->fileref->fcb->subvol;
1028 me->dummyfcb->inode = me->fileref->fcb->inode;
1029 me->dummyfcb->hash = me->fileref->fcb->hash;
1030
1031 if (!me->dummyfcb->ads) {
1032 me->dummyfcb->sd_dirty = me->fileref->fcb->sd_dirty;
1038 }
1039
1040 me->dummyfcb->created = me->fileref->fcb->created;
1041 me->dummyfcb->deleted = me->fileref->fcb->deleted;
1043
1044 if (!me->fileref->fcb->ads) {
1045 LIST_ENTRY* le2;
1046
1047 me->fileref->fcb->subvol = destdir->fcb->subvol;
1048 me->fileref->fcb->inode = InterlockedIncrement64(&destdir->fcb->subvol->lastinode);
1049 me->fileref->fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&me->fileref->fcb->inode, sizeof(uint64_t));
1050 me->fileref->fcb->inode_item.st_nlink = 1;
1051
1052 defda = get_file_attributes(me->fileref->fcb->Vcb, me->fileref->fcb->subvol, me->fileref->fcb->inode,
1053 me->fileref->fcb->type, me->fileref->dc && me->fileref->dc->name.Length >= sizeof(WCHAR) && me->fileref->dc->name.Buffer[0] == '.',
1054 true, Irp);
1055
1056 me->fileref->fcb->sd_dirty = !!me->fileref->fcb->sd;
1057 me->fileref->fcb->atts_changed = defda != me->fileref->fcb->atts;
1062 me->fileref->fcb->inode_item_changed = true;
1063
1064 le2 = me->fileref->fcb->xattrs.Flink;
1065 while (le2 != &me->fileref->fcb->xattrs) {
1067
1068 xa->dirty = true;
1069
1070 le2 = le2->Flink;
1071 }
1072
1073 if (le == move_list.Flink) { // first entry
1074 me->fileref->fcb->inode_item.transid = me->fileref->fcb->Vcb->superblock.generation;
1076
1079 }
1080
1081 le2 = me->fileref->fcb->extents.Flink;
1082 while (le2 != &me->fileref->fcb->extents) {
1084
1085 if (!ext->ignore && (ext->extent_data.type == EXTENT_TYPE_REGULAR || ext->extent_data.type == EXTENT_TYPE_PREALLOC)) {
1086 EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ext->extent_data.data;
1087
1088 if (ed2->size != 0) {
1090
1091 if (!c) {
1092 ERR("get_chunk_from_address(%I64x) failed\n", ed2->address);
1093 } else {
1094 Status = update_changed_extent_ref(me->fileref->fcb->Vcb, c, ed2->address, ed2->size, me->fileref->fcb->subvol->id, me->fileref->fcb->inode,
1095 ext->offset - ed2->offset, 1, me->fileref->fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp);
1096
1097 if (!NT_SUCCESS(Status)) {
1098 ERR("update_changed_extent_ref returned %08lx\n", Status);
1099 ExReleaseResourceLite(me->fileref->fcb->Header.Resource);
1100 goto end;
1101 }
1102 }
1103
1104 }
1105 }
1106
1107 le2 = le2->Flink;
1108 }
1109
1113 } else {
1114 me->fileref->fcb->subvol = me->parent->fileref->fcb->subvol;
1115 me->fileref->fcb->inode = me->parent->fileref->fcb->inode;
1116 me->fileref->fcb->hash = me->parent->fileref->fcb->hash;
1117
1118 // put stream after parent in FCB list
1119 InsertHeadList(&me->parent->fileref->fcb->list_entry, &me->fileref->fcb->list_entry);
1120 }
1121
1122 me->fileref->fcb->created = true;
1123
1124 InsertTailList(&me->fileref->fcb->Vcb->all_fcbs, &me->dummyfcb->list_entry_all);
1125
1126 while (!IsListEmpty(&me->fileref->fcb->hardlinks)) {
1128
1129 if (hl->name.Buffer)
1130 ExFreePool(hl->name.Buffer);
1131
1132 if (hl->utf8.Buffer)
1133 ExFreePool(hl->utf8.Buffer);
1134
1135 ExFreePool(hl);
1136 }
1137
1138 me->fileref->fcb->inode_item_changed = true;
1140
1141 if ((!me->dummyfcb->ads && me->dummyfcb->inode_item.st_nlink > 1) || (me->dummyfcb->ads && me->parent->dummyfcb->inode_item.st_nlink > 1)) {
1142 LIST_ENTRY* le2 = le->Flink;
1143
1144 while (le2 != &move_list) {
1146
1147 if (me2->fileref->fcb == me->fileref->fcb && !me2->fileref->fcb->ads) {
1148 me2->dummyfcb = me->dummyfcb;
1150 }
1151
1152 le2 = le2->Flink;
1153 }
1154 }
1155
1156 ExReleaseResourceLite(me->fileref->fcb->Header.Resource);
1157 } else {
1158 ExAcquireResourceExclusiveLite(me->fileref->fcb->Header.Resource, true);
1160 me->fileref->fcb->inode_item_changed = true;
1161 ExReleaseResourceLite(me->fileref->fcb->Header.Resource);
1162 }
1163 }
1164
1165 le = le->Flink;
1166 }
1167
1168 fileref->fcb->subvol->root_item.ctransid = fileref->fcb->Vcb->superblock.generation;
1169 fileref->fcb->subvol->root_item.ctime = now;
1170
1171 // loop through list and create new filerefs
1172
1173 le = move_list.Flink;
1174 while (le != &move_list) {
1175 hardlink* hl;
1176 bool name_changed = false;
1177
1179
1180 me->dummyfileref = create_fileref(fileref->fcb->Vcb);
1181 if (!me->dummyfileref) {
1182 ERR("out of memory\n");
1184 goto end;
1185 }
1186
1187 if (me->fileref->fcb == me->fileref->fcb->Vcb->dummy_fcb) {
1188 root* r = me->parent ? me->parent->fileref->fcb->subvol : destdir->fcb->subvol;
1189
1190 Status = create_directory_fcb(me->fileref->fcb->Vcb, r, me->fileref->parent->fcb, &me->fileref->fcb);
1191 if (!NT_SUCCESS(Status)) {
1192 ERR("create_directory_fcb returned %08lx\n", Status);
1193 goto