:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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
129 NTSTATUS STDCALL
130 IoQueryFileInformation(IN PFILE_OBJECT FileObject,
131                        IN FILE_INFORMATION_CLASS FileInformationClass,
132                        IN ULONG Length,
133                        OUT PVOID FileInformation,
134                        OUT PULONG ReturnedLength)
135 {
136    IO_STATUS_BLOCK IoStatusBlock;
137    PIRP Irp;
138    PDEVICE_OBJECT DeviceObject;
139    PIO_STACK_LOCATION StackPtr;
140    NTSTATUS Status;
141    
142    assert(FileInformation != NULL)
143    
144    Status = ObReferenceObjectByPointer(FileObject,
145                                        FILE_READ_ATTRIBUTES,
146                                        IoFileObjectType,
147                                        KernelMode);
148    if (!NT_SUCCESS(Status))
149      {
150         return(Status);
151      }
152    
153    DPRINT("FileObject %x\n", FileObject);
154    
155    DeviceObject = FileObject->DeviceObject;
156    
157    Irp = IoAllocateIrp(DeviceObject->StackSize,
158                        TRUE);
159    if (Irp == NULL)
160      {
161         ObDereferenceObject(FileObject);
162         return STATUS_INSUFFICIENT_RESOURCES;
163      }
164    
165    Irp->AssociatedIrp.SystemBuffer = FileInformation;
166    Irp->UserIosb = &IoStatusBlock;
167    Irp->UserEvent = &FileObject->Event;
168    KeResetEvent( &FileObject->Event );
169    
170    StackPtr = IoGetNextIrpStackLocation(Irp);
171    StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
172    StackPtr->MinorFunction = 0;
173    StackPtr->Flags = 0;
174    StackPtr->Control = 0;
175    StackPtr->DeviceObject = DeviceObject;
176    StackPtr->FileObject = FileObject;
177    
178    StackPtr->Parameters.QueryFile.FileInformationClass =
179      FileInformationClass;
180    StackPtr->Parameters.QueryFile.Length = Length;
181    
182    Status = IoCallDriver(FileObject->DeviceObject,
183                          Irp);
184    if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
185      {
186         KeWaitForSingleObject(&FileObject->Event,
187                               Executive,
188                               KernelMode,
189                               FALSE,
190                               NULL);
191         Status = IoStatusBlock.Status;
192      }
193    
194    if (ReturnedLength != NULL)
195      {
196         *ReturnedLength = IoStatusBlock.Information;
197      }
198    
199    
200    return Status;
201 }
202
203
204 NTSTATUS STDCALL
205 NtSetInformationFile(HANDLE FileHandle,
206                      PIO_STATUS_BLOCK IoStatusBlock,
207                      PVOID FileInformation,
208                      ULONG Length,
209                      FILE_INFORMATION_CLASS FileInformationClass)
210 {
211    PIO_STACK_LOCATION StackPtr;
212    PFILE_OBJECT FileObject;
213    PDEVICE_OBJECT DeviceObject;
214    PIRP Irp;
215    NTSTATUS Status;
216    PVOID SystemBuffer;
217    IO_STATUS_BLOCK IoSB;
218    
219    assert(IoStatusBlock != NULL)
220    assert(FileInformation != NULL)
221    
222    DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
223           "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
224           Length, FileInformationClass);
225    
226    /*  Get the file object from the file handle  */
227    Status = ObReferenceObjectByHandle(FileHandle,
228                                       FILE_WRITE_ATTRIBUTES,
229                                       IoFileObjectType,
230                                       UserMode,
231                                       (PVOID *)&FileObject,
232                                       NULL);
233    if (!NT_SUCCESS(Status))
234      {
235         return Status;
236      }
237    
238    DPRINT("FileObject %x\n", FileObject);
239    
240    DeviceObject = FileObject->DeviceObject;
241    
242    Irp = IoAllocateIrp(DeviceObject->StackSize,
243                        TRUE);
244    if (Irp == NULL)
245      {
246         ObDereferenceObject(FileObject);
247         return STATUS_INSUFFICIENT_RESOURCES;
248      }
249    
250    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
251                                         Length,
252                                         TAG_SYSB);
253    if (SystemBuffer == NULL)
254      {
255         IoFreeIrp(Irp);
256         ObDereferenceObject(FileObject);
257         return(STATUS_INSUFFICIENT_RESOURCES);
258      }
259    
260    MmSafeCopyFromUser(SystemBuffer,
261                       FileInformation,
262                       Length);
263    
264    Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
265    Irp->UserIosb = &IoSB;
266    Irp->UserEvent = &FileObject->Event;
267    KeResetEvent( &FileObject->Event );
268    
269    StackPtr = IoGetNextIrpStackLocation(Irp);
270    StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
271    StackPtr->MinorFunction = 0;
272    StackPtr->Flags = 0;
273    StackPtr->Control = 0;
274    StackPtr->DeviceObject = DeviceObject;
275    StackPtr->FileObject = FileObject;
276    
277    StackPtr->Parameters.SetFile.FileInformationClass =
278      FileInformationClass;
279    StackPtr->Parameters.SetFile.Length = Length;
280    
281    /*
282     * Pass the IRP to the FSD (and wait for
283     * it if required)
284     */
285    DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
286    Status = IoCallDriver(FileObject->DeviceObject,
287                          Irp);
288    if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
289      {
290         KeWaitForSingleObject(&FileObject->Event,
291                               Executive,
292                               KernelMode,
293                               FALSE,
294                               NULL);
295         Status = IoSB.Status;
296      }
297    if (IoStatusBlock)
298      {
299        *IoStatusBlock = IoSB;
300      }
301    ExFreePool(SystemBuffer);
302  
303    return Status;
304 }
305
306
307 NTSTATUS STDCALL
308 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
309                       OUT PFILE_BASIC_INFORMATION FileInformation)
310 {
311    UNIMPLEMENTED;
312    return STATUS_NOT_IMPLEMENTED;
313 }
314
315
316 NTSTATUS STDCALL
317 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
318                           OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
319 {
320    UNIMPLEMENTED;
321    return STATUS_NOT_IMPLEMENTED;
322 }
323
324
325 NTSTATUS STDCALL
326 NtQueryEaFile(IN HANDLE FileHandle,
327               OUT PIO_STATUS_BLOCK IoStatusBlock,
328               OUT PVOID Buffer,
329               IN ULONG Length,
330               IN BOOLEAN ReturnSingleEntry,
331               IN PVOID EaList OPTIONAL,
332               IN ULONG EaListLength,
333               IN PULONG EaIndex OPTIONAL,
334               IN BOOLEAN RestartScan)
335 {
336    UNIMPLEMENTED;
337    return STATUS_NOT_IMPLEMENTED;
338 }
339
340
341 NTSTATUS STDCALL
342 NtSetEaFile(IN HANDLE FileHandle,
343             IN PIO_STATUS_BLOCK IoStatusBlock,
344             IN PVOID EaBuffer,
345             IN ULONG EaBufferSize)
346 {
347    UNIMPLEMENTED;
348    return STATUS_NOT_IMPLEMENTED;
349 }
350
351 /* EOF */