ReactOS  0.4.13-dev-247-g0f29b3f
dirctrl.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 
24 };
25 
26 typedef struct {
30  enum DirEntryType dir_entry_type;
32 } dir_entry;
33 
35  ULONG tag;
36 
37  if (fcb->type == BTRFS_TYPE_SYMLINK)
39  else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
40  if (!fcb->reparse_xattr.Buffer || fcb->reparse_xattr.Length < sizeof(ULONG))
41  return 0;
42 
44  } else {
46  ULONG br;
47 
48  Status = read_file(fcb, (UINT8*)&tag, 0, sizeof(ULONG), &br, NULL);
49  if (!NT_SUCCESS(Status)) {
50  ERR("read_file returned %08x\n", Status);
51  return 0;
52  }
53  }
54 
55  return tag;
56 }
57 
59  fcb* fcb;
60  ULONG tag = 0;
62 
63  if (type == BTRFS_TYPE_SYMLINK)
65  else if (lxss) {
66  if (type == BTRFS_TYPE_SOCKET)
68  else if (type == BTRFS_TYPE_FIFO)
70  else if (type == BTRFS_TYPE_CHARDEV)
72  else if (type == BTRFS_TYPE_BLOCKDEV)
74  }
75 
77  return 0;
78 
80  return 0;
81 
82  Status = open_fcb(Vcb, subvol, inode, type, NULL, NULL, &fcb, PagedPool, Irp);
83  if (!NT_SUCCESS(Status)) {
84  ERR("open_fcb returned %08x\n", Status);
85  return 0;
86  }
87 
89 
91 
92  ExReleaseResourceLite(fcb->Header.Resource);
93 
94  free_fcb(fcb);
95 
96  return tag;
97 }
98 
100  UINT8* eadata;
101  UINT16 len;
102 
103  if (get_xattr(Vcb, subvol, inode, EA_EA, EA_EA_HASH, &eadata, &len, Irp)) {
104  ULONG offset;
106 
108 
109  if (!NT_SUCCESS(Status)) {
110  WARN("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset);
111  ExFreePool(eadata);
112  return 0;
113  } else {
114  FILE_FULL_EA_INFORMATION* eainfo;
115  ULONG ealen;
116 
117  ealen = 4;
118  eainfo = (FILE_FULL_EA_INFORMATION*)eadata;
119  do {
120  ealen += 5 + eainfo->EaNameLength + eainfo->EaValueLength;
121 
122  if (eainfo->NextEntryOffset == 0)
123  break;
124 
125  eainfo = (FILE_FULL_EA_INFORMATION*)(((UINT8*)eainfo) + eainfo->NextEntryOffset);
126  } while (TRUE);
127 
128  ExFreePool(eadata);
129 
130  return ealen;
131  }
132  } else
133  return 0;
134 }
135 
138  LONG needed;
139  UINT64 inode;
140  INODE_ITEM ii;
142  ULONG atts = 0, ealen = 0;
143  file_ref* fileref = ccb->fileref;
144 
146 
147  if (de->key.obj_type == TYPE_ROOT_ITEM) { // subvol
148  LIST_ENTRY* le;
149 
150  r = NULL;
151 
152  le = fcb->Vcb->roots.Flink;
153  while (le != &fcb->Vcb->roots) {
154  root* subvol = CONTAINING_RECORD(le, root, list_entry);
155 
156  if (subvol->id == de->key.obj_id) {
157  r = subvol;
158  break;
159  }
160 
161  le = le->Flink;
162  }
163 
164  if (r && r->parent != fcb->subvol->id)
165  r = NULL;
166 
168  } else {
169  inode = de->key.obj_id;
170  }
171 
172  if (IrpSp->Parameters.QueryDirectory.FileInformationClass != FileNamesInformation) { // FIXME - object ID and reparse point classes too?
173  switch (de->dir_entry_type) {
174  case DirEntryType_File:
175  {
176  if (!r) {
178 
179  ii = fcb->Vcb->dummy_fcb->inode_item;
180  atts = fcb->Vcb->dummy_fcb->atts;
181  ealen = fcb->Vcb->dummy_fcb->ealen;
182 
185  ii.st_atime = ii.st_mtime = ii.st_ctime = ii.otime;
186  } else {
187  BOOL found = FALSE;
188 
189  if (de->dc && de->dc->fileref && de->dc->fileref->fcb) {
190  ii = de->dc->fileref->fcb->inode_item;
191  atts = de->dc->fileref->fcb->atts;
192  ealen = de->dc->fileref->fcb->ealen;
193  found = TRUE;
194  }
195 
196  if (!found) {
197  KEY searchkey;
199 
200  searchkey.obj_id = inode;
201  searchkey.obj_type = TYPE_INODE_ITEM;
202  searchkey.offset = 0xffffffffffffffff;
203 
204  Status = find_item(fcb->Vcb, r, &tp, &searchkey, FALSE, Irp);
205  if (!NT_SUCCESS(Status)) {
206  ERR("error - find_item returned %08x\n", Status);
207  return Status;
208  }
209 
210  if (tp.item->key.obj_id != searchkey.obj_id || tp.item->key.obj_type != searchkey.obj_type) {
211  ERR("could not find inode item for inode %llx in root %llx\n", inode, r->id);
212  return STATUS_INTERNAL_ERROR;
213  }
214 
215  RtlZeroMemory(&ii, sizeof(INODE_ITEM));
216 
217  if (tp.item->size > 0)
218  RtlCopyMemory(&ii, tp.item->data, min(sizeof(INODE_ITEM), tp.item->size));
219 
220  if (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
221  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileDirectoryInformation ||
222  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileFullDirectoryInformation ||
223  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation ||
224  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdFullDirectoryInformation) {
225 
226  BOOL dotfile = de->name.Length > sizeof(WCHAR) && de->name.Buffer[0] == '.';
227 
228  atts = get_file_attributes(fcb->Vcb, r, inode, de->type, dotfile, FALSE, Irp);
229  }
230 
231  if (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
232  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileFullDirectoryInformation ||
233  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation ||
234  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdFullDirectoryInformation) {
235  ealen = get_ea_len(fcb->Vcb, r, inode, Irp);
236  }
237  }
238  }
239 
240  break;
241  }
242 
243  case DirEntryType_Self:
244  ii = fcb->inode_item;
245  r = fcb->subvol;
246  inode = fcb->inode;
247  atts = fcb->atts;
248  ealen = fcb->ealen;
249  break;
250 
251  case DirEntryType_Parent:
252  if (fileref && fileref->parent) {
253  ii = fileref->parent->fcb->inode_item;
254  r = fileref->parent->fcb->subvol;
255  inode = fileref->parent->fcb->inode;
256  atts = fileref->parent->fcb->atts;
257  ealen = fileref->parent->fcb->ealen;
258  } else {
259  ERR("no fileref\n");
260  return STATUS_INTERNAL_ERROR;
261  }
262  break;
263  }
264 
265  if (atts == 0)
267  }
268 
269  switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
271  {
273 
274  TRACE("FileBothDirectoryInformation\n");
275 
276  needed = sizeof(FILE_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
277 
278  if (needed > *len) {
279  TRACE("buffer overflow - %u > %u\n", needed, *len);
280  return STATUS_BUFFER_OVERFLOW;
281  }
282 
283  fbdi->NextEntryOffset = 0;
284  fbdi->FileIndex = 0;
289  fbdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
290 
291  if (de->type == BTRFS_TYPE_SYMLINK)
292  fbdi->AllocationSize.QuadPart = 0;
293  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
294  fbdi->AllocationSize.QuadPart = ii.st_blocks;
295  else
296  fbdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
297 
298  fbdi->FileAttributes = atts;
299  fbdi->FileNameLength = de->name.Length;
300  fbdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
301  fbdi->ShortNameLength = 0;
302 
303  RtlCopyMemory(fbdi->FileName, de->name.Buffer, de->name.Length);
304 
305  *len -= needed;
306 
307  return STATUS_SUCCESS;
308  }
309 
311  {
313 
314  TRACE("FileDirectoryInformation\n");
315 
316  needed = sizeof(FILE_DIRECTORY_INFORMATION) - sizeof(WCHAR) + de->name.Length;
317 
318  if (needed > *len) {
319  TRACE("buffer overflow - %u > %u\n", needed, *len);
320  return STATUS_BUFFER_OVERFLOW;
321  }
322 
323  fdi->NextEntryOffset = 0;
324  fdi->FileIndex = 0;
329  fdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
330 
331  if (de->type == BTRFS_TYPE_SYMLINK)
332  fdi->AllocationSize.QuadPart = 0;
333  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
335  else
336  fdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
337 
338  fdi->FileAttributes = atts;
339  fdi->FileNameLength = de->name.Length;
340 
341  RtlCopyMemory(fdi->FileName, de->name.Buffer, de->name.Length);
342 
343  *len -= needed;
344 
345  return STATUS_SUCCESS;
346  }
347 
349  {
351 
352  TRACE("FileFullDirectoryInformation\n");
353 
354  needed = sizeof(FILE_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
355 
356  if (needed > *len) {
357  TRACE("buffer overflow - %u > %u\n", needed, *len);
358  return STATUS_BUFFER_OVERFLOW;
359  }
360 
361  ffdi->NextEntryOffset = 0;
362  ffdi->FileIndex = 0;
367  ffdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
368 
369  if (de->type == BTRFS_TYPE_SYMLINK)
370  ffdi->AllocationSize.QuadPart = 0;
371  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
372  ffdi->AllocationSize.QuadPart = ii.st_blocks;
373  else
374  ffdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
375 
376  ffdi->FileAttributes = atts;
377  ffdi->FileNameLength = de->name.Length;
378  ffdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
379 
380  RtlCopyMemory(ffdi->FileName, de->name.Buffer, de->name.Length);
381 
382  *len -= needed;
383 
384  return STATUS_SUCCESS;
385  }
386 
388  {
390 
391  TRACE("FileIdBothDirectoryInformation\n");
392 
393  needed = sizeof(FILE_ID_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
394 
395  if (needed > *len) {
396  TRACE("buffer overflow - %u > %u\n", needed, *len);
397  return STATUS_BUFFER_OVERFLOW;
398  }
399 
400  fibdi->NextEntryOffset = 0;
401  fibdi->FileIndex = 0;
406  fibdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
407 
408  if (de->type == BTRFS_TYPE_SYMLINK)
409  fibdi->AllocationSize.QuadPart = 0;
410  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
411  fibdi->AllocationSize.QuadPart = ii.st_blocks;
412  else
413  fibdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
414 
415  fibdi->FileAttributes = atts;
416  fibdi->FileNameLength = de->name.Length;
417  fibdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
418  fibdi->ShortNameLength = 0;
419  fibdi->FileId.QuadPart = r ? make_file_id(r, inode) : make_file_id(fcb->Vcb->dummy_fcb->subvol, fcb->Vcb->dummy_fcb->inode);
420 
421  RtlCopyMemory(fibdi->FileName, de->name.Buffer, de->name.Length);
422 
423  *len -= needed;
424 
425  return STATUS_SUCCESS;
426  }
427 
429  {
431 
432  TRACE("FileIdFullDirectoryInformation\n");
433 
434  needed = sizeof(FILE_ID_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
435 
436  if (needed > *len) {
437  TRACE("buffer overflow - %u > %u\n", needed, *len);
438  return STATUS_BUFFER_OVERFLOW;
439  }
440 
441  fifdi->NextEntryOffset = 0;
442  fifdi->FileIndex = 0;
447  fifdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
448 
449  if (de->type == BTRFS_TYPE_SYMLINK)
450  fifdi->AllocationSize.QuadPart = 0;
451  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
452  fifdi->AllocationSize.QuadPart = ii.st_blocks;
453  else
454  fifdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
455 
456  fifdi->FileAttributes = atts;
457  fifdi->FileNameLength = de->name.Length;
458  fifdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
459  fifdi->FileId.QuadPart = r ? make_file_id(r, inode) : make_file_id(fcb->Vcb->dummy_fcb->subvol, fcb->Vcb->dummy_fcb->inode);
460 
461  RtlCopyMemory(fifdi->FileName, de->name.Buffer, de->name.Length);
462 
463  *len -= needed;
464 
465  return STATUS_SUCCESS;
466  }
467 
469  {
471 
472  TRACE("FileNamesInformation\n");
473 
474  needed = sizeof(FILE_NAMES_INFORMATION) - sizeof(WCHAR) + de->name.Length;
475 
476  if (needed > *len) {
477  TRACE("buffer overflow - %u > %u\n", needed, *len);
478  return STATUS_BUFFER_OVERFLOW;
479  }
480 
481  fni->NextEntryOffset = 0;
482  fni->FileIndex = 0;
483  fni->FileNameLength = de->name.Length;
484 
485  RtlCopyMemory(fni->FileName, de->name.Buffer, de->name.Length);
486 
487  *len -= needed;
488 
489  return STATUS_SUCCESS;
490  }
491 
493  FIXME("STUB: FileObjectIdInformation\n");
494  return STATUS_NOT_IMPLEMENTED;
495 
497  FIXME("STUB: FileQuotaInformation\n");
498  return STATUS_NOT_IMPLEMENTED;
499 
501  FIXME("STUB: FileReparsePointInformation\n");
502  return STATUS_NOT_IMPLEMENTED;
503 
504  default:
505  WARN("Unknown FileInformationClass %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
506  return STATUS_NOT_IMPLEMENTED;
507  }
508 
509  return STATUS_NO_MORE_FILES;
510 }
511 
513  LIST_ENTRY* le;
514  dir_child* dc;
515 
516  if (*pdc) {
517  dir_child* dc2 = *pdc;
518 
519  if (dc2->list_entry_index.Flink != &fileref->fcb->dir_children_index)
520  dc = CONTAINING_RECORD(dc2->list_entry_index.Flink, dir_child, list_entry_index);
521  else
522  dc = NULL;
523 
524  goto next;
525  }
526 
527  if (fileref->parent) { // don't return . and .. if root directory
528  if (*offset == 0) {
529  de->key.obj_id = fileref->fcb->inode;
531  de->key.offset = 0;
533  de->name.Buffer = L".";
534  de->name.Length = de->name.MaximumLength = sizeof(WCHAR);
536 
537  *offset = 1;
538  *pdc = NULL;
539 
540  return STATUS_SUCCESS;
541  } else if (*offset == 1) {
542  de->key.obj_id = fileref->parent->fcb->inode;
544  de->key.offset = 0;
546  de->name.Buffer = L"..";
547  de->name.Length = de->name.MaximumLength = sizeof(WCHAR) * 2;
549 
550  *offset = 2;
551  *pdc = NULL;
552 
553  return STATUS_SUCCESS;
554  }
555  }
556 
557  if (*offset < 2)
558  *offset = 2;
559 
560  dc = NULL;
561  le = fileref->fcb->dir_children_index.Flink;
562 
563  // skip entries before offset
564  while (le != &fileref->fcb->dir_children_index) {
565  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
566 
567  if (dc2->index >= *offset) {
568  dc = dc2;
569  break;
570  }
571 
572  le = le->Flink;
573  }
574 
575 next:
576  if (!dc)
577  return STATUS_NO_MORE_FILES;
578 
579  de->key = dc->key;
580  de->name = dc->name;
581  de->type = dc->type;
583  de->dc = dc;
584 
585  *offset = dc->index + 1;
586  *pdc = dc;
587 
588  return STATUS_SUCCESS;
589 }
590 
593  NTSTATUS Status, status2;
594  fcb* fcb;
595  ccb* ccb;
596  file_ref* fileref;
598  void* buf;
599  UINT8 *curitem, *lastitem;
600  LONG length;
601  ULONG count;
602  BOOL has_wildcard = FALSE, specific_file = FALSE, initial;
603  dir_entry de;
604  UINT64 newoffset;
605  dir_child* dc = NULL;
606 
607  TRACE("query directory\n");
608 
610  fcb = IrpSp->FileObject->FsContext;
611  ccb = IrpSp->FileObject->FsContext2;
612  fileref = ccb ? ccb->fileref : NULL;
613 
614  if (!fileref)
616 
617  if (!ccb) {
618  ERR("ccb was NULL\n");
620  }
621 
622  if (!fcb) {
623  ERR("fcb was NULL\n");
625  }
626 
627  if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_LIST_DIRECTORY)) {
628  WARN("insufficient privileges\n");
629  return STATUS_ACCESS_DENIED;
630  }
631 
632  Vcb = fcb->Vcb;
633 
634  if (!Vcb) {
635  ERR("Vcb was NULL\n");
637  }
638 
639  if (fileref->fcb == Vcb->dummy_fcb)
640  return STATUS_NO_MORE_FILES;
641 
642  if (IrpSp->Flags == 0) {
643  TRACE("QD flags: (none)\n");
644  } else {
645  ULONG flags = IrpSp->Flags;
646 
647  TRACE("QD flags:\n");
648 
649  if (flags & SL_INDEX_SPECIFIED) {
650  TRACE(" SL_INDEX_SPECIFIED\n");
652  }
653 
654  if (flags & SL_RESTART_SCAN) {
655  TRACE(" SL_RESTART_SCAN\n");
657  }
658 
660  TRACE(" SL_RETURN_SINGLE_ENTRY\n");
662  }
663 
664  if (flags != 0)
665  TRACE(" unknown flags: %u\n", flags);
666  }
667 
668  if (IrpSp->Flags & SL_RESTART_SCAN) {
669  ccb->query_dir_offset = 0;
670 
671  if (ccb->query_string.Buffer) {
674  }
675 
678  }
679 
680  initial = !ccb->query_string.Buffer;
681 
682  if (IrpSp->Parameters.QueryDirectory.FileName && IrpSp->Parameters.QueryDirectory.FileName->Length > 1) {
683  TRACE("QD filename: %.*S\n", IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR), IrpSp->Parameters.QueryDirectory.FileName->Buffer);
684 
685  if (IrpSp->Parameters.QueryDirectory.FileName->Length > sizeof(WCHAR) || IrpSp->Parameters.QueryDirectory.FileName->Buffer[0] != L'*') {
686  specific_file = TRUE;
687 
688  if (FsRtlDoesNameContainWildCards(IrpSp->Parameters.QueryDirectory.FileName)) {
689  has_wildcard = TRUE;
690  specific_file = FALSE;
691  }
692  }
693 
694  if (ccb->query_string.Buffer)
696 
697  if (has_wildcard)
698  RtlUpcaseUnicodeString(&ccb->query_string, IrpSp->Parameters.QueryDirectory.FileName, TRUE);
699  else {
700  ccb->query_string.Buffer = ExAllocatePoolWithTag(PagedPool, IrpSp->Parameters.QueryDirectory.FileName->Length, ALLOC_TAG);
701  if (!ccb->query_string.Buffer) {
702  ERR("out of memory\n");
704  }
705 
706  ccb->query_string.Length = ccb->query_string.MaximumLength = IrpSp->Parameters.QueryDirectory.FileName->Length;
707  RtlCopyMemory(ccb->query_string.Buffer, IrpSp->Parameters.QueryDirectory.FileName->Buffer, IrpSp->Parameters.QueryDirectory.FileName->Length);
708  }
709 
710  ccb->has_wildcard = has_wildcard;
711  ccb->specific_file = specific_file;
712  } else {
713  has_wildcard = ccb->has_wildcard;
714  specific_file = ccb->specific_file;
715 
716  if (!(IrpSp->Flags & SL_RESTART_SCAN)) {
717  initial = FALSE;
718 
719  if (specific_file)
720  return STATUS_NO_MORE_FILES;
721  }
722  }
723 
724  if (ccb->query_string.Buffer) {
725  TRACE("query string = %.*S\n", ccb->query_string.Length / sizeof(WCHAR), ccb->query_string.Buffer);
726  }
727 
728  newoffset = ccb->query_dir_offset;
729 
730  ExAcquireResourceSharedLite(&Vcb->tree_lock, TRUE);
731 
732  ExAcquireResourceSharedLite(&fileref->fcb->nonpaged->dir_children_lock, TRUE);
733 
734  Status = next_dir_entry(fileref, &newoffset, &de, &dc);
735 
736  if (!NT_SUCCESS(Status)) {
737  if (Status == STATUS_NO_MORE_FILES && initial)
739  goto end;
740  }
741 
742  ccb->query_dir_offset = newoffset;
743 
745 
746  if (Irp->MdlAddress && !buf) {
747  ERR("MmGetSystemAddressForMdlSafe returned NULL\n");
749  goto end;
750  }
751 
752  length = IrpSp->Parameters.QueryDirectory.Length;
753 
754  if (specific_file) {
755  BOOL found = FALSE;
757  LIST_ENTRY* le;
758  UINT32 hash;
759  UINT8 c;
760 
761  us.Buffer = NULL;
762 
763  if (!ccb->case_sensitive) {
765  if (!NT_SUCCESS(Status)) {
766  ERR("RtlUpcaseUnicodeString returned %08x\n", Status);
767  goto end;
768  }
769 
770  hash = calc_crc32c(0xffffffff, (UINT8*)us.Buffer, us.Length);
771  } else
773 
774  c = hash >> 24;
775 
776  if (ccb->case_sensitive) {
777  if (fileref->fcb->hash_ptrs[c]) {
778  le = fileref->fcb->hash_ptrs[c];
779  while (le != &fileref->fcb->dir_children_hash) {
780  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash);
781 
782  if (dc2->hash == hash) {
784  found = TRUE;
785 
786  de.key = dc2->key;
787  de.name = dc2->name;
788  de.type = dc2->type;
790  de.dc = dc2;
791 
792  break;
793  }
794  } else if (dc2->hash > hash)
795  break;
796 
797  le = le->Flink;
798  }
799  }
800  } else {
801  if (fileref->fcb->hash_ptrs_uc[c]) {
802  le = fileref->fcb->hash_ptrs_uc[c];
803  while (le != &fileref->fcb->dir_children_hash_uc) {
804  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
805 
806  if (dc2->hash_uc == hash) {
807  if (dc2->name_uc.Length == us.Length && RtlCompareMemory(dc2->name_uc.Buffer, us.Buffer, us.Length) == us.Length) {
808  found = TRUE;
809 
810  de.key = dc2->key;
811  de.name = dc2->name;
812  de.type = dc2->type;
814  de.dc = dc2;
815 
816  break;
817  }
818  } else if (dc2->hash_uc > hash)
819  break;
820 
821  le = le->Flink;
822  }
823  }
824  }
825 
826  if (us.Buffer)
827  ExFreePool(us.Buffer);
828 
829  if (!found) {
831  goto end;
832  }
833  } else if (has_wildcard) {
835  newoffset = ccb->query_dir_offset;
836  Status = next_dir_entry(fileref, &newoffset, &de, &dc);
837 
838  if (NT_SUCCESS(Status))
839  ccb->query_dir_offset = newoffset;
840  else {
841  if (Status == STATUS_NO_MORE_FILES && initial)
843 
844  goto end;
845  }
846  }
847  }
848 
849  TRACE("file(0) = %.*S\n", de.name.Length / sizeof(WCHAR), de.name.Buffer);
850  TRACE("offset = %u\n", ccb->query_dir_offset - 1);
851 
853 
854  count = 0;
855  if (NT_SUCCESS(Status) && !(IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) && !specific_file) {
856  lastitem = (UINT8*)buf;
857 
858  while (length > 0) {
859  switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
865  length -= length % 8;
866  break;
867 
869  length -= length % 4;
870  break;
871 
872  default:
873  WARN("unhandled file information class %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
874  break;
875  }
876 
877  if (length > 0) {
878  newoffset = ccb->query_dir_offset;
879  Status = next_dir_entry(fileref, &newoffset, &de, &dc);
880  if (NT_SUCCESS(Status)) {
881  if (!has_wildcard || FsRtlIsNameInExpression(&ccb->query_string, &de.name, !ccb->case_sensitive, NULL)) {
882  curitem = (UINT8*)buf + IrpSp->Parameters.QueryDirectory.Length - length;
883  count++;
884 
885  TRACE("file(%u) %u = %.*S\n", count, curitem - (UINT8*)buf, de.name.Length / sizeof(WCHAR), de.name.Buffer);
886  TRACE("offset = %u\n", ccb->query_dir_offset - 1);
887 
888  status2 = query_dir_item(fcb, ccb, curitem, &length, Irp, &de, fcb->subvol);
889 
890  if (NT_SUCCESS(status2)) {
891  ULONG* lastoffset = (ULONG*)lastitem;
892 
893  *lastoffset = (ULONG)(curitem - lastitem);
894  ccb->query_dir_offset = newoffset;
895 
896  lastitem = curitem;
897  } else
898  break;
899  } else
900  ccb->query_dir_offset = newoffset;
901  } else {
904 
905  break;
906  }
907  } else
908  break;
909  }
910  }
911 
912  Irp->IoStatus.Information = IrpSp->Parameters.QueryDirectory.Length - length;
913 
914 end:
915  ExReleaseResourceLite(&fileref->fcb->nonpaged->dir_children_lock);
916 
917  ExReleaseResourceLite(&Vcb->tree_lock);
918 
919  TRACE("returning %08x\n", Status);
920 
921  return Status;
922 }
923 
927  fcb* fcb = FileObject->FsContext;
928  ccb* ccb = FileObject->FsContext2;
929  file_ref* fileref = ccb ? ccb->fileref : NULL;
931 
932  TRACE("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
933 
934  if (!ccb) {
935  ERR("ccb was NULL\n");
937  }
938 
939  if (!fileref) {
940  ERR("no fileref\n");
942  }
943 
944  if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_LIST_DIRECTORY)) {
945  WARN("insufficient privileges\n");
946  return STATUS_ACCESS_DENIED;
947  }
948 
949  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, TRUE);
951 
952  if (fcb->type != BTRFS_TYPE_DIRECTORY) {
954  goto end;
955  }
956 
957  // FIXME - raise exception if FCB marked for deletion?
958 
959  TRACE("%S\n", file_desc(FileObject));
960 
961  if (ccb->filename.Length == 0) {
962  ULONG reqlen;
963 
965 
966  Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen);
969  if (!ccb->filename.Buffer) {
970  ERR("out of memory\n");
972  goto end;
973  }
974 
975  ccb->filename.MaximumLength = (UINT16)reqlen;
976 
977  Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen);
978  if (!NT_SUCCESS(Status)) {
979  ERR("fileref_get_filename returned %08x\n", Status);
980  goto end;
981  }
982  } else {
983  ERR("fileref_get_filename returned %08x\n", Status);
984  goto end;
985  }
986  }
987 
988  FsRtlNotifyFilterChangeDirectory(Vcb->NotifySync, &Vcb->DirNotifyList, FileObject->FsContext2, (PSTRING)&ccb->filename,
989  IrpSp->Flags & SL_WATCH_TREE, FALSE, IrpSp->Parameters.NotifyDirectory.CompletionFilter, Irp,
990  NULL, NULL, NULL);
991 
993 
994 end:
995  ExReleaseResourceLite(fcb->Header.Resource);
996  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
997 
998  return Status;
999 }
1000 
1003 NTSTATUS NTAPI drv_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
1005  NTSTATUS Status;
1006  ULONG func;
1007  BOOL top_level;
1009 
1011 
1012  TRACE("directory control\n");
1013 
1014  top_level = is_top_level(Irp);
1015 
1016  if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
1018  goto end;
1019  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
1021  goto end;
1022  }
1023 
1025 
1026  Irp->IoStatus.Information = 0;
1027 
1029 
1030  switch (func) {
1033  break;
1034 
1037  break;
1038 
1039  default:
1040  WARN("unknown minor %u\n", func);
1042  Irp->IoStatus.Status = Status;
1043  break;
1044  }
1045 
1046  if (Status == STATUS_PENDING)
1047  goto exit;
1048 
1049 end:
1050  Irp->IoStatus.Status = Status;
1051 
1053 
1054 exit:
1055  TRACE("returning %08x\n", Status);
1056 
1057  if (top_level)
1059 
1061 
1062  return Status;
1063 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
LARGE_INTEGER AllocationSize
Definition: iotypes.h:5367
struct _file_ref * parent
Definition: btrfs_drv.h:326
LARGE_INTEGER LastAccessTime
Definition: winternl.h:517
GLenum func
Definition: glext.h:6028
static NTSTATUS next_dir_entry(file_ref *fileref, UINT64 *offset, dir_entry *de, dir_child **pdc)
Definition: dirctrl.c:512
LARGE_INTEGER AllocationSize
Definition: iotypes.h:5400
UINT64 id
Definition: btrfs_drv.h:426
#define IN
Definition: typedefs.h:38
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _file_ref * fileref
Definition: btrfs_drv.h:234
static ULONG get_ea_len(device_extension *Vcb, root *subvol, UINT64 inode, PIRP Irp)
Definition: dirctrl.c:99
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define FsRtlEnterFileSystem
UINT64 offset
Definition: btrfs.h:125
#define FILE_ATTRIBUTE_SPARSE_FILE
Definition: ntifs_ex.h:380
BOOL case_sensitive
Definition: btrfs_drv.h:361
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:85
BTRFS_TIME otime
Definition: btrfs.h:281
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1793
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1507
#define FsRtlExitFileSystem
#define IO_REPARSE_TAG_LXSS_FIFO
Definition: btrfs_drv.h:115
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS fileref_get_filename(file_ref *fileref, PUNICODE_STRING fn, USHORT *name_offset, ULONG *preqlen)
Definition: fileinfo.c:2911
UNICODE_STRING name_uc
Definition: btrfs_drv.h:232
UINT32 hash_uc
Definition: btrfs_drv.h:231
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_In_ PIRP Irp
Definition: csq.h:116
static const BYTE us[]
Definition: encode.c:689
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:83
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
GLuint GLuint GLsizei count
Definition: gl.h:1545
UINT64 inode
Definition: btrfs_drv.h:262
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
BOOL specific_file
Definition: btrfs_drv.h:353
UINT8 type
Definition: dirctrl.c:29
#define BTRFS_TYPE_FIFO
Definition: shellext.h:84
GLintptr offset
Definition: glext.h:5920
static NTSTATUS query_dir_item(fcb *fcb, ccb *ccb, void *buf, LONG *len, PIRP Irp, dir_entry *de, root *r)
Definition: dirctrl.c:136
UINT64 obj_id
Definition: btrfs.h:123
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
Definition: ecma_167.h:138
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:275
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
struct _FILE_FULL_DIRECTORY_INFORMATION FILE_FULL_DIR_INFORMATION
enum DirEntryType dir_entry_type
Definition: dirctrl.c:30
#define VCB_TYPE_FS
Definition: btrfs_drv.h:634
static __inline UINT64 make_file_id(root *r, UINT64 inode)
Definition: btrfs_drv.h:1000
HDC dc
Definition: cylfrac.c:34
DirEntryType
Definition: dirctrl.c:20
static NTSTATUS query_directory(PIRP Irp)
Definition: dirctrl.c:591
GLuint GLuint end
Definition: gl.h:1545
_In_ UINT64 _In_ UINT64 _In_ UINT64 _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2663
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:357
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:82
UINT16 size
Definition: btrfs_drv.h:389
BTRFS_TIME st_ctime
Definition: btrfs.h:279
UINT8 type
Definition: btrfs_drv.h:227
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: recv.cpp:134
UNICODE_STRING filename
Definition: btrfs_drv.h:359
UINT8 obj_type
Definition: btrfs.h:124
UNICODE_STRING query_string
Definition: btrfs_drv.h:351
Definition: fs.h:78
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#define ALLOC_TAG
Definition: btrfs_drv.h:86
LARGE_INTEGER ChangeTime
Definition: winternl.h:519
BOOL has_wildcard
Definition: btrfs_drv.h:352
#define IO_DISK_INCREMENT
Definition: iotypes.h:567
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
LARGE_INTEGER LastWriteTime
Definition: from_kernel.h:143
unsigned int UINT32
int hash
Definition: main.c:58
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
LARGE_INTEGER EndOfFile
Definition: winternl.h:520
#define FIXME(fmt,...)
Definition: debug.h:110
NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, root *subvol, UINT64 inode, UINT8 type, PANSI_STRING utf8, fcb *parent, fcb **pfcb, POOL_TYPE pooltype, PIRP Irp)
Definition: create.c:595
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:81
PVOID DeviceExtension
Definition: env_spec_w32.h:418
ULONG get_reparse_tag_fcb(fcb *fcb)
Definition: dirctrl.c:34
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:288
smooth NULL
Definition: ftsmooth.c:416
ULONG get_reparse_tag(device_extension *Vcb, root *subvol, UINT64 inode, UINT8 type, ULONG atts, BOOL lxss, PIRP Irp)
Definition: dirctrl.c:58
#define IO_REPARSE_TAG_LXSS_CHARDEV
Definition: btrfs_drv.h:116
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
#define IoCompleteRequest
Definition: irp.c:1240
_Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL)
Definition: dirctrl.c:1001
struct _FILE_BOTH_DIR_INFORMATION FILE_BOTH_DIR_INFORMATION
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
_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
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static __inline uint64_t unix_time_to_win(BTRFS_TIME *t)
Definition: recv.cpp:1180
#define IO_REPARSE_TAG_LXSS_SOCKET
Definition: btrfs_drv.h:114
LARGE_INTEGER LastWriteTime
Definition: iotypes.h:5397
ULONG ealen
Definition: btrfs_drv.h:277
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:256
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
UINT64 query_dir_offset
Definition: btrfs_drv.h:350
#define TRACE(s)
Definition: solgame.cpp:4
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:286
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:284
struct _fcb fcb
Definition: btrfs_drv.h:1334
UINT64 index
Definition: btrfs_drv.h:226
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:636
#define Vcb
Definition: cdprocs.h:1425
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:965
LARGE_INTEGER LastWriteTime
Definition: winternl.h:518
const GLubyte * c
Definition: glext.h:8905
#define IO_REPARSE_TAG_LXSS_BLOCKDEV
Definition: btrfs_drv.h:117
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LIST_ENTRY list_entry_index
Definition: btrfs_drv.h:235
#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
GLbitfield flags
Definition: glext.h:7161
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
BTRFS_TIME st_atime
Definition: btrfs.h:278
LARGE_INTEGER CreationTime
Definition: iotypes.h:5362
UINT64 st_blocks
Definition: btrfs.h:268
struct _FILE_NAMES_INFORMATION FILE_NAMES_INFORMATION
tree_data * item
Definition: btrfs_drv.h:475
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
static const WCHAR L[]
Definition: oid.c:1250
#define SL_WATCH_TREE
Definition: iotypes.h:1795
#define TYPE_INODE_ITEM
Definition: btrfs.h:18
GLenum GLsizei len
Definition: glext.h:6722
UINT32 hash
Definition: btrfs_drv.h:229
struct _FILE_DIRECTORY_INFORMATION FILE_DIRECTORY_INFORMATION
fcb * fcb
Definition: btrfs_drv.h:316
Definition: typedefs.h:117
LARGE_INTEGER CreationTime
Definition: iotypes.h:5395
INODE_ITEM inode_item
Definition: btrfs_drv.h:265
DRIVER_DISPATCH(nfs41_FsdDispatch)
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
Definition: btrfs.h:122
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1792
const string EA_EA
Definition: recv.cpp:40
dir_child * dc
Definition: dirctrl.c:31
static unsigned __int64 next
Definition: rand_nt.c:6
ULONG atts
Definition: btrfs_drv.h:270
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
UINT64 st_size
Definition: btrfs.h:267
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:257
KEY key
Definition: dirctrl.c:27
LARGE_INTEGER CreationTime
Definition: winternl.h:516
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define TYPE_ROOT_ITEM
Definition: btrfs.h:26
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
unsigned short UINT16
struct _root * subvol
Definition: btrfs_drv.h:261
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
BOOL is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:256
#define SL_RESTART_SCAN
Definition: iotypes.h:1791
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define EA_EA_HASH
Definition: btrfs_drv.h:102
LARGE_INTEGER CreationTime
Definition: from_kernel.h:141
struct _FILE_ID_BOTH_DIR_INFORMATION FILE_ID_BOTH_DIR_INFORMATION
#define BTRFS_TYPE_FILE
Definition: shellext.h:80
UINT8 type
Definition: btrfs_drv.h:264
Definition: dirctrl.c:26
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:977
struct _FILE_ID_FULL_DIR_INFORMATION FILE_ID_FULL_DIR_INFORMATION
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:287
static NTSTATUS notify_change_directory(device_extension *Vcb, PIRP Irp)
Definition: dirctrl.c:924
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:285
LARGE_INTEGER LastAccessTime
Definition: from_kernel.h:142
ULONG get_file_attributes(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_ UINT64 inode, _In_ UINT8 type, _In_ BOOL dotfile, _In_ BOOL ignore_xa, _In_opt_ PIRP Irp)
Definition: btrfs.c:2384
void exit(int exitcode)
Definition: _exit.c:33
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:358
unsigned long long UINT64
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:524
return STATUS_SUCCESS
Definition: btrfs.c:2745
LARGE_INTEGER LastWriteTime
Definition: iotypes.h:5364
Definition: _hash_fun.h:40
unsigned char UINT8
BOOL lxss
Definition: btrfs_drv.h:366
_In_ UINT16 _Out_ ULONG * atts
Definition: btrfs_drv.h:1089
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6883
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
LARGE_INTEGER LastAccessTime
Definition: iotypes.h:5396
UINT8 * data
Definition: btrfs_drv.h:390
struct _device_extension * Vcb
Definition: btrfs_drv.h:260
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LARGE_INTEGER AllocationSize
Definition: winternl.h:521
UNICODE_STRING name
Definition: btrfs_drv.h:230
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
NTSTATUS vol_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:336
#define _Function_class_(x)
Definition: no_sal2.h:202
_Ret_z_ WCHAR * file_desc(_In_ PFILE_OBJECT FileObject)
Definition: btrfs.c:1336
LONGLONG QuadPart
Definition: typedefs.h:112
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:86
UNICODE_STRING name
Definition: dirctrl.c:28
LARGE_INTEGER LastAccessTime
Definition: iotypes.h:5363
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:539
char * tag
Definition: main.c:59
VOID NTAPI FsRtlNotifyFilterChangeDirectory(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL, IN PFILTER_REPORT_CHANGE FilterCallback OPTIONAL)
Definition: notify.c:749