[CDFS_NEW] Use CdAcquireForCreateSection from the old driver in place of the newer...
[reactos.git] / drivers / filesystems / cdfs_new / fileinfo.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 FileInfo.c
8
9 Abstract:
10
11 This module implements the File Information routines for Cdfs called by
12 the Fsd/Fsp dispatch drivers.
13
14
15 --*/
16
17 #include "cdprocs.h"
18
19 //
20 // The Bug check file id for this module
21 //
22
23 #define BugCheckFileId (CDFS_BUG_CHECK_FILEINFO)
24
25 //
26 // Local support routines
27 //
28
29 VOID
30 CdQueryBasicInfo (
31 _In_ PIRP_CONTEXT IrpContext,
32 _In_ PFCB Fcb,
33 _Out_ PFILE_BASIC_INFORMATION Buffer,
34 _Inout_ PULONG Length
35 );
36
37 VOID
38 CdQueryStandardInfo (
39 _In_ PIRP_CONTEXT IrpContext,
40 _In_ PFCB Fcb,
41 _Out_ PFILE_STANDARD_INFORMATION Buffer,
42 _Inout_ PULONG Length
43 );
44
45 VOID
46 CdQueryInternalInfo (
47 _In_ PIRP_CONTEXT IrpContext,
48 _In_ PFCB Fcb,
49 _Out_ PFILE_INTERNAL_INFORMATION Buffer,
50 _Inout_ PULONG Length
51 );
52
53 VOID
54 CdQueryEaInfo (
55 _In_ PIRP_CONTEXT IrpContext,
56 _In_ PFCB Fcb,
57 _Out_ PFILE_EA_INFORMATION Buffer,
58 _Inout_ PULONG Length
59 );
60
61 VOID
62 CdQueryPositionInfo (
63 _In_ PIRP_CONTEXT IrpContext,
64 _In_ PFILE_OBJECT FileObject,
65 _Out_ PFILE_POSITION_INFORMATION Buffer,
66 _Inout_ PULONG Length
67 );
68
69 NTSTATUS
70 CdQueryNameInfo (
71 _In_ PIRP_CONTEXT IrpContext,
72 _In_ PFILE_OBJECT FileObject,
73 _Out_ PFILE_NAME_INFORMATION Buffer,
74 _Inout_ PULONG Length
75 );
76
77 _Requires_lock_held_(_Global_critical_region_)
78 NTSTATUS
79 CdQueryAlternateNameInfo (
80 _In_ PIRP_CONTEXT IrpContext,
81 _In_ PFCB Fcb,
82 _In_ PCCB Ccb,
83 _Out_ PFILE_NAME_INFORMATION Buffer,
84 _Inout_ PULONG Length
85 );
86
87 VOID
88 CdQueryNetworkInfo (
89 _In_ PIRP_CONTEXT IrpContext,
90 _In_ PFCB Fcb,
91 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
92 _Inout_ PULONG Length
93 );
94
95 #ifdef ALLOC_PRAGMA
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)
109 #endif
110
111 \f
112 _Requires_lock_held_(_Global_critical_region_)
113 NTSTATUS
114 CdCommonQueryInfo (
115 _Inout_ PIRP_CONTEXT IrpContext,
116 _Inout_ PIRP Irp
117 )
118
119 /*++
120
121 Routine Description:
122
123 This is the common routine for query file information called by both the
124 fsd and fsp threads.
125
126 Arguments:
127
128 Irp - Supplies the Irp to process.
129
130 Return Value:
131
132 NTSTATUS - The return status for this operation.
133
134 --*/
135
136 {
137 NTSTATUS Status = STATUS_SUCCESS;
138 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
139
140 ULONG Length;
141 FILE_INFORMATION_CLASS FileInformationClass;
142 PFILE_ALL_INFORMATION Buffer;
143
144 TYPE_OF_OPEN TypeOfOpen;
145 PFCB Fcb;
146 PCCB Ccb;
147
148 BOOLEAN ReleaseFcb = FALSE;
149
150 PAGED_CODE();
151
152 //
153 // Reference our input parameters to make things easier
154 //
155
156 Length = IrpSp->Parameters.QueryFile.Length;
157 FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
158 Buffer = Irp->AssociatedIrp.SystemBuffer;
159
160 //
161 // Decode the file object
162 //
163
164 TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
165
166 //
167 // Use a try-finally to facilitate cleanup.
168 //
169
170 _SEH2_TRY {
171
172 //
173 // We only support query on file and directory handles.
174 //
175
176 switch (TypeOfOpen) {
177
178 case UserDirectoryOpen :
179 case UserFileOpen :
180
181 //
182 // Acquire shared access to this file. NOTE that this could be
183 // a recursive acquire, if we already preacquired in
184 // CdAcquireForCreateSection().
185 //
186
187 CdAcquireFileShared( IrpContext, Fcb );
188 ReleaseFcb = TRUE;
189
190 //
191 // Make sure we have the correct sizes for a directory.
192 //
193
194 if (!FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )) {
195
196 NT_ASSERT( TypeOfOpen == UserDirectoryOpen );
197 CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
198 }
199
200 //
201 // Make sure the Fcb is in a usable condition. This will raise
202 // an error condition if the volume is unusable
203 //
204
205 CdVerifyFcbOperation( IrpContext, Fcb );
206
207 //
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.
215 //
216
217 switch (FileInformationClass) {
218
219 case FileAllInformation:
220
221 //
222 // We don't allow this operation on a file opened by file Id.
223 //
224
225 if (FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {
226
227 Status = STATUS_INVALID_PARAMETER;
228 break;
229 }
230
231 //
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.
236 //
237
238 Length -= (sizeof( FILE_ACCESS_INFORMATION ) +
239 sizeof( FILE_MODE_INFORMATION ) +
240 sizeof( FILE_ALIGNMENT_INFORMATION ));
241
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 );
248
249 break;
250
251 case FileBasicInformation:
252
253 CdQueryBasicInfo( IrpContext, Fcb, (PFILE_BASIC_INFORMATION) Buffer, &Length );
254 break;
255
256 case FileStandardInformation:
257
258 CdQueryStandardInfo( IrpContext, Fcb, (PFILE_STANDARD_INFORMATION) Buffer, &Length );
259 break;
260
261 case FileInternalInformation:
262
263 CdQueryInternalInfo( IrpContext, Fcb, (PFILE_INTERNAL_INFORMATION) Buffer, &Length );
264 break;
265
266 case FileEaInformation:
267
268 CdQueryEaInfo( IrpContext, Fcb, (PFILE_EA_INFORMATION) Buffer, &Length );
269 break;
270
271 case FilePositionInformation:
272
273 CdQueryPositionInfo( IrpContext, IrpSp->FileObject, (PFILE_POSITION_INFORMATION) Buffer, &Length );
274 break;
275
276 case FileNameInformation:
277
278 //
279 // We don't allow this operation on a file opened by file Id.
280 //
281
282 if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {
283
284 Status = CdQueryNameInfo( IrpContext, IrpSp->FileObject, (PFILE_NAME_INFORMATION) Buffer, &Length );
285
286 } else {
287
288 Status = STATUS_INVALID_PARAMETER;
289 }
290
291 break;
292
293 case FileAlternateNameInformation:
294
295 if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {
296
297 Status = CdQueryAlternateNameInfo( IrpContext, Fcb, Ccb, (PFILE_NAME_INFORMATION) Buffer, &Length );
298
299 } else {
300
301 Status = STATUS_INVALID_PARAMETER;
302 }
303
304 break;
305
306 case FileNetworkOpenInformation:
307
308 CdQueryNetworkInfo( IrpContext, Fcb, (PFILE_NETWORK_OPEN_INFORMATION) Buffer, &Length );
309 break;
310
311 default :
312
313 Status = STATUS_INVALID_PARAMETER;
314 }
315
316 break;
317
318 default :
319
320 Status = STATUS_INVALID_PARAMETER;
321 }
322
323 //
324 // Set the information field to the number of bytes actually filled in
325 // and then complete the request
326 //
327
328 Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
329
330 } _SEH2_FINALLY {
331
332 //
333 // Release the file.
334 //
335
336 if (ReleaseFcb) {
337
338 CdReleaseFile( IrpContext, Fcb );
339 }
340 } _SEH2_END;
341
342 //
343 // Complete the request if we didn't raise.
344 //
345
346 CdCompleteRequest( IrpContext, Irp, Status );
347
348 return Status;
349 }
350
351 \f
352 _Requires_lock_held_(_Global_critical_region_)
353 NTSTATUS
354 CdCommonSetInfo (
355 _Inout_ PIRP_CONTEXT IrpContext,
356 _Inout_ PIRP Irp
357 )
358
359 /*++
360
361 Routine Description:
362
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.
365
366 Arguments:
367
368 Irp - Supplies the Irp to process.
369
370 Return Value:
371
372 NTSTATUS - The return status for this operation.
373
374 --*/
375
376 {
377 NTSTATUS Status = STATUS_INVALID_PARAMETER;
378
379 TYPE_OF_OPEN TypeOfOpen;
380 PFCB Fcb;
381 PCCB Ccb;
382
383 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
384
385 PFILE_POSITION_INFORMATION Buffer;
386
387 PAGED_CODE();
388
389 //
390 // Decode the file object
391 //
392
393 TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
394
395 //
396 // We only support a SetPositionInformation on a user file.
397 //
398
399 if ((TypeOfOpen != UserFileOpen) ||
400 (IrpSp->Parameters.QueryFile.FileInformationClass != FilePositionInformation)) {
401
402 CdCompleteRequest( IrpContext, Irp, Status );
403 return Status;
404 }
405
406 //
407 // Acquire shared access to this file.
408 //
409
410 CdAcquireFileShared( IrpContext, Fcb );
411
412 _SEH2_TRY {
413
414 //
415 // Make sure the Fcb is in a usable condition. This
416 // will raise an error condition if the fcb is unusable
417 //
418
419 CdVerifyFcbOperation( IrpContext, Fcb );
420
421 Buffer = Irp->AssociatedIrp.SystemBuffer;
422
423 //
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
427 //
428
429 if (FlagOn( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ) &&
430 ((Buffer->CurrentByteOffset.LowPart & Fcb->Vcb->BlockMask) != 0)) {
431
432 try_return( NOTHING );
433 }
434
435 //
436 // The input parameter is fine so set the current byte offset and
437 // complete the request
438 //
439
440 //
441 // Lock the Fcb to provide synchronization.
442 //
443
444 CdLockFcb( IrpContext, Fcb );
445 IrpSp->FileObject->CurrentByteOffset = Buffer->CurrentByteOffset;
446 CdUnlockFcb( IrpContext, Fcb );
447
448 Status = STATUS_SUCCESS;
449
450 try_exit: NOTHING;
451 } _SEH2_FINALLY {
452
453 CdReleaseFile( IrpContext, Fcb );
454 } _SEH2_END;
455
456 //
457 // Complete the request if there was no raise.
458 //
459
460 CdCompleteRequest( IrpContext, Irp, Status );
461 return Status;
462 }
463
464
465 _Function_class_(FAST_IO_QUERY_BASIC_INFO)
466 _IRQL_requires_same_\f
467 _Success_(return != FALSE)
468 BOOLEAN
469 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
470 CdFastQueryBasicInfo (
471 _In_ PFILE_OBJECT FileObject,
472 _In_ BOOLEAN Wait,
473 _Out_ PFILE_BASIC_INFORMATION Buffer,
474 _Out_ PIO_STATUS_BLOCK IoStatus,
475 _In_ PDEVICE_OBJECT DeviceObject
476 )
477
478 /*++
479
480 Routine Description:
481
482 This routine is for the fast query call for basic file information.
483
484 Arguments:
485
486 FileObject - Supplies the file object used in this operation
487
488 Wait - Indicates if we are allowed to wait for the information
489
490 Buffer - Supplies the output buffer to receive the basic information
491
492 IoStatus - Receives the final status of the operation
493
494 Return Value:
495
496 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
497 needs to take the long route.
498
499 --*/
500
501 {
502 BOOLEAN Result = FALSE;
503 TYPE_OF_OPEN TypeOfOpen;
504
505 PFCB Fcb;
506
507 PAGED_CODE();
508
509 UNREFERENCED_PARAMETER( DeviceObject );
510
511 ASSERT_FILE_OBJECT( FileObject );
512
513 FsRtlEnterFileSystem();
514
515 //
516 // Decode the file object to find the type of open and the data
517 // structures.
518 //
519
520 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
521
522 //
523 // We only support this request on user file or directory objects.
524 //
525
526 if ((TypeOfOpen != UserFileOpen) &&
527 ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED))) {
528
529 FsRtlExitFileSystem();
530 return FALSE;
531 }
532
533 //
534 // Acquire the file shared to access the Fcb.
535 //
536
537 if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) {
538
539 FsRtlExitFileSystem();
540 return FALSE;
541 }
542
543 //
544 // Use a try-finally to facilitate cleanup.
545 //
546
547 _SEH2_TRY {
548
549 //
550 // Only deal with 'good' Fcb's.
551 //
552
553 if (CdVerifyFcbOperation( NULL, Fcb )) {
554
555 //
556 // Fill in the input buffer from the Fcb fields.
557 //
558
559 Buffer->CreationTime.QuadPart =
560 Buffer->LastWriteTime.QuadPart =
561 Buffer->ChangeTime.QuadPart = Fcb->CreationTime;
562
563 Buffer->LastAccessTime.QuadPart = 0;
564
565 Buffer->FileAttributes = Fcb->FileAttributes;
566
567 //
568 // Update the IoStatus block with the size of this data.
569 //
570
571 IoStatus->Status = STATUS_SUCCESS;
572 IoStatus->Information = sizeof( FILE_BASIC_INFORMATION );
573
574 Result = TRUE;
575 }
576
577 } _SEH2_FINALLY {
578
579 ExReleaseResourceLite( Fcb->Resource );
580
581 FsRtlExitFileSystem();
582 } _SEH2_END;
583
584 return Result;
585 }
586
587
588 _Function_class_(FAST_IO_QUERY_STANDARD_INFO)
589 _IRQL_requires_same_
590 _Success_(return != FALSE)
591 BOOLEAN
592 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
593 CdFastQueryStdInfo (
594 _In_ PFILE_OBJECT FileObject,
595 _In_ BOOLEAN Wait,
596 _Out_ PFILE_STANDARD_INFORMATION Buffer,
597 _Out_ PIO_STATUS_BLOCK IoStatus,
598 _In_ PDEVICE_OBJECT DeviceObject
599 )
600
601 /*++
602
603 Routine Description:
604
605 This routine is for the fast query call for standard file information.
606
607 Arguments:
608
609 FileObject - Supplies the file object used in this operation
610
611 Wait - Indicates if we are allowed to wait for the information
612
613 Buffer - Supplies the output buffer to receive the basic information
614
615 IoStatus - Receives the final status of the operation
616
617 Return Value:
618
619 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
620 needs to take the long route.
621
622 --*/
623
624 {
625 BOOLEAN Result = FALSE;
626 TYPE_OF_OPEN TypeOfOpen;
627
628 PFCB Fcb;
629
630 PAGED_CODE();
631
632 UNREFERENCED_PARAMETER( DeviceObject );
633
634 ASSERT_FILE_OBJECT( FileObject );
635
636 FsRtlEnterFileSystem();
637
638 //
639 // Decode the file object to find the type of open and the data
640 // structures.
641 //
642
643 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
644
645 //
646 // We only support this request on initialized user file or directory objects.
647 //
648
649 if ((TypeOfOpen != UserFileOpen) &&
650 ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED ))) {
651
652 FsRtlExitFileSystem();
653 return FALSE;
654 }
655
656 //
657 // Acquire the file shared to access the Fcb.
658 //
659
660 if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) {
661
662 FsRtlExitFileSystem();
663 return FALSE;
664 }
665
666 //
667 // Use a try-finally to facilitate cleanup.
668 //
669
670 _SEH2_TRY {
671
672 //
673 // Only deal with 'good' Fcb's.
674 //
675
676 if (CdVerifyFcbOperation( NULL, Fcb )) {
677
678 //
679 // Check whether this is a directory.
680 //
681
682 if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {
683
684 Buffer->AllocationSize.QuadPart =
685 Buffer->EndOfFile.QuadPart = 0;
686
687 Buffer->Directory = TRUE;
688
689 } else {
690
691 Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
692 Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;
693
694 Buffer->Directory = FALSE;
695 }
696
697 Buffer->NumberOfLinks = 1;
698 Buffer->DeletePending = FALSE;
699
700 //
701 // Update the IoStatus block with the size of this data.
702 //
703
704 IoStatus->Status = STATUS_SUCCESS;
705 IoStatus->Information = sizeof( FILE_STANDARD_INFORMATION );
706
707 Result = TRUE;
708 }
709
710 } _SEH2_FINALLY {
711
712 ExReleaseResourceLite( Fcb->Resource );
713
714 FsRtlExitFileSystem();
715 } _SEH2_END;
716
717 return Result;
718 }
719
720
721 _Function_class_(FAST_IO_QUERY_NETWORK_OPEN_INFO)
722 _IRQL_requires_same_
723 _Success_(return != FALSE)
724 BOOLEAN
725 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
726 CdFastQueryNetworkInfo (
727 _In_ PFILE_OBJECT FileObject,
728 _In_ BOOLEAN Wait,
729 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
730 _Out_ PIO_STATUS_BLOCK IoStatus,
731 _In_ PDEVICE_OBJECT DeviceObject
732 )
733
734 /*++
735
736 Routine Description:
737
738 This routine is for the fast query call for network file information.
739
740 Arguments:
741
742 FileObject - Supplies the file object used in this operation
743
744 Wait - Indicates if we are allowed to wait for the information
745
746 Buffer - Supplies the output buffer to receive the basic information
747
748 IoStatus - Receives the final status of the operation
749
750 Return Value:
751
752 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
753 needs to take the long route.
754
755 --*/
756
757 {
758 BOOLEAN Result = FALSE;
759 TYPE_OF_OPEN TypeOfOpen;
760
761 PFCB Fcb;
762
763 PAGED_CODE();
764
765 UNREFERENCED_PARAMETER( DeviceObject );
766
767 ASSERT_FILE_OBJECT( FileObject );
768
769 FsRtlEnterFileSystem();
770
771 //
772 // Decode the file object to find the type of open and the data
773 // structures.
774 //
775
776 TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );
777
778 //
779 // We only support this request on user file or directory objects.
780 //
781
782 if ((TypeOfOpen != UserFileOpen) &&
783 ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED))) {
784
785 FsRtlExitFileSystem();
786 return FALSE;
787 }
788
789 //
790 // Acquire the file shared to access the Fcb.
791 //
792
793 if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) {
794
795 FsRtlExitFileSystem();
796 return FALSE;
797 }
798
799 //
800 // Use a try-finally to facilitate cleanup.
801 //
802
803 _SEH2_TRY {
804
805 //
806 // Only deal with 'good' Fcb's.
807 //
808
809 if (CdVerifyFcbOperation( NULL, Fcb )) {
810
811 //
812 // Fill in the input buffer from the Fcb fields.
813 //
814
815 Buffer->CreationTime.QuadPart =
816 Buffer->LastWriteTime.QuadPart =
817 Buffer->ChangeTime.QuadPart = Fcb->CreationTime;
818
819 Buffer->LastAccessTime.QuadPart = 0;
820
821 Buffer->FileAttributes = Fcb->FileAttributes;
822
823 //
824 // Check whether this is a directory.
825 //
826
827 if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {
828
829 Buffer->AllocationSize.QuadPart =
830 Buffer->EndOfFile.QuadPart = 0;
831
832 } else {
833
834 Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
835 Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;
836 }
837
838 //
839 // Update the IoStatus block with the size of this data.
840 //
841
842 IoStatus->Status = STATUS_SUCCESS;
843 IoStatus->Information = sizeof( FILE_NETWORK_OPEN_INFORMATION );
844
845 Result = TRUE;
846 }
847
848 } _SEH2_FINALLY {
849
850 ExReleaseResourceLite( Fcb->Resource );
851
852 FsRtlExitFileSystem();
853 } _SEH2_END;
854
855 return Result;
856 }
857
858 \f
859 //
860 // Local support routine
861 //
862
863 VOID
864 CdQueryBasicInfo (
865 _In_ PIRP_CONTEXT IrpContext,
866 _In_ PFCB Fcb,
867 _Out_ PFILE_BASIC_INFORMATION Buffer,
868 _Inout_ PULONG Length
869 )
870
871 /*++
872
873 Description:
874
875 This routine performs the query basic information function for Cdfs
876
877 Arguments:
878
879 Fcb - Supplies the Fcb being queried, it has been verified
880
881 Buffer - Supplies a pointer to the buffer where the information is to
882 be returned
883
884 Length - Supplies the length of the buffer in bytes, and receives the
885 remaining bytes free in the buffer upon return.
886
887 Return Value:
888
889 None
890
891 --*/
892
893 {
894 PAGED_CODE();
895
896 UNREFERENCED_PARAMETER( IrpContext );
897
898 //
899 // We only support creation, last modify and last write times on Cdfs.
900 //
901
902 Buffer->LastWriteTime.QuadPart =
903 Buffer->CreationTime.QuadPart =
904 Buffer->ChangeTime.QuadPart = Fcb->CreationTime;
905
906 Buffer->LastAccessTime.QuadPart = 0;
907
908 Buffer->FileAttributes = Fcb->FileAttributes;
909
910 //
911 // Update the length and status output variables
912 //
913
914 *Length -= sizeof( FILE_BASIC_INFORMATION );
915
916 return;
917 }
918
919 \f
920 //
921 // Local support routine
922 //
923
924 VOID
925 CdQueryStandardInfo (
926 _In_ PIRP_CONTEXT IrpContext,
927 _In_ PFCB Fcb,
928 _Out_ PFILE_STANDARD_INFORMATION Buffer,
929 _Inout_ PULONG Length
930 )
931 /*++
932
933 Routine Description:
934
935 This routine performs the query standard information function for cdfs.
936
937 Arguments:
938
939 Fcb - Supplies the Fcb being queried, it has been verified
940
941 Buffer - Supplies a pointer to the buffer where the information is to
942 be returned
943
944 Length - Supplies the length of the buffer in bytes, and receives the
945 remaining bytes free in the buffer upon return.
946
947 Return Value:
948
949 None
950
951 --*/
952
953 {
954 PAGED_CODE();
955
956 UNREFERENCED_PARAMETER( IrpContext );
957
958 //
959 // There is only one link and delete is never pending on a Cdrom file.
960 //
961
962 Buffer->NumberOfLinks = 1;
963 Buffer->DeletePending = FALSE;
964
965 //
966 // We get the sizes from the header. Return a size of zero
967 // for all directories.
968 //
969
970 if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {
971
972 Buffer->AllocationSize.QuadPart =
973 Buffer->EndOfFile.QuadPart = 0;
974
975 Buffer->Directory = TRUE;
976
977 } else {
978
979 Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
980 Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;
981
982 Buffer->Directory = FALSE;
983 }
984
985 //
986 // Update the length and status output variables
987 //
988
989 *Length -= sizeof( FILE_STANDARD_INFORMATION );
990
991 return;
992 }
993
994 \f
995 //
996 // Local support routine
997 //
998
999 VOID
1000 CdQueryInternalInfo (
1001 _In_ PIRP_CONTEXT IrpContext,
1002 _In_ PFCB Fcb,
1003 _Out_ PFILE_INTERNAL_INFORMATION Buffer,
1004 _Inout_ PULONG Length
1005 )
1006
1007 /*++
1008
1009 Routine Description:
1010
1011 This routine performs the query internal information function for cdfs.
1012
1013 Arguments:
1014
1015 Fcb - Supplies the Fcb being queried, it has been verified
1016
1017 Buffer - Supplies a pointer to the buffer where the information is to
1018 be returned
1019
1020 Length - Supplies the length of the buffer in bytes, and receives the
1021 remaining bytes free in the buffer upon return.
1022
1023 Return Value:
1024
1025 None
1026
1027 --*/
1028
1029 {
1030 PAGED_CODE();
1031
1032 UNREFERENCED_PARAMETER( IrpContext );
1033
1034 //
1035 // Index number is the file Id number in the Fcb.
1036 //
1037
1038 Buffer->IndexNumber = Fcb->FileId;
1039 *Length -= sizeof( FILE_INTERNAL_INFORMATION );
1040
1041 return;
1042 }
1043
1044 \f
1045 //
1046 // Local support routine
1047 //
1048
1049 VOID
1050 CdQueryEaInfo (
1051 _In_ PIRP_CONTEXT IrpContext,
1052 _In_ PFCB Fcb,
1053 _Out_ PFILE_EA_INFORMATION Buffer,
1054 _Inout_ PULONG Length
1055 )
1056
1057 /*++
1058
1059 Routine Description:
1060
1061 This routine performs the query Ea information function for cdfs.
1062
1063 Arguments:
1064
1065 Fcb - Supplies the Fcb being queried, it has been verified
1066
1067 Buffer - Supplies a pointer to the buffer where the information is to
1068 be returned
1069
1070 Length - Supplies the length of the buffer in bytes, and receives the
1071 remaining bytes free in the buffer upon return.
1072
1073 Return Value:
1074
1075 None
1076
1077 --*/
1078
1079 {
1080 PAGED_CODE();
1081
1082 UNREFERENCED_PARAMETER( IrpContext );
1083 UNREFERENCED_PARAMETER( Fcb );
1084
1085 //
1086 // No Ea's on Cdfs volumes.
1087 //
1088
1089 Buffer->EaSize = 0;
1090 *Length -= sizeof( FILE_EA_INFORMATION );
1091
1092 return;
1093 }
1094
1095 \f
1096 //
1097 // Local support routine
1098 //
1099
1100 VOID
1101 CdQueryPositionInfo (
1102 _In_ PIRP_CONTEXT IrpContext,
1103 _In_ PFILE_OBJECT FileObject,
1104 _Out_ PFILE_POSITION_INFORMATION Buffer,
1105 _Inout_ PULONG Length
1106 )
1107
1108 /*++
1109
1110 Routine Description:
1111
1112 This routine performs the query position information function for cdfs.
1113
1114 Arguments:
1115
1116 FileObject - Supplies the File object being queried
1117
1118 Buffer - Supplies a pointer to the buffer where the information is to
1119 be returned
1120
1121 Length - Supplies the length of the buffer in bytes, and receives the
1122 remaining bytes free in the buffer upon return.
1123
1124 Return Value:
1125
1126 None
1127
1128 --*/
1129
1130 {
1131 PAGED_CODE();
1132
1133 UNREFERENCED_PARAMETER( IrpContext );
1134
1135 //
1136 // Get the current position found in the file object.
1137 //
1138
1139 Buffer->CurrentByteOffset = FileObject->CurrentByteOffset;
1140
1141 //
1142 // Update the length and status output variables
1143 //
1144
1145 *Length -= sizeof( FILE_POSITION_INFORMATION );
1146
1147 return;
1148 }
1149
1150 \f
1151 //
1152 // Local support routine
1153 //
1154
1155 NTSTATUS
1156 CdQueryNameInfo (
1157 _In_ PIRP_CONTEXT IrpContext,
1158 _In_ PFILE_OBJECT FileObject,
1159 _Out_ PFILE_NAME_INFORMATION Buffer,
1160 _Inout_ PULONG Length
1161 )
1162
1163 /*++
1164
1165 Routine Description:
1166
1167 This routine performs the query name information function for cdfs.
1168
1169 Arguments:
1170
1171 FileObject - Supplies the file object containing the name.
1172
1173 Buffer - Supplies a pointer to the buffer where the information is to
1174 be returned
1175
1176 Length - Supplies the length of the buffer in bytes, and receives the
1177 remaining bytes free in the buffer upon return.
1178
1179 Return Value:
1180
1181 NTSTATUS - STATUS_BUFFER_OVERFLOW if the entire name can't be copied.
1182
1183 --*/
1184
1185 {
1186 NTSTATUS Status = STATUS_SUCCESS;
1187 ULONG LengthToCopy;
1188
1189 PAGED_CODE();
1190
1191 UNREFERENCED_PARAMETER( IrpContext );
1192
1193 NT_ASSERT(*Length >= sizeof(ULONG));
1194
1195 //
1196 // Simply copy the name in the file object to the user's buffer.
1197 //
1198
1199 //
1200 // Place the size of the filename in the user's buffer and reduce the remaining
1201 // size to match.
1202 //
1203
1204 Buffer->FileNameLength = LengthToCopy = FileObject->FileName.Length;
1205 *Length -= sizeof(ULONG);
1206
1207 if (LengthToCopy > *Length) {
1208
1209 LengthToCopy = *Length;
1210 Status = STATUS_BUFFER_OVERFLOW;
1211 }
1212
1213 RtlCopyMemory( Buffer->FileName, FileObject->FileName.Buffer, LengthToCopy );
1214
1215 //
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.
1219 //
1220
1221 *Length -= LengthToCopy;
1222
1223 return Status;
1224 }
1225
1226 \f
1227 //
1228 // Local support routine
1229 //
1230
1231 _Requires_lock_held_(_Global_critical_region_)
1232 NTSTATUS
1233 CdQueryAlternateNameInfo (
1234 _In_ PIRP_CONTEXT IrpContext,
1235 _In_ PFCB Fcb,
1236 _In_ PCCB Ccb,
1237 _Out_ PFILE_NAME_INFORMATION Buffer,
1238 _Inout_ PULONG Length
1239 )
1240
1241 /*++
1242
1243 Routine Description:
1244
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
1247 short name.
1248
1249 Arguments:
1250
1251 Fcb - Supplies the Fcb being queried, it has been verified.
1252
1253 Ccb - Ccb for this open handle.
1254
1255 Buffer - Supplies a pointer to the buffer where the information is to
1256 be returned.
1257
1258 Length - Supplies the length of the buffer in bytes, and receives the
1259 remaining bytes free in the buffer upon return.
1260
1261 Return Value:
1262
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.
1266
1267 --*/
1268
1269 {
1270 NTSTATUS Status = STATUS_SUCCESS;
1271
1272 DIRENT_ENUM_CONTEXT DirContext = {0};
1273 DIRENT Dirent = {0};
1274
1275 PUNICODE_STRING NameToUse;
1276 ULONG DirentOffset;
1277
1278 COMPOUND_PATH_ENTRY CompoundPathEntry = {{0}};/* ReactOS Change: GCC "missing braces around initializer" */
1279 FILE_ENUM_CONTEXT FileContext;
1280
1281 PFCB ParentFcb = NULL;
1282 BOOLEAN ReleaseParentFcb = FALSE;
1283
1284 BOOLEAN CleanupFileLookup = FALSE;
1285 BOOLEAN CleanupDirectoryLookup = FALSE;
1286
1287 WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / 2 ];
1288 USHORT ShortNameLength;
1289
1290 PAGED_CODE();
1291
1292 //
1293 // Initialize the buffer length to zero.
1294 //
1295
1296 Buffer->FileNameLength = 0;
1297
1298 //
1299 // If this is the root or this file was opened using a version number then
1300 // there is no short name.
1301 //
1302
1303 if ((Fcb == Fcb->Vcb->RootIndexFcb) ||
1304 FlagOn( Ccb->Flags, CCB_FLAG_OPEN_WITH_VERSION)) {
1305
1306 return STATUS_OBJECT_NAME_NOT_FOUND;
1307 }
1308
1309 //
1310 // Use a try-finally to cleanup the structures.
1311 //
1312
1313 _SEH2_TRY {
1314
1315 ParentFcb = Fcb->ParentFcb;
1316 CdAcquireFileShared( IrpContext, ParentFcb );
1317 ReleaseParentFcb = TRUE;
1318
1319 CdVerifyOrCreateDirStreamFile( IrpContext, ParentFcb);
1320
1321 if (CdFidIsDirectory( Fcb->FileId)) {
1322
1323 //
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.
1327 //
1328 // This could be optimized somewhat.
1329 //
1330
1331 CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry );
1332 CdInitializeFileContext( IrpContext, &FileContext );
1333
1334 CleanupDirectoryLookup = TRUE;
1335
1336 CdLookupPathEntry( IrpContext,
1337 CdQueryFidPathTableOffset( Fcb->FileId ),
1338 Fcb->Ordinal,
1339 FALSE,
1340 &CompoundPathEntry );
1341
1342 CdUpdatePathEntryName( IrpContext, &CompoundPathEntry.PathEntry, TRUE );
1343
1344 if (!CdFindDirectory( IrpContext,
1345 ParentFcb,
1346 &CompoundPathEntry.PathEntry.CdCaseDirName,
1347 TRUE,
1348 &FileContext )) {
1349
1350 //
1351 // If we failed to find the child directory by name in the parent
1352 // something is quite wrong with this disc.
1353 //
1354
1355 CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR );
1356 }
1357
1358 NameToUse = &FileContext.InitialDirent->Dirent.CdCaseFileName.FileName;
1359 DirentOffset = FileContext.InitialDirent->Dirent.DirentOffset;
1360
1361 } else {
1362
1363 //
1364 // Initialize the search dirent structures.
1365 //
1366
1367 CdInitializeDirContext( IrpContext, &DirContext );
1368 CdInitializeDirent( IrpContext, &Dirent );
1369
1370 CleanupFileLookup = TRUE;
1371
1372 CdLookupDirent( IrpContext,
1373 ParentFcb,
1374 CdQueryFidDirentOffset( Fcb->FileId ),
1375 &DirContext );
1376
1377 CdUpdateDirentFromRawDirent( IrpContext,
1378 ParentFcb,
1379 &DirContext,
1380 &Dirent );
1381
1382 //
1383 // Now update the dirent name.
1384 //
1385
1386 CdUpdateDirentName( IrpContext, &Dirent, TRUE );
1387
1388 NameToUse = &Dirent.CdCaseFileName.FileName;
1389 DirentOffset = Dirent.DirentOffset;
1390 }
1391
1392 //
1393 // If the name is 8.3 then fail this request.
1394 //
1395
1396 if (CdIs8dot3Name( IrpContext,
1397 *NameToUse )) {
1398
1399
1400 try_return( Status = STATUS_OBJECT_NAME_NOT_FOUND );
1401 }
1402
1403 CdGenerate8dot3Name( IrpContext,
1404 NameToUse,
1405 DirentOffset,
1406 ShortNameBuffer,
1407 &ShortNameLength );
1408
1409 //
1410 // We now have the short name. We have left it in Unicode form so copy it directly.
1411 //
1412
1413 Buffer->FileNameLength = ShortNameLength;
1414
1415 if (Buffer->FileNameLength + sizeof( ULONG ) > *Length) {
1416
1417 Buffer->FileNameLength = *Length - sizeof( ULONG );
1418 Status = STATUS_BUFFER_OVERFLOW;
1419 }
1420
1421 RtlCopyMemory( Buffer->FileName, ShortNameBuffer, Buffer->FileNameLength );
1422
1423 try_exit: NOTHING;
1424 } _SEH2_FINALLY {
1425
1426 if (CleanupFileLookup) {
1427
1428 CdCleanupDirContext( IrpContext, &DirContext );
1429 CdCleanupDirent( IrpContext, &Dirent );/* ReactOS Change: GCC "passing argument 1 from incompatible pointer type" */
1430
1431 } else if (CleanupDirectoryLookup) {
1432
1433 CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry );
1434 CdCleanupFileContext( IrpContext, &FileContext );
1435 }
1436
1437 if (ReleaseParentFcb) {
1438
1439 CdReleaseFile( IrpContext, ParentFcb );
1440 }
1441 } _SEH2_END;
1442
1443 //
1444 // Reduce the available bytes by the amount stored into this buffer.
1445 //
1446
1447 if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
1448
1449 *Length -= sizeof( ULONG ) + Buffer->FileNameLength;
1450 }
1451
1452 return Status;
1453 }
1454
1455 \f
1456 //
1457 // Local support routine
1458 //
1459
1460 VOID
1461 CdQueryNetworkInfo (
1462 _In_ PIRP_CONTEXT IrpContext,
1463 _In_ PFCB Fcb,
1464 _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer,
1465 _Inout_ PULONG Length
1466 )
1467
1468 /*++
1469
1470 Description:
1471
1472 This routine performs the query network open information function for Cdfs
1473
1474 Arguments:
1475
1476 Fcb - Supplies the Fcb being queried, it has been verified
1477
1478 Buffer - Supplies a pointer to the buffer where the information is to
1479 be returned
1480
1481 Length - Supplies the length of the buffer in bytes, and receives the
1482 remaining bytes free in the buffer upon return.
1483
1484 Return Value:
1485
1486 None
1487
1488 --*/
1489
1490 {
1491 PAGED_CODE();
1492
1493 UNREFERENCED_PARAMETER( IrpContext );
1494
1495 //
1496 // We only support creation, last modify and last write times on Cdfs.
1497 //
1498
1499 Buffer->LastWriteTime.QuadPart =
1500 Buffer->CreationTime.QuadPart =
1501 Buffer->ChangeTime.QuadPart = Fcb->CreationTime;
1502
1503 Buffer->LastAccessTime.QuadPart = 0;
1504
1505 Buffer->FileAttributes = Fcb->FileAttributes;
1506
1507 //
1508 // We get the sizes from the header. Return a size of zero
1509 // for all directories.
1510 //
1511
1512 if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {
1513
1514 Buffer->AllocationSize.QuadPart =
1515 Buffer->EndOfFile.QuadPart = 0;
1516
1517 } else {
1518
1519 Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
1520 Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;
1521 }
1522
1523 //
1524 // Update the length and status output variables
1525 //
1526
1527 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION );
1528
1529 return;
1530 }
1531