3 * Copyright (C) 2002, 2004 ReactOS Team
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.
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.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: services/fs/cdfs/finfo.c
23 * PURPOSE: CDROM (ISO 9660) filesystem driver
24 * PROGRAMMER: Art Yerkes
29 /* INCLUDES *****************************************************************/
36 /* FUNCTIONS ****************************************************************/
39 * FUNCTION: Retrieve the standard file information
42 CdfsGetStandardInformation(PFCB Fcb
,
43 PDEVICE_OBJECT DeviceObject
,
44 PFILE_STANDARD_INFORMATION StandardInfo
,
47 DPRINT("CdfsGetStandardInformation() called\n");
49 UNREFERENCED_PARAMETER(DeviceObject
);
51 if (*BufferLength
< sizeof(FILE_STANDARD_INFORMATION
))
52 return STATUS_BUFFER_OVERFLOW
;
55 ASSERT(StandardInfo
!= NULL
);
58 RtlZeroMemory(StandardInfo
,
59 sizeof(FILE_STANDARD_INFORMATION
));
61 if (CdfsFCBIsDirectory(Fcb
))
63 StandardInfo
->AllocationSize
.QuadPart
= 0LL;
64 StandardInfo
->EndOfFile
.QuadPart
= 0LL;
65 StandardInfo
->Directory
= TRUE
;
69 StandardInfo
->AllocationSize
= Fcb
->RFCB
.AllocationSize
;
70 StandardInfo
->EndOfFile
= Fcb
->RFCB
.FileSize
;
71 StandardInfo
->Directory
= FALSE
;
73 StandardInfo
->NumberOfLinks
= 0;
74 StandardInfo
->DeletePending
= FALSE
;
76 *BufferLength
-= sizeof(FILE_STANDARD_INFORMATION
);
77 return(STATUS_SUCCESS
);
82 * FUNCTION: Retrieve the file position information
85 CdfsGetPositionInformation(PFILE_OBJECT FileObject
,
86 PFILE_POSITION_INFORMATION PositionInfo
,
89 DPRINT("CdfsGetPositionInformation() called\n");
91 if (*BufferLength
< sizeof(FILE_POSITION_INFORMATION
))
92 return STATUS_BUFFER_OVERFLOW
;
94 PositionInfo
->CurrentByteOffset
.QuadPart
=
95 FileObject
->CurrentByteOffset
.QuadPart
;
97 DPRINT("Getting position %I64x\n",
98 PositionInfo
->CurrentByteOffset
.QuadPart
);
100 *BufferLength
-= sizeof(FILE_POSITION_INFORMATION
);
101 return(STATUS_SUCCESS
);
106 * FUNCTION: Retrieve the basic file information
109 CdfsGetBasicInformation(PFILE_OBJECT FileObject
,
111 PDEVICE_OBJECT DeviceObject
,
112 PFILE_BASIC_INFORMATION BasicInfo
,
115 DPRINT("CdfsGetBasicInformation() called\n");
117 UNREFERENCED_PARAMETER(FileObject
);
118 UNREFERENCED_PARAMETER(DeviceObject
);
120 if (*BufferLength
< sizeof(FILE_BASIC_INFORMATION
))
121 return STATUS_BUFFER_OVERFLOW
;
123 CdfsDateTimeToSystemTime(Fcb
,
124 &BasicInfo
->CreationTime
);
125 CdfsDateTimeToSystemTime(Fcb
,
126 &BasicInfo
->LastAccessTime
);
127 CdfsDateTimeToSystemTime(Fcb
,
128 &BasicInfo
->LastWriteTime
);
129 CdfsDateTimeToSystemTime(Fcb
,
130 &BasicInfo
->ChangeTime
);
132 CdfsFileFlagsToAttributes(Fcb
,
133 &BasicInfo
->FileAttributes
);
135 *BufferLength
-= sizeof(FILE_BASIC_INFORMATION
);
137 return(STATUS_SUCCESS
);
142 * FUNCTION: Retrieve the file name information
145 CdfsGetNameInformation(PFILE_OBJECT FileObject
,
147 PDEVICE_OBJECT DeviceObject
,
148 PFILE_NAME_INFORMATION NameInfo
,
154 DPRINT("CdfsGetNameInformation() called\n");
156 ASSERT(NameInfo
!= NULL
);
159 UNREFERENCED_PARAMETER(FileObject
);
160 UNREFERENCED_PARAMETER(DeviceObject
);
162 /* If buffer can't hold at least the file name length, bail out */
163 if (*BufferLength
< (ULONG
)FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]))
164 return STATUS_BUFFER_OVERFLOW
;
166 /* Calculate file name length in bytes */
167 NameLength
= Fcb
->PathName
.Length
;
168 NameInfo
->FileNameLength
= NameLength
;
170 /* Calculate amount of bytes to copy not to overflow the buffer */
171 BytesToCopy
= min(NameLength
,
172 *BufferLength
- FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]));
174 /* Fill in the bytes */
175 RtlCopyMemory(NameInfo
->FileName
, Fcb
->PathName
.Buffer
, BytesToCopy
);
177 /* Check if we could write more but are not able to */
178 if (*BufferLength
< NameLength
+ FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]))
180 /* Return number of bytes written */
181 *BufferLength
-= FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]) + BytesToCopy
;
182 return STATUS_BUFFER_OVERFLOW
;
185 /* We filled up as many bytes, as needed */
186 *BufferLength
-= (FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]) + NameLength
);
188 return STATUS_SUCCESS
;
193 * FUNCTION: Retrieve the internal file information
196 CdfsGetInternalInformation(PFCB Fcb
,
197 PFILE_INTERNAL_INFORMATION InternalInfo
,
200 DPRINT("CdfsGetInternalInformation() called\n");
202 ASSERT(InternalInfo
);
205 if (*BufferLength
< sizeof(FILE_INTERNAL_INFORMATION
))
206 return(STATUS_BUFFER_OVERFLOW
);
208 InternalInfo
->IndexNumber
.QuadPart
= Fcb
->IndexNumber
.QuadPart
;
210 *BufferLength
-= sizeof(FILE_INTERNAL_INFORMATION
);
212 return(STATUS_SUCCESS
);
217 * FUNCTION: Retrieve the file network open information
220 CdfsGetNetworkOpenInformation(PFCB Fcb
,
221 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo
,
227 if (*BufferLength
< sizeof(FILE_NETWORK_OPEN_INFORMATION
))
228 return(STATUS_BUFFER_OVERFLOW
);
230 CdfsDateTimeToSystemTime(Fcb
,
231 &NetworkInfo
->CreationTime
);
232 CdfsDateTimeToSystemTime(Fcb
,
233 &NetworkInfo
->LastAccessTime
);
234 CdfsDateTimeToSystemTime(Fcb
,
235 &NetworkInfo
->LastWriteTime
);
236 CdfsDateTimeToSystemTime(Fcb
,
237 &NetworkInfo
->ChangeTime
);
238 if (CdfsFCBIsDirectory(Fcb
))
240 NetworkInfo
->AllocationSize
.QuadPart
= 0LL;
241 NetworkInfo
->EndOfFile
.QuadPart
= 0LL;
245 NetworkInfo
->AllocationSize
= Fcb
->RFCB
.AllocationSize
;
246 NetworkInfo
->EndOfFile
= Fcb
->RFCB
.FileSize
;
248 CdfsFileFlagsToAttributes(Fcb
,
249 &NetworkInfo
->FileAttributes
);
251 *BufferLength
-= sizeof(FILE_NETWORK_OPEN_INFORMATION
);
253 return(STATUS_SUCCESS
);
258 * FUNCTION: Retrieve all file information
261 CdfsGetAllInformation(PFILE_OBJECT FileObject
,
263 PFILE_ALL_INFORMATION Info
,
271 NameLength
= Fcb
->PathName
.Length
;
272 if (*BufferLength
< sizeof(FILE_ALL_INFORMATION
) + NameLength
)
273 return(STATUS_BUFFER_OVERFLOW
);
275 /* Basic Information */
276 CdfsDateTimeToSystemTime(Fcb
,
277 &Info
->BasicInformation
.CreationTime
);
278 CdfsDateTimeToSystemTime(Fcb
,
279 &Info
->BasicInformation
.LastAccessTime
);
280 CdfsDateTimeToSystemTime(Fcb
,
281 &Info
->BasicInformation
.LastWriteTime
);
282 CdfsDateTimeToSystemTime(Fcb
,
283 &Info
->BasicInformation
.ChangeTime
);
284 CdfsFileFlagsToAttributes(Fcb
,
285 &Info
->BasicInformation
.FileAttributes
);
287 /* Standard Information */
288 if (CdfsFCBIsDirectory(Fcb
))
290 Info
->StandardInformation
.AllocationSize
.QuadPart
= 0LL;
291 Info
->StandardInformation
.EndOfFile
.QuadPart
= 0LL;
292 Info
->StandardInformation
.Directory
= TRUE
;
296 Info
->StandardInformation
.AllocationSize
= Fcb
->RFCB
.AllocationSize
;
297 Info
->StandardInformation
.EndOfFile
= Fcb
->RFCB
.FileSize
;
298 Info
->StandardInformation
.Directory
= FALSE
;
300 Info
->StandardInformation
.NumberOfLinks
= 0;
301 Info
->StandardInformation
.DeletePending
= FALSE
;
303 /* Internal Information */
304 Info
->InternalInformation
.IndexNumber
.QuadPart
= Fcb
->IndexNumber
.QuadPart
;
307 Info
->EaInformation
.EaSize
= 0;
309 /* Access Information */
310 /* The IO-Manager adds this information */
312 /* Position Information */
313 Info
->PositionInformation
.CurrentByteOffset
.QuadPart
= FileObject
->CurrentByteOffset
.QuadPart
;
315 /* Mode Information */
316 /* The IO-Manager adds this information */
318 /* Alignment Information */
319 /* The IO-Manager adds this information */
321 /* Name Information */
322 Info
->NameInformation
.FileNameLength
= NameLength
;
323 RtlCopyMemory(Info
->NameInformation
.FileName
,
324 Fcb
->PathName
.Buffer
,
325 NameLength
+ sizeof(WCHAR
));
327 *BufferLength
-= (sizeof(FILE_ALL_INFORMATION
) + NameLength
+ sizeof(WCHAR
));
329 return STATUS_SUCCESS
;
334 * FUNCTION: Retrieve the specified file information
337 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject
,
340 FILE_INFORMATION_CLASS FileInformationClass
;
341 PIO_STACK_LOCATION Stack
;
342 PFILE_OBJECT FileObject
;
347 NTSTATUS Status
= STATUS_SUCCESS
;
349 DPRINT("CdfsQueryInformation() called\n");
351 Stack
= IoGetCurrentIrpStackLocation(Irp
);
352 FileInformationClass
= Stack
->Parameters
.QueryFile
.FileInformationClass
;
353 FileObject
= Stack
->FileObject
;
354 Fcb
= FileObject
->FsContext
;
356 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
357 BufferLength
= Stack
->Parameters
.QueryFile
.Length
;
359 switch (FileInformationClass
)
361 case FileStandardInformation
:
362 Status
= CdfsGetStandardInformation(Fcb
,
368 case FilePositionInformation
:
369 Status
= CdfsGetPositionInformation(FileObject
,
374 case FileBasicInformation
:
375 Status
= CdfsGetBasicInformation(FileObject
,
382 case FileNameInformation
:
383 Status
= CdfsGetNameInformation(FileObject
,
390 case FileInternalInformation
:
391 Status
= CdfsGetInternalInformation(Fcb
,
396 case FileNetworkOpenInformation
:
397 Status
= CdfsGetNetworkOpenInformation(Fcb
,
402 case FileAllInformation
:
403 Status
= CdfsGetAllInformation(FileObject
,
409 case FileAlternateNameInformation
:
410 Status
= STATUS_NOT_IMPLEMENTED
;
414 DPRINT("Unimplemented information class %x\n", FileInformationClass
);
415 Status
= STATUS_INVALID_PARAMETER
;
419 Irp
->IoStatus
.Status
= Status
;
420 if (NT_SUCCESS(Status
) || Status
== STATUS_BUFFER_OVERFLOW
)
421 Irp
->IoStatus
.Information
=
422 Stack
->Parameters
.QueryFile
.Length
- BufferLength
;
424 Irp
->IoStatus
.Information
= 0;
426 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
433 * FUNCTION: Set the file position information
436 CdfsSetPositionInformation(PFILE_OBJECT FileObject
,
437 PFILE_POSITION_INFORMATION PositionInfo
)
439 DPRINT ("CdfsSetPositionInformation()\n");
441 DPRINT ("PositionInfo %p\n", PositionInfo
);
442 DPRINT ("Setting position %I64d\n", PositionInfo
->CurrentByteOffset
.QuadPart
);
444 FileObject
->CurrentByteOffset
.QuadPart
=
445 PositionInfo
->CurrentByteOffset
.QuadPart
;
447 return STATUS_SUCCESS
;
452 * FUNCTION: Set the specified file information
455 CdfsSetInformation(PDEVICE_OBJECT DeviceObject
,
458 FILE_INFORMATION_CLASS FileInformationClass
;
459 PIO_STACK_LOCATION Stack
;
460 PFILE_OBJECT FileObject
;
463 NTSTATUS Status
= STATUS_SUCCESS
;
465 UNREFERENCED_PARAMETER(DeviceObject
);
467 DPRINT("CdfsSetInformation() called\n");
469 Stack
= IoGetCurrentIrpStackLocation(Irp
);
470 FileInformationClass
= Stack
->Parameters
.SetFile
.FileInformationClass
;
471 FileObject
= Stack
->FileObject
;
473 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
475 switch (FileInformationClass
)
477 case FilePositionInformation
:
478 Status
= CdfsSetPositionInformation(FileObject
,
482 case FileBasicInformation
:
483 case FileRenameInformation
:
484 Status
= STATUS_NOT_IMPLEMENTED
;
488 Status
= STATUS_NOT_SUPPORTED
;
492 Irp
->IoStatus
.Status
= Status
;
493 Irp
->IoStatus
.Information
= 0;
495 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);