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 _Out_ PFILE_BASIC_INFORMATION Buffer
,
39 _In_ PIRP_CONTEXT IrpContext
,
41 _Out_ PFILE_STANDARD_INFORMATION Buffer
,
47 _In_ PIRP_CONTEXT IrpContext
,
49 _Out_ PFILE_INTERNAL_INFORMATION Buffer
,
55 _In_ PIRP_CONTEXT IrpContext
,
57 _Out_ PFILE_EA_INFORMATION Buffer
,
63 _In_ PIRP_CONTEXT IrpContext
,
64 _In_ PFILE_OBJECT FileObject
,
65 _Out_ PFILE_POSITION_INFORMATION Buffer
,
71 _In_ PIRP_CONTEXT IrpContext
,
72 _In_ PFILE_OBJECT FileObject
,
73 _Out_ PFILE_NAME_INFORMATION Buffer
,
77 _Requires_lock_held_(_Global_critical_region_
)
79 CdQueryAlternateNameInfo (
80 _In_ PIRP_CONTEXT IrpContext
,
83 _Out_ PFILE_NAME_INFORMATION Buffer
,
89 _In_ PIRP_CONTEXT IrpContext
,
91 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer
,
96 #pragma alloc_text(PAGE, CdCommonQueryInfo)
97 #pragma alloc_text(PAGE, CdCommonSetInfo)
98 #pragma alloc_text(PAGE, CdFastQueryBasicInfo)
99 #pragma alloc_text(PAGE, CdFastQueryStdInfo)
100 #pragma alloc_text(PAGE, CdFastQueryNetworkInfo)
101 #pragma alloc_text(PAGE, CdQueryAlternateNameInfo)
102 #pragma alloc_text(PAGE, CdQueryBasicInfo)
103 #pragma alloc_text(PAGE, CdQueryEaInfo)
104 #pragma alloc_text(PAGE, CdQueryInternalInfo)
105 #pragma alloc_text(PAGE, CdQueryNameInfo)
106 #pragma alloc_text(PAGE, CdQueryNetworkInfo)
107 #pragma alloc_text(PAGE, CdQueryPositionInfo)
108 #pragma alloc_text(PAGE, CdQueryStandardInfo)
112 _Requires_lock_held_(_Global_critical_region_
)
115 _Inout_ PIRP_CONTEXT IrpContext
,
123 This is the common routine for query file information called by both the
128 Irp - Supplies the Irp to process.
132 NTSTATUS - The return status for this operation.
137 NTSTATUS Status
= STATUS_SUCCESS
;
138 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
141 FILE_INFORMATION_CLASS FileInformationClass
;
142 PFILE_ALL_INFORMATION Buffer
;
144 TYPE_OF_OPEN TypeOfOpen
;
148 BOOLEAN ReleaseFcb
= FALSE
;
153 // Reference our input parameters to make things easier
156 Length
= IrpSp
->Parameters
.QueryFile
.Length
;
157 FileInformationClass
= IrpSp
->Parameters
.QueryFile
.FileInformationClass
;
158 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
161 // Decode the file object
164 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
167 // Use a try-finally to facilitate cleanup.
173 // We only support query on file and directory handles.
176 switch (TypeOfOpen
) {
178 case UserDirectoryOpen
:
182 // Acquire shared access to this file. NOTE that this could be
183 // a recursive acquire, if we already preacquired in
184 // CdAcquireForCreateSection().
187 CdAcquireFileShared( IrpContext
, Fcb
);
191 // Make sure we have the correct sizes for a directory.
194 if (!FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
)) {
196 NT_ASSERT( TypeOfOpen
== UserDirectoryOpen
);
197 CdVerifyOrCreateDirStreamFile( IrpContext
, Fcb
);
201 // Make sure the Fcb is in a usable condition. This will raise
202 // an error condition if the volume is unusable
205 CdVerifyFcbOperation( IrpContext
, Fcb
);
208 // Based on the information class we'll do different
209 // actions. Each of hte procedures that we're calling fills
210 // up the output buffer, if possible. They will raise the
211 // status STATUS_BUFFER_OVERFLOW for an insufficient buffer.
212 // This is considered a somewhat unusual case and is handled
213 // more cleanly with the exception mechanism rather than
214 // testing a return status value for each call.
217 switch (FileInformationClass
) {
219 case FileAllInformation
:
222 // We don't allow this operation on a file opened by file Id.
225 if (FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_BY_ID
)) {
227 Status
= STATUS_INVALID_PARAMETER
;
232 // In this case go ahead and call the individual routines to
233 // fill in the buffer. Only the name routine will
234 // pointer to the output buffer and then call the
235 // individual routines to fill in the buffer.
238 Length
-= (sizeof( FILE_ACCESS_INFORMATION
) +
239 sizeof( FILE_MODE_INFORMATION
) +
240 sizeof( FILE_ALIGNMENT_INFORMATION
));
242 CdQueryBasicInfo( IrpContext
, Fcb
, &Buffer
->BasicInformation
, &Length
);
243 CdQueryStandardInfo( IrpContext
, Fcb
, &Buffer
->StandardInformation
, &Length
);
244 CdQueryInternalInfo( IrpContext
, Fcb
, &Buffer
->InternalInformation
, &Length
);
245 CdQueryEaInfo( IrpContext
, Fcb
, &Buffer
->EaInformation
, &Length
);
246 CdQueryPositionInfo( IrpContext
, IrpSp
->FileObject
, &Buffer
->PositionInformation
, &Length
);
247 Status
= CdQueryNameInfo( IrpContext
, IrpSp
->FileObject
, &Buffer
->NameInformation
, &Length
);
251 case FileBasicInformation
:
253 CdQueryBasicInfo( IrpContext
, Fcb
, (PFILE_BASIC_INFORMATION
) Buffer
, &Length
);
256 case FileStandardInformation
:
258 CdQueryStandardInfo( IrpContext
, Fcb
, (PFILE_STANDARD_INFORMATION
) Buffer
, &Length
);
261 case FileInternalInformation
:
263 CdQueryInternalInfo( IrpContext
, Fcb
, (PFILE_INTERNAL_INFORMATION
) Buffer
, &Length
);
266 case FileEaInformation
:
268 CdQueryEaInfo( IrpContext
, Fcb
, (PFILE_EA_INFORMATION
) Buffer
, &Length
);
271 case FilePositionInformation
:
273 CdQueryPositionInfo( IrpContext
, IrpSp
->FileObject
, (PFILE_POSITION_INFORMATION
) Buffer
, &Length
);
276 case FileNameInformation
:
279 // We don't allow this operation on a file opened by file Id.
282 if (!FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_BY_ID
)) {
284 Status
= CdQueryNameInfo( IrpContext
, IrpSp
->FileObject
, (PFILE_NAME_INFORMATION
) Buffer
, &Length
);
288 Status
= STATUS_INVALID_PARAMETER
;
293 case FileAlternateNameInformation
:
295 if (!FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_BY_ID
)) {
297 Status
= CdQueryAlternateNameInfo( IrpContext
, Fcb
, Ccb
, (PFILE_NAME_INFORMATION
) Buffer
, &Length
);
301 Status
= STATUS_INVALID_PARAMETER
;
306 case FileNetworkOpenInformation
:
308 CdQueryNetworkInfo( IrpContext
, Fcb
, (PFILE_NETWORK_OPEN_INFORMATION
) Buffer
, &Length
);
313 Status
= STATUS_INVALID_PARAMETER
;
320 Status
= STATUS_INVALID_PARAMETER
;
324 // Set the information field to the number of bytes actually filled in
325 // and then complete the request
328 Irp
->IoStatus
.Information
= IrpSp
->Parameters
.QueryFile
.Length
- Length
;
338 CdReleaseFile( IrpContext
, Fcb
);
343 // Complete the request if we didn't raise.
346 CdCompleteRequest( IrpContext
, Irp
, Status
);
352 _Requires_lock_held_(_Global_critical_region_
)
355 _Inout_ PIRP_CONTEXT IrpContext
,
363 This is the common routine for set file information called by both the
364 fsd and fsp threads. We only support operations which set the file position.
368 Irp - Supplies the Irp to process.
372 NTSTATUS - The return status for this operation.
377 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
379 TYPE_OF_OPEN TypeOfOpen
;
383 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
385 PFILE_POSITION_INFORMATION Buffer
;
390 // Decode the file object
393 TypeOfOpen
= CdDecodeFileObject( IrpContext
, IrpSp
->FileObject
, &Fcb
, &Ccb
);
396 // We only support a SetPositionInformation on a user file.
399 if ((TypeOfOpen
!= UserFileOpen
) ||
400 (IrpSp
->Parameters
.QueryFile
.FileInformationClass
!= FilePositionInformation
)) {
402 CdCompleteRequest( IrpContext
, Irp
, Status
);
407 // Acquire shared access to this file.
410 CdAcquireFileShared( IrpContext
, Fcb
);
415 // Make sure the Fcb is in a usable condition. This
416 // will raise an error condition if the fcb is unusable
419 CdVerifyFcbOperation( IrpContext
, Fcb
);
421 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
424 // Check if the file does not use intermediate buffering. If it
425 // does not use intermediate buffering then the new position we're
426 // supplied must be aligned properly for the device
429 if (FlagOn( IrpSp
->FileObject
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
) &&
430 ((Buffer
->CurrentByteOffset
.LowPart
& Fcb
->Vcb
->BlockMask
) != 0)) {
432 try_return( NOTHING
);
436 // The input parameter is fine so set the current byte offset and
437 // complete the request
441 // Lock the Fcb to provide synchronization.
444 CdLockFcb( IrpContext
, Fcb
);
445 IrpSp
->FileObject
->CurrentByteOffset
= Buffer
->CurrentByteOffset
;
446 CdUnlockFcb( IrpContext
, Fcb
);
448 Status
= STATUS_SUCCESS
;
453 CdReleaseFile( IrpContext
, Fcb
);
457 // Complete the request if there was no raise.
460 CdCompleteRequest( IrpContext
, Irp
, Status
);
465 _Function_class_(FAST_IO_QUERY_BASIC_INFO
)
466 _IRQL_requires_same_
\f
467 _Success_(return != FALSE
)
469 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
470 CdFastQueryBasicInfo (
471 _In_ PFILE_OBJECT FileObject
,
473 _Out_ PFILE_BASIC_INFORMATION Buffer
,
474 _Out_ PIO_STATUS_BLOCK IoStatus
,
475 _In_ PDEVICE_OBJECT DeviceObject
482 This routine is for the fast query call for basic file information.
486 FileObject - Supplies the file object used in this operation
488 Wait - Indicates if we are allowed to wait for the information
490 Buffer - Supplies the output buffer to receive the basic information
492 IoStatus - Receives the final status of the operation
496 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
497 needs to take the long route.
502 BOOLEAN Result
= FALSE
;
503 TYPE_OF_OPEN TypeOfOpen
;
509 UNREFERENCED_PARAMETER( DeviceObject
);
511 ASSERT_FILE_OBJECT( FileObject
);
513 FsRtlEnterFileSystem();
516 // Decode the file object to find the type of open and the data
520 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
523 // We only support this request on user file or directory objects.
526 if ((TypeOfOpen
!= UserFileOpen
) &&
527 ((TypeOfOpen
!= UserDirectoryOpen
) || !FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
))) {
529 FsRtlExitFileSystem();
534 // Acquire the file shared to access the Fcb.
537 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
539 FsRtlExitFileSystem();
544 // Use a try-finally to facilitate cleanup.
550 // Only deal with 'good' Fcb's.
553 if (CdVerifyFcbOperation( NULL
, Fcb
)) {
556 // Fill in the input buffer from the Fcb fields.
559 Buffer
->CreationTime
.QuadPart
=
560 Buffer
->LastWriteTime
.QuadPart
=
561 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
563 Buffer
->LastAccessTime
.QuadPart
= 0;
565 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
568 // Update the IoStatus block with the size of this data.
571 IoStatus
->Status
= STATUS_SUCCESS
;
572 IoStatus
->Information
= sizeof( FILE_BASIC_INFORMATION
);
579 ExReleaseResourceLite( Fcb
->Resource
);
581 FsRtlExitFileSystem();
588 _Function_class_(FAST_IO_QUERY_STANDARD_INFO
)
590 _Success_(return != FALSE
)
592 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
594 _In_ PFILE_OBJECT FileObject
,
596 _Out_ PFILE_STANDARD_INFORMATION Buffer
,
597 _Out_ PIO_STATUS_BLOCK IoStatus
,
598 _In_ PDEVICE_OBJECT DeviceObject
605 This routine is for the fast query call for standard file information.
609 FileObject - Supplies the file object used in this operation
611 Wait - Indicates if we are allowed to wait for the information
613 Buffer - Supplies the output buffer to receive the basic information
615 IoStatus - Receives the final status of the operation
619 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
620 needs to take the long route.
625 BOOLEAN Result
= FALSE
;
626 TYPE_OF_OPEN TypeOfOpen
;
632 UNREFERENCED_PARAMETER( DeviceObject
);
634 ASSERT_FILE_OBJECT( FileObject
);
636 FsRtlEnterFileSystem();
639 // Decode the file object to find the type of open and the data
643 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
646 // We only support this request on initialized user file or directory objects.
649 if ((TypeOfOpen
!= UserFileOpen
) &&
650 ((TypeOfOpen
!= UserDirectoryOpen
) || !FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
))) {
652 FsRtlExitFileSystem();
657 // Acquire the file shared to access the Fcb.
660 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
662 FsRtlExitFileSystem();
667 // Use a try-finally to facilitate cleanup.
673 // Only deal with 'good' Fcb's.
676 if (CdVerifyFcbOperation( NULL
, Fcb
)) {
679 // Check whether this is a directory.
682 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
684 Buffer
->AllocationSize
.QuadPart
=
685 Buffer
->EndOfFile
.QuadPart
= 0;
687 Buffer
->Directory
= TRUE
;
691 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
692 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
694 Buffer
->Directory
= FALSE
;
697 Buffer
->NumberOfLinks
= 1;
698 Buffer
->DeletePending
= FALSE
;
701 // Update the IoStatus block with the size of this data.
704 IoStatus
->Status
= STATUS_SUCCESS
;
705 IoStatus
->Information
= sizeof( FILE_STANDARD_INFORMATION
);
712 ExReleaseResourceLite( Fcb
->Resource
);
714 FsRtlExitFileSystem();
721 _Function_class_(FAST_IO_QUERY_NETWORK_OPEN_INFO
)
723 _Success_(return != FALSE
)
725 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
726 CdFastQueryNetworkInfo (
727 _In_ PFILE_OBJECT FileObject
,
729 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer
,
730 _Out_ PIO_STATUS_BLOCK IoStatus
,
731 _In_ PDEVICE_OBJECT DeviceObject
738 This routine is for the fast query call for network file information.
742 FileObject - Supplies the file object used in this operation
744 Wait - Indicates if we are allowed to wait for the information
746 Buffer - Supplies the output buffer to receive the basic information
748 IoStatus - Receives the final status of the operation
752 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
753 needs to take the long route.
758 BOOLEAN Result
= FALSE
;
759 TYPE_OF_OPEN TypeOfOpen
;
765 UNREFERENCED_PARAMETER( DeviceObject
);
767 ASSERT_FILE_OBJECT( FileObject
);
769 FsRtlEnterFileSystem();
772 // Decode the file object to find the type of open and the data
776 TypeOfOpen
= CdFastDecodeFileObject( FileObject
, &Fcb
);
779 // We only support this request on user file or directory objects.
782 if ((TypeOfOpen
!= UserFileOpen
) &&
783 ((TypeOfOpen
!= UserDirectoryOpen
) || !FlagOn( Fcb
->FcbState
, FCB_STATE_INITIALIZED
))) {
785 FsRtlExitFileSystem();
790 // Acquire the file shared to access the Fcb.
793 if (!ExAcquireResourceSharedLite( Fcb
->Resource
, Wait
)) {
795 FsRtlExitFileSystem();
800 // Use a try-finally to facilitate cleanup.
806 // Only deal with 'good' Fcb's.
809 if (CdVerifyFcbOperation( NULL
, Fcb
)) {
812 // Fill in the input buffer from the Fcb fields.
815 Buffer
->CreationTime
.QuadPart
=
816 Buffer
->LastWriteTime
.QuadPart
=
817 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
819 Buffer
->LastAccessTime
.QuadPart
= 0;
821 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
824 // Check whether this is a directory.
827 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
829 Buffer
->AllocationSize
.QuadPart
=
830 Buffer
->EndOfFile
.QuadPart
= 0;
834 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
835 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
839 // Update the IoStatus block with the size of this data.
842 IoStatus
->Status
= STATUS_SUCCESS
;
843 IoStatus
->Information
= sizeof( FILE_NETWORK_OPEN_INFORMATION
);
850 ExReleaseResourceLite( Fcb
->Resource
);
852 FsRtlExitFileSystem();
860 // Local support routine
865 _In_ PIRP_CONTEXT IrpContext
,
867 _Out_ PFILE_BASIC_INFORMATION Buffer
,
868 _Inout_ PULONG Length
875 This routine performs the query basic information function for Cdfs
879 Fcb - Supplies the Fcb being queried, it has been verified
881 Buffer - Supplies a pointer to the buffer where the information is to
884 Length - Supplies the length of the buffer in bytes, and receives the
885 remaining bytes free in the buffer upon return.
896 UNREFERENCED_PARAMETER( IrpContext
);
899 // We only support creation, last modify and last write times on Cdfs.
902 Buffer
->LastWriteTime
.QuadPart
=
903 Buffer
->CreationTime
.QuadPart
=
904 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
906 Buffer
->LastAccessTime
.QuadPart
= 0;
908 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
911 // Update the length and status output variables
914 *Length
-= sizeof( FILE_BASIC_INFORMATION
);
921 // Local support routine
925 CdQueryStandardInfo (
926 _In_ PIRP_CONTEXT IrpContext
,
928 _Out_ PFILE_STANDARD_INFORMATION Buffer
,
929 _Inout_ PULONG Length
935 This routine performs the query standard information function for cdfs.
939 Fcb - Supplies the Fcb being queried, it has been verified
941 Buffer - Supplies a pointer to the buffer where the information is to
944 Length - Supplies the length of the buffer in bytes, and receives the
945 remaining bytes free in the buffer upon return.
956 UNREFERENCED_PARAMETER( IrpContext
);
959 // There is only one link and delete is never pending on a Cdrom file.
962 Buffer
->NumberOfLinks
= 1;
963 Buffer
->DeletePending
= FALSE
;
966 // We get the sizes from the header. Return a size of zero
967 // for all directories.
970 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
972 Buffer
->AllocationSize
.QuadPart
=
973 Buffer
->EndOfFile
.QuadPart
= 0;
975 Buffer
->Directory
= TRUE
;
979 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
980 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
982 Buffer
->Directory
= FALSE
;
986 // Update the length and status output variables
989 *Length
-= sizeof( FILE_STANDARD_INFORMATION
);
996 // Local support routine
1000 CdQueryInternalInfo (
1001 _In_ PIRP_CONTEXT IrpContext
,
1003 _Out_ PFILE_INTERNAL_INFORMATION Buffer
,
1004 _Inout_ PULONG Length
1009 Routine Description:
1011 This routine performs the query internal information function for cdfs.
1015 Fcb - Supplies the Fcb being queried, it has been verified
1017 Buffer - Supplies a pointer to the buffer where the information is to
1020 Length - Supplies the length of the buffer in bytes, and receives the
1021 remaining bytes free in the buffer upon return.
1032 UNREFERENCED_PARAMETER( IrpContext
);
1035 // Index number is the file Id number in the Fcb.
1038 Buffer
->IndexNumber
= Fcb
->FileId
;
1039 *Length
-= sizeof( FILE_INTERNAL_INFORMATION
);
1046 // Local support routine
1051 _In_ PIRP_CONTEXT IrpContext
,
1053 _Out_ PFILE_EA_INFORMATION Buffer
,
1054 _Inout_ PULONG Length
1059 Routine Description:
1061 This routine performs the query Ea information function for cdfs.
1065 Fcb - Supplies the Fcb being queried, it has been verified
1067 Buffer - Supplies a pointer to the buffer where the information is to
1070 Length - Supplies the length of the buffer in bytes, and receives the
1071 remaining bytes free in the buffer upon return.
1082 UNREFERENCED_PARAMETER( IrpContext
);
1083 UNREFERENCED_PARAMETER( Fcb
);
1086 // No Ea's on Cdfs volumes.
1090 *Length
-= sizeof( FILE_EA_INFORMATION
);
1097 // Local support routine
1101 CdQueryPositionInfo (
1102 _In_ PIRP_CONTEXT IrpContext
,
1103 _In_ PFILE_OBJECT FileObject
,
1104 _Out_ PFILE_POSITION_INFORMATION Buffer
,
1105 _Inout_ PULONG Length
1110 Routine Description:
1112 This routine performs the query position information function for cdfs.
1116 FileObject - Supplies the File object being queried
1118 Buffer - Supplies a pointer to the buffer where the information is to
1121 Length - Supplies the length of the buffer in bytes, and receives the
1122 remaining bytes free in the buffer upon return.
1133 UNREFERENCED_PARAMETER( IrpContext
);
1136 // Get the current position found in the file object.
1139 Buffer
->CurrentByteOffset
= FileObject
->CurrentByteOffset
;
1142 // Update the length and status output variables
1145 *Length
-= sizeof( FILE_POSITION_INFORMATION
);
1152 // Local support routine
1157 _In_ PIRP_CONTEXT IrpContext
,
1158 _In_ PFILE_OBJECT FileObject
,
1159 _Out_ PFILE_NAME_INFORMATION Buffer
,
1160 _Inout_ PULONG Length
1165 Routine Description:
1167 This routine performs the query name information function for cdfs.
1171 FileObject - Supplies the file object containing the name.
1173 Buffer - Supplies a pointer to the buffer where the information is to
1176 Length - Supplies the length of the buffer in bytes, and receives the
1177 remaining bytes free in the buffer upon return.
1181 NTSTATUS - STATUS_BUFFER_OVERFLOW if the entire name can't be copied.
1186 NTSTATUS Status
= STATUS_SUCCESS
;
1191 UNREFERENCED_PARAMETER( IrpContext
);
1193 NT_ASSERT(*Length
>= sizeof(ULONG
));
1196 // Simply copy the name in the file object to the user's buffer.
1200 // Place the size of the filename in the user's buffer and reduce the remaining
1204 Buffer
->FileNameLength
= LengthToCopy
= FileObject
->FileName
.Length
;
1205 *Length
-= sizeof(ULONG
);
1207 if (LengthToCopy
> *Length
) {
1209 LengthToCopy
= *Length
;
1210 Status
= STATUS_BUFFER_OVERFLOW
;
1213 RtlCopyMemory( Buffer
->FileName
, FileObject
->FileName
.Buffer
, LengthToCopy
);
1216 // Reduce the available bytes by the amount stored into this buffer. In the overflow
1217 // case, this simply drops to zero. The returned filenamelength will indicate to the
1218 // caller how much space is required.
1221 *Length
-= LengthToCopy
;
1228 // Local support routine
1231 _Requires_lock_held_(_Global_critical_region_
)
1233 CdQueryAlternateNameInfo (
1234 _In_ PIRP_CONTEXT IrpContext
,
1237 _Out_ PFILE_NAME_INFORMATION Buffer
,
1238 _Inout_ PULONG Length
1243 Routine Description:
1245 This routine performs the query alternate name information function.
1246 We lookup the dirent for this file and then check if there is a
1251 Fcb - Supplies the Fcb being queried, it has been verified.
1253 Ccb - Ccb for this open handle.
1255 Buffer - Supplies a pointer to the buffer where the information is to
1258 Length - Supplies the length of the buffer in bytes, and receives the
1259 remaining bytes free in the buffer upon return.
1263 NTSTATUS - STATUS_SUCCESS if the whole name would fit into the user buffer,
1264 STATUS_OBJECT_NAME_NOT_FOUND if we can't return the name,
1265 STATUS_BUFFER_OVERFLOW otherwise.
1270 NTSTATUS Status
= STATUS_SUCCESS
;
1272 DIRENT_ENUM_CONTEXT DirContext
= {0};
1273 DIRENT Dirent
= {0};
1275 PUNICODE_STRING NameToUse
;
1278 COMPOUND_PATH_ENTRY CompoundPathEntry
= {{0}};/* ReactOS Change: GCC "missing braces around initializer" */
1279 FILE_ENUM_CONTEXT FileContext
;
1281 PFCB ParentFcb
= NULL
;
1282 BOOLEAN ReleaseParentFcb
= FALSE
;
1284 BOOLEAN CleanupFileLookup
= FALSE
;
1285 BOOLEAN CleanupDirectoryLookup
= FALSE
;
1287 WCHAR ShortNameBuffer
[ BYTE_COUNT_8_DOT_3
/ 2 ];
1288 USHORT ShortNameLength
;
1293 // Initialize the buffer length to zero.
1296 Buffer
->FileNameLength
= 0;
1299 // If this is the root or this file was opened using a version number then
1300 // there is no short name.
1303 if ((Fcb
== Fcb
->Vcb
->RootIndexFcb
) ||
1304 FlagOn( Ccb
->Flags
, CCB_FLAG_OPEN_WITH_VERSION
)) {
1306 return STATUS_OBJECT_NAME_NOT_FOUND
;
1310 // Use a try-finally to cleanup the structures.
1315 ParentFcb
= Fcb
->ParentFcb
;
1316 CdAcquireFileShared( IrpContext
, ParentFcb
);
1317 ReleaseParentFcb
= TRUE
;
1319 CdVerifyOrCreateDirStreamFile( IrpContext
, ParentFcb
);
1321 if (CdFidIsDirectory( Fcb
->FileId
)) {
1324 // Fcb is for a directory, so we need to dig the dirent from the parent. In
1325 // order to do this we need to get the name of the directory from its pathtable
1326 // entry and then search in the parent for a matching dirent.
1328 // This could be optimized somewhat.
1331 CdInitializeCompoundPathEntry( IrpContext
, &CompoundPathEntry
);
1332 CdInitializeFileContext( IrpContext
, &FileContext
);
1334 CleanupDirectoryLookup
= TRUE
;
1336 CdLookupPathEntry( IrpContext
,
1337 CdQueryFidPathTableOffset( Fcb
->FileId
),
1340 &CompoundPathEntry
);
1342 CdUpdatePathEntryName( IrpContext
, &CompoundPathEntry
.PathEntry
, TRUE
);
1344 if (!CdFindDirectory( IrpContext
,
1346 &CompoundPathEntry
.PathEntry
.CdCaseDirName
,
1351 // If we failed to find the child directory by name in the parent
1352 // something is quite wrong with this disc.
1355 CdRaiseStatus( IrpContext
, STATUS_DISK_CORRUPT_ERROR
);
1358 NameToUse
= &FileContext
.InitialDirent
->Dirent
.CdCaseFileName
.FileName
;
1359 DirentOffset
= FileContext
.InitialDirent
->Dirent
.DirentOffset
;
1364 // Initialize the search dirent structures.
1367 CdInitializeDirContext( IrpContext
, &DirContext
);
1368 CdInitializeDirent( IrpContext
, &Dirent
);
1370 CleanupFileLookup
= TRUE
;
1372 CdLookupDirent( IrpContext
,
1374 CdQueryFidDirentOffset( Fcb
->FileId
),
1377 CdUpdateDirentFromRawDirent( IrpContext
,
1383 // Now update the dirent name.
1386 CdUpdateDirentName( IrpContext
, &Dirent
, TRUE
);
1388 NameToUse
= &Dirent
.CdCaseFileName
.FileName
;
1389 DirentOffset
= Dirent
.DirentOffset
;
1393 // If the name is 8.3 then fail this request.
1396 if (CdIs8dot3Name( IrpContext
,
1400 try_return( Status
= STATUS_OBJECT_NAME_NOT_FOUND
);
1403 CdGenerate8dot3Name( IrpContext
,
1410 // We now have the short name. We have left it in Unicode form so copy it directly.
1413 Buffer
->FileNameLength
= ShortNameLength
;
1415 if (Buffer
->FileNameLength
+ sizeof( ULONG
) > *Length
) {
1417 Buffer
->FileNameLength
= *Length
- sizeof( ULONG
);
1418 Status
= STATUS_BUFFER_OVERFLOW
;
1421 RtlCopyMemory( Buffer
->FileName
, ShortNameBuffer
, Buffer
->FileNameLength
);
1426 if (CleanupFileLookup
) {
1428 CdCleanupDirContext( IrpContext
, &DirContext
);
1429 CdCleanupDirent( IrpContext
, &Dirent
);/* ReactOS Change: GCC "passing argument 1 from incompatible pointer type" */
1431 } else if (CleanupDirectoryLookup
) {
1433 CdCleanupCompoundPathEntry( IrpContext
, &CompoundPathEntry
);
1434 CdCleanupFileContext( IrpContext
, &FileContext
);
1437 if (ReleaseParentFcb
) {
1439 CdReleaseFile( IrpContext
, ParentFcb
);
1444 // Reduce the available bytes by the amount stored into this buffer.
1447 if (Status
!= STATUS_OBJECT_NAME_NOT_FOUND
) {
1449 *Length
-= sizeof( ULONG
) + Buffer
->FileNameLength
;
1457 // Local support routine
1461 CdQueryNetworkInfo (
1462 _In_ PIRP_CONTEXT IrpContext
,
1464 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1465 _Inout_ PULONG Length
1472 This routine performs the query network open information function for Cdfs
1476 Fcb - Supplies the Fcb being queried, it has been verified
1478 Buffer - Supplies a pointer to the buffer where the information is to
1481 Length - Supplies the length of the buffer in bytes, and receives the
1482 remaining bytes free in the buffer upon return.
1493 UNREFERENCED_PARAMETER( IrpContext
);
1496 // We only support creation, last modify and last write times on Cdfs.
1499 Buffer
->LastWriteTime
.QuadPart
=
1500 Buffer
->CreationTime
.QuadPart
=
1501 Buffer
->ChangeTime
.QuadPart
= Fcb
->CreationTime
;
1503 Buffer
->LastAccessTime
.QuadPart
= 0;
1505 Buffer
->FileAttributes
= Fcb
->FileAttributes
;
1508 // We get the sizes from the header. Return a size of zero
1509 // for all directories.
1512 if (FlagOn( Fcb
->FileAttributes
, FILE_ATTRIBUTE_DIRECTORY
)) {
1514 Buffer
->AllocationSize
.QuadPart
=
1515 Buffer
->EndOfFile
.QuadPart
= 0;
1519 Buffer
->AllocationSize
.QuadPart
= Fcb
->AllocationSize
.QuadPart
;
1520 Buffer
->EndOfFile
.QuadPart
= Fcb
->FileSize
.QuadPart
;
1524 // Update the length and status output variables
1527 *Length
-= sizeof( FILE_NETWORK_OPEN_INFORMATION
);