ReactOS 0.4.16-dev-88-ga65b6ae
dirctrl.c File Reference
#include "btrfs_drv.h"
#include "crc32c.h"
Include dependency graph for dirctrl.c:

Go to the source code of this file.

Classes

struct  _FILE_ID_EXTD_DIR_INFORMATION
 
struct  _FILE_ID_EXTD_BOTH_DIR_INFORMATION
 
struct  dir_entry
 

Macros

#define FileIdExtdDirectoryInformation   (enum _FILE_INFORMATION_CLASS)60
 
#define FileIdExtdBothDirectoryInformation   (enum _FILE_INFORMATION_CLASS)63
 

Typedefs

typedef struct _FILE_ID_EXTD_DIR_INFORMATION FILE_ID_EXTD_DIR_INFORMATION
 
typedef struct _FILE_ID_EXTD_DIR_INFORMATIONPFILE_ID_EXTD_DIR_INFORMATION
 
typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION FILE_ID_EXTD_BOTH_DIR_INFORMATION
 
typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATIONPFILE_ID_EXTD_BOTH_DIR_INFORMATION
 

Enumerations

enum  DirEntryType { DirEntryType_File , DirEntryType_Self , DirEntryType_Parent }
 

Functions

ULONG get_reparse_tag_fcb (fcb *fcb)
 
ULONG get_reparse_tag (device_extension *Vcb, root *subvol, uint64_t inode, uint8_t type, ULONG atts, bool lxss, PIRP Irp)
 
static ULONG get_ea_len (device_extension *Vcb, root *subvol, uint64_t inode, PIRP Irp)
 
static NTSTATUS query_dir_item (fcb *fcb, ccb *ccb, void *buf, LONG *len, PIRP Irp, dir_entry *de, root *r)
 
static NTSTATUS next_dir_entry (file_ref *fileref, uint64_t *offset, dir_entry *de, dir_child **pdc)
 
static NTSTATUS query_directory (PIRP Irp)
 
static NTSTATUS notify_change_directory (device_extension *Vcb, PIRP Irp)
 
 _Dispatch_type_ (IRP_MJ_DIRECTORY_CONTROL)
 

Macro Definition Documentation

◆ FileIdExtdBothDirectoryInformation

#define FileIdExtdBothDirectoryInformation   (enum _FILE_INFORMATION_CLASS)63

Definition at line 25 of file dirctrl.c.

◆ FileIdExtdDirectoryInformation

#define FileIdExtdDirectoryInformation   (enum _FILE_INFORMATION_CLASS)60

Definition at line 24 of file dirctrl.c.

Typedef Documentation

◆ FILE_ID_EXTD_BOTH_DIR_INFORMATION

◆ FILE_ID_EXTD_DIR_INFORMATION

◆ PFILE_ID_EXTD_BOTH_DIR_INFORMATION

◆ PFILE_ID_EXTD_DIR_INFORMATION

Enumeration Type Documentation

◆ DirEntryType

Enumerator
DirEntryType_File 
DirEntryType_Self 
DirEntryType_Parent 

Definition at line 69 of file dirctrl.c.

69 {
73};
@ DirEntryType_File
Definition: dirctrl.c:70
@ DirEntryType_Parent
Definition: dirctrl.c:72
@ DirEntryType_Self
Definition: dirctrl.c:71

Function Documentation

◆ _Dispatch_type_()

_Dispatch_type_ ( IRP_MJ_DIRECTORY_CONTROL  )

Definition at line 1157 of file dirctrl.c.

1159 {
1162 ULONG func;
1163 bool top_level;
1164 device_extension* Vcb = DeviceObject->DeviceExtension;
1165
1167
1168 TRACE("directory control\n");
1169
1170 top_level = is_top_level(Irp);
1171
1172 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
1174 goto end;
1175 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
1177 goto end;
1178 }
1179
1181
1182 Irp->IoStatus.Information = 0;
1183
1185
1186 switch (func) {
1189 break;
1190
1193 break;
1194
1195 default:
1196 WARN("unknown minor %lu\n", func);
1198 Irp->IoStatus.Status = Status;
1199 break;
1200 }
1201
1202 if (Status == STATUS_PENDING)
1203 goto exit;
1204
1205end:
1206 Irp->IoStatus.Status = Status;
1207
1209
1210exit:
1211 TRACE("returning %08lx\n", Status);
1212
1213 if (top_level)
1215
1217
1218 return Status;
1219}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: precomp.h:61
static NTSTATUS query_directory(PIRP Irp)
Definition: dirctrl.c:737
static NTSTATUS notify_change_directory(device_extension *Vcb, PIRP Irp)
Definition: dirctrl.c:1080
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:689
#define VCB_TYPE_FS
Definition: btrfs_drv.h:687
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:278
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
GLuint GLuint end
Definition: gl.h:1545
GLenum func
Definition: glext.h:6028
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define Vcb
Definition: cdprocs.h:1415
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
#define exit(n)
Definition: config.h:202
#define TRACE(s)
Definition: solgame.cpp:4
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

◆ get_ea_len()

static ULONG get_ea_len ( device_extension Vcb,
root subvol,
uint64_t  inode,
PIRP  Irp 
)
static

Definition at line 148 of file dirctrl.c.

148 {
149 uint8_t* eadata;
151
152 if (get_xattr(Vcb, subvol, inode, EA_EA, EA_EA_HASH, &eadata, &len, Irp)) {
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 {
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}
unsigned short int uint16_t
Definition: acefiex.h:54
#define EA_EA
Definition: btrfs_drv.h:102
#define EA_EA_HASH
Definition: btrfs_drv.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
BYTE uint8_t
Definition: msvideo1.c:66
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
Definition: fs.h:78

Referenced by query_dir_item().

◆ get_reparse_tag()

ULONG get_reparse_tag ( device_extension Vcb,
root subvol,
uint64_t  inode,
uint8_t  type,
ULONG  atts,
bool  lxss,
PIRP  Irp 
)

Definition at line 107 of file dirctrl.c.

107 {
108 fcb* fcb;
109 ULONG tag = 0;
111
114 else if (lxss) {
115 if (type == BTRFS_TYPE_SOCKET)
117 else if (type == BTRFS_TYPE_FIFO)
119 else if (type == BTRFS_TYPE_CHARDEV)
121 else if (type == BTRFS_TYPE_BLOCKDEV)
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
142
143 free_fcb(fcb);
144
145 return tag;
146}
#define ERR(fmt,...)
Definition: precomp.h:57
ULONG get_reparse_tag_fcb(fcb *fcb)
Definition: dirctrl.c:83
#define IO_REPARSE_TAG_AF_UNIX
Definition: btrfs_drv.h:120
struct _fcb fcb
Definition: btrfs_drv.h:1364
_In_ uint16_t _Out_ ULONG * atts
Definition: btrfs_drv.h:1107
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:706
#define IO_REPARSE_TAG_LX_CHR
Definition: btrfs_drv.h:122
#define IO_REPARSE_TAG_LX_BLK
Definition: btrfs_drv.h:123
#define IO_REPARSE_TAG_LX_FIFO
Definition: btrfs_drv.h:121
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1734
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define BTRFS_TYPE_FILE
Definition: shellext.h:85
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
#define BTRFS_TYPE_SOCKET
Definition: shellext.h:90
#define BTRFS_TYPE_FIFO
Definition: shellext.h:89
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
#define BTRFS_TYPE_CHARDEV
Definition: shellext.h:87
#define BTRFS_TYPE_BLOCKDEV
Definition: shellext.h:88
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
Definition: ecma_167.h:138
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240

Referenced by query_dir_item().

◆ get_reparse_tag_fcb()

ULONG get_reparse_tag_fcb ( fcb fcb)

Definition at line 83 of file dirctrl.c.

83 {
84 ULONG tag;
85
88 else if (fcb->type == BTRFS_TYPE_DIRECTORY) {
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}
NTSTATUS read_file(fcb *fcb, uint8_t *data, uint64_t start, uint64_t length, ULONG *pbr, PIRP Irp) __attribute__((nonnull(1
uint8_t type
Definition: btrfs_drv.h:291
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by fill_in_file_attribute_information(), fill_in_file_stat_information(), fill_in_file_stat_lx_information(), and get_reparse_tag().

◆ next_dir_entry()

static NTSTATUS next_dir_entry ( file_ref fileref,
uint64_t offset,
dir_entry de,
dir_child **  pdc 
)
static

Definition at line 651 of file dirctrl.c.

651 {
652 LIST_ENTRY* le;
653 dir_child* dc;
654
655 if (*pdc) {
656 dir_child* dc2 = *pdc;
657
658 if (dc2->list_entry_index.Flink != &fileref->fcb->dir_children_index)
659 dc = CONTAINING_RECORD(dc2->list_entry_index.Flink, dir_child, list_entry_index);
660 else
661 dc = NULL;
662
663 goto next;
664 }
665
666 if (fileref->parent) { // don't return . and .. if root directory
667 if (*offset == 0) {
668 de->key.obj_id = fileref->fcb->inode;
670 de->key.offset = 0;
672 de->name.Buffer = L".";
673 de->name.Length = de->name.MaximumLength = sizeof(WCHAR);
675
676 *offset = 1;
677 *pdc = NULL;
678
679 return STATUS_SUCCESS;
680 } else if (*offset == 1) {
681 de->key.obj_id = fileref->parent->fcb->inode;
683 de->key.offset = 0;
685 de->name.Buffer = L"..";
686 de->name.Length = de->name.MaximumLength = sizeof(WCHAR) * 2;
688
689 *offset = 2;
690 *pdc = NULL;
691
692 return STATUS_SUCCESS;
693 }
694 }
695
696 if (*offset < 2)
697 *offset = 2;
698
699 dc = NULL;
700 le = fileref->fcb->dir_children_index.Flink;
701
702 // skip entries before offset
703 while (le != &fileref->fcb->dir_children_index) {
704 dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_index);
705
706 if (dc2->index >= *offset) {
707 dc = dc2;
708 break;
709 }
710
711 le = le->Flink;
712 }
713
714next:
715 if (!dc)
717
718 if (dc->root_dir && fileref->parent) { // hide $Root dir unless in apparent root, to avoid recursion
719 if (dc->list_entry_index.Flink == &fileref->fcb->dir_children_index)
721
722 dc = CONTAINING_RECORD(dc->list_entry_index.Flink, dir_child, list_entry_index);
723 }
724
725 de->key = dc->key;
726 de->name = dc->name;
727 de->type = dc->type;
729 de->dc = dc;
730
731 *offset = dc->index + 1;
732 *pdc = dc;
733
734 return STATUS_SUCCESS;
735}
#define TYPE_INODE_ITEM
Definition: btrfs.h:23
static const WCHAR dc[]
#define L(x)
Definition: ntvdm.h:50
static unsigned __int64 next
Definition: rand_nt.c:6
#define STATUS_SUCCESS
Definition: shellext.h:65
uint8_t obj_type
Definition: btrfs.h:145
uint64_t obj_id
Definition: btrfs.h:144
uint64_t offset
Definition: btrfs.h:146
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:314
uint64_t inode
Definition: btrfs_drv.h:289
struct _file_ref * parent
Definition: btrfs_drv.h:352
fcb * fcb
Definition: btrfs_drv.h:342
uint64_t index
Definition: btrfs_drv.h:252
LIST_ENTRY list_entry_index
Definition: btrfs_drv.h:262
enum DirEntryType dir_entry_type
Definition: dirctrl.c:79
KEY key
Definition: dirctrl.c:76
dir_child * dc
Definition: dirctrl.c:80
uint8_t type
Definition: dirctrl.c:78
UNICODE_STRING name
Definition: dirctrl.c:77
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by query_directory().

◆ notify_change_directory()

static NTSTATUS notify_change_directory ( device_extension Vcb,
PIRP  Irp 
)
static

Definition at line 1080 of file dirctrl.c.

1080 {
1083 fcb* fcb = FileObject->FsContext;
1084 ccb* ccb = FileObject->FsContext2;
1085 file_ref* fileref = ccb ? ccb->fileref : NULL;
1087
1088 TRACE("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
1089
1090 if (!ccb) {
1091 ERR("ccb was NULL\n");
1093 }
1094
1095 if (!fileref) {
1096 ERR("no fileref\n");
1098 }
1099
1100 if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_LIST_DIRECTORY)) {
1101 WARN("insufficient privileges\n");
1102 return STATUS_ACCESS_DENIED;
1103 }
1104
1105 ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true);
1106 ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
1107
1108 if (fcb->type != BTRFS_TYPE_DIRECTORY) {
1110 goto end;
1111 }
1112
1113 // FIXME - raise exception if FCB marked for deletion?
1114
1115 TRACE("FileObject %p\n", FileObject);
1116
1117 if (ccb->filename.Length == 0) {
1118 ULONG reqlen;
1119
1121
1122 Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen);
1125 if (!ccb->filename.Buffer) {
1126 ERR("out of memory\n");
1128 goto end;
1129 }
1130
1132
1133 Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen);
1134 if (!NT_SUCCESS(Status)) {
1135 ERR("fileref_get_filename returned %08lx\n", Status);
1136 goto end;
1137 }
1138 } else {
1139 ERR("fileref_get_filename returned %08lx\n", Status);
1140 goto end;
1141 }
1142 }
1143
1144 FsRtlNotifyFilterChangeDirectory(Vcb->NotifySync, &Vcb->DirNotifyList, FileObject->FsContext2, (PSTRING)&ccb->filename,
1145 IrpSp->Flags & SL_WATCH_TREE, false, IrpSp->Parameters.NotifyDirectory.CompletionFilter, Irp,
1146 NULL, NULL, NULL);
1147
1149
1150end:
1151 ExReleaseResourceLite(fcb->Header.Resource);
1152 ExReleaseResourceLite(&fcb->Vcb->tree_lock);
1153
1154 return Status;
1155}
#define ALLOC_TAG
Definition: btrfs_drv.h:87
NTSTATUS fileref_get_filename(file_ref *fileref, PUNICODE_STRING fn, USHORT *name_offset, ULONG *preqlen)
Definition: fileinfo.c:4245
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define UserMode
Definition: asm.h:35
#define uint16_t
Definition: nsiface.idl:60
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
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:773
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _IO_STACK_LOCATION::@3974::@3981 NotifyDirectory
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1575 Parameters
ACCESS_MASK access
Definition: btrfs_drv.h:382
UNICODE_STRING filename
Definition: btrfs_drv.h:384
file_ref * fileref
Definition: btrfs_drv.h:383
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define SL_WATCH_TREE
Definition: iotypes.h:1839
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by _Dispatch_type_().

◆ query_dir_item()

static NTSTATUS query_dir_item ( fcb fcb,
ccb ccb,
void buf,
LONG len,
PIRP  Irp,
dir_entry de,
root r 
)
static

Definition at line 185 of file dirctrl.c.

185 {
187 LONG needed;
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) {
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);
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 ||
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 ||
288 ealen = get_ea_len(fcb->Vcb, r, inode, Irp);
289 }
290 }
291 }
292
293 break;
294 }
295
297 ii = fcb->inode_item;
298 r = fcb->subvol;
299 inode = fcb->inode;
300 atts = fcb->atts;
301 ealen = fcb->ealen;
302 break;
303
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");
314 }
315 break;
316 }
317
318 if (atts == 0)
320 }
321
322 switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
324 {
326
327 TRACE("FileBothDirectoryInformation\n");
328
330
331 if (needed > *len) {
332 TRACE("buffer overflow - %li > %lu\n", needed, *len);
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;
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
370
371 if (needed > *len) {
372 TRACE("buffer overflow - %li > %lu\n", needed, *len);
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;
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
395
396 *len -= needed;
397
398 return STATUS_SUCCESS;
399 }
400
402 {
404
405 TRACE("FileFullDirectoryInformation\n");
406
408
409 if (needed > *len) {
410 TRACE("buffer overflow - %li > %lu\n", needed, *len);
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;
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
447
448 if (needed > *len) {
449 TRACE("buffer overflow - %li > %lu\n", needed, *len);
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;
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
488
489 if (needed > *len) {
490 TRACE("buffer overflow - %li > %lu\n", needed, *len);
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;
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);
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;
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;
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);
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;
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;
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
626
627 if (needed > *len) {
628 TRACE("buffer overflow - %li > %lu\n", needed, *len);
630 }
631
632 fni->NextEntryOffset = 0;
633 fni->FileIndex = 0;
634 fni->FileNameLength = de->name.Length;
635
637
638 *len -= needed;
639
640 return STATUS_SUCCESS;
641 }
642
643 default:
644 WARN("Unknown FileInformationClass %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
646 }
647
649}
#define FileIdExtdDirectoryInformation
Definition: dirctrl.c:24
static ULONG get_ea_len(device_extension *Vcb, root *subvol, uint64_t inode, PIRP Irp)
Definition: dirctrl.c:148
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
#define FileIdExtdBothDirectoryInformation
Definition: dirctrl.c:25
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:989
static __inline uint64_t make_file_id(root *r, uint64_t inode)
Definition: btrfs_drv.h:1012
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
UINT64 uint64_t
Definition: types.h:77
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
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:2664
#define TYPE_ROOT_ITEM
Definition: btrfs.h:32
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
@ FileIdFullDirectoryInformation
Definition: from_kernel.h:99
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
__u16 time
Definition: mkdosfs.c:8
#define min(a, b)
Definition: monoChain.cc:55
#define FILE_ATTRIBUTE_SPARSE_FILE
Definition: ntifs_ex.h:380
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
long LONG
Definition: pedump.c:60
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
static __inline uint64_t unix_time_to_win(BTRFS_TIME *t)
Definition: recv.cpp:1070
#define offsetof(TYPE, MEMBER)
BTRFS_TIME otime
Definition: btrfs.h:304
BTRFS_TIME st_mtime
Definition: btrfs.h:303
uint64_t st_size
Definition: btrfs.h:289
BTRFS_TIME st_atime
Definition: btrfs.h:301
uint64_t st_blocks
Definition: btrfs.h:290
BTRFS_TIME st_ctime
Definition: btrfs.h:302
Definition: btrfs.h:143
LARGE_INTEGER CreationTime
Definition: from_kernel.h:141
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
LARGE_INTEGER LastAccessTime
Definition: from_kernel.h:142
LARGE_INTEGER LastWriteTime
Definition: from_kernel.h:143
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:524
LARGE_INTEGER ChangeTime
Definition: winternl.h:519
LARGE_INTEGER EndOfFile
Definition: winternl.h:520
LARGE_INTEGER CreationTime
Definition: winternl.h:516
LARGE_INTEGER LastWriteTime
Definition: winternl.h:518
LARGE_INTEGER LastAccessTime
Definition: winternl.h:517
LARGE_INTEGER AllocationSize
Definition: winternl.h:521
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:539
UCHAR Identifier[16]
Definition: btrfs_drv.h:162
LARGE_INTEGER LastWriteTime
Definition: iotypes.h:5754
LARGE_INTEGER LastAccessTime
Definition: iotypes.h:5753
LARGE_INTEGER AllocationSize
Definition: iotypes.h:5757
LARGE_INTEGER CreationTime
Definition: iotypes.h:5752
LARGE_INTEGER EndOfFile
Definition: dirctrl.c:34
LARGE_INTEGER ChangeTime
Definition: dirctrl.c:33
LARGE_INTEGER LastAccessTime
Definition: dirctrl.c:31
LARGE_INTEGER LastWriteTime
Definition: dirctrl.c:32
LARGE_INTEGER AllocationSize
Definition: dirctrl.c:35
LARGE_INTEGER CreationTime
Definition: dirctrl.c:30
LARGE_INTEGER LastAccessTime
Definition: iotypes.h:5720
LARGE_INTEGER AllocationSize
Definition: iotypes.h:5724
LARGE_INTEGER CreationTime
Definition: iotypes.h:5719
LARGE_INTEGER LastWriteTime
Definition: iotypes.h:5721
struct _IO_STACK_LOCATION::@3974::@3980 QueryDirectory
bool lxss
Definition: btrfs_drv.h:391
ULONG ealen
Definition: btrfs_drv.h:303
ULONG atts
Definition: btrfs_drv.h:297
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
struct _root * subvol
Definition: btrfs_drv.h:288
uint64_t id
Definition: btrfs_drv.h:451
uint8_t * data
Definition: btrfs_drv.h:415
uint16_t size
Definition: btrfs_drv.h:414
bool root_dir
Definition: btrfs_drv.h:261
struct _file_ref * fileref
Definition: btrfs_drv.h:260
Definition: list.h:27
tree_data * item
Definition: btrfs_drv.h:509
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by query_directory().

◆ query_directory()

static NTSTATUS query_directory ( PIRP  Irp)
static

Definition at line 737 of file dirctrl.c.

737 {
739 NTSTATUS Status, status2;
740 fcb* fcb;
741 ccb* ccb;
742 file_ref* fileref;
744 void* buf;
745 uint8_t *curitem, *lastitem;
746 LONG length;
747 ULONG count;
748 bool has_wildcard = false, specific_file = false, initial;
749 dir_entry de;
750 uint64_t newoffset;
751 dir_child* dc = NULL;
752
753 TRACE("query directory\n");
754
756 fcb = IrpSp->FileObject->FsContext;
757 ccb = IrpSp->FileObject->FsContext2;
758 fileref = ccb ? ccb->fileref : NULL;
759
760 if (!fileref)
762
763 if (!ccb) {
764 ERR("ccb was NULL\n");
766 }
767
768 if (!fcb) {
769 ERR("fcb was NULL\n");
771 }
772
773 if (Irp->RequestorMode == UserMode && !(ccb->access & FILE_LIST_DIRECTORY)) {
774 WARN("insufficient privileges\n");
776 }
777
778 Vcb = fcb->Vcb;
779
780 if (!Vcb) {
781 ERR("Vcb was NULL\n");
783 }
784
785 if (fileref->fcb == Vcb->dummy_fcb)
787
788 if (IrpSp->Flags == 0) {
789 TRACE("QD flags: (none)\n");
790 } else {
792
793 TRACE("QD flags:\n");
794
796 TRACE(" SL_INDEX_SPECIFIED\n");
797 flags &= ~SL_INDEX_SPECIFIED;
798 }
799
800 if (flags & SL_RESTART_SCAN) {
801 TRACE(" SL_RESTART_SCAN\n");
802 flags &= ~SL_RESTART_SCAN;
803 }
804
806 TRACE(" SL_RETURN_SINGLE_ENTRY\n");
807 flags &= ~SL_RETURN_SINGLE_ENTRY;
808 }
809
810 if (flags != 0)
811 TRACE(" unknown flags: %lu\n", flags);
812 }
813
814 if (IrpSp->Flags & SL_RESTART_SCAN) {
816
817 if (ccb->query_string.Buffer) {
820 }
821
822 ccb->has_wildcard = false;
823 ccb->specific_file = false;
824 }
825
826 initial = !ccb->query_string.Buffer;
827
828 if (IrpSp->Parameters.QueryDirectory.FileName && IrpSp->Parameters.QueryDirectory.FileName->Length > 1) {
829 TRACE("QD filename: %.*S\n", (int)(IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR)), IrpSp->Parameters.QueryDirectory.FileName->Buffer);
830
831 if (IrpSp->Parameters.QueryDirectory.FileName->Length > sizeof(WCHAR) || IrpSp->Parameters.QueryDirectory.FileName->Buffer[0] != L'*') {
832 specific_file = true;
833
835 has_wildcard = true;
836 specific_file = false;
837 } else if (!initial)
839 }
840
843
844 if (has_wildcard)
846 else {
848 if (!ccb->query_string.Buffer) {
849 ERR("out of memory\n");
851 }
852
855 }
856
857 ccb->has_wildcard = has_wildcard;
858 ccb->specific_file = specific_file;
859 } else {
860 has_wildcard = ccb->has_wildcard;
861 specific_file = ccb->specific_file;
862
863 if (!(IrpSp->Flags & SL_RESTART_SCAN)) {
864 initial = false;
865
866 if (specific_file)
868 }
869 }
870
871 if (ccb->query_string.Buffer) {
872 TRACE("query string = %.*S\n", (int)(ccb->query_string.Length / sizeof(WCHAR)), ccb->query_string.Buffer);
873 }
874
875 newoffset = ccb->query_dir_offset;
876
877 ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
878
879 ExAcquireResourceSharedLite(&fileref->fcb->nonpaged->dir_children_lock, true);
880
881 Status = next_dir_entry(fileref, &newoffset, &de, &dc);
882
883 if (!NT_SUCCESS(Status)) {
884 if (Status == STATUS_NO_MORE_FILES && initial)
886 goto end;
887 }
888
889 ccb->query_dir_offset = newoffset;
890
892
893 if (Irp->MdlAddress && !buf) {
894 ERR("MmGetSystemAddressForMdlSafe returned NULL\n");
896 goto end;
897 }
898
900
901 if (specific_file) {
902 bool found = false;
904 LIST_ENTRY* le;
906 uint8_t c;
907
908 us.Buffer = NULL;
909
910 if (!ccb->case_sensitive) {
912 if (!NT_SUCCESS(Status)) {
913 ERR("RtlUpcaseUnicodeString returned %08lx\n", Status);
914 goto end;
915 }
916
917 hash = calc_crc32c(0xffffffff, (uint8_t*)us.Buffer, us.Length);
918 } else
920
921 c = hash >> 24;
922
923 if (ccb->case_sensitive) {
924 if (fileref->fcb->hash_ptrs[c]) {
925 le = fileref->fcb->hash_ptrs[c];
926 while (le != &fileref->fcb->dir_children_hash) {
927 dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash);
928
929 if (dc2->hash == hash) {
931 found = true;
932
933 de.key = dc2->key;
934 de.name = dc2->name;
935 de.type = dc2->type;
937 de.dc = dc2;
938
939 break;
940 }
941 } else if (dc2->hash > hash)
942 break;
943
944 le = le->Flink;
945 }
946 }
947 } else {
948 if (fileref->fcb->hash_ptrs_uc[c]) {
949 le = fileref->fcb->hash_ptrs_uc[c];
950 while (le != &fileref->fcb->dir_children_hash_uc) {
951 dir_child* dc2 = CONTAINING_RECORD(le, dir_child, list_entry_hash_uc);
952
953 if (dc2->hash_uc == hash) {
954 if (dc2->name_uc.Length == us.Length && RtlCompareMemory(dc2->name_uc.Buffer, us.Buffer, us.Length) == us.Length) {
955 found = true;
956
957 de.key = dc2->key;
958 de.name = dc2->name;
959 de.type = dc2->type;
961 de.dc = dc2;
962
963 break;
964 }
965 } else if (dc2->hash_uc > hash)
966 break;
967
968 le = le->Flink;
969 }
970 }
971 }
972
973 if (us.Buffer)
974 ExFreePool(us.Buffer);
975
976 if (!found) {
978 goto end;
979 }
980 } else if (has_wildcard) {
982 newoffset = ccb->query_dir_offset;
983 Status = next_dir_entry(fileref, &newoffset, &de, &dc);
984
985 if (NT_SUCCESS(Status))
986 ccb->query_dir_offset = newoffset;
987 else {
988 if (Status == STATUS_NO_MORE_FILES && initial)
990
991 goto end;
992 }
993 }
994 }
995
996 TRACE("file(0) = %.*S\n", (int)(de.name.Length / sizeof(WCHAR)), de.name.Buffer);
997 TRACE("offset = %I64u\n", ccb->query_dir_offset - 1);
998
1000
1001 count = 0;
1002 if (NT_SUCCESS(Status) && !(IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) && !specific_file) {
1003 lastitem = (uint8_t*)buf;
1004
1005 while (length > 0) {
1006 switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
1007#ifndef _MSC_VER
1008#pragma GCC diagnostic push
1009#pragma GCC diagnostic ignored "-Wswitch"
1010#endif
1018 length -= length % 8;
1019 break;
1020#ifndef _MSC_VER
1021#pragma GCC diagnostic pop
1022#endif
1023
1025 length -= length % 4;
1026 break;
1027
1028 default:
1029 WARN("unhandled file information class %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
1030 break;
1031 }
1032
1033 if (length > 0) {
1034 newoffset = ccb->query_dir_offset;
1035 Status = next_dir_entry(fileref, &newoffset, &de, &dc);
1036 if (NT_SUCCESS(Status)) {
1037 if (!has_wildcard || FsRtlIsNameInExpression(&ccb->query_string, &de.name, !ccb->case_sensitive, NULL)) {
1038 curitem = (uint8_t*)buf + IrpSp->Parameters.QueryDirectory.Length - length;
1039 count++;
1040
1041 TRACE("file(%lu) %Iu = %.*S\n", count, curitem - (uint8_t*)buf, (int)(de.name.Length / sizeof(WCHAR)), de.name.Buffer);
1042 TRACE("offset = %I64u\n", ccb->query_dir_offset - 1);
1043
1044 status2 = query_dir_item(fcb, ccb, curitem, &length, Irp, &de, fcb->subvol);
1045
1046 if (NT_SUCCESS(status2)) {
1047 ULONG* lastoffset = (ULONG*)lastitem;
1048
1049 *lastoffset = (ULONG)(curitem - lastitem);
1050 ccb->query_dir_offset = newoffset;
1051
1052 lastitem = curitem;
1053 } else
1054 break;
1055 } else
1056 ccb->query_dir_offset = newoffset;
1057 } else {
1060
1061 break;
1062 }
1063 } else
1064 break;
1065 }
1066 }
1067
1068 Irp->IoStatus.Information = IrpSp->Parameters.QueryDirectory.Length - length;
1069
1070end:
1071 ExReleaseResourceLite(&fileref->fcb->nonpaged->dir_children_lock);
1072
1073 ExReleaseResourceLite(&Vcb->tree_lock);
1074
1075 TRACE("returning %08lx\n", Status);
1076
1077 return Status;
1078}
static NTSTATUS query_dir_item(fcb *fcb, ccb *ccb, void *buf, LONG *len, PIRP Irp, dir_entry *de, root *r)
Definition: dirctrl.c:185
static NTSTATUS next_dir_entry(file_ref *fileref, uint64_t *offset, dir_entry *de, dir_child **pdc)
Definition: dirctrl.c:651
struct _ccb ccb
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:977
crc_func calc_crc32c
Definition: crc32c.c:23
UINT32 uint32_t
Definition: types.h:75
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
GLuint GLuint GLsizei count
Definition: gl.h:1545
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define c
Definition: ke_i.h:80
@ NormalPagePriority
Definition: imports.h:54
static const BYTE us[]
Definition: encode.c:689
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
uint64_t query_dir_offset
Definition: btrfs_drv.h:375
UNICODE_STRING query_string
Definition: btrfs_drv.h:376
bool specific_file
Definition: btrfs_drv.h:378
bool case_sensitive
Definition: btrfs_drv.h:386
bool has_wildcard
Definition: btrfs_drv.h:377
LIST_ENTRY dir_children_hash
Definition: btrfs_drv.h:315
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:318
LIST_ENTRY dir_children_hash_uc
Definition: btrfs_drv.h:316
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:317
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
UNICODE_STRING name
Definition: btrfs_drv.h:256
uint32_t hash
Definition: btrfs_drv.h:255
UNICODE_STRING name_uc
Definition: btrfs_drv.h:258
uint8_t type
Definition: btrfs_drv.h:253
uint32_t hash_uc
Definition: btrfs_drv.h:257
Definition: dirctrl.c:75
Definition: _hash_fun.h:40
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
#define SL_RESTART_SCAN
Definition: iotypes.h:1835

Referenced by _Dispatch_type_().