28 USHORT subnamelen, printnamelen,
i;
48 if (buflen < reqlen) {
70 ERR(
"out of memory\n");
79 ERR(
"read_file returned %08lx\n",
Status);
86 ERR(
"utf8_to_utf16 1 returned %08lx\n",
Status);
105 if (buflen < reqlen) {
122 ERR(
"utf8_to_utf16 2 returned %08lx\n",
Status);
149 ERR(
"read_file returned %08lx\n",
Status);
183 bool target_alloc =
false;
192 if (buflen < minlen) {
193 WARN(
"buffer was less than minimum length (%lu < %lu)\n", buflen, minlen);
198 WARN(
"rdb->SymbolicLinkReparseBuffer.SubstituteNameLength was too short\n");
209 ERR(
"utf16_to_utf8 1 failed with error %08lx\n",
Status);
216 ERR(
"out of memory\n");
224 ERR(
"utf16_to_utf8 2 failed with error %08lx\n",
Status);
237 WARN(
"buffer was less than expected length (%lu < %lu)\n", buflen,
262 if (fileref && fileref->
dc)
267 ERR(
"truncate_file returned %08lx\n",
Status);
312 WARN(
"tried to set a reparse point on an existing symlink\n");
321 TRACE(
"directory not empty\n");
325 if (buflen <
sizeof(
ULONG)) {
326 WARN(
"buffer was not long enough to hold tag\n");
332 ERR(
"FsRtlValidateReparsePointBuffer returned %08lx\n",
Status);
354 ERR(
"out of memory\n");
371 ERR(
"truncate_file returned %08lx\n",
Status);
377 Status =
write_file2(
fcb->
Vcb,
Irp,
offset, rdb, &buflen,
false,
true,
true,
false,
false,
rollback);
379 ERR(
"write_file2 returned %08lx\n",
Status);
412 void*
buffer =
Irp->AssociatedIrp.SystemBuffer;
426 ERR(
"FileObject was NULL\n");
438 ERR(
"ccb was NULL\n");
443 WARN(
"insufficient privileges\n");
450 ERR(
"fileref was NULL\n");
455 fileref = fileref->
parent;
464 ERR(
"set_reparse_point2 returned %08lx\n",
Status);
498 ERR(
"FileObject was NULL\n");
505 ERR(
"fcb was NULL\n");
512 ERR(
"ccb was NULL\n");
517 WARN(
"insufficient privileges\n");
524 ERR(
"fileref was NULL\n");
532 ERR(
"buffer was too short\n");
538 WARN(
"rdb->ReparseDataLength was not zero\n");
544 WARN(
"tried to delete reparse point on ADS\n");
554 WARN(
"reparse tag was not IO_REPARSE_TAG_SYMLINK\n");
575 fileref->
fcb->
atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
585 fileref->
fcb->
subvol->root_item.ctransid =
fcb->
Vcb->superblock.generation;
595 ERR(
"truncate_file returned %08lx\n",
Status);
599 fcb->
atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
625 fcb->
atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp) __attribute__((nonnull(1
NTSTATUS(__stdcall * tFsRtlValidateReparsePointBuffer)(ULONG BufferLength, PREPARSE_DATA_BUFFER ReparseBuffer)
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
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
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback) __attribute__((nonnull(1
NTSTATUS NTSTATUS NTSTATUS truncate_file(fcb *fcb, uint64_t end, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define IO_REPARSE_TAG_LX_SYMLINK
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
#define NT_SUCCESS(StatCode)
static string utf16_to_utf8(const wstring_view &utf16)
wstring utf8_to_utf16(const string_view &utf8)
void mark_fcb_dirty(_In_ fcb *fcb)
void mark_fileref_dirty(_In_ file_ref *fileref)
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
_In_ PIO_STACK_LOCATION IrpSp
#define ExAllocatePoolWithTag(hernya, size, tag)
#define KeQuerySystemTime(t)
#define ExAcquireResourceExclusiveLite(res, wait)
#define InitializeListHead(ListHead)
#define ExAcquireResourceSharedLite(res, wait)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint const GLchar GLint stringlen
GLenum GLuint GLenum GLsizei const GLchar * buf
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
#define FILE_WRITE_ATTRIBUTES
#define FILE_ATTRIBUTE_REPARSE_POINT
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
#define STATUS_INTERNAL_ERROR
#define STATUS_INVALID_BUFFER_SIZE
#define STATUS_NOT_A_REPARSE_POINT
NTSTATUS get_reparse_point(PFILE_OBJECT FileObject, void *buffer, DWORD buflen, ULONG_PTR *retlen)
NTSTATUS set_reparse_point(PIRP Irp)
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 delete_reparse_point(PIRP Irp)
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
#define offsetof(TYPE, MEMBER)
#define SYMLINK_FLAG_RELATIVE
#define BTRFS_TYPE_DIRECTORY
#define BTRFS_TYPE_SYMLINK
#define STATUS_BUFFER_OVERFLOW
#define BTRFS_TYPE_CHARDEV
#define BTRFS_TYPE_BLOCKDEV
struct _IO_STACK_LOCATION::@1575::@1576 DeviceIoControl
union _IO_STACK_LOCATION::@1575 Parameters
USHORT SubstituteNameOffset
struct _REPARSE_DATA_BUFFER::@312::@314 SymbolicLinkReparseBuffer
struct _REPARSE_DATA_BUFFER::@312::@316 GenericReparseBuffer
bool user_set_change_time
struct _device_extension * Vcb
ANSI_STRING reparse_xattr
bool reparse_xattr_changed
FSRTL_ADVANCED_FCB_HEADER Header
struct _file_ref * parent
#define RtlCopyMemory(Destination, Source, Length)
#define STATUS_DIRECTORY_NOT_EMPTY
#define STATUS_NOT_A_DIRECTORY
#define STATUS_ACCESS_DENIED
#define STATUS_INVALID_PARAMETER
#define STATUS_INSUFFICIENT_RESOURCES
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
_Reserved_ PVOID Reserved
#define FILE_ACTION_MODIFIED
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define IO_REPARSE_TAG_SYMLINK
#define IO_REPARSE_TAG_MOUNT_POINT
#define FILE_NOTIFY_CHANGE_LAST_WRITE