finished applying @implemented and @unimplemented comments and remove the comments...
[reactos.git] / reactos / ntoskrnl / io / file.c
1 /* $Id: file.c,v 1.26 2003/07/11 01:23:14 royce 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 /*
30 * @implemented
31 */
32 NTSTATUS STDCALL
33 NtQueryInformationFile(HANDLE FileHandle,
34 PIO_STATUS_BLOCK IoStatusBlock,
35 PVOID FileInformation,
36 ULONG Length,
37 FILE_INFORMATION_CLASS FileInformationClass)
38 {
39 PFILE_OBJECT FileObject;
40 NTSTATUS Status;
41 PIRP Irp;
42 PDEVICE_OBJECT DeviceObject;
43 PIO_STACK_LOCATION StackPtr;
44 PVOID SystemBuffer;
45 IO_STATUS_BLOCK IoSB;
46
47 assert(IoStatusBlock != NULL);
48 assert(FileInformation != NULL);
49
50 DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
51 "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
52 Length, FileInformationClass);
53
54 Status = ObReferenceObjectByHandle(FileHandle,
55 FILE_READ_ATTRIBUTES,
56 IoFileObjectType,
57 UserMode,
58 (PVOID *)&FileObject,
59 NULL);
60 if (!NT_SUCCESS(Status))
61 {
62 return(Status);
63 }
64 DPRINT("FileObject %x\n", FileObject);
65
66 DeviceObject = FileObject->DeviceObject;
67
68 Irp = IoAllocateIrp(DeviceObject->StackSize,
69 TRUE);
70 if (Irp == NULL)
71 {
72 ObDereferenceObject(FileObject);
73 return STATUS_INSUFFICIENT_RESOURCES;
74 }
75
76 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
77 Length,
78 TAG_SYSB);
79 if (SystemBuffer == NULL)
80 {
81 IoFreeIrp(Irp);
82 ObDereferenceObject(FileObject);
83 return(STATUS_INSUFFICIENT_RESOURCES);
84 }
85
86 //trigger FileObject/Event dereferencing
87 Irp->Tail.Overlay.OriginalFileObject = FileObject;
88
89 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
90 Irp->UserIosb = &IoSB;
91 Irp->UserEvent = &FileObject->Event;
92 KeResetEvent( &FileObject->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(&FileObject->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 return(Status);
132 }
133
134
135 /*
136 * @implemented
137 */
138 NTSTATUS STDCALL
139 IoQueryFileInformation(IN PFILE_OBJECT FileObject,
140 IN FILE_INFORMATION_CLASS FileInformationClass,
141 IN ULONG Length,
142 OUT PVOID FileInformation,
143 OUT PULONG ReturnedLength)
144 {
145 IO_STATUS_BLOCK IoStatusBlock;
146 PIRP Irp;
147 PDEVICE_OBJECT DeviceObject;
148 PIO_STACK_LOCATION StackPtr;
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 DeviceObject = FileObject->DeviceObject;
165
166 Irp = IoAllocateIrp(DeviceObject->StackSize,
167 TRUE);
168 if (Irp == NULL)
169 {
170 ObDereferenceObject(FileObject);
171 return STATUS_INSUFFICIENT_RESOURCES;
172 }
173
174 //trigger FileObject/Event dereferencing
175 Irp->Tail.Overlay.OriginalFileObject = FileObject;
176
177 Irp->AssociatedIrp.SystemBuffer = FileInformation;
178 Irp->UserIosb = &IoStatusBlock;
179 Irp->UserEvent = &FileObject->Event;
180 KeResetEvent( &FileObject->Event );
181
182 StackPtr = IoGetNextIrpStackLocation(Irp);
183 StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
184 StackPtr->MinorFunction = 0;
185 StackPtr->Flags = 0;
186 StackPtr->Control = 0;
187 StackPtr->DeviceObject = DeviceObject;
188 StackPtr->FileObject = FileObject;
189
190 StackPtr->Parameters.QueryFile.FileInformationClass =
191 FileInformationClass;
192 StackPtr->Parameters.QueryFile.Length = Length;
193
194 Status = IoCallDriver(FileObject->DeviceObject,
195 Irp);
196 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
197 {
198 KeWaitForSingleObject(&FileObject->Event,
199 Executive,
200 KernelMode,
201 FALSE,
202 NULL);
203 Status = IoStatusBlock.Status;
204 }
205
206 if (ReturnedLength != NULL)
207 {
208 *ReturnedLength = IoStatusBlock.Information;
209 }
210
211
212 return Status;
213 }
214
215
216 /*
217 * @implemented
218 */
219 NTSTATUS STDCALL
220 NtSetInformationFile(HANDLE FileHandle,
221 PIO_STATUS_BLOCK IoStatusBlock,
222 PVOID FileInformation,
223 ULONG Length,
224 FILE_INFORMATION_CLASS FileInformationClass)
225 {
226 PIO_STACK_LOCATION StackPtr;
227 PFILE_OBJECT FileObject;
228 PDEVICE_OBJECT DeviceObject;
229 PIRP Irp;
230 NTSTATUS Status;
231 PVOID SystemBuffer;
232 IO_STATUS_BLOCK IoSB;
233
234 assert(IoStatusBlock != NULL)
235 assert(FileInformation != NULL)
236
237 DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
238 "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
239 Length, FileInformationClass);
240
241 /* Get the file object from the file handle */
242 Status = ObReferenceObjectByHandle(FileHandle,
243 FILE_WRITE_ATTRIBUTES,
244 IoFileObjectType,
245 UserMode,
246 (PVOID *)&FileObject,
247 NULL);
248 if (!NT_SUCCESS(Status))
249 {
250 return Status;
251 }
252
253 DPRINT("FileObject %x\n", FileObject);
254
255 //io completion port?
256 if (FileInformationClass == FileCompletionInformation)
257 {
258 PKQUEUE Queue;
259
260 if (Length < sizeof(FILE_COMPLETION_INFORMATION))
261 {
262 Status = STATUS_INFO_LENGTH_MISMATCH;
263 }
264 else
265 {
266 Status = ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION)FileInformation)->IoCompletionHandle,
267 IO_COMPLETION_MODIFY_STATE,//???
268 ExIoCompletionType,
269 UserMode,
270 (PVOID*)&Queue,
271 NULL);
272 if (NT_SUCCESS(Status))
273 {
274 //FIXME: maybe use lookaside list
275 FileObject->CompletionContext = ExAllocatePool(NonPagedPool, sizeof(IO_COMPLETION_CONTEXT));
276 FileObject->CompletionContext->Key = ((PFILE_COMPLETION_INFORMATION)FileInformation)->CompletionKey;
277 FileObject->CompletionContext->Port = Queue;
278
279 ObDereferenceObject(Queue);
280 }
281 }
282
283 ObDereferenceObject(FileObject);
284 return Status;
285 }
286
287 DeviceObject = FileObject->DeviceObject;
288
289 Irp = IoAllocateIrp(DeviceObject->StackSize,
290 TRUE);
291 if (Irp == NULL)
292 {
293 ObDereferenceObject(FileObject);
294 return STATUS_INSUFFICIENT_RESOURCES;
295 }
296
297 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
298 Length,
299 TAG_SYSB);
300 if (SystemBuffer == NULL)
301 {
302 IoFreeIrp(Irp);
303 ObDereferenceObject(FileObject);
304 return(STATUS_INSUFFICIENT_RESOURCES);
305 }
306
307 MmSafeCopyFromUser(SystemBuffer,
308 FileInformation,
309 Length);
310
311 //trigger FileObject/Event dereferencing
312 Irp->Tail.Overlay.OriginalFileObject = FileObject;
313
314 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
315 Irp->UserIosb = &IoSB;
316 Irp->UserEvent = &FileObject->Event;
317 KeResetEvent( &FileObject->Event );
318
319 StackPtr = IoGetNextIrpStackLocation(Irp);
320 StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
321 StackPtr->MinorFunction = 0;
322 StackPtr->Flags = 0;
323 StackPtr->Control = 0;
324 StackPtr->DeviceObject = DeviceObject;
325 StackPtr->FileObject = FileObject;
326
327 StackPtr->Parameters.SetFile.FileInformationClass =
328 FileInformationClass;
329 StackPtr->Parameters.SetFile.Length = Length;
330
331 /*
332 * Pass the IRP to the FSD (and wait for
333 * it if required)
334 */
335 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
336 Status = IoCallDriver(FileObject->DeviceObject,
337 Irp);
338 if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
339 {
340 KeWaitForSingleObject(&FileObject->Event,
341 Executive,
342 KernelMode,
343 FALSE,
344 NULL);
345 Status = IoSB.Status;
346 }
347 if (IoStatusBlock)
348 {
349 *IoStatusBlock = IoSB;
350 }
351 ExFreePool(SystemBuffer);
352
353 return Status;
354 }
355
356
357 NTSTATUS STDCALL
358 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
359 OUT PFILE_BASIC_INFORMATION FileInformation)
360 {
361 IO_STATUS_BLOCK IoStatusBlock;
362 HANDLE FileHandle;
363 NTSTATUS Status;
364
365 /* Open the file */
366 Status = NtOpenFile (&FileHandle,
367 SYNCHRONIZE | FILE_READ_ATTRIBUTES,
368 ObjectAttributes,
369 &IoStatusBlock,
370 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
371 FILE_SYNCHRONOUS_IO_NONALERT);
372 if (!NT_SUCCESS (Status))
373 {
374 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
375 return Status;
376 }
377
378 /* Get file attributes */
379 Status = NtQueryInformationFile (FileHandle,
380 &IoStatusBlock,
381 FileInformation,
382 sizeof(FILE_BASIC_INFORMATION),
383 FileBasicInformation);
384 NtClose (FileHandle);
385 if (!NT_SUCCESS (Status))
386 {
387 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status);
388 }
389
390 return Status;
391 }
392
393
394 NTSTATUS STDCALL
395 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
396 OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
397 {
398 IO_STATUS_BLOCK IoStatusBlock;
399 HANDLE FileHandle;
400 NTSTATUS Status;
401
402 /* Open the file */
403 Status = NtOpenFile (&FileHandle,
404 SYNCHRONIZE | FILE_READ_ATTRIBUTES,
405 ObjectAttributes,
406 &IoStatusBlock,
407 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
408 FILE_SYNCHRONOUS_IO_NONALERT);
409 if (!NT_SUCCESS (Status))
410 {
411 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
412 return Status;
413 }
414
415 /* Get file attributes */
416 Status = NtQueryInformationFile (FileHandle,
417 &IoStatusBlock,
418 FileInformation,
419 sizeof(FILE_NETWORK_OPEN_INFORMATION),
420 FileNetworkOpenInformation);
421 NtClose (FileHandle);
422 if (!NT_SUCCESS (Status))
423 {
424 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status);
425 }
426
427 return Status;
428 }
429
430
431 /*
432 * @unimplemented
433 */
434 NTSTATUS STDCALL
435 NtQueryEaFile(IN HANDLE FileHandle,
436 OUT PIO_STATUS_BLOCK IoStatusBlock,
437 OUT PVOID Buffer,
438 IN ULONG Length,
439 IN BOOLEAN ReturnSingleEntry,
440 IN PVOID EaList OPTIONAL,
441 IN ULONG EaListLength,
442 IN PULONG EaIndex OPTIONAL,
443 IN BOOLEAN RestartScan)
444 {
445 UNIMPLEMENTED;
446 return STATUS_NOT_IMPLEMENTED;
447 }
448
449
450 /*
451 * @unimplemented
452 */
453 NTSTATUS STDCALL
454 NtSetEaFile(IN HANDLE FileHandle,
455 IN PIO_STATUS_BLOCK IoStatusBlock,
456 IN PVOID EaBuffer,
457 IN ULONG EaBufferSize)
458 {
459 UNIMPLEMENTED;
460 return STATUS_NOT_IMPLEMENTED;
461 }
462
463 /* EOF */