+NtSetInformationFile()
[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 #endif /* LIBCAPTIVE */
205
206 NTSTATUS STDCALL
207 NtSetInformationFile(HANDLE FileHandle,
208                      PIO_STATUS_BLOCK IoStatusBlock,
209                      PVOID FileInformation,
210                      ULONG Length,
211                      FILE_INFORMATION_CLASS FileInformationClass)
212 {
213    PIO_STACK_LOCATION StackPtr;
214    PFILE_OBJECT FileObject;
215    PDEVICE_OBJECT DeviceObject;
216    PIRP Irp;
217    NTSTATUS Status;
218    PVOID SystemBuffer;
219    IO_STATUS_BLOCK IoSB;
220    
221    assert(IoStatusBlock != NULL)
222    assert(FileInformation != NULL)
223    
224    DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
225           "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
226           Length, FileInformationClass);
227    
228    /*  Get the file object from the file handle  */
229    Status = ObReferenceObjectByHandle(FileHandle,
230                                       FILE_WRITE_ATTRIBUTES,
231                                       IoFileObjectType,
232                                       UserMode,
233                                       (PVOID *)&FileObject,
234                                       NULL);
235    if (!NT_SUCCESS(Status))
236      {
237         return Status;
238      }
239    
240    DPRINT("FileObject %x\n", FileObject);
241    
242    DeviceObject = FileObject->DeviceObject;
243    
244    Irp = IoAllocateIrp(DeviceObject->StackSize,
245                        TRUE);
246    if (Irp == NULL)
247      {
248         ObDereferenceObject(FileObject);
249         return STATUS_INSUFFICIENT_RESOURCES;
250      }
251    
252    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
253                                         Length,
254                                         TAG_SYSB);
255    if (SystemBuffer == NULL)
256      {
257         IoFreeIrp(Irp);
258         ObDereferenceObject(FileObject);
259         return(STATUS_INSUFFICIENT_RESOURCES);
260      }
261    
262    MmSafeCopyFromUser(SystemBuffer,
263                       FileInformation,
264                       Length);
265    
266    Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
267    Irp->UserIosb = &IoSB;
268    Irp->UserEvent = &FileObject->Event;
269    KeResetEvent( &FileObject->Event );
270    
271    StackPtr = IoGetNextIrpStackLocation(Irp);
272    StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
273    StackPtr->MinorFunction = 0;
274    StackPtr->Flags = 0;
275    StackPtr->Control = 0;
276    StackPtr->DeviceObject = DeviceObject;
277    StackPtr->FileObject = FileObject;
278    
279    StackPtr->Parameters.SetFile.FileInformationClass =
280      FileInformationClass;
281    StackPtr->Parameters.SetFile.Length = Length;
282    
283    /*
284     * Pass the IRP to the FSD (and wait for
285     * it if required)
286     */
287    DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
288    Status = IoCallDriver(FileObject->DeviceObject,
289                          Irp);
290    if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
291      {
292         KeWaitForSingleObject(&FileObject->Event,
293                               Executive,
294                               KernelMode,
295                               FALSE,
296                               NULL);
297         Status = IoSB.Status;
298      }
299    if (IoStatusBlock)
300      {
301        *IoStatusBlock = IoSB;
302      }
303    ExFreePool(SystemBuffer);
304  
305    return Status;
306 }
307
308 #ifndef LIBCAPTIVE
309
310 NTSTATUS STDCALL
311 NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
312                       OUT PFILE_BASIC_INFORMATION FileInformation)
313 {
314    UNIMPLEMENTED;
315    return STATUS_NOT_IMPLEMENTED;
316 }
317
318
319 NTSTATUS STDCALL
320 NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
321                           OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
322 {
323    UNIMPLEMENTED;
324    return STATUS_NOT_IMPLEMENTED;
325 }
326
327
328 NTSTATUS STDCALL
329 NtQueryEaFile(IN HANDLE FileHandle,
330               OUT PIO_STATUS_BLOCK IoStatusBlock,
331               OUT PVOID Buffer,
332               IN ULONG Length,
333               IN BOOLEAN ReturnSingleEntry,
334               IN PVOID EaList OPTIONAL,
335               IN ULONG EaListLength,
336               IN PULONG EaIndex OPTIONAL,
337               IN BOOLEAN RestartScan)
338 {
339    UNIMPLEMENTED;
340    return STATUS_NOT_IMPLEMENTED;
341 }
342
343
344 NTSTATUS STDCALL
345 NtSetEaFile(IN HANDLE FileHandle,
346             IN PIO_STATUS_BLOCK IoStatusBlock,
347             IN PVOID EaBuffer,
348             IN ULONG EaBufferSize)
349 {
350    UNIMPLEMENTED;
351    return STATUS_NOT_IMPLEMENTED;
352 }
353
354 #endif /* LIBCAPTIVE */
355
356 /* EOF */