ReactOS 0.4.16-dev-197-g92996da
volinfo.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 VolInfo.c
8
9Abstract:
10
11 This module implements the volume information routines for Fat called by
12 the dispatch driver.
13
14
15--*/
16
17#include "fatprocs.h"
18
19//
20// The local debug trace level
21//
22
23#define Dbg (DEBUG_TRACE_VOLINFO)
24
27 IN PIRP_CONTEXT IrpContext,
28 IN PVCB Vcb,
31 );
32
35 IN PIRP_CONTEXT IrpContext,
36 IN PVCB Vcb,
39 );
40
43 IN PIRP_CONTEXT IrpContext,
44 IN PVCB Vcb,
47 );
48
51 IN PIRP_CONTEXT IrpContext,
52 IN PVCB Vcb,
55 );
56
59 IN PIRP_CONTEXT IrpContext,
60 IN PVCB Vcb,
63 );
64
67 IN PIRP_CONTEXT IrpContext,
68 IN PVCB Vcb,
70 );
71
72#if (NTDDI_VERSION >= NTDDI_WIN8)
75 _In_ PIRP_CONTEXT IrpContext,
77 _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
79 );
80#endif
81
82#ifdef ALLOC_PRAGMA
83#pragma alloc_text(PAGE, FatCommonQueryVolumeInfo)
84#pragma alloc_text(PAGE, FatCommonSetVolumeInfo)
85#pragma alloc_text(PAGE, FatFsdQueryVolumeInformation)
86#pragma alloc_text(PAGE, FatFsdSetVolumeInformation)
87#pragma alloc_text(PAGE, FatQueryFsAttributeInfo)
88#pragma alloc_text(PAGE, FatQueryFsDeviceInfo)
89#pragma alloc_text(PAGE, FatQueryFsSizeInfo)
90#pragma alloc_text(PAGE, FatQueryFsVolumeInfo)
91#pragma alloc_text(PAGE, FatQueryFsFullSizeInfo)
92#pragma alloc_text(PAGE, FatSetFsLabelInfo)
93#if (NTDDI_VERSION >= NTDDI_WIN8)
94#pragma alloc_text(PAGE, FatQueryFsSectorSizeInfo)
95#endif
96#endif
97
98
102NTAPI
103FatFsdQueryVolumeInformation (
104 _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
106 )
107
108/*++
109
110Routine Description:
111
112 This routine implements the Fsd part of the NtQueryVolumeInformation API
113 call.
114
115Arguments:
116
117 VolumeDeviceObject - Supplies the volume device object where the file
118 being queried exists.
119
120 Irp - Supplies the Irp being processed.
121
122Return Value:
123
124 NTSTATUS - The FSD status for the Irp.
125
126--*/
127
128{
130 PIRP_CONTEXT IrpContext = NULL;
131
133
134 PAGED_CODE();
135
136 DebugTrace(+1, Dbg, "FatFsdQueryVolumeInformation\n", 0);
137
138 //
139 // Call the common query routine, with blocking allowed if synchronous
140 //
141
143
145
146 _SEH2_TRY {
147
148 IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
149
150 Status = FatCommonQueryVolumeInfo( IrpContext, Irp );
151
153
154 //
155 // We had some trouble trying to perform the requested
156 // operation, so we'll abort the I/O request with
157 // the error status that we get back from the
158 // exception code
159 //
160
161 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
162 } _SEH2_END;
163
164 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
165
167
168 //
169 // And return to our caller
170 //
171
172 DebugTrace(-1, Dbg, "FatFsdQueryVolumeInformation -> %08lx\n", Status);
173
174 UNREFERENCED_PARAMETER( VolumeDeviceObject );
175
176 return Status;
177}
178
179
183NTAPI
184FatFsdSetVolumeInformation (
185 _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
187 )
188
189/*++
190
191Routine Description:
192
193 This routine implements the FSD part of the NtSetVolumeInformation API
194 call.
195
196Arguments:
197
198 VolumeDeviceObject - Supplies the volume device object where the file
199 being set exists.
200
201 Irp - Supplies the Irp being processed.
202
203Return Value:
204
205 NTSTATUS - The FSD status for the Irp.
206
207--*/
208
209{
211 PIRP_CONTEXT IrpContext = NULL;
212
214
215 PAGED_CODE();
216
217 DebugTrace(+1, Dbg, "FatFsdSetVolumeInformation\n", 0);
218
219 //
220 // Call the common set routine
221 //
222
224
226
227 _SEH2_TRY {
228
229 IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
230
231 Status = FatCommonSetVolumeInfo( IrpContext, Irp );
232
234
235 //
236 // We had some trouble trying to perform the requested
237 // operation, so we'll abort the I/O request with
238 // the error status that we get back from the
239 // exception code
240 //
241
242 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
243 } _SEH2_END;
244
245 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
246
248
249 //
250 // And return to our caller
251 //
252
253 DebugTrace(-1, Dbg, "FatFsdSetVolumeInformation -> %08lx\n", Status);
254
255 UNREFERENCED_PARAMETER( VolumeDeviceObject );
256
257 return Status;
258}
259
260
261_Requires_lock_held_(_Global_critical_region_)
263FatCommonQueryVolumeInfo (
264 IN PIRP_CONTEXT IrpContext,
265 IN PIRP Irp
266 )
267
268/*++
269
270Routine Description:
271
272 This is the common routine for querying volume information called by both
273 the fsd and fsp threads.
274
275Arguments:
276
277 Irp - Supplies the Irp being processed
278
279Return Value:
280
281 NTSTATUS - The return status for the operation
282
283--*/
284
285{
288
289 PVCB Vcb;
290 PFCB Fcb;
291 PCCB Ccb;
292
296
297 BOOLEAN WeAcquiredVcb = FALSE;
298
299 PAGED_CODE();
300
301 //
302 // Get the current stack location
303 //
304
306
307 DebugTrace(+1, Dbg, "FatCommonQueryVolumeInfo...\n", 0);
308 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
309 DebugTrace( 0, Dbg, "->Length = %08lx\n", IrpSp->Parameters.QueryVolume.Length);
310 DebugTrace( 0, Dbg, "->FsInformationClass = %08lx\n", IrpSp->Parameters.QueryVolume.FsInformationClass);
311 DebugTrace( 0, Dbg, "->Buffer = %p\n", Irp->AssociatedIrp.SystemBuffer);
312
313 //
314 // Reference our input parameters to make things easier
315 //
316
318 FsInformationClass = IrpSp->Parameters.QueryVolume.FsInformationClass;
319 Buffer = Irp->AssociatedIrp.SystemBuffer;
320
321 //
322 // Decode the file object to get the Vcb
323 //
324
326
327 NT_ASSERT( Vcb != NULL );
329
330 _SEH2_TRY {
331
332 //
333 // Make sure the vcb is in a usable condition. This will raise
334 // an error condition if the volume is unusable
335 //
336 // Also verify the Root Dcb since we need info from there.
337 //
338
339 FatVerifyFcb( IrpContext, Vcb->RootDcb );
340
341 //
342 // Based on the information class we'll do different actions. Each
343 // of the procedures that we're calling fills up the output buffer
344 // if possible and returns true if it successfully filled the buffer
345 // and false if it couldn't wait for any I/O to complete.
346 //
347
348 switch (FsInformationClass) {
349
351
352 //
353 // This is the only routine we need the Vcb shared because of
354 // copying the volume label. All other routines copy fields that
355 // cannot change or are just manifest constants.
356 //
357
358 if (!FatAcquireSharedVcb( IrpContext, Vcb )) {
359
360 DebugTrace(0, Dbg, "Cannot acquire Vcb\n", 0);
361
362 Status = FatFsdPostRequest( IrpContext, Irp );
363 IrpContext = NULL;
364 Irp = NULL;
365
366 } else {
367
368 WeAcquiredVcb = TRUE;
369
370 Status = FatQueryFsVolumeInfo( IrpContext, Vcb, Buffer, &Length );
371 }
372
373 break;
374
376
377 Status = FatQueryFsSizeInfo( IrpContext, Vcb, Buffer, &Length );
378 break;
379
381
382 Status = FatQueryFsDeviceInfo( IrpContext, Vcb, Buffer, &Length );
383 break;
384
386
387 Status = FatQueryFsAttributeInfo( IrpContext, Vcb, Buffer, &Length );
388 break;
389
391
392 Status = FatQueryFsFullSizeInfo( IrpContext, Vcb, Buffer, &Length );
393 break;
394
395#if (NTDDI_VERSION >= NTDDI_WIN8)
396 case FileFsSectorSizeInformation:
397
398 Status = FatQueryFsSectorSizeInfo( IrpContext, Vcb, Buffer, &Length );
399 break;
400#endif
401
402 default:
403
405 break;
406 }
407
408 //
409 // Set the information field to the number of bytes actually filled in.
410 //
411
412 if (Irp != NULL) {
413
414 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
415 }
416
417 } _SEH2_FINALLY {
418
419 DebugUnwind( FatCommonQueryVolumeInfo );
420
421 if (WeAcquiredVcb) {
422
423 FatReleaseVcb( IrpContext, Vcb );
424 }
425
427
428 FatCompleteRequest( IrpContext, Irp, Status );
429 }
430
431 DebugTrace(-1, Dbg, "FatCommonQueryVolumeInfo -> %08lx\n", Status);
432 } _SEH2_END;
433
434 return Status;
435}
436
437
438_Requires_lock_held_(_Global_critical_region_)
440FatCommonSetVolumeInfo (
441 IN PIRP_CONTEXT IrpContext,
442 IN PIRP Irp
443 )
444
445/*++
446
447Routine Description:
448
449 This is the common routine for setting Volume Information called by both
450 the fsd and fsp threads.
451
452Arguments:
453
454 Irp - Supplies the Irp being processed
455
456Return Value:
457
458 NTSTATUS - The return status for the operation
459
460--*/
461
462{
465
466 PVCB Vcb;
467 PFCB Fcb;
468 PCCB Ccb;
470
473
474 PAGED_CODE();
475
476 //
477 // Get the current stack location
478 //
479
481
482 DebugTrace(+1, Dbg, "FatCommonSetVolumeInfo...\n", 0);
483 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
484 DebugTrace( 0, Dbg, "->Length = %08lx\n", IrpSp->Parameters.SetVolume.Length);
485 DebugTrace( 0, Dbg, "->FsInformationClass = %08lx\n", IrpSp->Parameters.SetVolume.FsInformationClass);
486 DebugTrace( 0, Dbg, "->Buffer = %p\n", Irp->AssociatedIrp.SystemBuffer);
487
488 //
489 // Reference our input parameters to make things easier
490 //
491
492 FsInformationClass = IrpSp->Parameters.SetVolume.FsInformationClass;
493 Buffer = Irp->AssociatedIrp.SystemBuffer;
494
495 //
496 // Decode the file object to get the Vcb
497 //
498
500
501 if (TypeOfOpen != UserVolumeOpen) {
502
504
505 DebugTrace(-1, Dbg, "FatCommonSetVolumeInfo -> STATUS_ACCESS_DENIED\n", 0);
506
508 }
509
510 //
511 // Acquire exclusive access to the Vcb and enqueue the Irp if we didn't
512 // get access
513 //
514
515 if (!FatAcquireExclusiveVcb( IrpContext, Vcb )) {
516
517 DebugTrace(0, Dbg, "Cannot acquire Vcb\n", 0);
518
519 Status = FatFsdPostRequest( IrpContext, Irp );
520
521 DebugTrace(-1, Dbg, "FatCommonSetVolumeInfo -> %08lx\n", Status );
522 return Status;
523 }
524
525 _SEH2_TRY {
526
527 //
528 // Make sure the vcb is in a usable condition. This will raise
529 // an error condition if the volume is unusable
530 //
531 // Also verify the Root Dcb since we need info from there.
532 //
533
534 FatVerifyFcb( IrpContext, Vcb->RootDcb );
535
536 //
537 // Based on the information class we'll do different actions. Each
538 // of the procedures that we're calling performs the action if
539 // possible and returns true if it successful and false if it couldn't
540 // wait for any I/O to complete.
541 //
542
543 switch (FsInformationClass) {
544
546
547 Status = FatSetFsLabelInfo( IrpContext, Vcb, Buffer );
548 break;
549
550 default:
551
553 break;
554 }
555
556 FatUnpinRepinnedBcbs( IrpContext );
557
558 } _SEH2_FINALLY {
559
560 DebugUnwind( FatCommonSetVolumeInfo );
561
562 FatReleaseVcb( IrpContext, Vcb );
563
565
566 FatCompleteRequest( IrpContext, Irp, Status );
567 }
568
569 DebugTrace(-1, Dbg, "FatCommonSetVolumeInfo -> %08lx\n", Status);
570 } _SEH2_END;
571
572 return Status;
573}
574
575
576//
577// Internal support routine
578//
579
582 IN PIRP_CONTEXT IrpContext,
583 IN PVCB Vcb,
586 )
587
588/*++
589
590Routine Description:
591
592 This routine implements the query volume info call
593
594Arguments:
595
596 Vcb - Supplies the Vcb being queried
597
598 Buffer - Supplies a pointer to the output buffer where the information
599 is to be returned
600
601 Length - Supplies the length of the buffer in bytes. This variable
602 upon return receives the remaining bytes free in the buffer
603
604Return Value:
605
606 NTSTATUS - Returns the status for the query
607
608--*/
609
610{
612
614
615 PAGED_CODE();
616
617 DebugTrace(0, Dbg, "FatQueryFsVolumeInfo...\n", 0);
618
619 //
620 // Zero out the buffer, then extract and fill up the non zero fields.
621 //
622
624
625 Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
626
627 Buffer->SupportsObjects = FALSE;
628
630
631 //
632 // Check if the buffer we're given is long enough
633 //
634
635 if ( *Length >= (ULONG)Vcb->Vpb->VolumeLabelLength ) {
636
637 BytesToCopy = Vcb->Vpb->VolumeLabelLength;
638
640
641 } else {
642
644
646 }
647
648 //
649 // Copy over what we can of the volume label, and adjust *Length
650 //
651
652 Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
653
654 RtlCopyMemory( &Buffer->VolumeLabel[0],
655 &Vcb->Vpb->VolumeLabel[0],
656 BytesToCopy );
657
659
660 //
661 // Set our status and return to our caller
662 //
663
664 UNREFERENCED_PARAMETER( IrpContext );
665
666 return Status;
667}
668
669
670//
671// Internal support routine
672//
673
676 IN PIRP_CONTEXT IrpContext,
677 IN PVCB Vcb,
680 )
681
682/*++
683
684Routine Description:
685
686 This routine implements the query volume size call
687
688Arguments:
689
690 Vcb - Supplies the Vcb being queried
691
692 Buffer - Supplies a pointer to the output buffer where the information
693 is to be returned
694
695 Length - Supplies the length of the buffer in bytes. This variable
696 upon return receives the remaining bytes free in the buffer
697
698Return Value:
699
700 Status - Returns the status for the query
701
702--*/
703
704{
705 PAGED_CODE();
706
707 DebugTrace(0, Dbg, "FatQueryFsSizeInfo...\n", 0);
708
710
711 //
712 // Set the output buffer.
713 //
714
715 Buffer->TotalAllocationUnits.LowPart =
716 Vcb->AllocationSupport.NumberOfClusters;
717 Buffer->AvailableAllocationUnits.LowPart =
718 Vcb->AllocationSupport.NumberOfFreeClusters;
719
720 Buffer->SectorsPerAllocationUnit = Vcb->Bpb.SectorsPerCluster;
721 Buffer->BytesPerSector = Vcb->Bpb.BytesPerSector;
722
723 //
724 // Adjust the length variable
725 //
726
728
729 //
730 // And return success to our caller
731 //
732
733 UNREFERENCED_PARAMETER( IrpContext );
734
735 return STATUS_SUCCESS;
736}
737
738
739//
740// Internal support routine
741//
742
745 IN PIRP_CONTEXT IrpContext,
746 IN PVCB Vcb,
749 )
750
751/*++
752
753Routine Description:
754
755 This routine implements the query volume device call
756
757Arguments:
758
759 Vcb - Supplies the Vcb being queried
760
761 Buffer - Supplies a pointer to the output buffer where the information
762 is to be returned
763
764 Length - Supplies the length of the buffer in bytes. This variable
765 upon return receives the remaining bytes free in the buffer
766
767Return Value:
768
769 Status - Returns the status for the query
770
771--*/
772
773{
774 PAGED_CODE();
775
776 DebugTrace(0, Dbg, "FatQueryFsDeviceInfo...\n", 0);
777
779
780 //
781 // Set the output buffer
782 //
783
784 Buffer->DeviceType = FILE_DEVICE_DISK;
785
786 Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
787
788 //
789 // Adjust the length variable
790 //
791
793
794 //
795 // And return success to our caller
796 //
797
798 UNREFERENCED_PARAMETER( IrpContext );
799
800 return STATUS_SUCCESS;
801}
802
803
804//
805// Internal support routine
806//
807
810 IN PIRP_CONTEXT IrpContext,
811 IN PVCB Vcb,
814 )
815
816/*++
817
818Routine Description:
819
820 This routine implements the query volume attribute call
821
822Arguments:
823
824 Vcb - Supplies the Vcb being queried
825
826 Buffer - Supplies a pointer to the output buffer where the information
827 is to be returned
828
829 Length - Supplies the length of the buffer in bytes. This variable
830 upon return receives the remaining bytes free in the buffer
831
832Return Value:
833
834 Status - Returns the status for the query
835
836--*/
837
838{
840
842
843 PAGED_CODE();
844
845 DebugTrace(0, Dbg, "FatQueryFsAttributeInfo...\n", 0);
846
847 //
848 // Set the output buffer
849 //
850
851 Buffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES |
853
854 if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED )) {
855
856 SetFlag( Buffer->FileSystemAttributes, FILE_READ_ONLY_VOLUME );
857 }
858
859
860 Buffer->MaximumComponentNameLength = FatData.ChicagoMode ? 255 : 12;
861
862 if (FatIsFat32(Vcb)) {
863
864 //
865 // Determine how much of the file system name will fit.
866 //
867
869 FileSystemName[0] )) >= 10 ) {
870
871 BytesToCopy = 10;
873 FileSystemName[0] ) + 10;
875
876 } else {
877
879 FileSystemName[0]);
880 *Length = 0;
881
883 }
884
885 RtlCopyMemory( &Buffer->FileSystemName[0], L"FAT32", BytesToCopy );
886
887 } else {
888
889 //
890 // Determine how much of the file system name will fit.
891 //
892
894 FileSystemName[0] )) >= 6 ) {
895
896 BytesToCopy = 6;
898 FileSystemName[0] ) + 6;
900
901 } else {
902
904 FileSystemName[0]);
905 *Length = 0;
906
908 }
909
910
911 RtlCopyMemory( &Buffer->FileSystemName[0], L"FAT", BytesToCopy );
912 }
913
914 Buffer->FileSystemNameLength = BytesToCopy;
915
916 //
917 // And return success to our caller
918 //
919
920 UNREFERENCED_PARAMETER( IrpContext );
922
923 return Status;
924}
925
926
927//
928// Internal support routine
929//
930
933 IN PIRP_CONTEXT IrpContext,
934 IN PVCB Vcb,
937 )
938
939/*++
940
941Routine Description:
942
943 This routine implements the query volume full size call
944
945Arguments:
946
947 Vcb - Supplies the Vcb being queried
948
949 Buffer - Supplies a pointer to the output buffer where the information
950 is to be returned
951
952 Length - Supplies the length of the buffer in bytes. This variable
953 upon return receives the remaining bytes free in the buffer
954
955Return Value:
956
957 Status - Returns the status for the query
958
959--*/
960
961{
962 PAGED_CODE();
963
964 DebugTrace(0, Dbg, "FatQueryFsSizeInfo...\n", 0);
965
967
968 Buffer->TotalAllocationUnits.LowPart =
969 Vcb->AllocationSupport.NumberOfClusters;
970 Buffer->CallerAvailableAllocationUnits.LowPart =
971 Vcb->AllocationSupport.NumberOfFreeClusters;
972 Buffer->ActualAvailableAllocationUnits.LowPart =
973 Buffer->CallerAvailableAllocationUnits.LowPart;
974 Buffer->SectorsPerAllocationUnit = Vcb->Bpb.SectorsPerCluster;
975 Buffer->BytesPerSector = Vcb->Bpb.BytesPerSector;
976
977 //
978 // Adjust the length variable
979 //
980
982
983 //
984 // And return success to our caller
985 //
986
987 UNREFERENCED_PARAMETER( IrpContext );
988
989 return STATUS_SUCCESS;
990}
991
992
993//
994// Internal support routine
995//
996
999 IN PIRP_CONTEXT IrpContext,
1000 IN PVCB Vcb,
1002 )
1003
1004/*++
1005
1006Routine Description:
1007
1008 This routine implements the set volume label call
1009
1010Arguments:
1011
1012 Vcb - Supplies the Vcb being queried
1013
1014 Buffer - Supplies the input where the information is stored.
1015
1016Return Value:
1017
1018 NTSTATUS - Returns the status for the operation
1019
1020--*/
1021
1022{
1024
1026 PBCB DirentBcb = NULL;
1028
1029 WCHAR TmpBuffer[11];
1030 UCHAR OemBuffer[11];
1031 OEM_STRING OemLabel;
1033 UNICODE_STRING UpcasedLabel;
1034
1035 PAGED_CODE();
1036
1037 DebugTrace(+1, Dbg, "FatSetFsLabelInfo...\n", 0);
1038
1039 //
1040 // Setup our local variable
1041 //
1042
1043 UnicodeString.Length = (USHORT)Buffer->VolumeLabelLength;
1044 UnicodeString.MaximumLength = UnicodeString.Length;
1045 UnicodeString.Buffer = (PWSTR) &Buffer->VolumeLabel[0];
1046
1047 //
1048 // Make sure the name can fit into the stack buffer
1049 //
1050
1051 if ( UnicodeString.Length > 11*sizeof(WCHAR) ) {
1052
1054 }
1055
1056 //
1057 // Upcase the name and convert it to the Oem code page.
1058 //
1059
1060 OemLabel.Buffer = (PCHAR)&OemBuffer[0];
1061 OemLabel.Length = 0;
1062 OemLabel.MaximumLength = 11;
1063
1066 FALSE );
1067
1068 //
1069 // Volume label that fits in 11 unicode character length limit
1070 // is not necessarily within 11 characters in OEM character set.
1071 //
1072
1073 if (!NT_SUCCESS( Status )) {
1074
1075 DebugTrace(-1, Dbg, "FatSetFsLabelInfo: Label must be too long. %08lx\n", Status );
1076
1078 }
1079
1080 //
1081 // Strip spaces off of the label.
1082 //
1083
1084 if (OemLabel.Length > 0) {
1085
1086 USHORT i;
1087 USHORT LastSpaceIndex = MAXUSHORT;
1088
1089 //
1090 // Check the label for illegal characters
1091 //
1092
1093 for ( i = 0; i < (ULONG)OemLabel.Length; i += 1 ) {
1094
1095 if ( FsRtlIsLeadDbcsCharacter( OemLabel.Buffer[i] ) ) {
1096
1097 LastSpaceIndex = MAXUSHORT;
1098 i += 1;
1099 continue;
1100 }
1101
1102 if (!FsRtlIsAnsiCharacterLegalFat(OemLabel.Buffer[i], FALSE) ||
1103 (OemLabel.Buffer[i] == '.')) {
1104
1106 }
1107
1108 //
1109 // Watch for the last run of spaces, so we can strip them.
1110 //
1111
1112 if (OemLabel.Buffer[i] == ' ' &&
1113 LastSpaceIndex == MAXUSHORT) {
1114 LastSpaceIndex = i;
1115 } else {
1116 LastSpaceIndex = MAXUSHORT;
1117 }
1118 }
1119
1120 if (LastSpaceIndex != MAXUSHORT) {
1121 OemLabel.Length = LastSpaceIndex;
1122 }
1123 }
1124
1125 //
1126 // Get the Unicode upcased string to store in the VPB.
1127 //
1128
1129 UpcasedLabel.Length = UnicodeString.Length;
1130 UpcasedLabel.MaximumLength = 11*sizeof(WCHAR);
1131 UpcasedLabel.Buffer = &TmpBuffer[0];
1132
1134 &OemLabel,
1135 FALSE );
1136
1137 if (!NT_SUCCESS( Status )) {
1138
1139 DebugTrace(-1, Dbg, "FatSetFsLabelInfo: Label must be too long. %08lx\n", Status );
1140
1142 }
1143
1144 DirentBcb = NULL;
1145
1146 //
1147 // Make this look like a write through to disk. This is important to
1148 // avoid a unpleasant window where it looks like we have the wrong volume.
1149 //
1150
1151 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH );
1152
1153 _SEH2_TRY {
1154
1155 //
1156 // Are we setting or removing the label? Note that shaving spaces could
1157 // make this different than wondering if the input buffer is non-zero length.
1158 //
1159
1160 if (OemLabel.Length > 0) {
1161
1162 //
1163 // Translate the first character from 0xe5 to 0x5.
1164 //
1165
1166 if ((UCHAR)OemLabel.Buffer[0] == 0xe5) {
1167
1168 OemLabel.Buffer[0] = FAT_DIRENT_REALLY_0E5;
1169 }
1170
1171 //
1172 // Locate the volume label if there already is one
1173 //
1174
1175 FatLocateVolumeLabel( IrpContext,
1176 Vcb,
1177 &Dirent,
1178 &DirentBcb,
1179 (PVBO)&ByteOffset );
1180
1181 //
1182 // Check that we really got one, if not then we need to create
1183 // a new one. The procedure we call will raise an appropriate
1184 // status if we are not able to allocate a new dirent
1185 //
1186
1187 if (Dirent == NULL) {
1188
1189 ByteOffset = FatCreateNewDirent( IrpContext,
1190 Vcb->RootDcb,
1191 1,
1192 FALSE );
1193
1194 FatPrepareWriteDirectoryFile( IrpContext,
1195 Vcb->RootDcb,
1196 ByteOffset,
1197 sizeof(DIRENT),
1198 &DirentBcb,
1199#ifndef __REACTOS__
1200 &Dirent,
1201#else
1202 (PVOID *)&Dirent,
1203#endif
1204 FALSE,
1205 TRUE,
1206 &Status );
1207
1209
1210 } else {
1211
1212 //
1213 // Just mark this guy dirty now.
1214 //
1215
1216 FatSetDirtyBcb( IrpContext, DirentBcb, Vcb, TRUE );
1217 }
1218
1219 //
1220 // Now reconstruct the volume label dirent.
1221 //
1222
1223 FatConstructLabelDirent( IrpContext,
1224 Dirent,
1225 &OemLabel );
1226
1227 //
1228 // Unpin the Bcb here so that we will get any IO errors
1229 // here before changing the VPB label.
1230 //
1231
1232 FatUnpinBcb( IrpContext, DirentBcb );
1233 FatUnpinRepinnedBcbs( IrpContext );
1234
1235 //
1236 // Now set the upcased label in the VPB
1237 //
1238
1239 RtlCopyMemory( &Vcb->Vpb->VolumeLabel[0],
1240 &UpcasedLabel.Buffer[0],
1241 UpcasedLabel.Length );
1242
1243 Vcb->Vpb->VolumeLabelLength = UpcasedLabel.Length;
1244
1245 } else {
1246
1247 //
1248 // Otherwise we're trying to delete the label
1249 // Locate the current volume label if there already is one
1250 //
1251
1252 FatLocateVolumeLabel( IrpContext,
1253 Vcb,
1254 &Dirent,
1255 &DirentBcb,
1256 (PVBO)&ByteOffset );
1257
1258 //
1259 // Check that we really got one
1260 //
1261
1262 if (Dirent == NULL) {
1263
1265 }
1266
1267 //
1268 // Now delete the current label.
1269 //
1270
1271 Dirent->FileName[0] = FAT_DIRENT_DELETED;
1272
1273 NT_ASSERT( (Vcb->RootDcb->Specific.Dcb.UnusedDirentVbo == 0xffffffff) ||
1274 RtlAreBitsSet( &Vcb->RootDcb->Specific.Dcb.FreeDirentBitmap,
1275 ByteOffset / sizeof(DIRENT),
1276 1 ) );
1277
1278 RtlClearBits( &Vcb->RootDcb->Specific.Dcb.FreeDirentBitmap,
1279 ByteOffset / sizeof(DIRENT),
1280 1 );
1281
1282 FatSetDirtyBcb( IrpContext, DirentBcb, Vcb, TRUE );
1283
1284 //
1285 // Unpin the Bcb here so that we will get any IO errors
1286 // here before changing the VPB label.
1287 //
1288
1289 FatUnpinBcb( IrpContext, DirentBcb );
1290 FatUnpinRepinnedBcbs( IrpContext );
1291
1292 //
1293 // Now set the label in the VPB
1294 //
1295
1296 Vcb->Vpb->VolumeLabelLength = 0;
1297 }
1298
1300
1301 try_exit: NOTHING;
1302 } _SEH2_FINALLY {
1303
1304 DebugUnwind( FatSetFsALabelInfo );
1305
1306 FatUnpinBcb( IrpContext, DirentBcb );
1307
1308 DebugTrace(-1, Dbg, "FatSetFsALabelInfo -> STATUS_SUCCESS\n", 0);
1309 } _SEH2_END;
1310
1311 return Status;
1312}
1313
1314#if (NTDDI_VERSION >= NTDDI_WIN8)
1315
1318 _In_ PIRP_CONTEXT IrpContext,
1319 _In_ PVCB Vcb,
1320 _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
1322 )
1323
1324/*++
1325
1326Routine Description:
1327
1328 This routine implements the query sector size information call
1329 This operation will work on any handle and requires no privilege.
1330
1331Arguments:
1332
1333 Vcb - Supplies the Vcb being queried
1334
1335 Buffer - Supplies a pointer to the output buffer where the information
1336 is to be returned
1337
1338 Length - Supplies the length of the buffer in bytes. This variable
1339 upon return receives the remaining bytes free in the buffer
1340
1341Return Value:
1342
1343 NTSTATUS - Returns the status for the query
1344
1345--*/
1346
1347{
1349
1350 PAGED_CODE();
1351 UNREFERENCED_PARAMETER( IrpContext );
1352
1353 //
1354 // Sufficient buffer size is guaranteed by the I/O manager or the
1355 // originating kernel mode driver.
1356 //
1357
1358 ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
1359 _Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
1360
1361 //
1362 // Retrieve the sector size information
1363 //
1364
1365 Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
1366 Buffer );
1367
1368 //
1369 // Adjust the length variable
1370 //
1371
1372 if (NT_SUCCESS( Status )) {
1373
1374 *Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
1375 }
1376
1377 return Status;
1378}
1379
1380#endif
1381
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define CanFsdWait(I)
Definition: cdprocs.h:2001
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define try_return(S)
Definition: cdprocs.h:2179
Definition: bufpool.h:45
#define _Requires_lock_held_(lock)
_In_ PIRP Irp
Definition: csq.h:116
#define RtlAreBitsSet
Definition: dbgbitmap.h:328
#define RtlClearBits
Definition: dbgbitmap.h:331
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:428
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
VBO * PVBO
Definition: fat.h:39
#define FAT_DIRENT_REALLY_0E5
Definition: fat.h:335
#define FAT_DIRENT_DELETED
Definition: fat.h:337
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
VOID FatConstructLabelDirent(IN PIRP_CONTEXT IrpContext, IN OUT PDIRENT Dirent, IN POEM_STRING Label)
Definition: dirsup.c:2440
NTSTATUS FatQueryFsSectorSizeInfo(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer, _Inout_ PULONG Length)
Definition: volinfo.c:1317
NTSTATUS FatQueryFsDeviceInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_DEVICE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:744
NTSTATUS FatQueryFsAttributeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:809
NTSTATUS FatQueryFsVolumeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_VOLUME_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:581
NTSTATUS FatQueryFsFullSizeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_FULL_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:932
NTSTATUS FatQueryFsSizeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:675
#define Dbg
Definition: volinfo.c:23
NTSTATUS FatSetFsLabelInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_LABEL_INFORMATION Buffer)
Definition: volinfo.c:998
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
FAT_DATA FatData
Definition: fatdata.c:56
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:547
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2418
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2634
#define FatAcquireExclusiveVcb(IC, V)
Definition: fatprocs.h:1461
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1641
#define FatIsFat32(VCB)
Definition: fatprocs.h:1447
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1330
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsLabelInformation
Definition: from_kernel.h:220
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
struct _FILE_FS_SIZE_INFORMATION FILE_FS_SIZE_INFORMATION
enum _FSINFOCLASS FS_INFORMATION_CLASS
struct _FILE_FS_FULL_SIZE_INFORMATION FILE_FS_FULL_SIZE_INFORMATION
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
#define FsRtlEnterFileSystem
#define FsRtlIsAnsiCharacterLegalFat(C, WILD)
Definition: fsrtlfuncs.h:1611
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
#define NOTHING
Definition: input_list.c:10
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define _Inout_
Definition: ms_sal.h:378
#define _Out_writes_bytes_(size)
Definition: ms_sal.h:350
#define _In_
Definition: ms_sal.h:308
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
DRIVER_DISPATCH(nfs41_FsdDispatch)
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1473
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
Definition: cdstruc.h:1067
BOOLEAN ChicagoMode
Definition: fatstruc.h:87
Definition: cdstruc.h:902
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _IO_STACK_LOCATION::@3974::@3987 QueryVolume
union _IO_STACK_LOCATION::@1575 Parameters
struct _IO_STACK_LOCATION::@3974::@3988 SetVolume
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
else
Definition: tritemp.h:161
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156
STRING OEM_STRING
Definition: umtypes.h:203
#define IRP_MJ_SET_VOLUME_INFORMATION
#define NT_ASSERT
Definition: rtlfuncs.h:3324
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180