ReactOS  0.4.15-dev-4874-g57c84dd
reparse.c
Go to the documentation of this file.
1 /* Copyright (c) Mark Harmstone 2016-17
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "btrfs_drv.h"
19 
21 
22 typedef struct {
24  char name[1];
26 
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 
99  if (buflen >= offsetof(REPARSE_DATA_BUFFER, Reserved))
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 }
178 
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 }
306 
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 
352  buf.Buffer = ExAllocatePoolWithTag(PagedPool, buflen, ALLOC_TAG);
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 }
408 
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 }
481 
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
struct _file_ref * parent
Definition: btrfs_drv.h:352
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
#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
NTSTATUS set_reparse_point(PIRP Irp)
Definition: reparse.c:409
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
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp) __attribute__((nonnull(1
NTSTATUS delete_reparse_point(PIRP Irp)
Definition: reparse.c:482
Definition: ecma_167.h:138
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
GLuint buffer
Definition: glext.h:5915
#define FILE_NOTIFY_CHANGE_LAST_WRITE
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:97
struct _REPARSE_DATA_BUFFER::@303::@307 GenericReparseBuffer
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:382
#define uint16_t
Definition: nsiface.idl:60
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
if(dx==0 &&dy==0)
Definition: linetemp.h:174
bool atts_changed
Definition: btrfs_drv.h:322
struct _REPARSE_DATA_BUFFER::@303::@305 SymbolicLinkReparseBuffer
BTRFS_TIME st_ctime
Definition: btrfs.h:302
NTSTATUS get_reparse_point(PFILE_OBJECT FileObject, void *buffer, DWORD buflen, ULONG_PTR *retlen)
Definition: reparse.c:27
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
bool user_set_write_time
Definition: btrfs_drv.h:389
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7231
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#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 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
#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 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
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#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
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
BTRFS_TIME st_mtime
Definition: btrfs.h:303
#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 STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
uint64_t st_size
Definition: btrfs.h:289
#define TRACE(s)
Definition: solgame.cpp:4
struct _fcb fcb
Definition: btrfs_drv.h:1355
__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
wstring utf8_to_utf16(const string_view &utf8)
Definition: main.cpp:734
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
char * name
Definition: compiler.c:66
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
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
dir_child * dc
Definition: btrfs_drv.h:353
USHORT ReparseDataLength
Definition: shellext.h:166
NTSTATUS(__stdcall * tFsRtlValidateReparsePointBuffer)(ULONG BufferLength, PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: btrfs_drv.h:1854
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
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
BYTE uint8_t
Definition: msvideo1.c:66
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#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
#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
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
#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
#define IO_REPARSE_TAG_LX_SYMLINK
Definition: btrfs_drv.h:118
struct _root * subvol
Definition: btrfs_drv.h:288
#define min(a, b)
Definition: monoChain.cc:55
#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
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
bool ads
Definition: btrfs_drv.h:330
Definition: name.c:38
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:981
USHORT SubstituteNameOffset
Definition: shellext.h:171
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define __S_IFLNK
Definition: btrfs_drv.h:1749
#define STATUS_SUCCESS
Definition: shellext.h:65
bool lxss
Definition: btrfs_drv.h:391
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:383
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define uint32_t
Definition: nsiface.idl:61
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
char * tag
Definition: main.c:59