ReactOS  0.4.15-dev-1187-g119f102
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 #include "crc32c.h"
20 
21 #ifndef __REACTOS__
22 // not currently in mingw
23 #ifndef _MSC_VER
24 #define FileIdExtdDirectoryInformation (enum _FILE_INFORMATION_CLASS)60
25 #define FileIdExtdBothDirectoryInformation (enum _FILE_INFORMATION_CLASS)63
26 
43 
62 
63 #endif
64 #else
65 #define FileIdExtdDirectoryInformation (enum _FILE_INFORMATION_CLASS)60
66 #define FileIdExtdBothDirectoryInformation (enum _FILE_INFORMATION_CLASS)63
67 #endif // __REACTOS__
68 
73 };
74 
75 typedef struct {
79  enum DirEntryType dir_entry_type;
81 } dir_entry;
82 
84  ULONG tag;
85 
86  if (fcb->type == BTRFS_TYPE_SYMLINK)
88  else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
89  if (!fcb->reparse_xattr.Buffer || fcb->reparse_xattr.Length < sizeof(ULONG))
90  return 0;
91 
93  } else {
95  ULONG br;
96 
97  Status = read_file(fcb, (uint8_t*)&tag, 0, sizeof(ULONG), &br, NULL);
98  if (!NT_SUCCESS(Status)) {
99  ERR("read_file returned %08lx\n", Status);
100  return 0;
101  }
102  }
103 
104  return tag;
105 }
106 
108  fcb* fcb;
109  ULONG tag = 0;
111 
112  if (type == BTRFS_TYPE_SYMLINK)
113  return IO_REPARSE_TAG_SYMLINK;
114  else if (lxss) {
115  if (type == BTRFS_TYPE_SOCKET)
116  return IO_REPARSE_TAG_AF_UNIX;
117  else if (type == BTRFS_TYPE_FIFO)
118  return IO_REPARSE_TAG_LX_FIFO;
119  else if (type == BTRFS_TYPE_CHARDEV)
120  return IO_REPARSE_TAG_LX_CHR;
121  else if (type == BTRFS_TYPE_BLOCKDEV)
122  return IO_REPARSE_TAG_LX_BLK;
123  }
124 
126  return 0;
127 
129  return 0;
130 
131  Status = open_fcb(Vcb, subvol, inode, type, NULL, false, NULL, &fcb, PagedPool, Irp);
132  if (!NT_SUCCESS(Status)) {
133  ERR("open_fcb returned %08lx\n", Status);
134  return 0;
135  }
136 
137  ExAcquireResourceSharedLite(fcb->Header.Resource, true);
138 
140 
141  ExReleaseResourceLite(fcb->Header.Resource);
142 
143  free_fcb(fcb);
144 
145  return tag;
146 }
147 
149  uint8_t* eadata;
150  uint16_t len;
151 
152  if (get_xattr(Vcb, subvol, inode, EA_EA, EA_EA_HASH, &eadata, &len, Irp)) {
153  ULONG offset;
155 
157 
158  if (!NT_SUCCESS(Status)) {
159  WARN("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset);
160  ExFreePool(eadata);
161  return 0;
162  } else {
163  FILE_FULL_EA_INFORMATION* eainfo;
164  ULONG ealen;
165 
166  ealen = 4;
167  eainfo = (FILE_FULL_EA_INFORMATION*)eadata;
168  do {
169  ealen += 5 + eainfo->EaNameLength + eainfo->EaValueLength;
170 
171  if (eainfo->NextEntryOffset == 0)
172  break;
173 
174  eainfo = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)eainfo) + eainfo->NextEntryOffset);
175  } while (true);
176 
177  ExFreePool(eadata);
178 
179  return ealen;
180  }
181  } else
182  return 0;
183 }
184 
187  LONG needed;
188  uint64_t inode;
189  INODE_ITEM ii;
191  ULONG atts = 0, ealen = 0;
192  file_ref* fileref = ccb->fileref;
193 
195 
196  if (de->key.obj_type == TYPE_ROOT_ITEM) { // subvol
197  LIST_ENTRY* le;
198 
199  r = NULL;
200 
201  le = fcb->Vcb->roots.Flink;
202  while (le != &fcb->Vcb->roots) {
203  root* subvol = CONTAINING_RECORD(le, root, list_entry);
204 
205  if (subvol->id == de->key.obj_id) {
206  r = subvol;
207  break;
208  }
209 
210  le = le->Flink;
211  }
212 
213  if (r && r->parent != fcb->subvol->id && (!de->dc || !de->dc->root_dir))
214  r = NULL;
215 
217  } else {
218  inode = de->key.obj_id;
219  }
220 
221  if (IrpSp->Parameters.QueryDirectory.FileInformationClass != FileNamesInformation) { // FIXME - object ID and reparse point classes too?
222  switch (de->dir_entry_type) {
223  case DirEntryType_File:
224  {
225  if (!r) {
227 
228  ii = fcb->Vcb->dummy_fcb->inode_item;
229  atts = fcb->Vcb->dummy_fcb->atts;
230  ealen = fcb->Vcb->dummy_fcb->ealen;
231 
234  ii.st_atime = ii.st_mtime = ii.st_ctime = ii.otime;
235  } else {
236  bool found = false;
237 
238  if (de->dc && de->dc->fileref && de->dc->fileref->fcb) {
239  ii = de->dc->fileref->fcb->inode_item;
240  atts = de->dc->fileref->fcb->atts;
241  ealen = de->dc->fileref->fcb->ealen;
242  found = true;
243  }
244 
245  if (!found) {
246  KEY searchkey;
248 
249  searchkey.obj_id = inode;
250  searchkey.obj_type = TYPE_INODE_ITEM;
251  searchkey.offset = 0xffffffffffffffff;
252 
253  Status = find_item(fcb->Vcb, r, &tp, &searchkey, false, Irp);
254  if (!NT_SUCCESS(Status)) {
255  ERR("error - find_item returned %08lx\n", Status);
256  return Status;
257  }
258 
259  if (tp.item->key.obj_id != searchkey.obj_id || tp.item->key.obj_type != searchkey.obj_type) {
260  ERR("could not find inode item for inode %I64x in root %I64x\n", inode, r->id);
261  return STATUS_INTERNAL_ERROR;
262  }
263 
264  RtlZeroMemory(&ii, sizeof(INODE_ITEM));
265 
266  if (tp.item->size > 0)
267  RtlCopyMemory(&ii, tp.item->data, min(sizeof(INODE_ITEM), tp.item->size));
268 
269  if (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
270  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileDirectoryInformation ||
271  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileFullDirectoryInformation ||
272  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation ||
273  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdFullDirectoryInformation ||
274  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdExtdDirectoryInformation ||
275  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdExtdBothDirectoryInformation) {
276 
277  bool dotfile = de->name.Length > sizeof(WCHAR) && de->name.Buffer[0] == '.';
278 
279  atts = get_file_attributes(fcb->Vcb, r, inode, de->type, dotfile, false, Irp);
280  }
281 
282  if (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
283  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileFullDirectoryInformation ||
284  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation ||
285  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdFullDirectoryInformation ||
286  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdExtdDirectoryInformation ||
287  IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdExtdBothDirectoryInformation) {
288  ealen = get_ea_len(fcb->Vcb, r, inode, Irp);
289  }
290  }
291  }
292 
293  break;
294  }
295 
296  case DirEntryType_Self:
297  ii = fcb->inode_item;
298  r = fcb->subvol;
299  inode = fcb->inode;
300  atts = fcb->atts;
301  ealen = fcb->ealen;
302  break;
303 
304  case DirEntryType_Parent:
305  if (fileref && fileref->parent) {
306  ii = fileref->parent->fcb->inode_item;
307  r = fileref->parent->fcb->subvol;
308  inode = fileref->parent->fcb->inode;
309  atts = fileref->parent->fcb->atts;
310  ealen = fileref->parent->fcb->ealen;
311  } else {
312  ERR("no fileref\n");
313  return STATUS_INTERNAL_ERROR;
314  }
315  break;
316  }
317 
318  if (atts == 0)
320  }
321 
322  switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
324  {
326 
327  TRACE("FileBothDirectoryInformation\n");
328 
329  needed = sizeof(FILE_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
330 
331  if (needed > *len) {
332  TRACE("buffer overflow - %li > %lu\n", needed, *len);
333  return STATUS_BUFFER_OVERFLOW;
334  }
335 
336  fbdi->NextEntryOffset = 0;
337  fbdi->FileIndex = 0;
342  fbdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
343 
344  if (de->type == BTRFS_TYPE_SYMLINK)
345  fbdi->AllocationSize.QuadPart = 0;
346  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
347  fbdi->AllocationSize.QuadPart = ii.st_blocks;
348  else
349  fbdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
350 
351  fbdi->FileAttributes = atts;
352  fbdi->FileNameLength = de->name.Length;
353  fbdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
354  fbdi->ShortNameLength = 0;
355 
356  RtlCopyMemory(fbdi->FileName, de->name.Buffer, de->name.Length);
357 
358  *len -= needed;
359 
360  return STATUS_SUCCESS;
361  }
362 
364  {
366 
367  TRACE("FileDirectoryInformation\n");
368 
369  needed = sizeof(FILE_DIRECTORY_INFORMATION) - sizeof(WCHAR) + de->name.Length;
370 
371  if (needed > *len) {
372  TRACE("buffer overflow - %li > %lu\n", needed, *len);
373  return STATUS_BUFFER_OVERFLOW;
374  }
375 
376  fdi->NextEntryOffset = 0;
377  fdi->FileIndex = 0;
382  fdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
383 
384  if (de->type == BTRFS_TYPE_SYMLINK)
385  fdi->AllocationSize.QuadPart = 0;
386  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
388  else
389  fdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
390 
391  fdi->FileAttributes = atts;
392  fdi->FileNameLength = de->name.Length;
393 
394  RtlCopyMemory(fdi->FileName, de->name.Buffer, de->name.Length);
395 
396  *len -= needed;
397 
398  return STATUS_SUCCESS;
399  }
400 
402  {
404 
405  TRACE("FileFullDirectoryInformation\n");
406 
407  needed = sizeof(FILE_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
408 
409  if (needed > *len) {
410  TRACE("buffer overflow - %li > %lu\n", needed, *len);
411  return STATUS_BUFFER_OVERFLOW;
412  }
413 
414  ffdi->NextEntryOffset = 0;
415  ffdi->FileIndex = 0;
420  ffdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
421 
422  if (de->type == BTRFS_TYPE_SYMLINK)
423  ffdi->AllocationSize.QuadPart = 0;
424  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
425  ffdi->AllocationSize.QuadPart = ii.st_blocks;
426  else
427  ffdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
428 
429  ffdi->FileAttributes = atts;
430  ffdi->FileNameLength = de->name.Length;
431  ffdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
432 
433  RtlCopyMemory(ffdi->FileName, de->name.Buffer, de->name.Length);
434 
435  *len -= needed;
436 
437  return STATUS_SUCCESS;
438  }
439 
441  {
443 
444  TRACE("FileIdBothDirectoryInformation\n");
445 
446  needed = sizeof(FILE_ID_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
447 
448  if (needed > *len) {
449  TRACE("buffer overflow - %li > %lu\n", needed, *len);
450  return STATUS_BUFFER_OVERFLOW;
451  }
452 
453  fibdi->NextEntryOffset = 0;
454  fibdi->FileIndex = 0;
459  fibdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
460 
461  if (de->type == BTRFS_TYPE_SYMLINK)
462  fibdi->AllocationSize.QuadPart = 0;
463  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
464  fibdi->AllocationSize.QuadPart = ii.st_blocks;
465  else
466  fibdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
467 
468  fibdi->FileAttributes = atts;
469  fibdi->FileNameLength = de->name.Length;
470  fibdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
471  fibdi->ShortNameLength = 0;
472  fibdi->FileId.QuadPart = r ? make_file_id(r, inode) : make_file_id(fcb->Vcb->dummy_fcb->subvol, fcb->Vcb->dummy_fcb->inode);
473 
474  RtlCopyMemory(fibdi->FileName, de->name.Buffer, de->name.Length);
475 
476  *len -= needed;
477 
478  return STATUS_SUCCESS;
479  }
480 
482  {
484 
485  TRACE("FileIdFullDirectoryInformation\n");
486 
487  needed = sizeof(FILE_ID_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;
488 
489  if (needed > *len) {
490  TRACE("buffer overflow - %li > %lu\n", needed, *len);
491  return STATUS_BUFFER_OVERFLOW;
492  }
493 
494  fifdi->NextEntryOffset = 0;
495  fifdi->FileIndex = 0;
500  fifdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
501 
502  if (de->type == BTRFS_TYPE_SYMLINK)
503  fifdi->AllocationSize.QuadPart = 0;
504  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
505  fifdi->AllocationSize.QuadPart = ii.st_blocks;
506  else
507  fifdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
508 
509  fifdi->FileAttributes = atts;
510  fifdi->FileNameLength = de->name.Length;
511  fifdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
512  fifdi->FileId.QuadPart = r ? make_file_id(r, inode) : make_file_id(fcb->Vcb->dummy_fcb->subvol, fcb->Vcb->dummy_fcb->inode);
513 
514  RtlCopyMemory(fifdi->FileName, de->name.Buffer, de->name.Length);
515 
516  *len -= needed;
517 
518  return STATUS_SUCCESS;
519  }
520 
521 #ifndef _MSC_VER
522 #pragma GCC diagnostic push
523 #pragma GCC diagnostic ignored "-Wswitch"
524 #endif
525 #if (NTDDI_VERSION >= NTDDI_VISTA)
527  {
529 
530  TRACE("FileIdExtdDirectoryInformation\n");
531 
533 
534  if (needed > *len) {
535  TRACE("buffer overflow - %li > %lu\n", needed, *len);
536  return STATUS_BUFFER_OVERFLOW;
537  }
538 
539  fiedi->NextEntryOffset = 0;
540  fiedi->FileIndex = 0;
545  fiedi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
546 
547  if (de->type == BTRFS_TYPE_SYMLINK)
548  fiedi->AllocationSize.QuadPart = 0;
549  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
550  fiedi->AllocationSize.QuadPart = ii.st_blocks;
551  else
552  fiedi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
553 
554  fiedi->FileAttributes = atts;
555  fiedi->FileNameLength = de->name.Length;
556  fiedi->EaSize = ealen;
557  fiedi->ReparsePointTag = get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp);
558 
559  RtlCopyMemory(&fiedi->FileId.Identifier[0], &fcb->inode, sizeof(uint64_t));
560  RtlCopyMemory(&fiedi->FileId.Identifier[sizeof(uint64_t)], &fcb->subvol->id, sizeof(uint64_t));
561 
562  RtlCopyMemory(fiedi->FileName, de->name.Buffer, de->name.Length);
563 
564  *len -= needed;
565 
566  return STATUS_SUCCESS;
567  }
568 
570  {
572 
573  TRACE("FileIdExtdBothDirectoryInformation\n");
574 
576 
577  if (needed > *len) {
578  TRACE("buffer overflow - %li > %lu\n", needed, *len);
579  return STATUS_BUFFER_OVERFLOW;
580  }
581 
582  fiebdi->NextEntryOffset = 0;
583  fiebdi->FileIndex = 0;
588  fiebdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;
589 
590  if (de->type == BTRFS_TYPE_SYMLINK)
591  fiebdi->AllocationSize.QuadPart = 0;
592  else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
593  fiebdi->AllocationSize.QuadPart = ii.st_blocks;
594  else
595  fiebdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);
596 
597  fiebdi->FileAttributes = atts;
598  fiebdi->FileNameLength = de->name.Length;
599  fiebdi->EaSize = ealen;
600  fiebdi->ReparsePointTag = get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp);
601 
602  RtlCopyMemory(&fiebdi->FileId.Identifier[0], &fcb->inode, sizeof(uint64_t));
603  RtlCopyMemory(&fiebdi->FileId.Identifier[sizeof(uint64_t)], &fcb->subvol->id, sizeof(uint64_t));
604 
605  fiebdi->ShortNameLength = 0;
606 
607  RtlCopyMemory(fiebdi->FileName, de->name.Buffer, de->name.Length);
608 
609  *len -= needed;
610 
611  return STATUS_SUCCESS;
612  }
613 #endif
614 
615 #ifndef _MSC_VER
616 #pragma GCC diagnostic pop
617 #endif
618 
620  {
622 
623  TRACE("FileNamesInformation\n");
624 
625  needed = sizeof(FILE_NAMES_INFORMATION) - sizeof(WCHAR) + de->name.Length;
626 
627  if (needed > *len) {
628  TRACE("buffer overflow - %li > %lu\n", needed, *len);
629  return STATUS_BUFFER_OVERFLOW;
630  }
631 
632  fni->NextEntryOffset = 0;
633  fni->FileIndex = 0;
634  fni->FileNameLength = de->name.Length;
635 
636  RtlCopyMemory(fni->FileName, de->name.Buffer, de->name.Length);
637 
638  *len -= needed;
639 
640  return STATUS_SUCCESS;
641  }
642 
644  FIXME("STUB: FileObjectIdInformation\n");
645  return STATUS_NOT_IMPLEMENTED;
646 
648  FIXME("STUB: FileQuotaInformation\n");
649  return STATUS_NOT_IMPLEMENTED;
650 
652  FIXME("STUB: FileReparsePointInformation\n");
653  return STATUS_NOT_IMPLEMENTED;
654 
655  default:
656  WARN("Unknown FileInformationClass %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
657  return STATUS_NOT_IMPLEMENTED;
658  }
659 
660  return STATUS_NO_MORE_FILES;
661 }
662 
664  LIST_ENTRY* le;
665  dir_child* dc;
666 
667  if (*pdc) {
668  dir_child* dc2 = *pdc;
669 
670  if (dc2->list_entry_index.Flink != &fileref->fcb->dir_children_index)
671  dc = CONTAINING_RECORD(dc2->list_entry_index.Flink, dir_child, list_entry_index);
672  else
673  dc = NULL;
674 
675  goto next;
676  }
677 
678  if (fileref->parent) { // don't return . and .. if root directory
679  if (*offset == 0) {
680  de->key.obj_id = fileref->fcb->inode;
682  de->key.offset = 0;
684  de->name.Buffer = L".";
685  de->name.Length = de->name.MaximumLength = sizeof(WCHAR);
687 
688  *offset = 1;
689  *pdc = NULL;
690 
691  return STATUS_SUCCESS;
692  } else if (*offset == 1) {
693  de->key.obj_id = fileref->parent->fcb->inode;
695  de->key.offset = 0;
697  de->name.Buffer = L"..";
698  de->name.Length = de->name.MaximumLength = sizeof(WCHAR) * 2;
700 
701  *offset = 2;
702  *pdc = NULL;
703 
704  return STATUS_SUCCESS;
705  }
706  }
707 
708  if (*offset < 2)
709  *offset = 2;
710 
711  dc = NULL;
712  le = fileref->fcb->dir_children_index.Flink;
713 
714  // skip entries before offset
715  while (le != &fileref->fcb->dir_children_index) {
716  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
717 
718  if (dc2->index >= *offset) {
719  dc = dc2;
720  break;
721  }
722 
723  le = le->Flink;
724  }
725 
726 next:
727  if (!dc)
728  return STATUS_NO_MORE_FILES;
729 
730  de->key = dc->key;
731  de->name = dc->name;
732  de->type = dc->type;
734  de->dc = dc;
735 
736  *offset = dc->index + 1;
737  *pdc = dc;
738 
739  return STATUS_SUCCESS;
740 }
741 
744  NTSTATUS Status, status2;
745  fcb* fcb;
746  ccb* ccb;
747  file_ref* fileref;
749  void* buf;
750  uint8_t *curitem, *lastitem;
751  LONG length;
752  ULONG count;
753  bool has_wildcard = false, specific_file = false, initial;
754  dir_entry de;
755  uint64_t newoffset;
756  dir_child* dc = NULL;
757 
758  TRACE("query directory\n");
759 
761  fcb = IrpSp->FileObject->FsContext;
762  ccb = IrpSp->FileObject->FsContext2;
763  fileref = ccb ? ccb->fileref : NULL;
764 
765  if (!fileref)
767 
768  if (!ccb) {
769  ERR("ccb was NULL\n");
771  }
772 
773  if (!fcb) {
774  ERR("fcb was NULL\n");
776  }
777 
778  if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_LIST_DIRECTORY)) {
779  WARN("insufficient privileges\n");
780  return STATUS_ACCESS_DENIED;
781  }
782 
783  Vcb = fcb->Vcb;
784 
785  if (!Vcb) {
786  ERR("Vcb was NULL\n");
788  }
789 
790  if (fileref->fcb == Vcb->dummy_fcb)
791  return STATUS_NO_MORE_FILES;
792 
793  if (IrpSp->Flags == 0) {
794  TRACE("QD flags: (none)\n");
795  } else {
796  ULONG flags = IrpSp->Flags;
797 
798  TRACE("QD flags:\n");
799 
800  if (flags & SL_INDEX_SPECIFIED) {
801  TRACE(" SL_INDEX_SPECIFIED\n");
803  }
804 
805  if (flags & SL_RESTART_SCAN) {
806  TRACE(" SL_RESTART_SCAN\n");
808  }
809 
811  TRACE(" SL_RETURN_SINGLE_ENTRY\n");
813  }
814 
815  if (flags != 0)
816  TRACE(" unknown flags: %lu\n", flags);
817  }
818 
819  if (IrpSp->Flags & SL_RESTART_SCAN) {
820  ccb->query_dir_offset = 0;
821 
822  if (ccb->query_string.Buffer) {
825  }
826 
827  ccb->has_wildcard = false;
828  ccb->specific_file = false;
829  }
830 
831  initial = !ccb->query_string.Buffer;
832 
833  if (IrpSp->Parameters.QueryDirectory.FileName && IrpSp->Parameters.QueryDirectory.FileName->Length > 1) {
834  TRACE("QD filename: %.*S\n", (int)(IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR)), IrpSp->Parameters.QueryDirectory.FileName->Buffer);
835 
836  if (IrpSp->Parameters.QueryDirectory.FileName->Length > sizeof(WCHAR) || IrpSp->Parameters.QueryDirectory.FileName->Buffer[0] != L'*') {
837  specific_file = true;
838 
839  if (FsRtlDoesNameContainWildCards(IrpSp->Parameters.QueryDirectory.FileName)) {
840  has_wildcard = true;
841  specific_file = false;
842  }
843  }
844 
845  if (ccb->query_string.Buffer)
847 
848  if (has_wildcard)
849  RtlUpcaseUnicodeString(&ccb->query_string, IrpSp->Parameters.QueryDirectory.FileName, true);
850  else {
851  ccb->query_string.Buffer = ExAllocatePoolWithTag(PagedPool, IrpSp->Parameters.QueryDirectory.FileName->Length, ALLOC_TAG);
852  if (!ccb->query_string.Buffer) {
853  ERR("out of memory\n");
855  }
856 
857  ccb->query_string.Length = ccb->query_string.MaximumLength = IrpSp->Parameters.QueryDirectory.FileName->Length;
858  RtlCopyMemory(ccb->query_string.Buffer, IrpSp->Parameters.QueryDirectory.FileName->Buffer, IrpSp->Parameters.QueryDirectory.FileName->Length);
859  }
860 
861  ccb->has_wildcard = has_wildcard;
862  ccb->specific_file = specific_file;
863  } else {
864  has_wildcard = ccb->has_wildcard;
865  specific_file = ccb->specific_file;
866 
867  if (!(IrpSp->Flags & SL_RESTART_SCAN)) {
868  initial = false;
869 
870  if (specific_file)
871  return STATUS_NO_MORE_FILES;
872  }
873  }
874 
875  if (ccb->query_string.Buffer) {
876  TRACE("query string = %.*S\n", (int)(ccb->query_string.Length / sizeof(WCHAR)), ccb->query_string.Buffer);
877  }
878 
879  newoffset = ccb->query_dir_offset;
880 
881  ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
882 
883  ExAcquireResourceSharedLite(&fileref->fcb->nonpaged->dir_children_lock, true);
884 
885  Status = next_dir_entry(fileref, &newoffset, &de, &dc);
886 
887  if (!NT_SUCCESS(Status)) {
888  if (Status == STATUS_NO_MORE_FILES && initial)
890  goto end;
891  }
892 
893  ccb->query_dir_offset = newoffset;
894 
896 
897  if (Irp->MdlAddress && !buf) {
898  ERR("MmGetSystemAddressForMdlSafe returned NULL\n");
900  goto end;
901  }
902 
903  length = IrpSp->Parameters.QueryDirectory.Length;
904 
905  if (specific_file) {
906  bool found = false;
908  LIST_ENTRY* le;
909  uint32_t hash;
910  uint8_t c;
911 
912  us.Buffer = NULL;
913 
914  if (!ccb->case_sensitive) {
916  if (!NT_SUCCESS(Status)) {
917  ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
918  goto end;
919  }
920 
921  hash = calc_crc32c(0xffffffff, (uint8_t*)us.Buffer, us.Length);
922  } else
924 
925  c = hash >> 24;
926 
927  if (ccb->case_sensitive) {
928  if (fileref->fcb->hash_ptrs[c]) {
929  le = fileref->fcb->hash_ptrs[c];
930  while (le != &fileref->fcb->dir_children_hash) {
931  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash);
932 
933  if (dc2->hash == hash) {
935  found = true;
936 
937  de.key = dc2->key;
938  de.name = dc2->name;
939  de.type = dc2->type;
941  de.dc = dc2;
942 
943  break;
944  }
945  } else if (dc2->hash > hash)
946  break;
947 
948  le = le->Flink;
949  }
950  }
951  } else {
952  if (fileref->fcb->hash_ptrs_uc[c]) {
953  le = fileref->fcb->hash_ptrs_uc[c];
954  while (le != &fileref->fcb->dir_children_hash_uc) {
955  dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
956 
957  if (dc2->hash_uc == hash) {
958  if (dc2->name_uc.Length == us.Length && RtlCompareMemory(dc2->name_uc.Buffer, us.Buffer, us.Length) == us.Length) {
959  found = true;
960 
961  de.key = dc2->key;
962  de.name = dc2->name;
963  de.type = dc2->type;
965  de.dc = dc2;
966 
967  break;
968  }
969  } else if (dc2->hash_uc > hash)
970  break;
971 
972  le = le->Flink;
973  }
974  }
975  }
976 
977  if (us.Buffer)
978  ExFreePool(us.Buffer);
979 
980  if (!found) {
982  goto end;
983  }
984  } else if (has_wildcard) {
986  newoffset = ccb->query_dir_offset;
987  Status = next_dir_entry(fileref, &newoffset, &de, &dc);
988 
989  if (NT_SUCCESS(Status))
990  ccb->query_dir_offset = newoffset;
991  else {
992  if (Status == STATUS_NO_MORE_FILES && initial)
994 
995  goto end;
996  }
997  }
998  }
999 
1000  TRACE("file(0) = %.*S\n", (int)(de.name.Length / sizeof(WCHAR)), de.name.Buffer);
1001  TRACE("offset = %I64u\n", ccb->query_dir_offset - 1);
1002 
1003  Status = query_dir_item(fcb, ccb, buf, &length, Irp, &de, fcb->subvol);
1004 
1005  count = 0;
1006  if (NT_SUCCESS(Status) && !(IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) && !specific_file) {
1007  lastitem = (uint8_t*)buf;
1008 
1009  while (length > 0) {
1010  switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
1011 #ifndef _MSC_VER
1012 #pragma GCC diagnostic push
1013 #pragma GCC diagnostic ignored "-Wswitch"
1014 #endif
1022  length -= length % 8;
1023  break;
1024 #ifndef _MSC_VER
1025 #pragma GCC diagnostic pop
1026 #endif
1027 
1028  case FileNamesInformation:
1029  length -= length % 4;
1030  break;
1031 
1032  default:
1033  WARN("unhandled file information class %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
1034  break;
1035  }
1036 
1037  if (length > 0) {
1038  newoffset = ccb->query_dir_offset;
1039  Status = next_dir_entry(fileref, &newoffset, &de, &dc);
1040  if (NT_SUCCESS(Status)) {
1041  if (!has_wildcard || FsRtlIsNameInExpression(&ccb->query_string, &de.name, !ccb->case_sensitive, NULL)) {
1042  curitem = (uint8_t*)buf + IrpSp->Parameters.QueryDirectory.Length - length;
1043  count++;
1044 
1045  TRACE("file(%lu) %Iu = %.*S\n", count, curitem - (uint8_t*)buf, (int)(de.name.Length / sizeof(WCHAR)), de.name.Buffer);
1046  TRACE("offset = %I64u\n", ccb->query_dir_offset - 1);
1047 
1048  status2 = query_dir_item(fcb, ccb, curitem, &length, Irp, &de, fcb->subvol);
1049 
1050  if (NT_SUCCESS(status2)) {
1051  ULONG* lastoffset = (ULONG*)lastitem;
1052 
1053  *lastoffset = (ULONG)(curitem - lastitem);
1054  ccb->query_dir_offset = newoffset;
1055 
1056  lastitem = curitem;
1057  } else
1058  break;
1059  } else
1060  ccb->query_dir_offset = newoffset;
1061  } else {
1064 
1065  break;
1066  }
1067  } else
1068  break;
1069  }
1070  }
1071 
1072  Irp->IoStatus.Information = IrpSp->Parameters.QueryDirectory.Length - length;
1073 
1074 end:
1075  ExReleaseResourceLite(&fileref->fcb->nonpaged->dir_children_lock);
1076 
1077  ExReleaseResourceLite(&Vcb->tree_lock);
1078 
1079  TRACE("returning %08lx\n", Status);
1080 
1081  return Status;
1082 }
1083 
1087  fcb* fcb = FileObject->FsContext;
1088  ccb* ccb = FileObject->FsContext2;
1089  file_ref* fileref = ccb ? ccb->fileref : NULL;
1090  NTSTATUS Status;
1091 
1092  TRACE("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
1093 
1094  if (!ccb) {
1095  ERR("ccb was NULL\n");
1096  return STATUS_INVALID_PARAMETER;
1097  }
1098 
1099  if (!fileref) {
1100  ERR("no fileref\n");
1101  return STATUS_INVALID_PARAMETER;
1102  }
1103 
1104  if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_LIST_DIRECTORY)) {
1105  WARN("insufficient privileges\n");
1106  return STATUS_ACCESS_DENIED;
1107  }
1108 
1109  ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true);
1110  ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
1111 
1112  if (fcb->type != BTRFS_TYPE_DIRECTORY) {
1114  goto end;
1115  }
1116 
1117  // FIXME - raise exception if FCB marked for deletion?
1118 
1119  TRACE("FileObject %p\n", FileObject);
1120 
1121  if (ccb->filename.Length == 0) {
1122  ULONG reqlen;
1123 
1125 
1126  Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen);
1127  if (Status == STATUS_BUFFER_OVERFLOW) {
1129  if (!ccb->filename.Buffer) {
1130  ERR("out of memory\n");
1132  goto end;
1133  }
1134 
1135  ccb->filename.MaximumLength = (uint16_t)reqlen;
1136 
1137  Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen);
1138  if (!NT_SUCCESS(Status)) {
1139  ERR("fileref_get_filename returned %08lx\n", Status);
1140  goto end;
1141  }
1142  } else {
1143  ERR("fileref_get_filename returned %08lx\n", Status);
1144  goto end;
1145  }
1146  }
1147 
1148  FsRtlNotifyFilterChangeDirectory(Vcb->NotifySync, &Vcb->DirNotifyList, FileObject->FsContext2, (PSTRING)&ccb->filename,
1149  IrpSp->Flags & SL_WATCH_TREE, false, IrpSp->Parameters.NotifyDirectory.CompletionFilter, Irp,
1150  NULL, NULL, NULL);
1151 
1153 
1154 end:
1155  ExReleaseResourceLite(fcb->Header.Resource);
1156  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
1157 
1158  return Status;
1159 }
1160 
1163 NTSTATUS __stdcall drv_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
1165  NTSTATUS Status;
1166  ULONG func;
1167  bool top_level;
1168  device_extension* Vcb = DeviceObject->DeviceExtension;
1169 
1171 
1172  TRACE("directory control\n");
1173 
1174  top_level = is_top_level(Irp);
1175 
1176  if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
1178  goto end;
1179  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
1181  goto end;
1182  }
1183 
1185 
1186  Irp->IoStatus.Information = 0;
1187 
1189 
1190  switch (func) {
1193  break;
1194 
1197  break;
1198 
1199  default:
1200  WARN("unknown minor %lu\n", func);
1202  Irp->IoStatus.Status = Status;
1203  break;
1204  }
1205 
1206  if (Status == STATUS_PENDING)
1207  goto exit;
1208 
1209 end:
1210  Irp->IoStatus.Status = Status;
1211 
1213 
1214 exit:
1215  TRACE("returning %08lx\n", Status);
1216 
1217  if (top_level)
1219 
1221 
1222  return Status;
1223 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
LARGE_INTEGER AllocationSize
Definition: iotypes.h:5703
struct _file_ref * parent
Definition: btrfs_drv.h:368
LARGE_INTEGER LastAccessTime
Definition: winternl.h:517
GLenum func
Definition: glext.h:6028
uint64_t obj_id
Definition: btrfs.h:137
LARGE_INTEGER AllocationSize
Definition: iotypes.h:5736
#define IN
Definition: typedefs.h:39
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _file_ref * fileref
Definition: btrfs_drv.h:271
uint8_t obj_type
Definition: btrfs.h:138
#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
#define FILE_ATTRIBUTE_SPARSE_FILE
Definition: ntifs_ex.h:380
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
BTRFS_TIME otime
Definition: btrfs.h:296
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1817
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1664
struct _FILE_ID_EXTD_DIR_INFORMATION FILE_ID_EXTD_DIR_INFORMATION
#define FsRtlExitFileSystem
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
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:4168
#define IO_REPARSE_TAG_LX_FIFO
Definition: btrfs_drv.h:125
UNICODE_STRING name_uc
Definition: btrfs_drv.h:269
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:88
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
GLuint GLuint GLsizei count
Definition: gl.h:1545
NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension *Vcb, root *subvol, uint64_t inode, uint8_t type, PANSI_STRING utf8, bool always_add_hl, fcb *parent, fcb **pfcb, POOL_TYPE pooltype, PIRP Irp)
Definition: create.c:699
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
GLintptr offset
Definition: glext.h:5920
struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION * PFILE_ID_EXTD_BOTH_DIR_INFORMATION
uint16_t size
Definition: btrfs_drv.h:430
uint8_t type
Definition: dirctrl.c:78
static NTSTATUS query_dir_item(fcb *fcb, ccb *ccb, void *buf, LONG *len, PIRP Irp, dir_entry *de, root *r)
Definition: dirctrl.c:185
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
Definition: ecma_167.h:138
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:312
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
uint32_t hash
Definition: btrfs_drv.h:266
enum DirEntryType dir_entry_type
Definition: dirctrl.c:79
#define VCB_TYPE_FS
Definition: btrfs_drv.h:695
DirEntryType
Definition: dirctrl.c:69
static NTSTATUS query_directory(PIRP Irp)
Definition: dirctrl.c:742
GLuint GLuint end
Definition: gl.h:1545
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:398
unsigned short int uint16_t
Definition: acefiex.h:54
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp)
Definition: read.c:2828
#define uint16_t
Definition: nsiface.idl:60
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define FileIdExtdDirectoryInformation
Definition: dirctrl.c:24
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:279
BTRFS_TIME st_ctime
Definition: btrfs.h:294
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
uint64_t offset
Definition: btrfs.h:139
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
uint8_t * data
Definition: btrfs_drv.h:431
bool has_wildcard
Definition: btrfs_drv.h:393
UNICODE_STRING filename
Definition: btrfs_drv.h:400
LARGE_INTEGER AllocationSize
Definition: dirctrl.c:35
UNICODE_STRING query_string
Definition: btrfs_drv.h:392
Definition: fs.h:78
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
struct _FILE_FULL_DIRECTORY_INFORMATION FILE_FULL_DIR_INFORMATION
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define ALLOC_TAG
Definition: btrfs_drv.h:91
LARGE_INTEGER ChangeTime
Definition: dirctrl.c:33
uint32_t hash_uc
Definition: btrfs_drv.h:268
LARGE_INTEGER ChangeTime
Definition: winternl.h:519
static __inline uint64_t make_file_id(root *r, uint64_t inode)
Definition: btrfs_drv.h:1020
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
LARGE_INTEGER LastWriteTime
Definition: from_kernel.h:143
int hash
Definition: main.c:58
uint64_t id
Definition: btrfs_drv.h:467
long LONG
Definition: pedump.c:60
LARGE_INTEGER EndOfFile
Definition: winternl.h:520
#define FIXME(fmt,...)
Definition: debug.h:111
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
bool root_dir
Definition: btrfs_drv.h:272
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
bool specific_file
Definition: btrfs_drv.h:394
ULONG get_reparse_tag_fcb(fcb *fcb)
Definition: dirctrl.c:83
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:329
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
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
#define FileIdExtdBothDirectoryInformation
Definition: dirctrl.c:25
_Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL)
Definition: dirctrl.c:1161
uint8_t type
Definition: btrfs_drv.h:302
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:588
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
BTRFS_TIME st_mtime
Definition: btrfs.h:295
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
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2930
LARGE_INTEGER LastWriteTime
Definition: iotypes.h:5733
ULONG ealen
Definition: btrfs_drv.h:314
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:294
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
uint64_t st_size
Definition: btrfs.h:282
#define TRACE(s)
Definition: solgame.cpp:4
LARGE_INTEGER EndOfFile
Definition: dirctrl.c:34
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:327
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:325
struct _fcb fcb
Definition: btrfs_drv.h:1357
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG get_file_attributes(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_ uint64_t inode, _In_ uint8_t type, _In_ bool dotfile, _In_ bool ignore_xa, _In_opt_ PIRP Irp)
Definition: btrfs.c:2600
#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
char CCHAR
Definition: typedefs.h:51
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:697
uint64_t inode
Definition: btrfs_drv.h:300
#define Vcb
Definition: cdprocs.h:1415
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:985
LARGE_INTEGER LastWriteTime
Definition: winternl.h:518
#define IO_REPARSE_TAG_LX_BLK
Definition: btrfs_drv.h:127
const GLubyte * c
Definition: glext.h:8905
UCHAR Identifier[16]
Definition: btrfs_drv.h:164
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LIST_ENTRY list_entry_index
Definition: btrfs_drv.h:273
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __stdcall
Definition: typedefs.h:25
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1978
GLbitfield flags
Definition: glext.h:7161
static NTSTATUS next_dir_entry(file_ref *fileref, uint64_t *offset, dir_entry *de, dir_child **pdc)
Definition: dirctrl.c:663
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _FILE_DIRECTORY_INFORMATION FILE_DIRECTORY_INFORMATION
BTRFS_TIME st_atime
Definition: btrfs.h:293
LARGE_INTEGER CreationTime
Definition: iotypes.h:5698
ULONG get_reparse_tag(device_extension *Vcb, root *subvol, uint64_t inode, uint8_t type, ULONG atts, bool lxss, PIRP Irp)
Definition: dirctrl.c:107
struct _FILE_NAMES_INFORMATION FILE_NAMES_INFORMATION
tree_data * item
Definition: btrfs_drv.h:518
LARGE_INTEGER LastAccessTime
Definition: dirctrl.c:31
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
Status
Definition: gdiplustypes.h:24
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:1819
bool case_sensitive
Definition: btrfs_drv.h:402
uint64_t index
Definition: btrfs_drv.h:263
#define TYPE_INODE_ITEM
Definition: btrfs.h:19
GLenum GLsizei len
Definition: glext.h:6722
crc_func calc_crc32c
Definition: crc32c.c:23
static ULONG get_ea_len(device_extension *Vcb, root *subvol, uint64_t inode, PIRP Irp)
Definition: dirctrl.c:148
fcb * fcb
Definition: btrfs_drv.h:357
Definition: typedefs.h:119
LARGE_INTEGER CreationTime
Definition: iotypes.h:5731
INODE_ITEM inode_item
Definition: btrfs_drv.h:303
DRIVER_DISPATCH(nfs41_FsdDispatch)
BYTE uint8_t
Definition: msvideo1.c:66
uint64_t st_blocks
Definition: btrfs.h:283
LARGE_INTEGER CreationTime
Definition: dirctrl.c:30
#define ERR(fmt,...)
Definition: debug.h:110
Definition: btrfs.h:136
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1816
const string EA_EA
Definition: recv.cpp:40
dir_child * dc
Definition: dirctrl.c:80
static unsigned __int64 next
Definition: rand_nt.c:6
UINT64 uint64_t
Definition: types.h:77
ULONG atts
Definition: btrfs_drv.h:308
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:295
#define IO_REPARSE_TAG_AF_UNIX
Definition: btrfs_drv.h:124
LARGE_INTEGER LastWriteTime
Definition: dirctrl.c:32
KEY key
Definition: dirctrl.c:76
uint8_t type
Definition: btrfs_drv.h:264
LARGE_INTEGER CreationTime
Definition: winternl.h:516
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define TYPE_ROOT_ITEM
Definition: btrfs.h:28
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
struct _root * subvol
Definition: btrfs_drv.h:299
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
#define IO_REPARSE_TAG_LX_CHR
Definition: btrfs_drv.h:126
UINT32 uint32_t
Definition: types.h:75
#define SL_RESTART_SCAN
Definition: iotypes.h:1815
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define EA_EA_HASH
Definition: btrfs_drv.h:107
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:85
struct _FILE_ID_EXTD_DIR_INFORMATION * PFILE_ID_EXTD_DIR_INFORMATION
Definition: dirctrl.c:75
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:997
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:328
static NTSTATUS notify_change_directory(device_extension *Vcb, PIRP Irp)
Definition: dirctrl.c:1084
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR dc[]
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:326
LARGE_INTEGER LastAccessTime
Definition: from_kernel.h:142
bool lxss
Definition: btrfs_drv.h:407
void exit(int exitcode)
Definition: _exit.c:33
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:399
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:524
return STATUS_SUCCESS
Definition: btrfs.c:3014
LARGE_INTEGER LastWriteTime
Definition: iotypes.h:5700
Definition: _hash_fun.h:40
uint64_t query_dir_offset
Definition: btrfs_drv.h:391
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7219
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
LARGE_INTEGER LastAccessTime
Definition: iotypes.h:5732
struct _device_extension * Vcb
Definition: btrfs_drv.h:298
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LARGE_INTEGER AllocationSize
Definition: winternl.h:521
UNICODE_STRING name
Definition: btrfs_drv.h:267
#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:356
#define _Function_class_(x)
Definition: no_sal2.h:202
_In_ uint16_t _Out_ ULONG * atts
Definition: btrfs_drv.h:1109
LONGLONG QuadPart
Definition: typedefs.h:114
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
UNICODE_STRING name
Definition: dirctrl.c:77
LARGE_INTEGER LastAccessTime
Definition: iotypes.h:5699
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION FILE_ID_EXTD_BOTH_DIR_INFORMATION
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