3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the File Information routines for Cdfs called by
12 the Fsd/Fsp dispatch drivers.
20 // The Bug check file id for this module
23 #define BugCheckFileId (CDFS_BUG_CHECK_FILEINFO)
26 // Local support routines
31 IN PIRP_CONTEXT IrpContext
,
33 IN OUT PFILE_BASIC_INFORMATION Buffer
,
39 IN PIRP_CONTEXT IrpContext
,
41 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
47 IN PIRP_CONTEXT IrpContext
,
49 IN OUT PFILE_INTERNAL_INFORMATION Buffer
,
55 IN PIRP_CONTEXT IrpContext
,
57 IN OUT PFILE_EA_INFORMATION Buffer
,
63 IN PIRP_CONTEXT IrpContext
,
64 IN PFILE_OBJECT FileObject
,
65 IN OUT PFILE_POSITION_INFORMATION Buffer
,
71 IN PIRP_CONTEXT IrpContext
,
72 IN PFILE_OBJECT FileObject
,
73 IN OUT PFILE_NAME_INFORMATION Buffer
,
78 CdQueryAlternateNameInfo (
79 IN PIRP_CONTEXT IrpContext
,
82 IN OUT PFILE_NAME_INFORMATION Buffer
,
88 IN PIRP_CONTEXT IrpContext
,
90 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
,
95 #pragma alloc_text(PAGE, CdCommonQueryInfo)
96 #pragma alloc_text(PAGE, CdCommonSetInfo)
97 #pragma alloc_text(PAGE, CdFastQueryBasicInfo)
98 #pragma alloc_text(PAGE, CdFastQueryStdInfo)
99 #pragma alloc_text(PAGE, CdFastQueryNetworkInfo)
100 #pragma alloc_text(PAGE, CdQueryAlternateNameInfo)
101 #pragma alloc_text(PAGE, CdQueryBasicInfo)
102 #pragma alloc_text(PAGE, CdQueryEaInfo)
103 #pragma alloc_text(PAGE, CdQueryInternalInfo)
104 #pragma alloc_text(PAGE, CdQueryNameInfo)
105 #pragma alloc_text(PAGE, CdQueryNetworkInfo)
106 #pragma alloc_text(PAGE, CdQueryPositionInfo)
107 #pragma alloc_text(PAGE, CdQueryStandardInfo)
113 IN PIRP_CONTEXT IrpContext
,
121 This is the common routine for query file information called by both the
126 Irp - Supplies the Irp to process.
130 NTSTATUS - The return status for this operation.
135 NTSTATUS Status
= STATUS_SUCCESS
;
136 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
139 FILE_INFORMATION_CLASS FileInformationClass
;
140 PFILE_ALL_INFORMATION Buffer
;
142 TYPE_OF_OPEN TypeOfOpen
;
146 BOOLEAN ReleaseFcb
= FALSE
;
151 // Reference our input parameters to make things easier
154 Length
= IrpSp
->Parameters
.QueryFile
.Length
;
155 FileInformationClass
= IrpSp
->Parameters
.QueryFile
.FileInformationClass
;
156 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
159 // Decode the file object
162 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
165 // Use a try-finally to facilitate cleanup.
171 // We only support query on file and directory handles.
174 switch (TypeOfOpen
) {
176 case UserDirectoryOpen
:
180 // Acquire shared access to this file. NOTE that this could be
181 // a recursive acquire, if we already preacquired in
182 // CdAcquireForCreateSection().
185 CdAcquireFileShared( IrpContext
, Fcb
);
189 // Make sure we have the correct sizes for a directory.
192 if (!FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
)) {
194 ASSERT( TypeOfOpen
== UserDirectoryOpen
);
195 CdCreateInternalStream( IrpContext
, Fcb
->Vcb
, Fcb
);
199 // Make sure the Fcb is in a usable condition. This will raise
200 // an error condition if the volume is unusable
203 CdVerifyFcbOperation( IrpContext
, Fcb
);
206 // Based on the information class we'll do different
207 // actions. Each of hte procedures that we're calling fills
208 // up the output buffer, if possible. They will raise the
209 // status STATUS_BUFFER_OVERFLOW for an insufficient buffer.
210 // This is considered a somewhat unusual case and is handled
211 // more cleanly with the exception mechanism rather than
212 // testing a return status value for each call.
215 switch (FileInformationClass
) {
217 case FileAllInformation
:
220 // We don't allow this operation on a file opened by file Id.
223 if (FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_BY_ID
)) {
225 Status
= STATUS_INVALID_PARAMETER
;
230 // In this case go ahead and call the individual routines to
231 // fill in the buffer. Only the name routine will
232 // pointer to the output buffer and then call the
233 // individual routines to fill in the buffer.
236 Length
-= (sizeof( FILE_ACCESS_INFORMATION
) +
237 sizeof( FILE_MODE_INFORMATION
) +
238 sizeof( FILE_ALIGNMENT_INFORMATION
));
240 CdQueryBasicInfo( IrpContext
, Fcb
, &Buffer
->BasicInformation
, &Length
);
241 CdQueryStandardInfo( IrpContext
, Fcb
, &Buffer
->StandardInformation
, &Length
);
242 CdQueryInternalInfo( IrpContext
, Fcb
, &Buffer
->InternalInformation
, &Length
);
243 CdQueryEaInfo( IrpContext
, Fcb
, &Buffer
->EaInformation
, &Length
);
244 CdQueryPositionInfo( IrpContext
, IrpSp
->FileObject
, &Buffer
->PositionInformation
, &Length
);
245 Status
= CdQueryNameInfo( IrpContext
, IrpSp
->FileObject
, &Buffer
->NameInformation
, &Length
);
249 case FileBasicInformation
:
251 CdQueryBasicInfo( IrpContext
, Fcb
, (PFILE_BASIC_INFORMATION
) Buffer
, &Length
);
254 case FileStandardInformation
:
256 CdQueryStandardInfo( IrpContext
, Fcb
, (PFILE_STANDARD_INFORMATION
) Buffer
, &Length
);
259 case FileInternalInformation
:
261 CdQueryInternalInfo( IrpContext
, Fcb
, (PFILE_INTERNAL_INFORMATION
) Buffer
, &Length
);
264 case FileEaInformation
:
266 CdQueryEaInfo( IrpContext
, Fcb
, (PFILE_EA_INFORMATION
) Buffer
, &Length
);
269 case FilePositionInformation
:
271 CdQueryPositionInfo( IrpContext
, IrpSp
->FileObject
, (PFILE_POSITION_INFORMATION
) Buffer
, &Length
);
274 case FileNameInformation
:
277 // We don't allow this operation on a file opened by file Id.
280 if (!FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_BY_ID
)) {
282 Status
= CdQueryNameInfo( IrpContext
, IrpSp
->FileObject
, (PFILE_NAME_INFORMATION
) Buffer
, &Length
);
286 Status
= STATUS_INVALID_PARAMETER
;
291 case FileAlternateNameInformation
:
293 if (!FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_BY_ID
)) {
295 Status
= CdQueryAlternateNameInfo( IrpContext
, Fcb
, Ccb
, (PFILE_NAME_INFORMATION
) Buffer
, &Length
);
299 Status
= STATUS_INVALID_PARAMETER
;
304 case FileNetworkOpenInformation
:
306 CdQueryNetworkInfo( IrpContext
, Fcb
, (PFILE_NETWORK_OPEN_INFORMATION
) Buffer
, &Length
);
311 Status
= STATUS_INVALID_PARAMETER
;
318 Status
= STATUS_INVALID_PARAMETER
;
322 // Set the information field to the number of bytes actually filled in
323 // and then complete the request
326 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryFile
.Length
- Length
;
336 CdReleaseFile( IrpContext
, Fcb
);
341 // Complete the request if we didn't raise.
344 CdCompleteRequest( IrpContext
, Irp
, Status
);
352 IN PIRP_CONTEXT IrpContext
,
360 This is the common routine for set file information called by both the
361 fsd and fsp threads. We only support operations which set the file position.
365 Irp - Supplies the Irp to process.
369 NTSTATUS - The return status for this operation.
374 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
376 TYPE_OF_OPEN TypeOfOpen
;
380 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
382 PFILE_POSITION_INFORMATION Buffer
;
387 // Decode the file object
390 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
393 // We only support a SetPositionInformation on a user file.
396 if ((TypeOfOpen
!= UserFileOpen
) ||
397 (IrpSp
->Parameters
.QueryFile
.FileInformationClass
!= FilePositionInformation
)) {
399 CdCompleteRequest( IrpContext
, Irp
, Status
);
404 // Acquire shared access to this file.
407 CdAcquireFileShared( IrpContext
, Fcb
);
412 // Make sure the Fcb is in a usable condition. This
413 // will raise an error condition if the fcb is unusable
416 CdVerifyFcbOperation( IrpContext
, Fcb
);
418 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
421 // Check if the file does not use intermediate buffering. If it
422 // does not use intermediate buffering then the new position we're
423 // supplied must be aligned properly for the device
426 if (FlagOn( IrpSp
->FileObject
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
) &&
427 ((Buffer
->CurrentByteOffset
.LowPart
& Fcb
->Vcb
->BlockMask
) != 0)) {
429 try_return( NOTHING
);
433 // The input parameter is fine so set the current byte offset and
434 // complete the request
438 // Lock the Fcb to provide synchronization.
441 CdLockFcb( IrpContext
, Fcb
);
442 IrpSp
->FileObject
->CurrentByteOffset
= Buffer
->CurrentByteOffset
;
443 CdUnlockFcb( IrpContext
, Fcb
);
445 Status
= STATUS_SUCCESS
;
450 CdReleaseFile( IrpContext
, Fcb
);
454 // Complete the request if there was no raise.
457 CdCompleteRequest( IrpContext
, Irp
, Status
);
463 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
464 CdFastQueryBasicInfo (
465 IN PFILE_OBJECT FileObject
,
467 IN OUT PFILE_BASIC_INFORMATION Buffer
,
468 OUT PIO_STATUS_BLOCK IoStatus
,
469 IN PDEVICE_OBJECT DeviceObject
476 This routine is for the fast query call for basic file information.
480 FileObject - Supplies the file object used in this operation
482 Wait - Indicates if we are allowed to wait for the information
484 Buffer - Supplies the output buffer to receive the basic information
486 IoStatus - Receives the final status of the operation
490 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
491 needs to take the long route.
496 BOOLEAN Result
= FALSE
;
497 TYPE_OF_OPEN TypeOfOpen
;
503 ASSERT_FILE_OBJECT( FileObject
);
505 FsRtlEnterFileSystem();
508 // Decode the file object to find the type of open and the data
512 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
515 // We only support this request on user file or directory objects.
518 if ((TypeOfOpen
!= UserFileOpen
) &&
519 ((TypeOfOpen
!= UserDirectoryOpen
) || !FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
))) {
521 FsRtlExitFileSystem();
526 // Acquire the file shared to access the Fcb.
529 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
531 FsRtlExitFileSystem();
536 // Use a try-finally to facilitate cleanup.
542 // Only deal with 'good' Fcb's.
545 if (CdVerifyFcbOperation( NULL
, Fcb
)) {
548 // Fill in the input buffer from the Fcb fields.
551 Buffer
->CreationTime
.QuadPart
=
552 Buffer
->LastWriteTime
.QuadPart
=
553 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
555 Buffer
->LastAccessTime
.QuadPart
= 0;
557 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
560 // Update the IoStatus block with the size of this data.
563 IoStatus
->Status
= STATUS_SUCCESS
;
564 IoStatus
->Information
= sizeof( FILE_BASIC_INFORMATION
);
571 ExReleaseResourceLite( Fcb
->Resource
);
573 FsRtlExitFileSystem();
581 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
583 IN PFILE_OBJECT FileObject
,
585 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
586 OUT PIO_STATUS_BLOCK IoStatus
,
587 IN PDEVICE_OBJECT DeviceObject
594 This routine is for the fast query call for standard file information.
598 FileObject - Supplies the file object used in this operation
600 Wait - Indicates if we are allowed to wait for the information
602 Buffer - Supplies the output buffer to receive the basic information
604 IoStatus - Receives the final status of the operation
608 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
609 needs to take the long route.
614 BOOLEAN Result
= FALSE
;
615 TYPE_OF_OPEN TypeOfOpen
;
621 ASSERT_FILE_OBJECT( FileObject
);
623 FsRtlEnterFileSystem();
626 // Decode the file object to find the type of open and the data
630 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
633 // We only support this request on initialized user file or directory objects.
636 if ((TypeOfOpen
!= UserFileOpen
) &&
637 ((TypeOfOpen
!= UserDirectoryOpen
) || !FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
))) {
639 FsRtlExitFileSystem();
644 // Acquire the file shared to access the Fcb.
647 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
649 FsRtlExitFileSystem();
654 // Use a try-finally to facilitate cleanup.
660 // Only deal with 'good' Fcb's.
663 if (CdVerifyFcbOperation( NULL
, Fcb
)) {
666 // Check whether this is a directory.
669 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
671 Buffer
->AllocationSize
.QuadPart
=
672 Buffer
->EndOfFile
.QuadPart
= 0;
674 Buffer
->Directory
= TRUE
;
678 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
679 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
681 Buffer
->Directory
= FALSE
;
684 Buffer
->NumberOfLinks
= 1;
685 Buffer
->DeletePending
= FALSE
;
688 // Update the IoStatus block with the size of this data.
691 IoStatus
->Status
= STATUS_SUCCESS
;
692 IoStatus
->Information
= sizeof( FILE_STANDARD_INFORMATION
);
699 ExReleaseResourceLite( Fcb
->Resource
);
701 FsRtlExitFileSystem();
709 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
710 CdFastQueryNetworkInfo (
711 IN PFILE_OBJECT FileObject
,
713 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
,
714 OUT PIO_STATUS_BLOCK IoStatus
,
715 IN PDEVICE_OBJECT DeviceObject
722 This routine is for the fast query call for network file information.
726 FileObject - Supplies the file object used in this operation
728 Wait - Indicates if we are allowed to wait for the information
730 Buffer - Supplies the output buffer to receive the basic information
732 IoStatus - Receives the final status of the operation
736 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
737 needs to take the long route.
742 BOOLEAN Result
= FALSE
;
743 TYPE_OF_OPEN TypeOfOpen
;
749 ASSERT_FILE_OBJECT( FileObject
);
751 FsRtlEnterFileSystem();
754 // Decode the file object to find the type of open and the data
758 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
761 // We only support this request on user file or directory objects.
764 if ((TypeOfOpen
!= UserFileOpen
) &&
765 ((TypeOfOpen
!= UserDirectoryOpen
) || !FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
))) {
767 FsRtlExitFileSystem();
772 // Acquire the file shared to access the Fcb.
775 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
777 FsRtlExitFileSystem();
782 // Use a try-finally to facilitate cleanup.
788 // Only deal with 'good' Fcb's.
791 if (CdVerifyFcbOperation( NULL
, Fcb
)) {
794 // Fill in the input buffer from the Fcb fields.
797 Buffer
->CreationTime
.QuadPart
=
798 Buffer
->LastWriteTime
.QuadPart
=
799 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
801 Buffer
->LastAccessTime
.QuadPart
= 0;
803 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
806 // Check whether this is a directory.
809 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
811 Buffer
->AllocationSize
.QuadPart
=
812 Buffer
->EndOfFile
.QuadPart
= 0;
816 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
817 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
821 // Update the IoStatus block with the size of this data.
824 IoStatus
->Status
= STATUS_SUCCESS
;
825 IoStatus
->Information
= sizeof( FILE_NETWORK_OPEN_INFORMATION
);
832 ExReleaseResourceLite( Fcb
->Resource
);
834 FsRtlExitFileSystem();
842 // Local support routine
847 IN PIRP_CONTEXT IrpContext
,
849 IN OUT PFILE_BASIC_INFORMATION Buffer
,
857 This routine performs the query basic information function for Cdfs
861 Fcb - Supplies the Fcb being queried, it has been verified
863 Buffer - Supplies a pointer to the buffer where the information is to
866 Length - Supplies the length of the buffer in bytes, and receives the
867 remaining bytes free in the buffer upon return.
879 // We only support creation, last modify and last write times on Cdfs.
882 Buffer
->LastWriteTime
.QuadPart
=
883 Buffer
->CreationTime
.QuadPart
=
884 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
886 Buffer
->LastAccessTime
.QuadPart
= 0;
888 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
891 // Update the length and status output variables
894 *Length
-= sizeof( FILE_BASIC_INFORMATION
);
901 // Local support routine
905 CdQueryStandardInfo (
906 IN PIRP_CONTEXT IrpContext
,
908 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
915 This routine performs the query standard information function for cdfs.
919 Fcb - Supplies the Fcb being queried, it has been verified
921 Buffer - Supplies a pointer to the buffer where the information is to
924 Length - Supplies the length of the buffer in bytes, and receives the
925 remaining bytes free in the buffer upon return.
937 // There is only one link and delete is never pending on a Cdrom file.
940 Buffer
->NumberOfLinks
= 1;
941 Buffer
->DeletePending
= FALSE
;
944 // We get the sizes from the header. Return a size of zero
945 // for all directories.
948 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
950 Buffer
->AllocationSize
.QuadPart
=
951 Buffer
->EndOfFile
.QuadPart
= 0;
953 Buffer
->Directory
= TRUE
;
957 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
958 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
960 Buffer
->Directory
= FALSE
;
964 // Update the length and status output variables
967 *Length
-= sizeof( FILE_STANDARD_INFORMATION
);
974 // Local support routine
978 CdQueryInternalInfo (
979 IN PIRP_CONTEXT IrpContext
,
981 IN OUT PFILE_INTERNAL_INFORMATION Buffer
,
989 This routine performs the query internal information function for cdfs.
993 Fcb - Supplies the Fcb being queried, it has been verified
995 Buffer - Supplies a pointer to the buffer where the information is to
998 Length - Supplies the length of the buffer in bytes, and receives the
999 remaining bytes free in the buffer upon return.
1011 // Index number is the file Id number in the Fcb.
1014 Buffer
->IndexNumber
= Fcb
->FileId
;
1015 *Length
-= sizeof( FILE_INTERNAL_INFORMATION
);
1022 // Local support routine
1027 IN PIRP_CONTEXT IrpContext
,
1029 IN OUT PFILE_EA_INFORMATION Buffer
,
1030 IN OUT PULONG Length
1035 Routine Description:
1037 This routine performs the query Ea information function for cdfs.
1041 Fcb - Supplies the Fcb being queried, it has been verified
1043 Buffer - Supplies a pointer to the buffer where the information is to
1046 Length - Supplies the length of the buffer in bytes, and receives the
1047 remaining bytes free in the buffer upon return.
1059 // No Ea's on Cdfs volumes.
1063 *Length
-= sizeof( FILE_EA_INFORMATION
);
1070 // Local support routine
1074 CdQueryPositionInfo (
1075 IN PIRP_CONTEXT IrpContext
,
1076 IN PFILE_OBJECT FileObject
,
1077 IN OUT PFILE_POSITION_INFORMATION Buffer
,
1078 IN OUT PULONG Length
1083 Routine Description:
1085 This routine performs the query position information function for cdfs.
1089 FileObject - Supplies the File object being queried
1091 Buffer - Supplies a pointer to the buffer where the information is to
1094 Length - Supplies the length of the buffer in bytes, and receives the
1095 remaining bytes free in the buffer upon return.
1107 // Get the current position found in the file object.
1110 Buffer
->CurrentByteOffset
= FileObject
->CurrentByteOffset
;
1113 // Update the length and status output variables
1116 *Length
-= sizeof( FILE_POSITION_INFORMATION
);
1123 // Local support routine
1128 IN PIRP_CONTEXT IrpContext
,
1129 IN PFILE_OBJECT FileObject
,
1130 IN OUT PFILE_NAME_INFORMATION Buffer
,
1131 IN OUT PULONG Length
1136 Routine Description:
1138 This routine performs the query name information function for cdfs.
1142 FileObject - Supplies the file object containing the name.
1144 Buffer - Supplies a pointer to the buffer where the information is to
1147 Length - Supplies the length of the buffer in bytes, and receives the
1148 remaining bytes free in the buffer upon return.
1152 NTSTATUS - STATUS_BUFFER_OVERFLOW if the entire name can't be copied.
1157 NTSTATUS Status
= STATUS_SUCCESS
;
1162 ASSERT(*Length
>= sizeof(ULONG
));
1165 // Simply copy the name in the file object to the user's buffer.
1169 // Place the size of the filename in the user's buffer and reduce the remaining
1173 Buffer
->FileNameLength
= LengthToCopy
= FileObject
->FileName
.Length
;
1174 *Length
-= sizeof(ULONG
);
1176 if (LengthToCopy
> *Length
) {
1178 LengthToCopy
= *Length
;
1179 Status
= STATUS_BUFFER_OVERFLOW
;
1182 RtlCopyMemory( Buffer
->FileName
, FileObject
->FileName
.Buffer
, LengthToCopy
);
1185 // Reduce the available bytes by the amount stored into this buffer. In the overflow
1186 // case, this simply drops to zero. The returned filenamelength will indicate to the
1187 // caller how much space is required.
1190 *Length
-= LengthToCopy
;
1197 // Local support routine
1201 CdQueryAlternateNameInfo (
1202 IN PIRP_CONTEXT IrpContext
,
1205 IN OUT PFILE_NAME_INFORMATION Buffer
,
1206 IN OUT PULONG Length
1211 Routine Description:
1213 This routine performs the query alternate name information function.
1214 We lookup the dirent for this file and then check if there is a
1219 Fcb - Supplies the Fcb being queried, it has been verified.
1221 Ccb - Ccb for this open handle.
1223 Buffer - Supplies a pointer to the buffer where the information is to
1226 Length - Supplies the length of the buffer in bytes, and receives the
1227 remaining bytes free in the buffer upon return.
1231 NTSTATUS - STATUS_SUCCESS if the whole name would fit into the user buffer,
1232 STATUS_OBJECT_NAME_NOT_FOUND if we can't return the name,
1233 STATUS_BUFFER_OVERFLOW otherwise.
1238 NTSTATUS Status
= STATUS_SUCCESS
;
1240 DIRENT_ENUM_CONTEXT DirContext
;
1243 PUNICODE_STRING NameToUse
;
1246 COMPOUND_PATH_ENTRY CompoundPathEntry
;
1247 FILE_ENUM_CONTEXT FileContext
;
1250 BOOLEAN ReleaseParentFcb
= FALSE
;
1252 BOOLEAN CleanupFileLookup
= FALSE
;
1253 BOOLEAN CleanupDirectoryLookup
= FALSE
;
1255 WCHAR ShortNameBuffer
[ BYTE_COUNT_8_DOT_3
/ 2 ];
1256 USHORT ShortNameLength
;
1261 // Initialize the buffer length to zero.
1264 Buffer
->FileNameLength
= 0;
1267 // If this is the root or this file was opened using a version number then
1268 // there is no short name.
1271 if ((Fcb
== Fcb
->Vcb
->RootIndexFcb
) ||
1272 FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_WITH_VERSION
)) {
1274 return STATUS_OBJECT_NAME_NOT_FOUND
;
1278 // Use a try-finally to cleanup the structures.
1283 ParentFcb
= Fcb
->ParentFcb
;
1284 CdAcquireFileShared( IrpContext
, ParentFcb
);
1285 ReleaseParentFcb
= TRUE
;
1288 // Do an unsafe test to see if we need to create a file object.
1291 if (ParentFcb
->FileObject
== NULL
) {
1293 CdCreateInternalStream( IrpContext
, ParentFcb
->Vcb
, ParentFcb
);
1296 if (CdFidIsDirectory( Fcb
->FileId
)) {
1299 // Fcb is for a directory, so we need to dig the dirent from the parent. In
1300 // order to do this we need to get the name of the directory from its pathtable
1301 // entry and then search in the parent for a matching dirent.
1303 // This could be optimized somewhat.
1306 CdInitializeCompoundPathEntry( IrpContext
, &CompoundPathEntry
);
1307 CdInitializeFileContext( IrpContext
, &FileContext
);
1309 CleanupDirectoryLookup
= TRUE
;
1311 CdLookupPathEntry( IrpContext
,
1312 CdQueryFidPathTableOffset( Fcb
->FileId
),
1315 &CompoundPathEntry
);
1317 CdUpdatePathEntryName( IrpContext
, &CompoundPathEntry
.PathEntry
, TRUE
);
1319 if (!CdFindDirectory( IrpContext
,
1321 &CompoundPathEntry
.PathEntry
.CdCaseDirName
,
1326 // If we failed to find the child directory by name in the parent
1327 // something is quite wrong with this disc.
1330 CdRaiseStatus( IrpContext
, STATUS_DISK_CORRUPT_ERROR
);
1333 NameToUse
= &FileContext
.InitialDirent
->Dirent
.CdCaseFileName
.FileName
;
1334 DirentOffset
= FileContext
.InitialDirent
->Dirent
.DirentOffset
;
1339 // Initialize the search dirent structures.
1342 CdInitializeDirContext( IrpContext
, &DirContext
);
1343 CdInitializeDirent( IrpContext
, &Dirent
);
1345 CleanupFileLookup
= TRUE
;
1347 CdLookupDirent( IrpContext
,
1349 CdQueryFidDirentOffset( Fcb
->FileId
),
1352 CdUpdateDirentFromRawDirent( IrpContext
,
1358 // Now update the dirent name.
1361 CdUpdateDirentName( IrpContext
, &Dirent
, TRUE
);
1363 NameToUse
= &Dirent
.CdCaseFileName
.FileName
;
1364 DirentOffset
= Dirent
.DirentOffset
;
1368 // If the name is 8.3 then fail this request.
1371 if (CdIs8dot3Name( IrpContext
,
1375 try_return( Status
= STATUS_OBJECT_NAME_NOT_FOUND
);
1378 CdGenerate8dot3Name( IrpContext
,
1385 // We now have the short name. We have left it in Unicode form so copy it directly.
1388 Buffer
->FileNameLength
= ShortNameLength
;
1390 if (Buffer
->FileNameLength
+ sizeof( ULONG
) > *Length
) {
1392 Buffer
->FileNameLength
= *Length
- sizeof( ULONG
);
1393 Status
= STATUS_BUFFER_OVERFLOW
;
1396 RtlCopyMemory( Buffer
->FileName
, ShortNameBuffer
, Buffer
->FileNameLength
);
1401 if (CleanupFileLookup
) {
1403 CdCleanupDirContext( IrpContext
, &DirContext
);
1404 CdCleanupDirent( IrpContext
, &Dirent
);
1406 } else if (CleanupDirectoryLookup
) {
1408 CdCleanupCompoundPathEntry( IrpContext
, &CompoundPathEntry
);
1409 CdCleanupFileContext( IrpContext
, &FileContext
);
1412 if (ReleaseParentFcb
) {
1414 CdReleaseFile( IrpContext
, ParentFcb
);
1419 // Reduce the available bytes by the amount stored into this buffer.
1422 if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
) {
1424 *Length
-= sizeof( ULONG
) + Buffer
->FileNameLength
;
1432 // Local support routine
1436 CdQueryNetworkInfo (
1437 IN PIRP_CONTEXT IrpContext
,
1439 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1440 IN OUT PULONG Length
1447 This routine performs the query network open information function for Cdfs
1451 Fcb - Supplies the Fcb being queried, it has been verified
1453 Buffer - Supplies a pointer to the buffer where the information is to
1456 Length - Supplies the length of the buffer in bytes, and receives the
1457 remaining bytes free in the buffer upon return.
1469 // We only support creation, last modify and last write times on Cdfs.
1472 Buffer
->LastWriteTime
.QuadPart
=
1473 Buffer
->CreationTime
.QuadPart
=
1474 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
1476 Buffer
->LastAccessTime
.QuadPart
= 0;
1478 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
1481 // We get the sizes from the header. Return a size of zero
1482 // for all directories.
1485 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
1487 Buffer
->AllocationSize
.QuadPart
=
1488 Buffer
->EndOfFile
.QuadPart
= 0;
1492 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
1493 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
1497 // Update the length and status output variables
1500 *Length
-= sizeof( FILE_NETWORK_OPEN_INFORMATION
);