3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/dir.c
6 * PURPOSE: Directory functions
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* FUNCTIONS *****************************************************************/
26 NtNotifyChangeDirectoryFile (
28 IN HANDLE Event OPTIONAL
,
29 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
30 IN PVOID ApcContext OPTIONAL
,
31 OUT PIO_STATUS_BLOCK IoStatusBlock
,
34 IN ULONG CompletionFilter
,
39 PDEVICE_OBJECT DeviceObject
;
40 PFILE_OBJECT FileObject
;
42 PIO_STACK_LOCATION IoStack
;
43 KPROCESSOR_MODE PreviousMode
;
45 DPRINT("NtNotifyChangeDirectoryFile()\n");
47 PreviousMode
= ExGetPreviousMode();
49 Status
= ObReferenceObjectByHandle(FileHandle
,
56 if (Status
!= STATUS_SUCCESS
)
60 DeviceObject
= FileObject
->DeviceObject
;
62 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, TRUE
);
65 ObDereferenceObject(FileObject
);
66 return STATUS_UNSUCCESSFUL
;
71 Event
= &FileObject
->Event
;
74 /* Trigger FileObject/Event dereferencing */
75 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
76 Irp
->RequestorMode
= PreviousMode
;
77 Irp
->UserIosb
= IoStatusBlock
;
78 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
79 Irp
->UserEvent
= Event
;
80 KeResetEvent( Event
);
81 Irp
->UserBuffer
= Buffer
;
82 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
83 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
85 IoStack
= IoGetNextIrpStackLocation(Irp
);
87 IoStack
->MajorFunction
= IRP_MJ_DIRECTORY_CONTROL
;
88 IoStack
->MinorFunction
= IRP_MN_NOTIFY_CHANGE_DIRECTORY
;
91 IoStack
->DeviceObject
= DeviceObject
;
92 IoStack
->FileObject
= FileObject
;
96 IoStack
->Flags
= SL_WATCH_TREE
;
99 IoStack
->Parameters
.NotifyDirectory
.CompletionFilter
= CompletionFilter
;
100 IoStack
->Parameters
.NotifyDirectory
.Length
= BufferSize
;
102 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
104 /* FIXME: Should we wait here or not for synchronously opened files? */
115 NtQueryDirectoryFile(
116 IN HANDLE FileHandle
,
117 IN HANDLE PEvent OPTIONAL
,
118 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
119 IN PVOID ApcContext OPTIONAL
,
120 OUT PIO_STATUS_BLOCK IoStatusBlock
,
121 OUT PVOID FileInformation
,
123 IN FILE_INFORMATION_CLASS FileInformationClass
,
124 IN BOOLEAN ReturnSingleEntry
,
125 IN PUNICODE_STRING FileName OPTIONAL
,
126 IN BOOLEAN RestartScan
129 * FUNCTION: Queries a directory file.
131 * FileHandle = Handle to a directory file
132 * EventHandle = Handle to the event signaled on completion
133 * ApcRoutine = Asynchroneous procedure callback, called on completion
134 * ApcContext = Argument to the apc.
135 * IoStatusBlock = Caller supplies storage for extended status information.
136 * FileInformation = Caller supplies storage for the resulting information.
138 * FileNameInformation FILE_NAMES_INFORMATION
139 * FileDirectoryInformation FILE_DIRECTORY_INFORMATION
140 * FileFullDirectoryInformation FILE_FULL_DIRECTORY_INFORMATION
141 * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
143 * Length = Size of the storage supplied
144 * FileInformationClass = Indicates the type of information requested.
145 * ReturnSingleEntry = Specify true if caller only requests the first
147 * FileName = Initial directory name to query, that may contain wild
149 * RestartScan = Number of times the action should be repeated
150 * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
151 * STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
152 * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
156 PDEVICE_OBJECT DeviceObject
;
157 PFILE_OBJECT FileObject
;
159 PIO_STACK_LOCATION IoStack
;
160 KPROCESSOR_MODE PreviousMode
;
162 DPRINT("NtQueryDirectoryFile()\n");
164 PreviousMode
= ExGetPreviousMode();
166 Status
= ObReferenceObjectByHandle(FileHandle
,
170 (PVOID
*)&FileObject
,
173 if (Status
!= STATUS_SUCCESS
)
177 DeviceObject
= FileObject
->DeviceObject
;
179 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, TRUE
);
182 ObDereferenceObject(FileObject
);
183 return STATUS_UNSUCCESSFUL
;
186 /* Trigger FileObject/Event dereferencing */
187 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
188 Irp
->RequestorMode
= PreviousMode
;
189 Irp
->UserIosb
= IoStatusBlock
;
190 Irp
->UserEvent
= &FileObject
->Event
;
191 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
192 KeResetEvent( &FileObject
->Event
);
193 Irp
->UserBuffer
=FileInformation
;
194 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
195 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
197 IoStack
= IoGetNextIrpStackLocation(Irp
);
199 IoStack
->MajorFunction
= IRP_MJ_DIRECTORY_CONTROL
;
200 IoStack
->MinorFunction
= IRP_MN_QUERY_DIRECTORY
;
202 IoStack
->Control
= 0;
203 IoStack
->DeviceObject
= DeviceObject
;
204 IoStack
->FileObject
= FileObject
;
208 IoStack
->Flags
= IoStack
->Flags
| SL_RESTART_SCAN
;
210 if (ReturnSingleEntry
)
212 IoStack
->Flags
= IoStack
->Flags
| SL_RETURN_SINGLE_ENTRY
;
214 if (((PFILE_DIRECTORY_INFORMATION
)FileInformation
)->FileIndex
!= 0)
216 IoStack
->Flags
= IoStack
->Flags
| SL_INDEX_SPECIFIED
;
219 IoStack
->Parameters
.QueryDirectory
.FileInformationClass
=
220 FileInformationClass
;
221 IoStack
->Parameters
.QueryDirectory
.FileName
= FileName
;
222 IoStack
->Parameters
.QueryDirectory
.Length
= Length
;
224 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
225 if (Status
==STATUS_PENDING
&& !(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
227 KeWaitForSingleObject(&FileObject
->Event
,
230 FileObject
->Flags
& FO_ALERTABLE_IO
,
232 Status
= IoStatusBlock
->Status
;