ReactOS  0.4.15-dev-4914-g2220e56
reparse.c File Reference
#include "btrfs_drv.h"
Include dependency graph for reparse.c:

Go to the source code of this file.

Classes

struct  REPARSE_DATA_BUFFER_LX_SYMLINK
 

Functions

NTSTATUS get_reparse_point (PFILE_OBJECT FileObject, void *buffer, DWORD buflen, ULONG_PTR *retlen)
 
static NTSTATUS set_symlink (PIRP Irp, file_ref *fileref, fcb *fcb, ccb *ccb, REPARSE_DATA_BUFFER *rdb, ULONG buflen, LIST_ENTRY *rollback)
 
NTSTATUS set_reparse_point2 (fcb *fcb, REPARSE_DATA_BUFFER *rdb, ULONG buflen, ccb *ccb, file_ref *fileref, PIRP Irp, LIST_ENTRY *rollback)
 
NTSTATUS set_reparse_point (PIRP Irp)
 
NTSTATUS delete_reparse_point (PIRP Irp)
 

Variables

tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
 

Function Documentation

◆ delete_reparse_point()

NTSTATUS delete_reparse_point ( PIRP  Irp)

Definition at line 482 of file reparse.c.

482  {
485  REPARSE_DATA_BUFFER* rdb = Irp->AssociatedIrp.SystemBuffer;
486  DWORD buflen = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
488  fcb* fcb;
489  ccb* ccb;
490  file_ref* fileref;
492 
493  TRACE("(%p)\n", Irp);
494 
496 
497  if (!FileObject) {
498  ERR("FileObject was NULL\n");
500  }
501 
502  fcb = FileObject->FsContext;
503 
504  if (!fcb) {
505  ERR("fcb was NULL\n");
507  }
508 
509  ccb = FileObject->FsContext2;
510 
511  if (!ccb) {
512  ERR("ccb was NULL\n");
514  }
515 
516  if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_ATTRIBUTES)) {
517  WARN("insufficient privileges\n");
518  return STATUS_ACCESS_DENIED;
519  }
520 
521  fileref = ccb->fileref;
522 
523  if (!fileref) {
524  ERR("fileref was NULL\n");
526  }
527 
528  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true);
529  ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
530 
531  if (buflen < offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)) {
532  ERR("buffer was too short\n");
534  goto end;
535  }
536 
537  if (rdb->ReparseDataLength > 0) {
538  WARN("rdb->ReparseDataLength was not zero\n");
540  goto end;
541  }
542 
543  if (fcb->ads) {
544  WARN("tried to delete reparse point on ADS\n");
546  goto end;
547  }
548 
549  if (fcb->type == BTRFS_TYPE_SYMLINK) {
551  BTRFS_TIME now;
552 
553  if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
554  WARN("reparse tag was not IO_REPARSE_TAG_SYMLINK\n");
556  goto end;
557  }
558 
561 
562  fileref->fcb->type = BTRFS_TYPE_FILE;
563  fileref->fcb->inode_item.st_mode &= ~__S_IFLNK;
564  fileref->fcb->inode_item.st_mode |= __S_IFREG;
565  fileref->fcb->inode_item.generation = fileref->fcb->Vcb->superblock.generation; // so we don't confuse btrfs send on Linux
566  fileref->fcb->inode_item.transid = fileref->fcb->Vcb->superblock.generation;
567  fileref->fcb->inode_item.sequence++;
568 
570  fileref->fcb->inode_item.st_ctime = now;
571 
572  if (!ccb->user_set_write_time)
573  fileref->fcb->inode_item.st_mtime = now;
574 
575  fileref->fcb->atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
576 
577  if (fileref->dc)
578  fileref->dc->type = fileref->fcb->type;
579 
580  mark_fileref_dirty(fileref);
581 
582  fileref->fcb->inode_item_changed = true;
583  mark_fcb_dirty(fileref->fcb);
584 
585  fileref->fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
586  fileref->fcb->subvol->root_item.ctime = now;
587  } else if (fcb->type == BTRFS_TYPE_FILE) {
589  BTRFS_TIME now;
590 
591  // FIXME - do we need to check that the reparse tags match?
592 
594  if (!NT_SUCCESS(Status)) {
595  ERR("truncate_file returned %08lx\n", Status);
596  goto end;
597  }
598 
600  fcb->atts_changed = true;
601 
604 
605  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
607 
610 
611  if (!ccb->user_set_write_time)
613 
614  fcb->inode_item_changed = true;
616 
617  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
618  fcb->subvol->root_item.ctime = now;
619  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
621  BTRFS_TIME now;
622 
623  // FIXME - do we need to check that the reparse tags match?
624 
626  fcb->atts_changed = true;
627 
628  if (fcb->reparse_xattr.Buffer) {
631  }
632 
633  fcb->reparse_xattr_changed = true;
634 
637 
638  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
640 
643 
644  if (!ccb->user_set_write_time)
646 
647  fcb->inode_item_changed = true;
649 
650  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
651  fcb->subvol->root_item.ctime = now;
652  } else {
653  ERR("unsupported file type %u\n", fcb->type);
655  goto end;
656  }
657 
659 
661 
662 end:
663  if (NT_SUCCESS(Status))
665  else
667 
668  ExReleaseResourceLite(fcb->Header.Resource);
669  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
670 
671  return Status;
672 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
bool reparse_xattr_changed
Definition: btrfs_drv.h:324
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
#define FILE_NOTIFY_CHANGE_LAST_WRITE
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:382
bool atts_changed
Definition: btrfs_drv.h:322
BTRFS_TIME st_ctime
Definition: btrfs.h:302
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
bool user_set_write_time
Definition: btrfs_drv.h:389
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1636
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1686
_In_ PIRP Irp
Definition: csq.h:116
uint64_t sequence
Definition: btrfs.h:299
time_t now
Definition: finger.c:65
NTSTATUS NTSTATUS NTSTATUS truncate_file(fcb *fcb, uint64_t end, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define FILE_ACTION_MODIFIED
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
UCHAR DataBuffer[1]
Definition: shellext.h:188
#define offsetof(TYPE, MEMBER)
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
uint8_t type
Definition: btrfs_drv.h:291
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
BTRFS_TIME st_mtime
Definition: btrfs.h:303
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
struct _fcb fcb
Definition: btrfs_drv.h:1355
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
bool user_set_change_time
Definition: btrfs_drv.h:390
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1998
GLuint GLuint end
Definition: gl.h:1545
dir_child * dc
Definition: btrfs_drv.h:353
USHORT ReparseDataLength
Definition: shellext.h:166
fcb * fcb
Definition: btrfs_drv.h:342
Definition: typedefs.h:119
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback) __attribute__((nonnull(1
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
uint64_t generation
Definition: btrfs.h:287
#define __S_IFREG
Definition: btrfs_drv.h:1747
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
ULONG atts
Definition: btrfs_drv.h:297
uint8_t type
Definition: btrfs_drv.h:253
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
uint64_t transid
Definition: btrfs.h:288
struct _root * subvol
Definition: btrfs_drv.h:288
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
bool ads
Definition: btrfs_drv.h:330
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:981
uint32_t buflen
Definition: read.c:49
#define __S_IFLNK
Definition: btrfs_drv.h:1749
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:383
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
bool inode_item_changed
Definition: btrfs_drv.h:306
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
uint32_t st_mode
Definition: btrfs.h:295

Referenced by fsctl_request().

◆ get_reparse_point()

NTSTATUS get_reparse_point ( PFILE_OBJECT  FileObject,
void buffer,
DWORD  buflen,
ULONG_PTR retlen 
)

Definition at line 27 of file reparse.c.

27  {
28  USHORT subnamelen, printnamelen, i;
30  DWORD reqlen;
32  fcb* fcb = FileObject->FsContext;
33  ccb* ccb = FileObject->FsContext2;
35 
36  TRACE("(%p, %p, %lx, %p)\n", FileObject, buffer, buflen, retlen);
37 
38  if (!ccb)
40 
41  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true);
42  ExAcquireResourceSharedLite(fcb->Header.Resource, true);
43 
44  if (fcb->type == BTRFS_TYPE_SYMLINK) {
45  if (ccb->lxss) {
46  reqlen = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + sizeof(uint32_t);
47 
48  if (buflen < reqlen) {
50  goto end;
51  }
52 
54  rdb->ReparseDataLength = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + sizeof(uint32_t);
55  rdb->Reserved = 0;
56 
57  *((uint32_t*)rdb->GenericReparseBuffer.DataBuffer) = 1;
58 
59  *retlen = reqlen;
60  } else {
61  char* data;
62 
63  if (fcb->inode_item.st_size == 0 || fcb->inode_item.st_size > 0xffff) {
65  goto end;
66  }
67 
69  if (!data) {
70  ERR("out of memory\n");
72  goto end;
73  }
74 
75  TRACE("data = %p, size = %I64x\n", data, fcb->inode_item.st_size);
77 
78  if (!NT_SUCCESS(Status)) {
79  ERR("read_file returned %08lx\n", Status);
81  goto end;
82  }
83 
85  if (!NT_SUCCESS(Status)) {
86  ERR("utf8_to_utf16 1 returned %08lx\n", Status);
88  goto end;
89  }
90 
91  subnamelen = (uint16_t)stringlen;
92  printnamelen = (uint16_t)stringlen;
93 
94  reqlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + subnamelen + printnamelen;
95 
96  if (buflen >= offsetof(REPARSE_DATA_BUFFER, ReparseDataLength))
98 
100  rdb->ReparseDataLength = (USHORT)(reqlen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
101 
102  if (buflen >= offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset))
103  rdb->Reserved = 0;
104 
105  if (buflen < reqlen) {
106  ExFreePool(data);
108  *retlen = min(buflen, offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset));
109  goto end;
110  }
111 
112  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
113  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = subnamelen;
114  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = subnamelen;
115  rdb->SymbolicLinkReparseBuffer.PrintNameLength = printnamelen;
117 
118  Status = utf8_to_utf16(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
120 
121  if (!NT_SUCCESS(Status)) {
122  ERR("utf8_to_utf16 2 returned %08lx\n", Status);
123  ExFreePool(data);
124  goto end;
125  }
126 
127  for (i = 0; i < stringlen / sizeof(WCHAR); i++) {
128  if (rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] == '/')
129  rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] = '\\';
130  }
131 
132  RtlCopyMemory(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)],
133  &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
134  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
135 
136  *retlen = reqlen;
137 
138  ExFreePool(data);
139  }
140 
142  } else if (fcb->atts & FILE_ATTRIBUTE_REPARSE_POINT) {
143  if (fcb->type == BTRFS_TYPE_FILE) {
144  ULONG len;
145 
146  Status = read_file(fcb, buffer, 0, buflen, &len, NULL);
147 
148  if (!NT_SUCCESS(Status)) {
149  ERR("read_file returned %08lx\n", Status);
150  }
151 
152  *retlen = len;
153  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
154  if (!fcb->reparse_xattr.Buffer || fcb->reparse_xattr.Length < sizeof(ULONG)) {
156  goto end;
157  }
158 
159  if (buflen > 0) {
160  *retlen = min(buflen, fcb->reparse_xattr.Length);
162  } else
163  *retlen = 0;
164 
166  } else
168  } else {
170  }
171 
172 end:
173  ExReleaseResourceLite(fcb->Header.Resource);
174  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
175 
176  return Status;
177 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp) __attribute__((nonnull(1
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
GLuint buffer
Definition: glext.h:5915
struct _REPARSE_DATA_BUFFER::@303::@307 GenericReparseBuffer
#define uint16_t
Definition: nsiface.idl:60
if(dx==0 &&dy==0)
Definition: linetemp.h:174
struct _REPARSE_DATA_BUFFER::@303::@305 SymbolicLinkReparseBuffer
#define ALLOC_TAG
Definition: btrfs_drv.h:87
WCHAR PathBuffer[1]
Definition: shellext.h:176
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
UCHAR DataBuffer[1]
Definition: shellext.h:188
#define offsetof(TYPE, MEMBER)
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
uint8_t type
Definition: btrfs_drv.h:291
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
uint64_t st_size
Definition: btrfs.h:289
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
wstring utf8_to_utf16(const string_view &utf8)
Definition: main.cpp:734
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
USHORT ReparseDataLength
Definition: shellext.h:166
GLint const GLchar GLint stringlen
Definition: glext.h:7232
#define STATUS_NOT_A_REPARSE_POINT
Definition: ntstatus.h:753
GLenum GLsizei len
Definition: glext.h:6722
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
BYTE uint8_t
Definition: msvideo1.c:66
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define ERR(fmt,...)
Definition: debug.h:110
ULONG atts
Definition: btrfs_drv.h:297
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
#define IO_REPARSE_TAG_LX_SYMLINK
Definition: btrfs_drv.h:118
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
uint32_t buflen
Definition: read.c:49
USHORT SubstituteNameOffset
Definition: shellext.h:171
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
bool lxss
Definition: btrfs_drv.h:391
#define uint32_t
Definition: nsiface.idl:61
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91

Referenced by fsctl_request().

◆ set_reparse_point()

NTSTATUS set_reparse_point ( PIRP  Irp)

Definition at line 409 of file reparse.c.

409  {
412  void* buffer = Irp->AssociatedIrp.SystemBuffer;
414  DWORD buflen = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
416  fcb* fcb;
417  ccb* ccb;
418  file_ref* fileref;
420 
421  TRACE("(%p)\n", Irp);
422 
424 
425  if (!FileObject) {
426  ERR("FileObject was NULL\n");
428  }
429 
430  // IFSTest insists on this, for some reason...
431  if (Irp->UserBuffer)
433 
434  fcb = FileObject->FsContext;
435  ccb = FileObject->FsContext2;
436 
437  if (!ccb) {
438  ERR("ccb was NULL\n");
440  }
441 
442  if (Irp->RequestorMode == UserMode && !(ccb->access & (FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA))) {
443  WARN("insufficient privileges\n");
444  return STATUS_ACCESS_DENIED;
445  }
446 
447  fileref = ccb->fileref;
448 
449  if (!fileref) {
450  ERR("fileref was NULL\n");
452  }
453 
454  if (fcb->ads) {
455  fileref = fileref->parent;
456  fcb = fileref->fcb;
457  }
458 
459  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true);
460  ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
461 
462  Status = set_reparse_point2(fcb, rdb, buflen, ccb, fileref, Irp, &rollback);
463  if (!NT_SUCCESS(Status)) {
464  ERR("set_reparse_point2 returned %08lx\n", Status);
465  goto end;
466  }
467 
469 
470 end:
471  if (NT_SUCCESS(Status))
473  else
475 
476  ExReleaseResourceLite(fcb->Header.Resource);
477  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
478 
479  return Status;
480 }
struct _file_ref * parent
Definition: btrfs_drv.h:352
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS set_reparse_point2(fcb *fcb, REPARSE_DATA_BUFFER *rdb, ULONG buflen, ccb *ccb, file_ref *fileref, PIRP Irp, LIST_ENTRY *rollback)
Definition: reparse.c:307
GLuint buffer
Definition: glext.h:5915
#define FILE_NOTIFY_CHANGE_LAST_WRITE
ACCESS_MASK access
Definition: btrfs_drv.h:382
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1636
_In_ PIRP Irp
Definition: csq.h:116
#define FILE_ACTION_MODIFIED
#define FILE_WRITE_DATA
Definition: nt_native.h:631
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
struct _fcb fcb
Definition: btrfs_drv.h:1355
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1998
GLuint GLuint end
Definition: gl.h:1545
fcb * fcb
Definition: btrfs_drv.h:342
Definition: typedefs.h:119
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define ERR(fmt,...)
Definition: debug.h:110
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
bool ads
Definition: btrfs_drv.h:330
uint32_t buflen
Definition: read.c:49
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:383
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
struct _device_extension * Vcb
Definition: btrfs_drv.h:287

Referenced by fsctl_request().

◆ set_reparse_point2()

NTSTATUS set_reparse_point2 ( fcb fcb,
REPARSE_DATA_BUFFER rdb,
ULONG  buflen,
ccb ccb,
file_ref fileref,
PIRP  Irp,
LIST_ENTRY rollback 
)

Definition at line 307 of file reparse.c.

307  {
309  ULONG tag;
310 
311  if (fcb->type == BTRFS_TYPE_SYMLINK) {
312  WARN("tried to set a reparse point on an existing symlink\n");
314  }
315 
316  // FIXME - fail if we already have the attribute FILE_ATTRIBUTE_REPARSE_POINT
317 
318  // FIXME - die if not file or directory
319 
321  TRACE("directory not empty\n");
323  }
324 
325  if (buflen < sizeof(ULONG)) {
326  WARN("buffer was not long enough to hold tag\n");
328  }
329 
331  if (!NT_SUCCESS(Status)) {
332  ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status);
333  return Status;
334  }
335 
336  tag = *(ULONG*)rdb;
337 
339  return STATUS_NOT_A_DIRECTORY;
340 
341  if (fcb->type == BTRFS_TYPE_FILE &&
343  Status = set_symlink(Irp, fileref, fcb, ccb, rdb, buflen, rollback);
345  } else {
347  BTRFS_TIME now;
348 
349  if (fcb->type == BTRFS_TYPE_DIRECTORY || fcb->type == BTRFS_TYPE_CHARDEV || fcb->type == BTRFS_TYPE_BLOCKDEV) { // store as xattr
351 
353  if (!buf.Buffer) {
354  ERR("out of memory\n");
356  }
357  buf.Length = buf.MaximumLength = (uint16_t)buflen;
358 
359  if (fcb->reparse_xattr.Buffer)
361 
362  fcb->reparse_xattr = buf;
363  RtlCopyMemory(buf.Buffer, rdb, buflen);
364 
365  fcb->reparse_xattr_changed = true;
366 
368  } else { // otherwise, store as file data
370  if (!NT_SUCCESS(Status)) {
371  ERR("truncate_file returned %08lx\n", Status);
372  return Status;
373  }
374 
375  offset.QuadPart = 0;
376 
377  Status = write_file2(fcb->Vcb, Irp, offset, rdb, &buflen, false, true, true, false, false, rollback);
378  if (!NT_SUCCESS(Status)) {
379  ERR("write_file2 returned %08lx\n", Status);
380  return Status;
381  }
382  }
383 
386 
387  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
389 
390  if (!ccb || !ccb->user_set_change_time)
392 
393  if (!ccb || !ccb->user_set_write_time)
395 
397  fcb->atts_changed = true;
398 
399  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
400  fcb->subvol->root_item.ctime = now;
401 
402  fcb->inode_item_changed = true;
404  }
405 
406  return STATUS_SUCCESS;
407 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
static NTSTATUS set_symlink(PIRP Irp, file_ref *fileref, fcb *fcb, ccb *ccb, REPARSE_DATA_BUFFER *rdb, ULONG buflen, LIST_ENTRY *rollback)
Definition: reparse.c:179
bool reparse_xattr_changed
Definition: btrfs_drv.h:324
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
Definition: ecma_167.h:138
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:97
__u16 time
Definition: mkdosfs.c:366
#define uint16_t
Definition: nsiface.idl:60
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
bool atts_changed
Definition: btrfs_drv.h:322
struct _REPARSE_DATA_BUFFER::@303::@305 SymbolicLinkReparseBuffer
BTRFS_TIME st_ctime
Definition: btrfs.h:302
bool user_set_write_time
Definition: btrfs_drv.h:389
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7231
#define ALLOC_TAG
Definition: btrfs_drv.h:87
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
_In_ PIRP Irp
Definition: csq.h:116
uint64_t sequence
Definition: btrfs.h:299
time_t now
Definition: finger.c:65
NTSTATUS NTSTATUS NTSTATUS truncate_file(fcb *fcb, uint64_t end, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
uint8_t type
Definition: btrfs_drv.h:291
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
BTRFS_TIME st_mtime
Definition: btrfs.h:303
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
uint64_t st_size
Definition: btrfs.h:289
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLintptr offset
Definition: glext.h:5920
bool user_set_change_time
Definition: btrfs_drv.h:390
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define ERR(fmt,...)
Definition: debug.h:110
ULONG atts
Definition: btrfs_drv.h:297
NTSTATUS NTSTATUS write_file2(device_extension *Vcb, PIRP Irp, LARGE_INTEGER offset, void *buf, ULONG *length, bool paging_io, bool no_cache, bool wait, bool deferred_write, bool write_irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
uint64_t transid
Definition: btrfs.h:288
#define IO_REPARSE_TAG_LX_SYMLINK
Definition: btrfs_drv.h:118
struct _root * subvol
Definition: btrfs_drv.h:288
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:981
uint32_t buflen
Definition: read.c:49
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
bool inode_item_changed
Definition: btrfs_drv.h:306
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
char * tag
Definition: main.c:59

Referenced by file_create(), and set_reparse_point().

◆ set_symlink()

static NTSTATUS set_symlink ( PIRP  Irp,
file_ref fileref,
fcb fcb,
ccb ccb,
REPARSE_DATA_BUFFER rdb,
ULONG  buflen,
LIST_ENTRY rollback 
)
static

Definition at line 179 of file reparse.c.

179  {
181  ULONG tlength;
183  bool target_alloc = false;
185  BTRFS_TIME now;
186 
187  if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
188  UNICODE_STRING subname;
189  ULONG minlen, len;
190 
191  minlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + sizeof(WCHAR);
192  if (buflen < minlen) {
193  WARN("buffer was less than minimum length (%lu < %lu)\n", buflen, minlen);
195  }
196 
197  if (rdb->SymbolicLinkReparseBuffer.SubstituteNameLength < sizeof(WCHAR)) {
198  WARN("rdb->SymbolicLinkReparseBuffer.SubstituteNameLength was too short\n");
200  }
201 
202  subname.Buffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)];
203  subname.MaximumLength = subname.Length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength;
204 
205  TRACE("substitute name = %.*S\n", (int)(subname.Length / sizeof(WCHAR)), subname.Buffer);
206 
207  Status = utf16_to_utf8(NULL, 0, &len, subname.Buffer, subname.Length);
208  if (!NT_SUCCESS(Status)) {
209  ERR("utf16_to_utf8 1 failed with error %08lx\n", Status);
210  return Status;
211  }
212 
213  target.MaximumLength = target.Length = (USHORT)len;
214  target.Buffer = ExAllocatePoolWithTag(PagedPool, target.MaximumLength, ALLOC_TAG);
215  if (!target.Buffer) {
216  ERR("out of memory\n");
218  }
219 
220  target_alloc = true;
221 
222  Status = utf16_to_utf8(target.Buffer, target.Length, &len, subname.Buffer, subname.Length);
223  if (!NT_SUCCESS(Status)) {
224  ERR("utf16_to_utf8 2 failed with error %08lx\n", Status);
225  ExFreePool(target.Buffer);
226  return Status;
227  }
228 
229  for (USHORT i = 0; i < target.Length; i++) {
230  if (target.Buffer[i] == '\\')
231  target.Buffer[i] = '/';
232  }
233  } else if (rdb->ReparseTag == IO_REPARSE_TAG_LX_SYMLINK) {
235 
236  if (buflen < offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + rdb->ReparseDataLength) {
237  WARN("buffer was less than expected length (%lu < %lu)\n", buflen,
238  (unsigned long)(offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + rdb->ReparseDataLength));
240  }
241 
243 
245  WARN("buffer was less than minimum length (%u < %lu)\n", rdb->ReparseDataLength,
246  (unsigned long)(offsetof(REPARSE_DATA_BUFFER_LX_SYMLINK, name)));
248  }
249 
250  target.Buffer = buf->name;
252  } else {
253  ERR("unexpected reparse tag %08lx\n", rdb->ReparseTag);
254  return STATUS_INTERNAL_ERROR;
255  }
256 
260  fcb->inode_item.generation = fcb->Vcb->superblock.generation; // so we don't confuse btrfs send on Linux
261 
262  if (fileref && fileref->dc)
263  fileref->dc->type = fcb->type;
264 
266  if (!NT_SUCCESS(Status)) {
267  ERR("truncate_file returned %08lx\n", Status);
268 
269  if (target_alloc)
270  ExFreePool(target.Buffer);
271 
272  return Status;
273  }
274 
275  offset.QuadPart = 0;
276  tlength = target.Length;
277  Status = write_file2(fcb->Vcb, Irp, offset, target.Buffer, &tlength, false, true,
278  true, false, false, rollback);
279 
280  if (target_alloc)
281  ExFreePool(target.Buffer);
282 
285 
286  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
288 
289  if (!ccb || !ccb->user_set_change_time)
291 
292  if (!ccb || !ccb->user_set_write_time)
294 
295  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
296  fcb->subvol->root_item.ctime = now;
297 
298  fcb->inode_item_changed = true;
300 
301  if (fileref)
302  mark_fileref_dirty(fileref);
303 
304  return Status;
305 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
struct _REPARSE_DATA_BUFFER::@303::@307 GenericReparseBuffer
__u16 time
Definition: mkdosfs.c:366
if(dx==0 &&dy==0)
Definition: linetemp.h:174
struct _REPARSE_DATA_BUFFER::@303::@305 SymbolicLinkReparseBuffer
BTRFS_TIME st_ctime
Definition: btrfs.h:302
bool user_set_write_time
Definition: btrfs_drv.h:389
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:87
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
WCHAR PathBuffer[1]
Definition: shellext.h:176
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1686
_In_ PIRP Irp
Definition: csq.h:116
uint64_t sequence
Definition: btrfs.h:299
time_t now
Definition: finger.c:65
NTSTATUS NTSTATUS NTSTATUS truncate_file(fcb *fcb, uint64_t end, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
UCHAR DataBuffer[1]
Definition: shellext.h:188
#define offsetof(TYPE, MEMBER)
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1664
#define __S_IFMT
Definition: btrfs_drv.h:1743
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:670
uint8_t type
Definition: btrfs_drv.h:291
BTRFS_TIME st_mtime
Definition: btrfs.h:303
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLintptr offset
Definition: glext.h:5920
bool user_set_change_time
Definition: btrfs_drv.h:390
char * name
Definition: compiler.c:66
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
dir_child * dc
Definition: btrfs_drv.h:353
USHORT ReparseDataLength
Definition: shellext.h:166
GLenum GLsizei len
Definition: glext.h:6722
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
uint64_t generation
Definition: btrfs.h:287
#define ERR(fmt,...)
Definition: debug.h:110
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS NTSTATUS write_file2(device_extension *Vcb, PIRP Irp, LARGE_INTEGER offset, void *buf, ULONG *length, bool paging_io, bool no_cache, bool wait, bool deferred_write, bool write_irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
unsigned short USHORT
Definition: pedump.c:61
uint8_t type
Definition: btrfs_drv.h:253
uint64_t transid
Definition: btrfs.h:288
#define IO_REPARSE_TAG_LX_SYMLINK
Definition: btrfs_drv.h:118
struct _root * subvol
Definition: btrfs_drv.h:288
#define NULL
Definition: types.h:112
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1355
Definition: name.c:38
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:981
uint32_t buflen
Definition: read.c:49
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
#define __S_IFLNK
Definition: btrfs_drv.h:1749
bool inode_item_changed
Definition: btrfs_drv.h:306
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
uint32_t st_mode
Definition: btrfs.h:295

Referenced by set_reparse_point2().

Variable Documentation

◆ fFsRtlValidateReparsePointBuffer

tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer

Definition at line 97 of file btrfs.c.

Referenced by _Function_class_(), and set_reparse_point2().