ReactOS  0.4.15-dev-4934-gfd1e799
create.c File Reference
#include <sys/stat.h>
#include "btrfs_drv.h"
#include "crc32c.h"
#include <ntddstor.h>
Include dependency graph for create.c:

Go to the source code of this file.

Classes

struct  _FILE_TIMESTAMPS
 
struct  _ATOMIC_CREATE_ECP_CONTEXT
 
struct  oplock_context
 

Macros

#define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED   0x0002
 
#define ATOMIC_CREATE_ECP_IN_FLAG_OP_FLAGS_SPECIFIED   0x0080
 
#define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT   0x0100
 
#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET   0x0002
 
#define ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED   0x0080
 
#define ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED   1
 
#define ATOMIC_CREATE_ECP_OUT_OP_FLAG_CASE_SENSITIVE_FLAGS_SET   1
 
#define SL_IGNORE_READONLY_ATTRIBUTE   0x40
 
#define called_from_lxss()   false
 

Typedefs

typedef struct _FILE_TIMESTAMPS FILE_TIMESTAMPS
 
typedef struct _FILE_TIMESTAMPSPFILE_TIMESTAMPS
 
typedef struct _ATOMIC_CREATE_ECP_CONTEXT ATOMIC_CREATE_ECP_CONTEXT
 
typedef struct _ATOMIC_CREATE_ECP_CONTEXTPATOMIC_CREATE_ECP_CONTEXT
 

Functions

fcbcreate_fcb (device_extension *Vcb, POOL_TYPE pool_type)
 
file_refcreate_fileref (device_extension *Vcb)
 
NTSTATUS find_file_in_dir (PUNICODE_STRING filename, fcb *fcb, root **subvol, uint64_t *inode, dir_child **pdc, bool case_sensitive)
 
static NTSTATUS split_path (device_extension *Vcb, PUNICODE_STRING path, LIST_ENTRY *parts, bool *stream)
 
NTSTATUS load_csum (_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, void *csum, uint64_t start, uint64_t length, PIRP Irp)
 
NTSTATUS load_dir_children (_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, fcb *fcb, bool ignore_size, PIRP Irp)
 
NTSTATUS open_fcb (_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, root *subvol, uint64_t inode, uint8_t type, PANSI_STRING utf8, bool always_add_hl, fcb *parent, fcb **pfcb, POOL_TYPE pooltype, PIRP Irp)
 
static NTSTATUS open_fcb_stream (_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, dir_child *dc, fcb *parent, fcb **pfcb, PIRP Irp)
 
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)
 
NTSTATUS open_fileref (_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _Out_ file_ref **pfr, _In_ PUNICODE_STRING fnus, _In_opt_ file_ref *related, _In_ bool parent, _Out_opt_ USHORT *parsed, _Out_opt_ ULONG *fn_offset, _In_ POOL_TYPE pooltype, _In_ bool case_sensitive, _In_opt_ PIRP Irp)
 
NTSTATUS add_dir_child (fcb *fcb, uint64_t inode, bool subvol, PANSI_STRING utf8, PUNICODE_STRING name, uint8_t type, dir_child **pdc)
 
uint32_t inherit_mode (fcb *parfcb, bool is_dir)
 
static NTSTATUS file_create_parse_ea (fcb *fcb, FILE_FULL_EA_INFORMATION *ea)
 
static NTSTATUS file_create2 (_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _In_ PUNICODE_STRING fpus, _In_ file_ref *parfileref, _In_ ULONG options, _In_reads_bytes_opt_(ealen) FILE_FULL_EA_INFORMATION *ea, _In_ ULONG ealen, _Out_ file_ref **pfr, bool case_sensitive, _In_ LIST_ENTRY *rollback)
 
static NTSTATUS create_stream (_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, file_ref **pfileref, file_ref **pparfileref, PUNICODE_STRING fpus, PUNICODE_STRING stream, PIRP Irp, ULONG options, POOL_TYPE pool_type, bool case_sensitive, LIST_ENTRY *rollback)
 
static NTSTATUS file_create (PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, PFILE_OBJECT FileObject, file_ref *related, bool loaded_related, PUNICODE_STRING fnus, ULONG disposition, ULONG options, file_ref **existing_fileref, LIST_ENTRY *rollback)
 
static __inline void debug_create_options (ULONG RequestedOptions)
 
static NTSTATUS get_reparse_block (fcb *fcb, uint8_t **data)
 
static void fcb_load_csums (_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, fcb *fcb, PIRP Irp)
 
static NTSTATUS open_file3 (device_extension *Vcb, PIRP Irp, ACCESS_MASK granted_access, file_ref *fileref, LIST_ENTRY *rollback)
 
static void __stdcall oplock_complete (PVOID Context, PIRP Irp)
 
static NTSTATUS open_file2 (device_extension *Vcb, ULONG RequestedDisposition, file_ref *fileref, ACCESS_MASK *granted_access, PFILE_OBJECT FileObject, UNICODE_STRING *fn, ULONG options, PIRP Irp, LIST_ENTRY *rollback, oplock_context **opctx)
 
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)
 
static NTSTATUS open_file (PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, PIRP Irp, LIST_ENTRY *rollback, oplock_context **opctx)
 
static NTSTATUS verify_vcb (device_extension *Vcb, PIRP Irp)
 
static bool has_manage_volume_privilege (ACCESS_STATE *access_state, KPROCESSOR_MODE processor_mode)
 
 _Dispatch_type_ (IRP_MJ_CREATE)
 

Variables

PDEVICE_OBJECT master_devobj
 
tFsRtlGetEcpListFromIrp fFsRtlGetEcpListFromIrp
 
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
 
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
 
static const WCHAR datastring [] = L"::$DATA"
 
static const char root_dir [] = "$Root"
 
static const WCHAR root_dir_utf16 [] = L"$Root"
 
static const GUID GUID_ECP_ATOMIC_CREATE = { 0x4720bd83, 0x52ac, 0x4104, { 0xa1, 0x30, 0xd1, 0xec, 0x6a, 0x8c, 0xc8, 0xe5 } }
 
static const GUID GUID_ECP_QUERY_ON_CREATE = { 0x1aca62e9, 0xabb4, 0x4ff2, { 0xbb, 0x5c, 0x1c, 0x79, 0x02, 0x5e, 0x41, 0x7f } }
 
static const GUID GUID_ECP_CREATE_REDIRECTION = { 0x188d6bd6, 0xa126, 0x4fa8, { 0xbd, 0xf2, 0x1c, 0xcd, 0xf8, 0x96, 0xf3, 0xe0 } }
 

Macro Definition Documentation

◆ ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT

#define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT   0x0100

Definition at line 38 of file create.c.

◆ ATOMIC_CREATE_ECP_IN_FLAG_OP_FLAGS_SPECIFIED

#define ATOMIC_CREATE_ECP_IN_FLAG_OP_FLAGS_SPECIFIED   0x0080

Definition at line 37 of file create.c.

◆ ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED

#define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED   0x0002

Definition at line 36 of file create.c.

◆ ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED

#define ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED   1

Definition at line 43 of file create.c.

◆ ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED

#define ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED   0x0080

Definition at line 41 of file create.c.

◆ ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET

#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET   0x0002

Definition at line 40 of file create.c.

◆ ATOMIC_CREATE_ECP_OUT_OP_FLAG_CASE_SENSITIVE_FLAGS_SET

#define ATOMIC_CREATE_ECP_OUT_OP_FLAG_CASE_SENSITIVE_FLAGS_SET   1

Definition at line 44 of file create.c.

◆ called_from_lxss

#define called_from_lxss ( )    false

Definition at line 2999 of file create.c.

◆ SL_IGNORE_READONLY_ATTRIBUTE

#define SL_IGNORE_READONLY_ATTRIBUTE   0x40

Definition at line 47 of file create.c.

Typedef Documentation

◆ ATOMIC_CREATE_ECP_CONTEXT

◆ FILE_TIMESTAMPS

◆ PATOMIC_CREATE_ECP_CONTEXT

◆ PFILE_TIMESTAMPS

Function Documentation

◆ _Dispatch_type_()

_Dispatch_type_ ( IRP_MJ_CREATE  )

Definition at line 4821 of file create.c.

4823  {
4824  NTSTATUS Status;
4826  device_extension* Vcb = DeviceObject->DeviceExtension;
4827  bool top_level, locked = false;
4828  oplock_context* opctx = NULL;
4829 
4831 
4832  TRACE("create (flags = %lx)\n", Irp->Flags);
4833 
4834  top_level = is_top_level(Irp);
4835 
4836  /* return success if just called for FS device object */
4837  if (DeviceObject == master_devobj) {
4838  TRACE("create called for FS device object\n");
4839 
4840  Irp->IoStatus.Information = FILE_OPENED;
4842 
4843  goto exit;
4844  } else if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
4846  goto exit;
4847  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
4849  goto exit;
4850  }
4851 
4852  if (!(Vcb->Vpb->Flags & VPB_MOUNTED)) {
4854  goto exit;
4855  }
4856 
4857  if (Vcb->removing) {
4859  goto exit;
4860  }
4861 
4862  Status = verify_vcb(Vcb, Irp);
4863  if (!NT_SUCCESS(Status)) {
4864  ERR("verify_vcb returned %08lx\n", Status);
4865  goto exit;
4866  }
4867 
4868  ExAcquireResourceSharedLite(&Vcb->load_lock, true);
4869  locked = true;
4870 
4872 
4873  if (IrpSp->Flags != 0) {
4875 
4876  TRACE("flags:\n");
4877 
4878  if (flags & SL_CASE_SENSITIVE) {
4879  TRACE("SL_CASE_SENSITIVE\n");
4881  }
4882 
4883  if (flags & SL_FORCE_ACCESS_CHECK) {
4884  TRACE("SL_FORCE_ACCESS_CHECK\n");
4886  }
4887 
4888  if (flags & SL_OPEN_PAGING_FILE) {
4889  TRACE("SL_OPEN_PAGING_FILE\n");
4891  }
4892 
4894  TRACE("SL_OPEN_TARGET_DIRECTORY\n");
4896  }
4897 
4898  if (flags & SL_STOP_ON_SYMLINK) {
4899  TRACE("SL_STOP_ON_SYMLINK\n");
4901  }
4902 
4904  TRACE("SL_IGNORE_READONLY_ATTRIBUTE\n");
4906  }
4907 
4908  if (flags)
4909  WARN("unknown flags: %x\n", flags);
4910  } else {
4911  TRACE("flags: (none)\n");
4912  }
4913 
4914  if (!IrpSp->FileObject) {
4915  ERR("FileObject was NULL\n");
4917  goto exit;
4918  }
4919 
4920  if (IrpSp->FileObject->RelatedFileObject) {
4921  fcb* relatedfcb = IrpSp->FileObject->RelatedFileObject->FsContext;
4922 
4923  if (relatedfcb && relatedfcb->Vcb != Vcb) {
4924  WARN("RelatedFileObject was for different device\n");
4926  goto exit;
4927  }
4928  }
4929 
4930  // opening volume
4931  if (IrpSp->FileObject->FileName.Length == 0 && !IrpSp->FileObject->RelatedFileObject) {
4932  ULONG RequestedDisposition = ((IrpSp->Parameters.Create.Options >> 24) & 0xff);
4933  ULONG RequestedOptions = IrpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
4934 #ifdef DEBUG_FCB_REFCOUNTS
4935  LONG rc;
4936 #endif
4937  ccb* ccb;
4938 
4939  TRACE("open operation for volume\n");
4940 
4941  if (RequestedDisposition != FILE_OPEN && RequestedDisposition != FILE_OPEN_IF) {
4943  goto exit;
4944  }
4945 
4946  if (RequestedOptions & FILE_DIRECTORY_FILE) {
4948  goto exit;
4949  }
4950 
4952  if (!ccb) {
4953  ERR("out of memory\n");
4955  goto exit;
4956  }
4957 
4958  RtlZeroMemory(ccb, sizeof(*ccb));
4959 
4961  ccb->NodeSize = sizeof(*ccb);
4962  ccb->disposition = RequestedDisposition;
4963  ccb->options = RequestedOptions;
4964  ccb->access = IrpSp->Parameters.Create.SecurityContext->AccessState->PreviouslyGrantedAccess;
4966  IrpSp->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode);
4967  ccb->reserving = false;
4968  ccb->lxss = called_from_lxss();
4969 
4970 #ifdef DEBUG_FCB_REFCOUNTS
4971  rc = InterlockedIncrement(&Vcb->volume_fcb->refcount);
4972  WARN("fcb %p: refcount now %i (volume)\n", Vcb->volume_fcb, rc);
4973 #else
4974  InterlockedIncrement(&Vcb->volume_fcb->refcount);
4975 #endif
4976  IrpSp->FileObject->FsContext = Vcb->volume_fcb;
4977  IrpSp->FileObject->FsContext2 = ccb;
4978 
4979  IrpSp->FileObject->SectionObjectPointer = &Vcb->volume_fcb->nonpaged->segment_object;
4980 
4981  if (!IrpSp->FileObject->Vpb)
4982  IrpSp->FileObject->Vpb = DeviceObject->Vpb;
4983 
4984  InterlockedIncrement(&Vcb->open_files);
4985 
4986  Irp->IoStatus.Information = FILE_OPENED;
4988  } else {
4990  bool skip_lock;
4991 
4993 
4994  TRACE("file name: %.*S\n", (int)(IrpSp->FileObject->FileName.Length / sizeof(WCHAR)), IrpSp->FileObject->FileName.Buffer);
4995 
4996  if (IrpSp->FileObject->RelatedFileObject)
4997  TRACE("related file = %p\n", IrpSp->FileObject->RelatedFileObject);
4998 
4999  // Don't lock again if we're being called from within CcCopyRead etc.
5000  skip_lock = ExIsResourceAcquiredExclusiveLite(&Vcb->tree_lock);
5001 
5002  if (!skip_lock)
5003  ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
5004 
5005  ExAcquireResourceSharedLite(&Vcb->fileref_lock, true);
5006 
5007  Status = open_file(DeviceObject, Vcb, Irp, &rollback, &opctx);
5008 
5009  if (!NT_SUCCESS(Status))
5011  else
5013 
5014  ExReleaseResourceLite(&Vcb->fileref_lock);
5015 
5016  if (!skip_lock)
5017  ExReleaseResourceLite(&Vcb->tree_lock);
5018  }
5019 
5020 exit:
5021  if (Status != STATUS_PENDING) {
5022  Irp->IoStatus.Status = Status;
5024  }
5025 
5026  if (locked)
5027  ExReleaseResourceLite(&Vcb->load_lock);
5028 
5029  if (Status == STATUS_PENDING) {
5031  Status = opctx->Status;
5032  ExFreePool(opctx);
5033  }
5034 
5035  TRACE("create returning %08lx\n", Status);
5036 
5037  if (top_level)
5039 
5041 
5042  return Status;
5043 }
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FsRtlEnterFileSystem
#define FILE_OPEN_IF
Definition: from_kernel.h:56
ULONG options
Definition: btrfs_drv.h:374
USHORT Flags
Definition: iotypes.h:192
NTSTATUS Status
Definition: create.c:87
#define FsRtlExitFileSystem
Iosb Status
Definition: create.c:4287
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
#define SL_STOP_ON_SYMLINK
Definition: iotypes.h:1819
#define VCB_TYPE_FS
Definition: btrfs_drv.h:679
ACCESS_MASK access
Definition: btrfs_drv.h:382
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:277
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1816
bool manage_volume_privilege
Definition: btrfs_drv.h:379
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
_In_ PIRP Irp
Definition: csq.h:116
long LONG
Definition: pedump.c:60
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:66
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
#define IoCompleteRequest
Definition: irp.c:1240
static bool has_manage_volume_privilege(ACCESS_STATE *access_state, KPROCESSOR_MODE processor_mode)
Definition: create.c:4810
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:84
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
KEVENT event
Definition: create.c:88
#define SL_IGNORE_READONLY_ATTRIBUTE
Definition: create.c:47
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:681
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
NTSTATUS vol_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:36
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
USHORT NodeType
Definition: btrfs_drv.h:371
GLbitfield flags
Definition: glext.h:7161
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
Definition: typedefs.h:119
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define FILE_OPEN
Definition: from_kernel.h:54
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818
#define InterlockedIncrement
Definition: armddk.h:53
ULONG disposition
Definition: btrfs_drv.h:373
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define called_from_lxss()
Definition: create.c:2999
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
bool reserving
Definition: btrfs_drv.h:381
#define STATUS_SUCCESS
Definition: shellext.h:65
bool lxss
Definition: btrfs_drv.h:391
void exit(int exitcode)
Definition: _exit.c:33
struct _ccb ccb
static NTSTATUS verify_vcb(device_extension *Vcb, PIRP Irp)
Definition: create.c:4748
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
CSHORT NodeSize
Definition: btrfs_drv.h:372
#define VPB_MOUNTED
Definition: iotypes.h:1807
static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, PIRP Irp, LIST_ENTRY *rollback, oplock_context **opctx)
Definition: create.c:4461
HRESULT Create([out]ITransactionReceiver **ppReceiver)
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70

◆ add_dir_child()

NTSTATUS add_dir_child ( fcb fcb,
uint64_t  inode,
bool  subvol,
PANSI_STRING  utf8,
PUNICODE_STRING  name,
uint8_t  type,
dir_child **  pdc 
)

Definition at line 1871 of file create.c.

1871  {
1872  NTSTATUS Status;
1873  dir_child* dc;
1874  bool locked;
1875 
1877  if (!dc) {
1878  ERR("out of memory\n");
1880  }
1881 
1882  RtlZeroMemory(dc, sizeof(dir_child));
1883 
1884  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, utf8->Length, ALLOC_TAG);
1885  if (!dc->utf8.Buffer) {
1886  ERR("out of memory\n");
1887  ExFreePool(dc);
1889  }
1890 
1891  dc->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
1892  if (!dc->name.Buffer) {
1893  ERR("out of memory\n");
1894  ExFreePool(dc->utf8.Buffer);
1895  ExFreePool(dc);
1897  }
1898 
1899  dc->key.obj_id = inode;
1900  dc->key.obj_type = subvol ? TYPE_ROOT_ITEM : TYPE_INODE_ITEM;
1901  dc->key.offset = subvol ? 0xffffffffffffffff : 0;
1902  dc->type = type;
1903  dc->fileref = NULL;
1904 
1905  dc->utf8.Length = dc->utf8.MaximumLength = utf8->Length;
1906  RtlCopyMemory(dc->utf8.Buffer, utf8->Buffer, utf8->Length);
1907 
1908  dc->name.Length = dc->name.MaximumLength = name->Length;
1909  RtlCopyMemory(dc->name.Buffer, name->Buffer, name->Length);
1910 
1911  Status = RtlUpcaseUnicodeString(&dc->name_uc, name, true);
1912  if (!NT_SUCCESS(Status)) {
1913  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
1914  ExFreePool(dc->utf8.Buffer);
1915  ExFreePool(dc->name.Buffer);
1916  ExFreePool(dc);
1917  return Status;
1918  }
1919 
1920  dc->hash = calc_crc32c(0xffffffff, (uint8_t*)dc->name.Buffer, dc->name.Length);
1921  dc->hash_uc = calc_crc32c(0xffffffff, (uint8_t*)dc->name_uc.Buffer, dc->name_uc.Length);
1922 
1923  locked = ExIsResourceAcquiredExclusive(&fcb->nonpaged->dir_children_lock);
1924 
1925  if (!locked)
1926  ExAcquireResourceExclusiveLite(&fcb->nonpaged->dir_children_lock, true);
1927 
1929  dc->index = 2;
1930  else {
1931  dir_child* dc2 = CONTAINING_RECORD(fcb->dir_children_index.Blink, dir_child, list_entry_index);
1932 
1933  dc->index = max(2, dc2->index + 1);
1934  }
1935 
1936  InsertTailList(&fcb->dir_children_index, &dc->list_entry_index);
1937 
1939 
1940  if (!locked)
1941  ExReleaseResourceLite(&fcb->nonpaged->dir_children_lock);
1942 
1943  *pdc = dc;
1944 
1945  return STATUS_SUCCESS;
1946 }
#define max(a, b)
Definition: svc.c:63
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
Iosb Status
Definition: create.c:4287
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
LONG NTSTATUS
Definition: precomp.h:26
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
Definition: fs.h:78
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:87
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:314
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
uint64_t index
Definition: btrfs_drv.h:252
#define TYPE_INODE_ITEM
Definition: btrfs.h:23
crc_func calc_crc32c
Definition: crc32c.c:23
BYTE uint8_t
Definition: msvideo1.c:66
#define ERR(fmt,...)
Definition: debug.h:110
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
#define TYPE_ROOT_ITEM
Definition: btrfs.h:32
void insert_dir_child_into_hash_lists(fcb *fcb, dir_child *dc)
Definition: fileinfo.c:1470
#define NULL
Definition: types.h:112
Definition: name.c:38
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR dc[]
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by create_subvol(), do_create_snapshot(), file_create2(), mknod(), and set_link_information().

◆ create_fcb()

fcb* create_fcb ( device_extension Vcb,
POOL_TYPE  pool_type 
)

Definition at line 91 of file create.c.

91  {
92  fcb* fcb;
93 
94  if (pool_type == NonPagedPool) {
95  fcb = ExAllocatePoolWithTag(pool_type, sizeof(struct _fcb), ALLOC_TAG);
96  if (!fcb) {
97  ERR("out of memory\n");
98  return NULL;
99  }
100  } else {
101  fcb = ExAllocateFromPagedLookasideList(&Vcb->fcb_lookaside);
102  if (!fcb) {
103  ERR("out of memory\n");
104  return NULL;
105  }
106  }
107 
108 #ifdef DEBUG_FCB_REFCOUNTS
109  WARN("allocating fcb %p\n", fcb);
110 #endif
111  RtlZeroMemory(fcb, sizeof(struct _fcb));
112  fcb->pool_type = pool_type;
113 
114  fcb->Header.NodeTypeCode = BTRFS_NODE_TYPE_FCB;
115  fcb->Header.NodeByteSize = sizeof(struct _fcb);
116 
117  fcb->nonpaged = ExAllocateFromNPagedLookasideList(&Vcb->fcb_np_lookaside);
118  if (!fcb->nonpaged) {
119  ERR("out of memory\n");
120 
121  if (pool_type == NonPagedPool)
122  ExFreePool(fcb);
123  else
124  ExFreeToPagedLookasideList(&Vcb->fcb_lookaside, fcb);
125 
126  return NULL;
127  }
128  RtlZeroMemory(fcb->nonpaged, sizeof(struct _fcb_nonpaged));
129 
130  ExInitializeResourceLite(&fcb->nonpaged->paging_resource);
131  fcb->Header.PagingIoResource = &fcb->nonpaged->paging_resource;
132 
133  ExInitializeFastMutex(&fcb->nonpaged->HeaderMutex);
134  FsRtlSetupAdvancedHeader(&fcb->Header, &fcb->nonpaged->HeaderMutex);
135 
136  fcb->refcount = 1;
137 #ifdef DEBUG_FCB_REFCOUNTS
138  WARN("fcb %p: refcount now %i\n", fcb, fcb->refcount);
139 #endif
140 
142  fcb->Header.Resource = &fcb->nonpaged->resource;
143 
144  ExInitializeResourceLite(&fcb->nonpaged->dir_children_lock);
145 
148 
152 
156 
157  return fcb;
158 }
#define BTRFS_NODE_TYPE_FCB
Definition: btrfs_drv.h:85
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
#define WARN(fmt,...)
Definition: debug.h:112
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
FILE_LOCK lock
Definition: btrfs_drv.h:294
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:316
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:314
struct _fcb fcb
Definition: btrfs_drv.h:1355
LIST_ENTRY xattrs
Definition: btrfs_drv.h:308
VOID NTAPI FsRtlInitializeOplock(IN OUT POPLOCK Oplock)
Definition: oplock.c:1400
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
LIST_ENTRY hardlinks
Definition: btrfs_drv.h:304
LIST_ENTRY extents
Definition: btrfs_drv.h:300
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
LONG refcount
Definition: btrfs_drv.h:285
#define ERR(fmt,...)
Definition: debug.h:110
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
static __inline POPLOCK fcb_oplock(fcb *fcb)
Definition: btrfs_drv.h:1670
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:315
POOL_TYPE pool_type
Definition: btrfs_drv.h:286
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by allocate_cache_chunk(), create_directory_fcb(), create_stream(), create_subvol(), duplicate_fcb(), file_create2(), mknod(), mount_vol(), open_fcb(), open_fcb_stream(), rename_stream(), and rename_stream_to_file().

◆ create_fileref()

file_ref* create_fileref ( device_extension Vcb)

Definition at line 160 of file create.c.

160  {
161  file_ref* fr;
162 
163  fr = ExAllocateFromPagedLookasideList(&Vcb->fileref_lookaside);
164  if (!fr) {
165  ERR("out of memory\n");
166  return NULL;
167  }
168 
169  RtlZeroMemory(fr, sizeof(file_ref));
170 
171  fr->refcount = 1;
172 
173 #ifdef DEBUG_FCB_REFCOUNTS
174  WARN("fileref %p: refcount now 1\n", fr);
175 #endif
176 
178 
179  return fr;
180 }
#define WARN(fmt,...)
Definition: debug.h:112
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
LONG refcount
Definition: btrfs_drv.h:350
LIST_ENTRY children
Definition: btrfs_drv.h:349
#define ERR(fmt,...)
Definition: debug.h:110
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by create_stream(), create_subvol(), do_create_snapshot(), file_create2(), mknod(), mount_vol(), move_across_subvols(), open_fileref_child(), rename_file_to_stream(), set_link_information(), and set_rename_information().

◆ create_stream()

static NTSTATUS create_stream ( _Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension Vcb,
file_ref **  pfileref,
file_ref **  pparfileref,
PUNICODE_STRING  fpus,
PUNICODE_STRING  stream,
PIRP  Irp,
ULONG  options,
POOL_TYPE  pool_type,
bool  case_sensitive,
LIST_ENTRY rollback 
)
static

Definition at line 2635 of file create.c.

2637  {
2639  file_ref *fileref, *newpar, *parfileref;
2640  fcb* fcb;
2641  static const char xapref[] = "user.";
2642  static const WCHAR DOSATTRIB[] = L"DOSATTRIB";
2643  static const WCHAR EA[] = L"EA";
2644  static const WCHAR reparse[] = L"reparse";
2645  static const WCHAR casesensitive_str[] = L"casesensitive";
2647  BTRFS_TIME now;
2648  ULONG utf8len, overhead;
2649  NTSTATUS Status;
2650  KEY searchkey;
2651  traverse_ptr tp;
2652  dir_child* dc;
2653  dir_child* existing_dc = NULL;
2654  ACCESS_MASK granted_access;
2655 #ifdef DEBUG_FCB_REFCOUNTS
2656  LONG rc;
2657 #endif
2658 
2659  TRACE("fpus = %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer);
2660  TRACE("stream = %.*S\n", (int)(stream->Length / sizeof(WCHAR)), stream->Buffer);
2661 
2662  parfileref = *pparfileref;
2663 
2664  if (parfileref->fcb == Vcb->dummy_fcb)
2665  return STATUS_ACCESS_DENIED;
2666 
2667  Status = check_file_name_valid(stream, false, true);
2668  if (!NT_SUCCESS(Status))
2669  return Status;
2670 
2671  Status = open_fileref(Vcb, &newpar, fpus, parfileref, false, NULL, NULL, PagedPool, case_sensitive, Irp);
2672 
2674  UNICODE_STRING fpus2;
2675 
2676  Status = check_file_name_valid(fpus, false, false);
2677  if (!NT_SUCCESS(Status))
2678  return Status;
2679 
2680  fpus2.Length = fpus2.MaximumLength = fpus->Length;
2682 
2683  if (!fpus2.Buffer) {
2684  ERR("out of memory\n");
2686  }
2687 
2688  RtlCopyMemory(fpus2.Buffer, fpus->Buffer, fpus2.Length);
2689 
2690  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2691 
2692  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2695  &granted_access, &Status)) {
2696  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2697  return Status;
2698  }
2699 
2700  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2701 
2702  Status = file_create2(Irp, Vcb, &fpus2, parfileref, options, NULL, 0, &newpar, case_sensitive, rollback);
2703 
2704  if (!NT_SUCCESS(Status)) {
2705  ERR("file_create2 returned %08lx\n", Status);
2706  ExFreePool(fpus2.Buffer);
2707  return Status;
2708  } else if (Status != STATUS_OBJECT_NAME_COLLISION) {
2711  }
2712 
2713  ExFreePool(fpus2.Buffer);
2714  } else if (!NT_SUCCESS(Status)) {
2715  ERR("open_fileref returned %08lx\n", Status);
2716  return Status;
2717  }
2718 
2719  parfileref = newpar;
2720  *pparfileref = parfileref;
2721 
2722  if (parfileref->fcb->type != BTRFS_TYPE_FILE && parfileref->fcb->type != BTRFS_TYPE_SYMLINK && parfileref->fcb->type != BTRFS_TYPE_DIRECTORY) {
2723  WARN("parent not file, directory, or symlink\n");
2724  free_fileref(parfileref);
2725  return STATUS_INVALID_PARAMETER;
2726  }
2727 
2728  if (options & FILE_DIRECTORY_FILE) {
2729  WARN("tried to create directory as stream\n");
2730  free_fileref(parfileref);
2731  return STATUS_INVALID_PARAMETER;
2732  }
2733 
2735  free_fileref(parfileref);
2736  return STATUS_ACCESS_DENIED;
2737  }
2738 
2739  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2740 
2741  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2743  &granted_access, &Status)) {
2744  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2745  free_fileref(parfileref);
2746  return Status;
2747  }
2748 
2749  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2750 
2751  if ((stream->Length == sizeof(DOSATTRIB) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, DOSATTRIB, stream->Length) == stream->Length) ||
2752  (stream->Length == sizeof(EA) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, EA, stream->Length) == stream->Length) ||
2753  (stream->Length == sizeof(reparse) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, reparse, stream->Length) == stream->Length) ||
2754  (stream->Length == sizeof(casesensitive_str) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, casesensitive_str, stream->Length) == stream->Length)) {
2755  free_fileref(parfileref);
2757  }
2758 
2760  if (!fcb) {
2761  ERR("out of memory\n");
2762  free_fileref(parfileref);
2764  }
2765 
2766  fcb->Vcb = Vcb;
2767 
2768  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2769  fcb->Header.AllocationSize.QuadPart = 0;
2770  fcb->Header.FileSize.QuadPart = 0;
2771  fcb->Header.ValidDataLength.QuadPart = 0;
2772 
2773 #ifdef DEBUG_FCB_REFCOUNTS
2774  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2775  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2776 #else
2777  InterlockedIncrement(&parfileref->fcb->refcount);
2778 #endif
2779  fcb->subvol = parfileref->fcb->subvol;
2780  fcb->inode = parfileref->fcb->inode;
2781  fcb->hash = parfileref->fcb->hash;
2782  fcb->type = parfileref->fcb->type;
2783 
2784  fcb->ads = true;
2785 
2786  Status = utf16_to_utf8(NULL, 0, &utf8len, stream->Buffer, stream->Length);
2787  if (!NT_SUCCESS(Status)) {
2788  ERR("utf16_to_utf8 1 returned %08lx\n", Status);
2789  reap_fcb(fcb);
2790  free_fileref(parfileref);
2791  return Status;
2792  }
2793 
2794  fcb->adsxattr.Length = (uint16_t)utf8len + sizeof(xapref) - 1;
2797  if (!fcb->adsxattr.Buffer) {
2798  ERR("out of memory\n");
2799  reap_fcb(fcb);
2800  free_fileref(parfileref);
2802  }
2803 
2804  RtlCopyMemory(fcb->adsxattr.Buffer, xapref, sizeof(xapref) - 1);
2805 
2806  Status = utf16_to_utf8(&fcb->adsxattr.Buffer[sizeof(xapref) - 1], utf8len, &utf8len, stream->Buffer, stream->Length);
2807  if (!NT_SUCCESS(Status)) {
2808  ERR("utf16_to_utf8 2 returned %08lx\n", Status);
2809  reap_fcb(fcb);
2810  free_fileref(parfileref);
2811  return Status;
2812  }
2813 
2815 
2816  TRACE("adsxattr = %s\n", fcb->adsxattr.Buffer);
2817 
2819  TRACE("adshash = %08x\n", fcb->adshash);
2820 
2821  searchkey.obj_id = parfileref->fcb->inode;
2822  searchkey.obj_type = TYPE_XATTR_ITEM;
2823  searchkey.offset = fcb->adshash;
2824 
2825  Status = find_item(Vcb, parfileref->fcb->subvol, &tp, &searchkey, false, Irp);
2826  if (!NT_SUCCESS(Status)) {
2827  ERR("find_item returned %08lx\n", Status);
2828  reap_fcb(fcb);
2829  free_fileref(parfileref);
2830  return Status;
2831  }
2832 
2833  if (!keycmp(tp.item->key, searchkey))
2834  overhead = tp.item->size;
2835  else
2836  overhead = 0;
2837 
2838  fcb->adsmaxlen = Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - (sizeof(DIR_ITEM) - 1);
2839 
2840  if (utf8len + sizeof(xapref) - 1 + overhead > fcb->adsmaxlen) {
2841  WARN("not enough room for new DIR_ITEM (%Iu + %lu > %lu)", utf8len + sizeof(xapref) - 1, overhead, fcb->adsmaxlen);
2842  reap_fcb(fcb);
2843  free_fileref(parfileref);
2844  return STATUS_DISK_FULL;
2845  } else
2846  fcb->adsmaxlen -= overhead + utf8len + sizeof(xapref) - 1;
2847 
2848  fcb->created = true;
2849  fcb->deleted = true;
2850 
2851  acquire_fcb_lock_exclusive(Vcb);
2852  InsertHeadList(&parfileref->fcb->list_entry, &fcb->list_entry); // insert in list after parent fcb
2853  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2854  parfileref->fcb->subvol->fcbs_version++;
2855  release_fcb_lock(Vcb);
2856 
2858 
2860  if (!fileref) {
2861  ERR("out of memory\n");
2862  free_fcb(fcb);
2863  free_fileref(parfileref);
2865  }
2866 
2867  fileref->fcb = fcb;
2868 
2870  if (!dc) {
2871  ERR("out of memory\n");
2873  free_fileref(parfileref);
2875  }
2876 
2877  RtlZeroMemory(dc, sizeof(dir_child));
2878 
2879  dc->utf8.MaximumLength = dc->utf8.Length = fcb->adsxattr.Length + 1 - sizeof(xapref);
2880  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, dc->utf8.MaximumLength, ALLOC_TAG);
2881  if (!dc->utf8.Buffer) {
2882  ERR("out of memory\n");
2883  ExFreePool(dc);
2885  free_fileref(parfileref);
2887  }
2888 
2889  RtlCopyMemory(dc->utf8.Buffer, &fcb->adsxattr.Buffer[sizeof(xapref) - 1], fcb->adsxattr.Length + 1 - sizeof(xapref));
2890 
2891  dc->name.MaximumLength = dc->name.Length = stream->Length;
2892  dc->name.Buffer = ExAllocatePoolWithTag(pool_type, dc->name.MaximumLength, ALLOC_TAG);
2893  if (!dc->name.Buffer) {
2894  ERR("out of memory\n");
2895  ExFreePool(dc->utf8.Buffer);
2896  ExFreePool(dc);
2898  free_fileref(parfileref);
2900  }
2901 
2902  RtlCopyMemory(dc->name.Buffer, stream->Buffer, stream->Length);
2903 
2904  Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true);
2905  if (!NT_SUCCESS(Status)) {
2906  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
2907  ExFreePool(dc->utf8.Buffer);
2908  ExFreePool(dc->name.Buffer);
2909  ExFreePool(dc);
2911  free_fileref(parfileref);
2912  return Status;
2913  }
2914 
2917 
2918  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2919 
2920  LIST_ENTRY* le = parfileref->fcb->dir_children_index.Flink;
2921  while (le != &parfileref->fcb->dir_children_index) {
2922  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
2923 
2924  if (dc2->index == 0) {
2925  if ((case_sensitive && dc2->name.Length == dc->name.Length && RtlCompareMemory(dc2->name.Buffer, dc->name.Buffer, dc2->name.Length) == dc2->name.Length) ||
2926  (!case_sensitive && dc2->name_uc.Length == dc->name_uc.Length && RtlCompareMemory(dc2->name_uc.Buffer, dc->name_uc.Buffer, dc2->name_uc.Length) == dc2->name_uc.Length)
2927  ) {
2928  existing_dc = dc2;
2929  break;
2930  }
2931  } else
2932  break;
2933 
2934  le = le->Flink;
2935  }
2936 
2937  if (existing_dc) {
2938  ExFreePool(dc->utf8.Buffer);
2939  ExFreePool(dc->name.Buffer);
2940  ExFreePool(dc);
2942  free_fileref(parfileref);
2943 
2944  increase_fileref_refcount(existing_dc->fileref);
2945  *pfileref = existing_dc->fileref;
2946 
2948  }
2949 
2950  dc->fileref = fileref;
2951  fileref->dc = dc;
2952  fileref->parent = (struct _file_ref*)parfileref;
2953  fcb->deleted = false;
2954 
2955  InsertHeadList(&parfileref->fcb->dir_children_index, &dc->list_entry_index);
2956 
2957  InsertTailList(&parfileref->children, &fileref->list_entry);
2958 
2959  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2960 
2961  mark_fileref_dirty(fileref);
2962 
2963  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2964  parfileref->fcb->inode_item.sequence++;
2965  parfileref->fcb->inode_item.st_ctime = now;
2966  parfileref->fcb->inode_item_changed = true;
2967 
2968  mark_fcb_dirty(parfileref->fcb);
2969 
2970  parfileref->fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2971  parfileref->fcb->subvol->root_item.ctime = now;
2972 
2973  increase_fileref_refcount(parfileref);
2974 
2975  *pfileref = fileref;
2976 
2978 
2979  return STATUS_SUCCESS;
2980 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3266
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
struct _file_ref * parent
Definition: btrfs_drv.h:352
uint64_t obj_id
Definition: btrfs.h:144
struct _file_ref * fileref
Definition: btrfs_drv.h:260
NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _Out_ file_ref **pfr, _In_ PUNICODE_STRING fnus, _In_opt_ file_ref *related, _In_ bool parent, _Out_opt_ USHORT *parsed, _Out_opt_ ULONG *fn_offset, _In_ POOL_TYPE pooltype, _In_ bool case_sensitive, _In_opt_ PIRP Irp)
Definition: create.c:1690
uint8_t obj_type
Definition: btrfs.h:145
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
file_ref * create_fileref(device_extension *Vcb)
Definition: create.c:160
uint32_t adshash
Definition: btrfs_drv.h:331
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1703
USHORT MaximumLength
Definition: env_spec_w32.h:370
static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _In_ PUNICODE_STRING fpus, _In_ file_ref *parfileref, _In_ ULONG options, _In_reads_bytes_opt_(ealen) FILE_FULL_EA_INFORMATION *ea, _In_ ULONG ealen, _Out_ file_ref **pfr, bool case_sensitive, _In_ LIST_ENTRY *rollback)
Definition: create.c:2182
Iosb Status
Definition: create.c:4287
UNICODE_STRING name_uc
Definition: btrfs_drv.h:258
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define keycmp(key1, key2)
Definition: btrfs_drv.h:1008
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
uint16_t size
Definition: btrfs_drv.h:414
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_FILE_NAME
__u16 time
Definition: mkdosfs.c:366
#define uint16_t
Definition: nsiface.idl:60
void reap_fileref(device_extension *Vcb, file_ref *fr)
Definition: btrfs.c:1844
#define InsertTailList(ListHead, Entry)
#define FILE_NOTIFY_CHANGE_DIR_NAME
void send_notification_fileref(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1486
BTRFS_TIME st_ctime
Definition: btrfs.h:302
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1816
uint64_t offset
Definition: btrfs.h:146
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:337
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:91
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1636
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:293
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1686
#define L(x)
Definition: ntvdm.h:50
#define FILE_ADD_FILE
Definition: nt_native.h:632
_In_ PIRP Irp
Definition: csq.h:116
long LONG
Definition: pedump.c:60
LIST_ENTRY list_entry
Definition: btrfs_drv.h:336
uint64_t sequence
Definition: btrfs.h:299
time_t now
Definition: finger.c:65
#define FILE_ACTION_MODIFIED
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
void reap_fcb(fcb *fcb)
Definition: btrfs.c:1712
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:670
uint8_t type
Definition: btrfs_drv.h:291
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1729
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2965
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define TYPE_XATTR_ITEM
Definition: btrfs.h:26
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:314
struct _fcb fcb
Definition: btrfs_drv.h:1355
#define SL_IGNORE_READONLY_ATTRIBUTE
Definition: create.c:47
NTSTATUS find_item(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _Out_ traverse_ptr *tp, _In_ const KEY *searchkey, _In_ bool ignore, _In_opt_ PIRP Irp) __attribute__((nonnull(1
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t inode
Definition: btrfs_drv.h:289
#define FILE_NOTIFY_CHANGE_STREAM_NAME
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
struct _file_ref * fileref
Definition: btrfs_drv.h:305
bool case_sensitive
Definition: btrfs_drv.h:310
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
uint32_t hash
Definition: btrfs_drv.h:290
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
dir_child * dc
Definition: btrfs_drv.h:353
tree_data * item
Definition: btrfs_drv.h:502
LIST_ENTRY children
Definition: btrfs_drv.h:349
LONG refcount
Definition: btrfs_drv.h:285
Definition: parse.h:22
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
uint64_t index
Definition: btrfs_drv.h:252
crc_func calc_crc32c
Definition: crc32c.c:23
bool created
Definition: btrfs_drv.h:328
fcb * fcb
Definition: btrfs_drv.h:342
Definition: typedefs.h:119
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1677
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:903
#define ERR(fmt,...)
Definition: debug.h:110
Definition: btrfs.h:143
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULONG atts
Definition: btrfs_drv.h:297
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
bool deleted
Definition: btrfs_drv.h:295
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
uint64_t transid
Definition: btrfs.h:288
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
struct _root * subvol
Definition: btrfs_drv.h:288
ULONG adsmaxlen
Definition: btrfs_drv.h:332
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1825
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
bool ads
Definition: btrfs_drv.h:330
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:981
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR dc[]
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS check_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5766
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
bool inode_item_changed
Definition: btrfs_drv.h:306
HRESULT Create([out]ITransactionReceiver **ppReceiver)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_ACTION_ADDED_STREAM
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
POOL_TYPE pool_type
Definition: btrfs_drv.h:286
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UNICODE_STRING name
Definition: btrfs_drv.h:256
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
ANSI_STRING adsxattr
Definition: btrfs_drv.h:333
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
LIST_ENTRY list_entry
Definition: btrfs_drv.h:357

Referenced by file_create().

◆ debug_create_options()

static __inline void debug_create_options ( ULONG  RequestedOptions)
static

Definition at line 3295 of file create.c.

3295  {
3296  if (RequestedOptions != 0) {
3297  ULONG options = RequestedOptions;
3298 
3299  TRACE("requested options:\n");
3300 
3301  if (options & FILE_DIRECTORY_FILE) {
3302  TRACE(" FILE_DIRECTORY_FILE\n");
3304  }
3305 
3306  if (options & FILE_WRITE_THROUGH) {
3307  TRACE(" FILE_WRITE_THROUGH\n");
3309  }
3310 
3311  if (options & FILE_SEQUENTIAL_ONLY) {
3312  TRACE(" FILE_SEQUENTIAL_ONLY\n");
3314  }
3315 
3317  TRACE(" FILE_NO_INTERMEDIATE_BUFFERING\n");
3319  }
3320 
3322  TRACE(" FILE_SYNCHRONOUS_IO_ALERT\n");
3324  }
3325 
3327  TRACE(" FILE_SYNCHRONOUS_IO_NONALERT\n");
3329  }
3330 
3332  TRACE(" FILE_NON_DIRECTORY_FILE\n");
3334  }
3335 
3337  TRACE(" FILE_CREATE_TREE_CONNECTION\n");
3339  }
3340 
3342  TRACE(" FILE_COMPLETE_IF_OPLOCKED\n");
3344  }
3345 
3346  if (options & FILE_NO_EA_KNOWLEDGE) {
3347  TRACE(" FILE_NO_EA_KNOWLEDGE\n");
3349  }
3350 
3352  TRACE(" FILE_OPEN_REMOTE_INSTANCE\n");
3354  }
3355 
3356  if (options & FILE_RANDOM_ACCESS) {
3357  TRACE(" FILE_RANDOM_ACCESS\n");
3359  }
3360 
3361  if (options & FILE_DELETE_ON_CLOSE) {
3362  TRACE(" FILE_DELETE_ON_CLOSE\n");
3364  }
3365 
3366  if (options & FILE_OPEN_BY_FILE_ID) {
3367  TRACE(" FILE_OPEN_BY_FILE_ID\n");
3369  }
3370 
3372  TRACE(" FILE_OPEN_FOR_BACKUP_INTENT\n");
3374  }
3375 
3376  if (options & FILE_NO_COMPRESSION) {
3377  TRACE(" FILE_NO_COMPRESSION\n");
3379  }
3380 
3381 #if NTDDI_VERSION >= NTDDI_WIN7
3383  TRACE(" FILE_OPEN_REQUIRING_OPLOCK\n");
3385  }
3386 
3388  TRACE(" FILE_DISALLOW_EXCLUSIVE\n");
3390  }
3391 #endif
3392 
3394  TRACE(" FILE_RESERVE_OPFILTER\n");
3396  }
3397 
3399  TRACE(" FILE_OPEN_REPARSE_POINT\n");
3401  }
3402 
3403  if (options & FILE_OPEN_NO_RECALL) {
3404  TRACE(" FILE_OPEN_NO_RECALL\n");
3406  }
3407 
3409  TRACE(" FILE_OPEN_FOR_FREE_SPACE_QUERY\n");
3411  }
3412 
3413  if (options)
3414  TRACE(" unknown options: %lx\n", options);
3415  } else {
3416  TRACE("requested options: (none)\n");
3417  }
3418 }
#define FILE_NO_COMPRESSION
Definition: from_kernel.h:43
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_DISALLOW_EXCLUSIVE
#define FILE_OPEN_NO_RECALL
Definition: from_kernel.h:47
#define FILE_OPEN_REMOTE_INSTANCE
Definition: from_kernel.h:37
#define FILE_RESERVE_OPFILTER
Definition: from_kernel.h:45
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define FILE_NO_EA_KNOWLEDGE
Definition: from_kernel.h:36
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define TRACE(s)
Definition: solgame.cpp:4
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_OPEN_FOR_FREE_SPACE_QUERY
Definition: constants.h:495
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FILE_RANDOM_ACCESS
Definition: from_kernel.h:38
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
#define FILE_OPEN_REQUIRING_OPLOCK
Definition: winternl.h:186
#define FILE_CREATE_TREE_CONNECTION
Definition: from_kernel.h:33
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_COMPLETE_IF_OPLOCKED
Definition: constants.h:493

Referenced by open_file().

◆ fcb_load_csums()

static void fcb_load_csums ( _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
fcb fcb,
PIRP  Irp 
)
static

Definition at line 3542 of file create.c.

3542  {
3543  LIST_ENTRY* le;
3544  NTSTATUS Status;
3545 
3546  if (fcb->csum_loaded)
3547  return;
3548 
3550  goto end;
3551 
3552  le = fcb->extents.Flink;
3553  while (le != &fcb->extents) {
3555 
3556  if (!ext->ignore && ext->extent_data.type == EXTENT_TYPE_REGULAR) {
3557  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)&ext->extent_data.data[0];
3558  uint64_t len;
3559 
3560  len = (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->num_bytes : ed2->size) >> Vcb->sector_shift;
3561 
3562  ext->csum = ExAllocatePoolWithTag(NonPagedPool, (ULONG)(len * Vcb->csum_size), ALLOC_TAG);
3563  if (!ext->csum) {
3564  ERR("out of memory\n");
3565  goto end;
3566  }
3567 
3568  Status = load_csum(Vcb, ext->csum, ed2->address + (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->offset : 0), len, Irp);
3569 
3570  if (!NT_SUCCESS(Status)) {
3571  ERR("load_csum returned %08lx\n", Status);
3572  goto end;
3573  }
3574  }
3575 
3576  le = le->Flink;
3577  }
3578 
3579 end:
3580  fcb->csum_loaded = true;
3581 }
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
Iosb Status
Definition: create.c:4287
LONG NTSTATUS
Definition: precomp.h:26
uint32_t flags
Definition: btrfs.h:297
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
_In_ PIRP Irp
Definition: csq.h:116
uint64_t address
Definition: btrfs.h:368
char ext[3]
Definition: mkdosfs.c:358
uint64_t size
Definition: btrfs.h:369
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, void *csum, uint64_t start, uint64_t length, PIRP Irp)
Definition: create.c:453
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
LIST_ENTRY extents
Definition: btrfs_drv.h:300
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
uint64_t num_bytes
Definition: btrfs.h:371
#define EXTENT_TYPE_REGULAR
Definition: btrfs.h:75
#define ERR(fmt,...)
Definition: debug.h:110
UINT64 uint64_t
Definition: types.h:77
Definition: list.h:27
unsigned int ULONG
Definition: retypes.h:1
uint64_t offset
Definition: btrfs.h:370
bool csum_loaded
Definition: btrfs_drv.h:299

Referenced by open_file(), and oplock_complete().

◆ file_create()

static NTSTATUS file_create ( PIRP  Irp,
_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension Vcb,
PFILE_OBJECT  FileObject,
file_ref related,
bool  loaded_related,
PUNICODE_STRING  fnus,
ULONG  disposition,
ULONG  options,
file_ref **  existing_fileref,
LIST_ENTRY rollback 
)
static

Definition at line 3002 of file create.c.

3004  {
3005  NTSTATUS Status;
3006  file_ref *fileref, *parfileref = NULL;
3007  ULONG i, j;
3008  ccb* ccb;
3009  static const WCHAR datasuf[] = {':','$','D','A','T','A',0};
3010  UNICODE_STRING dsus, fpus, stream;
3013  ECP_LIST* ecp_list;
3015 #ifdef DEBUG_FCB_REFCOUNTS
3016  LONG oc;
3017 #endif
3018 
3019  TRACE("(%p, %p, %p, %.*S, %lx, %lx)\n", Irp, Vcb, FileObject, (int)(fnus->Length / sizeof(WCHAR)), fnus->Buffer, disposition, options);
3020 
3021  if (Vcb->readonly)
3023 
3026  return STATUS_CANNOT_DELETE;
3027  }
3028 
3030  if (NT_SUCCESS(fFsRtlGetEcpListFromIrp(Irp, &ecp_list)) && ecp_list) {
3031  void* ctx = NULL;
3032  GUID type;
3033  ULONG ctxsize;
3034 
3035  do {
3036  Status = fFsRtlGetNextExtraCreateParameter(ecp_list, ctx, &type, &ctx, &ctxsize);
3037 
3038  if (NT_SUCCESS(Status)) {
3039  if (RtlCompareMemory(&type, &GUID_ECP_ATOMIC_CREATE, sizeof(GUID)) == sizeof(GUID)) {
3040  if (ctxsize >= sizeof(ATOMIC_CREATE_ECP_CONTEXT))
3041  acec = ctx;
3042  else {
3043  ERR("GUID_ECP_ATOMIC_CREATE context was too short: %lu bytes, expected %Iu\n", ctxsize,
3044  sizeof(ATOMIC_CREATE_ECP_CONTEXT));
3045  }
3046  } else if (RtlCompareMemory(&type, &GUID_ECP_QUERY_ON_CREATE, sizeof(GUID)) == sizeof(GUID))
3047  WARN("unhandled ECP GUID_ECP_QUERY_ON_CREATE\n");
3048  else if (RtlCompareMemory(&type, &GUID_ECP_CREATE_REDIRECTION, sizeof(GUID)) == sizeof(GUID))
3049  WARN("unhandled ECP GUID_ECP_CREATE_REDIRECTION\n");
3050  else {
3051  WARN("unhandled ECP {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", type.Data1, type.Data2,
3052  type.Data3, type.Data4[0], type.Data4[1], type.Data4[2], type.Data4[3], type.Data4[4], type.Data4[5],
3053  type.Data4[6], type.Data4[7]);
3054  }
3055  }
3056  } while (NT_SUCCESS(Status));
3057  }
3058  }
3059 
3060  dsus.Buffer = (WCHAR*)datasuf;
3061  dsus.Length = dsus.MaximumLength = sizeof(datasuf) - sizeof(WCHAR);
3062  fpus.Buffer = NULL;
3063 
3064  if (!loaded_related) {
3065  Status = open_fileref(Vcb, &parfileref, fnus, related, true, NULL, NULL, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, Irp);
3066 
3067  if (!NT_SUCCESS(Status))
3068  goto end;
3069  } else
3070  parfileref = related;
3071 
3072  if (parfileref->fcb->type != BTRFS_TYPE_DIRECTORY && (fnus->Length < sizeof(WCHAR) || fnus->Buffer[0] != ':')) {
3074  goto end;
3075  }
3076 
3077  if (is_subvol_readonly(parfileref->fcb->subvol, Irp)) {
3079  goto end;
3080  }
3081 
3082  i = (fnus->Length / sizeof(WCHAR))-1;
3083  while ((fnus->Buffer[i] == '\\' || fnus->Buffer[i] == '/') && i > 0) { i--; }
3084 
3085  j = i;
3086 
3087  while (i > 0 && fnus->Buffer[i-1] != '\\' && fnus->Buffer[i-1] != '/') { i--; }
3088 
3089  fpus.MaximumLength = (USHORT)((j - i + 2) * sizeof(WCHAR));
3090  fpus.Buffer = ExAllocatePoolWithTag(pool_type, fpus.MaximumLength, ALLOC_TAG);
3091  if (!fpus.Buffer) {
3092  ERR("out of memory\n");
3094  goto end;
3095  }
3096 
3097  fpus.Length = (USHORT)((j - i + 1) * sizeof(WCHAR));
3098 
3099  RtlCopyMemory(fpus.Buffer, &fnus->Buffer[i], (j - i + 1) * sizeof(WCHAR));
3100  fpus.Buffer[j - i + 1] = 0;
3101 
3102  if (fpus.Length > dsus.Length) { // check for :$DATA suffix
3103  UNICODE_STRING lb;
3104 
3105  lb.Buffer = &fpus.Buffer[(fpus.Length - dsus.Length)/sizeof(WCHAR)];
3106  lb.Length = lb.MaximumLength = dsus.Length;
3107 
3108  TRACE("lb = %.*S\n", (int)(lb.Length/sizeof(WCHAR)), lb.Buffer);
3109 
3110  if (FsRtlAreNamesEqual(&dsus, &lb, true, NULL)) {
3111  TRACE("ignoring :$DATA suffix\n");
3112 
3113  fpus.Length -= lb.Length;
3114 
3115  if (fpus.Length > sizeof(WCHAR) && fpus.Buffer[(fpus.Length-1)/sizeof(WCHAR)] == ':')
3116  fpus.Length -= sizeof(WCHAR);
3117 
3118  TRACE("fpus = %.*S\n", (int)(fpus.Length / sizeof(WCHAR)), fpus.Buffer);
3119  }
3120  }
3121 
3122  stream.Length = 0;
3123 
3124  for (i = 0; i < fpus.Length / sizeof(WCHAR); i++) {
3125  if (fpus.Buffer[i] == ':') {
3126  stream.Length = (USHORT)(fpus.Length - (i * sizeof(WCHAR)) - sizeof(WCHAR));
3127  stream.Buffer = &fpus.Buffer[i+1];
3128  fpus.Buffer[i] = 0;
3129  fpus.Length = (USHORT)(i * sizeof(WCHAR));
3130  break;
3131  }
3132  }
3133 
3134  if (stream.Length > 0) {
3135  Status = create_stream(Vcb, &fileref, &parfileref, &fpus, &stream, Irp, options, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3136  if (!NT_SUCCESS(Status)) {
3137  ERR("create_stream returned %08lx\n", Status);
3138  goto end;
3139  }
3140 
3141  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess,
3142  FileObject, &fileref->fcb->share_access);
3143  } else {
3144  ACCESS_MASK granted_access;
3145 
3146  Status = check_file_name_valid(&fpus, false, false);
3147  if (!NT_SUCCESS(Status))
3148  goto end;
3149 
3150  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3151 
3152  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
3155  &granted_access, &Status)) {
3156  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3157  goto end;
3158  }
3159 
3160  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3161 
3162  if (Irp->AssociatedIrp.SystemBuffer && IrpSp->Parameters.Create.EaLength > 0) {
3163  ULONG offset;
3164 
3165  Status = IoCheckEaBufferValidity(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength, &offset);
3166  if (!NT_SUCCESS(Status)) {
3167  ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset);
3168  goto end;
3169  }
3170  }
3171 
3172  Status = file_create2(Irp, Vcb, &fpus, parfileref, options, Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength,
3173  &fileref, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3174 
3176  *existing_fileref = fileref;
3177  goto end;
3178  } else if (!NT_SUCCESS(Status)) {
3179  ERR("file_create2 returned %08lx\n", Status);
3180  goto end;
3181  }
3182 
3183  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess, FileObject, &fileref->fcb->share_access);
3184 
3187  }
3188 
3189  FileObject->FsContext = fileref->fcb;
3190 
3192  if (!ccb) {
3193  ERR("out of memory\n");
3195  fileref->deleted = true;
3196  fileref->fcb->deleted = true;
3197 
3198  if (stream.Length == 0) {
3199  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3200  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3201  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3202  }
3203 
3204  free_fileref(fileref);
3205  goto end;
3206  }
3207 
3208  RtlZeroMemory(ccb, sizeof(*ccb));
3209 
3210  ccb->fileref = fileref;
3211 
3213  ccb->NodeSize = sizeof(*ccb);
3214  ccb->disposition = disposition;
3215  ccb->options = options;
3216  ccb->query_dir_offset = 0;
3218  ccb->has_wildcard = false;
3219  ccb->specific_file = false;
3220  ccb->access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3222  ccb->reserving = false;
3223  ccb->lxss = called_from_lxss();
3224 
3225 #ifdef DEBUG_FCB_REFCOUNTS
3226  oc = InterlockedIncrement(&fileref->open_count);
3227  ERR("fileref %p: open_count now %i\n", fileref, oc);
3228 #else
3229  InterlockedIncrement(&fileref->open_count);
3230 #endif
3231  InterlockedIncrement(&Vcb->open_files);
3232 
3233  FileObject->FsContext2 = ccb;
3234 
3235  FileObject->SectionObjectPointer = &fileref->fcb->nonpaged->segment_object;
3236 
3237  // FIXME - ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT
3239  if (acec->ReparseBufferLength > sizeof(uint32_t) && *(uint32_t*)acec->ReparseBuffer == IO_REPARSE_TAG_SYMLINK) {
3241  fileref->fcb->type = BTRFS_TYPE_FILE;
3242  fileref->fcb->atts &= ~FILE_ATTRIBUTE_DIRECTORY;
3243  }
3244 
3245  if (fileref->fcb->type == BTRFS_TYPE_SOCKET || fileref->fcb->type == BTRFS_TYPE_FIFO ||
3246  fileref->fcb->type == BTRFS_TYPE_CHARDEV || fileref->fcb->type == BTRFS_TYPE_BLOCKDEV) {
3247  // NOP. If called from LXSS, humour it - we hardcode the values elsewhere.
3248  } else {
3250  if (!NT_SUCCESS(Status)) {
3251  ERR("set_reparse_point2 returned %08lx\n", Status);
3252  fileref->deleted = true;
3253  fileref->fcb->deleted = true;
3254 
3255  if (stream.Length == 0) {
3256  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3257  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3258  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3259  }
3260 
3261  free_fileref(fileref);
3262  return Status;
3263  }
3264  }
3265 
3267  }
3268 
3273  fileref->fcb->case_sensitive = true;
3274  ccb->case_sensitive = true;
3275  }
3276 
3278  }
3279 
3281  }
3282 
3283  fileref->dc->type = fileref->fcb->type;
3284 
3285 end:
3286  if (fpus.Buffer)
3287  ExFreePool(fpus.Buffer);
3288 
3289  if (parfileref && !loaded_related)
3290  free_fileref(parfileref);
3291 
3292  return Status;
3293 }
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3266
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
struct _file_ref * parent
Definition: btrfs_drv.h:352
static const GUID GUID_ECP_QUERY_ON_CREATE
Definition: create.c:80
NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _Out_ file_ref **pfr, _In_ PUNICODE_STRING fnus, _In_opt_ file_ref *related, _In_ bool parent, _Out_opt_ USHORT *parsed, _Out_opt_ ULONG *fn_offset, _In_ POOL_TYPE pooltype, _In_ bool case_sensitive, _In_opt_ PIRP Irp)
Definition: create.c:1690
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
ULONG options
Definition: btrfs_drv.h:374
USHORT MaximumLength
Definition: env_spec_w32.h:370
static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension *Vcb, _In_ PUNICODE_STRING fpus, _In_ file_ref *parfileref, _In_ ULONG options, _In_reads_bytes_opt_(ealen) FILE_FULL_EA_INFORMATION *ea, _In_ ULONG ealen, _Out_ file_ref **pfr, bool case_sensitive, _In_ LIST_ENTRY *rollback)
Definition: create.c:2182
Iosb Status
Definition: create.c:4287
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define __S_IFSOCK
Definition: btrfs_drv.h:1750
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
#define ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED
Definition: create.c:43
ANSI_STRING utf8
Definition: btrfs_drv.h:254
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define ATOMIC_CREATE_ECP_IN_FLAG_OP_FLAGS_SPECIFIED
Definition: create.c:37
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3516
LONG open_count
Definition: btrfs_drv.h:351
ACCESS_MASK access
Definition: btrfs_drv.h:382
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define FILE_NOTIFY_CHANGE_DIR_NAME
void send_notification_fileref(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1486
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1816
bool has_wildcard
Definition: btrfs_drv.h:377
UNICODE_STRING query_string
Definition: btrfs_drv.h:376
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:87
PREPARSE_DATA_BUFFER ReparseBuffer
Definition: create.c:62
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1636
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:293
#define FILE_ADD_FILE
Definition: nt_native.h:632
_In_ PIRP Irp
Definition: csq.h:116
static __inline bool is_subvol_readonly(root *r, PIRP Irp)
Definition: btrfs_drv.h:1025
static const GUID GUID_ECP_ATOMIC_CREATE
Definition: create.c:79
long LONG
Definition: pedump.c:60
#define ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED
Definition: create.c:41
#define FILE_ACTION_MODIFIED
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
bool specific_file
Definition: btrfs_drv.h:378
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
uint8_t type
Definition: btrfs_drv.h:291
int options
Definition: main.c:106
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:84
#define ATOMIC_CREATE_ECP_OUT_OP_FLAG_CASE_SENSITIVE_FLAGS_SET
Definition: create.c:44
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 GLint GLint j
Definition: glfuncs.h:250
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET
Definition: create.c:40
Status
Definition: gdiplustypes.h:24
bool deleted
Definition: btrfs_drv.h:347
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
uint64_t st_size
Definition: btrfs.h:289
#define TRACE(s)
Definition: solgame.cpp:4
#define SL_IGNORE_READONLY_ATTRIBUTE
Definition: create.c:47
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, file_ref **pfileref, file_ref **pparfileref, PUNICODE_STRING fpus, PUNICODE_STRING stream, PIRP Irp, ULONG options, POOL_TYPE pool_type, bool case_sensitive, LIST_ENTRY *rollback)
Definition: create.c:2635
INT POOL_TYPE
Definition: typedefs.h:78
GLintptr offset
Definition: glext.h:5920
static const GUID GUID_ECP_CREATE_REDIRECTION
Definition: create.c:81
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_CS_FLAG_CASE_SENSITIVE_DIR
Definition: btrfs_drv.h:165
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED
Definition: create.c:36
bool case_sensitive
Definition: btrfs_drv.h:310
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __S_IFIFO
Definition: btrfs_drv.h:1748
#define __S_IFCHR
Definition: btrfs_drv.h:1745
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
USHORT NodeType
Definition: btrfs_drv.h:371
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
dir_child * dc
Definition: btrfs_drv.h:353
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
bool case_sensitive
Definition: btrfs_drv.h:386
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
fcb * fcb
Definition: btrfs_drv.h:342
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:903
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define InterlockedIncrement
Definition: armddk.h:53
ULONG atts
Definition: btrfs_drv.h:297
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
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
unsigned short USHORT
Definition: pedump.c:61
bool deleted
Definition: btrfs_drv.h:295
uint8_t type
Definition: btrfs_drv.h:253
ULONG disposition
Definition: btrfs_drv.h:373
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
struct _root * subvol
Definition: btrfs_drv.h:288
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
UINT32 uint32_t
Definition: types.h:75
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1825
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define called_from_lxss()
Definition: create.c:2999
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
Definition: btrfs.c:96
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSTATUS set_reparse_point2(fcb *fcb, REPARSE_DATA_BUFFER *rdb, ULONG buflen, ccb *ccb, file_ref *fileref, PIRP Irp, LIST_ENTRY *rollback)
Definition: reparse.c:307
tFsRtlGetEcpListFromIrp fFsRtlGetEcpListFromIrp
Definition: btrfs.c:95
bool reserving
Definition: btrfs_drv.h:381
#define __S_IFBLK
Definition: btrfs_drv.h:1746
bool lxss
Definition: btrfs_drv.h:391
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
SHARE_ACCESS share_access
Definition: btrfs_drv.h:298
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:383
NTSTATUS check_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5766
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
CSHORT NodeSize
Definition: btrfs_drv.h:372
uint64_t query_dir_offset
Definition: btrfs_drv.h:375
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
HRESULT Create([out]ITransactionReceiver **ppReceiver)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t st_mode
Definition: btrfs.h:295

Referenced by open_file().

◆ file_create2()

static NTSTATUS file_create2 ( _In_ PIRP  Irp,
_Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension Vcb,
_In_ PUNICODE_STRING  fpus,
_In_ file_ref parfileref,
_In_ ULONG  options,
_In_reads_bytes_opt_(ealen) FILE_FULL_EA_INFORMATION ea,
_In_ ULONG  ealen,
_Out_ file_ref **  pfr,
bool  case_sensitive,
_In_ LIST_ENTRY rollback 
)
static

Definition at line 2182 of file create.c.

2184  {
2185  NTSTATUS Status;
2186  fcb* fcb;
2187  ULONG utf8len;
2188  char* utf8 = NULL;
2189  uint64_t inode;
2190  uint8_t type;
2192  BTRFS_TIME now;
2195  USHORT defda;
2196  file_ref* fileref;
2197  dir_child* dc;
2198  ANSI_STRING utf8as;
2199  LIST_ENTRY* lastle = NULL;
2200  file_ref* existing_fileref = NULL;
2201 #ifdef DEBUG_FCB_REFCOUNTS
2202  LONG rc;
2203 #endif
2204 
2205  if (parfileref->fcb == Vcb->dummy_fcb)
2206  return STATUS_ACCESS_DENIED;
2207 
2209  return STATUS_INVALID_PARAMETER;
2210 
2211  Status = utf16_to_utf8(NULL, 0, &utf8len, fpus->Buffer, fpus->Length);
2212  if (!NT_SUCCESS(Status)) {
2213  ERR("utf16_to_utf8 returned %08lx\n", Status);
2214  return Status;
2215  }
2216 
2217  utf8 = ExAllocatePoolWithTag(pool_type, utf8len + 1, ALLOC_TAG);
2218  if (!utf8) {
2219  ERR("out of memory\n");
2221  }
2222 
2223  Status = utf16_to_utf8(utf8, utf8len, &utf8len, fpus->Buffer, fpus->Length);
2224  if (!NT_SUCCESS(Status)) {
2225  ERR("utf16_to_utf8 returned %08lx\n", Status);
2226  ExFreePool(utf8);
2227  return Status;
2228  }
2229 
2230  utf8[utf8len] = 0;
2231 
2234 
2235  TRACE("create file %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer);
2236  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2237  TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) was %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size);
2238  parfileref->fcb->inode_item.st_size += utf8len * 2;
2239  TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) now %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size);
2240  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2241  parfileref->fcb->inode_item.sequence++;
2242  parfileref->fcb->inode_item.st_ctime = now;
2243  parfileref->fcb->inode_item.st_mtime = now;
2244  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2245 
2246  parfileref->fcb->inode_item_changed = true;
2247  mark_fcb_dirty(parfileref->fcb);
2248 
2249  inode = InterlockedIncrement64(&parfileref->fcb->subvol->lastinode);
2250 
2252 
2253  // FIXME - link FILE_ATTRIBUTE_READONLY to st_mode
2254 
2255  TRACE("requested attributes = %x\n", IrpSp->Parameters.Create.FileAttributes);
2256 
2257  defda = 0;
2258 
2259  if (utf8[0] == '.')
2260  defda |= FILE_ATTRIBUTE_HIDDEN;
2261 
2262  if (options & FILE_DIRECTORY_FILE) {
2263  defda |= FILE_ATTRIBUTE_DIRECTORY;
2264  IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
2265  } else
2266  IrpSp->Parameters.Create.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
2267 
2268  if (!(IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2269  IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
2270  defda |= FILE_ATTRIBUTE_ARCHIVE;
2271  }
2272 
2273  TRACE("defda = %x\n", defda);
2274 
2275  if (IrpSp->Parameters.Create.FileAttributes == FILE_ATTRIBUTE_NORMAL)
2276  IrpSp->Parameters.Create.FileAttributes = defda;
2277 
2278  fcb = create_fcb(Vcb, pool_type);
2279  if (!fcb) {
2280  ERR("out of memory\n");
2281  ExFreePool(utf8);
2282 
2283  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2284  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2285  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2286 
2288  }
2289 
2290  fcb->Vcb = Vcb;
2291 
2294 
2295  fcb->inode_item.generation = Vcb->superblock.generation;
2296  fcb->inode_item.transid = Vcb->superblock.generation;
2297  fcb->inode_item.st_size = 0;
2298  fcb->inode_item.st_blocks = 0;
2299  fcb->inode_item.block_group = 0;
2300  fcb->inode_item.st_nlink = 1;
2301  fcb->inode_item.st_gid = GID_NOBODY; // FIXME?
2302  fcb->inode_item.st_mode = inherit_mode(parfileref->fcb, type == BTRFS_TYPE_DIRECTORY); // use parent's permissions by default
2303  fcb->inode_item.st_rdev = 0;
2304  fcb->inode_item.flags = 0;
2305  fcb->inode_item.sequence = 1;
2309  fcb->inode_item.otime = now;
2310 
2311  if (type == BTRFS_TYPE_DIRECTORY)
2313  else {
2315  fcb->inode_item.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); // remove executable bit if not directory
2316  }
2317 
2318  if (IrpSp->Flags & SL_OPEN_PAGING_FILE) {
2320  } else {
2321  // inherit nodatacow flag from parent directory
2322  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_NODATACOW) {
2324 
2325  if (type != BTRFS_TYPE_DIRECTORY)
2327  }
2328 
2329  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_COMPRESS)
2331  }
2332 
2333  fcb->prop_compression = parfileref->fcb->prop_compression;
2335 
2336  fcb->inode_item_changed = true;
2337 
2338  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2339  fcb->Header.AllocationSize.QuadPart = 0;
2340  fcb->Header.FileSize.QuadPart = 0;
2341  fcb->Header.ValidDataLength.QuadPart = 0;
2342 
2343  fcb->atts = IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL;
2344  fcb->atts_changed = fcb->atts != defda;
2345 
2346 #ifdef DEBUG_FCB_REFCOUNTS
2347  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2348  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2349 #else
2350  InterlockedIncrement(&parfileref->fcb->refcount);
2351 #endif
2352  fcb->subvol = parfileref->fcb->subvol;
2353  fcb->inode = inode;
2354  fcb->type = type;
2355  fcb->created = true;
2356  fcb->deleted = true;
2357 
2358  fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&inode, sizeof(uint64_t));
2359 
2360  acquire_fcb_lock_exclusive(Vcb);
2361 
2362  if (fcb->subvol->fcbs_ptrs[fcb->hash >> 24]) {
2363  LIST_ENTRY* le = fcb->subvol->fcbs_ptrs[fcb->hash >> 24];
2364 
2365  while (le != &fcb->subvol->fcbs) {
2366  struct _fcb* fcb2 = CONTAINING_RECORD(le, struct _fcb, list_entry);
2367 
2368  if (fcb2->hash > fcb->hash) {
2369  lastle = le->Blink;
2370  break;
2371  }
2372 
2373  le = le->Flink;
2374  }
2375  }
2376 
2377  if (!lastle) {
2378  uint8_t c = fcb->hash >> 24;
2379 
2380  if (c != 0xff) {
2381  uint8_t d = c + 1;
2382 
2383  do {
2384  if (fcb->subvol->fcbs_ptrs[d]) {
2385  lastle = fcb->subvol->fcbs_ptrs[d]->Blink;
2386  break;
2387  }
2388 
2389  d++;
2390  } while (d != 0);
2391  }
2392  }
2393 
2394  if (lastle) {
2395  InsertHeadList(lastle, &fcb->list_entry);
2396 
2397  if (lastle == &fcb->subvol->fcbs || (CONTAINING_RECORD(lastle, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2398  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2399  } else {
2400  InsertTailList(&fcb->subvol->fcbs, &fcb->list_entry);
2401 
2402  if (fcb->list_entry.Blink == &fcb->subvol->fcbs || (CONTAINING_RECORD(fcb->list_entry.Blink, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2403  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2404  }
2405 
2406  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2407 
2408  fcb->subvol->fcbs_version++;
2409 
2410  release_fcb_lock(Vcb);
2411 
2413 
2414  Status = fcb_get_new_sd(fcb, parfileref, IrpSp->Parameters.Create.SecurityContext->AccessState);
2415 
2416  if (!NT_SUCCESS(Status)) {
2417  ERR("fcb_get_new_sd returned %08lx\n", Status);
2418  free_fcb(fcb);
2419 
2420  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2421  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2422  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2423 
2424  ExFreePool(utf8);
2425 
2426  return Status;
2427  }
2428 
2429  fcb->sd_dirty = true;
2430 
2431  if (ea && ealen > 0) {
2433  if (!NT_SUCCESS(Status)) {
2434  ERR("file_create_parse_ea returned %08lx\n", Status);
2435  free_fcb(fcb);
2436 
2437  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2438  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2439  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2440 
2441  ExFreePool(utf8);
2442 
2443  return Status;
2444  }
2445  }
2446 
2448  if (!fileref) {
2449  ERR("out of memory\n");
2450  free_fcb(fcb);
2451 
2452  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2453  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2454  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2455 
2456  ExFreePool(utf8);
2457 
2459  }
2460 
2461  fileref->fcb = fcb;
2462 
2463  if (Irp->Overlay.AllocationSize.QuadPart > 0 && !write_fcb_compressed(fcb) && fcb->type != BTRFS_TYPE_DIRECTORY) {
2464  Status = extend_file(fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback);
2465 
2466  if (!NT_SUCCESS(Status)) {
2467  ERR("extend_file returned %08lx\n", Status);
2469 
2470  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2471  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2472  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2473 
2474  ExFreePool(utf8);
2475 
2476  return Status;
2477  }
2478  }
2479 
2480  if (fcb->type == BTRFS_TYPE_DIRECTORY) {
2482  if (!fcb->hash_ptrs) {
2483  ERR("out of memory\n");
2485 
2486  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2487  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2488  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2489 
2490  ExFreePool(utf8);
2491 
2493  }
2494 
2495  RtlZeroMemory(fcb->hash_ptrs, sizeof(LIST_ENTRY*) * 256);
2496 
2498  if (!fcb->hash_ptrs_uc) {
2499  ERR("out of memory\n");
2501 
2502  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2503  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2504  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2505 
2506  ExFreePool(utf8);
2507 
2509  }
2510 
2511  RtlZeroMemory(fcb->hash_ptrs_uc, sizeof(LIST_ENTRY*) * 256);
2512  }
2513 
2514  fcb->deleted = false;
2515 
2516  fileref->created = true;
2517 
2518  fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2519  fcb->subvol->root_item.ctime = now;
2520 
2521  utf8as.Buffer = utf8;
2522  utf8as.Length = utf8as.MaximumLength = (uint16_t)utf8len;
2523 
2524  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2525 
2526  // check again doesn't already exist
2527  if (case_sensitive) {
2528  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpus->Buffer, fpus->Length);
2529 
2530  if (parfileref->fcb->hash_ptrs[dc_hash >> 24]) {
2531  LIST_ENTRY* le = parfileref->fcb->hash_ptrs[dc_hash >> 24];
2532  while (le != &parfileref->fcb->dir_children_hash) {
2533  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
2534 
2535  if (dc->hash == dc_hash && dc->name.Length == fpus->Length && RtlCompareMemory(dc->name.Buffer, fpus->Buffer, fpus->Length) == fpus->Length) {
2536  existing_fileref = dc->fileref;
2537  break;
2538  } else if (dc->hash > dc_hash)
2539  break;
2540 
2541  le = le->Flink;
2542  }
2543  }
2544  } else {
2545  UNICODE_STRING fpusuc;
2546 
2547  Status = RtlUpcaseUnicodeString(&fpusuc, fpus, true);
2548  if (!NT_SUCCESS(Status)) {
2549  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2550  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
2552 
2553  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2554  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2555  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2556 
2557  ExFreePool(utf8);
2558 
2559  return Status;
2560  }
2561 
2562  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length);
2563 
2564  if (parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]) {
2565  LIST_ENTRY* le = parfileref->fcb->hash_ptrs_uc[dc_hash >> 24];
2566  while (le != &parfileref->fcb->dir_children_hash_uc) {
2567  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
2568 
2569  if (dc->hash_uc == dc_hash && dc->name.Length == fpusuc.Length && RtlCompareMemory(dc->name.Buffer, fpusuc.Buffer, fpusuc.Length) == fpusuc.Length) {
2570  existing_fileref = dc->fileref;
2571  break;
2572  } else if (dc->hash_uc > dc_hash)
2573  break;
2574 
2575  le = le->Flink;
2576  }
2577  }
2578 
2579  ExFreePool(fpusuc.Buffer);
2580  }
2581 
2582  if (existing_fileref) {
2583  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2585 
2586  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2587  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2588  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2589 
2590  ExFreePool(utf8);
2591 
2592  increase_fileref_refcount(existing_fileref);
2593  *pfr = existing_fileref;
2594 
2596  }
2597 
2598  Status = add_dir_child(parfileref->fcb, fcb->inode, false, &utf8as, fpus, fcb->type, &dc);
2599  if (!NT_SUCCESS(Status)) {
2600  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2601  ERR("add_dir_child returned %08lx\n", Status);
2603 
2604  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2605  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2606  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2607 
2608  ExFreePool(utf8);
2609 
2610  return Status;
2611  }
2612 
2613  fileref->parent = parfileref;
2614  fileref->dc = dc;
2615  dc->fileref = fileref;
2616 
2617  if (type == BTRFS_TYPE_DIRECTORY)
2618  fileref->fcb->fileref = fileref;
2619 
2620  InsertTailList(&parfileref->children, &fileref->list_entry);
2621  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2622 
2623  ExFreePool(utf8);
2624 
2626  increase_fileref_refcount(parfileref);
2627 
2628  *pfr = fileref;
2629 
2630  TRACE("created new file in subvol %I64x, inode %I64x\n", fcb->subvol->id, fcb->inode);
2631 
2632  return STATUS_SUCCESS;
2633 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
file_ref * create_fileref(device_extension *Vcb)
Definition: create.c:160
BTRFS_TIME otime
Definition: btrfs.h:304
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1703
#define BTRFS_INODE_NODATACOW
Definition: propsheet.h:77
Iosb Status
Definition: create.c:4287
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FSRTL_FLAG2_IS_PAGING_FILE
Definition: fsrtltypes.h:57
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
enum prop_compression_type prop_compression
Definition: btrfs_drv.h:307
uint32_t inherit_mode(fcb *parfcb, bool is_dir)
Definition: create.c:1948
#define S_IFREG
Definition: ext2fs.h:356
__u16 time
Definition: mkdosfs.c:366
uint64_t block_group
Definition: btrfs.h:291
#define uint16_t
Definition: nsiface.idl:60
void reap_fileref(device_extension *Vcb, file_ref *fr)
Definition: btrfs.c:1844
#define InsertTailList(ListHead, Entry)
uint32_t flags
Definition: btrfs.h:297
bool atts_changed
Definition: btrfs_drv.h:322
BTRFS_TIME st_ctime
Definition: btrfs.h:302
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:337
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:91
Definition: fs.h:78
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
uint32_t st_gid
Definition: btrfs.h:294
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1686
_In_ PIRP Irp
Definition: csq.h:116
#define BTRFS_INODE_COMPRESS
Definition: propsheet.h:87
long LONG
Definition: pedump.c:60
LIST_ENTRY list_entry
Definition: btrfs_drv.h:336
#define S_IXOTH
Definition: propsheet.h:61
uint64_t sequence
Definition: btrfs.h:299
uint32_t st_nlink
Definition: btrfs.h:292
time_t now
Definition: finger.c:65
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:318
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:670
NTSTATUS NTSTATUS NTSTATUS NTSTATUS extend_file(fcb *fcb, file_ref *fileref, uint64_t end, bool prealloc, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
uint8_t type
Definition: btrfs_drv.h:291
BTRFS_TIME st_mtime
Definition: btrfs.h:303
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1729
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
bool prop_compression_changed
Definition: btrfs_drv.h:326
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define S_IFDIR
Definition: acwin.h:115
static __inline bool write_fcb_compressed(fcb *fcb)
Definition: btrfs_drv.h:1699
ULONG ealen
Definition: btrfs_drv.h:303
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define S_IXGRP
Definition: propsheet.h:49
uint64_t st_size
Definition: btrfs.h:289
#define TRACE(s)
Definition: solgame.cpp:4
struct _fcb fcb
Definition: btrfs_drv.h:1355
bool sd_dirty
Definition: btrfs_drv.h:321
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
INT POOL_TYPE
Definition: typedefs.h:78
uint64_t inode
Definition: btrfs_drv.h:289
uint64_t st_rdev
Definition: btrfs.h:296
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
const GLubyte * c
Definition: glext.h:8905
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
struct _file_ref * fileref
Definition: btrfs_drv.h:305
bool case_sensitive
Definition: btrfs_drv.h:310
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
uint32_t hash
Definition: btrfs_drv.h:290
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
BTRFS_TIME st_atime
Definition: btrfs.h:301
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define S_IXUSR
Definition: propsheet.h:37
crc_func calc_crc32c
Definition: crc32c.c:23
bool created
Definition: btrfs_drv.h:328
Definition: typedefs.h:119
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1677
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
uint64_t generation
Definition: btrfs.h:287
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t st_blocks
Definition: btrfs.h:290
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
NTSTATUS add_dir_child(fcb *fcb, uint64_t inode, bool subvol, PANSI_STRING utf8, PUNICODE_STRING name, uint8_t type, dir_child **pdc)
Definition: create.c:1871
UINT64 uint64_t
Definition: types.h:77
#define InterlockedIncrement
Definition: armddk.h:53
ULONG atts
Definition: btrfs_drv.h:297
unsigned short USHORT
Definition: pedump.c:61
bool deleted
Definition: btrfs_drv.h:295
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
uint64_t transid
Definition: btrfs.h:288
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
struct _root * subvol
Definition: btrfs_drv.h:288
Definition: list.h:27
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
UINT32 uint32_t
Definition: types.h:75
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:981
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:317
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR dc[]
#define STATUS_SUCCESS
Definition: shellext.h:65
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: _hash_fun.h:40
bool inode_item_changed
Definition: btrfs_drv.h:306
NTSTATUS fcb_get_new_sd(fcb *fcb, file_ref *parfileref, ACCESS_STATE *as)
Definition: security.c:988
HRESULT Create([out]ITransactionReceiver **ppReceiver)
#define BTRFS_INODE_NOCOMPRESS
Definition: propsheet.h:79
#define GID_NOBODY
Definition: btrfs_drv.h:91
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
static NTSTATUS file_create_parse_ea(fcb *fcb, FILE_FULL_EA_INFORMATION *ea)
Definition: create.c:1964
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define d
Definition: ke_i.h:81
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t st_mode
Definition: btrfs.h:295

Referenced by create_stream(), and file_create().

◆ file_create_parse_ea()

static NTSTATUS file_create_parse_ea ( fcb fcb,
FILE_FULL_EA_INFORMATION ea 
)
static

Definition at line 1964 of file create.c.

1964  {
1965  NTSTATUS Status;
1966  LIST_ENTRY ealist, *le;
1967  uint16_t size = 0;
1968  char* buf;
1969 
1970  InitializeListHead(&ealist);
1971 
1972  do {
1973  STRING s;
1974  bool found = false;
1975 
1976  s.Length = s.MaximumLength = ea->EaNameLength;
1977  s.Buffer = ea->EaName;
1978 
1979  RtlUpperString(&s, &s);
1980 
1981  le = ealist.Flink;
1982  while (le != &ealist) {
1984 
1985  if (item->name.Length == s.Length && RtlCompareMemory(item->name.Buffer, s.Buffer, s.Length) == s.Length) {
1986  item->flags = ea->Flags;
1987  item->value.Length = item->value.MaximumLength = ea->EaValueLength;
1988  item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
1989  found = true;
1990  break;
1991  }
1992 
1993  le = le->Flink;
1994  }
1995 
1996  if (!found) {
1998  if (!item) {
1999  ERR("out of memory\n");
2001  goto end;
2002  }
2003 
2004  item->name.Length = item->name.MaximumLength = ea->EaNameLength;
2005  item->name.Buffer = ea->EaName;
2006 
2007  item->value.Length = item->value.MaximumLength = ea->EaValueLength;
2008  item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
2009 
2010  item->flags = ea->Flags;
2011 
2012  InsertTailList(&ealist, &item->list_entry);
2013  }
2014 
2015  if (ea->NextEntryOffset == 0)
2016  break;
2017 
2018  ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
2019  } while (true);
2020 
2021  // handle LXSS values
2022  le = ealist.Flink;
2023  while (le != &ealist) {
2024  LIST_ENTRY* le2 = le->Flink;
2026 
2027  if (item->name.Length == sizeof(lxuid) - 1 && RtlCompareMemory(item->name.Buffer, lxuid, item->name.Length) == item->name.Length) {
2028  if (item->value.Length < sizeof(uint32_t)) {
2029  ERR("uid value was shorter than expected\n");
2031  goto end;
2032  }
2033 
2034  RtlCopyMemory(&fcb->inode_item.st_uid, item->value.Buffer, sizeof(uint32_t));
2035  fcb->sd_dirty = true;
2036  fcb->sd_deleted = false;
2037 
2038  RemoveEntryList(&item->list_entry);
2039  ExFreePool(item);
2040  } else if (item->name.Length == sizeof(lxgid) - 1 && RtlCompareMemory(item->name.Buffer, lxgid, item->name.Length) == item->name.Length) {
2041  if (item->value.Length < sizeof(uint32_t)) {
2042  ERR("gid value was shorter than expected\n");
2044  goto end;
2045  }
2046 
2047  RtlCopyMemory(&fcb->inode_item.st_gid, item->value.Buffer, sizeof(uint32_t));
2048 
2049  RemoveEntryList(&item->list_entry);
2050  ExFreePool(item);
2051  } else if (item->name.Length == sizeof(lxmod) - 1 && RtlCompareMemory(item->name.Buffer, lxmod, item->name.Length) == item->name.Length) {
2053  uint32_t val;
2054 
2055  if (item->value.Length < sizeof(uint32_t)) {
2056  ERR("mode value was shorter than expected\n");
2058  goto end;
2059  }
2060 
2061  val = *(uint32_t*)item->value.Buffer;
2062 
2063  fcb->inode_item.st_mode &= ~allowed;
2064  fcb->inode_item.st_mode |= val & allowed;
2065 
2067  if (__S_ISTYPE(val, __S_IFCHR)) {
2071  } else if (__S_ISTYPE(val, __S_IFBLK)) {
2075  } else if (__S_ISTYPE(val, __S_IFIFO)) {
2079  } else if (__S_ISTYPE(val, __S_IFSOCK)) {
2083  }
2084  }
2085 
2086  RemoveEntryList(&item->list_entry);
2087  ExFreePool(item);
2088  } else if (item->name.Length == sizeof(lxdev) - 1 && RtlCompareMemory(item->name.Buffer, lxdev, item->name.Length) == item->name.Length) {
2089  uint32_t major, minor;
2090 
2091  if (item->value.Length < sizeof(uint64_t)) {
2092  ERR("dev value was shorter than expected\n");
2094  goto end;
2095  }
2096 
2097  major = *(uint32_t*)item->value.Buffer;
2098  minor = *(uint32_t*)&item->value.Buffer[sizeof(uint32_t)];
2099 
2100  fcb->inode_item.st_rdev = (minor & 0xFFFFF) | ((major & 0xFFFFFFFFFFF) << 20);
2101 
2102  RemoveEntryList(&item->list_entry);
2103  ExFreePool(item);
2104  }
2105 
2106  le = le2;
2107  }
2108 
2110  fcb->inode_item.st_rdev = 0;
2111 
2112  if (IsListEmpty(&ealist))
2113  return STATUS_SUCCESS;
2114 
2115  le = ealist.Flink;
2116  while (le != &ealist) {
2118 
2119  if (size % 4 > 0)
2120  size += 4 - (size % 4);
2121 
2122  size += (uint16_t)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + item->name.Length + 1 + item->value.Length;
2123 
2124  le = le->Flink;
2125  }
2126 
2128  if (!buf) {
2129  ERR("out of memory\n");
2131  goto end;
2132  }
2133 
2135  fcb->ea_xattr.Buffer = buf;
2136 
2137  fcb->ealen = 4;
2138  ea = NULL;
2139 
2140  le = ealist.Flink;
2141  while (le != &ealist) {
2143 
2144  if (ea) {
2146 
2147  if (ea->NextEntryOffset % 4 > 0)
2148  ea->NextEntryOffset += 4 - (ea->NextEntryOffset % 4);
2149 
2150  ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
2151  } else
2153 
2154  ea->NextEntryOffset = 0;
2155  ea->Flags = item->flags;
2156  ea->EaNameLength = (UCHAR)item->name.Length;
2157  ea->EaValueLength = item->value.Length;
2158 
2159  RtlCopyMemory(ea->EaName, item->name.Buffer, item->name.Length);
2160  ea->EaName[item->name.Length] = 0;
2161  RtlCopyMemory(&ea->EaName[item->name.Length + 1], item->value.Buffer, item->value.Length);
2162 
2163  fcb->ealen += 5 + item->name.Length + item->value.Length;
2164 
2165  le = le->Flink;
2166  }
2167 
2168  fcb->ea_changed = true;
2169 
2171 
2172 end:
2173  while (!IsListEmpty(&ealist)) {
2175 
2176  ExFreePool(item);
2177  }
2178 
2179  return Status;
2180 }
NTSYSAPI VOID NTAPI RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
static const char lxuid[]
Definition: btrfs_drv.h:1278
#define __S_ISTYPE(mode, mask)
Definition: btrfs_drv.h:1751
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
#define S_ISGID
Definition: propsheet.h:69
static const char lxdev[]
Definition: btrfs_drv.h:1281
Iosb Status
Definition: create.c:4287
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
if(OpenRequiringOplock &&(Iosb.Status==STATUS_SUCCESS))
Definition: create.c:4300
#define __S_IFSOCK
Definition: btrfs_drv.h:1750
LONG NTSTATUS
Definition: precomp.h:26
bool sd_deleted
Definition: btrfs_drv.h:321
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
ANSI_STRING ea_xattr
Definition: btrfs_drv.h:302
unsigned short int uint16_t
Definition: acefiex.h:54
#define uint16_t
Definition: nsiface.idl:60
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define ALLOC_TAG
Definition: btrfs_drv.h:87
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
bool ea_changed
Definition: btrfs_drv.h:325
uint32_t st_gid
Definition: btrfs.h:294
#define S_IRGRP
Definition: propsheet.h:41
#define S_IXOTH
Definition: propsheet.h:61
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
ULONG major
#define offsetof(TYPE, MEMBER)
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define __S_IFMT
Definition: btrfs_drv.h:1743
uint8_t type
Definition: btrfs_drv.h:291
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
GLuint GLfloat * val
Definition: glext.h:7180
ULONG ealen
Definition: btrfs_drv.h:303
Status
Definition: gdiplustypes.h:24
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define S_IWGRP
Definition: propsheet.h:45
#define S_IXGRP
Definition: propsheet.h:49
GLsizeiptr size
Definition: glext.h:5919
#define S_IWUSR
Definition: propsheet.h:33
bool sd_dirty
Definition: btrfs_drv.h:321
uint64_t st_rdev
Definition: btrfs.h:296
#define __S_IFIFO
Definition: btrfs_drv.h:1748
#define __S_IFCHR
Definition: btrfs_drv.h:1745
GLuint GLuint end
Definition: gl.h:1545
std::wstring STRING
Definition: fontsub.cpp:33
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define S_IXUSR
Definition: propsheet.h:37
#define S_IROTH
Definition: propsheet.h:53
GLdouble s
Definition: gl.h:2039
Definition: typedefs.h:119
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
#define S_IWOTH
Definition: propsheet.h:57
#define ERR(fmt,...)
Definition: debug.h:110
UINT64 uint64_t
Definition: types.h:77
static ATOM item
Definition: dde.c:856
static const char lxgid[]
Definition: btrfs_drv.h:1279
#define S_ISUID
Definition: propsheet.h:65
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static const char lxmod[]
Definition: btrfs_drv.h:1280
#define S_IRUSR
Definition: propsheet.h:29
Definition: list.h:27
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define __S_IFBLK
Definition: btrfs_drv.h:1746
#define STATUS_SUCCESS
Definition: shellext.h:65
#define uint32_t
Definition: nsiface.idl:61
uint32_t st_uid
Definition: btrfs.h:293
ULONG minor
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define S_ISVTX
Definition: propsheet.h:73
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t st_mode
Definition: btrfs.h:295

Referenced by file_create2().

◆ find_file_in_dir()

NTSTATUS find_file_in_dir ( PUNICODE_STRING  filename,
fcb fcb,
root **  subvol,
uint64_t inode,
dir_child **  pdc,
bool  case_sensitive 
)

Definition at line 182 of file create.c.

182  {
184  UNICODE_STRING fnus;
185  uint32_t hash;
186  LIST_ENTRY* le;
187  uint8_t c;
188  bool locked = false;
189 
190  if (!case_sensitive) {
191  Status = RtlUpcaseUnicodeString(&fnus, filename, true);
192 
193  if (!NT_SUCCESS(Status)) {
194  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
195  return Status;
196  }
197  } else
198  fnus = *filename;
199 
200  Status = check_file_name_valid(filename, false, false);
201  if (!NT_SUCCESS(Status))
202  return Status;
203 
204  hash = calc_crc32c(0xffffffff, (uint8_t*)fnus.Buffer, fnus.Length);
205 
206  c = hash >> 24;
207 
208  if (!ExIsResourceAcquiredSharedLite(&fcb->nonpaged->dir_children_lock)) {
209  ExAcquireResourceSharedLite(&fcb->nonpaged->dir_children_lock, true);
210  locked = true;
211  }
212 
213  if (case_sensitive) {
214  if (!fcb->hash_ptrs[c]) {
216  goto end;
217  }
218 
219  le = fcb->hash_ptrs[c];
220  while (le != &fcb->dir_children_hash) {
221  dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
222 
223  if (dc->hash == hash) {
224  if (dc->name.Length == fnus.Length && RtlCompareMemory(dc->name.Buffer, fnus.Buffer, fnus.Length) == fnus.Length) {
225  if (dc->key.obj_type == TYPE_ROOT_ITEM) {
226  LIST_ENTRY* le2;
227 
228  *subvol = NULL;
229 
230  le2 = fcb->Vcb->roots.Flink;
231  while (le2 != &fcb->Vcb->roots) {
233 
234  if (r2->id == dc->key.obj_id) {
235  *subvol = r2;
236  break;
237  }
238 
239  le2 = le2->Flink;
240  }
241 
243  } else {
244  *subvol = fcb->subvol;
245  *inode = dc->key.obj_id;
246  }
247 
248  *pdc = dc;
249 
251  goto end;
252  }
253  } else if (dc->hash > hash) {
255  goto end;
256  }
257 
258  le = le->Flink;
259  }
260  } else {
261  if (!fcb->hash_ptrs_uc[c]) {
263  goto end;
264  }
265 
266  le = fcb->hash_ptrs_uc[c];
267  while (le != &fcb->dir_children_hash_uc) {
268  dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
269 
270  if (dc->hash_uc == hash) {
271  if (dc->name_uc.Length == fnus.Length && RtlCompareMemory(dc->name_uc.Buffer, fnus.Buffer, fnus.Length) == fnus.Length) {
272  if (dc->key.obj_type == TYPE_ROOT_ITEM) {
273  LIST_ENTRY* le2;
274 
275  *subvol = NULL;
276 
277  le2 = fcb->Vcb->roots.Flink;
278  while (le2 != &fcb->Vcb->roots) {
280 
281  if (r2->id == dc->key.obj_id) {
282  *subvol = r2;
283  break;
284  }
285 
286  le2 = le2->Flink;
287  }
288 
290  } else {
291  *subvol = fcb->subvol;
292  *inode = dc->key.obj_id;
293  }
294 
295  *pdc = dc;
296 
298  goto end;
299  }
300  } else if (dc->hash_uc > hash) {
302  goto end;
303  }
304 
305  le = le->Flink;
306  }
307  }
308 
310 
311 end:
312  if (locked)
313  ExReleaseResourceLite(&fcb->nonpaged->dir_children_lock);
314 
315  if (!case_sensitive)
316  ExFreePool(fnus.Buffer);
317 
318  return Status;
319 }
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
Iosb Status
Definition: create.c:4287
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
LONG NTSTATUS
Definition: precomp.h:26
const char * filename
Definition: ioapi.h:135
Definition: fs.h:78
int hash
Definition: main.c:58
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:318
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:316
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static DNS_RECORDW r2
Definition: record.c:38
const GLubyte * c
Definition: glext.h:8905
bool case_sensitive
Definition: btrfs_drv.h:310
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLuint GLuint end
Definition: gl.h:1545
crc_func calc_crc32c
Definition: crc32c.c:23
Definition: typedefs.h:119
BYTE uint8_t
Definition: msvideo1.c:66
#define ERR(fmt,...)
Definition: debug.h:110
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
#define TYPE_ROOT_ITEM
Definition: btrfs.h:32
struct _root * subvol
Definition: btrfs_drv.h:288
Definition: list.h:27
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define c
Definition: ke_i.h:80
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1658
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:317
static const WCHAR dc[]
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:315
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS check_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5766
Definition: _hash_fun.h:40
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by mknod(), and open_fileref_child().

◆ get_reparse_block()

static NTSTATUS get_reparse_block ( fcb fcb,
uint8_t **  data 
)
static

Definition at line 3420 of file create.c.

3420  {
3421  NTSTATUS Status;
3422 
3424  ULONG size, bytes_read, i;
3425 
3426  if (fcb->type == BTRFS_TYPE_FILE && fcb->inode_item.st_size < sizeof(ULONG)) {
3427  WARN("file was too short to be a reparse point\n");
3428  return STATUS_INVALID_PARAMETER;
3429  }
3430 
3431  // 0x10007 = 0xffff (maximum length of data buffer) + 8 bytes header
3432  size = (ULONG)min(0x10007, fcb->inode_item.st_size);
3433 
3434  if (size == 0)
3435  return STATUS_INVALID_PARAMETER;
3436 
3438  if (!*data) {
3439  ERR("out of memory\n");
3441  }
3442 
3443  Status = read_file(fcb, *data, 0, size, &bytes_read, NULL);
3444  if (!NT_SUCCESS(Status)) {
3445  ERR("read_file_fcb returned %08lx\n", Status);
3446  ExFreePool(*data);
3447  return Status;
3448  }
3449 
3450  if (fcb->type == BTRFS_TYPE_SYMLINK) {
3451  ULONG stringlen, reqlen;
3452  uint16_t subnamelen, printnamelen;
3453  REPARSE_DATA_BUFFER* rdb;
3454 
3455  Status = utf8_to_utf16(NULL, 0, &stringlen, (char*)*data, bytes_read);
3456  if (!NT_SUCCESS(Status)) {
3457  ERR("utf8_to_utf16 1 returned %08lx\n", Status);
3458  ExFreePool(*data);
3459  return Status;
3460  }
3461 
3462  subnamelen = printnamelen = (USHORT)stringlen;
3463 
3464  reqlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + subnamelen + printnamelen;
3465 
3466  rdb = ExAllocatePoolWithTag(PagedPool, reqlen, ALLOC_TAG);
3467 
3468  if (!rdb) {
3469  ERR("out of memory\n");
3470  ExFreePool(*data);
3472  }
3473 
3475  rdb->ReparseDataLength = (USHORT)(reqlen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
3476  rdb->Reserved = 0;
3477 
3478  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
3479  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = subnamelen;
3480  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = subnamelen;
3481  rdb->SymbolicLinkReparseBuffer.PrintNameLength = printnamelen;
3483 
3484  Status = utf8_to_utf16(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3485  stringlen, &stringlen, (char*)*data, size);
3486 
3487  if (!NT_SUCCESS(Status)) {
3488  ERR("utf8_to_utf16 2 returned %08lx\n", Status);
3489  ExFreePool(rdb);
3490  ExFreePool(*data);
3491  return Status;
3492  }
3493 
3494  for (i = 0; i < stringlen / sizeof(WCHAR); i++) {
3495  if (rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] == '/')
3496  rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] = '\\';
3497  }
3498 
3499  RtlCopyMemory(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)],
3500  &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3501  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
3502 
3503  ExFreePool(*data);
3504 
3505  *data = (uint8_t*)rdb;
3506  } else {
3508  if (!NT_SUCCESS(Status)) {
3509  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
3510  ExFreePool(*data);
3511  return Status;
3512  }
3513  }
3514  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
3516  return STATUS_INTERNAL_ERROR;
3517 
3518  if (fcb->reparse_xattr.Length < sizeof(ULONG)) {
3519  WARN("xattr was too short to be a reparse point\n");
3520  return STATUS_INTERNAL_ERROR;
3521  }
3522 
3524  if (!NT_SUCCESS(Status)) {
3525  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
3526  return Status;
3527  }
3528 
3530  if (!*data) {
3531  ERR("out of memory\n");
3533  }
3534 
3536  } else
3537  return STATUS_INVALID_PARAMETER;
3538 
3539  return STATUS_SUCCESS;
3540 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Iosb Status
Definition: create.c:4287
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp) __attribute__((nonnull(1
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
unsigned short int uint16_t
Definition: acefiex.h:54
struct _REPARSE_DATA_BUFFER::@303::@305 SymbolicLinkReparseBuffer
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:87
WCHAR PathBuffer[1]
Definition: shellext.h:176
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
#define offsetof(TYPE, MEMBER)
uint8_t type
Definition: btrfs_drv.h:291
Status
Definition: gdiplustypes.h:24
uint64_t st_size
Definition: btrfs.h:289
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
wstring utf8_to_utf16(const string_view &utf8)
Definition: main.cpp:734
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
USHORT ReparseDataLength
Definition: shellext.h:166
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:97
GLint const GLchar GLint stringlen
Definition: glext.h:7232
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define ERR(fmt,...)
Definition: debug.h:110
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
unsigned short USHORT
Definition: pedump.c:61
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91

Referenced by open_file(), and open_file2().

◆ has_manage_volume_privilege()

static bool has_manage_volume_privilege ( ACCESS_STATE access_state,
KPROCESSOR_MODE  processor_mode 
)
static

Definition at line 4810 of file create.c.

4810  {
4811  PRIVILEGE_SET privset;
4812 
4813  privset.PrivilegeCount = 1;
4815  privset.Privilege[0].Luid = RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE);
4816  privset.Privilege[0].Attributes = 0;
4817 
4818  return SePrivilegeCheck(&privset, &access_state->SubjectSecurityContext, processor_mode) ? true : false;
4819 }
$ULONG Control
Definition: setypes.h:87
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
$ULONG PrivilegeCount
Definition: setypes.h:86
Definition: stddef.h:6
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h:234
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88

Referenced by _Dispatch_type_().