Implemented FileAllInformation.
[reactos.git] / reactos / drivers / fs / cdfs / finfo.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: finfo.c,v 1.4 2002/07/20 11:44:24 ekohl Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/fs/cdfs/finfo.c
24 * PURPOSE: CDROM (ISO 9660) filesystem driver
25 * PROGRAMMER: Art Yerkes
26 * Eric Kohl
27 * UPDATE HISTORY:
28 */
29
30 /* INCLUDES *****************************************************************/
31
32 #include <ddk/ntddk.h>
33
34 #define NDEBUG
35 #include <debug.h>
36
37 #include "cdfs.h"
38
39
40 /* FUNCTIONS ****************************************************************/
41
42 static NTSTATUS
43 CdfsGetStandardInformation(PFCB Fcb,
44 PDEVICE_OBJECT DeviceObject,
45 PFILE_STANDARD_INFORMATION StandardInfo,
46 PULONG BufferLength)
47 /*
48 * FUNCTION: Retrieve the standard file information
49 */
50 {
51 DPRINT("CdfsGetStandardInformation() called\n");
52
53 if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
54 return STATUS_BUFFER_OVERFLOW;
55
56 /* PRECONDITION */
57 assert(StandardInfo != NULL);
58 assert(Fcb != NULL);
59
60 RtlZeroMemory(StandardInfo,
61 sizeof(FILE_STANDARD_INFORMATION));
62
63 StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
64 StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
65 StandardInfo->NumberOfLinks = 0;
66 StandardInfo->DeletePending = FALSE;
67 StandardInfo->Directory = Fcb->Entry.FileFlags & 0x02 ? TRUE : FALSE;
68
69 *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
70 return(STATUS_SUCCESS);
71 }
72
73
74 static NTSTATUS
75 CdfsGetPositionInformation(PFILE_OBJECT FileObject,
76 PFILE_POSITION_INFORMATION PositionInfo,
77 PULONG BufferLength)
78 {
79 DPRINT("CdfsGetPositionInformation() called\n");
80
81 if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
82 return STATUS_BUFFER_OVERFLOW;
83
84 PositionInfo->CurrentByteOffset.QuadPart =
85 FileObject->CurrentByteOffset.QuadPart;
86
87 DPRINT("Getting position %I64x\n",
88 PositionInfo->CurrentByteOffset.QuadPart);
89
90 *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
91 return(STATUS_SUCCESS);
92 }
93
94
95 static NTSTATUS
96 CdfsGetBasicInformation(PFILE_OBJECT FileObject,
97 PFCB Fcb,
98 PDEVICE_OBJECT DeviceObject,
99 PFILE_BASIC_INFORMATION BasicInfo,
100 PULONG BufferLength)
101 {
102 DPRINT("CdfsGetBasicInformation() called\n");
103
104 if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
105 return STATUS_BUFFER_OVERFLOW;
106
107 CdfsDateTimeToFileTime(Fcb,
108 &BasicInfo->CreationTime);
109 CdfsDateTimeToFileTime(Fcb,
110 &BasicInfo->LastAccessTime);
111 CdfsDateTimeToFileTime(Fcb,
112 &BasicInfo->LastWriteTime);
113 CdfsDateTimeToFileTime(Fcb,
114 &BasicInfo->ChangeTime);
115
116 CdfsFileFlagsToAttributes(Fcb,
117 &BasicInfo->FileAttributes);
118
119 *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
120
121 return(STATUS_SUCCESS);
122 }
123
124
125 static NTSTATUS
126 CdfsGetNameInformation(PFILE_OBJECT FileObject,
127 PFCB Fcb,
128 PDEVICE_OBJECT DeviceObject,
129 PFILE_NAME_INFORMATION NameInfo,
130 PULONG BufferLength)
131 /*
132 * FUNCTION: Retrieve the file name information
133 */
134 {
135 ULONG NameLength;
136
137 DPRINT("CdfsGetNameInformation() called\n");
138
139 assert(NameInfo != NULL);
140 assert(Fcb != NULL);
141
142 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
143 if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
144 return STATUS_BUFFER_OVERFLOW;
145
146 NameInfo->FileNameLength = NameLength;
147 RtlCopyMemory(NameInfo->FileName,
148 Fcb->PathName,
149 NameLength + sizeof(WCHAR));
150
151 *BufferLength -=
152 (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
153
154 return STATUS_SUCCESS;
155 }
156
157
158 static NTSTATUS
159 CdfsGetInternalInformation(PFCB Fcb,
160 PFILE_INTERNAL_INFORMATION InternalInfo,
161 PULONG BufferLength)
162 {
163 DPRINT("CdfsGetInternalInformation() called\n");
164
165 assert(InternalInfo);
166 assert(Fcb);
167
168 if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
169 return(STATUS_BUFFER_OVERFLOW);
170
171 /* FIXME: get a real index, that can be used in a create operation */
172 InternalInfo->IndexNumber.QuadPart = 0;
173
174 *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
175
176 return(STATUS_SUCCESS);
177 }
178
179
180 static NTSTATUS
181 CdfsGetNetworkOpenInformation(PFCB Fcb,
182 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
183 PULONG BufferLength)
184 /*
185 * FUNCTION: Retrieve the file network open information
186 */
187 {
188 assert(NetworkInfo);
189 assert(Fcb);
190
191 if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
192 return(STATUS_BUFFER_OVERFLOW);
193
194 CdfsDateTimeToFileTime(Fcb,
195 &NetworkInfo->CreationTime);
196 CdfsDateTimeToFileTime(Fcb,
197 &NetworkInfo->LastAccessTime);
198 CdfsDateTimeToFileTime(Fcb,
199 &NetworkInfo->LastWriteTime);
200 CdfsDateTimeToFileTime(Fcb,
201 &NetworkInfo->ChangeTime);
202 NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
203 NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
204 CdfsFileFlagsToAttributes(Fcb,
205 &NetworkInfo->FileAttributes);
206
207 *BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
208
209 return(STATUS_SUCCESS);
210 }
211
212
213 static NTSTATUS
214 CdfsGetAllInformation(PFILE_OBJECT FileObject,
215 PFCB Fcb,
216 PFILE_ALL_INFORMATION Info,
217 PULONG BufferLength)
218 /*
219 * FUNCTION: Retrieve the all file information
220 */
221 {
222 ULONG NameLength;
223
224 assert(Info);
225 assert(Fcb);
226
227 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
228 if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength)
229 return(STATUS_BUFFER_OVERFLOW);
230
231 /* Basic Information */
232 CdfsDateTimeToFileTime(Fcb,
233 &Info->BasicInformation.CreationTime);
234 CdfsDateTimeToFileTime(Fcb,
235 &Info->BasicInformation.LastAccessTime);
236 CdfsDateTimeToFileTime(Fcb,
237 &Info->BasicInformation.LastWriteTime);
238 CdfsDateTimeToFileTime(Fcb,
239 &Info->BasicInformation.ChangeTime);
240 CdfsFileFlagsToAttributes(Fcb,
241 &Info->BasicInformation.FileAttributes);
242
243 /* Standard Information */
244 Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
245 Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
246 Info->StandardInformation.NumberOfLinks = 0;
247 Info->StandardInformation.DeletePending = FALSE;
248 Info->StandardInformation.Directory = Fcb->Entry.FileFlags & 0x02 ? TRUE : FALSE;
249
250 /* Internal Information */
251 /* FIXME: get a real index, that can be used in a create operation */
252 Info->InternalInformation.IndexNumber.QuadPart = 0;
253
254 /* EA Information */
255 Info->EaInformation.EaSize = 0;
256
257 /* Access Information */
258 /* The IO-Manager adds this information */
259
260 /* Position Information */
261 Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
262
263 /* Mode Information */
264 /* The IO-Manager adds this information */
265
266 /* Alignment Information */
267 /* The IO-Manager adds this information */
268
269 /* Name Information */
270 Info->NameInformation.FileNameLength = NameLength;
271 RtlCopyMemory(Info->NameInformation.FileName,
272 Fcb->PathName,
273 NameLength + sizeof(WCHAR));
274
275 *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
276
277 return STATUS_SUCCESS;
278 }
279
280
281 NTSTATUS STDCALL
282 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
283 PIRP Irp)
284 /*
285 * FUNCTION: Retrieve the specified file information
286 */
287 {
288 FILE_INFORMATION_CLASS FileInformationClass;
289 PIO_STACK_LOCATION Stack;
290 PFILE_OBJECT FileObject;
291 PFCB Fcb;
292 PVOID SystemBuffer;
293 ULONG BufferLength;
294
295 NTSTATUS Status = STATUS_SUCCESS;
296
297 DPRINT("CdfsQueryInformation() called\n");
298
299 Stack = IoGetCurrentIrpStackLocation(Irp);
300 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
301 FileObject = Stack->FileObject;
302 Fcb = FileObject->FsContext;
303
304 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
305 BufferLength = Stack->Parameters.QueryFile.Length;
306
307 switch (FileInformationClass)
308 {
309 case FileStandardInformation:
310 Status = CdfsGetStandardInformation(Fcb,
311 DeviceObject,
312 SystemBuffer,
313 &BufferLength);
314 break;
315
316 case FilePositionInformation:
317 Status = CdfsGetPositionInformation(FileObject,
318 SystemBuffer,
319 &BufferLength);
320 break;
321
322 case FileBasicInformation:
323 Status = CdfsGetBasicInformation(FileObject,
324 Fcb,
325 DeviceObject,
326 SystemBuffer,
327 &BufferLength);
328 break;
329
330 case FileNameInformation:
331 Status = CdfsGetNameInformation(FileObject,
332 Fcb,
333 DeviceObject,
334 SystemBuffer,
335 &BufferLength);
336 break;
337
338 case FileInternalInformation:
339 Status = CdfsGetInternalInformation(Fcb,
340 SystemBuffer,
341 &BufferLength);
342 break;
343
344 case FileNetworkOpenInformation:
345 Status = CdfsGetNetworkOpenInformation(Fcb,
346 SystemBuffer,
347 &BufferLength);
348 break;
349
350 case FileAllInformation:
351 Status = CdfsGetAllInformation(FileObject,
352 Fcb,
353 SystemBuffer,
354 &BufferLength);
355 break;
356
357 case FileAlternateNameInformation:
358 Status = STATUS_NOT_IMPLEMENTED;
359 break;
360
361 default:
362 DPRINT("Unimplemented information class %u\n", FileInformationClass);
363 Status = STATUS_NOT_SUPPORTED;
364 }
365
366 Irp->IoStatus.Status = Status;
367 if (NT_SUCCESS(Status))
368 Irp->IoStatus.Information =
369 Stack->Parameters.QueryFile.Length - BufferLength;
370 else
371 Irp->IoStatus.Information = 0;
372
373 IoCompleteRequest(Irp, IO_NO_INCREMENT);
374
375 return(Status);
376 }
377
378 /* EOF */