ReactOS  0.4.14-dev-376-gaedba84
create.c File Reference
#include <sys/stat.h>
#include "btrfs_drv.h"
#include <ntddstor.h>
Include dependency graph for create.c:

Go to the source code of this file.

Classes

struct  _ATOMIC_CREATE_ECP_CONTEXT
 

Macros

#define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED   0x0002
 
#define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT   0x0100
 
#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET   0x0002
 
#define called_from_lxss()   false
 

Typedefs

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, uint32_t *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 } }
 

Macro Definition Documentation

◆ ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT

#define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT   0x0100

Definition at line 36 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 35 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 37 of file create.c.

◆ called_from_lxss

#define called_from_lxss ( )    false

Definition at line 2958 of file create.c.

Typedef Documentation

◆ ATOMIC_CREATE_ECP_CONTEXT

◆ PATOMIC_CREATE_ECP_CONTEXT

Function Documentation

◆ _Dispatch_type_()

_Dispatch_type_ ( IRP_MJ_CREATE  )

Definition at line 4720 of file create.c.

4722  {
4723  NTSTATUS Status;
4726  bool top_level, locked = false;
4727 
4729 
4730  TRACE("create (flags = %x)\n", Irp->Flags);
4731 
4732  top_level = is_top_level(Irp);
4733 
4734  /* return success if just called for FS device object */
4735  if (DeviceObject == master_devobj) {
4736  TRACE("create called for FS device object\n");
4737 
4738  Irp->IoStatus.Information = FILE_OPENED;
4740 
4741  goto exit;
4742  } else if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
4744  goto exit;
4745  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
4747  goto exit;
4748  }
4749 
4750  if (!(Vcb->Vpb->Flags & VPB_MOUNTED)) {
4752  goto exit;
4753  }
4754 
4755  if (Vcb->removing) {
4757  goto exit;
4758  }
4759 
4760  Status = verify_vcb(Vcb, Irp);
4761  if (!NT_SUCCESS(Status)) {
4762  ERR("verify_vcb returned %08x\n", Status);
4763  goto exit;
4764  }
4765 
4766  ExAcquireResourceSharedLite(&Vcb->load_lock, true);
4767  locked = true;
4768 
4770 
4771  if (IrpSp->Flags != 0) {
4773 
4774  TRACE("flags:\n");
4775 
4776  if (flags & SL_CASE_SENSITIVE) {
4777  TRACE("SL_CASE_SENSITIVE\n");
4779  }
4780 
4781  if (flags & SL_FORCE_ACCESS_CHECK) {
4782  TRACE("SL_FORCE_ACCESS_CHECK\n");
4784  }
4785 
4786  if (flags & SL_OPEN_PAGING_FILE) {
4787  TRACE("SL_OPEN_PAGING_FILE\n");
4789  }
4790 
4792  TRACE("SL_OPEN_TARGET_DIRECTORY\n");
4794  }
4795 
4796  if (flags & SL_STOP_ON_SYMLINK) {
4797  TRACE("SL_STOP_ON_SYMLINK\n");
4799  }
4800 
4801  if (flags)
4802  WARN("unknown flags: %x\n", flags);
4803  } else {
4804  TRACE("flags: (none)\n");
4805  }
4806 
4807  if (!IrpSp->FileObject) {
4808  ERR("FileObject was NULL\n");
4810  goto exit;
4811  }
4812 
4813  if (IrpSp->FileObject->RelatedFileObject) {
4814  fcb* relatedfcb = IrpSp->FileObject->RelatedFileObject->FsContext;
4815 
4816  if (relatedfcb && relatedfcb->Vcb != Vcb) {
4817  WARN("RelatedFileObject was for different device\n");
4819  goto exit;
4820  }
4821  }
4822 
4823  // opening volume
4824  if (IrpSp->FileObject->FileName.Length == 0 && !IrpSp->FileObject->RelatedFileObject) {
4825  ULONG RequestedDisposition = ((IrpSp->Parameters.Create.Options >> 24) & 0xff);
4826  ULONG RequestedOptions = IrpSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
4827 #ifdef DEBUG_FCB_REFCOUNTS
4828  LONG rc;
4829 #endif
4830  ccb* ccb;
4831 
4832  TRACE("open operation for volume\n");
4833 
4834  if (RequestedDisposition != FILE_OPEN && RequestedDisposition != FILE_OPEN_IF) {
4836  goto exit;
4837  }
4838 
4839  if (RequestedOptions & FILE_DIRECTORY_FILE) {
4841  goto exit;
4842  }
4843 
4845  if (!ccb) {
4846  ERR("out of memory\n");
4848  goto exit;
4849  }
4850 
4851  RtlZeroMemory(ccb, sizeof(*ccb));
4852 
4854  ccb->NodeSize = sizeof(*ccb);
4855  ccb->disposition = RequestedDisposition;
4856  ccb->options = RequestedOptions;
4857  ccb->access = IrpSp->Parameters.Create.SecurityContext->AccessState->PreviouslyGrantedAccess;
4859  IrpSp->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode);
4860  ccb->reserving = false;
4861  ccb->lxss = called_from_lxss();
4862 
4863 #ifdef DEBUG_FCB_REFCOUNTS
4864  rc = InterlockedIncrement(&Vcb->volume_fcb->refcount);
4865  WARN("fcb %p: refcount now %i (volume)\n", Vcb->volume_fcb, rc);
4866 #else
4867  InterlockedIncrement(&Vcb->volume_fcb->refcount);
4868 #endif
4869  IrpSp->FileObject->FsContext = Vcb->volume_fcb;
4870  IrpSp->FileObject->FsContext2 = ccb;
4871 
4872  IrpSp->FileObject->SectionObjectPointer = &Vcb->volume_fcb->nonpaged->segment_object;
4873 
4874  if (!IrpSp->FileObject->Vpb)
4875  IrpSp->FileObject->Vpb = DeviceObject->Vpb;
4876 
4877  InterlockedIncrement(&Vcb->open_files);
4878 
4879  Irp->IoStatus.Information = FILE_OPENED;
4881  } else {
4883  bool skip_lock;
4884 
4886 
4887  TRACE("file name: %.*S\n", IrpSp->FileObject->FileName.Length / sizeof(WCHAR), IrpSp->FileObject->FileName.Buffer);
4888 
4889  if (IrpSp->FileObject->RelatedFileObject)
4890  TRACE("related file = %p\n", IrpSp->FileObject->RelatedFileObject);
4891 
4892  // Don't lock again if we're being called from within CcCopyRead etc.
4893  skip_lock = ExIsResourceAcquiredExclusiveLite(&Vcb->tree_lock);
4894 
4895  if (!skip_lock)
4896  ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
4897 
4898  ExAcquireResourceSharedLite(&Vcb->fileref_lock, true);
4899 
4901 
4902  if (!NT_SUCCESS(Status))
4904  else
4906 
4907  ExReleaseResourceLite(&Vcb->fileref_lock);
4908 
4909  if (!skip_lock)
4910  ExReleaseResourceLite(&Vcb->tree_lock);
4911  }
4912 
4913 exit:
4914  Irp->IoStatus.Status = Status;
4916 
4917  TRACE("create returning %08x\n", Status);
4918 
4919  if (locked)
4920  ExReleaseResourceLite(&Vcb->load_lock);
4921 
4922  if (top_level)
4924 
4926 
4927  return Status;
4928 }
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback)
Definition: treefuncs.c:1049
void clear_rollback(LIST_ENTRY *rollback)
Definition: treefuncs.c:1028
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1777
#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:375
USHORT Flags
Definition: iotypes.h:169
#define FsRtlExitFileSystem
Iosb Status
Definition: create.c:4311
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1774
_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:111
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
#define SL_STOP_ON_SYMLINK
Definition: iotypes.h:1776
#define VCB_TYPE_FS
Definition: btrfs_drv.h:664
ACCESS_MASK access
Definition: btrfs_drv.h:383
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:276
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1773
bool manage_volume_privilege
Definition: btrfs_drv.h:380
#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:4157
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
long LONG
Definition: pedump.c:60
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:67
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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:4709
#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:666
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:372
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:4359
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
#define ERR(fmt,...)
Definition: debug.h:109
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1775
#define InterlockedIncrement
Definition: armddk.h:53
ULONG disposition
Definition: btrfs_drv.h:374
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_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:1314
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:2958
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
bool reserving
Definition: btrfs_drv.h:382
bool lxss
Definition: btrfs_drv.h:392
void exit(int exitcode)
Definition: _exit.c:33
struct _ccb ccb
static NTSTATUS verify_vcb(device_extension *Vcb, PIRP Irp)
Definition: create.c:4647
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
CSHORT NodeSize
Definition: btrfs_drv.h:373
#define VPB_MOUNTED
Definition: iotypes.h:1764
HRESULT Create([out]ITransactionReceiver **ppReceiver)
struct _device_extension * Vcb
Definition: btrfs_drv.h:283
#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 1830 of file create.c.

1830  {
1831  NTSTATUS Status;
1832  dir_child* dc;
1833  bool locked;
1834 
1836  if (!dc) {
1837  ERR("out of memory\n");
1839  }
1840 
1841  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, utf8->Length, ALLOC_TAG);
1842  if (!dc->utf8.Buffer) {
1843  ERR("out of memory\n");
1844  ExFreePool(dc);
1846  }
1847 
1848  dc->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
1849  if (!dc->name.Buffer) {
1850  ERR("out of memory\n");
1851  ExFreePool(dc->utf8.Buffer);
1852  ExFreePool(dc);
1854  }
1855 
1856  dc->key.obj_id = inode;
1857  dc->key.obj_type = subvol ? TYPE_ROOT_ITEM : TYPE_INODE_ITEM;
1858  dc->key.offset = subvol ? 0xffffffffffffffff : 0;
1859  dc->type = type;
1860  dc->fileref = NULL;
1861 
1862  dc->utf8.Length = dc->utf8.MaximumLength = utf8->Length;
1863  RtlCopyMemory(dc->utf8.Buffer, utf8->Buffer, utf8->Length);
1864 
1865  dc->name.Length = dc->name.MaximumLength = name->Length;
1866  RtlCopyMemory(dc->name.Buffer, name->Buffer, name->Length);
1867 
1868  Status = RtlUpcaseUnicodeString(&dc->name_uc, name, true);
1869  if (!NT_SUCCESS(Status)) {
1870  ERR("RtlUpcaseUnicodeString returned %08x\n", Status);
1871  ExFreePool(dc->utf8.Buffer);
1872  ExFreePool(dc->name.Buffer);
1873  ExFreePool(dc);
1874  return Status;
1875  }
1876 
1877  dc->hash = calc_crc32c(0xffffffff, (uint8_t*)dc->name.Buffer, dc->name.Length);
1878  dc->hash_uc = calc_crc32c(0xffffffff, (uint8_t*)dc->name_uc.Buffer, dc->name_uc.Length);
1879 
1880  locked = ExIsResourceAcquiredExclusive(&fcb->nonpaged->dir_children_lock);
1881 
1882  if (!locked)
1883  ExAcquireResourceExclusiveLite(&fcb->nonpaged->dir_children_lock, true);
1884 
1886  dc->index = 2;
1887  else {
1888  dir_child* dc2 = CONTAINING_RECORD(fcb->dir_children_index.Blink, dir_child, list_entry_index);
1889 
1890  dc->index = max(2, dc2->index + 1);
1891  }
1892 
1893  InsertTailList(&fcb->dir_children_index, &dc->list_entry_index);
1894 
1896 
1897  if (!locked)
1898  ExReleaseResourceLite(&fcb->nonpaged->dir_children_lock);
1899 
1900  *pdc = dc;
1901 
1902  return STATUS_SUCCESS;
1903 }
#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:4311
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
LONG NTSTATUS
Definition: precomp.h:26
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
HDC dc
Definition: cylfrac.c:34
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: recv.cpp:134
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:310
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
uint64_t index
Definition: btrfs_drv.h:248
#define TYPE_INODE_ITEM
Definition: btrfs.h:19
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:280
#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:36
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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 51 of file create.c.

51  {
52  fcb* fcb;
53 
54  if (pool_type == NonPagedPool) {
55  fcb = ExAllocatePoolWithTag(pool_type, sizeof(struct _fcb), ALLOC_TAG);
56  if (!fcb) {
57  ERR("out of memory\n");
58  return NULL;
59  }
60  } else {
61  fcb = ExAllocateFromPagedLookasideList(&Vcb->fcb_lookaside);
62  if (!fcb) {
63  ERR("out of memory\n");
64  return NULL;
65  }
66  }
67 
68 #ifdef DEBUG_FCB_REFCOUNTS
69  WARN("allocating fcb %p\n", fcb);
70 #endif
71  RtlZeroMemory(fcb, sizeof(struct _fcb));
72  fcb->pool_type = pool_type;
73 
74  fcb->Header.NodeTypeCode = BTRFS_NODE_TYPE_FCB;
75  fcb->Header.NodeByteSize = sizeof(struct _fcb);
76 
77  fcb->nonpaged = ExAllocateFromNPagedLookasideList(&Vcb->fcb_np_lookaside);
78  if (!fcb->nonpaged) {
79  ERR("out of memory\n");
80 
81  if (pool_type == NonPagedPool)
82  ExFreePool(fcb);
83  else
84  ExFreeToPagedLookasideList(&Vcb->fcb_lookaside, fcb);
85 
86  return NULL;
87  }
88  RtlZeroMemory(fcb->nonpaged, sizeof(struct _fcb_nonpaged));
89 
90  ExInitializeResourceLite(&fcb->nonpaged->paging_resource);
91  fcb->Header.PagingIoResource = &fcb->nonpaged->paging_resource;
92 
93  ExInitializeFastMutex(&fcb->nonpaged->HeaderMutex);
94  FsRtlSetupAdvancedHeader(&fcb->Header, &fcb->nonpaged->HeaderMutex);
95 
96  fcb->refcount = 1;
97 #ifdef DEBUG_FCB_REFCOUNTS
98  WARN("fcb %p: refcount now %i\n", fcb, fcb->refcount);
99 #endif
100 
102  fcb->Header.Resource = &fcb->nonpaged->resource;
103 
104  ExInitializeResourceLite(&fcb->nonpaged->dir_children_lock);
105 
108 
112 
116 
117  return fcb;
118 }
#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:111
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:4157
smooth NULL
Definition: ftsmooth.c:416
FILE_LOCK lock
Definition: btrfs_drv.h:290
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:279
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:312
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:310
struct _fcb fcb
Definition: btrfs_drv.h:1314
LIST_ENTRY xattrs
Definition: btrfs_drv.h:304
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:300
LIST_ENTRY extents
Definition: btrfs_drv.h:296
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
LONG refcount
Definition: btrfs_drv.h:281
#define ERR(fmt,...)
Definition: debug.h:109
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:280
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static __inline POPLOCK fcb_oplock(fcb *fcb)
Definition: btrfs_drv.h:1629
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:311
POOL_TYPE pool_type
Definition: btrfs_drv.h:282
#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 120 of file create.c.

120  {
121  file_ref* fr;
122 
123  fr = ExAllocateFromPagedLookasideList(&Vcb->fileref_lookaside);
124  if (!fr) {
125  ERR("out of memory\n");
126  return NULL;
127  }
128 
129  RtlZeroMemory(fr, sizeof(file_ref));
130 
131  fr->nonpaged = ExAllocateFromNPagedLookasideList(&Vcb->fileref_np_lookaside);
132  if (!fr->nonpaged) {
133  ERR("out of memory\n");
134  ExFreeToPagedLookasideList(&Vcb->fileref_lookaside, fr);
135  return NULL;
136  }
137 
138  fr->refcount = 1;
139 
140 #ifdef DEBUG_FCB_REFCOUNTS
141  WARN("fileref %p: refcount now 1\n", fr);
142 #endif
143 
145 
147 
148  return fr;
149 }
#define WARN(fmt,...)
Definition: debug.h:111
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
file_ref_nonpaged * nonpaged
Definition: btrfs_drv.h:349
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4157
smooth NULL
Definition: ftsmooth.c:416
LONG refcount
Definition: btrfs_drv.h:351
ERESOURCE fileref_lock
Definition: btrfs_drv.h:338
LIST_ENTRY children
Definition: btrfs_drv.h:350
#define ERR(fmt,...)
Definition: debug.h:109
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

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

2595  {
2597  file_ref *fileref, *newpar, *parfileref;
2598  fcb* fcb;
2599  static const char xapref[] = "user.";
2600  static const WCHAR DOSATTRIB[] = L"DOSATTRIB";
2601  static const WCHAR EA[] = L"EA";
2602  static const WCHAR reparse[] = L"reparse";
2603  static const WCHAR casesensitive_str[] = L"casesensitive";
2605  BTRFS_TIME now;
2606  ULONG utf8len, overhead;
2607  NTSTATUS Status;
2608  KEY searchkey;
2609  traverse_ptr tp;
2610  dir_child* dc;
2611  dir_child* existing_dc = NULL;
2612  ACCESS_MASK granted_access;
2613 #ifdef DEBUG_FCB_REFCOUNTS
2614  LONG rc;
2615 #endif
2616 #ifdef __REACTOS__
2617  LIST_ENTRY* le;
2618 #endif
2619 
2620  TRACE("fpus = %.*S\n", fpus->Length / sizeof(WCHAR), fpus->Buffer);
2621  TRACE("stream = %.*S\n", stream->Length / sizeof(WCHAR), stream->Buffer);
2622 
2623  parfileref = *pparfileref;
2624 
2625  if (parfileref->fcb == Vcb->dummy_fcb)
2626  return STATUS_ACCESS_DENIED;
2627 
2628  Status = open_fileref(Vcb, &newpar, fpus, parfileref, false, NULL, NULL, PagedPool, case_sensitive, Irp);
2629 
2631  UNICODE_STRING fpus2;
2632 
2633  if (!is_file_name_valid(fpus, false, true))
2635 
2636  fpus2.Length = fpus2.MaximumLength = fpus->Length;
2638 
2639  if (!fpus2.Buffer) {
2640  ERR("out of memory\n");
2642  }
2643 
2644  RtlCopyMemory(fpus2.Buffer, fpus->Buffer, fpus2.Length);
2645 
2646  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2647 
2648  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2651  &granted_access, &Status)) {
2652  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2653  return Status;
2654  }
2655 
2656  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2657 
2658  Status = file_create2(Irp, Vcb, &fpus2, parfileref, options, NULL, 0, &newpar, case_sensitive, rollback);
2659 
2660  if (!NT_SUCCESS(Status)) {
2661  ERR("file_create2 returned %08x\n", Status);
2662  ExFreePool(fpus2.Buffer);
2663  return Status;
2664  } else if (Status != STATUS_OBJECT_NAME_COLLISION) {
2667  }
2668 
2669  ExFreePool(fpus2.Buffer);
2670  } else if (!NT_SUCCESS(Status)) {
2671  ERR("open_fileref returned %08x\n", Status);
2672  return Status;
2673  }
2674 
2675  parfileref = newpar;
2676  *pparfileref = parfileref;
2677 
2678  if (parfileref->fcb->type != BTRFS_TYPE_FILE && parfileref->fcb->type != BTRFS_TYPE_SYMLINK && parfileref->fcb->type != BTRFS_TYPE_DIRECTORY) {
2679  WARN("parent not file, directory, or symlink\n");
2680  free_fileref(parfileref);
2681  return STATUS_INVALID_PARAMETER;
2682  }
2683 
2684  if (options & FILE_DIRECTORY_FILE) {
2685  WARN("tried to create directory as stream\n");
2686  free_fileref(parfileref);
2687  return STATUS_INVALID_PARAMETER;
2688  }
2689 
2690  if (parfileref->fcb->atts & FILE_ATTRIBUTE_READONLY) {
2691  free_fileref(parfileref);
2692  return STATUS_ACCESS_DENIED;
2693  }
2694 
2695  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2696 
2697  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
2699  &granted_access, &Status)) {
2700  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2701  free_fileref(parfileref);
2702  return Status;
2703  }
2704 
2705  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
2706 
2707  if ((stream->Length == sizeof(DOSATTRIB) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, DOSATTRIB, stream->Length) == stream->Length) ||
2708  (stream->Length == sizeof(EA) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, EA, stream->Length) == stream->Length) ||
2709  (stream->Length == sizeof(reparse) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, reparse, stream->Length) == stream->Length) ||
2710  (stream->Length == sizeof(casesensitive_str) - sizeof(WCHAR) && RtlCompareMemory(stream->Buffer, casesensitive_str, stream->Length) == stream->Length)) {
2711  free_fileref(parfileref);
2713  }
2714 
2716  if (!fcb) {
2717  ERR("out of memory\n");
2718  free_fileref(parfileref);
2720  }
2721 
2722  fcb->Vcb = Vcb;
2723 
2724  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2725  fcb->Header.AllocationSize.QuadPart = 0;
2726  fcb->Header.FileSize.QuadPart = 0;
2727  fcb->Header.ValidDataLength.QuadPart = 0;
2728 
2729 #ifdef DEBUG_FCB_REFCOUNTS
2730  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2731  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2732 #else
2733  InterlockedIncrement(&parfileref->fcb->refcount);
2734 #endif
2735  fcb->subvol = parfileref->fcb->subvol;
2736  fcb->inode = parfileref->fcb->inode;
2737  fcb->type = parfileref->fcb->type;
2738 
2739  fcb->ads = true;
2740 
2741  Status = utf16_to_utf8(NULL, 0, &utf8len, stream->Buffer, stream->Length);
2742  if (!NT_SUCCESS(Status)) {
2743  ERR("utf16_to_utf8 1 returned %08x\n", Status);
2744  reap_fcb(fcb);
2745  free_fileref(parfileref);
2746  return Status;
2747  }
2748 
2749  fcb->adsxattr.Length = (uint16_t)utf8len + sizeof(xapref) - 1;
2752  if (!fcb->adsxattr.Buffer) {
2753  ERR("out of memory\n");
2754  reap_fcb(fcb);
2755  free_fileref(parfileref);
2757  }
2758 
2759  RtlCopyMemory(fcb->adsxattr.Buffer, xapref, sizeof(xapref) - 1);
2760 
2761  Status = utf16_to_utf8(&fcb->adsxattr.Buffer[sizeof(xapref) - 1], utf8len, &utf8len, stream->Buffer, stream->Length);
2762  if (!NT_SUCCESS(Status)) {
2763  ERR("utf16_to_utf8 2 returned %08x\n", Status);
2764  reap_fcb(fcb);
2765  free_fileref(parfileref);
2766  return Status;
2767  }
2768 
2770 
2771  TRACE("adsxattr = %s\n", fcb->adsxattr.Buffer);
2772 
2774  TRACE("adshash = %08x\n", fcb->adshash);
2775 
2776  searchkey.obj_id = parfileref->fcb->inode;
2777  searchkey.obj_type = TYPE_XATTR_ITEM;
2778  searchkey.offset = fcb->adshash;
2779 
2780  Status = find_item(Vcb, parfileref->fcb->subvol, &tp, &searchkey, false, Irp);
2781  if (!NT_SUCCESS(Status)) {
2782  ERR("find_item returned %08x\n", Status);
2783  reap_fcb(fcb);
2784  free_fileref(parfileref);
2785  return Status;
2786  }
2787 
2788  if (!keycmp(tp.item->key, searchkey))
2789  overhead = tp.item->size;
2790  else
2791  overhead = 0;
2792 
2793  fcb->adsmaxlen = Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - (sizeof(DIR_ITEM) - 1);
2794 
2795  if (utf8len + sizeof(xapref) - 1 + overhead > fcb->adsmaxlen) {
2796  WARN("not enough room for new DIR_ITEM (%u + %u > %u)", utf8len + sizeof(xapref) - 1, overhead, fcb->adsmaxlen);
2797  reap_fcb(fcb);
2798  free_fileref(parfileref);
2799  return STATUS_DISK_FULL;
2800  } else
2801  fcb->adsmaxlen -= overhead + utf8len + sizeof(xapref) - 1;
2802 
2803  fcb->created = true;
2804  fcb->deleted = true;
2805 
2806  acquire_fcb_lock_exclusive(Vcb);
2807  InsertHeadList(&parfileref->fcb->list_entry, &fcb->list_entry); // insert in list after parent fcb
2808  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2809  parfileref->fcb->subvol->fcbs_version++;
2810  release_fcb_lock(Vcb);
2811 
2813 
2815  if (!fileref) {
2816  ERR("out of memory\n");
2817  free_fcb(fcb);
2818  free_fileref(parfileref);
2820  }
2821 
2822  fileref->fcb = fcb;
2823 
2825  if (!dc) {
2826  ERR("out of memory\n");
2828  free_fileref(parfileref);
2830  }
2831 
2832  RtlZeroMemory(dc, sizeof(dir_child));
2833 
2834  dc->utf8.MaximumLength = dc->utf8.Length = fcb->adsxattr.Length + 1 - sizeof(xapref);
2835  dc->utf8.Buffer = ExAllocatePoolWithTag(PagedPool, dc->utf8.MaximumLength, ALLOC_TAG);
2836  if (!dc->utf8.Buffer) {
2837  ERR("out of memory\n");
2838  ExFreePool(dc);
2840  free_fileref(parfileref);
2842  }
2843 
2844  RtlCopyMemory(dc->utf8.Buffer, &fcb->adsxattr.Buffer[sizeof(xapref) - 1], fcb->adsxattr.Length + 1 - sizeof(xapref));
2845 
2846  dc->name.MaximumLength = dc->name.Length = stream->Length;
2847  dc->name.Buffer = ExAllocatePoolWithTag(pool_type, dc->name.MaximumLength, ALLOC_TAG);
2848  if (!dc->name.Buffer) {
2849  ERR("out of memory\n");
2850  ExFreePool(dc->utf8.Buffer);
2851  ExFreePool(dc);
2853  free_fileref(parfileref);
2855  }
2856 
2857  RtlCopyMemory(dc->name.Buffer, stream->Buffer, stream->Length);
2858 
2859  Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true);
2860  if (!NT_SUCCESS(Status)) {
2861  ERR("RtlUpcaseUnicodeString returned %08x\n", Status);
2862  ExFreePool(dc->utf8.Buffer);
2863  ExFreePool(dc->name.Buffer);
2864  ExFreePool(dc);
2866  free_fileref(parfileref);
2867  return Status;
2868  }
2869 
2872 
2873  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2874 
2875 #ifndef __REACTOS__
2876  LIST_ENTRY* le = parfileref->fcb->dir_children_index.Flink;
2877 #else
2878  le = parfileref->fcb->dir_children_index.Flink;
2879 #endif
2880  while (le != &parfileref->fcb->dir_children_index) {
2881  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
2882 
2883  if (dc2->index == 0) {
2884  if ((case_sensitive && dc2->name.Length == dc->name.Length && RtlCompareMemory(dc2->name.Buffer, dc->name.Buffer, dc2->name.Length) == dc2->name.Length) ||
2885  (!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)
2886  ) {
2887  existing_dc = dc2;
2888  break;
2889  }
2890  } else
2891  break;
2892 
2893  le = le->Flink;
2894  }
2895 
2896  if (existing_dc) {
2897  ExFreePool(dc->utf8.Buffer);
2898  ExFreePool(dc->name.Buffer);
2899  ExFreePool(dc);
2901  free_fileref(parfileref);
2902 
2903  increase_fileref_refcount(existing_dc->fileref);
2904  *pfileref = existing_dc->fileref;
2905 
2907  }
2908 
2909  dc->fileref = fileref;
2910  fileref->dc = dc;
2911  fileref->parent = (struct _file_ref*)parfileref;
2912  fcb->deleted = false;
2913 
2914  InsertHeadList(&parfileref->fcb->dir_children_index, &dc->list_entry_index);
2915 
2916  InsertTailList(&parfileref->children, &fileref->list_entry);
2917 
2918  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2919 
2920  mark_fileref_dirty(fileref);
2921 
2922  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2923  parfileref->fcb->inode_item.sequence++;
2924  parfileref->fcb->inode_item.st_ctime = now;
2925  parfileref->fcb->inode_item_changed = true;
2926 
2927  mark_fcb_dirty(parfileref->fcb);
2928 
2929  parfileref->fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2930  parfileref->fcb->subvol->root_item.ctime = now;
2931 
2932  increase_fileref_refcount(parfileref);
2933 
2934  *pfileref = fileref;
2935 
2937 
2938  return STATUS_SUCCESS;
2939 }
#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:353
uint64_t obj_id
Definition: btrfs.h:128
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:256
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:1649
uint8_t obj_type
Definition: btrfs.h:129
#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:120
uint32_t adshash
Definition: btrfs_drv.h:327
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1653
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:2133
Iosb Status
Definition: create.c:4311
UNICODE_STRING name_uc
Definition: btrfs_drv.h:254
_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:991
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
uint16_t size
Definition: btrfs_drv.h:415
VOID NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:314
HDC dc
Definition: cylfrac.c:34
#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:1788
#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:1438
BTRFS_TIME st_ctime
Definition: btrfs.h:284
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1773
uint64_t offset
Definition: btrfs.h:130
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: recv.cpp:134
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:333
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:51
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:4157
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1586
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:289
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1636
#define FILE_ADD_FILE
Definition: nt_native.h:632
long LONG
Definition: pedump.c:60
LIST_ENTRY list_entry
Definition: btrfs_drv.h:332
uint64_t sequence
Definition: btrfs.h:281
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:1662
smooth NULL
Definition: ftsmooth.c:416
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1614
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:672
uint8_t type
Definition: btrfs_drv.h:287
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1716
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:2855
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:279
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:119
#define TRACE(s)
Definition: solgame.cpp:4
#define TYPE_XATTR_ITEM
Definition: btrfs.h:22
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:310
struct _fcb fcb
Definition: btrfs_drv.h:1314
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t inode
Definition: btrfs_drv.h:285
#define FILE_NOTIFY_CHANGE_STREAM_NAME
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
struct _file_ref * fileref
Definition: btrfs_drv.h:301
bool case_sensitive
Definition: btrfs_drv.h:306
#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:354
tree_data * item
Definition: btrfs_drv.h:502
LIST_ENTRY children
Definition: btrfs_drv.h:350
static const WCHAR L[]
Definition: oid.c:1250
LONG refcount
Definition: btrfs_drv.h:281
Definition: parse.h:22
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
uint64_t index
Definition: btrfs_drv.h:248
bool created
Definition: btrfs_drv.h:324
fcb * fcb
Definition: btrfs_drv.h:342
Definition: typedefs.h:117
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1636
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
bool is_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5450
#define ERR(fmt,...)
Definition: debug.h:109
Definition: btrfs.h:127
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULONG atts
Definition: btrfs_drv.h:293
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:280
bool deleted
Definition: btrfs_drv.h:291
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
uint64_t transid
Definition: btrfs.h:271
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
struct _root * subvol
Definition: btrfs_drv.h:284
ULONG adsmaxlen
Definition: btrfs_drv.h:328
_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:1314
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1768
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
bool ads
Definition: btrfs_drv.h:326
#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:964
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
bool inode_item_changed
Definition: btrfs_drv.h:302
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:283
POOL_TYPE pool_type
Definition: btrfs_drv.h:282
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UNICODE_STRING name
Definition: btrfs_drv.h:252
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
ANSI_STRING adsxattr
Definition: btrfs_drv.h:329
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
LIST_ENTRY list_entry
Definition: btrfs_drv.h:358

Referenced by file_create().

◆ debug_create_options()

static __inline void debug_create_options ( ULONG  RequestedOptions)
static

Definition at line 3234 of file create.c.

3234  {
3235  if (RequestedOptions != 0) {
3236  ULONG options = RequestedOptions;
3237 
3238  TRACE("requested options:\n");
3239 
3240  if (options & FILE_DIRECTORY_FILE) {
3241  TRACE(" FILE_DIRECTORY_FILE\n");
3243  }
3244 
3245  if (options & FILE_WRITE_THROUGH) {
3246  TRACE(" FILE_WRITE_THROUGH\n");
3248  }
3249 
3250  if (options & FILE_SEQUENTIAL_ONLY) {
3251  TRACE(" FILE_SEQUENTIAL_ONLY\n");
3253  }
3254 
3256  TRACE(" FILE_NO_INTERMEDIATE_BUFFERING\n");
3258  }
3259 
3261  TRACE(" FILE_SYNCHRONOUS_IO_ALERT\n");
3263  }
3264 
3266  TRACE(" FILE_SYNCHRONOUS_IO_NONALERT\n");
3268  }
3269 
3271  TRACE(" FILE_NON_DIRECTORY_FILE\n");
3273  }
3274 
3276  TRACE(" FILE_CREATE_TREE_CONNECTION\n");
3278  }
3279 
3281  TRACE(" FILE_COMPLETE_IF_OPLOCKED\n");
3283  }
3284 
3285  if (options & FILE_NO_EA_KNOWLEDGE) {
3286  TRACE(" FILE_NO_EA_KNOWLEDGE\n");
3288  }
3289 
3291  TRACE(" FILE_OPEN_REMOTE_INSTANCE\n");
3293  }
3294 
3295  if (options & FILE_RANDOM_ACCESS) {
3296  TRACE(" FILE_RANDOM_ACCESS\n");
3298  }
3299 
3300  if (options & FILE_DELETE_ON_CLOSE) {
3301  TRACE(" FILE_DELETE_ON_CLOSE\n");
3303  }
3304 
3305  if (options & FILE_OPEN_BY_FILE_ID) {
3306  TRACE(" FILE_OPEN_BY_FILE_ID\n");
3308  }
3309 
3311  TRACE(" FILE_OPEN_FOR_BACKUP_INTENT\n");
3313  }
3314 
3315  if (options & FILE_NO_COMPRESSION) {
3316  TRACE(" FILE_NO_COMPRESSION\n");
3318  }
3319 
3320 #if NTDDI_VERSION >= NTDDI_WIN7
3322  TRACE(" FILE_OPEN_REQUIRING_OPLOCK\n");
3324  }
3325 
3327  TRACE(" FILE_DISALLOW_EXCLUSIVE\n");
3329  }
3330 #endif
3331 
3333  TRACE(" FILE_RESERVE_OPFILTER\n");
3335  }
3336 
3338  TRACE(" FILE_OPEN_REPARSE_POINT\n");
3340  }
3341 
3342  if (options & FILE_OPEN_NO_RECALL) {
3343  TRACE(" FILE_OPEN_NO_RECALL\n");
3345  }
3346 
3348  TRACE(" FILE_OPEN_FOR_FREE_SPACE_QUERY\n");
3350  }
3351 
3352  if (options)
3353  TRACE(" unknown options: %x\n", options);
3354  } else {
3355  TRACE("requested options: (none)\n");
3356  }
3357 }
#define FILE_OPEN_REQUIRING_OPLOCK
Definition: winternl.h:186
#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_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 3481 of file create.c.

3481  {
3482  LIST_ENTRY* le;
3483  NTSTATUS Status;
3484 
3485  if (fcb->csum_loaded)
3486  return;
3487 
3489  goto end;
3490 
3491  le = fcb->extents.Flink;
3492  while (le != &fcb->extents) {
3494 
3495  if (!ext->ignore && ext->extent_data.type == EXTENT_TYPE_REGULAR) {
3496  EXTENT_DATA2* ed2 = (EXTENT_DATA2*)&ext->extent_data.data[0];
3497  uint64_t len;
3498 
3499  len = (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->num_bytes : ed2->size) / Vcb->superblock.sector_size;
3500 
3502  if (!ext->csum) {
3503  ERR("out of memory\n");
3504  goto end;
3505  }
3506 
3507  Status = load_csum(Vcb, ext->csum, ed2->address + (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->offset : 0), len, Irp);
3508 
3509  if (!NT_SUCCESS(Status)) {
3510  ERR("load_csum returned %08x\n", Status);
3511  goto end;
3512  }
3513  }
3514 
3515  le = le->Flink;
3516  }
3517 
3518 end:
3519  fcb->csum_loaded = true;
3520 }
#define BTRFS_COMPRESSION_NONE
Definition: btrfs.h:61
EXTENT_DATA2 * ed2
Definition: write.c:2819
Iosb Status
Definition: create.c:4311
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
GLuint GLuint end
Definition: gl.h:1545
NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, uint32_t *csum, uint64_t start, uint64_t length, PIRP Irp)
Definition: create.c:418
_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:4157
uint64_t address
Definition: btrfs.h:346
char ext[3]
Definition: mkdosfs.c:358
uint64_t size
Definition: btrfs.h:347
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:119
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
LIST_ENTRY extents
Definition: btrfs_drv.h:296
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:117
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
uint64_t num_bytes
Definition: btrfs.h:349
uint64_t flags
Definition: btrfs.h:280
#define EXTENT_TYPE_REGULAR
Definition: btrfs.h:71
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
UINT64 uint64_t
Definition: types.h:77
Definition: list.h:27
UINT32 uint32_t
Definition: types.h:75
unsigned int ULONG
Definition: retypes.h:1
uint64_t offset
Definition: btrfs.h:348
bool csum_loaded
Definition: btrfs_drv.h:295

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

2963  {
2964  NTSTATUS Status;
2965  file_ref *fileref, *parfileref = NULL;
2966  ULONG i, j;
2967  ccb* ccb;
2968  static const WCHAR datasuf[] = {':','$','D','A','T','A',0};
2969  UNICODE_STRING dsus, fpus, stream;
2972  ECP_LIST* ecp_list;
2974 #ifdef DEBUG_FCB_REFCOUNTS
2975  LONG oc;
2976 #endif
2977 
2978  TRACE("(%p, %p, %p, %.*S, %x, %x)\n", Irp, Vcb, FileObject, fnus->Length / sizeof(WCHAR), fnus->Buffer, disposition, options);
2979 
2980  if (Vcb->readonly)
2982 
2984  return STATUS_CANNOT_DELETE;
2985 
2987  if (NT_SUCCESS(fFsRtlGetEcpListFromIrp(Irp, &ecp_list)) && ecp_list) {
2988  void* ctx = NULL;
2989  GUID type;
2990  ULONG ctxsize;
2991 
2992  do {
2993  Status = fFsRtlGetNextExtraCreateParameter(ecp_list, ctx, &type, &ctx, &ctxsize);
2994 
2995  if (NT_SUCCESS(Status)) {
2996  if (RtlCompareMemory(&type, &GUID_ECP_ATOMIC_CREATE, sizeof(GUID)) == sizeof(GUID)) {
2997  if (ctxsize >= sizeof(ATOMIC_CREATE_ECP_CONTEXT))
2998  acec = ctx;
2999  else {
3000  ERR("GUID_ECP_ATOMIC_CREATE context was too short: %u bytes, expected %u\n", ctxsize,
3001  sizeof(ATOMIC_CREATE_ECP_CONTEXT));
3002  }
3003  } else {
3004  WARN("unhandled ECP {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", type.Data1, type.Data2,
3005  type.Data3, type.Data4[0], type.Data4[1], type.Data4[2], type.Data4[3], type.Data4[4], type.Data4[5],
3006  type.Data4[6], type.Data4[7]);
3007  }
3008  }
3009  } while (NT_SUCCESS(Status));
3010  }
3011  }
3012 
3013  dsus.Buffer = (WCHAR*)datasuf;
3014  dsus.Length = dsus.MaximumLength = sizeof(datasuf) - sizeof(WCHAR);
3015  fpus.Buffer = NULL;
3016 
3017  if (!loaded_related) {
3018  Status = open_fileref(Vcb, &parfileref, fnus, related, true, NULL, NULL, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, Irp);
3019 
3020  if (!NT_SUCCESS(Status))
3021  goto end;
3022  } else
3023  parfileref = related;
3024 
3025  if (parfileref->fcb->type != BTRFS_TYPE_DIRECTORY && (fnus->Length < sizeof(WCHAR) || fnus->Buffer[0] != ':')) {
3027  goto end;
3028  }
3029 
3030  if (is_subvol_readonly(parfileref->fcb->subvol, Irp)) {
3032  goto end;
3033  }
3034 
3035  i = (fnus->Length / sizeof(WCHAR))-1;
3036  while ((fnus->Buffer[i] == '\\' || fnus->Buffer[i] == '/') && i > 0) { i--; }
3037 
3038  j = i;
3039 
3040  while (i > 0 && fnus->Buffer[i-1] != '\\' && fnus->Buffer[i-1] != '/') { i--; }
3041 
3042  fpus.MaximumLength = (USHORT)((j - i + 2) * sizeof(WCHAR));
3043  fpus.Buffer = ExAllocatePoolWithTag(pool_type, fpus.MaximumLength, ALLOC_TAG);
3044  if (!fpus.Buffer) {
3045  ERR("out of memory\n");
3047  goto end;
3048  }
3049 
3050  fpus.Length = (USHORT)((j - i + 1) * sizeof(WCHAR));
3051 
3052  RtlCopyMemory(fpus.Buffer, &fnus->Buffer[i], (j - i + 1) * sizeof(WCHAR));
3053  fpus.Buffer[j - i + 1] = 0;
3054 
3055  if (fpus.Length > dsus.Length) { // check for :$DATA suffix
3056  UNICODE_STRING lb;
3057 
3058  lb.Buffer = &fpus.Buffer[(fpus.Length - dsus.Length)/sizeof(WCHAR)];
3059  lb.Length = lb.MaximumLength = dsus.Length;
3060 
3061  TRACE("lb = %.*S\n", lb.Length/sizeof(WCHAR), lb.Buffer);
3062 
3063  if (FsRtlAreNamesEqual(&dsus, &lb, true, NULL)) {
3064  TRACE("ignoring :$DATA suffix\n");
3065 
3066  fpus.Length -= lb.Length;
3067 
3068  if (fpus.Length > sizeof(WCHAR) && fpus.Buffer[(fpus.Length-1)/sizeof(WCHAR)] == ':')
3069  fpus.Length -= sizeof(WCHAR);
3070 
3071  TRACE("fpus = %.*S\n", fpus.Length / sizeof(WCHAR), fpus.Buffer);
3072  }
3073  }
3074 
3075  stream.Length = 0;
3076 
3077  for (i = 0; i < fpus.Length / sizeof(WCHAR); i++) {
3078  if (fpus.Buffer[i] == ':') {
3079  stream.Length = (USHORT)(fpus.Length - (i * sizeof(WCHAR)) - sizeof(WCHAR));
3080  stream.Buffer = &fpus.Buffer[i+1];
3081  fpus.Buffer[i] = 0;
3082  fpus.Length = (USHORT)(i * sizeof(WCHAR));
3083  break;
3084  }
3085  }
3086 
3087  if (stream.Length > 0) {
3088  Status = create_stream(Vcb, &fileref, &parfileref, &fpus, &stream, Irp, options, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3089  if (!NT_SUCCESS(Status)) {
3090  ERR("create_stream returned %08x\n", Status);
3091  goto end;
3092  }
3093 
3094  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess,
3095  FileObject, &fileref->fcb->share_access);
3096  } else {
3097  ACCESS_MASK granted_access;
3098 
3099  if (!is_file_name_valid(&fpus, false, false)) {
3101  goto end;
3102  }
3103 
3104  SeLockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3105 
3106  if (!SeAccessCheck(parfileref->fcb->sd, &IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext,
3109  &granted_access, &Status)) {
3110  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3111  goto end;
3112  }
3113 
3114  SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext);
3115 
3116  if (Irp->AssociatedIrp.SystemBuffer && IrpSp->Parameters.Create.EaLength > 0) {
3117  ULONG offset;
3118 
3119  Status = IoCheckEaBufferValidity(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength, &offset);
3120  if (!NT_SUCCESS(Status)) {
3121  ERR("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset);
3122  goto end;
3123  }
3124  }
3125 
3126  Status = file_create2(Irp, Vcb, &fpus, parfileref, options, Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength,
3127  &fileref, IrpSp->Flags & SL_CASE_SENSITIVE, rollback);
3128 
3130  *existing_fileref = fileref;
3131  goto end;
3132  } else if (!NT_SUCCESS(Status)) {
3133  ERR("file_create2 returned %08x\n", Status);
3134  goto end;
3135  }
3136 
3137  IoSetShareAccess(IrpSp->Parameters.Create.SecurityContext->DesiredAccess, IrpSp->Parameters.Create.ShareAccess, FileObject, &fileref->fcb->share_access);
3138 
3141  }
3142 
3143  FileObject->FsContext = fileref->fcb;
3144 
3146  if (!ccb) {
3147  ERR("out of memory\n");
3149  fileref->deleted = true;
3150  fileref->fcb->deleted = true;
3151 
3152  if (stream.Length == 0) {
3153  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3154  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3155  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3156  }
3157 
3158  free_fileref(fileref);
3159  goto end;
3160  }
3161 
3162  RtlZeroMemory(ccb, sizeof(*ccb));
3163 
3164  ccb->fileref = fileref;
3165 
3167  ccb->NodeSize = sizeof(*ccb);
3168  ccb->disposition = disposition;
3169  ccb->options = options;
3170  ccb->query_dir_offset = 0;
3172  ccb->has_wildcard = false;
3173  ccb->specific_file = false;
3174  ccb->access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3176  ccb->reserving = false;
3177  ccb->lxss = called_from_lxss();
3178 
3179 #ifdef DEBUG_FCB_REFCOUNTS
3180  oc = InterlockedIncrement(&fileref->open_count);
3181  ERR("fileref %p: open_count now %i\n", fileref, oc);
3182 #else
3183  InterlockedIncrement(&fileref->open_count);
3184 #endif
3185  InterlockedIncrement(&Vcb->open_files);
3186 
3187  FileObject->FsContext2 = ccb;
3188 
3189  FileObject->SectionObjectPointer = &fileref->fcb->nonpaged->segment_object;
3190 
3191  // FIXME - ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT
3193  if (acec->ReparseBufferLength > sizeof(uint32_t) && *(uint32_t*)acec->ReparseBuffer == IO_REPARSE_TAG_SYMLINK) {
3195  fileref->fcb->type = BTRFS_TYPE_FILE;
3196  }
3197 
3198  if (fileref->fcb->type == BTRFS_TYPE_SOCKET || fileref->fcb->type == BTRFS_TYPE_FIFO ||
3199  fileref->fcb->type == BTRFS_TYPE_CHARDEV || fileref->fcb->type == BTRFS_TYPE_BLOCKDEV) {
3200  // NOP. If called from LXSS, humour it - we hardcode the values elsewhere.
3201  } else {
3203  if (!NT_SUCCESS(Status)) {
3204  ERR("set_reparse_point2 returned %08x\n", Status);
3205  fileref->deleted = true;
3206  fileref->fcb->deleted = true;
3207 
3208  if (stream.Length == 0) {
3209  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
3210  parfileref->fcb->inode_item.st_size -= fileref->dc->utf8.Length * 2;
3211  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
3212  }
3213 
3214  free_fileref(fileref);
3215  return Status;
3216  }
3217  }
3218 
3220  }
3221 
3222  fileref->dc->type = fileref->fcb->type;
3223 
3224 end:
3225  if (fpus.Buffer)
3226  ExFreePool(fpus.Buffer);
3227 
3228  if (parfileref && !loaded_related)
3229  free_fileref(parfileref);
3230 
3231  return Status;
3232 }
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:353
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)
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:1649
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1777
#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:375
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:2133
Iosb Status
Definition: create.c:4311
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1774
_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:1737
#define WARN(fmt,...)
Definition: debug.h:111
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
ANSI_STRING utf8
Definition: btrfs_drv.h:250
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_FILE_NAME
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:352
ACCESS_MASK access
Definition: btrfs_drv.h:383
#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:1438
#define SL_FORCE_ACCESS_CHECK
Definition: iotypes.h:1773
bool has_wildcard
Definition: btrfs_drv.h:378
UNICODE_STRING query_string
Definition: btrfs_drv.h:377
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:44
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4157
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1586
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:289
#define FILE_ADD_FILE
Definition: nt_native.h:632
static __inline bool is_subvol_readonly(root *r, PIRP Irp)
Definition: btrfs_drv.h:1008
static const GUID GUID_ECP_ATOMIC_CREATE
Definition: create.c:49
long LONG
Definition: pedump.c:60
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4157
#define FILE_ACTION_MODIFIED
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
bool specific_file
Definition: btrfs_drv.h:379
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:287
int options
Definition: main.c:106
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:88
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
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:279
#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET
Definition: create.c:37
bool deleted
Definition: btrfs_drv.h:347
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
uint64_t st_size
Definition: btrfs.h:272
#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:2593
INT POOL_TYPE
Definition: typedefs.h:76
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED
Definition: create.c:35
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __S_IFIFO
Definition: btrfs_drv.h:1735
#define __S_IFCHR
Definition: btrfs_drv.h:1732
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
USHORT NodeType
Definition: btrfs_drv.h:372
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
dir_child * dc
Definition: btrfs_drv.h:354
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
bool case_sensitive
Definition: btrfs_drv.h:387
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
fcb * fcb
Definition: btrfs_drv.h:342
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
Status
Definition: gdiplustypes.h:24
bool is_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
Definition: btrfs.c:5450
#define ERR(fmt,...)
Definition: debug.h:109
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define InterlockedIncrement
Definition: armddk.h:53
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:280
unsigned short USHORT
Definition: pedump.c:61
bool deleted
Definition: btrfs_drv.h:291
uint8_t type
Definition: btrfs_drv.h:249
ULONG disposition
Definition: btrfs_drv.h:374
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
struct _root * subvol
Definition: btrfs_drv.h:284
_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:1314
UINT32 uint32_t
Definition: types.h:75
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1768
#define FILE_ACTION_ADDED
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define called_from_lxss()
Definition: create.c:2958
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
Definition: btrfs.c:100
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
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:99
bool reserving
Definition: btrfs_drv.h:382
#define __S_IFBLK
Definition: btrfs_drv.h:1733
bool lxss
Definition: btrfs_drv.h:392
SHARE_ACCESS share_access
Definition: btrfs_drv.h:294
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:384
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
CSHORT NodeSize
Definition: btrfs_drv.h:373
uint64_t query_dir_offset
Definition: btrfs_drv.h:376
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6884
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:278

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

2135  {
2136  NTSTATUS Status;
2137  fcb* fcb;
2138  ULONG utf8len;
2139  char* utf8 = NULL;
2140  uint64_t inode;
2141  uint8_t type;
2143  BTRFS_TIME now;
2146  USHORT defda;
2147  file_ref* fileref;
2148  dir_child* dc;
2149  ANSI_STRING utf8as;
2150  LIST_ENTRY* lastle = NULL;
2151  file_ref* existing_fileref = NULL;
2152 #ifdef DEBUG_FCB_REFCOUNTS
2153  LONG rc;
2154 #endif
2155 
2156  if (parfileref->fcb == Vcb->dummy_fcb)
2157  return STATUS_ACCESS_DENIED;
2158 
2160  return STATUS_INVALID_PARAMETER;
2161 
2162  Status = utf16_to_utf8(NULL, 0, &utf8len, fpus->Buffer, fpus->Length);
2163  if (!NT_SUCCESS(Status)) {
2164  ERR("utf16_to_utf8 returned %08x\n", Status);
2165  return Status;
2166  }
2167 
2168  utf8 = ExAllocatePoolWithTag(pool_type, utf8len + 1, ALLOC_TAG);
2169  if (!utf8) {
2170  ERR("out of memory\n");
2172  }
2173 
2174  Status = utf16_to_utf8(utf8, utf8len, &utf8len, fpus->Buffer, fpus->Length);
2175  if (!NT_SUCCESS(Status)) {
2176  ERR("utf16_to_utf8 returned %08x\n", Status);
2177  ExFreePool(utf8);
2178  return Status;
2179  }
2180 
2181  utf8[utf8len] = 0;
2182 
2185 
2186  TRACE("create file %.*S\n", fpus->Length / sizeof(WCHAR), fpus->Buffer);
2187  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2188  TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) was %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size);
2189  parfileref->fcb->inode_item.st_size += utf8len * 2;
2190  TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) now %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size);
2191  parfileref->fcb->inode_item.transid = Vcb->superblock.generation;
2192  parfileref->fcb->inode_item.sequence++;
2193  parfileref->fcb->inode_item.st_ctime = now;
2194  parfileref->fcb->inode_item.st_mtime = now;
2195  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2196 
2197  parfileref->fcb->inode_item_changed = true;
2198  mark_fcb_dirty(parfileref->fcb);
2199 
2200  inode = InterlockedIncrement64(&parfileref->fcb->subvol->lastinode);
2201 
2203 
2204  // FIXME - link FILE_ATTRIBUTE_READONLY to st_mode
2205 
2206  TRACE("requested attributes = %x\n", IrpSp->Parameters.Create.FileAttributes);
2207 
2208  defda = 0;
2209 
2210  if (utf8[0] == '.')
2211  defda |= FILE_ATTRIBUTE_HIDDEN;
2212 
2213  if (options & FILE_DIRECTORY_FILE) {
2214  defda |= FILE_ATTRIBUTE_DIRECTORY;
2215  IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
2216  } else
2217  IrpSp->Parameters.Create.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
2218 
2219  if (!(IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2220  IrpSp->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
2221  defda |= FILE_ATTRIBUTE_ARCHIVE;
2222  }
2223 
2224  TRACE("defda = %x\n", defda);
2225 
2226  if (IrpSp->Parameters.Create.FileAttributes == FILE_ATTRIBUTE_NORMAL)
2227  IrpSp->Parameters.Create.FileAttributes = defda;
2228 
2229  fcb = create_fcb(Vcb, pool_type);
2230  if (!fcb) {
2231  ERR("out of memory\n");
2232  ExFreePool(utf8);
2233 
2234  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2235  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2236  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2237 
2239  }
2240 
2241  fcb->Vcb = Vcb;
2242 
2245 
2246  fcb->inode_item.generation = Vcb->superblock.generation;
2247  fcb->inode_item.transid = Vcb->superblock.generation;
2248  fcb->inode_item.st_size = 0;
2249  fcb->inode_item.st_blocks = 0;
2250  fcb->inode_item.block_group = 0;
2251  fcb->inode_item.st_nlink = 1;
2252  fcb->inode_item.st_gid = GID_NOBODY; // FIXME?
2253  fcb->inode_item.st_mode = inherit_mode(parfileref->fcb, type == BTRFS_TYPE_DIRECTORY); // use parent's permissions by default
2254  fcb->inode_item.st_rdev = 0;
2255  fcb->inode_item.flags = 0;
2256  fcb->inode_item.sequence = 1;
2260  fcb->inode_item.otime = now;
2261 
2262  if (type == BTRFS_TYPE_DIRECTORY)
2264  else {
2266  fcb->inode_item.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); // remove executable bit if not directory
2267  }
2268 
2269  if (IrpSp->Flags & SL_OPEN_PAGING_FILE) {
2271  } else {
2272  // inherit nodatacow flag from parent directory
2273  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_NODATACOW) {
2275 
2276  if (type != BTRFS_TYPE_DIRECTORY)
2278  }
2279 
2280  if (parfileref->fcb->inode_item.flags & BTRFS_INODE_COMPRESS)
2282  }
2283 
2284  fcb->prop_compression = parfileref->fcb->prop_compression;
2286 
2287  fcb->inode_item_changed = true;
2288 
2289  fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
2290  fcb->Header.AllocationSize.QuadPart = 0;
2291  fcb->Header.FileSize.QuadPart = 0;
2292  fcb->Header.ValidDataLength.QuadPart = 0;
2293 
2294  fcb->atts = IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL;
2295  fcb->atts_changed = fcb->atts != defda;
2296 
2297 #ifdef DEBUG_FCB_REFCOUNTS
2298  rc = InterlockedIncrement(&parfileref->fcb->refcount);
2299  WARN("fcb %p: refcount now %i\n", parfileref->fcb, rc);
2300 #else
2301  InterlockedIncrement(&parfileref->fcb->refcount);
2302 #endif
2303  fcb->subvol = parfileref->fcb->subvol;
2304  fcb->inode = inode;
2305  fcb->type = type;
2306  fcb->created = true;
2307  fcb->deleted = true;
2308 
2309  fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&inode, sizeof(uint64_t));
2310 
2311  acquire_fcb_lock_exclusive(Vcb);
2312 
2313  if (fcb->subvol->fcbs_ptrs[fcb->hash >> 24]) {
2314  LIST_ENTRY* le = fcb->subvol->fcbs_ptrs[fcb->hash >> 24];
2315 
2316  while (le != &fcb->subvol->fcbs) {
2317  struct _fcb* fcb2 = CONTAINING_RECORD(le, struct _fcb, list_entry);
2318 
2319  if (fcb2->hash > fcb->hash) {
2320  lastle = le->Blink;
2321  break;
2322  }
2323 
2324  le = le->Flink;
2325  }
2326  }
2327 
2328  if (!lastle) {
2329  uint8_t c = fcb->hash >> 24;
2330 
2331  if (c != 0xff) {
2332  uint8_t d = c + 1;
2333 
2334  do {
2335  if (fcb->subvol->fcbs_ptrs[d]) {
2336  lastle = fcb->subvol->fcbs_ptrs[d]->Blink;
2337  break;
2338  }
2339 
2340  d++;
2341  } while (d != 0);
2342  }
2343  }
2344 
2345  if (lastle) {
2346  InsertHeadList(lastle, &fcb->list_entry);
2347 
2348  if (lastle == &fcb->subvol->fcbs || (CONTAINING_RECORD(lastle, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2349  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2350  } else {
2351  InsertTailList(&fcb->subvol->fcbs, &fcb->list_entry);
2352 
2353  if (fcb->list_entry.Blink == &fcb->subvol->fcbs || (CONTAINING_RECORD(fcb->list_entry.Blink, struct _fcb, list_entry)->hash >> 24) != (fcb->hash >> 24))
2354  fcb->subvol->fcbs_ptrs[fcb->hash >> 24] = &fcb->list_entry;
2355  }
2356 
2357  InsertTailList(&Vcb->all_fcbs, &fcb->list_entry_all);
2358 
2359  fcb->subvol->fcbs_version++;
2360 
2361  release_fcb_lock(Vcb);
2362 
2364 
2365  Status = fcb_get_new_sd(fcb, parfileref, IrpSp->Parameters.Create.SecurityContext->AccessState);
2366 
2367  if (!NT_SUCCESS(Status)) {
2368  ERR("fcb_get_new_sd returned %08x\n", Status);
2369  free_fcb(fcb);
2370 
2371  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2372  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2373  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2374 
2375  ExFreePool(utf8);
2376 
2377  return Status;
2378  }
2379 
2380  fcb->sd_dirty = true;
2381 
2382  if (ea && ealen > 0) {
2384  if (!NT_SUCCESS(Status)) {
2385  ERR("file_create_parse_ea returned %08x\n", Status);
2386  free_fcb(fcb);
2387 
2388  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2389  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2390  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2391 
2392  ExFreePool(utf8);
2393 
2394  return Status;
2395  }
2396  }
2397 
2399  if (!fileref) {
2400  ERR("out of memory\n");
2401  free_fcb(fcb);
2402 
2403  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2404  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2405  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2406 
2407  ExFreePool(utf8);
2408 
2410  }
2411 
2412  fileref->fcb = fcb;
2413 
2414  if (Irp->Overlay.AllocationSize.QuadPart > 0 && !write_fcb_compressed(fcb)) {
2415  Status = extend_file(fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback);
2416 
2417  if (!NT_SUCCESS(Status)) {
2418  ERR("extend_file returned %08x\n", Status);
2420 
2421  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2422  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2423  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2424 
2425  ExFreePool(utf8);
2426 
2427  return Status;
2428  }
2429  }
2430 
2431  if (fcb->type == BTRFS_TYPE_DIRECTORY) {
2433  if (!fcb->hash_ptrs) {
2434  ERR("out of memory\n");
2436 
2437  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2438  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2439  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2440 
2441  ExFreePool(utf8);
2442 
2444  }
2445 
2446  RtlZeroMemory(fcb->hash_ptrs, sizeof(LIST_ENTRY*) * 256);
2447 
2449  if (!fcb->hash_ptrs_uc) {
2450  ERR("out of memory\n");
2452 
2453  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2454  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2455  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2456 
2457  ExFreePool(utf8);
2458 
2460  }
2461 
2462  RtlZeroMemory(fcb->hash_ptrs_uc, sizeof(LIST_ENTRY*) * 256);
2463  }
2464 
2465  fcb->deleted = false;
2466 
2467  fileref->created = true;
2468 
2469  fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
2470  fcb->subvol->root_item.ctime = now;
2471 
2472  utf8as.Buffer = utf8;
2473  utf8as.Length = utf8as.MaximumLength = (uint16_t)utf8len;
2474 
2475  ExAcquireResourceExclusiveLite(&parfileref->fcb->nonpaged->dir_children_lock, true);
2476 
2477  // check again doesn't already exist
2478  if (case_sensitive) {
2479  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpus->Buffer, fpus->Length);
2480 
2481  if (parfileref->fcb->hash_ptrs[dc_hash >> 24]) {
2482  LIST_ENTRY* le = parfileref->fcb->hash_ptrs[dc_hash >> 24];
2483  while (le != &parfileref->fcb->dir_children_hash) {
2484  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
2485 
2486  if (dc->hash == dc_hash && dc->name.Length == fpus->Length && RtlCompareMemory(dc->name.Buffer, fpus->Buffer, fpus->Length) == fpus->Length) {
2487  existing_fileref = dc->fileref;
2488  break;
2489  } else if (dc->hash > dc_hash)
2490  break;
2491 
2492  le = le->Flink;
2493  }
2494  }
2495  } else {
2496  UNICODE_STRING fpusuc;
2497 #ifdef __REACTOS__
2498  UINT32 dc_hash;
2499 #endif
2500 
2501  Status = RtlUpcaseUnicodeString(&fpusuc, fpus, true);
2502  if (!NT_SUCCESS(Status)) {
2503  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2504  ERR("RtlUpcaseUnicodeString returned %08x\n", Status);
2506 
2507  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2508  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2509  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2510 
2511  ExFreePool(utf8);
2512 
2513  return Status;
2514  }
2515 
2516 #ifndef __REACTOS__
2517  uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length);
2518 #else
2519  dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length);
2520 #endif
2521 
2522  if (parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]) {
2523  LIST_ENTRY* le = parfileref->fcb->hash_ptrs_uc[dc_hash >> 24];
2524  while (le != &parfileref->fcb->dir_children_hash_uc) {
2525  dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
2526 
2527  if (dc->hash_uc == dc_hash && dc->name.Length == fpusuc.Length && RtlCompareMemory(dc->name.Buffer, fpusuc.Buffer, fpusuc.Length) == fpusuc.Length) {
2528  existing_fileref = dc->fileref;
2529  break;
2530  } else if (dc->hash_uc > dc_hash)
2531  break;
2532 
2533  le = le->Flink;
2534  }
2535  }
2536 
2537  ExFreePool(fpusuc.Buffer);
2538  }
2539 
2540  if (existing_fileref) {
2541  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2543 
2544  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2545  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2546  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2547 
2548  ExFreePool(utf8);
2549 
2550  increase_fileref_refcount(existing_fileref);
2551  *pfr = existing_fileref;
2552 
2554  }
2555 
2556  Status = add_dir_child(parfileref->fcb, fcb->inode, false, &utf8as, fpus, fcb->type, &dc);
2557  if (!NT_SUCCESS(Status)) {
2558  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2559  ERR("add_dir_child returned %08x\n", Status);
2561 
2562  ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true);
2563  parfileref->fcb->inode_item.st_size -= utf8len * 2;
2564  ExReleaseResourceLite(parfileref->fcb->Header.Resource);
2565 
2566  ExFreePool(utf8);
2567 
2568  return Status;
2569  }
2570 
2571  fileref->parent = parfileref;
2572  fileref->dc = dc;
2573  dc->fileref = fileref;
2574 
2575  if (type == BTRFS_TYPE_DIRECTORY)
2576  fileref->fcb->fileref = fileref;
2577 
2578  InsertTailList(&parfileref->children, &fileref->list_entry);
2579  ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock);
2580 
2581  ExFreePool(utf8);
2582 
2584  increase_fileref_refcount(parfileref);
2585 
2586  *pfr = fileref;
2587 
2588  TRACE("created new file in subvol %I64x, inode %I64x\n", fcb->subvol->id, fcb->inode);
2589 
2590  return STATUS_SUCCESS;
2591 }
#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:120
BTRFS_TIME otime
Definition: btrfs.h:286
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1653
#define BTRFS_INODE_NODATACOW
Definition: propsheet.h:77
Iosb Status
Definition: create.c:4311
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1774
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
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:111
LONG NTSTATUS
Definition: precomp.h:26
enum prop_compression_type prop_compression
Definition: btrfs_drv.h:303
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
uint32_t inherit_mode(fcb *parfcb, bool is_dir)
Definition: create.c:1905
HDC dc
Definition: cylfrac.c:34
#define S_IFREG
Definition: ext2fs.h:356
__u16 time
Definition: mkdosfs.c:366
uint64_t block_group
Definition: btrfs.h:274
#define uint16_t
Definition: nsiface.idl:60
void reap_fileref(device_extension *Vcb, file_ref *fr)
Definition: btrfs.c:1788
#define InsertTailList(ListHead, Entry)
bool atts_changed
Definition: btrfs_drv.h:318
BTRFS_TIME st_ctime
Definition: btrfs.h:284
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: recv.cpp:134
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:333
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:51
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:4157
uint32_t st_gid
Definition: btrfs.h:277
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1636
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:332
#define S_IXOTH
Definition: propsheet.h:61
uint64_t sequence
Definition: btrfs.h:281
uint32_t st_nlink
Definition: btrfs.h:275
time_t now
Definition: finger.c:65
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:314
smooth NULL
Definition: ftsmooth.c:416
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1614
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:672
uint8_t type
Definition: btrfs_drv.h:287
BTRFS_TIME st_mtime
Definition: btrfs.h:285
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1716
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:322
#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:1658
ULONG ealen
Definition: btrfs_drv.h:299
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:279
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define S_IXGRP
Definition: propsheet.h:49
uint64_t st_size
Definition: btrfs.h:272
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedIncrement64
Definition: interlocked.h:211
struct _fcb fcb
Definition: btrfs_drv.h:1314
bool sd_dirty
Definition: btrfs_drv.h:317
#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:76
uint64_t inode
Definition: btrfs_drv.h:285
uint64_t st_rdev
Definition: btrfs.h:279
#define BTRFS_INODE_NODATASUM
Definition: propsheet.h:76
const GLubyte * c
Definition: glext.h:8905
struct _file_ref * fileref
Definition: btrfs_drv.h:301
bool case_sensitive
Definition: btrfs_drv.h:306
#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:286
#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:283
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define S_IXUSR
Definition: propsheet.h:37
bool created
Definition: btrfs_drv.h:324
Definition: typedefs.h:117
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1636
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
uint64_t generation
Definition: btrfs.h:270
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t st_blocks
Definition: btrfs.h:273
uint64_t flags
Definition: btrfs.h:280
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
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:1830
UINT64 uint64_t
Definition: types.h:77
#define InterlockedIncrement
Definition: armddk.h:53
ULONG atts
Definition: btrfs_drv.h:293
unsigned short USHORT
Definition: pedump.c:61
bool deleted
Definition: btrfs_drv.h:291
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
uint64_t transid
Definition: btrfs.h:271
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
struct _root * subvol
Definition: btrfs_drv.h:284
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:1314
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:964
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:313
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
Definition: _hash_fun.h:40
bool inode_item_changed
Definition: btrfs_drv.h:302
NTSTATUS extend_file(fcb *fcb, file_ref *fileref, uint64_t end, bool prealloc, PIRP Irp, LIST_ENTRY *rollback)
Definition: write.c:3319
NTSTATUS fcb_get_new_sd(fcb *fcb, file_ref *parfileref, ACCESS_STATE *as)
Definition: security.c:907
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:283
static NTSTATUS file_create_parse_ea(fcb *fcb, FILE_FULL_EA_INFORMATION *ea)
Definition: create.c:1921
#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:278

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

1921  {
1922  NTSTATUS Status;
1923  LIST_ENTRY ealist, *le;
1924  uint16_t size = 0;
1925  char* buf;
1926 
1927  InitializeListHead(&ealist);
1928 
1929  do {
1930  STRING s;
1931  bool found = false;
1932 
1933  s.Length = s.MaximumLength = ea->EaNameLength;
1934  s.Buffer = ea->EaName;
1935 
1936  RtlUpperString(&s, &s);
1937 
1938  le = ealist.Flink;
1939  while (le != &ealist) {
1941 
1942  if (item->name.Length == s.Length && RtlCompareMemory(item->name.Buffer, s.Buffer, s.Length) == s.Length) {
1943  item->flags = ea->Flags;
1944  item->value.Length = item->value.MaximumLength = ea->EaValueLength;
1945  item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
1946  found = true;
1947  break;
1948  }
1949 
1950  le = le->Flink;
1951  }
1952 
1953  if (!found) {
1955  if (!item) {
1956  ERR("out of memory\n");
1958  goto end;
1959  }
1960 
1961  item->name.Length = item->name.MaximumLength = ea->EaNameLength;
1962  item->name.Buffer = ea->EaName;
1963 
1964  item->value.Length = item->value.MaximumLength = ea->EaValueLength;
1965  item->value.Buffer = &ea->EaName[ea->EaNameLength + 1];
1966 
1967  item->flags = ea->Flags;
1968 
1969  InsertTailList(&ealist, &item->list_entry);
1970  }
1971 
1972  if (ea->NextEntryOffset == 0)
1973  break;
1974 
1975  ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
1976  } while (true);
1977 
1978  // handle LXSS values
1979  le = ealist.Flink;
1980  while (le != &ealist) {
1981  LIST_ENTRY* le2 = le->Flink;
1983 
1984  if (item->name.Length == sizeof(lxuid) - 1 && RtlCompareMemory(item->name.Buffer, lxuid, item->name.Length) == item->name.Length) {
1985  if (item->value.Length < sizeof(uint32_t)) {
1986  ERR("uid value was shorter than expected\n");
1988  goto end;
1989  }
1990 
1991  RtlCopyMemory(&fcb->inode_item.st_uid, item->value.Buffer, sizeof(uint32_t));
1992  fcb->sd_dirty = true;
1993  fcb->sd_deleted = false;
1994 
1995  RemoveEntryList(&item->list_entry);
1996  ExFreePool(item);
1997  } else if (item->name.Length == sizeof(lxgid) - 1 && RtlCompareMemory(item->name.Buffer, lxgid, item->name.Length) == item->name.Length) {
1998  if (item->value.Length < sizeof(uint32_t)) {
1999  ERR("gid value was shorter than expected\n");
2001  goto end;
2002  }
2003 
2004  RtlCopyMemory(&fcb->inode_item.st_gid, item->value.Buffer, sizeof(uint32_t));
2005 
2006  RemoveEntryList(&item->list_entry);
2007  ExFreePool(item);
2008  } else if (item->name.Length == sizeof(lxmod) - 1 && RtlCompareMemory(item->name.Buffer, lxmod, item->name.Length) == item->name.Length) {
2010  uint32_t val;
2011 
2012  if (item->value.Length < sizeof(uint32_t)) {
2013  ERR("mode value was shorter than expected\n");
2015  goto end;
2016  }
2017 
2018  RtlCopyMemory(&val, item->value.Buffer, sizeof(uint32_t));
2019 
2020  if (fcb->type != BTRFS_TYPE_DIRECTORY)
2021  allowed |= __S_IFIFO | __S_IFCHR | __S_IFBLK | __S_IFSOCK;
2022 
2023  fcb->inode_item.st_mode &= ~allowed;
2024  fcb->inode_item.st_mode |= val & allowed;
2025 
2026  if (fcb->type != BTRFS_TYPE_DIRECTORY) {
2029  else if ((fcb->inode_item.st_mode & __S_IFBLK) == __S_IFBLK)
2031  else if ((fcb->inode_item.st_mode & __S_IFIFO) == __S_IFIFO)
2033  else if ((fcb->inode_item.st_mode & __S_IFSOCK) == __S_IFSOCK)
2035  }
2036 
2037  RemoveEntryList(&item->list_entry);
2038  ExFreePool(item);
2039  } else if (item->name.Length == sizeof(lxdev) - 1 && RtlCompareMemory(item->name.Buffer, lxdev, item->name.Length) == item->name.Length) {
2040  uint32_t major, minor;
2041 
2042  if (item->value.Length < sizeof(uint64_t)) {
2043  ERR("dev value was shorter than expected\n");
2045  goto end;
2046  }
2047 
2048  major = *(uint32_t*)item->value.Buffer;
2049  minor = *(uint32_t*)&item->value.Buffer[sizeof(uint32_t)];
2050 
2051  fcb->inode_item.st_rdev = (minor & 0xFFFFF) | ((major & 0xFFFFFFFFFFF) << 20);
2052 
2053  RemoveEntryList(&item->list_entry);
2054  ExFreePool(item);
2055  }
2056 
2057  le = le2;
2058  }
2059 
2061  fcb->inode_item.st_rdev = 0;
2062 
2063  if (IsListEmpty(&ealist))
2064  return STATUS_SUCCESS;
2065 
2066  le = ealist.Flink;
2067  while (le != &ealist) {
2069 
2070  if (size % 4 > 0)
2071  size += 4 - (size % 4);
2072 
2073  size += (uint16_t)offsetof(FILE_FULL_EA_INFORMATION, EaName[0]) + item->name.Length + 1 + item->value.Length;
2074 
2075  le = le->Flink;
2076  }
2077 
2079  if (!buf) {
2080  ERR("out of memory\n");
2082  goto end;
2083  }
2084 
2086  fcb->ea_xattr.Buffer = buf;
2087 
2088  fcb->ealen = 4;
2089  ea = NULL;
2090 
2091  le = ealist.Flink;
2092  while (le != &ealist) {
2094 
2095  if (ea) {
2097 
2098  if (ea->NextEntryOffset % 4 > 0)
2099  ea->NextEntryOffset += 4 - (ea->NextEntryOffset % 4);
2100 
2101  ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset);
2102  } else
2104 
2105  ea->NextEntryOffset = 0;
2106  ea->Flags = item->flags;
2107  ea->EaNameLength = (UCHAR)item->name.Length;
2108  ea->EaValueLength = item->value.Length;
2109 
2110  RtlCopyMemory(ea->EaName, item->name.Buffer, item->name.Length);
2111  ea->EaName[item->name.Length] = 0;
2112  RtlCopyMemory(&ea->EaName[item->name.Length + 1], item->value.Buffer, item->value.Length);
2113 
2114  fcb->ealen += 5 + item->name.Length + item->value.Length;
2115 
2116  le = le->Flink;
2117  }
2118 
2119  fcb->ea_changed = true;
2120 
2122 
2123 end:
2124  while (!IsListEmpty(&ealist)) {
2126 
2127  ExFreePool(item);
2128  }
2129 
2130  return Status;
2131 }
NTSYSAPI VOID NTAPI RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
static const char lxuid[]
Definition: btrfs_drv.h:1244
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:1247
Iosb Status
Definition: create.c:4311
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:1737
LONG NTSTATUS
Definition: precomp.h:26
bool sd_deleted
Definition: btrfs_drv.h:317
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
ANSI_STRING ea_xattr
Definition: btrfs_drv.h:298
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:321
uint32_t st_gid
Definition: btrfs.h:277
#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:287
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:299
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#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:317
uint64_t st_rdev
Definition: btrfs.h:279
#define __S_IFIFO
Definition: btrfs_drv.h:1735
#define __S_IFCHR
Definition: btrfs_drv.h:1732
std::wstring STRING
Definition: fontsub.cpp:33
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define S_IXUSR
Definition: propsheet.h:37
#define S_IROTH
Definition: propsheet.h:53
GLdouble s
Definition: gl.h:2039
Definition: typedefs.h:117
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
BYTE uint8_t
Definition: msvideo1.c:66
#define S_IWOTH
Definition: propsheet.h:57
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
UINT64 uint64_t
Definition: types.h:77
static ATOM item
Definition: dde.c:856
static const char lxgid[]
Definition: btrfs_drv.h:1245
#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:1246
#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:1733
#define uint32_t
Definition: nsiface.idl:61
uint32_t st_uid
Definition: btrfs.h:276
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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:278

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

151  {
153  UNICODE_STRING fnus;
154  uint32_t hash;
155  LIST_ENTRY* le;
156  uint8_t c;
157  bool locked = false;
158 
159  if (!case_sensitive) {
160  Status = RtlUpcaseUnicodeString(&fnus, filename, true);
161 
162  if (!NT_SUCCESS(Status)) {
163  ERR("RtlUpcaseUnicodeString returned %08x\n", Status);
164  return Status;
165  }
166  } else
167  fnus = *filename;
168 
169  hash = calc_crc32c(0xffffffff, (uint8_t*)fnus.Buffer, fnus.Length);
170 
171  c = hash >> 24;
172 
173  if (!ExIsResourceAcquiredSharedLite(&fcb->nonpaged->dir_children_lock)) {
174  ExAcquireResourceSharedLite(&fcb->nonpaged->dir_children_lock, true);
175  locked = true;
176  }
177 
178  if (case_sensitive) {
179  if (!fcb->hash_ptrs[c]) {
181  goto end;
182  }
183 
184  le = fcb->hash_ptrs[c];
185  while (le != &fcb->dir_children_hash) {
186  dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_hash);
187 
188  if (dc->hash == hash) {
189  if (dc->name.Length == fnus.Length && RtlCompareMemory(dc->name.Buffer, fnus.Buffer, fnus.Length) == fnus.Length) {
190  if (dc->key.obj_type == TYPE_ROOT_ITEM) {
191  LIST_ENTRY* le2;
192 
193  *subvol = NULL;
194 
195  le2 = fcb->Vcb->roots.Flink;
196  while (le2 != &fcb->Vcb->roots) {
198 
199  if (r2->id == dc->key.obj_id) {
200  *subvol = r2;
201  break;
202  }
203 
204  le2 = le2->Flink;
205  }
206 
208  } else {
209  *subvol = fcb->subvol;
210  *inode = dc->key.obj_id;
211  }
212 
213  *pdc = dc;
214 
216  goto end;
217  }
218  } else if (dc->hash > hash) {
220  goto end;
221  }
222 
223  le = le->Flink;
224  }
225  } else {
226  if (!fcb->hash_ptrs_uc[c]) {
228  goto end;
229  }
230 
231  le = fcb->hash_ptrs_uc[c];
232  while (le != &fcb->dir_children_hash_uc) {
233  dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
234 
235  if (dc->hash_uc == hash) {
236  if (dc->name_uc.Length == fnus.Length && RtlCompareMemory(dc->name_uc.Buffer, fnus.Buffer, fnus.Length) == fnus.Length) {
237  if (dc->key.obj_type == TYPE_ROOT_ITEM) {
238  LIST_ENTRY* le2;
239 
240  *subvol = NULL;
241 
242  le2 = fcb->Vcb->roots.Flink;
243  while (le2 != &fcb->Vcb->roots) {
245 
246  if (r2->id == dc->key.obj_id) {
247  *subvol = r2;
248  break;
249  }
250 
251  le2 = le2->Flink;
252  }
253 
255  } else {
256  *subvol = fcb->subvol;
257  *inode = dc->key.obj_id;
258  }
259 
260  *pdc = dc;
261 
263  goto end;
264  }
265  } else if (dc->hash_uc > hash) {
267  goto end;
268  }
269 
270  le = le->Flink;
271  }
272  }
273 
275 
276 end:
277  if (locked)
278  ExReleaseResourceLite(&fcb->nonpaged->dir_children_lock);
279 
280  if (!case_sensitive)
281  ExFreePool(fnus.Buffer);
282 
283  return Status;
284 }
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
Iosb Status
Definition: create.c:4311
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
LONG NTSTATUS
Definition: precomp.h:26
HDC dc
Definition: cylfrac.c:34
GLuint GLuint end
Definition: gl.h:1545
const char * filename
Definition: ioapi.h:135
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: recv.cpp:134
Definition: fs.h:78
int hash
Definition: main.c:58
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:314
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:119
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:312
#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:306
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
Definition: typedefs.h:117
BYTE uint8_t
Definition: msvideo1.c:66
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:280
#define TYPE_ROOT_ITEM
Definition: btrfs.h:28
struct _root * subvol
Definition: btrfs_drv.h:284
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:313
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:311
return STATUS_SUCCESS
Definition: btrfs.c:2938
Definition: _hash_fun.h:40
struct _device_extension * Vcb
Definition: btrfs_drv.h:283
#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 3359 of file create.c.

3359  {
3360  NTSTATUS Status;
3361 
3363  ULONG size, bytes_read, i;
3364 
3365  if (fcb->type == BTRFS_TYPE_FILE && fcb->inode_item.st_size < sizeof(ULONG)) {
3366  WARN("file was too short to be a reparse point\n");
3367  return STATUS_INVALID_PARAMETER;
3368  }
3369 
3370  // 0x10007 = 0xffff (maximum length of data buffer) + 8 bytes header
3371  size = (ULONG)min(0x10007, fcb->inode_item.st_size);
3372 
3373  if (size == 0)
3374  return STATUS_INVALID_PARAMETER;
3375 
3377  if (!*data) {
3378  ERR("out of memory\n");
3380  }
3381 
3382  Status = read_file(fcb, *data, 0, size, &bytes_read, NULL);
3383  if (!NT_SUCCESS(Status)) {
3384  ERR("read_file_fcb returned %08x\n", Status);
3385  ExFreePool(*data);
3386  return Status;
3387  }
3388 
3389  if (fcb->type == BTRFS_TYPE_SYMLINK) {
3390  ULONG stringlen, reqlen;
3391  uint16_t subnamelen, printnamelen;
3392  REPARSE_DATA_BUFFER* rdb;
3393 
3394  Status = utf8_to_utf16(NULL, 0, &stringlen, (char*)*data, bytes_read);
3395  if (!NT_SUCCESS(Status)) {
3396  ERR("utf8_to_utf16 1 returned %08x\n", Status);
3397  ExFreePool(*data);
3398  return Status;
3399  }
3400 
3401  subnamelen = printnamelen = (USHORT)stringlen;
3402 
3403  reqlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + subnamelen + printnamelen;
3404 
3405  rdb = ExAllocatePoolWithTag(PagedPool, reqlen, ALLOC_TAG);
3406 
3407  if (!rdb) {
3408  ERR("out of memory\n");
3409  ExFreePool(*data);
3411  }
3412 
3414  rdb->ReparseDataLength = (USHORT)(reqlen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
3415  rdb->Reserved = 0;
3416 
3417  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
3418  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = subnamelen;
3419  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = subnamelen;
3420  rdb->SymbolicLinkReparseBuffer.PrintNameLength = printnamelen;
3422 
3423  Status = utf8_to_utf16(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3424  stringlen, &stringlen, (char*)*data, size);
3425 
3426  if (!NT_SUCCESS(Status)) {
3427  ERR("utf8_to_utf16 2 returned %08x\n", Status);
3428  ExFreePool(rdb);
3429  ExFreePool(*data);
3430  return Status;
3431  }
3432 
3433  for (i = 0; i < stringlen / sizeof(WCHAR); i++) {
3434  if (rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] == '/')
3435  rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] = '\\';
3436  }
3437 
3438  RtlCopyMemory(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)],
3439  &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
3440  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
3441 
3442  ExFreePool(*data);
3443 
3444  *data = (uint8_t*)rdb;
3445  } else {
3447  if (!NT_SUCCESS(Status)) {
3448  ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status);
3449  ExFreePool(*data);
3450  return Status;
3451  }
3452  }
3453  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
3455  return STATUS_INTERNAL_ERROR;
3456 
3457  if (fcb->reparse_xattr.Length < sizeof(ULONG)) {
3458  WARN("xattr was too short to be a reparse point\n");
3459  return STATUS_INTERNAL_ERROR;
3460  }
3461 
3463  if (!NT_SUCCESS(Status)) {
3464  ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status);
3465  return Status;
3466  }
3467 
3469  if (!*data) {
3470  ERR("out of memory\n");
3472  }
3473 
3475  } else
3476  return STATUS_INVALID_PARAMETER;
3477 
3478  return STATUS_SUCCESS;
3479 }
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:4311
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:297
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:2715
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#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:287
uint64_t st_size
Definition: btrfs.h:272
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
USHORT ReparseDataLength
Definition: shellext.h:166
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:101
GLint const GLchar GLint stringlen
Definition: glext.h:7232
struct _REPARSE_DATA_BUFFER::@308::@310 SymbolicLinkReparseBuffer
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
BYTE uint8_t
Definition: msvideo1.c:66
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
unsigned short USHORT
Definition: pedump.c:61
#define min(a, b)
Definition: monoChain.cc:55
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6884
#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 4709 of file create.c.

4709  {
4710  PRIVILEGE_SET privset;
4711 
4712  privset.PrivilegeCount = 1;
4714  privset.Privilege[0].Luid = RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE);
4715  privset.Privilege[0].Attributes = 0;
4716 
4717  return SePrivilegeCheck(&privset, &access_state->SubjectSecurityContext, processor_mode) ? true : false;
4718 }
#define true
Definition: stdbool.h:37
$ULONG Control
Definition: setypes.h:87
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
$ULONG PrivilegeCount
Definition: setypes.h:86
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h: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 1905 of file create.c.

1905  {
1906  uint32_t mode;
1907 
1908  if (!parfcb)
1909  return 0755;
1910 
1911  mode = parfcb->inode_item.st_mode & ~S_IFDIR;
1912  mode &= ~S_ISVTX; // clear sticky bit
1913  mode &= ~S_ISUID; // clear setuid bit
1914 
1915  if (!is_dir)
1916  mode &= ~S_ISGID; // if not directory, clear setgid bit
1917 
1918  return mode;
1919 }
#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:288
#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:278

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,
uint32_t csum,
uint64_t  start,
uint64_t  length,
PIRP  Irp 
)

Definition at line 418 of file create.c.

418  {
420  KEY searchkey;
421  traverse_ptr tp, next_tp;
422  uint64_t i, j;
423  bool b;
424 
425  searchkey.obj_id = EXTENT_CSUM_ID;
426  searchkey.obj_type = TYPE_EXTENT_CSUM;
427  searchkey.offset = start;
428 
429  Status = find_item(Vcb, Vcb->checksum_root, &tp, &searchkey, false, Irp);
430  if (!NT_SUCCESS(Status)) {
431  ERR("error - find_item returned %08x\n", Status);
432  return Status;
433  }
434 
435  i = 0;
436  do {
437  if (tp.item->key.obj_id == searchkey.obj_id && tp.item->key.obj_type == searchkey.obj_type) {
438  ULONG readlen;
439 
440  if (start < tp.item->key.offset)
441  j = 0;
442  else
443  j = ((start - tp.item->key.offset) / Vcb->superblock.sector_size) + i;
444 
445  if (j * sizeof(uint32_t) > tp.item->size || tp.item->key.offset > start + (i * Vcb->superblock.sector_size)) {
446  ERR("checksum not found for %I64x\n", start + (i * Vcb->superblock.sector_size));
447  return STATUS_INTERNAL_ERROR;
448  }
449 
450  readlen = (ULONG)min((tp.item->size / sizeof(uint32_t)) - j, length - i);
451  RtlCopyMemory(&csum[i], tp.item->data + (j * sizeof(uint32_t)), readlen * sizeof(uint32_t));
452  i += readlen;
453 
454  if (i == length)
455  break;
456  }
457 
458  b = find_next_item(Vcb, &tp, &next_tp, false, Irp);
459 
460  if (b)
461  tp = next_tp;
462  } while (b);
463 
464  if (i < length) {
465  ERR("could not read checksums: offset %I64x, length %I64x sectors\n", start, length);
466  return STATUS_INTERNAL_ERROR;
467  }
468 
469  return STATUS_SUCCESS;
470 }
uint64_t obj_id
Definition: btrfs.h:128
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
uint8_t obj_type
Definition: btrfs.h:129
Iosb Status
Definition: create.c:4311
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
uint16_t size
Definition: btrfs_drv.h:415
uint64_t offset
Definition: btrfs.h:130
uint8_t * data
Definition: btrfs_drv.h:416
#define TYPE_EXTENT_CSUM
Definition: btrfs.h:27
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB Vcb
Definition: create.c:4157
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 b
Definition: ke_i.h:79
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
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2855
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
bool find_next_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, const traverse_ptr *tp, traverse_ptr *next_tp, bool ignore, PIRP Irp)
Definition: treefuncs.c:592
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32