migrate substitution keywords to SVN
[reactos.git] / reactos / ntoskrnl / io / dir.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/dir.c
6 * PURPOSE: Directory functions
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 /* FUNCTIONS *****************************************************************/
19
20
21
22 /*
23 * @implemented
24 */
25 NTSTATUS
26 STDCALL
27 NtNotifyChangeDirectoryFile (
28 IN HANDLE FileHandle,
29 IN HANDLE Event OPTIONAL,
30 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
31 IN PVOID ApcContext OPTIONAL,
32 OUT PIO_STATUS_BLOCK IoStatusBlock,
33 OUT PVOID Buffer,
34 IN ULONG BufferSize,
35 IN ULONG CompletionFilter,
36 IN BOOLEAN WatchTree
37 )
38 {
39 PIRP Irp;
40 PDEVICE_OBJECT DeviceObject;
41 PFILE_OBJECT FileObject;
42 NTSTATUS Status;
43 PIO_STACK_LOCATION IoStack;
44 KPROCESSOR_MODE PreviousMode;
45
46 DPRINT("NtNotifyChangeDirectoryFile()\n");
47
48 PreviousMode = ExGetPreviousMode();
49
50 Status = ObReferenceObjectByHandle(FileHandle,
51 FILE_LIST_DIRECTORY,
52 IoFileObjectType,
53 PreviousMode,
54 (PVOID *)&FileObject,
55 NULL);
56
57 if (Status != STATUS_SUCCESS)
58 {
59 return(Status);
60 }
61 DeviceObject = FileObject->DeviceObject;
62
63 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
64 if (Irp==NULL)
65 {
66 ObDereferenceObject(FileObject);
67 return STATUS_UNSUCCESSFUL;
68 }
69
70 if (Event == NULL)
71 {
72 Event = &FileObject->Event;
73 }
74
75 /* Trigger FileObject/Event dereferencing */
76 Irp->Tail.Overlay.OriginalFileObject = FileObject;
77 Irp->RequestorMode = PreviousMode;
78 Irp->UserIosb = IoStatusBlock;
79 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
80 Irp->UserEvent = Event;
81 KeResetEvent( Event );
82 Irp->UserBuffer = Buffer;
83 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
84 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
85
86 IoStack = IoGetNextIrpStackLocation(Irp);
87
88 IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
89 IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
90 IoStack->Flags = 0;
91 IoStack->Control = 0;
92 IoStack->DeviceObject = DeviceObject;
93 IoStack->FileObject = FileObject;
94
95 if (WatchTree)
96 {
97 IoStack->Flags = SL_WATCH_TREE;
98 }
99
100 IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
101 IoStack->Parameters.NotifyDirectory.Length = BufferSize;
102
103 Status = IoCallDriver(FileObject->DeviceObject,Irp);
104
105 /* FIXME: Should we wait here or not for synchronously opened files? */
106
107 return Status;
108 }
109
110
111 /*
112 * @implemented
113 */
114 NTSTATUS
115 STDCALL
116 NtQueryDirectoryFile(
117 IN HANDLE FileHandle,
118 IN HANDLE PEvent OPTIONAL,
119 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
120 IN PVOID ApcContext OPTIONAL,
121 OUT PIO_STATUS_BLOCK IoStatusBlock,
122 OUT PVOID FileInformation,
123 IN ULONG Length,
124 IN FILE_INFORMATION_CLASS FileInformationClass,
125 IN BOOLEAN ReturnSingleEntry,
126 IN PUNICODE_STRING FileName OPTIONAL,
127 IN BOOLEAN RestartScan
128 )
129 /*
130 * FUNCTION: Queries a directory file.
131 * ARGUMENTS:
132 * FileHandle = Handle to a directory file
133 * EventHandle = Handle to the event signaled on completion
134 * ApcRoutine = Asynchroneous procedure callback, called on completion
135 * ApcContext = Argument to the apc.
136 * IoStatusBlock = Caller supplies storage for extended status information.
137 * FileInformation = Caller supplies storage for the resulting information.
138 *
139 * FileNameInformation FILE_NAMES_INFORMATION
140 * FileDirectoryInformation FILE_DIRECTORY_INFORMATION
141 * FileFullDirectoryInformation FILE_FULL_DIRECTORY_INFORMATION
142 * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
143 *
144 * Length = Size of the storage supplied
145 * FileInformationClass = Indicates the type of information requested.
146 * ReturnSingleEntry = Specify true if caller only requests the first
147 * directory found.
148 * FileName = Initial directory name to query, that may contain wild
149 * cards.
150 * RestartScan = Number of times the action should be repeated
151 * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
152 * STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
153 * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
154 */
155 {
156 PIRP Irp;
157 PDEVICE_OBJECT DeviceObject;
158 PFILE_OBJECT FileObject;
159 NTSTATUS Status;
160 PIO_STACK_LOCATION IoStack;
161 KPROCESSOR_MODE PreviousMode;
162
163 DPRINT("NtQueryDirectoryFile()\n");
164
165 PreviousMode = ExGetPreviousMode();
166
167 Status = ObReferenceObjectByHandle(FileHandle,
168 FILE_LIST_DIRECTORY,
169 IoFileObjectType,
170 PreviousMode,
171 (PVOID *)&FileObject,
172 NULL);
173
174 if (Status != STATUS_SUCCESS)
175 {
176 return(Status);
177 }
178 DeviceObject = FileObject->DeviceObject;
179
180 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
181 if (Irp==NULL)
182 {
183 ObDereferenceObject(FileObject);
184 return STATUS_UNSUCCESSFUL;
185 }
186
187 /* Trigger FileObject/Event dereferencing */
188 Irp->Tail.Overlay.OriginalFileObject = FileObject;
189 Irp->RequestorMode = PreviousMode;
190 Irp->UserIosb = IoStatusBlock;
191 Irp->UserEvent = &FileObject->Event;
192 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
193 KeResetEvent( &FileObject->Event );
194 Irp->UserBuffer=FileInformation;
195 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
196 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
197
198 IoStack = IoGetNextIrpStackLocation(Irp);
199
200 IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
201 IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
202 IoStack->Flags = 0;
203 IoStack->Control = 0;
204 IoStack->DeviceObject = DeviceObject;
205 IoStack->FileObject = FileObject;
206
207 if (RestartScan)
208 {
209 IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN;
210 }
211 if (ReturnSingleEntry)
212 {
213 IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY;
214 }
215 if (((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0)
216 {
217 IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
218 }
219
220 IoStack->Parameters.QueryDirectory.FileInformationClass =
221 FileInformationClass;
222 IoStack->Parameters.QueryDirectory.FileName = FileName;
223 IoStack->Parameters.QueryDirectory.Length = Length;
224
225 Status = IoCallDriver(FileObject->DeviceObject,Irp);
226 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
227 {
228 KeWaitForSingleObject(&FileObject->Event,
229 Executive,
230 PreviousMode,
231 FileObject->Flags & FO_ALERTABLE_IO,
232 NULL);
233 Status = IoStatusBlock->Status;
234 }
235
236 return(Status);
237 }
238
239 NTSTATUS STDCALL NtQueryOleDirectoryFile(VOID)
240 {
241 UNIMPLEMENTED;
242 return(STATUS_NOT_IMPLEMENTED);
243 }
244
245
246 /* EOF */