4ab0b69bcc13bbf95d28d52a7d59cf2b294c08de
[reactos.git] / ntoskrnl / io / file.c
1 /* $Id$
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    PVOID SystemBuffer;
42    IO_STATUS_BLOCK IoSB;
43    
44    assert(IoStatusBlock != NULL);
45    assert(FileInformation != NULL);
46    
47    DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
48           "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
49           Length, FileInformationClass);
50    
51    Status = ObReferenceObjectByHandle(FileHandle,
52                                       FILE_READ_ATTRIBUTES,
53                                       IoFileObjectType,
54                                       UserMode,
55                                       (PVOID *)&FileObject,
56                                       NULL);
57    if (!NT_SUCCESS(Status))
58      {
59         return(Status);
60      }
61    DPRINT("FileObject %x\n", FileObject);
62    
63    DeviceObject = FileObject->DeviceObject;
64    
65    Irp = IoAllocateIrp(DeviceObject->StackSize,
66                        TRUE);
67    if (Irp == NULL)
68      {
69         ObDereferenceObject(FileObject);
70         return STATUS_INSUFFICIENT_RESOURCES;
71      }
72    
73    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
74                                         Length,
75                                         TAG_SYSB);
76    if (SystemBuffer == NULL)
77      {
78         IoFreeIrp(Irp);
79         ObDereferenceObject(FileObject);
80         return(STATUS_INSUFFICIENT_RESOURCES);
81      }
82    
83    Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
84    Irp->UserIosb = &IoSB;
85    Irp->UserEvent = &FileObject->Event;
86    KeResetEvent( &FileObject->Event );
87    
88    StackPtr = IoGetNextIrpStackLocation(Irp);
89    StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
90    StackPtr->MinorFunction = 0;
91    StackPtr->Flags = 0;
92    StackPtr->Control = 0;
93    StackPtr->DeviceObject = DeviceObject;
94    StackPtr->FileObject = FileObject;
95    
96    StackPtr->Parameters.QueryFile.FileInformationClass =
97      FileInformationClass;
98    StackPtr->Parameters.QueryFile.Length = Length;
99    
100    Status = IoCallDriver(FileObject->DeviceObject,
101                          Irp);
102    if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
103      {
104         KeWaitForSingleObject(&FileObject->Event,
105                               Executive,
106                               KernelMode,
107                               FALSE,
108                               NULL);
109         Status = IoSB.Status;
110      }
111   if (IoStatusBlock)
112     {
113       *IoStatusBlock = IoSB;
114     }
115
116   if (NT_SUCCESS(Status))
117     {
118       DPRINT("Information %lu\n", IoStatusBlock->Information);
119       MmSafeCopyToUser(FileInformation,
120                        SystemBuffer,
121                        IoStatusBlock->Information);
122     }
123    
124    ExFreePool(SystemBuffer);   
125    return(Status);
126 }
127
128 #ifndef LIBCAPTIVE
129
130 NTSTATUS STDCALL
131 IoQueryFileInformation(IN PFILE_OBJECT FileObject,
132                        IN FILE_INFORMATION_CLASS FileInformationClass,
133                        IN ULONG Length,
134                        OUT PVOID FileInformation,
135                        OUT PULONG ReturnedLength)
136 {
137    IO_STATUS_BLOCK IoStatusBlock;
138    PIRP Irp;
139    PDEVICE_OBJECT DeviceObject;
140    PIO_STACK_LOCATION StackPtr;
141    NTSTATUS Status;
142    
143    assert(FileInformation != NULL)
144    
145    Status = ObReferenceObjectByPointer(FileObject,
146                                        FILE_READ_ATTRIBUTES,
147                                        IoFileObjectType,
148                                        KernelMode);
149    if (!NT_SUCCESS(Status))
150      {
151         return(Status);
152      }
153    
154    DPRINT("FileObject %x\n", FileObject);
155    
156    DeviceObject = FileObject->DeviceObject;
157    
158    Irp = IoAllocateIrp(DeviceObject->StackSize,
159                        TRUE);
160    if (Irp == NULL)
161      {
162         ObDereferenceObject(FileObject);
163         return STATUS_INSUFFICIENT_RESOURCES;
164      }
165    
166    Irp->AssociatedIrp.SystemBuffer = FileInformation;
167    Irp->UserIosb = &IoStatusBlock;
168    Irp->UserEvent = &FileObject->Event;
169    KeResetEvent( &FileObject->Event );
170    
171    StackPtr = IoGetNextIrpStackLocation(Irp);
172    StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
173    StackPtr->MinorFunction = 0;
174    StackPtr->Flags = 0;
175    StackPtr->Control = 0;
176    StackPtr->DeviceObject = DeviceObject;
177    StackPtr->FileObject = FileObject;
178    
179    StackPtr->Parameters.QueryFile.FileInformationClass =
180      FileInformationClass;
181    StackPtr->Parameters.QueryFile.Length = Length;
182    
183    Status = IoCallDriver(FileObject->DeviceObject,
184                          Irp);
185    if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
186      {
187         KeWaitForSingleObject(&FileObject->Event,
188                               Executive,
189                               KernelMode,
190                               FALSE,
191                               NULL);
192         Status = IoStatusBlock.Status;
193      }
194    
195    if (ReturnedLength != NULL)
196      {
197         *ReturnedLength = IoStatusBlock.Information;
198      }
199    
200    
201    return Status;
202 }
203
204
205 NTSTATUS STDCALL
206 NtSetInformationFile(HANDLE FileHandle,
207                      PIO_STATUS_BLOCK IoStatusBlock,
208                      PVOID FileInformation,
209                      ULONG Length,
210                      FILE_INFORMATION_CLASS FileInformationClass)
211 {
212    PIO_STACK_LOCATION StackPtr;
213    PFILE_OBJECT FileObject;
214    PDEVICE_OBJECT DeviceObject;
215    PIRP Irp;
216    NTSTATUS Status;
217    PVOID SystemBuffer;
218    IO_STATUS_BLOCK IoSB;
219    
220    assert(IoStatusBlock != NULL)
221    assert(FileInformation != NULL)
222    
223    DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
224           "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
225           Length, FileInformationClass);
226    
227    /*  Get the file object from the file handle  */
228    Status = ObReferenceObjectByHandle(FileHandle,
229                                       FILE_WRITE_ATTRIBUTES,
230                                       IoFileObjectType,
231                                       UserMode,
232                                       (PVOID *)&FileObject,
233                                       NULL);
234    if (!NT_SUCCESS(Status))
235      {
236         return Status;
237      }
238    
239    DPRINT("FileObject %x\n", FileObject);
240    
241    DeviceObject = FileObject->DeviceObject;
242    
243    Irp = IoAllocateIrp(DeviceObject->StackSize,
244                        TRUE);
245    if (Irp == NULL)
246      {
247         ObDereferenceObject(FileObject);
248         return STATUS_INSUFFICIENT_RESOURCES;
249      }
250    
251    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
252                                         Length,
253                                         TAG_SYSB);
254    if (SystemBuffer == NULL)
255      {
256         IoFreeIrp(Irp);
257         ObDereferenceObject(FileObject);
258         return(STATUS_INSUFFICIENT_RESOURCES);
259      }
260    
261    MmSafeCopyFromUser(SystemBuffer,
262                       FileInformation,
263                       Length);
264    
265    Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
266    Irp->UserIosb = &IoSB;
267    Irp->UserEvent = &FileObject->Event;
268    KeResetEvent( &FileObject->Event );
269    
270    StackPtr = IoGetNextIrpStackLocation(Irp);
271    StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
272    StackPtr->MinorFunction = 0;
273    StackPtr->Flags = 0;
274    StackPtr->Control = 0;
275    StackPtr->DeviceObject = DeviceObject;
276    StackPtr->FileObject = FileObject;
277    
278    StackPtr->Parameters.SetFile.FileInformationClass =
279      FileInformationClass;
280    StackPtr->Parameters.SetFile.Length = Length;
281    
282    /*
283     * Pass the IRP to the FSD (and wait for
284     * it if required)
285     */
286    DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
287    Status = IoCallDriver(FileObject->DeviceObject,
288                          Irp);
289    if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
290      {
291         KeWaitForSingleObject(&FileObject->Event,
292                               Executive,
293                               KernelMode,
294                               FALSE,
295                               NULL);
296         Status = IoSB.Status;
297      }
298    if (IoStatusBlock)
299      {
300        *IoStatusBlock = IoSB;
301      }
302    ExFreePool(SystemBuffer);
303  
304    return Status;
305 }
306
307
308 NTSTATUS STDCALL
309 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
310                       OUT PFILE_BASIC_INFORMATION FileInformation)
311 {
312    UNIMPLEMENTED;
313    return STATUS_NOT_IMPLEMENTED;
314 }
315
316
317 NTSTATUS STDCALL
318 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
319                           OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
320 {
321    UNIMPLEMENTED;
322    return STATUS_NOT_IMPLEMENTED;
323 }
324
325
326 NTSTATUS STDCALL
327 NtQueryEaFile(IN HANDLE FileHandle,
328               OUT PIO_STATUS_BLOCK IoStatusBlock,
329               OUT PVOID Buffer,
330               IN ULONG Length,
331               IN BOOLEAN ReturnSingleEntry,
332               IN PVOID EaList OPTIONAL,
333               IN ULONG EaListLength,
334               IN PULONG EaIndex OPTIONAL,
335               IN BOOLEAN RestartScan)
336 {
337    UNIMPLEMENTED;
338    return STATUS_NOT_IMPLEMENTED;
339 }
340
341
342 NTSTATUS STDCALL
343 NtSetEaFile(IN HANDLE FileHandle,
344             IN PIO_STATUS_BLOCK IoStatusBlock,
345             IN PVOID EaBuffer,
346             IN ULONG EaBufferSize)
347 {
348    UNIMPLEMENTED;
349    return STATUS_NOT_IMPLEMENTED;
350 }
351
352 #endif /* LIBCAPTIVE */
353
354 /* EOF */