migrate substitution keywords to SVN
[reactos.git] / reactos / drivers / fs / cdfs / finfo.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002, 2004 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$
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 /*
43 * FUNCTION: Retrieve the standard file information
44 */
45 static NTSTATUS
46 CdfsGetStandardInformation(PFCB Fcb,
47 PDEVICE_OBJECT DeviceObject,
48 PFILE_STANDARD_INFORMATION StandardInfo,
49 PULONG BufferLength)
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 if (CdfsFCBIsDirectory(Fcb))
64 {
65 StandardInfo->AllocationSize.QuadPart = 0LL;;
66 StandardInfo->EndOfFile.QuadPart = 0LL;
67 StandardInfo->Directory = TRUE;
68 }
69 else
70 {
71 StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
72 StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
73 StandardInfo->Directory = FALSE;
74 }
75 StandardInfo->NumberOfLinks = 0;
76 StandardInfo->DeletePending = FALSE;
77
78 *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
79 return(STATUS_SUCCESS);
80 }
81
82
83 /*
84 * FUNCTION: Retrieve the file position information
85 */
86 static NTSTATUS
87 CdfsGetPositionInformation(PFILE_OBJECT FileObject,
88 PFILE_POSITION_INFORMATION PositionInfo,
89 PULONG BufferLength)
90 {
91 DPRINT("CdfsGetPositionInformation() called\n");
92
93 if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
94 return STATUS_BUFFER_OVERFLOW;
95
96 PositionInfo->CurrentByteOffset.QuadPart =
97 FileObject->CurrentByteOffset.QuadPart;
98
99 DPRINT("Getting position %I64x\n",
100 PositionInfo->CurrentByteOffset.QuadPart);
101
102 *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
103 return(STATUS_SUCCESS);
104 }
105
106
107 /*
108 * FUNCTION: Retrieve the basic file information
109 */
110 static NTSTATUS
111 CdfsGetBasicInformation(PFILE_OBJECT FileObject,
112 PFCB Fcb,
113 PDEVICE_OBJECT DeviceObject,
114 PFILE_BASIC_INFORMATION BasicInfo,
115 PULONG BufferLength)
116 {
117 DPRINT("CdfsGetBasicInformation() called\n");
118
119 if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
120 return STATUS_BUFFER_OVERFLOW;
121
122 CdfsDateTimeToSystemTime(Fcb,
123 &BasicInfo->CreationTime);
124 CdfsDateTimeToSystemTime(Fcb,
125 &BasicInfo->LastAccessTime);
126 CdfsDateTimeToSystemTime(Fcb,
127 &BasicInfo->LastWriteTime);
128 CdfsDateTimeToSystemTime(Fcb,
129 &BasicInfo->ChangeTime);
130
131 CdfsFileFlagsToAttributes(Fcb,
132 &BasicInfo->FileAttributes);
133
134 *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
135
136 return(STATUS_SUCCESS);
137 }
138
139
140 /*
141 * FUNCTION: Retrieve the file name information
142 */
143 static NTSTATUS
144 CdfsGetNameInformation(PFILE_OBJECT FileObject,
145 PFCB Fcb,
146 PDEVICE_OBJECT DeviceObject,
147 PFILE_NAME_INFORMATION NameInfo,
148 PULONG BufferLength)
149 {
150 ULONG NameLength;
151
152 DPRINT("CdfsGetNameInformation() called\n");
153
154 ASSERT(NameInfo != NULL);
155 ASSERT(Fcb != NULL);
156
157 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
158 if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
159 return STATUS_BUFFER_OVERFLOW;
160
161 NameInfo->FileNameLength = NameLength;
162 RtlCopyMemory(NameInfo->FileName,
163 Fcb->PathName,
164 NameLength + sizeof(WCHAR));
165
166 *BufferLength -=
167 (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
168
169 return STATUS_SUCCESS;
170 }
171
172
173 /*
174 * FUNCTION: Retrieve the internal file information
175 */
176 static NTSTATUS
177 CdfsGetInternalInformation(PFCB Fcb,
178 PFILE_INTERNAL_INFORMATION InternalInfo,
179 PULONG BufferLength)
180 {
181 DPRINT("CdfsGetInternalInformation() called\n");
182
183 ASSERT(InternalInfo);
184 ASSERT(Fcb);
185
186 if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
187 return(STATUS_BUFFER_OVERFLOW);
188
189 InternalInfo->IndexNumber.QuadPart = Fcb->IndexNumber.QuadPart;
190
191 *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
192
193 return(STATUS_SUCCESS);
194 }
195
196
197 /*
198 * FUNCTION: Retrieve the file network open information
199 */
200 static NTSTATUS
201 CdfsGetNetworkOpenInformation(PFCB Fcb,
202 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
203 PULONG BufferLength)
204 {
205 ASSERT(NetworkInfo);
206 ASSERT(Fcb);
207
208 if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
209 return(STATUS_BUFFER_OVERFLOW);
210
211 CdfsDateTimeToSystemTime(Fcb,
212 &NetworkInfo->CreationTime);
213 CdfsDateTimeToSystemTime(Fcb,
214 &NetworkInfo->LastAccessTime);
215 CdfsDateTimeToSystemTime(Fcb,
216 &NetworkInfo->LastWriteTime);
217 CdfsDateTimeToSystemTime(Fcb,
218 &NetworkInfo->ChangeTime);
219 if (CdfsFCBIsDirectory(Fcb))
220 {
221 NetworkInfo->AllocationSize.QuadPart = 0LL;;
222 NetworkInfo->EndOfFile.QuadPart = 0LL;
223 }
224 else
225 {
226 NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
227 NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
228 }
229 CdfsFileFlagsToAttributes(Fcb,
230 &NetworkInfo->FileAttributes);
231
232 *BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
233
234 return(STATUS_SUCCESS);
235 }
236
237
238 /*
239 * FUNCTION: Retrieve all file information
240 */
241 static NTSTATUS
242 CdfsGetAllInformation(PFILE_OBJECT FileObject,
243 PFCB Fcb,
244 PFILE_ALL_INFORMATION Info,
245 PULONG BufferLength)
246 {
247 ULONG NameLength;
248
249 ASSERT(Info);
250 ASSERT(Fcb);
251
252 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
253 if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength)
254 return(STATUS_BUFFER_OVERFLOW);
255
256 /* Basic Information */
257 CdfsDateTimeToSystemTime(Fcb,
258 &Info->BasicInformation.CreationTime);
259 CdfsDateTimeToSystemTime(Fcb,
260 &Info->BasicInformation.LastAccessTime);
261 CdfsDateTimeToSystemTime(Fcb,
262 &Info->BasicInformation.LastWriteTime);
263 CdfsDateTimeToSystemTime(Fcb,
264 &Info->BasicInformation.ChangeTime);
265 CdfsFileFlagsToAttributes(Fcb,
266 &Info->BasicInformation.FileAttributes);
267
268 /* Standard Information */
269 if (CdfsFCBIsDirectory(Fcb))
270 {
271 Info->StandardInformation.AllocationSize.QuadPart = 0LL;
272 Info->StandardInformation.EndOfFile.QuadPart = 0LL;
273 Info->StandardInformation.Directory = TRUE;
274 }
275 else
276 {
277 Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
278 Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
279 Info->StandardInformation.Directory = FALSE;
280 }
281 Info->StandardInformation.NumberOfLinks = 0;
282 Info->StandardInformation.DeletePending = FALSE;
283
284 /* Internal Information */
285 Info->InternalInformation.IndexNumber.QuadPart = Fcb->IndexNumber.QuadPart;
286
287 /* EA Information */
288 Info->EaInformation.EaSize = 0;
289
290 /* Access Information */
291 /* The IO-Manager adds this information */
292
293 /* Position Information */
294 Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
295
296 /* Mode Information */
297 /* The IO-Manager adds this information */
298
299 /* Alignment Information */
300 /* The IO-Manager adds this information */
301
302 /* Name Information */
303 Info->NameInformation.FileNameLength = NameLength;
304 RtlCopyMemory(Info->NameInformation.FileName,
305 Fcb->PathName,
306 NameLength + sizeof(WCHAR));
307
308 *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
309
310 return STATUS_SUCCESS;
311 }
312
313
314 /*
315 * FUNCTION: Retrieve the specified file information
316 */
317 NTSTATUS STDCALL
318 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
319 PIRP Irp)
320 {
321 FILE_INFORMATION_CLASS FileInformationClass;
322 PIO_STACK_LOCATION Stack;
323 PFILE_OBJECT FileObject;
324 PFCB Fcb;
325 PVOID SystemBuffer;
326 ULONG BufferLength;
327
328 NTSTATUS Status = STATUS_SUCCESS;
329
330 DPRINT("CdfsQueryInformation() called\n");
331
332 Stack = IoGetCurrentIrpStackLocation(Irp);
333 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
334 FileObject = Stack->FileObject;
335 Fcb = FileObject->FsContext;
336
337 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
338 BufferLength = Stack->Parameters.QueryFile.Length;
339
340 switch (FileInformationClass)
341 {
342 case FileStandardInformation:
343 Status = CdfsGetStandardInformation(Fcb,
344 DeviceObject,
345 SystemBuffer,
346 &BufferLength);
347 break;
348
349 case FilePositionInformation:
350 Status = CdfsGetPositionInformation(FileObject,
351 SystemBuffer,
352 &BufferLength);
353 break;
354
355 case FileBasicInformation:
356 Status = CdfsGetBasicInformation(FileObject,
357 Fcb,
358 DeviceObject,
359 SystemBuffer,
360 &BufferLength);
361 break;
362
363 case FileNameInformation:
364 Status = CdfsGetNameInformation(FileObject,
365 Fcb,
366 DeviceObject,
367 SystemBuffer,
368 &BufferLength);
369 break;
370
371 case FileInternalInformation:
372 Status = CdfsGetInternalInformation(Fcb,
373 SystemBuffer,
374 &BufferLength);
375 break;
376
377 case FileNetworkOpenInformation:
378 Status = CdfsGetNetworkOpenInformation(Fcb,
379 SystemBuffer,
380 &BufferLength);
381 break;
382
383 case FileAllInformation:
384 Status = CdfsGetAllInformation(FileObject,
385 Fcb,
386 SystemBuffer,
387 &BufferLength);
388 break;
389
390 case FileAlternateNameInformation:
391 Status = STATUS_NOT_IMPLEMENTED;
392 break;
393
394 default:
395 DPRINT("Unimplemented information class %u\n", FileInformationClass);
396 Status = STATUS_NOT_SUPPORTED;
397 break;
398 }
399
400 Irp->IoStatus.Status = Status;
401 if (NT_SUCCESS(Status))
402 Irp->IoStatus.Information =
403 Stack->Parameters.QueryFile.Length - BufferLength;
404 else
405 Irp->IoStatus.Information = 0;
406
407 IoCompleteRequest(Irp, IO_NO_INCREMENT);
408
409 return(Status);
410 }
411
412
413 /*
414 * FUNCTION: Set the file position information
415 */
416 static NTSTATUS
417 CdfsSetPositionInformation(PFILE_OBJECT FileObject,
418 PFILE_POSITION_INFORMATION PositionInfo)
419 {
420 DPRINT ("CdfsSetPositionInformation()\n");
421
422 DPRINT ("PositionInfo %x\n", PositionInfo);
423 DPRINT ("Setting position %I64u\n", PositionInfo->CurrentByteOffset.QuadPart);
424
425 FileObject->CurrentByteOffset.QuadPart =
426 PositionInfo->CurrentByteOffset.QuadPart;
427
428 return STATUS_SUCCESS;
429 }
430
431
432 /*
433 * FUNCTION: Set the specified file information
434 */
435 NTSTATUS STDCALL
436 CdfsSetInformation(PDEVICE_OBJECT DeviceObject,
437 PIRP Irp)
438 {
439 FILE_INFORMATION_CLASS FileInformationClass;
440 PIO_STACK_LOCATION Stack;
441 PFILE_OBJECT FileObject;
442 PFCB Fcb;
443 PVOID SystemBuffer;
444
445 NTSTATUS Status = STATUS_SUCCESS;
446
447 DPRINT("CdfsSetInformation() called\n");
448
449 Stack = IoGetCurrentIrpStackLocation(Irp);
450 FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
451 FileObject = Stack->FileObject;
452 Fcb = FileObject->FsContext;
453
454 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
455
456 switch (FileInformationClass)
457 {
458 case FilePositionInformation:
459 Status = CdfsSetPositionInformation(FileObject,
460 SystemBuffer);
461 break;
462
463 case FileBasicInformation:
464 case FileRenameInformation:
465 Status = STATUS_NOT_IMPLEMENTED;
466 break;
467
468 default:
469 Status = STATUS_NOT_SUPPORTED;
470 break;
471 }
472
473 Irp->IoStatus.Status = Status;
474 Irp->IoStatus.Information = 0;
475
476 IoCompleteRequest(Irp, IO_NO_INCREMENT);
477
478 return Status;
479 }
480
481 /* EOF */