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.
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
30 /* INCLUDES *****************************************************************/
37 /* FUNCTIONS ****************************************************************/
40 * FUNCTION: Retrieve the standard file information
43 CdfsGetStandardInformation(PFCB Fcb
,
44 PDEVICE_OBJECT DeviceObject
,
45 PFILE_STANDARD_INFORMATION StandardInfo
,
48 DPRINT("CdfsGetStandardInformation() called\n");
50 if (*BufferLength
< sizeof(FILE_STANDARD_INFORMATION
))
51 return STATUS_BUFFER_OVERFLOW
;
54 ASSERT(StandardInfo
!= NULL
);
57 RtlZeroMemory(StandardInfo
,
58 sizeof(FILE_STANDARD_INFORMATION
));
60 if (CdfsFCBIsDirectory(Fcb
))
62 StandardInfo
->AllocationSize
.QuadPart
= 0LL;
63 StandardInfo
->EndOfFile
.QuadPart
= 0LL;
64 StandardInfo
->Directory
= TRUE
;
68 StandardInfo
->AllocationSize
= Fcb
->RFCB
.AllocationSize
;
69 StandardInfo
->EndOfFile
= Fcb
->RFCB
.FileSize
;
70 StandardInfo
->Directory
= FALSE
;
72 StandardInfo
->NumberOfLinks
= 0;
73 StandardInfo
->DeletePending
= FALSE
;
75 *BufferLength
-= sizeof(FILE_STANDARD_INFORMATION
);
76 return(STATUS_SUCCESS
);
81 * FUNCTION: Retrieve the file position information
84 CdfsGetPositionInformation(PFILE_OBJECT FileObject
,
85 PFILE_POSITION_INFORMATION PositionInfo
,
88 DPRINT("CdfsGetPositionInformation() called\n");
90 if (*BufferLength
< sizeof(FILE_POSITION_INFORMATION
))
91 return STATUS_BUFFER_OVERFLOW
;
93 PositionInfo
->CurrentByteOffset
.QuadPart
=
94 FileObject
->CurrentByteOffset
.QuadPart
;
96 DPRINT("Getting position %I64x\n",
97 PositionInfo
->CurrentByteOffset
.QuadPart
);
99 *BufferLength
-= sizeof(FILE_POSITION_INFORMATION
);
100 return(STATUS_SUCCESS
);
105 * FUNCTION: Retrieve the basic file information
108 CdfsGetBasicInformation(PFILE_OBJECT FileObject
,
110 PDEVICE_OBJECT DeviceObject
,
111 PFILE_BASIC_INFORMATION BasicInfo
,
114 DPRINT("CdfsGetBasicInformation() called\n");
116 if (*BufferLength
< sizeof(FILE_BASIC_INFORMATION
))
117 return STATUS_BUFFER_OVERFLOW
;
119 CdfsDateTimeToSystemTime(Fcb
,
120 &BasicInfo
->CreationTime
);
121 CdfsDateTimeToSystemTime(Fcb
,
122 &BasicInfo
->LastAccessTime
);
123 CdfsDateTimeToSystemTime(Fcb
,
124 &BasicInfo
->LastWriteTime
);
125 CdfsDateTimeToSystemTime(Fcb
,
126 &BasicInfo
->ChangeTime
);
128 CdfsFileFlagsToAttributes(Fcb
,
129 &BasicInfo
->FileAttributes
);
131 *BufferLength
-= sizeof(FILE_BASIC_INFORMATION
);
133 return(STATUS_SUCCESS
);
138 * FUNCTION: Retrieve the file name information
141 CdfsGetNameInformation(PFILE_OBJECT FileObject
,
143 PDEVICE_OBJECT DeviceObject
,
144 PFILE_NAME_INFORMATION NameInfo
,
150 DPRINT("CdfsGetNameInformation() called\n");
152 ASSERT(NameInfo
!= NULL
);
155 /* If buffer can't hold at least the file name length, bail out */
156 if (*BufferLength
< FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]))
157 return STATUS_BUFFER_OVERFLOW
;
159 /* Calculate file name length in bytes */
160 NameLength
= wcslen(Fcb
->PathName
) * sizeof(WCHAR
);
161 NameInfo
->FileNameLength
= NameLength
;
163 /* Calculate amount of bytes to copy not to overflow the buffer */
164 BytesToCopy
= min(NameLength
,
165 *BufferLength
- FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]));
167 /* Fill in the bytes */
168 RtlCopyMemory(NameInfo
->FileName
, Fcb
->PathName
, BytesToCopy
);
170 /* Check if we could write more but are not able to */
171 if (*BufferLength
< NameLength
+ FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]))
173 /* Return number of bytes written */
174 *BufferLength
-= FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]) + BytesToCopy
;
175 return STATUS_BUFFER_OVERFLOW
;
178 /* We filled up as many bytes, as needed */
179 *BufferLength
-= (FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
[0]) + NameLength
);
181 return STATUS_SUCCESS
;
186 * FUNCTION: Retrieve the internal file information
189 CdfsGetInternalInformation(PFCB Fcb
,
190 PFILE_INTERNAL_INFORMATION InternalInfo
,
193 DPRINT("CdfsGetInternalInformation() called\n");
195 ASSERT(InternalInfo
);
198 if (*BufferLength
< sizeof(FILE_INTERNAL_INFORMATION
))
199 return(STATUS_BUFFER_OVERFLOW
);
201 InternalInfo
->IndexNumber
.QuadPart
= Fcb
->IndexNumber
.QuadPart
;
203 *BufferLength
-= sizeof(FILE_INTERNAL_INFORMATION
);
205 return(STATUS_SUCCESS
);
210 * FUNCTION: Retrieve the file network open information
213 CdfsGetNetworkOpenInformation(PFCB Fcb
,
214 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo
,
220 if (*BufferLength
< sizeof(FILE_NETWORK_OPEN_INFORMATION
))
221 return(STATUS_BUFFER_OVERFLOW
);
223 CdfsDateTimeToSystemTime(Fcb
,
224 &NetworkInfo
->CreationTime
);
225 CdfsDateTimeToSystemTime(Fcb
,
226 &NetworkInfo
->LastAccessTime
);
227 CdfsDateTimeToSystemTime(Fcb
,
228 &NetworkInfo
->LastWriteTime
);
229 CdfsDateTimeToSystemTime(Fcb
,
230 &NetworkInfo
->ChangeTime
);
231 if (CdfsFCBIsDirectory(Fcb
))
233 NetworkInfo
->AllocationSize
.QuadPart
= 0LL;
234 NetworkInfo
->EndOfFile
.QuadPart
= 0LL;
238 NetworkInfo
->AllocationSize
= Fcb
->RFCB
.AllocationSize
;
239 NetworkInfo
->EndOfFile
= Fcb
->RFCB
.FileSize
;
241 CdfsFileFlagsToAttributes(Fcb
,
242 &NetworkInfo
->FileAttributes
);
244 *BufferLength
-= sizeof(FILE_NETWORK_OPEN_INFORMATION
);
246 return(STATUS_SUCCESS
);
251 * FUNCTION: Retrieve all file information
254 CdfsGetAllInformation(PFILE_OBJECT FileObject
,
256 PFILE_ALL_INFORMATION Info
,
264 NameLength
= wcslen(Fcb
->PathName
) * sizeof(WCHAR
);
265 if (*BufferLength
< sizeof(FILE_ALL_INFORMATION
) + NameLength
)
266 return(STATUS_BUFFER_OVERFLOW
);
268 /* Basic Information */
269 CdfsDateTimeToSystemTime(Fcb
,
270 &Info
->BasicInformation
.CreationTime
);
271 CdfsDateTimeToSystemTime(Fcb
,
272 &Info
->BasicInformation
.LastAccessTime
);
273 CdfsDateTimeToSystemTime(Fcb
,
274 &Info
->BasicInformation
.LastWriteTime
);
275 CdfsDateTimeToSystemTime(Fcb
,
276 &Info
->BasicInformation
.ChangeTime
);
277 CdfsFileFlagsToAttributes(Fcb
,
278 &Info
->BasicInformation
.FileAttributes
);
280 /* Standard Information */
281 if (CdfsFCBIsDirectory(Fcb
))
283 Info
->StandardInformation
.AllocationSize
.QuadPart
= 0LL;
284 Info
->StandardInformation
.EndOfFile
.QuadPart
= 0LL;
285 Info
->StandardInformation
.Directory
= TRUE
;
289 Info
->StandardInformation
.AllocationSize
= Fcb
->RFCB
.AllocationSize
;
290 Info
->StandardInformation
.EndOfFile
= Fcb
->RFCB
.FileSize
;
291 Info
->StandardInformation
.Directory
= FALSE
;
293 Info
->StandardInformation
.NumberOfLinks
= 0;
294 Info
->StandardInformation
.DeletePending
= FALSE
;
296 /* Internal Information */
297 Info
->InternalInformation
.IndexNumber
.QuadPart
= Fcb
->IndexNumber
.QuadPart
;
300 Info
->EaInformation
.EaSize
= 0;
302 /* Access Information */
303 /* The IO-Manager adds this information */
305 /* Position Information */
306 Info
->PositionInformation
.CurrentByteOffset
.QuadPart
= FileObject
->CurrentByteOffset
.QuadPart
;
308 /* Mode Information */
309 /* The IO-Manager adds this information */
311 /* Alignment Information */
312 /* The IO-Manager adds this information */
314 /* Name Information */
315 Info
->NameInformation
.FileNameLength
= NameLength
;
316 RtlCopyMemory(Info
->NameInformation
.FileName
,
318 NameLength
+ sizeof(WCHAR
));
320 *BufferLength
-= (sizeof(FILE_ALL_INFORMATION
) + NameLength
+ sizeof(WCHAR
));
322 return STATUS_SUCCESS
;
327 * FUNCTION: Retrieve the specified file information
330 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject
,
333 FILE_INFORMATION_CLASS FileInformationClass
;
334 PIO_STACK_LOCATION Stack
;
335 PFILE_OBJECT FileObject
;
340 NTSTATUS Status
= STATUS_SUCCESS
;
342 DPRINT("CdfsQueryInformation() called\n");
344 Stack
= IoGetCurrentIrpStackLocation(Irp
);
345 FileInformationClass
= Stack
->Parameters
.QueryFile
.FileInformationClass
;
346 FileObject
= Stack
->FileObject
;
347 Fcb
= FileObject
->FsContext
;
349 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
350 BufferLength
= Stack
->Parameters
.QueryFile
.Length
;
352 switch (FileInformationClass
)
354 case FileStandardInformation
:
355 Status
= CdfsGetStandardInformation(Fcb
,
361 case FilePositionInformation
:
362 Status
= CdfsGetPositionInformation(FileObject
,
367 case FileBasicInformation
:
368 Status
= CdfsGetBasicInformation(FileObject
,
375 case FileNameInformation
:
376 Status
= CdfsGetNameInformation(FileObject
,
383 case FileInternalInformation
:
384 Status
= CdfsGetInternalInformation(Fcb
,
389 case FileNetworkOpenInformation
:
390 Status
= CdfsGetNetworkOpenInformation(Fcb
,
395 case FileAllInformation
:
396 Status
= CdfsGetAllInformation(FileObject
,
402 case FileAlternateNameInformation
:
403 Status
= STATUS_NOT_IMPLEMENTED
;
407 DPRINT("Unimplemented information class %u\n", FileInformationClass
);
408 Status
= STATUS_INVALID_PARAMETER
;
412 Irp
->IoStatus
.Status
= Status
;
413 if (NT_SUCCESS(Status
) || Status
== STATUS_BUFFER_OVERFLOW
)
414 Irp
->IoStatus
.Information
=
415 Stack
->Parameters
.QueryFile
.Length
- BufferLength
;
417 Irp
->IoStatus
.Information
= 0;
419 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
426 * FUNCTION: Set the file position information
429 CdfsSetPositionInformation(PFILE_OBJECT FileObject
,
430 PFILE_POSITION_INFORMATION PositionInfo
)
432 DPRINT ("CdfsSetPositionInformation()\n");
434 DPRINT ("PositionInfo %x\n", PositionInfo
);
435 DPRINT ("Setting position %I64u\n", PositionInfo
->CurrentByteOffset
.QuadPart
);
437 FileObject
->CurrentByteOffset
.QuadPart
=
438 PositionInfo
->CurrentByteOffset
.QuadPart
;
440 return STATUS_SUCCESS
;
445 * FUNCTION: Set the specified file information
448 CdfsSetInformation(PDEVICE_OBJECT DeviceObject
,
451 FILE_INFORMATION_CLASS FileInformationClass
;
452 PIO_STACK_LOCATION Stack
;
453 PFILE_OBJECT FileObject
;
457 NTSTATUS Status
= STATUS_SUCCESS
;
459 DPRINT("CdfsSetInformation() called\n");
461 Stack
= IoGetCurrentIrpStackLocation(Irp
);
462 FileInformationClass
= Stack
->Parameters
.SetFile
.FileInformationClass
;
463 FileObject
= Stack
->FileObject
;
464 Fcb
= FileObject
->FsContext
;
466 SystemBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
468 switch (FileInformationClass
)
470 case FilePositionInformation
:
471 Status
= CdfsSetPositionInformation(FileObject
,
475 case FileBasicInformation
:
476 case FileRenameInformation
:
477 Status
= STATUS_NOT_IMPLEMENTED
;
481 Status
= STATUS_NOT_SUPPORTED
;
485 Irp
->IoStatus
.Status
= Status
;
486 Irp
->IoStatus
.Information
= 0;
488 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);