ReactOS  0.4.15-dev-5446-g3f3714b
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 3004 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 4826 of file create.c.

4828  {
4829  NTSTATUS Status;
4831  device_extension* Vcb = DeviceObject->DeviceExtension;
4832  bool top_level, locked = false;
4833  oplock_context* opctx = NULL;
4834 
4836 
4837  TRACE("create (flags = %lx)\n", Irp->Flags);
4838 
4839  top_level = is_top_level(Irp);
4840 
4841  /* return success if just called for FS device object */
4842  if (DeviceObject == master_devobj) {
4843  TRACE("create called for FS device object\n");
4844 
4845  Irp->IoStatus.Information = FILE_OPENED;
4847 
4848  goto exit;
4849  } else if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
4851  goto exit;
4852  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
4854  goto exit;
4855  }
4856 
4857  if (!(Vcb->Vpb->Flags & VPB_MOUNTED)) {
4859  goto exit;
4860  }
4861 
4862  if (Vcb->removing) {
4864  goto exit;
4865  }
4866 
4867  Status = verify_vcb(Vcb, Irp);
4868  if (!NT_SUCCESS(Status)) {
4869  ERR("verify_vcb returned %08lx\n", Status);
4870  goto exit;
4871  }
4872 
4873  ExAcquireResourceSharedLite(&Vcb->load_lock, true);
4874  locked = true;
4875 
4877 
4878  if (IrpSp->Flags != 0) {
4880 
4881  TRACE("flags:\n");
4882 
4883  if (flags & SL_CASE_SENSITIVE) {
4884  TRACE("SL_CASE_SENSITIVE\n");
4886  }
4887 
4888  if (flags & SL_FORCE_ACCESS_CHECK) {
4889  TRACE("SL_FORCE_ACCESS_CHECK\n");
4891  }
4892 
4893  if (flags & SL_OPEN_PAGING_FILE) {
4894  TRACE("SL_OPEN_PAGING_FILE\n");
4896  }
4897 
4899  TRACE("SL_OPEN_TARGET_DIRECTORY\n");
4901  }
4902 
4903  if (flags & SL_STOP_ON_SYMLINK) {
4904  TRACE("SL_STOP_ON_SYMLINK\n");
4906  }
4907 
4909  TRACE("SL_IGNORE_READONLY_ATTRIBUTE\n");
4911  }
4912 
4913  if (flags)
4914  WARN("unknown flags: %x\n", flags);
4915  } else {
4916  TRACE("flags: (none)\n");
4917  }
4918 
4919  if (!IrpSp->FileObject) {
4920  ERR("FileObject was NULL\n");
4922  goto exit;
4923  }
4924 
4925  if (IrpSp->FileObject->RelatedFileObject) {
4926  fcb* relatedfcb = IrpSp->FileObject->RelatedFileObject->FsContext;
4927 
4928  if (relatedfcb && relatedfcb->Vcb != Vcb) {
4929  WARN("RelatedFileObject was for different device\n");
4931  goto exit;
4932  }
4933  }
4934 
4935  // opening volume
4936  if (IrpSp->FileObject->FileName.Length == 0 && !IrpSp->FileObject->RelatedFileObject) {
4937  ULONG RequestedDisposition = ((IrpSp->Parameters.Create.Options >> 24) & 0xff);
4938  ULONG RequestedOptions = IrpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
4939 #ifdef DEBUG_FCB_REFCOUNTS
4940  LONG rc;
4941 #endif
4942  ccb* ccb;
4943 
4944  TRACE("open operation for volume\n");
4945 
4946  if (RequestedDisposition != FILE_OPEN && RequestedDisposition != FILE_OPEN_IF) {
4948  goto exit;
4949  }
4950 
4951  if (RequestedOptions & FILE_DIRECTORY_FILE) {
4953  goto exit;
4954  }
4955 
4957  if (!ccb) {
4958  ERR("out of memory\n");
4960  goto exit;
4961  }
4962 
4963  RtlZeroMemory(ccb, sizeof(*ccb));
4964 
4966  ccb->NodeSize = sizeof(*ccb);
4967  ccb->disposition = RequestedDisposition;
4968  ccb->options = RequestedOptions;
4969  ccb->access = IrpSp->Parameters.Create.SecurityContext->AccessState->PreviouslyGrantedAccess;
4971  IrpSp->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode);
4972  ccb->reserving = false;
4973  ccb->lxss = called_from_lxss();
4974 
4975 #ifdef DEBUG_FCB_REFCOUNTS
4976  rc = InterlockedIncrement(&Vcb->volume_fcb->refcount);
4977  WARN("fcb %p: refcount now %i (volume)\n", Vcb->volume_fcb, rc);
4978 #else
4979  InterlockedIncrement(&Vcb->volume_fcb->refcount);
4980 #endif
4981  IrpSp->FileObject->FsContext = Vcb->volume_fcb;
4982  IrpSp->FileObject->FsContext2 = ccb;
4983 
4984  IrpSp->FileObject->SectionObjectPointer = &Vcb->volume_fcb->nonpaged->segment_object;
4985 
4986  if (!IrpSp->FileObject->Vpb)
4987  IrpSp->FileObject->Vpb = DeviceObject->Vpb;
4988 
4989  InterlockedIncrement(&Vcb->open_files);
4990 
4991  Irp->IoStatus.Information = FILE_OPENED;
4993  } else {
4995  bool skip_lock;
4996 
4998 
4999  TRACE("file name: %.*S\n", (int)(IrpSp->FileObject->FileName.Length / sizeof(WCHAR)), IrpSp->FileObject->FileName.Buffer);
5000 
5001  if (IrpSp->FileObject->RelatedFileObject)
5002  TRACE("related file = %p\n", IrpSp->FileObject->RelatedFileObject);
5003 
5004  // Don't lock again if we're being called from within CcCopyRead etc.
5005  skip_lock = ExIsResourceAcquiredExclusiveLite(&Vcb->tree_lock);
5006 
5007  if (!skip_lock)
5008  ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
5009 
5010  ExAcquireResourceSharedLite(&Vcb->fileref_lock, true);
5011 
5012  Status = open_file(DeviceObject, Vcb, Irp, &rollback, &opctx);
5013 
5014  if (!NT_SUCCESS(Status))
5016  else
5018 
5019  ExReleaseResourceLite(&Vcb->fileref_lock);
5020 
5021  if (!skip_lock)
5022  ExReleaseResourceLite(&Vcb->tree_lock);
5023  }
5024 
5025 exit:
5026  if (Status != STATUS_PENDING) {
5027  Irp->IoStatus.Status = Status;
5029  }
5030 
5031  if (locked)
5032  ExReleaseResourceLite(&Vcb->load_lock);
5033 
5034  if (Status == STATUS_PENDING) {
5036  Status = opctx->Status;
5037  ExFreePool(opctx);
5038  }
5039 
5040  TRACE("create returning %08lx\n", Status);
5041 
5042  if (top_level)
5044 
5046 
5047  return Status;
5048 }
#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
#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:687
ACCESS_MASK access
Definition: btrfs_drv.h:382
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:278
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
#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
Iosb Status
Definition: create.c:4287
static bool has_manage_volume_privilege(ACCESS_STATE *access_state, KPROCESSOR_MODE processor_mode)
Definition: create.c:4815
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:84
Status
Definition: gdiplustypes.h:24
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
#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:689
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
#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:1364
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:3004
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:4753
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:4466
HRESULT Create([out]ITransactionReceiver **ppReceiver)
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#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
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
Iosb Status
Definition: create.c:4287
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
FILE_LOCK lock
Definition: btrfs_drv.h:294
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
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:1364
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:1677
#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
LONG refcount
Definition: btrfs_drv.h:350
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
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 2640 of file create.c.

2642  {
2644  file_ref *fileref, *newpar, *parfileref;
2645  fcb* fcb;
2646  static const char xapref[] = "user.";
2647  static const WCHAR DOSATTRIB[] = L"DOSATTRIB";
2648  static const WCHAR EA[] = L"EA";
2649  static const WCHAR reparse[] = L"reparse";
2650  static const WCHAR casesensitive_str[] = L"casesensitive";
2652  BTRFS_TIME now;
2653  ULONG utf8len, overhead;
2654  NTSTATUS Status;
2655  KEY searchkey;
2656  traverse_ptr tp;
2657  dir_child* dc;
2658  dir_child* existing_dc = NULL;
2659  ACCESS_MASK granted_access;
2660 #ifdef DEBUG_FCB_REFCOUNTS
2661  LONG rc;
2662 #endif
2663 
2664  TRACE("fpus = %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer);
2665  TRACE("stream = %.*S\n", (int)(stream->Length / sizeof(WCHAR)), stream->Buffer);
2666 
2667  parfileref = *pparfileref;
2668 
2669  if (parfileref->fcb == Vcb->dummy_fcb)
2670  return STATUS_ACCESS_DENIED;
2671 
2672  Status = check_file_name_valid(stream, false, true);
2673  if (!NT_SUCCESS(Status))
2674  return Status;
2675 
2676  Status = open_fileref(Vcb, &newpar, fpus, parfileref, false, NULL, NULL, PagedPool, case_sensitive, Irp);
2677 
2679  UNICODE_STRING fpus2;
2680 
2681  Status = check_file_name_valid(fpus, false, false);
2682  if (!NT_SUCCESS(Status))
2683  return Status;
2684 
2685  fpus2.Length = fpus2.MaximumLength = fpus->Length;
2687 
2688  if (!fpus2.Buffer) {
2689  ERR("out of memory\n");
2691  }
2692 
2693  RtlCopyMemory(fpus2.Buffer, fpus->Buffer, fpus2.Length);
2694 
2695  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2696 
2697  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2700  &granted_access, &Status)) {
2701  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2702  return Status;
2703  }
2704 
2705  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2706 
2707  Status = file_create2(Irp, Vcb, &fpus2, parfileref, options, NULL, 0, &newpar, case_sensitive, rollback);
2708 
2709  if (!NT_SUCCESS(Status)) {
2710  ERR("file_create2 returned %08lx\n", Status);
2711  ExFreePool(fpus2.Buffer);
2712  return Status;
2713  } else if (Status != STATUS_OBJECT_NAME_COLLISION) {
2716  }
2717 
2718  ExFreePool(fpus2.Buffer);
2719  } else if (!NT_SUCCESS(Status)) {
2720  ERR("open_fileref returned %08lx\n", Status);
2721  return Status;
2722  }
2723 
2724  parfileref = newpar;
2725  *pparfileref = parfileref;
2726 
2727  if (parfileref->fcb->type != BTRFS_TYPE_FILE && parfileref->fcb->type != BTRFS_TYPE_SYMLINK && parfileref->fcb->type != BTRFS_TYPE_DIRECTORY) {
2728  WARN("parent not file, directory, or symlink\n");
2729  free_fileref(parfileref);
2730  return STATUS_INVALID_PARAMETER;
2731  }
2732 
2733  if (options & FILE_DIRECTORY_FILE) {
2734  WARN("tried to create directory as stream\n");
2735  free_fileref(parfileref);
2736  return STATUS_INVALID_PARAMETER;
2737  }
2738 
2740  free_fileref(parfileref);
2741  return STATUS_ACCESS_DENIED;
2742  }
2743 
2744  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2745 
2746  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2748  &granted_access, &Status)) {
2749  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2750  free_fileref(parfileref);
2751  return Status;
2752  }
2753 
2754  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2755 
2756  if ((stream->Length == sizeof(DOSATTRIB) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, DOSATTRIB, stream->Length) == stream->Length) ||
2757  (stream->Length == sizeof(EA) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, EA, stream->Length) == stream->Length) ||
2758  (stream->Length == sizeof(reparse) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, reparse, stream->Length) == stream->Length) ||
2759  (stream->Length == sizeof(casesensitive_str) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, casesensitive_str, stream->Length) == stream->Length)) {
2760  free_fileref(parfileref);
2762  }
2763 
2765  if (!fcb) {
2766  ERR("out of memory\n");
2767  free_fileref(parfileref);
2769  }
2770 
2771  fcb->Vcb = Vcb;
2772 
2773  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2774  fcb->Header.AllocationSize.QuadPart = 0;
2775  fcb->Header.FileSize.QuadPart = 0;
2776  fcb->Header.ValidDataLength.QuadPart = 0;
2777 
2778 #ifdef DEBUG_FCB_REFCOUNTS
2779  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2780  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2781 #else
2782  InterlockedIncrement(&parfileref->fcb->refcount);
2783 #endif
2784  fcb->subvol = parfileref->fcb->subvol;
2785  fcb->inode = parfileref->fcb->inode;
2786  fcb->hash = parfileref->fcb->hash;
2787  fcb->type = parfileref->fcb->type;
2788 
2789  fcb->ads = true;
2790 
2791  Status = utf16_to_utf8(NULL, 0, &utf8len, stream->Buffer, stream->Length);
2792  if (!NT_SUCCESS(Status)) {
2793  ERR("utf16_to_utf8 1 returned %08lx\n", Status);
2794  reap_fcb(fcb);
2795  free_fileref(parfileref);
2796  return Status;
2797  }
2798 
2799  fcb->adsxattr.Length = (uint16_t)utf8len + sizeof(xapref) - 1;
2802  if (!fcb->adsxattr.Buffer) {
2803  ERR("out of memory\n");
2804  reap_fcb(fcb);
2805  free_fileref(parfileref);
2807  }
2808 
2809  RtlCopyMemory(fcb->adsxattr.Buffer, xapref, sizeof(xapref) - 1);
2810 
2811  Status = utf16_to_utf8(&fcb->adsxattr.Buffer[sizeof(xapref) - 1], utf8len, &utf8len, stream->Buffer, stream->Length);
2812  if (!NT_SUCCESS(Status)) {
2813  ERR("utf16_to_utf8 2 returned %08lx\n", Status);
2814  reap_fcb(fcb);
2815  free_fileref(parfileref);
2816  return Status;
2817  }
2818 
2820 
2821  TRACE("adsxattr = %s\n", fcb->adsxattr.Buffer);
2822 
2824  TRACE("adshash = %08x\n", fcb->adshash);
2825 
2826  searchkey.obj_id = parfileref->fcb->inode;
2827  searchkey.obj_type = TYPE_XATTR_ITEM;
2828  searchkey.offset = fcb->adshash;
2829 
2830  Status = find_item(Vcb, parfileref->fcb->subvol, &tp, &searchkey, false, Irp);
2831  if (!NT_SUCCESS(Status)) {
2832  ERR("find_item returned %08lx\n", Status);
2833  reap_fcb(fcb);
2834  free_fileref(parfileref);
2835  return Status;
2836  }
2837 
2838  if (!keycmp(tp.item->key, searchkey))
2839  overhead = tp.item->size;
2840  else
2841  overhead = 0;
2842 
2843  fcb->adsmaxlen = Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - (sizeof(DIR_ITEM) - 1);
2844 
2845  if (utf8len + sizeof(xapref) - 1 + overhead > fcb->adsmaxlen) {
2846  WARN("not enough room for new DIR_ITEM (%Iu + %lu > %lu)\n", utf8len + sizeof(xapref) - 1, overhead, fcb->adsmaxlen);
2847  reap_fcb(fcb);
2848  free_fileref(parfileref);
2849  return STATUS_DISK_FULL;
2850  } else
2851  fcb->adsmaxlen -= overhead + utf8len + sizeof(xapref) - 1;
2852 
2853  fcb->created = true;
2854  fcb->deleted = true;
2855 
2856  acquire_fcb_lock_exclusive(Vcb);
2857  InsertHeadList(&parfileref->fcb->list_entry, &fcb->list_entry); // insert in list after parent fcb
2858  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2859  parfileref->fcb->subvol->fcbs_version++;
2860  release_fcb_lock(Vcb);
2861 
2863 
2865  if (!fileref) {
2866  ERR("out of memory\n");
2867  free_fcb(fcb);
2868  free_fileref(parfileref);
2870  }
2871 
2872  fileref->fcb = fcb;
2873 
2875  if (!dc) {
2876  ERR("out of memory\n");
2878  free_fileref(parfileref);
2880  }
2881 
2882  RtlZeroMemory(dc, sizeof(dir_child));
2883 
2884  dc->utf8.MaximumLength = dc->utf8.Length = fcb->adsxattr.Length + 1 - sizeof(xapref);
2885  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, dc->utf8.MaximumLength, ALLOC_TAG);
2886  if (!dc->utf8.Buffer) {
2887  ERR("out of memory\n");
2888  ExFreePool(dc);
2890  free_fileref(parfileref);
2892  }
2893 
2894  RtlCopyMemory(dc->utf8.Buffer, &fcb->adsxattr.Buffer[sizeof(xapref) - 1], fcb->adsxattr.Length + 1 - sizeof(xapref));
2895 
2896  dc->name.MaximumLength = dc->name.Length = stream->Length;
2897  dc->name.Buffer = ExAllocatePoolWithTag(pool_type, dc->name.MaximumLength, ALLOC_TAG);
2898  if (!dc->name.Buffer) {
2899  ERR("out of memory\n");
2900  ExFreePool(dc->utf8.Buffer);
2901  ExFreePool(dc);
2903  free_fileref(parfileref);
2905  }
2906 
2907  RtlCopyMemory(dc->name.Buffer, stream->Buffer, stream->Length);
2908 
2909  Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true);
2910  if (!NT_SUCCESS(Status)) {
2911  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
2912  ExFreePool(dc->utf8.Buffer);
2913  ExFreePool(dc->name.Buffer);
2914  ExFreePool(dc);
2916  free_fileref(parfileref);
2917  return Status;
2918  }
2919 
2922 
2923  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2924 
2925  LIST_ENTRY* le = parfileref->fcb->dir_children_index.Flink;
2926  while (le != &parfileref->fcb->dir_children_index) {
2927  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
2928 
2929  if (dc2->index == 0) {
2930  if ((case_sensitive && dc2->name.Length == dc->name.Length && RtlCompareMemory(dc2->name.Buffer, dc->name.Buffer, dc2->name.Length) == dc2->name.Length) ||
2931  (!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)
2932  ) {
2933  existing_dc = dc2;
2934  break;
2935  }
2936  } else
2937  break;
2938 
2939  le = le->Flink;
2940  }
2941 
2942  if (existing_dc) {
2943  ExFreePool(dc->utf8.Buffer);
2944  ExFreePool(dc->name.Buffer);
2945  ExFreePool(dc);
2947  free_fileref(parfileref);
2948 
2949  increase_fileref_refcount(existing_dc->fileref);
2950  *pfileref = existing_dc->fileref;
2951 
2953  }
2954 
2955  dc->fileref = fileref;
2956  fileref->dc = dc;
2957  fileref->parent = (struct _file_ref*)parfileref;
2958  fcb->deleted = false;
2959 
2960  InsertHeadList(&parfileref->fcb->dir_children_index, &dc->list_entry_index);
2961 
2962  InsertTailList(&parfileref->children, &fileref->list_entry);
2963 
2964  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2965 
2966  mark_fileref_dirty(fileref);
2967 
2968  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2969  parfileref->fcb->inode_item.sequence++;
2970  parfileref->fcb->inode_item.st_ctime = now;
2971  parfileref->fcb->inode_item_changed = true;
2972 
2973  mark_fcb_dirty(parfileref->fcb);
2974 
2975  parfileref->fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2976  parfileref->fcb->subvol->root_item.ctime = now;
2977 
2978  increase_fileref_refcount(parfileref);
2979 
2980  *pfileref = fileref;
2981 
2983 
2984  return STATUS_SUCCESS;
2985 }
#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:1734
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
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:1016
#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:1875
#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:1517
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
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1667
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:293
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1717
#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:1743
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1695
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:670
uint8_t type
Definition: btrfs_drv.h:291
Iosb Status
Definition: create.c:4287
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1739
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:2996
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
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
#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:1364
#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:509
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:1684
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:910
#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
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:1364
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1856
#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:989
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:5797
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
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#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 3300 of file create.c.

3300  {
3301  if (RequestedOptions != 0) {
3302  ULONG options = RequestedOptions;
3303 
3304  TRACE("requested options:\n");
3305 
3306  if (options & FILE_DIRECTORY_FILE) {
3307  TRACE(" FILE_DIRECTORY_FILE\n");
3309  }
3310 
3311  if (options & FILE_WRITE_THROUGH) {
3312  TRACE(" FILE_WRITE_THROUGH\n");
3314  }
3315 
3316  if (options & FILE_SEQUENTIAL_ONLY) {
3317  TRACE(" FILE_SEQUENTIAL_ONLY\n");
3319  }
3320 
3322  TRACE(" FILE_NO_INTERMEDIATE_BUFFERING\n");
3324  }
3325 
3327  TRACE(" FILE_SYNCHRONOUS_IO_ALERT\n");
3329  }
3330 
3332  TRACE(" FILE_SYNCHRONOUS_IO_NONALERT\n");
3334  }
3335 
3337  TRACE(" FILE_NON_DIRECTORY_FILE\n");
3339  }
3340 
3342  TRACE(" FILE_CREATE_TREE_CONNECTION\n");
3344  }
3345 
3347  TRACE(" FILE_COMPLETE_IF_OPLOCKED\n");
3349  }
3350 
3351  if (options & FILE_NO_EA_KNOWLEDGE) {
3352  TRACE(" FILE_NO_EA_KNOWLEDGE\n");
3354  }
3355 
3357  TRACE(" FILE_OPEN_REMOTE_INSTANCE\n");
3359  }
3360 
3361  if (options & FILE_RANDOM_ACCESS) {
3362  TRACE(" FILE_RANDOM_ACCESS\n");
3364  }
3365 
3366  if (options & FILE_DELETE_ON_CLOSE) {
3367  TRACE(" FILE_DELETE_ON_CLOSE\n");
3369  }
3370 
3371  if (options & FILE_OPEN_BY_FILE_ID) {
3372  TRACE(" FILE_OPEN_BY_FILE_ID\n");
3374  }
3375 
3377  TRACE(" FILE_OPEN_FOR_BACKUP_INTENT\n");
3379  }
3380 
3381  if (options & FILE_NO_COMPRESSION) {
3382  TRACE(" FILE_NO_COMPRESSION\n");
3384  }
3385 
3386 #if NTDDI_VERSION >= NTDDI_WIN7
3388  TRACE(" FILE_OPEN_REQUIRING_OPLOCK\n");
3390  }
3391 
3393  TRACE(" FILE_DISALLOW_EXCLUSIVE\n");
3395  }
3396 #endif
3397 
3399  TRACE(" FILE_RESERVE_OPFILTER\n");
3401  }
3402 
3404  TRACE(" FILE_OPEN_REPARSE_POINT\n");
3406  }
3407 
3408  if (options & FILE_OPEN_NO_RECALL) {
3409  TRACE(" FILE_OPEN_NO_RECALL\n");
3411  }
3412 
3414  TRACE(" FILE_OPEN_FOR_FREE_SPACE_QUERY\n");
3416  }
3417 
3418  if (options)
3419  TRACE(" unknown options: %lx\n", options);
3420  } else {
3421  TRACE("requested options: (none)\n");
3422  }
3423 }
#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 3547 of file create.c.

3547  {
3548  LIST_ENTRY* le;
3549  NTSTATUS Status;
3550 
3551  if (fcb->csum_loaded)
3552  return;
3553 
3555  goto end;
3556 
3557  le = fcb->extents.Flink;
3558  while (le != &fcb->extents) {
3560 
3561  if (!ext->ignore && ext->extent_data.type == EXTENT_TYPE_REGULAR) {
3562  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)&ext->extent_data.data[0];
3563  uint64_t len;
3564 
3565  len = (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->num_bytes : ed2->size) >> Vcb->sector_shift;
3566 
3567  ext->csum = ExAllocatePoolWithTag(NonPagedPool, (ULONG)(len * Vcb->csum_size), ALLOC_TAG);
3568  if (!ext->csum) {
3569  ERR("out of memory\n");
3570  goto end;
3571  }
3572 
3573  Status = load_csum(Vcb, ext->csum, ed2->address + (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->offset : 0), len, Irp);
3574 
3575  if (!NT_SUCCESS(Status)) {
3576  ERR("load_csum returned %08lx\n", Status);
3577  goto end;
3578  }
3579  }
3580 
3581  le = le->Flink;
3582  }
3583 
3584 end:
3585  fcb->csum_loaded = true;
3586 }
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:65
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_ 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
Iosb Status
Definition: create.c:4287
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
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
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 3007 of file create.c.

3009  {
3010  NTSTATUS Status;
3011  file_ref *fileref, *parfileref = NULL;
3012  ULONG i, j;
3013  ccb* ccb;
3014  static const WCHAR datasuf[] = {':','$','D','A','T','A',0};
3015  UNICODE_STRING dsus, fpus, stream;
3018  ECP_LIST* ecp_list;
3020 #ifdef DEBUG_FCB_REFCOUNTS
3021  LONG oc;
3022 #endif
3023 
3024  TRACE("(%p, %p, %p, %.*S, %lx, %lx)\n", Irp, Vcb, FileObject, (int)(fnus->Length / sizeof(WCHAR)), fnus->Buffer, disposition, options);
3025 
3026  if (Vcb->readonly)
3028 
3031  return STATUS_CANNOT_DELETE;
3032  }
3033 
3035  if (NT_SUCCESS(fFsRtlGetEcpListFromIrp(Irp, &ecp_list)) && ecp_list) {
3036  void* ctx = NULL;
3037  GUID type;
3038  ULONG ctxsize;
3039 
3040  do {
3041  Status = fFsRtlGetNextExtraCreateParameter(ecp_list, ctx, &type, &ctx, &ctxsize);
3042 
3043  if (NT_SUCCESS(Status)) {
3044  if (RtlCompareMemory(&type, &GUID_ECP_ATOMIC_CREATE, sizeof(GUID)) == sizeof(GUID)) {
3045  if (ctxsize >= sizeof(ATOMIC_CREATE_ECP_CONTEXT))
3046  acec = ctx;
3047  else {
3048  ERR("GUID_ECP_ATOMIC_CREATE context was too short: %lu bytes, expected %Iu\n", ctxsize,
3049  sizeof(ATOMIC_CREATE_ECP_CONTEXT));
3050  }
3051  } else if (RtlCompareMemory(&type, &GUID_ECP_QUERY_ON_CREATE, sizeof(GUID)) == sizeof(GUID))
3052  WARN("unhandled ECP GUID_ECP_QUERY_ON_CREATE\n");
3053  else if (RtlCompareMemory(&type, &GUID_ECP_CREATE_REDIRECTION, sizeof(GUID)) == sizeof(GUID))
3054  WARN("unhandled ECP GUID_ECP_CREATE_REDIRECTION\n");
3055  else {
3056  WARN("unhandled ECP {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", type.Data1, type.Data2,
3057  type.Data3, type.Data4[0], type.Data4[1], type.Data4[2], type.Data4[3], type.Data4[4], type.Data4[5],
3058  type.Data4[6], type.Data4[7]);
3059  }
3060  }
3061  } while (NT_SUCCESS(Status));
3062  }
3063  }
3064 
3065  dsus.Buffer = (WCHAR*)datasuf;
3066  dsus.Length = dsus.MaximumLength = sizeof(datasuf) - sizeof(WCHAR);
3067  fpus.Buffer = NULL;
3068 
3069  if (!loaded_related) {
3070  Status = open_fileref(Vcb, &parfileref, fnus, related, true, NULL, NULL, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, Irp);
3071 
3072  if (!NT_SUCCESS(Status))
3073  goto end;
3074  } else
3075  parfileref = related;
3076 
3077  if (parfileref->fcb->type != BTRFS_TYPE_DIRECTORY && (fnus->Length < sizeof(WCHAR) || fnus->Buffer[0] != ':')) {
3079  goto end;
3080  }
3081 
3082  if (is_subvol_readonly(parfileref->fcb->subvol, Irp)) {
3084  goto end;
3085  }
3086 
3087  i = (fnus->Length / sizeof(WCHAR))-1;
3088  while ((fnus->Buffer[i] == '\\' || fnus->Buffer[i] == '/') && i > 0) { i--; }
3089 
3090  j = i;
3091 
3092  while (i > 0 && fnus->Buffer[i-1] != '\\' && fnus->Buffer[i-1] != '/') { i--; }
3093 
3094  fpus.MaximumLength = (USHORT)((j - i + 2) * sizeof(WCHAR));
3095  fpus.Buffer = ExAllocatePoolWithTag(pool_type, fpus.MaximumLength, ALLOC_TAG);
3096  if (!fpus.Buffer) {
3097  ERR("out of memory\n");
3099  goto end;
3100  }
3101 
3102  fpus.Length = (USHORT)((j - i + 1) * sizeof(WCHAR));
3103 
3104  RtlCopyMemory(fpus.Buffer, &fnus->Buffer[i], (j - i + 1) * sizeof(WCHAR));
3105  fpus.Buffer[j - i + 1] = 0;
3106 
3107  if (fpus.Length > dsus.Length) { // check for :$DATA suffix
3108  UNICODE_STRING lb;
3109 
3110  lb.Buffer = &fpus.Buffer[(fpus.Length - dsus.Length)/sizeof(WCHAR)];
3111  lb.Length = lb.MaximumLength = dsus.Length;
3112 
3113  TRACE("lb = %.*S\n", (int)(lb.Length/sizeof(WCHAR)), lb.Buffer);
3114 
3115  if (FsRtlAreNamesEqual(&dsus, &lb, true, NULL)) {
3116  TRACE("ignoring :$DATA suffix\n");
3117 
3118  fpus.Length -= lb.Length;
3119 
3120  if (fpus.Length > sizeof(WCHAR) && fpus.Buffer[(fpus.Length-1)/sizeof(WCHAR)] == ':')
3121  fpus.Length -= sizeof(WCHAR);
3122 
3123  TRACE("fpus = %.*S\n", (int)(fpus.Length / sizeof(WCHAR)), fpus.Buffer);
3124  }
3125  }
3126 
3127  stream.Length = 0;
3128 
3129  for (i = 0; i < fpus.Length / sizeof(WCHAR); i++) {
3130  if (fpus.Buffer[i] == ':') {
3131  stream.Length = (USHORT)(fpus.Length - (i * sizeof(WCHAR)) - sizeof(WCHAR));
3132  stream.Buffer = &fpus.Buffer[i+1];
3133  fpus.Buffer[i] = 0;
3134  fpus.Length = (USHORT)(i * sizeof(WCHAR));
3135  break;
3136  }
3137  }
3138 
3139  if (stream.Length > 0) {
3140  Status = create_stream(Vcb, &fileref, &parfileref, &fpus, &stream, Irp, options, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3141  if (!NT_SUCCESS(Status)) {
3142  ERR("create_stream returned %08lx\n", Status);
3143  goto end;
3144  }
3145 
3146  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess,
3147  FileObject, &fileref->fcb->share_access);
3148  } else {
3149  ACCESS_MASK granted_access;
3150 
3151  Status = check_file_name_valid(&fpus, false, false);
3152  if (!NT_SUCCESS(Status))
3153  goto end;
3154 
3155  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3156 
3157  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
3160  &granted_access, &Status)) {
3161  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3162  goto end;
3163  }
3164 
3165  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3166 
3167  if (Irp->AssociatedIrp.SystemBuffer && IrpSp->Parameters.Create.EaLength > 0) {
3168  ULONG offset;
3169 
3170  Status = IoCheckEaBufferValidity(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength, &offset);
3171  if (!NT_SUCCESS(Status)) {
3172  ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset);
3173  goto end;
3174  }
3175  }
3176 
3177  Status = file_create2(Irp, Vcb, &fpus, parfileref, options, Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength,
3178  &fileref, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3179 
3181  *existing_fileref = fileref;
3182  goto end;
3183  } else if (!NT_SUCCESS(Status)) {
3184  ERR("file_create2 returned %08lx\n", Status);
3185  goto end;
3186  }
3187 
3188  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess, FileObject, &fileref->fcb->share_access);
3189 
3192  }
3193 
3194  FileObject->FsContext = fileref->fcb;
3195 
3197  if (!ccb) {
3198  ERR("out of memory\n");
3200  fileref->deleted = true;
3201  fileref->fcb->deleted = true;
3202 
3203  if (stream.Length == 0) {
3204  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3205  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3206  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3207  }
3208 
3209  free_fileref(fileref);
3210  goto end;
3211  }
3212 
3213  RtlZeroMemory(ccb, sizeof(*ccb));
3214 
3215  ccb->fileref = fileref;
3216 
3218  ccb->NodeSize = sizeof(*ccb);
3219  ccb->disposition = disposition;
3220  ccb->options = options;
3221  ccb->query_dir_offset = 0;
3223  ccb->has_wildcard = false;
3224  ccb->specific_file = false;
3225  ccb->access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3227  ccb->reserving = false;
3228  ccb->lxss = called_from_lxss();
3229 
3230 #ifdef DEBUG_FCB_REFCOUNTS
3231  oc = InterlockedIncrement(&fileref->open_count);
3232  ERR("fileref %p: open_count now %i\n", fileref, oc);
3233 #else
3234  InterlockedIncrement(&fileref->open_count);
3235 #endif
3236  InterlockedIncrement(&Vcb->open_files);
3237 
3238  FileObject->FsContext2 = ccb;
3239 
3240  FileObject->SectionObjectPointer = &fileref->fcb->nonpaged->segment_object;
3241 
3242  // FIXME - ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT
3244  if (acec->ReparseBufferLength > sizeof(uint32_t) && *(uint32_t*)acec->ReparseBuffer == IO_REPARSE_TAG_SYMLINK) {
3246  fileref->fcb->type = BTRFS_TYPE_FILE;
3247  fileref->fcb->atts &= ~FILE_ATTRIBUTE_DIRECTORY;
3248  }
3249 
3250  if (fileref->fcb->type == BTRFS_TYPE_SOCKET || fileref->fcb->type == BTRFS_TYPE_FIFO ||
3251  fileref->fcb->type == BTRFS_TYPE_CHARDEV || fileref->fcb->type == BTRFS_TYPE_BLOCKDEV) {
3252  // NOP. If called from LXSS, humour it - we hardcode the values elsewhere.
3253  } else {
3255  if (!NT_SUCCESS(Status)) {
3256  ERR("set_reparse_point2 returned %08lx\n", Status);
3257  fileref->deleted = true;
3258  fileref->fcb->deleted = true;
3259 
3260  if (stream.Length == 0) {
3261  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3262  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3263  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3264  }
3265 
3266  free_fileref(fileref);
3267  return Status;
3268  }
3269  }
3270 
3272  }
3273 
3278  fileref->fcb->case_sensitive = true;
3279  ccb->case_sensitive = true;
3280  }
3281 
3283  }
3284 
3286  }
3287 
3288  fileref->dc->type = fileref->fcb->type;
3289 
3290 end:
3291  if (fpus.Buffer)
3292  ExFreePool(fpus.Buffer);
3293 
3294  if (parfileref && !loaded_related)
3295  free_fileref(parfileref);
3296 
3297  return Status;
3298 }
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
#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:1760
#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:1517
#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
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1667
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:1033
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
Iosb Status
Definition: create.c:4287
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
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
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:2640
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:1758
#define __S_IFCHR
Definition: btrfs_drv.h:1755
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:910
#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
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:1364
UINT32 uint32_t
Definition: types.h:75
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1856
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define called_from_lxss()
Definition: create.c:3004
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
Definition: btrfs.c:97
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:96
bool reserving
Definition: btrfs_drv.h:381
#define __S_IFBLK
Definition: btrfs_drv.h:1756
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:5797
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
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
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 || Vcb->options.nodatacow) {
2324 
2325  if (type != BTRFS_TYPE_DIRECTORY)
2327  }
2328 
2329  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_COMPRESS &&
2332  }
2333  }
2334 
2336  fcb->prop_compression = parfileref->fcb->prop_compression;
2338  } else
2340 
2341  fcb->inode_item_changed = true;
2342 
2343  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2344  fcb->Header.AllocationSize.QuadPart = 0;
2345  fcb->Header.FileSize.QuadPart = 0;
2346  fcb->Header.ValidDataLength.QuadPart = 0;
2347 
2348  fcb->atts = IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL;
2349  fcb->atts_changed = fcb->atts != defda;
2350 
2351 #ifdef DEBUG_FCB_REFCOUNTS
2352  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2353  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2354 #else
2355  InterlockedIncrement(&parfileref->fcb->refcount);
2356 #endif
2357  fcb->subvol = parfileref->fcb->subvol;
2358  fcb->inode = inode;
2359  fcb->type = type;
2360  fcb->created = true;
2361  fcb->deleted = true;
2362 
2363  fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&inode, sizeof(uint64_t));
2364 
2365  acquire_fcb_lock_exclusive(Vcb);
2366 
2367  if (fcb->subvol->fcbs_ptrs[fcb->hash >> 24]) {
2368  LIST_ENTRY* le = fcb->subvol->fcbs_ptrs[fcb->hash >> 24];
2369 
2370  while (le != &fcb->subvol->fcbs) {
2371  struct _fcb* fcb2 = CONTAINING_RECORD(le, struct _fcb, list_entry);
2372 
2373  if (fcb2->hash > fcb->hash) {
2374  lastle = le->Blink;
2375  break;
2376  }
2377 
2378  le = le->Flink;
2379  }
2380  }
2381 
2382  if (!lastle) {
2383  uint8_t c = fcb->hash >> 24;
2384 
2385  if (c != 0xff) {
2386  uint8_t d = c + 1;
2387 
2388  do {
2389  if (fcb->subvol->fcbs_ptrs[d]) {
2390  lastle = fcb->subvol->fcbs_ptrs[d]->Blink;
2391  break;
2392  }
2393 
2394  d++;
2395  } while (d != 0);
2396  }
2397  }
2398 
2399  if (lastle) {
2400  InsertHeadList(lastle, &fcb->list_entry);
2401 
2402  if (lastle == &fcb->subvol->fcbs || (CONTAINING_RECORD(lastle, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2403  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2404  } else {
2405  InsertTailList(&fcb->subvol->fcbs, &fcb->list_entry);
2406 
2407  if (fcb->list_entry.Blink == &fcb->subvol->fcbs || (CONTAINING_RECORD(fcb->list_entry.Blink, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2408  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2409  }
2410 
2411  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2412 
2413  fcb->subvol->fcbs_version++;
2414 
2415  release_fcb_lock(Vcb);
2416 
2418 
2419  Status = fcb_get_new_sd(fcb, parfileref, IrpSp->Parameters.Create.SecurityContext->AccessState);
2420 
2421  if (!NT_SUCCESS(Status)) {
2422  ERR("fcb_get_new_sd returned %08lx\n", Status);
2423  free_fcb(fcb);
2424 
2425  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2426  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2427  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2428 
2429  ExFreePool(utf8);
2430 
2431  return Status;
2432  }
2433 
2434  fcb->sd_dirty = true;
2435 
2436  if (ea && ealen > 0) {
2438  if (!NT_SUCCESS(Status)) {
2439  ERR("file_create_parse_ea returned %08lx\n", Status);
2440  free_fcb(fcb);
2441 
2442  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2443  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2444  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2445 
2446  ExFreePool(utf8);
2447 
2448  return Status;
2449  }
2450  }
2451 
2453  if (!fileref) {
2454  ERR("out of memory\n");
2455  free_fcb(fcb);
2456 
2457  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2458  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2459  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2460 
2461  ExFreePool(utf8);
2462 
2464  }
2465 
2466  fileref->fcb = fcb;
2467 
2468  if (Irp->Overlay.AllocationSize.QuadPart > 0 && !write_fcb_compressed(fcb) && fcb->type != BTRFS_TYPE_DIRECTORY) {
2469  Status = extend_file(fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback);
2470 
2471  if (!NT_SUCCESS(Status)) {
2472  ERR("extend_file returned %08lx\n", Status);
2474 
2475  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2476  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2477  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2478 
2479  ExFreePool(utf8);
2480 
2481  return Status;
2482  }
2483  }
2484 
2485  if (fcb->type == BTRFS_TYPE_DIRECTORY) {
2487  if (!fcb->hash_ptrs) {
2488  ERR("out of memory\n");
2490 
2491  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2492  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2493  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2494 
2495  ExFreePool(utf8);
2496 
2498  }
2499 
2500  RtlZeroMemory(fcb->hash_ptrs, sizeof(LIST_ENTRY*) * 256);
2501 
2503  if (!fcb->hash_ptrs_uc) {
2504  ERR("out of memory\n");
2506 
2507  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2508  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2509  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2510 
2511  ExFreePool(utf8);
2512 
2514  }
2515 
2516  RtlZeroMemory(fcb->hash_ptrs_uc, sizeof(LIST_ENTRY*) * 256);
2517  }
2518 
2519  fcb->deleted = false;
2520 
2521  fileref->created = true;
2522 
2523  fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2524  fcb->subvol->root_item.ctime = now;
2525 
2526  utf8as.Buffer = utf8;
2527  utf8as.Length = utf8as.MaximumLength = (uint16_t)utf8len;
2528 
2529  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2530 
2531  // check again doesn't already exist
2532  if (case_sensitive) {
2533  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpus->Buffer, fpus->Length);
2534 
2535  if (parfileref->fcb->hash_ptrs[dc_hash >> 24]) {
2536  LIST_ENTRY* le = parfileref->fcb->hash_ptrs[dc_hash >> 24];
2537  while (le != &parfileref->fcb->dir_children_hash) {
2538  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
2539 
2540  if (dc->hash == dc_hash && dc->name.Length == fpus->Length && RtlCompareMemory(dc->name.Buffer, fpus->Buffer, fpus->Length) == fpus->Length) {
2541  existing_fileref = dc->fileref;
2542  break;
2543  } else if (dc->hash > dc_hash)
2544  break;
2545 
2546  le = le->Flink;
2547  }
2548  }
2549  } else {
2550  UNICODE_STRING fpusuc;
2551 
2552  Status = RtlUpcaseUnicodeString(&fpusuc, fpus, true);
2553  if (!NT_SUCCESS(Status)) {
2554  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2555  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
2557 
2558  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2559  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2560  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2561 
2562  ExFreePool(utf8);
2563 
2564  return Status;
2565  }
2566 
2567  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length);
2568 
2569  if (parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]) {
2570  LIST_ENTRY* le = parfileref->fcb->hash_ptrs_uc[dc_hash >> 24];
2571  while (le != &parfileref->fcb->dir_children_hash_uc) {
2572  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
2573 
2574  if (dc->hash_uc == dc_hash && dc->name.Length == fpusuc.Length && RtlCompareMemory(dc->name.Buffer, fpusuc.Buffer, fpusuc.Length) == fpusuc.Length) {
2575  existing_fileref = dc->fileref;
2576  break;
2577  } else if (dc->hash_uc > dc_hash)
2578  break;
2579 
2580  le = le->Flink;
2581  }
2582  }
2583 
2584  ExFreePool(fpusuc.Buffer);
2585  }
2586 
2587  if (existing_fileref) {
2588  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2590 
2591  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2592  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2593  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2594 
2595  ExFreePool(utf8);
2596 
2597  increase_fileref_refcount(existing_fileref);
2598  *pfr = existing_fileref;
2599 
2601  }
2602 
2603  Status = add_dir_child(parfileref->fcb, fcb->inode, false, &utf8as, fpus, fcb->type, &dc);
2604  if (!NT_SUCCESS(Status)) {
2605  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2606  ERR("add_dir_child returned %08lx\n", Status);
2608 
2609  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2610  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2611  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2612 
2613  ExFreePool(utf8);
2614 
2615  return Status;
2616  }
2617 
2618  fileref->parent = parfileref;
2619  fileref->dc = dc;
2620  dc->fileref = fileref;
2621 
2622  if (type == BTRFS_TYPE_DIRECTORY)
2623  fileref->fcb->fileref = fileref;
2624 
2625  InsertTailList(&parfileref->children, &fileref->list_entry);
2626  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2627 
2628  ExFreePool(utf8);
2629 
2631  increase_fileref_refcount(parfileref);
2632 
2633  *pfr = fileref;
2634 
2635  TRACE("created new file in subvol %I64x, inode %I64x\n", fcb->subvol->id, fcb->inode);
2636 
2637  return STATUS_SUCCESS;
2638 }
#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:1734
#define BTRFS_INODE_NODATACOW
Definition: propsheet.h:77
#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:1875
#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
uint32_t st_gid
Definition: btrfs.h:294
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1717
_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:1695
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
Iosb Status
Definition: create.c:4287
BTRFS_TIME st_mtime
Definition: btrfs.h:303
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1739
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:1706
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
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
#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:1364
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:1684
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
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:1364
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:989
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
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
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:1287
#define __S_ISTYPE(mode, mask)
Definition: btrfs_drv.h:1761
#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:1290
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
#define __S_IFSOCK
Definition: btrfs_drv.h:1760
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:1753
uint8_t type
Definition: btrfs_drv.h:291
Iosb Status
Definition: create.c:4287
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:1758
#define __S_IFCHR
Definition: btrfs_drv.h:1755
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:1288
#define S_ISUID
Definition: propsheet.h:65
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static const char lxmod[]
Definition: btrfs_drv.h:1289
#define S_IRUSR
Definition: propsheet.h:29
if(OpenRequiringOplock &&(Iosb.Status==STATUS_SUCCESS))
Definition: create.c:4300
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:1756
#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
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
LONG NTSTATUS
Definition: precomp.h:26
const char * filename
Definition: ioapi.h:137
Definition: fs.h:78
int hash
Definition: main.c:58
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:318
Iosb Status
Definition: create.c:4287
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:5797
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 3425 of file create.c.

3425  {
3426  NTSTATUS Status;
3427 
3429  ULONG size, bytes_read, i;
3430 
3431  if (fcb->type == BTRFS_TYPE_FILE && fcb->inode_item.st_size < sizeof(ULONG)) {
3432  WARN("file was too short to be a reparse point\n");
3433  return STATUS_INVALID_PARAMETER;
3434  }
3435 
3436  // 0x10007 = 0xffff (maximum length of data buffer) + 8 bytes header
3437  size = (ULONG)min(0x10007, fcb->inode_item.st_size);
3438 
3439  if (size == 0)
3440  return STATUS_INVALID_PARAMETER;
3441 
3443  if (!*data) {
3444  ERR("out of memory\n");
3446  }
3447 
3448  Status = read_file(fcb, *data, 0, size, &bytes_read, NULL);
3449  if (!NT_SUCCESS(Status)) {
3450  ERR("read_file_fcb returned %08lx\n", Status);
3451  ExFreePool(*data);
3452  return Status;
3453  }
3454 
3455  if (fcb->type == BTRFS_TYPE_SYMLINK) {
3456  ULONG stringlen, reqlen;
3457  uint16_t subnamelen, printnamelen;
3458  REPARSE_DATA_BUFFER* rdb;
3459 
3460  Status = utf8_to_utf16(NULL, 0, &stringlen, (char*)*data, bytes_read);
3461  if (!NT_SUCCESS(Status)) {
3462  ERR("utf8_to_utf16 1 returned %08lx\n", Status);
3463  ExFreePool(*data);
3464  return Status;
3465  }
3466 
3467  subnamelen = printnamelen = (USHORT)stringlen;
3468 
3469  reqlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + subnamelen + printnamelen;
3470 
3471  rdb = ExAllocatePoolWithTag(PagedPool, reqlen, ALLOC_TAG);
3472 
3473  if (!rdb) {
3474  ERR("out of memory\n");
3475  ExFreePool(*data);
3477  }
3478 
3480  rdb->ReparseDataLength = (USHORT)(reqlen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
3481  rdb->Reserved = 0;
3482 
3483  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
3484  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = subnamelen;
3485  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = subnamelen;
3486  rdb->SymbolicLinkReparseBuffer.PrintNameLength = printnamelen;
3488 
3489  Status = utf8_to_utf16(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3490  stringlen, &stringlen, (char*)*data, size);
3491 
3492  if (!NT_SUCCESS(Status)) {
3493  ERR("utf8_to_utf16 2 returned %08lx\n", Status);
3494  ExFreePool(rdb);
3495  ExFreePool(*data);
3496  return Status;
3497  }
3498 
3499  for (i = 0; i < stringlen / sizeof(WCHAR); i++) {
3500  if (rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] == '/')
3501  rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] = '\\';
3502  }
3503 
3504  RtlCopyMemory(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)],
3505  &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3506  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
3507 
3508  ExFreePool(*data);
3509 
3510  *data = (uint8_t*)rdb;
3511  } else {
3513  if (!NT_SUCCESS(Status)) {
3514  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
3515  ExFreePool(*data);
3516  return Status;
3517  }
3518  }
3519  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
3521  return STATUS_INTERNAL_ERROR;
3522 
3523  if (fcb->reparse_xattr.Length < sizeof(ULONG)) {
3524  WARN("xattr was too short to be a reparse point\n");
3525  return STATUS_INTERNAL_ERROR;
3526  }
3527 
3529  if (!NT_SUCCESS(Status)) {
3530  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
3531  return Status;
3532  }
3533 
3535  if (!*data) {
3536  ERR("out of memory\n");
3538  }
3539 
3541  } else
3542  return STATUS_INVALID_PARAMETER;
3543 
3544  return STATUS_SUCCESS;
3545 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#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
#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
Iosb Status
Definition: create.c:4287
Status
Definition: gdiplustypes.h:24
struct _REPARSE_DATA_BUFFER::@306::@308 SymbolicLinkReparseBuffer
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:98
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 4815 of file create.c.

4815  {
4816  PRIVILEGE_SET privset;
4817 
4818  privset.PrivilegeCount = 1;
4820  privset.Privilege[0].Luid = RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE);
4821  privset.Privilege[0].Attributes = 0;
4822 
4823  return SePrivilegeCheck(&privset, &access_state->SubjectSecurityContext, processor_mode) ? true : false;
4824 }
$ULONG Control
Definition: setypes.h:87
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
$ULONG PrivilegeCount
Definition: setypes.h:86
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h:234
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
Definition: stddef.h:6
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