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
;
41 PIO_STACK_LOCATION IoStack
;
42 KPROCESSOR_MODE PreviousMode
;
43 NTSTATUS Status
= STATUS_SUCCESS
;
45 DPRINT("NtNotifyChangeDirectoryFile()\n");
49 PreviousMode
= ExGetPreviousMode();
51 if(PreviousMode
!= KernelMode
)
55 ProbeForWrite(IoStatusBlock
,
56 sizeof(IO_STATUS_BLOCK
),
67 Status
= _SEH_GetExceptionCode();
71 if(!NT_SUCCESS(Status
))
77 Status
= ObReferenceObjectByHandle(FileHandle
,
84 if (Status
!= STATUS_SUCCESS
)
88 DeviceObject
= FileObject
->DeviceObject
;
90 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, TRUE
);
93 ObDereferenceObject(FileObject
);
94 return STATUS_UNSUCCESSFUL
;
99 Event
= &FileObject
->Event
;
102 /* Trigger FileObject/Event dereferencing */
103 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
104 Irp
->RequestorMode
= PreviousMode
;
105 Irp
->UserIosb
= IoStatusBlock
;
106 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
107 Irp
->UserEvent
= Event
;
108 KeResetEvent( Event
);
109 Irp
->UserBuffer
= Buffer
;
110 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
111 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
113 IoStack
= IoGetNextIrpStackLocation(Irp
);
115 IoStack
->MajorFunction
= IRP_MJ_DIRECTORY_CONTROL
;
116 IoStack
->MinorFunction
= IRP_MN_NOTIFY_CHANGE_DIRECTORY
;
118 IoStack
->Control
= 0;
119 IoStack
->DeviceObject
= DeviceObject
;
120 IoStack
->FileObject
= FileObject
;
124 IoStack
->Flags
= SL_WATCH_TREE
;
127 IoStack
->Parameters
.NotifyDirectory
.CompletionFilter
= CompletionFilter
;
128 IoStack
->Parameters
.NotifyDirectory
.Length
= BufferSize
;
130 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
132 /* FIXME: Should we wait here or not for synchronously opened files? */
143 NtQueryDirectoryFile(
144 IN HANDLE FileHandle
,
145 IN HANDLE PEvent OPTIONAL
,
146 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
147 IN PVOID ApcContext OPTIONAL
,
148 OUT PIO_STATUS_BLOCK IoStatusBlock
,
149 OUT PVOID FileInformation
,
151 IN FILE_INFORMATION_CLASS FileInformationClass
,
152 IN BOOLEAN ReturnSingleEntry
,
153 IN PUNICODE_STRING FileName OPTIONAL
,
154 IN BOOLEAN RestartScan
157 * FUNCTION: Queries a directory file.
159 * FileHandle = Handle to a directory file
160 * EventHandle = Handle to the event signaled on completion
161 * ApcRoutine = Asynchroneous procedure callback, called on completion
162 * ApcContext = Argument to the apc.
163 * IoStatusBlock = Caller supplies storage for extended status information.
164 * FileInformation = Caller supplies storage for the resulting information.
166 * FileNameInformation FILE_NAMES_INFORMATION
167 * FileDirectoryInformation FILE_DIRECTORY_INFORMATION
168 * FileFullDirectoryInformation FILE_FULL_DIRECTORY_INFORMATION
169 * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
171 * Length = Size of the storage supplied
172 * FileInformationClass = Indicates the type of information requested.
173 * ReturnSingleEntry = Specify true if caller only requests the first
175 * FileName = Initial directory name to query, that may contain wild
177 * RestartScan = Number of times the action should be repeated
178 * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
179 * STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
180 * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
184 PDEVICE_OBJECT DeviceObject
;
185 PFILE_OBJECT FileObject
;
186 PIO_STACK_LOCATION IoStack
;
187 KPROCESSOR_MODE PreviousMode
;
188 NTSTATUS Status
= STATUS_SUCCESS
;
190 DPRINT("NtQueryDirectoryFile()\n");
194 PreviousMode
= ExGetPreviousMode();
196 if(PreviousMode
!= KernelMode
)
200 ProbeForWrite(IoStatusBlock
,
201 sizeof(IO_STATUS_BLOCK
),
203 ProbeForWrite(FileInformation
,
209 Status
= _SEH_GetExceptionCode();
213 if(!NT_SUCCESS(Status
))
219 Status
= ObReferenceObjectByHandle(FileHandle
,
223 (PVOID
*)&FileObject
,
226 if (Status
!= STATUS_SUCCESS
)
230 DeviceObject
= FileObject
->DeviceObject
;
232 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, TRUE
);
235 ObDereferenceObject(FileObject
);
236 return STATUS_UNSUCCESSFUL
;
239 /* Trigger FileObject/Event dereferencing */
240 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
241 Irp
->RequestorMode
= PreviousMode
;
242 Irp
->UserIosb
= IoStatusBlock
;
243 Irp
->UserEvent
= &FileObject
->Event
;
244 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
245 KeResetEvent( &FileObject
->Event
);
246 Irp
->UserBuffer
=FileInformation
;
247 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
248 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
250 IoStack
= IoGetNextIrpStackLocation(Irp
);
252 IoStack
->MajorFunction
= IRP_MJ_DIRECTORY_CONTROL
;
253 IoStack
->MinorFunction
= IRP_MN_QUERY_DIRECTORY
;
255 IoStack
->Control
= 0;
256 IoStack
->DeviceObject
= DeviceObject
;
257 IoStack
->FileObject
= FileObject
;
261 IoStack
->Flags
= IoStack
->Flags
| SL_RESTART_SCAN
;
263 if (ReturnSingleEntry
)
265 IoStack
->Flags
= IoStack
->Flags
| SL_RETURN_SINGLE_ENTRY
;
267 if (((PFILE_DIRECTORY_INFORMATION
)FileInformation
)->FileIndex
!= 0)
269 IoStack
->Flags
= IoStack
->Flags
| SL_INDEX_SPECIFIED
;
272 IoStack
->Parameters
.QueryDirectory
.FileInformationClass
=
273 FileInformationClass
;
274 IoStack
->Parameters
.QueryDirectory
.FileName
= FileName
;
275 IoStack
->Parameters
.QueryDirectory
.Length
= Length
;
277 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
278 if (Status
==STATUS_PENDING
&& !(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
280 KeWaitForSingleObject(&FileObject
->Event
,
283 FileObject
->Flags
& FO_ALERTABLE_IO
,
285 Status
= IoStatusBlock
->Status
;