ReactOS  0.4.13-dev-257-gfabbd7c
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  USHORT subnamelen, printnamelen, i;
23  DWORD reqlen;
25  fcb* fcb = FileObject->FsContext;
26  ccb* ccb = FileObject->FsContext2;
28 
29  TRACE("(%p, %p, %p, %x, %p)\n", DeviceObject, FileObject, buffer, buflen, retlen);
30 
31  if (!ccb)
33 
34  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, TRUE);
36 
37  if (fcb->type == BTRFS_TYPE_SYMLINK) {
38  if (ccb->lxss) {
39  reqlen = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + sizeof(UINT32);
40 
41  if (buflen < reqlen) {
43  goto end;
44  }
45 
47  rdb->ReparseDataLength = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + sizeof(UINT32);
48  rdb->Reserved = 0;
49 
50  *((UINT32*)rdb->GenericReparseBuffer.DataBuffer) = 1;
51 
52  *retlen = reqlen;
53  } else {
54  char* data;
55 
56  if (fcb->inode_item.st_size == 0 || fcb->inode_item.st_size > 0xffff) {
58  goto end;
59  }
60 
62  if (!data) {
63  ERR("out of memory\n");
65  goto end;
66  }
67 
68  TRACE("data = %p, size = %x\n", data, fcb->inode_item.st_size);
70 
71  if (!NT_SUCCESS(Status)) {
72  ERR("read_file returned %08x\n", Status);
74  goto end;
75  }
76 
78  if (!NT_SUCCESS(Status)) {
79  ERR("RtlUTF8ToUnicodeN 1 returned %08x\n", Status);
81  goto end;
82  }
83 
84  subnamelen = (UINT16)stringlen;
85  printnamelen = (UINT16)stringlen;
86 
87  reqlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + subnamelen + printnamelen;
88 
89  if (buflen >= offsetof(REPARSE_DATA_BUFFER, ReparseDataLength))
91 
93  rdb->ReparseDataLength = (USHORT)(reqlen - offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer));
94 
95  if (buflen >= offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset))
96  rdb->Reserved = 0;
97 
98  if (buflen < reqlen) {
101  *retlen = min(buflen, offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset));
102  goto end;
103  }
104 
105  rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
106  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength = subnamelen;
107  rdb->SymbolicLinkReparseBuffer.PrintNameOffset = subnamelen;
108  rdb->SymbolicLinkReparseBuffer.PrintNameLength = printnamelen;
110 
111  Status = RtlUTF8ToUnicodeN(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
113 
114  if (!NT_SUCCESS(Status)) {
115  ERR("RtlUTF8ToUnicodeN 2 returned %08x\n", Status);
116  ExFreePool(data);
117  goto end;
118  }
119 
120  for (i = 0; i < stringlen / sizeof(WCHAR); i++) {
121  if (rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] == '/')
122  rdb->SymbolicLinkReparseBuffer.PathBuffer[(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)) + i] = '\\';
123  }
124 
125  RtlCopyMemory(&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)],
126  &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
127  rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
128 
129  *retlen = reqlen;
130 
131  ExFreePool(data);
132  }
133 
135  } else if (fcb->atts & FILE_ATTRIBUTE_REPARSE_POINT) {
136  if (fcb->type == BTRFS_TYPE_FILE) {
137  ULONG len;
138 
139  Status = read_file(fcb, buffer, 0, buflen, &len, NULL);
140 
141  if (!NT_SUCCESS(Status)) {
142  ERR("read_file returned %08x\n", Status);
143  }
144 
145  *retlen = len;
146  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
147  if (!fcb->reparse_xattr.Buffer || fcb->reparse_xattr.Length < sizeof(ULONG)) {
149  goto end;
150  }
151 
152  if (buflen > 0) {
153  *retlen = min(buflen, fcb->reparse_xattr.Length);
155  } else
156  *retlen = 0;
157 
159  } else
161  } else {
163  }
164 
165 end:
166  ExReleaseResourceLite(fcb->Header.Resource);
167  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
168 
169  return Status;
170 }
171 
174  ULONG minlen;
175  ULONG tlength;
176  UNICODE_STRING subname;
179  BTRFS_TIME now;
180  USHORT i;
181 
182  if (write) {
183  minlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + sizeof(WCHAR);
184  if (buflen < minlen) {
185  WARN("buffer was less than minimum length (%u < %u)\n", buflen, minlen);
187  }
188 
189  if (rdb->SymbolicLinkReparseBuffer.SubstituteNameLength < sizeof(WCHAR)) {
190  WARN("rdb->SymbolicLinkReparseBuffer.SubstituteNameLength was too short\n");
192  }
193 
194  subname.Buffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)];
195  subname.MaximumLength = subname.Length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength;
196 
197  TRACE("substitute name = %.*S\n", subname.Length / sizeof(WCHAR), subname.Buffer);
198  }
199 
202  fcb->inode_item.generation = fcb->Vcb->superblock.generation; // so we don't confuse btrfs send on Linux
203 
204  if (fileref && fileref->dc)
205  fileref->dc->type = fcb->type;
206 
207  if (write) {
209  if (!NT_SUCCESS(Status)) {
210  ERR("truncate_file returned %08x\n", Status);
211  return Status;
212  }
213 
214  Status = RtlUnicodeToUTF8N(NULL, 0, (PULONG)&target.Length, subname.Buffer, subname.Length);
215  if (!NT_SUCCESS(Status)) {
216  ERR("RtlUnicodeToUTF8N 1 failed with error %08x\n", Status);
217  return Status;
218  }
219 
220  target.MaximumLength = target.Length;
221  target.Buffer = ExAllocatePoolWithTag(PagedPool, target.MaximumLength, ALLOC_TAG);
222  if (!target.Buffer) {
223  ERR("out of memory\n");
225  }
226 
227  Status = RtlUnicodeToUTF8N(target.Buffer, target.Length, (PULONG)&target.Length, subname.Buffer, subname.Length);
228  if (!NT_SUCCESS(Status)) {
229  ERR("RtlUnicodeToUTF8N 2 failed with error %08x\n", Status);
230  ExFreePool(target.Buffer);
231  return Status;
232  }
233 
234  for (i = 0; i < target.MaximumLength; i++) {
235  if (target.Buffer[i] == '\\')
236  target.Buffer[i] = '/';
237  }
238 
239  offset.QuadPart = 0;
240  tlength = target.Length;
241  Status = write_file2(fcb->Vcb, Irp, offset, target.Buffer, &tlength, FALSE, TRUE,
242  TRUE, FALSE, FALSE, rollback);
243  ExFreePool(target.Buffer);
244  } else
246 
249 
250  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
252 
253  if (!ccb || !ccb->user_set_change_time)
255 
256  if (!ccb || !ccb->user_set_write_time)
258 
259  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
260  fcb->subvol->root_item.ctime = now;
261 
264 
265  if (fileref)
266  mark_fileref_dirty(fileref);
267 
268  return Status;
269 }
270 
273  ULONG tag;
274 
275  if (fcb->type == BTRFS_TYPE_SYMLINK) {
276  WARN("tried to set a reparse point on an existing symlink\n");
278  }
279 
280  // FIXME - fail if we already have the attribute FILE_ATTRIBUTE_REPARSE_POINT
281 
282  // FIXME - die if not file or directory
283 
284  if (buflen < sizeof(ULONG)) {
285  WARN("buffer was not long enough to hold tag\n");
287  }
288 
290  if (!NT_SUCCESS(Status)) {
291  ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status);
292  return Status;
293  }
294 
295  RtlCopyMemory(&tag, rdb, sizeof(ULONG));
296 
297  if (fcb->type == BTRFS_TYPE_FILE &&
301  } else {
303  BTRFS_TIME now;
304 
305  if (fcb->type == BTRFS_TYPE_DIRECTORY || fcb->type == BTRFS_TYPE_CHARDEV || fcb->type == BTRFS_TYPE_BLOCKDEV) { // store as xattr
307 
309  if (!buf.Buffer) {
310  ERR("out of memory\n");
312  }
313  buf.Length = buf.MaximumLength = (UINT16)buflen;
314 
315  if (fcb->reparse_xattr.Buffer)
317 
318  fcb->reparse_xattr = buf;
319  RtlCopyMemory(buf.Buffer, rdb, buflen);
320 
322 
324  } else { // otherwise, store as file data
326  if (!NT_SUCCESS(Status)) {
327  ERR("truncate_file returned %08x\n", Status);
328  return Status;
329  }
330 
331  offset.QuadPart = 0;
332 
334  if (!NT_SUCCESS(Status)) {
335  ERR("write_file2 returned %08x\n", Status);
336  return Status;
337  }
338  }
339 
342 
343  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
345 
346  if (!ccb || !ccb->user_set_change_time)
348 
349  if (!ccb || !ccb->user_set_write_time)
351 
353  fcb->atts_changed = TRUE;
354 
355  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
356  fcb->subvol->root_item.ctime = now;
357 
360  }
361 
362  return STATUS_SUCCESS;
363 }
364 
368  void* buffer = Irp->AssociatedIrp.SystemBuffer;
370  DWORD buflen = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
372  fcb* fcb;
373  ccb* ccb;
374  file_ref* fileref;
376 
377  TRACE("(%p, %p)\n", DeviceObject, Irp);
378 
380 
381  if (!FileObject) {
382  ERR("FileObject was NULL\n");
384  }
385 
386  // IFSTest insists on this, for some reason...
387  if (Irp->UserBuffer)
389 
390  fcb = FileObject->FsContext;
391  ccb = FileObject->FsContext2;
392 
393  if (!ccb) {
394  ERR("ccb was NULL\n");
396  }
397 
398  if (Irp->RequestorMode == UserMode && !(ccb->access & (FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA))) {
399  WARN("insufficient privileges\n");
400  return STATUS_ACCESS_DENIED;
401  }
402 
403  fileref = ccb->fileref;
404 
405  if (!fileref) {
406  ERR("fileref was NULL\n");
408  }
409 
410  if (fcb->ads) {
411  fileref = fileref->parent;
412  fcb = fileref->fcb;
413  }
414 
415  TRACE("%S\n", file_desc(FileObject));
416 
417  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, TRUE);
419 
420  Status = set_reparse_point2(fcb, rdb, buflen, ccb, fileref, Irp, &rollback);
421  if (!NT_SUCCESS(Status)) {
422  ERR("set_reparse_point2 returned %08x\n", Status);
423  goto end;
424  }
425 
427 
428 end:
429  if (NT_SUCCESS(Status))
431  else
433 
434  ExReleaseResourceLite(fcb->Header.Resource);
435  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
436 
437  return Status;
438 }
439 
443  REPARSE_DATA_BUFFER* rdb = Irp->AssociatedIrp.SystemBuffer;
444  DWORD buflen = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
446  fcb* fcb;
447  ccb* ccb;
448  file_ref* fileref;
450 
451  TRACE("(%p, %p)\n", DeviceObject, Irp);
452 
454 
455  if (!FileObject) {
456  ERR("FileObject was NULL\n");
458  }
459 
460  fcb = FileObject->FsContext;
461 
462  if (!fcb) {
463  ERR("fcb was NULL\n");
465  }
466 
467  ccb = FileObject->FsContext2;
468 
469  if (!ccb) {
470  ERR("ccb was NULL\n");
472  }
473 
474  if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_WRITE_ATTRIBUTES)) {
475  WARN("insufficient privileges\n");
476  return STATUS_ACCESS_DENIED;
477  }
478 
479  fileref = ccb->fileref;
480 
481  if (!fileref) {
482  ERR("fileref was NULL\n");
484  }
485 
486  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, TRUE);
488 
489  TRACE("%S\n", file_desc(FileObject));
490 
491  if (buflen < offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)) {
492  ERR("buffer was too short\n");
494  goto end;
495  }
496 
497  if (rdb->ReparseDataLength > 0) {
498  WARN("rdb->ReparseDataLength was not zero\n");
500  goto end;
501  }
502 
503  if (fcb->ads) {
504  WARN("tried to delete reparse point on ADS\n");
506  goto end;
507  }
508 
509  if (fcb->type == BTRFS_TYPE_SYMLINK) {
511  BTRFS_TIME now;
512 
513  if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
514  WARN("reparse tag was not IO_REPARSE_TAG_SYMLINK\n");
516  goto end;
517  }
518 
521 
522  fileref->fcb->type = BTRFS_TYPE_FILE;
523  fileref->fcb->inode_item.st_mode &= ~__S_IFLNK;
524  fileref->fcb->inode_item.st_mode |= __S_IFREG;
525  fileref->fcb->inode_item.generation = fileref->fcb->Vcb->superblock.generation; // so we don't confuse btrfs send on Linux
526  fileref->fcb->inode_item.transid = fileref->fcb->Vcb->superblock.generation;
527  fileref->fcb->inode_item.sequence++;
528 
530  fileref->fcb->inode_item.st_ctime = now;
531 
532  if (!ccb->user_set_write_time)
533  fileref->fcb->inode_item.st_mtime = now;
534 
535  fileref->fcb->atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
536 
537  if (fileref->dc)
538  fileref->dc->type = fileref->fcb->type;
539 
540  mark_fileref_dirty(fileref);
541 
542  fileref->fcb->inode_item_changed = TRUE;
543  mark_fcb_dirty(fileref->fcb);
544 
545  fileref->fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
546  fileref->fcb->subvol->root_item.ctime = now;
547  } else if (fcb->type == BTRFS_TYPE_FILE) {
549  BTRFS_TIME now;
550 
551  // FIXME - do we need to check that the reparse tags match?
552 
554  if (!NT_SUCCESS(Status)) {
555  ERR("truncate_file returned %08x\n", Status);
556  goto end;
557  }
558 
560  fcb->atts_changed = TRUE;
561 
564 
565  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
567 
570 
571  if (!ccb->user_set_write_time)
573 
576 
577  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
578  fcb->subvol->root_item.ctime = now;
579  } else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
581  BTRFS_TIME now;
582 
583  // FIXME - do we need to check that the reparse tags match?
584 
586  fcb->atts_changed = TRUE;
587 
588  if (fcb->reparse_xattr.Buffer) {
591  }
592 
594 
597 
598  fcb->inode_item.transid = fcb->Vcb->superblock.generation;
600 
603 
604  if (!ccb->user_set_write_time)
606 
609 
610  fcb->subvol->root_item.ctransid = fcb->Vcb->superblock.generation;
611  fcb->subvol->root_item.ctime = now;
612  } else {
613  ERR("unsupported file type %u\n", fcb->type);
615  goto end;
616  }
617 
619 
621 
622 end:
623  if (NT_SUCCESS(Status))
625  else
627 
628  ExReleaseResourceLite(fcb->Header.Resource);
629  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
630 
631  return Status;
632 }
BOOL reparse_xattr_changed
Definition: btrfs_drv.h:294
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
struct _file_ref * parent
Definition: btrfs_drv.h:326
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback)
Definition: treefuncs.c:1049
void clear_rollback(LIST_ENTRY *rollback)
Definition: treefuncs.c:1028
struct _REPARSE_DATA_BUFFER::@300::@302 SymbolicLinkReparseBuffer
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS delete_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: reparse.c:440
#define IO_REPARSE_TAG_LXSS_SYMLINK
Definition: btrfs_drv.h:112
USHORT MaximumLength
Definition: env_spec_w32.h:370
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:83
NTSTATUS write_file2(device_extension *Vcb, PIRP Irp, LARGE_INTEGER offset, void *buf, ULONG *length, BOOLEAN paging_io, BOOLEAN no_cache, BOOLEAN wait, BOOLEAN deferred_write, BOOLEAN write_irp, LIST_ENTRY *rollback)
Definition: write.c:4143
#define WARN(fmt,...)
Definition: debug.h:111
NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: reparse.c:365
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:271
GLintptr offset
Definition: glext.h:5920
Definition: ecma_167.h:138
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:275
NTSTATUS WINAPI RtlUTF8ToUnicodeN(PWSTR uni_dest, ULONG uni_bytes_max, PULONG uni_bytes_written, PCCH utf8_src, ULONG utf8_bytes)
Definition: reactos.cpp:21
GLuint buffer
Definition: glext.h:5915
#define FILE_NOTIFY_CHANGE_LAST_WRITE
GLuint GLuint end
Definition: gl.h:1545
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:357
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:82
BTRFS_TIME st_ctime
Definition: btrfs.h:279
UINT8 type
Definition: btrfs_drv.h:227
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
UINT32 st_mode
Definition: btrfs.h:273
UINT64 generation
Definition: btrfs.h:265
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, void *buffer, DWORD buflen, ULONG_PTR *retlen)
Definition: reparse.c:20
#define ALLOC_TAG
Definition: btrfs_drv.h:86
#define write
Definition: acwin.h:73
WCHAR PathBuffer[1]
Definition: shellext.h:152
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
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1490
unsigned int UINT32
unsigned int BOOL
Definition: ntddk_ex.h:94
time_t now
Definition: finger.c:65
#define FILE_ACTION_MODIFIED
NTKERNELAPI NTSTATUS NTAPI FsRtlValidateReparsePointBuffer(IN ULONG BufferLength, IN PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: fsrtl.c:173
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:81
UCHAR DataBuffer[1]
Definition: shellext.h:164
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1468
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
BTRFS_TIME st_mtime
Definition: btrfs.h:280
#define FILE_WRITE_DATA
Definition: nt_native.h:631
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:256
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
#define TRACE(s)
Definition: solgame.cpp:4
struct _fcb fcb
Definition: btrfs_drv.h:1334
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _REPARSE_DATA_BUFFER::@300::@304 GenericReparseBuffer
BOOL atts_changed
Definition: btrfs_drv.h:292
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:1954
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
NTSTATUS read_file(fcb *fcb, UINT8 *data, UINT64 start, UINT64 length, ULONG *pbr, PIRP Irp)
Definition: read.c:2737
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOL inode_item_changed
Definition: btrfs_drv.h:280
BOOL ads
Definition: btrfs_drv.h:300
dir_child * dc
Definition: btrfs_drv.h:328
USHORT ReparseDataLength
Definition: shellext.h:142
UINT32 buflen
Definition: read.c:47
GLint const GLchar GLint stringlen
Definition: glext.h:7232
#define STATUS_NOT_A_REPARSE_POINT
Definition: ntstatus.h:739
GLenum GLsizei len
Definition: glext.h:6722
fcb * fcb
Definition: btrfs_drv.h:316
Definition: typedefs.h:117
INODE_ITEM inode_item
Definition: btrfs_drv.h:265
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:169
_In_ fcb _In_ chunk _In_ UINT64 _In_ UINT64 _In_ BOOL _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1334
BOOL user_set_write_time
Definition: btrfs_drv.h:364
#define __S_IFREG
Definition: btrfs_drv.h:1708
Status
Definition: gdiplustypes.h:24
#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:2812
ULONG atts
Definition: btrfs_drv.h:270
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
UINT64 st_size
Definition: btrfs.h:267
unsigned short USHORT
Definition: pedump.c:61
UINT64 transid
Definition: btrfs.h:266
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
unsigned short UINT16
unsigned int * PULONG
Definition: retypes.h:1
struct _root * subvol
Definition: btrfs_drv.h:261
#define min(a, b)
Definition: monoChain.cc:55
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define BTRFS_TYPE_FILE
Definition: shellext.h:80
UINT8 type
Definition: btrfs_drv.h:264
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:977
USHORT SubstituteNameOffset
Definition: shellext.h:147
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
void send_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1387
#define __S_IFLNK
Definition: btrfs_drv.h:1710
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:358
NTSTATUS truncate_file(fcb *fcb, UINT64 end, PIRP Irp, LIST_ENTRY *rollback)
Definition: write.c:3244
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
static NTSTATUS set_symlink(PIRP Irp, file_ref *fileref, fcb *fcb, ccb *ccb, REPARSE_DATA_BUFFER *rdb, ULONG buflen, BOOL write, LIST_ENTRY *rollback)
Definition: reparse.c:172
return STATUS_SUCCESS
Definition: btrfs.c:2745
unsigned char UINT8
BOOL lxss
Definition: btrfs_drv.h:366
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6883
BOOL user_set_change_time
Definition: btrfs_drv.h:365
struct _device_extension * Vcb
Definition: btrfs_drv.h:260
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_Ret_z_ WCHAR * file_desc(_In_ PFILE_OBJECT FileObject)
Definition: btrfs.c:1336
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:86
UINT64 sequence
Definition: btrfs.h:276
char * tag
Definition: main.c:59
NTSTATUS NTAPI RtlUnicodeToUTF8N(PCHAR UTF8StringDestination, ULONG UTF8StringMaxByteCount, PULONG UTF8StringActualByteCount, PCWCH UnicodeStringSource, ULONG UnicodeStringByteCount)