ReactOS  0.4.15-dev-1070-ge1a01de
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
 

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 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_file2 (device_extension *Vcb, ULONG RequestedDisposition, POOL_TYPE pool_type, file_ref *fileref, ACCESS_MASK *granted_access, PFILE_OBJECT FileObject, UNICODE_STRING *fn, ULONG options, PIRP Irp, LIST_ENTRY *rollback)
 
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)
 
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 2989 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 4769 of file create.c.

4771  {
4772  NTSTATUS Status;
4774  device_extension* Vcb = DeviceObject->DeviceExtension;
4775  bool top_level, locked = false;
4776 
4778 
4779  TRACE("create (flags = %lx)\n", Irp->Flags);
4780 
4781  top_level = is_top_level(Irp);
4782 
4783  /* return success if just called for FS device object */
4784  if (DeviceObject == master_devobj) {
4785  TRACE("create called for FS device object\n");
4786 
4787  Irp->IoStatus.Information = FILE_OPENED;
4789 
4790  goto exit;
4791  } else if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
4793  goto exit;
4794  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
4796  goto exit;
4797  }
4798 
4799  if (!(Vcb->Vpb->Flags & VPB_MOUNTED)) {
4801  goto exit;
4802  }
4803 
4804  if (Vcb->removing) {
4806  goto exit;
4807  }
4808 
4809  Status = verify_vcb(Vcb, Irp);
4810  if (!NT_SUCCESS(Status)) {
4811  ERR("verify_vcb returned %08lx\n", Status);
4812  goto exit;
4813  }
4814 
4815  ExAcquireResourceSharedLite(&Vcb->load_lock, true);
4816  locked = true;
4817 
4819 
4820  if (IrpSp->Flags != 0) {
4822 
4823  TRACE("flags:\n");
4824 
4825  if (flags & SL_CASE_SENSITIVE) {
4826  TRACE("SL_CASE_SENSITIVE\n");
4828  }
4829 
4830  if (flags & SL_FORCE_ACCESS_CHECK) {
4831  TRACE("SL_FORCE_ACCESS_CHECK\n");
4833  }
4834 
4835  if (flags & SL_OPEN_PAGING_FILE) {
4836  TRACE("SL_OPEN_PAGING_FILE\n");
4838  }
4839 
4841  TRACE("SL_OPEN_TARGET_DIRECTORY\n");
4843  }
4844 
4845  if (flags & SL_STOP_ON_SYMLINK) {
4846  TRACE("SL_STOP_ON_SYMLINK\n");
4848  }
4849 
4850  if (flags)
4851  WARN("unknown flags: %x\n", flags);
4852  } else {
4853  TRACE("flags: (none)\n");
4854  }
4855 
4856  if (!IrpSp->FileObject) {
4857  ERR("FileObject was NULL\n");
4859  goto exit;
4860  }
4861 
4862  if (IrpSp->FileObject->RelatedFileObject) {
4863  fcb* relatedfcb = IrpSp->FileObject->RelatedFileObject->FsContext;
4864 
4865  if (relatedfcb && relatedfcb->Vcb != Vcb) {
4866  WARN("RelatedFileObject was for different device\n");
4868  goto exit;
4869  }
4870  }
4871 
4872  // opening volume
4873  if (IrpSp->FileObject->FileName.Length == 0 && !IrpSp->FileObject->RelatedFileObject) {
4874  ULONG RequestedDisposition = ((IrpSp->Parameters.Create.Options >> 24) & 0xff);
4875  ULONG RequestedOptions = IrpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
4876 #ifdef DEBUG_FCB_REFCOUNTS
4877  LONG rc;
4878 #endif
4879  ccb* ccb;
4880 
4881  TRACE("open operation for volume\n");
4882 
4883  if (RequestedDisposition != FILE_OPEN && RequestedDisposition != FILE_OPEN_IF) {
4885  goto exit;
4886  }
4887 
4888  if (RequestedOptions & FILE_DIRECTORY_FILE) {
4890  goto exit;
4891  }
4892 
4894  if (!ccb) {
4895  ERR("out of memory\n");
4897  goto exit;
4898  }
4899 
4900  RtlZeroMemory(ccb, sizeof(*ccb));
4901 
4903  ccb->NodeSize = sizeof(*ccb);
4904  ccb->disposition = RequestedDisposition;
4905  ccb->options = RequestedOptions;
4906  ccb->access = IrpSp->Parameters.Create.SecurityContext->AccessState->PreviouslyGrantedAccess;
4908  IrpSp->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode);
4909  ccb->reserving = false;
4910  ccb->lxss = called_from_lxss();
4911 
4912 #ifdef DEBUG_FCB_REFCOUNTS
4913  rc = InterlockedIncrement(&Vcb->volume_fcb->refcount);
4914  WARN("fcb %p: refcount now %i (volume)\n", Vcb->volume_fcb, rc);
4915 #else
4916  InterlockedIncrement(&Vcb->volume_fcb->refcount);
4917 #endif
4918  IrpSp->FileObject->FsContext = Vcb->volume_fcb;
4919  IrpSp->FileObject->FsContext2 = ccb;
4920 
4921  IrpSp->FileObject->SectionObjectPointer = &Vcb->volume_fcb->nonpaged->segment_object;
4922 
4923  if (!IrpSp->FileObject->Vpb)
4924  IrpSp->FileObject->Vpb = DeviceObject->Vpb;
4925 
4926  InterlockedIncrement(&Vcb->open_files);
4927 
4928  Irp->IoStatus.Information = FILE_OPENED;
4930  } else {
4932  bool skip_lock;
4933 
4935 
4936  TRACE("file name: %.*S\n", (int)(IrpSp->FileObject->FileName.Length / sizeof(WCHAR)), IrpSp->FileObject->FileName.Buffer);
4937 
4938  if (IrpSp->FileObject->RelatedFileObject)
4939  TRACE("related file = %p\n", IrpSp->FileObject->RelatedFileObject);
4940 
4941  // Don't lock again if we're being called from within CcCopyRead etc.
4942  skip_lock = ExIsResourceAcquiredExclusiveLite(&Vcb->tree_lock);
4943 
4944  if (!skip_lock)
4945  ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
4946 
4947  ExAcquireResourceSharedLite(&Vcb->fileref_lock, true);
4948 
4950 
4951  if (!NT_SUCCESS(Status))
4953  else
4955 
4956  ExReleaseResourceLite(&Vcb->fileref_lock);
4957 
4958  if (!skip_lock)
4959  ExReleaseResourceLite(&Vcb->tree_lock);
4960  }
4961 
4962 exit:
4963  Irp->IoStatus.Status = Status;
4965 
4966  TRACE("create returning %08lx\n", Status);
4967 
4968  if (locked)
4969  ExReleaseResourceLite(&Vcb->load_lock);
4970 
4971  if (top_level)
4973 
4975 
4976  return Status;
4977 }
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback)
Definition: treefuncs.c:1050
void clear_rollback(LIST_ENTRY *rollback)
Definition: treefuncs.c:1029
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1800
#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:390
USHORT Flags
Definition: iotypes.h:171
#define FsRtlExitFileSystem
Iosb Status
Definition: create.c:4287
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1797
_In_ PIRP Irp
Definition: csq.h:116
#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:1799
#define VCB_TYPE_FS
Definition: btrfs_drv.h:695
ACCESS_MASK access
Definition: btrfs_drv.h:398
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:279
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1796
bool manage_volume_privilege
Definition: btrfs_drv.h:395
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
#define ALLOC_TAG
Definition: btrfs_drv.h:91
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
long LONG
Definition: pedump.c:60
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:69
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
#define IoCompleteRequest
Definition: irp.c:1240
static bool has_manage_volume_privilege(ACCESS_STATE *access_state, KPROCESSOR_MODE processor_mode)
Definition: create.c:4758
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:88
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:697
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:387
GLbitfield flags
Definition: glext.h:7161
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, PIRP Irp, LIST_ENTRY *rollback)
Definition: create.c:4408
Status
Definition: gdiplustypes.h:24
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
Definition: typedefs.h:119
#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:2789
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1798
#define InterlockedIncrement
Definition: armddk.h:53
ULONG disposition
Definition: btrfs_drv.h:389
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
_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:1357
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:2989
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
bool reserving
Definition: btrfs_drv.h:397
bool lxss
Definition: btrfs_drv.h:407
void exit(int exitcode)
Definition: _exit.c:33
struct _ccb ccb
static NTSTATUS verify_vcb(device_extension *Vcb, PIRP Irp)
Definition: create.c:4696
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
CSHORT NodeSize
Definition: btrfs_drv.h:388
#define VPB_MOUNTED
Definition: iotypes.h:1787
HRESULT Create([out]ITransactionReceiver **ppReceiver)
struct _device_extension * Vcb
Definition: btrfs_drv.h:298
#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 1861 of file create.c.

1861  {
1862  NTSTATUS Status;
1863  dir_child* dc;
1864  bool locked;
1865 
1867  if (!dc) {
1868  ERR("out of memory\n");
1870  }
1871 
1872  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, utf8->Length, ALLOC_TAG);
1873  if (!dc->utf8.Buffer) {
1874  ERR("out of memory\n");
1875  ExFreePool(dc);
1877  }
1878 
1879  dc->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
1880  if (!dc->name.Buffer) {
1881  ERR("out of memory\n");
1882  ExFreePool(dc->utf8.Buffer);
1883  ExFreePool(dc);
1885  }
1886 
1887  dc->key.obj_id = inode;
1888  dc->key.obj_type = subvol ? TYPE_ROOT_ITEM : TYPE_INODE_ITEM;
1889  dc->key.offset = subvol ? 0xffffffffffffffff : 0;
1890  dc->type = type;
1891  dc->fileref = NULL;
1892 
1893  dc->utf8.Length = dc->utf8.MaximumLength = utf8->Length;
1894  RtlCopyMemory(dc->utf8.Buffer, utf8->Buffer, utf8->Length);
1895 
1896  dc->name.Length = dc->name.MaximumLength = name->Length;
1897  RtlCopyMemory(dc->name.Buffer, name->Buffer, name->Length);
1898 
1899  Status = RtlUpcaseUnicodeString(&dc->name_uc, name, true);
1900  if (!NT_SUCCESS(Status)) {
1901  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
1902  ExFreePool(dc->utf8.Buffer);
1903  ExFreePool(dc->name.Buffer);
1904  ExFreePool(dc);
1905  return Status;
1906  }
1907 
1908  dc->hash = calc_crc32c(0xffffffff, (uint8_t*)dc->name.Buffer, dc->name.Length);
1909  dc->hash_uc = calc_crc32c(0xffffffff, (uint8_t*)dc->name_uc.Buffer, dc->name_uc.Length);
1910 
1911  locked = ExIsResourceAcquiredExclusive(&fcb->nonpaged->dir_children_lock);
1912 
1913  if (!locked)
1914  ExAcquireResourceExclusiveLite(&fcb->nonpaged->dir_children_lock, true);
1915 
1917  dc->index = 2;
1918  else {
1919  dir_child* dc2 = CONTAINING_RECORD(fcb->dir_children_index.Blink, dir_child, list_entry_index);
1920 
1921  dc->index = max(2, dc2->index + 1);
1922  }
1923 
1924  InsertTailList(&fcb->dir_children_index, &dc->list_entry_index);
1925 
1927 
1928  if (!locked)
1929  ExReleaseResourceLite(&fcb->nonpaged->dir_children_lock);
1930 
1931  *pdc = dc;
1932 
1933  return STATUS_SUCCESS;
1934 }
#define max(a, b)
Definition: svc.c:63
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
Iosb Status
Definition: create.c:4287
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
LONG NTSTATUS
Definition: precomp.h:26
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#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:91
smooth NULL
Definition: ftsmooth.c:416
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
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:325
#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
Status
Definition: gdiplustypes.h:24
uint64_t index
Definition: btrfs_drv.h:263
#define TYPE_INODE_ITEM
Definition: btrfs.h:19
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:295
#define TYPE_ROOT_ITEM
Definition: btrfs.h:28
void insert_dir_child_into_hash_lists(fcb *fcb, dir_child *dc)
Definition: fileinfo.c:1417
Definition: name.c:38
static const WCHAR dc[]
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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 79 of file create.c.

79  {
80  fcb* fcb;
81 
82  if (pool_type == NonPagedPool) {
83  fcb = ExAllocatePoolWithTag(pool_type, sizeof(struct _fcb), ALLOC_TAG);
84  if (!fcb) {
85  ERR("out of memory\n");
86  return NULL;
87  }
88  } else {
89  fcb = ExAllocateFromPagedLookasideList(&Vcb->fcb_lookaside);
90  if (!fcb) {
91  ERR("out of memory\n");
92  return NULL;
93  }
94  }
95 
96 #ifdef DEBUG_FCB_REFCOUNTS
97  WARN("allocating fcb %p\n", fcb);
98 #endif
99  RtlZeroMemory(fcb, sizeof(struct _fcb));
100  fcb->pool_type = pool_type;
101 
102  fcb->Header.NodeTypeCode = BTRFS_NODE_TYPE_FCB;
103  fcb->Header.NodeByteSize = sizeof(struct _fcb);
104 
105  fcb->nonpaged = ExAllocateFromNPagedLookasideList(&Vcb->fcb_np_lookaside);
106  if (!fcb->nonpaged) {
107  ERR("out of memory\n");
108 
109  if (pool_type == NonPagedPool)
110  ExFreePool(fcb);
111  else
112  ExFreeToPagedLookasideList(&Vcb->fcb_lookaside, fcb);
113 
114  return NULL;
115  }
116  RtlZeroMemory(fcb->nonpaged, sizeof(struct _fcb_nonpaged));
117 
118  ExInitializeResourceLite(&fcb->nonpaged->paging_resource);
119  fcb->Header.PagingIoResource = &fcb->nonpaged->paging_resource;
120 
121  ExInitializeFastMutex(&fcb->nonpaged->HeaderMutex);
122  FsRtlSetupAdvancedHeader(&fcb->Header, &fcb->nonpaged->HeaderMutex);
123 
124  fcb->refcount = 1;
125 #ifdef DEBUG_FCB_REFCOUNTS
126  WARN("fcb %p: refcount now %i\n", fcb, fcb->refcount);
127 #endif
128 
130  fcb->Header.Resource = &fcb->nonpaged->resource;
131 
132  ExInitializeResourceLite(&fcb->nonpaged->dir_children_lock);
133 
136 
140 
144 
145  return fcb;
146 }
#define BTRFS_NODE_TYPE_FCB
Definition: btrfs_drv.h:89
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1261
#define WARN(fmt,...)
Definition: debug.h:112
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ALLOC_TAG
Definition: btrfs_drv.h:91
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
smooth NULL
Definition: ftsmooth.c:416
FILE_LOCK lock
Definition: btrfs_drv.h:305
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:294
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:327
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:325
struct _fcb fcb
Definition: btrfs_drv.h:1357
LIST_ENTRY xattrs
Definition: btrfs_drv.h:319
VOID NTAPI FsRtlInitializeOplock(IN OUT POPLOCK Oplock)
Definition: oplock.c:1402
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
LIST_ENTRY hardlinks
Definition: btrfs_drv.h:315
LIST_ENTRY extents
Definition: btrfs_drv.h:311
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
LONG refcount
Definition: btrfs_drv.h:296
#define ERR(fmt,...)
Definition: debug.h:110
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:295
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static __inline POPLOCK fcb_oplock(fcb *fcb)
Definition: btrfs_drv.h:1683
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:326
POOL_TYPE pool_type
Definition: btrfs_drv.h:297
#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 148 of file create.c.

148  {
149  file_ref* fr;
150 
151  fr = ExAllocateFromPagedLookasideList(&Vcb->fileref_lookaside);
152  if (!fr) {
153  ERR("out of memory\n");
154  return NULL;
155  }
156 
157  RtlZeroMemory(fr, sizeof(file_ref));
158 
159  fr->nonpaged = ExAllocateFromNPagedLookasideList(&Vcb->fileref_np_lookaside);
160  if (!fr->nonpaged) {
161  ERR("out of memory\n");
162  ExFreeToPagedLookasideList(&Vcb->fileref_lookaside, fr);
163  return NULL;
164  }
165 
166  fr->refcount = 1;
167 
168 #ifdef DEBUG_FCB_REFCOUNTS
169  WARN("fileref %p: refcount now 1\n", fr);
170 #endif
171 
173 
175 
176  return fr;
177 }
#define WARN(fmt,...)
Definition: debug.h:112
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
file_ref_nonpaged * nonpaged
Definition: btrfs_drv.h:364
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
smooth NULL
Definition: ftsmooth.c:416
LONG refcount
Definition: btrfs_drv.h:366
ERESOURCE fileref_lock
Definition: btrfs_drv.h:353
LIST_ENTRY children
Definition: btrfs_drv.h:365
#define ERR(fmt,...)
Definition: debug.h:110
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#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 2624 of file create.c.

2626  {
2628  file_ref *fileref, *newpar, *parfileref;
2629  fcb* fcb;
2630  static const char xapref[] = "user.";
2631  static const WCHAR DOSATTRIB[] = L"DOSATTRIB";
2632  static const WCHAR EA[] = L"EA";
2633  static const WCHAR reparse[] = L"reparse";
2634  static const WCHAR casesensitive_str[] = L"casesensitive";
2636  BTRFS_TIME now;
2637  ULONG utf8len, overhead;
2638  NTSTATUS Status;
2639  KEY searchkey;
2640  traverse_ptr tp;
2641  dir_child* dc;
2642  dir_child* existing_dc = NULL;
2643  ACCESS_MASK granted_access;
2644 #ifdef DEBUG_FCB_REFCOUNTS
2645  LONG rc;
2646 #endif
2647 #ifdef __REACTOS__
2648  LIST_ENTRY* le;
2649 #endif
2650 
2651  TRACE("fpus = %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer);
2652  TRACE("stream = %.*S\n", (int)(stream->Length / sizeof(WCHAR)), stream->Buffer);
2653 
2654  parfileref = *pparfileref;
2655 
2656  if (parfileref->fcb == Vcb->dummy_fcb)
2657  return STATUS_ACCESS_DENIED;
2658 
2659  Status = open_fileref(Vcb, &newpar, fpus, parfileref, false, NULL, NULL, PagedPool, case_sensitive, Irp);
2660 
2662  UNICODE_STRING fpus2;
2663 
2664  if (!is_file_name_valid(fpus, false, true))
2666 
2667  fpus2.Length = fpus2.MaximumLength = fpus->Length;
2669 
2670  if (!fpus2.Buffer) {
2671  ERR("out of memory\n");
2673  }
2674 
2675  RtlCopyMemory(fpus2.Buffer, fpus->Buffer, fpus2.Length);
2676 
2677  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2678 
2679  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2682  &granted_access, &Status)) {
2683  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2684  return Status;
2685  }
2686 
2687  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2688 
2689  Status = file_create2(Irp, Vcb, &fpus2, parfileref, options, NULL, 0, &newpar, case_sensitive, rollback);
2690 
2691  if (!NT_SUCCESS(Status)) {
2692  ERR("file_create2 returned %08lx\n", Status);
2693  ExFreePool(fpus2.Buffer);
2694  return Status;
2695  } else if (Status != STATUS_OBJECT_NAME_COLLISION) {
2698  }
2699 
2700  ExFreePool(fpus2.Buffer);
2701  } else if (!NT_SUCCESS(Status)) {
2702  ERR("open_fileref returned %08lx\n", Status);
2703  return Status;
2704  }
2705 
2706  parfileref = newpar;
2707  *pparfileref = parfileref;
2708 
2709  if (parfileref->fcb->type != BTRFS_TYPE_FILE && parfileref->fcb->type != BTRFS_TYPE_SYMLINK && parfileref->fcb->type != BTRFS_TYPE_DIRECTORY) {
2710  WARN("parent not file, directory, or symlink\n");
2711  free_fileref(parfileref);
2712  return STATUS_INVALID_PARAMETER;
2713  }
2714 
2715  if (options & FILE_DIRECTORY_FILE) {
2716  WARN("tried to create directory as stream\n");
2717  free_fileref(parfileref);
2718  return STATUS_INVALID_PARAMETER;
2719  }
2720 
2721  if (parfileref->fcb->atts & FILE_ATTRIBUTE_READONLY) {
2722  free_fileref(parfileref);
2723  return STATUS_ACCESS_DENIED;
2724  }
2725 
2726  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2727 
2728  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2730  &granted_access, &Status)) {
2731  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2732  free_fileref(parfileref);
2733  return Status;
2734  }
2735 
2736  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2737 
2738  if ((stream->Length == sizeof(DOSATTRIB) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, DOSATTRIB, stream->Length) == stream->Length) ||
2739  (stream->Length == sizeof(EA) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, EA, stream->Length) == stream->Length) ||
2740  (stream->Length == sizeof(reparse) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, reparse, stream->Length) == stream->Length) ||
2741  (stream->Length == sizeof(casesensitive_str) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, casesensitive_str, stream->Length) == stream->Length)) {
2742  free_fileref(parfileref);
2744  }
2745 
2747  if (!fcb) {
2748  ERR("out of memory\n");
2749  free_fileref(parfileref);
2751  }
2752 
2753  fcb->Vcb = Vcb;
2754 
2755  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2756  fcb->Header.AllocationSize.QuadPart = 0;
2757  fcb->Header.FileSize.QuadPart = 0;
2758  fcb->Header.ValidDataLength.QuadPart = 0;
2759 
2760 #ifdef DEBUG_FCB_REFCOUNTS
2761  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2762  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2763 #else
2764  InterlockedIncrement(&parfileref->fcb->refcount);
2765 #endif
2766  fcb->subvol = parfileref->fcb->subvol;
2767  fcb->inode = parfileref->fcb->inode;
2768  fcb->type = parfileref->fcb->type;
2769 
2770  fcb->ads = true;
2771 
2772  Status = utf16_to_utf8(NULL, 0, &utf8len, stream->Buffer, stream->Length);
2773  if (!NT_SUCCESS(Status)) {
2774  ERR("utf16_to_utf8 1 returned %08lx\n", Status);
2775  reap_fcb(fcb);
2776  free_fileref(parfileref);
2777  return Status;
2778  }
2779 
2780  fcb->adsxattr.Length = (uint16_t)utf8len + sizeof(xapref) - 1;
2783  if (!fcb->adsxattr.Buffer) {
2784  ERR("out of memory\n");
2785  reap_fcb(fcb);
2786  free_fileref(parfileref);
2788  }
2789 
2790  RtlCopyMemory(fcb->adsxattr.Buffer, xapref, sizeof(xapref) - 1);
2791 
2792  Status = utf16_to_utf8(&fcb->adsxattr.Buffer[sizeof(xapref) - 1], utf8len, &utf8len, stream->Buffer, stream->Length);
2793  if (!NT_SUCCESS(Status)) {
2794  ERR("utf16_to_utf8 2 returned %08lx\n", Status);
2795  reap_fcb(fcb);
2796  free_fileref(parfileref);
2797  return Status;
2798  }
2799 
2801 
2802  TRACE("adsxattr = %s\n", fcb->adsxattr.Buffer);
2803 
2805  TRACE("adshash = %08x\n", fcb->adshash);
2806 
2807  searchkey.obj_id = parfileref->fcb->inode;
2808  searchkey.obj_type = TYPE_XATTR_ITEM;
2809  searchkey.offset = fcb->adshash;
2810 
2811  Status = find_item(Vcb, parfileref->fcb->subvol, &tp, &searchkey, false, Irp);
2812  if (!NT_SUCCESS(Status)) {
2813  ERR("find_item returned %08lx\n", Status);
2814  reap_fcb(fcb);
2815  free_fileref(parfileref);
2816  return Status;
2817  }
2818 
2819  if (!keycmp(tp.item->key, searchkey))
2820  overhead = tp.item->size;
2821  else
2822  overhead = 0;
2823 
2824  fcb->adsmaxlen = Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - (sizeof(DIR_ITEM) - 1);
2825 
2826  if (utf8len + sizeof(xapref) - 1 + overhead > fcb->adsmaxlen) {
2827  WARN("not enough room for new DIR_ITEM (%Iu + %lu > %lu)", utf8len + sizeof(xapref) - 1, overhead, fcb->adsmaxlen);
2828  reap_fcb(fcb);
2829  free_fileref(parfileref);
2830  return STATUS_DISK_FULL;
2831  } else
2832  fcb->adsmaxlen -= overhead + utf8len + sizeof(xapref) - 1;
2833 
2834  fcb->created = true;
2835  fcb->deleted = true;
2836 
2837  acquire_fcb_lock_exclusive(Vcb);
2838  InsertHeadList(&parfileref->fcb->list_entry, &fcb->list_entry); // insert in list after parent fcb
2839  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2840  parfileref->fcb->subvol->fcbs_version++;
2841  release_fcb_lock(Vcb);
2842 
2844 
2846  if (!fileref) {
2847  ERR("out of memory\n");
2848  free_fcb(fcb);
2849  free_fileref(parfileref);
2851  }
2852 
2853  fileref->fcb = fcb;
2854 
2856  if (!dc) {
2857  ERR("out of memory\n");
2859  free_fileref(parfileref);
2861  }
2862 
2863  RtlZeroMemory(dc, sizeof(dir_child));
2864 
2865  dc->utf8.MaximumLength = dc->utf8.Length = fcb->adsxattr.Length + 1 - sizeof(xapref);
2866  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, dc->utf8.MaximumLength, ALLOC_TAG);
2867  if (!dc->utf8.Buffer) {
2868  ERR("out of memory\n");
2869  ExFreePool(dc);
2871  free_fileref(parfileref);
2873  }
2874 
2875  RtlCopyMemory(dc->utf8.Buffer, &fcb->adsxattr.Buffer[sizeof(xapref) - 1], fcb->adsxattr.Length + 1 - sizeof(xapref));
2876 
2877  dc->name.MaximumLength = dc->name.Length = stream->Length;
2878  dc->name.Buffer = ExAllocatePoolWithTag(pool_type, dc->name.MaximumLength, ALLOC_TAG);
2879  if (!dc->name.Buffer) {
2880  ERR("out of memory\n");
2881  ExFreePool(dc->utf8.Buffer);
2882  ExFreePool(dc);
2884  free_fileref(parfileref);
2886  }
2887 
2888  RtlCopyMemory(dc->name.Buffer, stream->Buffer, stream->Length);
2889 
2890  Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true);
2891  if (!NT_SUCCESS(Status)) {
2892  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
2893  ExFreePool(dc->utf8.Buffer);
2894  ExFreePool(dc->name.Buffer);
2895  ExFreePool(dc);
2897  free_fileref(parfileref);
2898  return Status;
2899  }
2900 
2903 
2904  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2905 
2906 #ifndef __REACTOS__
2907  LIST_ENTRY* le = parfileref->fcb->dir_children_index.Flink;
2908 #else
2909  le = parfileref->fcb->dir_children_index.Flink;
2910 #endif
2911  while (le != &parfileref->fcb->dir_children_index) {
2912  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
2913 
2914  if (dc2->index == 0) {
2915  if ((case_sensitive && dc2->name.Length == dc->name.Length && RtlCompareMemory(dc2->name.Buffer, dc->name.Buffer, dc2->name.Length) == dc2->name.Length) ||
2916  (!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)
2917  ) {
2918  existing_dc = dc2;
2919  break;
2920  }
2921  } else
2922  break;
2923 
2924  le = le->Flink;
2925  }
2926 
2927  if (existing_dc) {
2928  ExFreePool(dc->utf8.Buffer);
2929  ExFreePool(dc->name.Buffer);
2930  ExFreePool(dc);
2932  free_fileref(parfileref);
2933 
2934  increase_fileref_refcount(existing_dc->fileref);
2935  *pfileref = existing_dc->fileref;
2936 
2938  }
2939 
2940  dc->fileref = fileref;
2941  fileref->dc = dc;
2942  fileref->parent = (struct _file_ref*)parfileref;
2943  fcb->deleted = false;
2944 
2945  InsertHeadList(&parfileref->fcb->dir_children_index, &dc->list_entry_index);
2946 
2947  InsertTailList(&parfileref->children, &fileref->list_entry);
2948 
2949  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2950 
2951  mark_fileref_dirty(fileref);
2952 
2953  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2954  parfileref->fcb->inode_item.sequence++;
2955  parfileref->fcb->inode_item.st_ctime = now;
2956  parfileref->fcb->inode_item_changed = true;
2957 
2958  mark_fcb_dirty(parfileref->fcb);
2959 
2960  parfileref->fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2961  parfileref->fcb->subvol->root_item.ctime = now;
2962 
2963  increase_fileref_refcount(parfileref);
2964 
2965  *pfileref = fileref;
2966 
2968 
2969  return STATUS_SUCCESS;
2970 }
#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:368
uint64_t obj_id
Definition: btrfs.h:137
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)
Definition: accesschk.c:340
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _file_ref * fileref
Definition: btrfs_drv.h:271
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:1680
uint8_t obj_type
Definition: btrfs.h:138
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
VOID NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:336
file_ref * create_fileref(device_extension *Vcb)
Definition: create.c:148
uint32_t adshash
Definition: btrfs_drv.h:342
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1664
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:2164
Iosb Status
Definition: create.c:4287
UNICODE_STRING name_uc
Definition: btrfs_drv.h:269
_In_ PIRP Irp
Definition: csq.h:116
#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:1024
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
uint16_t size
Definition: btrfs_drv.h:430
VOID NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:314
#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:1806
#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:1449
BTRFS_TIME st_ctime
Definition: btrfs.h:294
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1796
uint64_t offset
Definition: btrfs.h:139
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:348
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:79
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:91
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1597
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:304
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1647
#define FILE_ADD_FILE
Definition: nt_native.h:632
long LONG
Definition: pedump.c:60
LIST_ENTRY list_entry
Definition: btrfs_drv.h:347
uint64_t sequence
Definition: btrfs.h:291
time_t now
Definition: finger.c:65
#define FILE_ACTION_MODIFIED
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
void reap_fcb(fcb *fcb)
Definition: btrfs.c:1673
smooth NULL
Definition: ftsmooth.c:416
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1625
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:672
uint8_t type
Definition: btrfs_drv.h:302
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1785
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:2930
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:294
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define TYPE_XATTR_ITEM
Definition: btrfs.h:22
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:325
struct _fcb fcb
Definition: btrfs_drv.h:1357
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t inode
Definition: btrfs_drv.h:300
#define FILE_NOTIFY_CHANGE_STREAM_NAME
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
struct _file_ref * fileref
Definition: btrfs_drv.h:316
bool case_sensitive
Definition: btrfs_drv.h:321
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
dir_child * dc
Definition: btrfs_drv.h:369
tree_data * item
Definition: btrfs_drv.h:518
LIST_ENTRY children
Definition: btrfs_drv.h:365
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
LONG refcount
Definition: btrfs_drv.h:296
Definition: parse.h:22
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
uint64_t index
Definition: btrfs_drv.h:263
crc_func calc_crc32c
Definition: crc32c.c:23
bool created
Definition: btrfs_drv.h:339
fcb * fcb
Definition: btrfs_drv.h:357
Definition: typedefs.h:119
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1690
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
BYTE uint8_t
Definition: msvideo1.c:66
bool is_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5724
#define ERR(fmt,...)
Definition: debug.h:110
Definition: btrfs.h:136
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULONG atts
Definition: btrfs_drv.h:308
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:295
bool deleted
Definition: btrfs_drv.h:306
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
uint64_t transid
Definition: btrfs.h:281
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
struct _root * subvol
Definition: btrfs_drv.h:299
ULONG adsmaxlen
Definition: btrfs_drv.h:343
_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:1357
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1786
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
bool ads
Definition: btrfs_drv.h:341
#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:997
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR dc[]
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
bool inode_item_changed
Definition: btrfs_drv.h:317
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:298
POOL_TYPE pool_type
Definition: btrfs_drv.h:297
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UNICODE_STRING name
Definition: btrfs_drv.h:267
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
ANSI_STRING adsxattr
Definition: btrfs_drv.h:344
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
LIST_ENTRY list_entry
Definition: btrfs_drv.h:373

Referenced by file_create().

◆ debug_create_options()

static __inline void debug_create_options ( ULONG  RequestedOptions)
static

Definition at line 3283 of file create.c.

3283  {
3284  if (RequestedOptions != 0) {
3285  ULONG options = RequestedOptions;
3286 
3287  TRACE("requested options:\n");
3288 
3289  if (options & FILE_DIRECTORY_FILE) {
3290  TRACE(" FILE_DIRECTORY_FILE\n");
3292  }
3293 
3294  if (options & FILE_WRITE_THROUGH) {
3295  TRACE(" FILE_WRITE_THROUGH\n");
3297  }
3298 
3299  if (options & FILE_SEQUENTIAL_ONLY) {
3300  TRACE(" FILE_SEQUENTIAL_ONLY\n");
3302  }
3303 
3305  TRACE(" FILE_NO_INTERMEDIATE_BUFFERING\n");
3307  }
3308 
3310  TRACE(" FILE_SYNCHRONOUS_IO_ALERT\n");
3312  }
3313 
3315  TRACE(" FILE_SYNCHRONOUS_IO_NONALERT\n");
3317  }
3318 
3320  TRACE(" FILE_NON_DIRECTORY_FILE\n");
3322  }
3323 
3325  TRACE(" FILE_CREATE_TREE_CONNECTION\n");
3327  }
3328 
3330  TRACE(" FILE_COMPLETE_IF_OPLOCKED\n");
3332  }
3333 
3334  if (options & FILE_NO_EA_KNOWLEDGE) {
3335  TRACE(" FILE_NO_EA_KNOWLEDGE\n");
3337  }
3338 
3340  TRACE(" FILE_OPEN_REMOTE_INSTANCE\n");
3342  }
3343 
3344  if (options & FILE_RANDOM_ACCESS) {
3345  TRACE(" FILE_RANDOM_ACCESS\n");
3347  }
3348 
3349  if (options & FILE_DELETE_ON_CLOSE) {
3350  TRACE(" FILE_DELETE_ON_CLOSE\n");
3352  }
3353 
3354  if (options & FILE_OPEN_BY_FILE_ID) {
3355  TRACE(" FILE_OPEN_BY_FILE_ID\n");
3357  }
3358 
3360  TRACE(" FILE_OPEN_FOR_BACKUP_INTENT\n");
3362  }
3363 
3364  if (options & FILE_NO_COMPRESSION) {
3365  TRACE(" FILE_NO_COMPRESSION\n");
3367  }
3368 
3369 #if NTDDI_VERSION >= NTDDI_WIN7
3371  TRACE(" FILE_OPEN_REQUIRING_OPLOCK\n");
3373  }
3374 
3376  TRACE(" FILE_DISALLOW_EXCLUSIVE\n");
3378  }
3379 #endif
3380 
3382  TRACE(" FILE_RESERVE_OPFILTER\n");
3384  }
3385 
3387  TRACE(" FILE_OPEN_REPARSE_POINT\n");
3389  }
3390 
3391  if (options & FILE_OPEN_NO_RECALL) {
3392  TRACE(" FILE_OPEN_NO_RECALL\n");
3394  }
3395 
3397  TRACE(" FILE_OPEN_FOR_FREE_SPACE_QUERY\n");
3399  }
3400 
3401  if (options)
3402  TRACE(" unknown options: %lx\n", options);
3403  } else {
3404  TRACE("requested options: (none)\n");
3405  }
3406 }
#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 3530 of file create.c.

3530  {
3531  LIST_ENTRY* le;
3532  NTSTATUS Status;
3533 
3534  if (fcb->csum_loaded)
3535  return;
3536 
3538  goto end;
3539 
3540  le = fcb->extents.Flink;
3541  while (le != &fcb->extents) {
3543 
3544  if (!ext->ignore && ext->extent_data.type == EXTENT_TYPE_REGULAR) {
3545  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)&ext->extent_data.data[0];
3546  uint64_t len;
3547 
3548  len = (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->num_bytes : ed2->size) / Vcb->superblock.sector_size;
3549 
3550  ext->csum = ExAllocatePoolWithTag(NonPagedPool, (ULONG)(len * Vcb->csum_size), ALLOC_TAG);
3551  if (!ext->csum) {
3552  ERR("out of memory\n");
3553  goto end;
3554  }
3555 
3556  Status = load_csum(Vcb, ext->csum, ed2->address + (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->offset : 0), len, Irp);
3557 
3558  if (!NT_SUCCESS(Status)) {
3559  ERR("load_csum returned %08lx\n", Status);
3560  goto end;
3561  }
3562  }
3563 
3564  le = le->Flink;
3565  }
3566 
3567 end:
3568  fcb->csum_loaded = true;
3569 }
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:61
EXTENT_DATA2 * ed2
Definition: write.c:2805
Iosb Status
Definition: create.c:4287
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
GLuint GLuint end
Definition: gl.h:1545
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define ALLOC_TAG
Definition: btrfs_drv.h:91
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
uint64_t address
Definition: btrfs.h:356
char ext[3]
Definition: mkdosfs.c:358
uint64_t size
Definition: btrfs.h:357
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, void *csum, uint64_t start, uint64_t length, PIRP Irp)
Definition: create.c:446
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
LIST_ENTRY extents
Definition: btrfs_drv.h:311
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
uint64_t num_bytes
Definition: btrfs.h:359
uint64_t flags
Definition: btrfs.h:290
#define EXTENT_TYPE_REGULAR
Definition: btrfs.h:71
#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:358
bool csum_loaded
Definition: btrfs_drv.h:310

Referenced by open_file().

◆ 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 2992 of file create.c.

2994  {
2995  NTSTATUS Status;
2996  file_ref *fileref, *parfileref = NULL;
2997  ULONG i, j;
2998  ccb* ccb;
2999  static const WCHAR datasuf[] = {':','$','D','A','T','A',0};
3000  UNICODE_STRING dsus, fpus, stream;
3003  ECP_LIST* ecp_list;
3005 #ifdef DEBUG_FCB_REFCOUNTS
3006  LONG oc;
3007 #endif
3008 
3009  TRACE("(%p, %p, %p, %.*S, %lx, %lx)\n", Irp, Vcb, FileObject, (int)(fnus->Length / sizeof(WCHAR)), fnus->Buffer, disposition, options);
3010 
3011  if (Vcb->readonly)
3013 
3015  return STATUS_CANNOT_DELETE;
3016 
3018  if (NT_SUCCESS(fFsRtlGetEcpListFromIrp(Irp, &ecp_list)) && ecp_list) {
3019  void* ctx = NULL;
3020  GUID type;
3021  ULONG ctxsize;
3022 
3023  do {
3024  Status = fFsRtlGetNextExtraCreateParameter(ecp_list, ctx, &type, &ctx, &ctxsize);
3025 
3026  if (NT_SUCCESS(Status)) {
3027  if (RtlCompareMemory(&type, &GUID_ECP_ATOMIC_CREATE, sizeof(GUID)) == sizeof(GUID)) {
3028  if (ctxsize >= sizeof(ATOMIC_CREATE_ECP_CONTEXT))
3029  acec = ctx;
3030  else {
3031  ERR("GUID_ECP_ATOMIC_CREATE context was too short: %lu bytes, expected %Iu\n", ctxsize,
3032  sizeof(ATOMIC_CREATE_ECP_CONTEXT));
3033  }
3034  } else if (RtlCompareMemory(&type, &GUID_ECP_QUERY_ON_CREATE, sizeof(GUID)) == sizeof(GUID))
3035  WARN("unhandled ECP GUID_ECP_QUERY_ON_CREATE\n");
3036  else if (RtlCompareMemory(&type, &GUID_ECP_CREATE_REDIRECTION, sizeof(GUID)) == sizeof(GUID))
3037  WARN("unhandled ECP GUID_ECP_CREATE_REDIRECTION\n");
3038  else {
3039  WARN("unhandled ECP {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", type.Data1, type.Data2,
3040  type.Data3, type.Data4[0], type.Data4[1], type.Data4[2], type.Data4[3], type.Data4[4], type.Data4[5],
3041  type.Data4[6], type.Data4[7]);
3042  }
3043  }
3044  } while (NT_SUCCESS(Status));
3045  }
3046  }
3047 
3048  dsus.Buffer = (WCHAR*)datasuf;
3049  dsus.Length = dsus.MaximumLength = sizeof(datasuf) - sizeof(WCHAR);
3050  fpus.Buffer = NULL;
3051 
3052  if (!loaded_related) {
3053  Status = open_fileref(Vcb, &parfileref, fnus, related, true, NULL, NULL, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, Irp);
3054 
3055  if (!NT_SUCCESS(Status))
3056  goto end;
3057  } else
3058  parfileref = related;
3059 
3060  if (parfileref->fcb->type != BTRFS_TYPE_DIRECTORY && (fnus->Length < sizeof(WCHAR) || fnus->Buffer[0] != ':')) {
3062  goto end;
3063  }
3064 
3065  if (is_subvol_readonly(parfileref->fcb->subvol, Irp)) {
3067  goto end;
3068  }
3069 
3070  i = (fnus->Length / sizeof(WCHAR))-1;
3071  while ((fnus->Buffer[i] == '\\' || fnus->Buffer[i] == '/') && i > 0) { i--; }
3072 
3073  j = i;
3074 
3075  while (i > 0 && fnus->Buffer[i-1] != '\\' && fnus->Buffer[i-1] != '/') { i--; }
3076 
3077  fpus.MaximumLength = (USHORT)((j - i + 2) * sizeof(WCHAR));
3078  fpus.Buffer = ExAllocatePoolWithTag(pool_type, fpus.MaximumLength, ALLOC_TAG);
3079  if (!fpus.Buffer) {
3080  ERR("out of memory\n");
3082  goto end;
3083  }
3084 
3085  fpus.Length = (USHORT)((j - i + 1) * sizeof(WCHAR));
3086 
3087  RtlCopyMemory(fpus.Buffer, &fnus->Buffer[i], (j - i + 1) * sizeof(WCHAR));
3088  fpus.Buffer[j - i + 1] = 0;
3089 
3090  if (fpus.Length > dsus.Length) { // check for :$DATA suffix
3091  UNICODE_STRING lb;
3092 
3093  lb.Buffer = &fpus.Buffer[(fpus.Length - dsus.Length)/sizeof(WCHAR)];
3094  lb.Length = lb.MaximumLength = dsus.Length;
3095 
3096  TRACE("lb = %.*S\n", (int)(lb.Length/sizeof(WCHAR)), lb.Buffer);
3097 
3098  if (FsRtlAreNamesEqual(&dsus, &lb, true, NULL)) {
3099  TRACE("ignoring :$DATA suffix\n");
3100 
3101  fpus.Length -= lb.Length;
3102 
3103  if (fpus.Length > sizeof(WCHAR) && fpus.Buffer[(fpus.Length-1)/sizeof(WCHAR)] == ':')
3104  fpus.Length -= sizeof(WCHAR);
3105 
3106  TRACE("fpus = %.*S\n", (int)(fpus.Length / sizeof(WCHAR)), fpus.Buffer);
3107  }
3108  }
3109 
3110  stream.Length = 0;
3111 
3112  for (i = 0; i < fpus.Length / sizeof(WCHAR); i++) {
3113  if (fpus.Buffer[i] == ':') {
3114  stream.Length = (USHORT)(fpus.Length - (i * sizeof(WCHAR)) - sizeof(WCHAR));
3115  stream.Buffer = &fpus.Buffer[i+1];
3116  fpus.Buffer[i] = 0;
3117  fpus.Length = (USHORT)(i * sizeof(WCHAR));
3118  break;
3119  }
3120  }
3121 
3122  if (stream.Length > 0) {
3123  Status = create_stream(Vcb, &fileref, &parfileref, &fpus, &stream, Irp, options, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3124  if (!NT_SUCCESS(Status)) {
3125  ERR("create_stream returned %08lx\n", Status);
3126  goto end;
3127  }
3128 
3129  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess,
3130  FileObject, &fileref->fcb->share_access);
3131  } else {
3132  ACCESS_MASK granted_access;
3133 
3134  if (!is_file_name_valid(&fpus, false, false)) {
3136  goto end;
3137  }
3138 
3139  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3140 
3141  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
3144  &granted_access, &Status)) {
3145  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3146  goto end;
3147  }
3148 
3149  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3150 
3151  if (Irp->AssociatedIrp.SystemBuffer && IrpSp->Parameters.Create.EaLength > 0) {
3152  ULONG offset;
3153 
3154  Status = IoCheckEaBufferValidity(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength, &offset);
3155  if (!NT_SUCCESS(Status)) {
3156  ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset);
3157  goto end;
3158  }
3159  }
3160 
3161  Status = file_create2(Irp, Vcb, &fpus, parfileref, options, Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength,
3162  &fileref, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3163 
3165  *existing_fileref = fileref;
3166  goto end;
3167  } else if (!NT_SUCCESS(Status)) {
3168  ERR("file_create2 returned %08lx\n", Status);
3169  goto end;
3170  }
3171 
3172  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess, FileObject, &fileref->fcb->share_access);
3173 
3176  }
3177 
3178  FileObject->FsContext = fileref->fcb;
3179 
3181  if (!ccb) {
3182  ERR("out of memory\n");
3184  fileref->deleted = true;
3185  fileref->fcb->deleted = true;
3186 
3187  if (stream.Length == 0) {
3188  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3189  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3190  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3191  }
3192 
3193  free_fileref(fileref);
3194  goto end;
3195  }
3196 
3197  RtlZeroMemory(ccb, sizeof(*ccb));
3198 
3199  ccb->fileref = fileref;
3200 
3202  ccb->NodeSize = sizeof(*ccb);
3203  ccb->disposition = disposition;
3204  ccb->options = options;
3205  ccb->query_dir_offset = 0;
3207  ccb->has_wildcard = false;
3208  ccb->specific_file = false;
3209  ccb->access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3211  ccb->reserving = false;
3212  ccb->lxss = called_from_lxss();
3213 
3214 #ifdef DEBUG_FCB_REFCOUNTS
3215  oc = InterlockedIncrement(&fileref->open_count);
3216  ERR("fileref %p: open_count now %i\n", fileref, oc);
3217 #else
3218  InterlockedIncrement(&fileref->open_count);
3219 #endif
3220  InterlockedIncrement(&Vcb->open_files);
3221 
3222  FileObject->FsContext2 = ccb;
3223 
3224  FileObject->SectionObjectPointer = &fileref->fcb->nonpaged->segment_object;
3225 
3226  // FIXME - ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT
3228  if (acec->ReparseBufferLength > sizeof(uint32_t) && *(uint32_t*)acec->ReparseBuffer == IO_REPARSE_TAG_SYMLINK) {
3230  fileref->fcb->type = BTRFS_TYPE_FILE;
3231  }
3232 
3233  if (fileref->fcb->type == BTRFS_TYPE_SOCKET || fileref->fcb->type == BTRFS_TYPE_FIFO ||
3234  fileref->fcb->type == BTRFS_TYPE_CHARDEV || fileref->fcb->type == BTRFS_TYPE_BLOCKDEV) {
3235  // NOP. If called from LXSS, humour it - we hardcode the values elsewhere.
3236  } else {
3238  if (!NT_SUCCESS(Status)) {
3239  ERR("set_reparse_point2 returned %08lx\n", Status);
3240  fileref->deleted = true;
3241  fileref->fcb->deleted = true;
3242 
3243  if (stream.Length == 0) {
3244  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3245  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3246  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3247  }
3248 
3249  free_fileref(fileref);
3250  return Status;
3251  }
3252  }
3253 
3255  }
3256 
3261  fileref->fcb->case_sensitive = true;
3262  ccb->case_sensitive = true;
3263  }
3264 
3266  }
3267 
3269  }
3270 
3271  fileref->dc->type = fileref->fcb->type;
3272 
3273 end:
3274  if (fpus.Buffer)
3275  ExFreePool(fpus.Buffer);
3276 
3277  if (parfileref && !loaded_related)
3278  free_fileref(parfileref);
3279 
3280  return Status;
3281 }
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:368
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)
Definition: accesschk.c:340
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
static const GUID GUID_ECP_QUERY_ON_CREATE
Definition: create.c:76
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:1680
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1800
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:336
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
ULONG options
Definition: btrfs_drv.h:390
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:2164
Iosb Status
Definition: create.c:4287
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1797
_In_ PIRP Irp
Definition: csq.h:116
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define __S_IFSOCK
Definition: btrfs_drv.h:1806
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
GLintptr offset
Definition: glext.h:5920
VOID NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:314
#define ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED
Definition: create.c:43
ANSI_STRING utf8
Definition: btrfs_drv.h:265
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#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
GLuint GLuint end
Definition: gl.h:1545
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:367
ACCESS_MASK access
Definition: btrfs_drv.h:398
#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:1449
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1796
bool has_wildcard
Definition: btrfs_drv.h:393
UNICODE_STRING query_string
Definition: btrfs_drv.h:392
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:91
PREPARSE_DATA_BUFFER ReparseBuffer
Definition: create.c:58
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1597
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
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:304
#define FILE_ADD_FILE
Definition: nt_native.h:632
static __inline bool is_subvol_readonly(root *r, PIRP Irp)
Definition: btrfs_drv.h:1041
static const GUID GUID_ECP_ATOMIC_CREATE
Definition: create.c:75
long LONG
Definition: pedump.c:60
#define ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED
Definition: create.c:41
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4137
#define FILE_ACTION_MODIFIED
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
bool specific_file
Definition: btrfs_drv.h:394
smooth NULL
Definition: ftsmooth.c:416
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:302
int options
Definition: main.c:106
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:88
#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:294
#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET
Definition: create.c:40
bool deleted
Definition: btrfs_drv.h:362
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
uint64_t st_size
Definition: btrfs.h:282
#define TRACE(s)
Definition: solgame.cpp:4
__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:2624
INT POOL_TYPE
Definition: typedefs.h:78
static const GUID GUID_ECP_CREATE_REDIRECTION
Definition: create.c:77
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_CS_FLAG_CASE_SENSITIVE_DIR
Definition: btrfs_drv.h:167
#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:321
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __S_IFIFO
Definition: btrfs_drv.h:1804
#define __S_IFCHR
Definition: btrfs_drv.h:1801
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
USHORT NodeType
Definition: btrfs_drv.h:387
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
dir_child * dc
Definition: btrfs_drv.h:369
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
Status
Definition: gdiplustypes.h:24
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
bool case_sensitive
Definition: btrfs_drv.h:402
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
fcb * fcb
Definition: btrfs_drv.h:357
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
bool is_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5724
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define InterlockedIncrement
Definition: armddk.h:53
ULONG atts
Definition: btrfs_drv.h:308
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:295
unsigned short USHORT
Definition: pedump.c:61
bool deleted
Definition: btrfs_drv.h:306
uint8_t type
Definition: btrfs_drv.h:264
ULONG disposition
Definition: btrfs_drv.h:389
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
struct _root * subvol
Definition: btrfs_drv.h:299
_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:1357
UINT32 uint32_t
Definition: types.h:75
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1786
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define called_from_lxss()
Definition: create.c:2989
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
Definition: btrfs.c:102
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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:273
tFsRtlGetEcpListFromIrp fFsRtlGetEcpListFromIrp
Definition: btrfs.c:101
bool reserving
Definition: btrfs_drv.h:397
#define __S_IFBLK
Definition: btrfs_drv.h:1802
bool lxss
Definition: btrfs_drv.h:407
SHARE_ACCESS share_access
Definition: btrfs_drv.h:309
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:399
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
CSHORT NodeSize
Definition: btrfs_drv.h:388
uint64_t query_dir_offset
Definition: btrfs_drv.h:391
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7219
HRESULT Create([out]ITransactionReceiver **ppReceiver)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t st_mode
Definition: btrfs.h:288

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 2164 of file create.c.

2166  {
2167  NTSTATUS Status;
2168  fcb* fcb;
2169  ULONG utf8len;
2170  char* utf8 = NULL;
2171  uint64_t inode;
2172  uint8_t type;
2174  BTRFS_TIME now;
2177  USHORT defda;
2178  file_ref* fileref;
2179  dir_child* dc;
2180  ANSI_STRING utf8as;
2181  LIST_ENTRY* lastle = NULL;
2182  file_ref* existing_fileref = NULL;
2183 #ifdef DEBUG_FCB_REFCOUNTS
2184  LONG rc;
2185 #endif
2186 
2187  if (parfileref->fcb == Vcb->dummy_fcb)
2188  return STATUS_ACCESS_DENIED;
2189 
2191  return STATUS_INVALID_PARAMETER;
2192 
2193  Status = utf16_to_utf8(NULL, 0, &utf8len, fpus->Buffer, fpus->Length);
2194  if (!NT_SUCCESS(Status)) {
2195  ERR("utf16_to_utf8 returned %08lx\n", Status);
2196  return Status;
2197  }
2198 
2199  utf8 = ExAllocatePoolWithTag(pool_type, utf8len + 1, ALLOC_TAG);
2200  if (!utf8) {
2201  ERR("out of memory\n");
2203  }
2204 
2205  Status = utf16_to_utf8(utf8, utf8len, &utf8len, fpus->Buffer, fpus->Length);
2206  if (!NT_SUCCESS(Status)) {
2207  ERR("utf16_to_utf8 returned %08lx\n", Status);
2208  ExFreePool(utf8);
2209  return Status;
2210  }
2211 
2212  utf8[utf8len] = 0;
2213 
2216 
2217  TRACE("create file %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer);
2218  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2219  TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) was %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size);
2220  parfileref->fcb->inode_item.st_size += utf8len * 2;
2221  TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) now %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size);
2222  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2223  parfileref->fcb->inode_item.sequence++;
2224  parfileref->fcb->inode_item.st_ctime = now;
2225  parfileref->fcb->inode_item.st_mtime = now;
2226  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2227 
2228  parfileref->fcb->inode_item_changed = true;
2229  mark_fcb_dirty(parfileref->fcb);
2230 
2231  inode = InterlockedIncrement64(&parfileref->fcb->subvol->lastinode);
2232 
2234 
2235  // FIXME - link FILE_ATTRIBUTE_READONLY to st_mode
2236 
2237  TRACE("requested attributes = %x\n", IrpSp->Parameters.Create.FileAttributes);
2238 
2239  defda = 0;
2240 
2241  if (utf8[0] == '.')
2242  defda |= FILE_ATTRIBUTE_HIDDEN;
2243 
2244  if (options & FILE_DIRECTORY_FILE) {
2245  defda |= FILE_ATTRIBUTE_DIRECTORY;
2246  IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
2247  } else
2248  IrpSp->Parameters.Create.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
2249 
2250  if (!(IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2251  IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
2252  defda |= FILE_ATTRIBUTE_ARCHIVE;
2253  }
2254 
2255  TRACE("defda = %x\n", defda);
2256 
2257  if (IrpSp->Parameters.Create.FileAttributes == FILE_ATTRIBUTE_NORMAL)
2258  IrpSp->Parameters.Create.FileAttributes = defda;
2259 
2260  fcb = create_fcb(Vcb, pool_type);
2261  if (!fcb) {
2262  ERR("out of memory\n");
2263  ExFreePool(utf8);
2264 
2265  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2266  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2267  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2268 
2270  }
2271 
2272  fcb->Vcb = Vcb;
2273 
2276 
2277  fcb->inode_item.generation = Vcb->superblock.generation;
2278  fcb->inode_item.transid = Vcb->superblock.generation;
2279  fcb->inode_item.st_size = 0;
2280  fcb->inode_item.st_blocks = 0;
2281  fcb->inode_item.block_group = 0;
2282  fcb->inode_item.st_nlink = 1;
2283  fcb->inode_item.st_gid = GID_NOBODY; // FIXME?
2284  fcb->inode_item.st_mode = inherit_mode(parfileref->fcb, type == BTRFS_TYPE_DIRECTORY); // use parent's permissions by default
2285  fcb->inode_item.st_rdev = 0;
2286  fcb->inode_item.flags = 0;
2287  fcb->inode_item.sequence = 1;
2291  fcb->inode_item.otime = now;
2292 
2293  if (type == BTRFS_TYPE_DIRECTORY)
2295  else {
2297  fcb->inode_item.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); // remove executable bit if not directory
2298  }
2299 
2300  if (IrpSp->Flags & SL_OPEN_PAGING_FILE) {
2302  } else {
2303  // inherit nodatacow flag from parent directory
2304  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_NODATACOW) {
2306 
2307  if (type != BTRFS_TYPE_DIRECTORY)
2309  }
2310 
2311  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_COMPRESS)
2313  }
2314 
2315  fcb->prop_compression = parfileref->fcb->prop_compression;
2317 
2318  fcb->inode_item_changed = true;
2319 
2320  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2321  fcb->Header.AllocationSize.QuadPart = 0;
2322  fcb->Header.FileSize.QuadPart = 0;
2323  fcb->Header.ValidDataLength.QuadPart = 0;
2324 
2325  fcb->atts = IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL;
2326  fcb->atts_changed = fcb->atts != defda;
2327 
2328 #ifdef DEBUG_FCB_REFCOUNTS
2329  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2330  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2331 #else
2332  InterlockedIncrement(&parfileref->fcb->refcount);
2333 #endif
2334  fcb->subvol = parfileref->fcb->subvol;
2335  fcb->inode = inode;
2336  fcb->type = type;
2337  fcb->created = true;
2338  fcb->deleted = true;
2339 
2340  fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&inode, sizeof(uint64_t));
2341 
2342  acquire_fcb_lock_exclusive(Vcb);
2343 
2344  if (fcb->subvol->fcbs_ptrs[fcb->hash >> 24]) {
2345  LIST_ENTRY* le = fcb->subvol->fcbs_ptrs[fcb->hash >> 24];
2346 
2347  while (le != &fcb->subvol->fcbs) {
2348  struct _fcb* fcb2 = CONTAINING_RECORD(le, struct _fcb, list_entry);
2349 
2350  if (fcb2->hash > fcb->hash) {
2351  lastle = le->Blink;
2352  break;
2353  }
2354 
2355  le = le->Flink;
2356  }
2357  }
2358 
2359  if (!lastle) {
2360  uint8_t c = fcb->hash >> 24;
2361 
2362  if (c != 0xff) {
2363  uint8_t d = c + 1;
2364 
2365  do {
2366  if (fcb->subvol->fcbs_ptrs[d]) {
2367  lastle = fcb->subvol->fcbs_ptrs[d]->Blink;
2368  break;
2369  }
2370 
2371  d++;
2372  } while (d != 0);
2373  }
2374  }
2375 
2376  if (lastle) {
2377  InsertHeadList(lastle, &fcb->list_entry);
2378 
2379  if (lastle == &fcb->subvol->fcbs || (CONTAINING_RECORD(lastle, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2380  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2381  } else {
2382  InsertTailList(&fcb->subvol->fcbs, &fcb->list_entry);
2383 
2384  if (fcb->list_entry.Blink == &fcb->subvol->fcbs || (CONTAINING_RECORD(fcb->list_entry.Blink, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2385  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2386  }
2387 
2388  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2389 
2390  fcb->subvol->fcbs_version++;
2391 
2392  release_fcb_lock(Vcb);
2393 
2395 
2396  Status = fcb_get_new_sd(fcb, parfileref, IrpSp->Parameters.Create.SecurityContext->AccessState);
2397 
2398  if (!NT_SUCCESS(Status)) {
2399  ERR("fcb_get_new_sd returned %08lx\n", Status);
2400  free_fcb(fcb);
2401 
2402  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2403  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2404  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2405 
2406  ExFreePool(utf8);
2407 
2408  return Status;
2409  }
2410 
2411  fcb->sd_dirty = true;
2412 
2413  if (ea && ealen > 0) {
2415  if (!NT_SUCCESS(Status)) {
2416  ERR("file_create_parse_ea returned %08lx\n", Status);
2417  free_fcb(fcb);
2418 
2419  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2420  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2421  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2422 
2423  ExFreePool(utf8);
2424 
2425  return Status;
2426  }
2427  }
2428 
2430  if (!fileref) {
2431  ERR("out of memory\n");
2432  free_fcb(fcb);
2433 
2434  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2435  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2436  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2437 
2438  ExFreePool(utf8);
2439 
2441  }
2442 
2443  fileref->fcb = fcb;
2444 
2445  if (Irp->Overlay.AllocationSize.QuadPart > 0 && !write_fcb_compressed(fcb)) {
2446  Status = extend_file(fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback);
2447 
2448  if (!NT_SUCCESS(Status)) {
2449  ERR("extend_file returned %08lx\n", Status);
2451 
2452  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2453  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2454  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2455 
2456  ExFreePool(utf8);
2457 
2458  return Status;
2459  }
2460  }
2461 
2462  if (fcb->type == BTRFS_TYPE_DIRECTORY) {
2464  if (!fcb->hash_ptrs) {
2465  ERR("out of memory\n");
2467 
2468  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2469  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2470  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2471 
2472  ExFreePool(utf8);
2473 
2475  }
2476 
2477  RtlZeroMemory(fcb->hash_ptrs, sizeof(LIST_ENTRY*) * 256);
2478 
2480  if (!fcb->hash_ptrs_uc) {
2481  ERR("out of memory\n");
2483 
2484  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2485  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2486  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2487 
2488  ExFreePool(utf8);
2489 
2491  }
2492 
2493  RtlZeroMemory(fcb->hash_ptrs_uc, sizeof(LIST_ENTRY*) * 256);
2494  }
2495 
2496  fcb->deleted = false;
2497 
2498  fileref->created = true;
2499 
2500  fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2501  fcb->subvol->root_item.ctime = now;
2502 
2503  utf8as.Buffer = utf8;
2504  utf8as.Length = utf8as.MaximumLength = (uint16_t)utf8len;
2505 
2506  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2507 
2508  // check again doesn't already exist
2509  if (case_sensitive) {
2510  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpus->Buffer, fpus->Length);
2511 
2512  if (parfileref->fcb->hash_ptrs[dc_hash >> 24]) {
2513  LIST_ENTRY* le = parfileref->fcb->hash_ptrs[dc_hash >> 24];
2514  while (le != &parfileref->fcb->dir_children_hash) {
2515  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
2516 
2517  if (dc->hash == dc_hash && dc->name.Length == fpus->Length && RtlCompareMemory(dc->name.Buffer, fpus->Buffer, fpus->Length) == fpus->Length) {
2518  existing_fileref = dc->fileref;
2519  break;
2520  } else if (dc->hash > dc_hash)
2521  break;
2522 
2523  le = le->Flink;
2524  }
2525  }
2526  } else {
2527  UNICODE_STRING fpusuc;
2528 #ifdef __REACTOS__
2529  UINT32 dc_hash;
2530 #endif
2531 
2532  Status = RtlUpcaseUnicodeString(&fpusuc, fpus, true);
2533  if (!NT_SUCCESS(Status)) {
2534  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2535  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
2537 
2538  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2539  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2540  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2541 
2542  ExFreePool(utf8);
2543 
2544  return Status;
2545  }
2546 
2547 #ifndef __REACTOS__
2548  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length);
2549 #else
2550  dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length);
2551 #endif // __REACTOS__
2552 
2553  if (parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]) {
2554  LIST_ENTRY* le = parfileref->fcb->hash_ptrs_uc[dc_hash >> 24];
2555  while (le != &parfileref->fcb->dir_children_hash_uc) {
2556  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
2557 
2558  if (dc->hash_uc == dc_hash && dc->name.Length == fpusuc.Length && RtlCompareMemory(dc->name.Buffer, fpusuc.Buffer, fpusuc.Length) == fpusuc.Length) {
2559  existing_fileref = dc->fileref;
2560  break;
2561  } else if (dc->hash_uc > dc_hash)
2562  break;
2563 
2564  le = le->Flink;
2565  }
2566  }
2567 
2568  ExFreePool(fpusuc.Buffer);
2569  }
2570 
2571  if (existing_fileref) {
2572  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2574 
2575  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2576  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2577  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2578 
2579  ExFreePool(utf8);
2580 
2581  increase_fileref_refcount(existing_fileref);
2582  *pfr = existing_fileref;
2583 
2585  }
2586 
2587  Status = add_dir_child(parfileref->fcb, fcb->inode, false, &utf8as, fpus, fcb->type, &dc);
2588  if (!NT_SUCCESS(Status)) {
2589  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2590  ERR("add_dir_child returned %08lx\n", Status);
2592 
2593  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2594  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2595  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2596 
2597  ExFreePool(utf8);
2598 
2599  return Status;
2600  }
2601 
2602  fileref->parent = parfileref;
2603  fileref->dc = dc;
2604  dc->fileref = fileref;
2605 
2606  if (type == BTRFS_TYPE_DIRECTORY)
2607  fileref->fcb->fileref = fileref;
2608 
2609  InsertTailList(&parfileref->children, &fileref->list_entry);
2610  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2611 
2612  ExFreePool(utf8);
2613 
2615  increase_fileref_refcount(parfileref);
2616 
2617  *pfr = fileref;
2618 
2619  TRACE("created new file in subvol %I64x, inode %I64x\n", fcb->subvol->id, fcb->inode);
2620 
2621  return STATUS_SUCCESS;
2622 }
#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:148
BTRFS_TIME otime
Definition: btrfs.h:296
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1664
#define BTRFS_INODE_NODATACOW
Definition: propsheet.h:77
Iosb Status
Definition: create.c:4287
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1797
_In_ PIRP Irp
Definition: csq.h:116
#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:318
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
uint32_t inherit_mode(fcb *parfcb, bool is_dir)
Definition: create.c:1936
#define S_IFREG
Definition: ext2fs.h:356
__u16 time
Definition: mkdosfs.c:366
uint64_t block_group
Definition: btrfs.h:284
#define uint16_t
Definition: nsiface.idl:60
void reap_fileref(device_extension *Vcb, file_ref *fr)
Definition: btrfs.c:1806
#define InsertTailList(ListHead, Entry)
bool atts_changed
Definition: btrfs_drv.h:333
BTRFS_TIME st_ctime
Definition: btrfs.h:294
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:348
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:79
Definition: fs.h:78
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:91
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4137
uint32_t st_gid
Definition: btrfs.h:287
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1647
unsigned int UINT32
#define BTRFS_INODE_COMPRESS
Definition: propsheet.h:87
long LONG
Definition: pedump.c:60
LIST_ENTRY list_entry
Definition: btrfs_drv.h:347
#define S_IXOTH
Definition: propsheet.h:61
uint64_t sequence
Definition: btrfs.h:291
uint32_t st_nlink
Definition: btrfs.h:285
time_t now
Definition: finger.c:65
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:329
smooth NULL
Definition: ftsmooth.c:416
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1625
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:672
uint8_t type
Definition: btrfs_drv.h:302
BTRFS_TIME st_mtime
Definition: btrfs.h:295
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1785
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:337
#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:1712
ULONG ealen
Definition: btrfs_drv.h:314
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:294
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define S_IXGRP
Definition: propsheet.h:49
uint64_t st_size
Definition: btrfs.h:282
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedIncrement64
Definition: interlocked.h:211
struct _fcb fcb
Definition: btrfs_drv.h:1357
bool sd_dirty
Definition: btrfs_drv.h:332
#define d
Definition: ke_i.h:81
__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:300
uint64_t st_rdev
Definition: btrfs.h:289
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
const GLubyte * c
Definition: glext.h:8905
struct _file_ref * fileref
Definition: btrfs_drv.h:316
bool case_sensitive
Definition: btrfs_drv.h:321
#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:301
#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:293
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
Status
Definition: gdiplustypes.h:24
#define S_IXUSR
Definition: propsheet.h:37
crc_func calc_crc32c
Definition: crc32c.c:23
bool created
Definition: btrfs_drv.h:339
Definition: typedefs.h:119
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1690
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
uint64_t generation
Definition: btrfs.h:280
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t st_blocks
Definition: btrfs.h:283
uint64_t flags
Definition: btrfs.h:290
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
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:1861
UINT64 uint64_t
Definition: types.h:77
#define InterlockedIncrement
Definition: armddk.h:53
ULONG atts
Definition: btrfs_drv.h:308
unsigned short USHORT
Definition: pedump.c:61
bool deleted
Definition: btrfs_drv.h:306
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
uint64_t transid
Definition: btrfs.h:281
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
struct _root * subvol
Definition: btrfs_drv.h:299
Definition: list.h:27
_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:1357
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:997
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:328
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR dc[]
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
Definition: _hash_fun.h:40
bool inode_item_changed
Definition: btrfs_drv.h:317
NTSTATUS extend_file(fcb *fcb, file_ref *fileref, uint64_t end, bool prealloc, PIRP Irp, LIST_ENTRY *rollback)
Definition: write.c:3299
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:95
struct _device_extension * Vcb
Definition: btrfs_drv.h:298
static NTSTATUS file_create_parse_ea(fcb *fcb, FILE_FULL_EA_INFORMATION *ea)
Definition: create.c:1952
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
uint32_t st_mode
Definition: btrfs.h:288

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 1952 of file create.c.

1952  {
1953  NTSTATUS Status;
1954  LIST_ENTRY ealist, *le;
1955  uint16_t size = 0;
1956  char* buf;
1957 
1958  InitializeListHead(&ealist);
1959 
1960  do {
1961  STRING s;
1962  bool found = false;
1963 
1964  s.Length = s.MaximumLength = ea->EaNameLength;
1965  s.Buffer = ea->EaName;
1966 
1967  RtlUpperString(&s, &s);
1968 
1969  le = ealist.Flink;
1970  while (le != &ealist) {
1972 
1973  if (item->name.Length == s.Length && RtlCompareMemory(item->name.Buffer, s.Buffer, s.Length) == s.Length) {
1974  item->flags = ea->Flags;
1975  item->value.Length = item->value.MaximumLength = ea->EaValueLength;
1976  item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
1977  found = true;
1978  break;
1979  }
1980 
1981  le = le->Flink;
1982  }
1983 
1984  if (!found) {
1986  if (!item) {
1987  ERR("out of memory\n");
1989  goto end;
1990  }
1991 
1992  item->name.Length = item->name.MaximumLength = ea->EaNameLength;
1993  item->name.Buffer = ea->EaName;
1994 
1995  item->value.Length = item->value.MaximumLength = ea->EaValueLength;
1996  item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
1997 
1998  item->flags = ea->Flags;
1999 
2000  InsertTailList(&ealist, &item->list_entry);
2001  }
2002 
2003  if (ea->NextEntryOffset == 0)
2004  break;
2005 
2006  ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
2007  } while (true);
2008 
2009  // handle LXSS values
2010  le = ealist.Flink;
2011  while (le != &ealist) {
2012  LIST_ENTRY* le2 = le->Flink;
2014 
2015  if (item->name.Length == sizeof(lxuid) - 1 && RtlCompareMemory(item->name.Buffer, lxuid, item->name.Length) == item->name.Length) {
2016  if (item->value.Length < sizeof(uint32_t)) {
2017  ERR("uid value was shorter than expected\n");
2019  goto end;
2020  }
2021 
2022  RtlCopyMemory(&fcb->inode_item.st_uid, item->value.Buffer, sizeof(uint32_t));
2023  fcb->sd_dirty = true;
2024  fcb->sd_deleted = false;
2025 
2026  RemoveEntryList(&item->list_entry);
2027  ExFreePool(item);
2028  } else if (item->name.Length == sizeof(lxgid) - 1 && RtlCompareMemory(item->name.Buffer, lxgid, item->name.Length) == item->name.Length) {
2029  if (item->value.Length < sizeof(uint32_t)) {
2030  ERR("gid value was shorter than expected\n");
2032  goto end;
2033  }
2034 
2035  RtlCopyMemory(&fcb->inode_item.st_gid, item->value.Buffer, sizeof(uint32_t));
2036 
2037  RemoveEntryList(&item->list_entry);
2038  ExFreePool(item);
2039  } else if (item->name.Length == sizeof(lxmod) - 1 && RtlCompareMemory(item->name.Buffer, lxmod, item->name.Length) == item->name.Length) {
2041  uint32_t val;
2042 
2043  if (item->value.Length < sizeof(uint32_t)) {
2044  ERR("mode value was shorter than expected\n");
2046  goto end;
2047  }
2048 
2049  RtlCopyMemory(&val, item->value.Buffer, sizeof(uint32_t));
2050 
2051  if (fcb->type != BTRFS_TYPE_DIRECTORY)
2052  allowed |= __S_IFIFO | __S_IFCHR | __S_IFBLK | __S_IFSOCK;
2053 
2054  fcb->inode_item.st_mode &= ~allowed;
2055  fcb->inode_item.st_mode |= val & allowed;
2056 
2057  if (fcb->type != BTRFS_TYPE_DIRECTORY) {
2060  else if ((fcb->inode_item.st_mode & __S_IFBLK) == __S_IFBLK)
2062  else if ((fcb->inode_item.st_mode & __S_IFIFO) == __S_IFIFO)
2064  else if ((fcb->inode_item.st_mode & __S_IFSOCK) == __S_IFSOCK)
2066  }
2067 
2068  RemoveEntryList(&item->list_entry);
2069  ExFreePool(item);
2070  } else if (item->name.Length == sizeof(lxdev) - 1 && RtlCompareMemory(item->name.Buffer, lxdev, item->name.Length) == item->name.Length) {
2071  uint32_t major, minor;
2072 
2073  if (item->value.Length < sizeof(uint64_t)) {
2074  ERR("dev value was shorter than expected\n");
2076  goto end;
2077  }
2078 
2079  major = *(uint32_t*)item->value.Buffer;
2080  minor = *(uint32_t*)&item->value.Buffer[sizeof(uint32_t)];
2081 
2082  fcb->inode_item.st_rdev = (minor & 0xFFFFF) | ((major & 0xFFFFFFFFFFF) << 20);
2083 
2084  RemoveEntryList(&item->list_entry);
2085  ExFreePool(item);
2086  }
2087 
2088  le = le2;
2089  }
2090 
2092  fcb->inode_item.st_rdev = 0;
2093 
2094  if (IsListEmpty(&ealist))
2095  return STATUS_SUCCESS;
2096 
2097  le = ealist.Flink;
2098  while (le != &ealist) {
2100 
2101  if (size % 4 > 0)
2102  size += 4 - (size % 4);
2103 
2104  size += (uint16_t)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + item->name.Length + 1 + item->value.Length;
2105 
2106  le = le->Flink;
2107  }
2108 
2110  if (!buf) {
2111  ERR("out of memory\n");
2113  goto end;
2114  }
2115 
2117  fcb->ea_xattr.Buffer = buf;
2118 
2119  fcb->ealen = 4;
2120  ea = NULL;
2121 
2122  le = ealist.Flink;
2123  while (le != &ealist) {
2125 
2126  if (ea) {
2128 
2129  if (ea->NextEntryOffset % 4 > 0)
2130  ea->NextEntryOffset += 4 - (ea->NextEntryOffset % 4);
2131 
2132  ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
2133  } else
2135 
2136  ea->NextEntryOffset = 0;
2137  ea->Flags = item->flags;
2138  ea->EaNameLength = (UCHAR)item->name.Length;
2139  ea->EaValueLength = item->value.Length;
2140 
2141  RtlCopyMemory(ea->EaName, item->name.Buffer, item->name.Length);
2142  ea->EaName[item->name.Length] = 0;
2143  RtlCopyMemory(&ea->EaName[item->name.Length + 1], item->value.Buffer, item->value.Length);
2144 
2145  fcb->ealen += 5 + item->name.Length + item->value.Length;
2146 
2147  le = le->Flink;
2148  }
2149 
2150  fcb->ea_changed = true;
2151 
2153 
2154 end:
2155  while (!IsListEmpty(&ealist)) {
2157 
2158  ExFreePool(item);
2159  }
2160 
2161  return Status;
2162 }
NTSYSAPI VOID NTAPI RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
static const char lxuid[]
Definition: btrfs_drv.h:1287
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#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
Iosb Status
Definition: create.c:4287
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
#define __S_IFSOCK
Definition: btrfs_drv.h:1806
LONG NTSTATUS
Definition: precomp.h:26
bool sd_deleted
Definition: btrfs_drv.h:332
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
ANSI_STRING ea_xattr
Definition: btrfs_drv.h:313
GLuint GLuint end
Definition: gl.h:1545
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:91
bool ea_changed
Definition: btrfs_drv.h:336
uint32_t st_gid
Definition: btrfs.h:287
#define S_IRGRP
Definition: propsheet.h:41
#define S_IXOTH
Definition: propsheet.h:61
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
uint8_t type
Definition: btrfs_drv.h:302
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:314
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:332
uint64_t st_rdev
Definition: btrfs.h:289
#define __S_IFIFO
Definition: btrfs_drv.h:1804
#define __S_IFCHR
Definition: btrfs_drv.h:1801
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
Status
Definition: gdiplustypes.h:24
#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:303
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 major(rdev)
Definition: propsheet.cpp:916
#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
Definition: list.h:27
UINT32 uint32_t
Definition: types.h:75
unsigned int ULONG
Definition: retypes.h:1
#define minor(rdev)
Definition: propsheet.cpp:917
#define __S_IFBLK
Definition: btrfs_drv.h:1802
#define uint32_t
Definition: nsiface.idl:61
uint32_t st_uid
Definition: btrfs.h:286
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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:288

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 179 of file create.c.

179  {
181  UNICODE_STRING fnus;
182  uint32_t hash;
183  LIST_ENTRY* le;
184  uint8_t c;
185  bool locked = false;
186 
187  if (!case_sensitive) {
188  Status = RtlUpcaseUnicodeString(&fnus, filename, true);
189 
190  if (!NT_SUCCESS(Status)) {
191  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
192  return Status;
193  }
194  } else
195  fnus = *filename;
196 
197  hash = calc_crc32c(0xffffffff, (uint8_t*)fnus.Buffer, fnus.Length);
198 
199  c = hash >> 24;
200 
201  if (!ExIsResourceAcquiredSharedLite(&fcb->nonpaged->dir_children_lock)) {
202  ExAcquireResourceSharedLite(&fcb->nonpaged->dir_children_lock, true);
203  locked = true;
204  }
205 
206  if (case_sensitive) {
207  if (!fcb->hash_ptrs[c]) {
209  goto end;
210  }
211 
212  le = fcb->hash_ptrs[c];
213  while (le != &fcb->dir_children_hash) {
214  dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
215 
216  if (dc->hash == hash) {
217  if (dc->name.Length == fnus.Length && RtlCompareMemory(dc->name.Buffer, fnus.Buffer, fnus.Length) == fnus.Length) {
218  if (dc->key.obj_type == TYPE_ROOT_ITEM) {
219  LIST_ENTRY* le2;
220 
221  *subvol = NULL;
222 
223  le2 = fcb->Vcb->roots.Flink;
224  while (le2 != &fcb->Vcb->roots) {
226 
227  if (r2->id == dc->key.obj_id) {
228  *subvol = r2;
229  break;
230  }
231 
232  le2 = le2->Flink;
233  }
234 
236  } else {
237  *subvol = fcb->subvol;
238  *inode = dc->key.obj_id;
239  }
240 
241  *pdc = dc;
242 
244  goto end;
245  }
246  } else if (dc->hash > hash) {
248  goto end;
249  }
250 
251  le = le->Flink;
252  }
253  } else {
254  if (!fcb->hash_ptrs_uc[c]) {
256  goto end;
257  }
258 
259  le = fcb->hash_ptrs_uc[c];
260  while (le != &fcb->dir_children_hash_uc) {
261  dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
262 
263  if (dc->hash_uc == hash) {
264  if (dc->name_uc.Length == fnus.Length && RtlCompareMemory(dc->name_uc.Buffer, fnus.Buffer, fnus.Length) == fnus.Length) {
265  if (dc->key.obj_type == TYPE_ROOT_ITEM) {
266  LIST_ENTRY* le2;
267 
268  *subvol = NULL;
269 
270  le2 = fcb->Vcb->roots.Flink;
271  while (le2 != &fcb->Vcb->roots) {
273 
274  if (r2->id == dc->key.obj_id) {
275  *subvol = r2;
276  break;
277  }
278 
279  le2 = le2->Flink;
280  }
281 
283  } else {
284  *subvol = fcb->subvol;
285  *inode = dc->key.obj_id;
286  }
287 
288  *pdc = dc;
289 
291  goto end;
292  }
293  } else if (dc->hash_uc > hash) {
295  goto end;
296  }
297 
298  le = le->Flink;
299  }
300  }
301 
303 
304 end:
305  if (locked)
306  ExReleaseResourceLite(&fcb->nonpaged->dir_children_lock);
307 
308  if (!case_sensitive)
309  ExFreePool(fnus.Buffer);
310 
311  return Status;
312 }
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
Iosb Status
Definition: create.c:4287
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
LONG NTSTATUS
Definition: precomp.h:26
GLuint GLuint end
Definition: gl.h:1545
const char * filename
Definition: ioapi.h:135
Definition: fs.h:78
int hash
Definition: main.c:58
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:329
smooth NULL
Definition: ftsmooth.c:416
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:327
#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:321
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
Status
Definition: gdiplustypes.h:24
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:295
#define TYPE_ROOT_ITEM
Definition: btrfs.h:28
struct _root * subvol
Definition: btrfs_drv.h:299
Definition: list.h:27
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:328
static const WCHAR dc[]
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:326
return STATUS_SUCCESS
Definition: btrfs.c:3014
Definition: _hash_fun.h:40
struct _device_extension * Vcb
Definition: btrfs_drv.h:298
#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 3408 of file create.c.

3408  {
3409  NTSTATUS Status;
3410 
3412  ULONG size, bytes_read, i;
3413 
3414  if (fcb->type == BTRFS_TYPE_FILE && fcb->inode_item.st_size < sizeof(ULONG)) {
3415  WARN("file was too short to be a reparse point\n");
3416  return STATUS_INVALID_PARAMETER;
3417  }
3418 
3419  // 0x10007 = 0xffff (maximum length of data buffer) + 8 bytes header
3420  size = (ULONG)min(0x10007, fcb->inode_item.st_size);
3421 
3422  if (size == 0)
3423  return STATUS_INVALID_PARAMETER;
3424 
3426  if (!*data) {
3427  ERR("out of memory\n");
3429  }
3430 
3431  Status = read_file(fcb, *data, 0, size, &bytes_read, NULL);
3432  if (!NT_SUCCESS(Status)) {
3433  ERR("read_file_fcb returned %08lx\n", Status);
3434  ExFreePool(*data);
3435  return Status;
3436  }
3437 
3438  if (fcb->type == BTRFS_TYPE_SYMLINK) {
3439  ULONG stringlen, reqlen;
3440  uint16_t subnamelen, printnamelen;
3441  REPARSE_DATA_BUFFER* rdb;
3442 
3443  Status = utf8_to_utf16(NULL, 0, &stringlen, (char*)*data, bytes_read);
3444  if (!NT_SUCCESS(Status)) {
3445  ERR("utf8_to_utf16 1 returned %08lx\n", Status);
3446  ExFreePool(*data);
3447  return Status;
3448  }
3449 
3450  subnamelen = printnamelen = (USHORT)stringlen;
3451 
3452  reqlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + subnamelen + printnamelen;
3453 
3454  rdb = ExAllocatePoolWithTag(PagedPool, reqlen, ALLOC_TAG);
3455 
3456  if (!rdb) {
3457  ERR("out of memory\n");
3458  ExFreePool(*data);
3460  }
3461 
3463  rdb->ReparseDataLength = (USHORT)(reqlen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
3464  rdb->Reserved = 0;
3465 
3466  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
3467  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = subnamelen;
3468  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = subnamelen;
3469  rdb->SymbolicLinkReparseBuffer.PrintNameLength = printnamelen;
3471 
3472  Status = utf8_to_utf16(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3473  stringlen, &stringlen, (char*)*data, size);
3474 
3475  if (!NT_SUCCESS(Status)) {
3476  ERR("utf8_to_utf16 2 returned %08lx\n", Status);
3477  ExFreePool(rdb);
3478  ExFreePool(*data);
3479  return Status;
3480  }
3481 
3482  for (i = 0; i < stringlen / sizeof(WCHAR); i++) {
3483  if (rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] == '/')
3484  rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] = '\\';
3485  }
3486 
3487  RtlCopyMemory(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)],
3488  &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3489  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
3490 
3491  ExFreePool(*data);
3492 
3493  *data = (uint8_t*)rdb;
3494  } else {
3496  if (!NT_SUCCESS(Status)) {
3497  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
3498  ExFreePool(*data);
3499  return Status;
3500  }
3501  }
3502  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
3504  return STATUS_INTERNAL_ERROR;
3505 
3506  if (fcb->reparse_xattr.Length < sizeof(ULONG)) {
3507  WARN("xattr was too short to be a reparse point\n");
3508  return STATUS_INTERNAL_ERROR;
3509  }
3510 
3512  if (!NT_SUCCESS(Status)) {
3513  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
3514  return Status;
3515  }
3516 
3518  if (!*data) {
3519  ERR("out of memory\n");
3521  }
3522 
3524  } else
3525  return STATUS_INVALID_PARAMETER;
3526 
3527  return STATUS_SUCCESS;
3528 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Iosb Status
Definition: create.c:4287
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:312
unsigned short int uint16_t
Definition: acefiex.h:54
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp)
Definition: read.c:2828
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:91
WCHAR PathBuffer[1]
Definition: shellext.h:176
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
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
uint8_t type
Definition: btrfs_drv.h:302
uint64_t st_size
Definition: btrfs.h:282
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:736
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
Status
Definition: gdiplustypes.h:24
USHORT ReparseDataLength
Definition: shellext.h:166
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:103
GLint const GLchar GLint stringlen
Definition: glext.h:7232
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
BYTE uint8_t
Definition: msvideo1.c:66
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define ERR(fmt,...)
Definition: debug.h:110
unsigned short USHORT
Definition: pedump.c:61
#define min(a, b)
Definition: monoChain.cc:55
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
struct _REPARSE_DATA_BUFFER::@309::@311 SymbolicLinkReparseBuffer
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7219
#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 4758 of file create.c.

4758  {
4759  PRIVILEGE_SET privset;
4760 
4761  privset.PrivilegeCount = 1;
4763  privset.Privilege[0].Luid = RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE);
4764  privset.Privilege[0].Attributes = 0;
4765 
4766  return SePrivilegeCheck(&privset, &access_state->SubjectSecurityContext, processor_mode) ? true : false;
4767 }
$ULONG Control
Definition: setypes.h:87
#define true
Definition: osdep.h:36
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
$ULONG PrivilegeCount
Definition: setypes.h:86
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h:206
BOOLEAN NTAPI SePrivilegeCheck(PPRIVILEGE_SET Privileges, PSECURITY_SUBJECT_CONTEXT SubjectContext, KPROCESSOR_MODE PreviousMode)
Definition: priv.c:491
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88

Referenced by _Dispatch_type_().

◆ inherit_mode()

uint32_t inherit_mode ( fcb parfcb,
bool  is_dir 
)

Definition at line 1936 of file create.c.

1936  {
1937  uint32_t mode;
1938 
1939  if (!parfcb)
1940  return 0755;
1941 
1942  mode = parfcb->inode_item.st_mode & ~S_IFDIR;
1943  mode &= ~S_ISVTX; // clear sticky bit
1944  mode &= ~S_ISUID; // clear setuid bit
1945 
1946  if (!is_dir)
1947  mode &= ~S_ISGID; // if not directory, clear setgid bit
1948 
1949  return mode;
1950 }
#define S_ISGID
Definition: propsheet.h:69
#define S_IFDIR
Definition: acwin.h:115
GLenum mode
Definition: glext.h:6217
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
#define S_ISUID
Definition: propsheet.h:65
UINT32 uint32_t
Definition: types.h:75
#define S_ISVTX
Definition: propsheet.h:73
uint32_t st_mode
Definition: btrfs.h:288

Referenced by create_directory_fcb(), create_subvol(), file_create2(), and mknod().

◆ load_csum()

NTSTATUS load_csum ( _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
void csum,
uint64_t  start,
uint64_t  length,
PIRP  Irp 
)

Definition at line 446 of file create.c.

446  {
448  KEY searchkey;
449  traverse_ptr tp, next_tp;
450  uint64_t i, j;
451  bool b;
452  void* ptr = csum;
453 
454  searchkey.obj_id = EXTENT_CSUM_ID;
455  searchkey.obj_type = TYPE_EXTENT_CSUM;
456  searchkey.offset = start;
457 
458  Status = find_item(Vcb, Vcb->checksum_root, &tp, &searchkey, false, Irp);
459  if (!NT_SUCCESS(Status)) {
460  ERR("error - find_item returned %08lx\n", Status);
461  return Status;
462  }
463 
464  i = 0;
465  do {
466  if (tp.item->key.obj_id == searchkey.obj_id && tp.item->