ReactOS 0.4.15-dev-7918-g2a2556c
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
22typedef 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
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) {
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);
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
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
172end:
174 ExReleaseResourceLite(&fcb->Vcb->tree_lock);
175
176 return Status;
177}
178
181 ULONG tlength;
183 bool target_alloc = false;
186
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);
255 }
256
258 fcb->inode_item.st_mode &= ~__S_IFMT;
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
340
341 if (fcb->type == BTRFS_TYPE_FILE &&
343 Status = set_symlink(Irp, fileref, fcb, ccb, rdb, buflen, rollback);
345 } else {
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
361
363 RtlCopyMemory(buf.Buffer, rdb, buflen);
364
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");
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);
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
470end:
471 if (NT_SUCCESS(Status))
473 else
475
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");
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);
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) {
552
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
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) {
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
599 fcb->atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
600 fcb->atts_changed = true;
601
604
605 fcb->inode_item.transid = fcb->Vcb->superblock.generation;
607
610
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) {
622
623 // FIXME - do we need to check that the reparse tags match?
624
625 fcb->atts &= ~FILE_ATTRIBUTE_REPARSE_POINT;
626 fcb->atts_changed = true;
627
628 if (fcb->reparse_xattr.Buffer) {
631 }
632
634
637
638 fcb->inode_item.transid = fcb->Vcb->superblock.generation;
640
643
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
662end:
663 if (NT_SUCCESS(Status))
665 else
667
669 ExReleaseResourceLite(&fcb->Vcb->tree_lock);
670
671 return Status;
672}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
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)
Definition: btrfs_drv.h:1864
_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:1365
#define __S_IFREG
Definition: btrfs_drv.h:1757
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)
Definition: btrfs_drv.h:989
struct _fcb fcb
Definition: btrfs_drv.h:1364
#define ALLOC_TAG
Definition: btrfs_drv.h:87
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define __S_IFLNK
Definition: btrfs_drv.h:1759
NTSTATUS NTSTATUS NTSTATUS truncate_file(fcb *fcb, uint64_t end, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
#define IO_REPARSE_TAG_LX_SYMLINK
Definition: btrfs_drv.h:118
struct _ccb ccb
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static string utf16_to_utf8(const wstring_view &utf16)
Definition: main.cpp:670
wstring utf8_to_utf16(const string_view &utf8)
Definition: main.cpp:734
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1695
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1717
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1667
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
unsigned long DWORD
Definition: ntddk_ex.h:95
time_t now
Definition: finger.c:65
Status
Definition: gdiplustypes.h:25
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint const GLchar GLint stringlen
Definition: glext.h:7232
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLenum target
Definition: glext.h:7315
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
if(dx< 0)
Definition: linetemp.h:194
__u16 time
Definition: mkdosfs.c:8
#define min(a, b)
Definition: monoChain.cc:55
BYTE uint8_t
Definition: msvideo1.c:66
#define UserMode
Definition: asm.h:35
#define uint32_t
Definition: nsiface.idl:61
#define uint16_t
Definition: nsiface.idl:60
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_NOT_A_REPARSE_POINT
Definition: ntstatus.h:753
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS get_reparse_point(PFILE_OBJECT FileObject, void *buffer, DWORD buflen, ULONG_PTR *retlen)
Definition: reparse.c:27
NTSTATUS set_reparse_point(PIRP Irp)
Definition: reparse.c:409
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
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 delete_reparse_point(PIRP Irp)
Definition: reparse.c:482
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:98
#define offsetof(TYPE, MEMBER)
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
#define STATUS_SUCCESS
Definition: shellext.h:65
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
#define TRACE(s)
Definition: solgame.cpp:4
uint32_t st_mode
Definition: btrfs.h:295
BTRFS_TIME st_mtime
Definition: btrfs.h:303
uint64_t st_size
Definition: btrfs.h:289
uint64_t sequence
Definition: btrfs.h:299
BTRFS_TIME st_ctime
Definition: btrfs.h:302
uint64_t transid
Definition: btrfs.h:288
uint64_t generation
Definition: btrfs.h:287
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1564 Parameters
Definition: typedefs.h:120
WCHAR PathBuffer[1]
Definition: shellext.h:176
USHORT SubstituteNameOffset
Definition: shellext.h:171
struct _REPARSE_DATA_BUFFER::@318::@320 SymbolicLinkReparseBuffer
USHORT ReparseDataLength
Definition: shellext.h:166
struct _REPARSE_DATA_BUFFER::@318::@322 GenericReparseBuffer
UCHAR DataBuffer[1]
Definition: shellext.h:188
USHORT MaximumLength
Definition: env_spec_w32.h:370
bool user_set_change_time
Definition: btrfs_drv.h:390
bool lxss
Definition: btrfs_drv.h:391
ACCESS_MASK access
Definition: btrfs_drv.h:382
bool user_set_write_time
Definition: btrfs_drv.h:389
file_ref * fileref
Definition: btrfs_drv.h:383
bool ads
Definition: btrfs_drv.h:330
ULONG atts
Definition: btrfs_drv.h:297
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
uint8_t type
Definition: btrfs_drv.h:291
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
struct _root * subvol
Definition: btrfs_drv.h:288
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
bool reparse_xattr_changed
Definition: btrfs_drv.h:324
bool atts_changed
Definition: btrfs_drv.h:322
bool inode_item_changed
Definition: btrfs_drv.h:306
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
struct _file_ref * parent
Definition: btrfs_drv.h:352
fcb * fcb
Definition: btrfs_drv.h:342
dir_child * dc
Definition: btrfs_drv.h:353
char * name
Definition: compiler.c:66
uint8_t type
Definition: btrfs_drv.h:253
Definition: name.c:39
Definition: ecma_167.h:138
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define FILE_ACTION_MODIFIED
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7231
#define FILE_NOTIFY_CHANGE_LAST_WRITE
__wchar_t WCHAR
Definition: xmlstorage.h:180