Added some modifications for asyncronous i/o requests (for vfatfs).
[reactos.git] / reactos / ntoskrnl / io / file.c
1 /* $Id: file.c,v 1.15 2001/11/02 22:22:33 hbirr Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/file.c
6 * PURPOSE: Graceful system shutdown if a bug is detected
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/mm.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21
22 /* GLOBALS *******************************************************************/
23
24 #define TAG_SYSB TAG('S', 'Y', 'S', 'B')
25
26
27 /* FUNCTIONS *****************************************************************/
28
29 NTSTATUS STDCALL
30 NtQueryInformationFile(HANDLE FileHandle,
31 PIO_STATUS_BLOCK IoStatusBlock,
32 PVOID FileInformation,
33 ULONG Length,
34 FILE_INFORMATION_CLASS FileInformationClass)
35 {
36 PFILE_OBJECT FileObject;
37 NTSTATUS Status;
38 PIRP Irp;
39 PDEVICE_OBJECT DeviceObject;
40 PIO_STACK_LOCATION StackPtr;
41 KEVENT Event;
42 PVOID SystemBuffer;
43 IO_STATUS_BLOCK IoSB;
44
45 assert(IoStatusBlock != NULL);
46 assert(FileInformation != NULL);
47
48 DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d Class %d)\n",
49 FileHandle,
50 IoStatusBlock,
51 FileInformation,
52 Length,
53 FileInformationClass);
54
55 Status = ObReferenceObjectByHandle(FileHandle,
56 FILE_READ_ATTRIBUTES,
57 IoFileObjectType,
58 UserMode,
59 (PVOID *)&FileObject,
60 NULL);
61 if (!NT_SUCCESS(Status))
62 {
63 return(Status);
64 }
65 DPRINT("FileObject %x\n", FileObject);
66
67 KeInitializeEvent(&Event,
68 NotificationEvent,
69 FALSE);
70 DeviceObject = FileObject->DeviceObject;
71
72 Irp = IoAllocateIrp(DeviceObject->StackSize,
73 TRUE);
74 if (Irp == NULL)
75 {
76 ObDereferenceObject(FileObject);
77 return STATUS_INSUFFICIENT_RESOURCES;
78 }
79
80 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
81 Length,
82 TAG_SYSB);
83 if (SystemBuffer == NULL)
84 {
85 IoFreeIrp(Irp);
86 ObDereferenceObject(FileObject);
87 return(STATUS_INSUFFICIENT_RESOURCES);
88 }
89
90 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
91 Irp->UserIosb = &IoSB;
92 Irp->UserEvent = &Event;
93
94 StackPtr = IoGetNextIrpStackLocation(Irp);
95 StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
96 StackPtr->MinorFunction = 0;
97 StackPtr->Flags = 0;
98 StackPtr->Control = 0;
99 StackPtr->DeviceObject = DeviceObject;
100 StackPtr->FileObject = FileObject;
101
102 StackPtr->Parameters.QueryFile.FileInformationClass =
103 FileInformationClass;
104 StackPtr->Parameters.QueryFile.Length = Length;
105
106 Status = IoCallDriver(FileObject->DeviceObject,
107 Irp);
108 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
109 {
110 KeWaitForSingleObject(&Event,
111 Executive,
112 KernelMode,
113 FALSE,
114 NULL);
115 Status = IoSB.Status;
116 }
117 if (IoStatusBlock)
118 {
119 *IoStatusBlock = IoSB;
120 }
121
122 if (NT_SUCCESS(Status))
123 {
124 DPRINT("Information %lu\n", IoStatusBlock->Information);
125 MmSafeCopyToUser(FileInformation,
126 SystemBuffer,
127 IoStatusBlock->Information);
128 }
129
130 ExFreePool(SystemBuffer);
131 ObDereferenceObject(FileObject);
132
133 return(Status);
134 }
135
136
137 NTSTATUS STDCALL
138 IoQueryFileInformation(IN PFILE_OBJECT FileObject,
139 IN FILE_INFORMATION_CLASS FileInformationClass,
140 IN ULONG Length,
141 OUT PVOID FileInformation,
142 OUT PULONG ReturnedLength)
143 {
144 IO_STATUS_BLOCK IoStatusBlock;
145 PIRP Irp;
146 PDEVICE_OBJECT DeviceObject;
147 PIO_STACK_LOCATION StackPtr;
148 KEVENT Event;
149 NTSTATUS Status;
150
151 assert(FileInformation != NULL)
152
153 Status = ObReferenceObjectByPointer(FileObject,
154 FILE_READ_ATTRIBUTES,
155 IoFileObjectType,
156 KernelMode);
157 if (!NT_SUCCESS(Status))
158 {
159 return(Status);
160 }
161
162 DPRINT("FileObject %x\n", FileObject);
163
164 KeInitializeEvent(&Event,
165 NotificationEvent,
166 FALSE);
167 DeviceObject = FileObject->DeviceObject;
168
169 Irp = IoAllocateIrp(DeviceObject->StackSize,
170 TRUE);
171 if (Irp == NULL)
172 {
173 ObDereferenceObject(FileObject);
174 return STATUS_INSUFFICIENT_RESOURCES;
175 }
176
177 Irp->AssociatedIrp.SystemBuffer = FileInformation;
178 Irp->UserIosb = &IoStatusBlock;
179 Irp->UserEvent = &Event;
180
181 StackPtr = IoGetNextIrpStackLocation(Irp);
182 StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
183 StackPtr->MinorFunction = 0;
184 StackPtr->Flags = 0;
185 StackPtr->Control = 0;
186 StackPtr->DeviceObject = DeviceObject;
187 StackPtr->FileObject = FileObject;
188
189 StackPtr->Parameters.QueryFile.FileInformationClass =
190 FileInformationClass;
191 StackPtr->Parameters.QueryFile.Length = Length;
192
193 Status = IoCallDriver(FileObject->DeviceObject,
194 Irp);
195 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
196 {
197 KeWaitForSingleObject(&Event,
198 Executive,
199 KernelMode,
200 FALSE,
201 NULL);
202 Status = IoStatusBlock.Status;
203 }
204
205 if (ReturnedLength != NULL)
206 {
207 *ReturnedLength = IoStatusBlock.Information;
208 }
209
210 ObDereferenceObject(FileObject);
211
212 return Status;
213 }
214
215
216 NTSTATUS STDCALL
217 NtSetInformationFile(HANDLE FileHandle,
218 PIO_STATUS_BLOCK IoStatusBlock,
219 PVOID FileInformation,
220 ULONG Length,
221 FILE_INFORMATION_CLASS FileInformationClass)
222 {
223 PIO_STACK_LOCATION StackPtr;
224 PFILE_OBJECT FileObject;
225 PDEVICE_OBJECT DeviceObject;
226 PIRP Irp;
227 KEVENT Event;
228 NTSTATUS Status;
229 PVOID SystemBuffer;
230 IO_STATUS_BLOCK IoSB;
231
232 assert(IoStatusBlock != NULL)
233 assert(FileInformation != NULL)
234
235 DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d Class %d)\n",
236 FileHandle,
237 IoStatusBlock,
238 FileInformation,
239 Length,
240 FileInformationClass);
241
242 /* Get the file object from the file handle */
243 Status = ObReferenceObjectByHandle(FileHandle,
244 FILE_WRITE_ATTRIBUTES,
245 IoFileObjectType,
246 UserMode,
247 (PVOID *)&FileObject,
248 NULL);
249 if (!NT_SUCCESS(Status))
250 {
251 return Status;
252 }
253
254 DPRINT("FileObject %x\n", FileObject);
255
256 /*
257 * Initialize an event object to wait
258 * on for the request.
259 */
260 KeInitializeEvent(&Event,
261 NotificationEvent,
262 FALSE);
263
264 DeviceObject = FileObject->DeviceObject;
265
266 Irp = IoAllocateIrp(DeviceObject->StackSize,
267 TRUE);
268 if (Irp == NULL)
269 {
270 ObDereferenceObject(FileObject);
271 return STATUS_INSUFFICIENT_RESOURCES;
272 }
273
274 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
275 Length,
276 TAG_SYSB);
277 if (SystemBuffer == NULL)
278 {
279 IoFreeIrp(Irp);
280 ObDereferenceObject(FileObject);
281 return(STATUS_INSUFFICIENT_RESOURCES);
282 }
283
284 MmSafeCopyFromUser(SystemBuffer,
285 FileInformation,
286 Length);
287
288 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
289 Irp->UserIosb = &IoSB;
290 Irp->UserEvent = &Event;
291
292 StackPtr = IoGetNextIrpStackLocation(Irp);
293 StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
294 StackPtr->MinorFunction = 0;
295 StackPtr->Flags = 0;
296 StackPtr->Control = 0;
297 StackPtr->DeviceObject = DeviceObject;
298 StackPtr->FileObject = FileObject;
299
300 StackPtr->Parameters.SetFile.FileInformationClass =
301 FileInformationClass;
302 StackPtr->Parameters.SetFile.Length = Length;
303
304 /*
305 * Pass the IRP to the FSD (and wait for
306 * it if required)
307 */
308 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
309 Status = IoCallDriver(FileObject->DeviceObject,
310 Irp);
311 if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
312 {
313 KeWaitForSingleObject(&Event,
314 Executive,
315 KernelMode,
316 FALSE,
317 NULL);
318 Status = IoSB.Status;
319 }
320 if (IoStatusBlock)
321 {
322 *IoStatusBlock = IoSB;
323 }
324 ExFreePool(SystemBuffer);
325 ObDereferenceObject(FileObject);
326
327 return Status;
328 }
329
330
331 NTSTATUS STDCALL
332 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
333 IN PVOID Buffer)
334 {
335 UNIMPLEMENTED;
336 return STATUS_NOT_IMPLEMENTED;
337 }
338
339
340 NTSTATUS STDCALL
341 NtQueryFullAttributesFile(IN HANDLE FileHandle,
342 IN PVOID Attributes)
343 {
344 UNIMPLEMENTED;
345 return STATUS_NOT_IMPLEMENTED;
346 }
347
348
349 NTSTATUS STDCALL
350 NtQueryEaFile(IN HANDLE FileHandle,
351 OUT PIO_STATUS_BLOCK IoStatusBlock,
352 OUT PVOID Buffer,
353 IN ULONG Length,
354 IN BOOLEAN ReturnSingleEntry,
355 IN PVOID EaList OPTIONAL,
356 IN ULONG EaListLength,
357 IN PULONG EaIndex OPTIONAL,
358 IN BOOLEAN RestartScan)
359 {
360 UNIMPLEMENTED;
361 return STATUS_NOT_IMPLEMENTED;
362 }
363
364
365 NTSTATUS STDCALL
366 NtSetEaFile(IN HANDLE FileHandle,
367 IN PIO_STATUS_BLOCK IoStatusBlock,
368 IN PVOID EaBuffer,
369 IN ULONG EaBufferSize)
370 {
371 UNIMPLEMENTED;
372 return STATUS_NOT_IMPLEMENTED;
373 }
374
375 /* EOF */