ReactOS  0.4.14-dev-384-g5b37caa
volinfo.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  VolInfo.c
8 
9 Abstract:
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,
76  _In_ PVCB Vcb,
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 
101 NTSTATUS
102 NTAPI
103 FatFsdQueryVolumeInformation (
104  _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
106  )
107 
108 /*++
109 
110 Routine Description:
111 
112  This routine implements the Fsd part of the NtQueryVolumeInformation API
113  call.
114 
115 Arguments:
116 
117  VolumeDeviceObject - Supplies the volume device object where the file
118  being queried exists.
119 
120  Irp - Supplies the Irp being processed.
121 
122 Return 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  // execption 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 
182 NTSTATUS
183 NTAPI
184 FatFsdSetVolumeInformation (
185  _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
187  )
188 
189 /*++
190 
191 Routine Description:
192 
193  This routine implements the FSD part of the NtSetVolumeInformation API
194  call.
195 
196 Arguments:
197 
198  VolumeDeviceObject - Supplies the volume device object where the file
199  being set exists.
200 
201  Irp - Supplies the Irp being processed.
202 
203 Return 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  // execption 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_)
262 NTSTATUS
263 FatCommonQueryVolumeInfo (
264  IN PIRP_CONTEXT IrpContext,
265  IN PIRP Irp
266  )
267 
268 /*++
269 
270 Routine Description:
271 
272  This is the common routine for querying volume information called by both
273  the fsd and fsp threads.
274 
275 Arguments:
276 
277  Irp - Supplies the Irp being processed
278 
279 Return 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 
293  ULONG Length;
295  PVOID Buffer;
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 
317  Length = IrpSp->Parameters.QueryVolume.Length;
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 );
328  _Analysis_assume_( Vcb != NULL );
329 
330  _SEH2_TRY {
331 
332  //
333  // Make sure the vcb is in a usable condition. This will raise
334  // and 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 
426  if (!_SEH2_AbnormalTermination()) {
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_)
439 NTSTATUS
440 FatCommonSetVolumeInfo (
441  IN PIRP_CONTEXT IrpContext,
442  IN PIRP Irp
443  )
444 
445 /*++
446 
447 Routine Description:
448 
449  This is the common routine for setting Volume Information called by both
450  the fsd and fsp threads.
451 
452 Arguments:
453 
454  Irp - Supplies the Irp being processed
455 
456 Return 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 
472  PVOID Buffer;
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 
507  return STATUS_ACCESS_DENIED;
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  // and 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 
564  if (!_SEH2_AbnormalTermination()) {
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 
580 NTSTATUS
582  IN PIRP_CONTEXT IrpContext,
583  IN PVCB Vcb,
586  )
587 
588 /*++
589 
590 Routine Description:
591 
592  This routine implements the query volume info call
593 
594 Arguments:
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 byte. This variable
602  upon return recieves the remaining bytes free in the buffer
603 
604 Return 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 
629  *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
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 
643  BytesToCopy = *Length;
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 
658  *Length -= BytesToCopy;
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 
674 NTSTATUS
676  IN PIRP_CONTEXT IrpContext,
677  IN PVCB Vcb,
680  )
681 
682 /*++
683 
684 Routine Description:
685 
686  This routine implements the query volume size call
687 
688 Arguments:
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 byte. This variable
696  upon return recieves the remaining bytes free in the buffer
697 
698 Return 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 
727  *Length -= sizeof(FILE_FS_SIZE_INFORMATION);
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 
743 NTSTATUS
745  IN PIRP_CONTEXT IrpContext,
746  IN PVCB Vcb,
749  )
750 
751 /*++
752 
753 Routine Description:
754 
755  This routine implements the query volume device call
756 
757 Arguments:
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 byte. This variable
765  upon return recieves the remaining bytes free in the buffer
766 
767 Return 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 
808 NTSTATUS
810  IN PIRP_CONTEXT IrpContext,
811  IN PVCB Vcb,
814  )
815 
816 /*++
817 
818 Routine Description:
819 
820  This routine implements the query volume attribute call
821 
822 Arguments:
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 byte. This variable
830  upon return recieves the remaining bytes free in the buffer
831 
832 Return 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 
931 NTSTATUS
933  IN PIRP_CONTEXT IrpContext,
934  IN PVCB Vcb,
937  )
938 
939 /*++
940 
941 Routine Description:
942 
943  This routine implements the query volume full size call
944 
945 Arguments:
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 byte. This variable
953  upon return recieves the remaining bytes free in the buffer
954 
955 Return 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 
997 NTSTATUS
999  IN PIRP_CONTEXT IrpContext,
1000  IN PVCB Vcb,
1002  )
1003 
1004 /*++
1005 
1006 Routine Description:
1007 
1008  This routine implements the set volume label call
1009 
1010 Arguments:
1011 
1012  Vcb - Supplies the Vcb being queried
1013 
1014  Buffer - Supplies the input where the information is stored.
1015 
1016 Return Value:
1017 
1018  NTSTATUS - Returns the status for the operation
1019 
1020 --*/
1021 
1022 {
1023  NTSTATUS Status;
1024 
1025  PDIRENT Dirent;
1026  PBCB DirentBcb = NULL;
1027  ULONG ByteOffset;
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 
1065  &UnicodeString,
1066  FALSE );
1067 
1068  //
1069  // Volume label that fits in 11 unicode character length limit
1070  // is not necessary 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 
1133  Status = RtlOemStringToCountedUnicodeString( &UpcasedLabel,
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  // Locate the volume label if there already is one
1164  //
1165 
1166  FatLocateVolumeLabel( IrpContext,
1167  Vcb,
1168  &Dirent,
1169  &DirentBcb,
1170  (PVBO)&ByteOffset );
1171 
1172  //
1173  // Check that we really got one, if not then we need to create
1174  // a new one. The procedure we call will raise an appropriate
1175  // status if we are not able to allocate a new dirent
1176  //
1177 
1178  if (Dirent == NULL) {
1179 
1180  ByteOffset = FatCreateNewDirent( IrpContext,
1181  Vcb->RootDcb,
1182  1,
1183  FALSE );
1184 
1185  FatPrepareWriteDirectoryFile( IrpContext,
1186  Vcb->RootDcb,
1187  ByteOffset,
1188  sizeof(DIRENT),
1189  &DirentBcb,
1190 #ifndef __REACTOS__
1191  &Dirent,
1192 #else
1193  (PVOID *)&Dirent,
1194 #endif
1195  FALSE,
1196  TRUE,
1197  &Status );
1198 
1200 
1201  } else {
1202 
1203  //
1204  // Just mark this guy dirty now.
1205  //
1206 
1207  FatSetDirtyBcb( IrpContext, DirentBcb, Vcb, TRUE );
1208  }
1209 
1210  //
1211  // Now reconstruct the volume label dirent.
1212  //
1213 
1214  FatConstructLabelDirent( IrpContext,
1215  Dirent,
1216  &OemLabel );
1217 
1218  //
1219  // Unpin the Bcb here so that we will get any IO errors
1220  // here before changing the VPB label.
1221  //
1222 
1223  FatUnpinBcb( IrpContext, DirentBcb );
1224  FatUnpinRepinnedBcbs( IrpContext );
1225 
1226  //
1227  // Now set the upcased label in the VPB
1228  //
1229 
1230  RtlCopyMemory( &Vcb->Vpb->VolumeLabel[0],
1231  &UpcasedLabel.Buffer[0],
1232  UpcasedLabel.Length );
1233 
1234  Vcb->Vpb->VolumeLabelLength = UpcasedLabel.Length;
1235 
1236  } else {
1237 
1238  //
1239  // Otherwise we're trying to delete the label
1240  // Locate the current volume label if there already is one
1241  //
1242 
1243  FatLocateVolumeLabel( IrpContext,
1244  Vcb,
1245  &Dirent,
1246  &DirentBcb,
1247  (PVBO)&ByteOffset );
1248 
1249  //
1250  // Check that we really got one
1251  //
1252 
1253  if (Dirent == NULL) {
1254 
1256  }
1257 
1258  //
1259  // Now delete the current label.
1260  //
1261 
1262  Dirent->FileName[0] = FAT_DIRENT_DELETED;
1263 
1264  NT_ASSERT( (Vcb->RootDcb->Specific.Dcb.UnusedDirentVbo == 0xffffffff) ||
1265  RtlAreBitsSet( &Vcb->RootDcb->Specific.Dcb.FreeDirentBitmap,
1266  ByteOffset / sizeof(DIRENT),
1267  1 ) );
1268 
1269  RtlClearBits( &Vcb->RootDcb->Specific.Dcb.FreeDirentBitmap,
1270  ByteOffset / sizeof(DIRENT),
1271  1 );
1272 
1273  FatSetDirtyBcb( IrpContext, DirentBcb, Vcb, TRUE );
1274 
1275  //
1276  // Unpin the Bcb here so that we will get any IO errors
1277  // here before changing the VPB label.
1278  //
1279 
1280  FatUnpinBcb( IrpContext, DirentBcb );
1281  FatUnpinRepinnedBcbs( IrpContext );
1282 
1283  //
1284  // Now set the label in the VPB
1285  //
1286 
1287  Vcb->Vpb->VolumeLabelLength = 0;
1288  }
1289 
1291 
1292  try_exit: NOTHING;
1293  } _SEH2_FINALLY {
1294 
1295  DebugUnwind( FatSetFsALabelInfo );
1296 
1297  FatUnpinBcb( IrpContext, DirentBcb );
1298 
1299  DebugTrace(-1, Dbg, "FatSetFsALabelInfo -> STATUS_SUCCESS\n", 0);
1300  } _SEH2_END;
1301 
1302  return Status;
1303 }
1304 
1305 #if (NTDDI_VERSION >= NTDDI_WIN8)
1306 
1307 NTSTATUS
1309  _In_ PIRP_CONTEXT IrpContext,
1310  _In_ PVCB Vcb,
1311  _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer,
1313  )
1314 
1315 /*++
1316 
1317 Routine Description:
1318 
1319  This routine implements the query sector size information call
1320  This operation will work on any handle and requires no privilege.
1321 
1322 Arguments:
1323 
1324  Vcb - Supplies the Vcb being queried
1325 
1326  Buffer - Supplies a pointer to the output buffer where the information
1327  is to be returned
1328 
1329  Length - Supplies the length of the buffer in byte. This variable
1330  upon return receives the remaining bytes free in the buffer
1331 
1332 Return Value:
1333 
1334  NTSTATUS - Returns the status for the query
1335 
1336 --*/
1337 
1338 {
1339  NTSTATUS Status;
1340 
1341  PAGED_CODE();
1342  UNREFERENCED_PARAMETER( IrpContext );
1343 
1344  //
1345  // Sufficient buffer size is guaranteed by the I/O manager or the
1346  // originating kernel mode driver.
1347  //
1348 
1349  ASSERT( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
1350  _Analysis_assume_( *Length >= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION ));
1351 
1352  //
1353  // Retrieve the sector size information
1354  //
1355 
1356  Status = FsRtlGetSectorSizeInformation( Vcb->Vpb->RealDevice,
1357  Buffer );
1358 
1359  //
1360  // Adjust the length variable
1361  //
1362 
1363  if (NT_SUCCESS( Status )) {
1364 
1365  *Length -= sizeof( FILE_FS_SECTOR_SIZE_INFORMATION );
1366  }
1367 
1368  return Status;
1369 }
1370 
1371 #endif
1372 
NTSTATUS FatQueryFsVolumeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_VOLUME_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:581
#define IN
Definition: typedefs.h:38
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
struct _FILE_FS_FULL_SIZE_INFORMATION FILE_FS_FULL_SIZE_INFORMATION
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1329
#define FsRtlEnterFileSystem
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define FsRtlExitFileSystem
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2621
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:54
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
Definition: cdstruc.h:1073
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
NTSTATUS FatSetFsLabelInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_LABEL_INFORMATION Buffer)
Definition: volinfo.c:998
#define IRP_MJ_SET_VOLUME_INFORMATION
Definition: cdstruc.h:504
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:569
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1463
BOOLEAN ChicagoMode
Definition: fatstruc.h:86
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156
STRING OEM_STRING
Definition: umtypes.h:203
#define PAGED_CODE()
Definition: video.h:57
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3167
_SEH2_TRY
Definition: create.c:4250
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2401
NTSTATUS FatQueryFsSizeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:675
else
Definition: tritemp.h:161
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS FatQueryFsAttributeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:809
_Requires_lock_held_(_Global_critical_region_)
Definition: volinfo.c:29
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:537
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define _Out_writes_bytes_(size)
Definition: no_sal2.h:370
Definition: bufpool.h:45
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2300
enum _FSINFOCLASS FS_INFORMATION_CLASS
#define PCHAR
Definition: match.c:90
#define DebugUnwind(X)
Definition: fatdata.h:315
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
FAT_DATA FatData
Definition: fatdata.c:56
#define Dbg
Definition: volinfo.c:23
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define try_return(S)
Definition: cdprocs.h:2189
#define Vcb
Definition: cdprocs.h:1425
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define CanFsdWait(I)
Definition: cdprocs.h:2011
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
VBO * PVBO
Definition: fat.h:39
static const WCHAR L[]
Definition: oid.c:1250
#define FsRtlIsAnsiCharacterLegalFat(C, WILD)
Definition: fsrtlfuncs.h:1611
NTSTATUS FatQueryFsDeviceInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_DEVICE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:744
_Function_class_(IRP_MJ_QUERY_VOLUME_INFORMATION)
Definition: volinfo.c:99
#define VOID
Definition: acefi.h:82
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define FatIsFat32(VCB)
Definition: fatprocs.h:1437
Status
Definition: gdiplustypes.h:24
struct _FILE_FS_SIZE_INFORMATION FILE_FS_SIZE_INFORMATION
#define _In_
Definition: no_sal2.h:204
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_SEH2_END
Definition: create.c:4424
NTSYSAPI BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP, ULONG, ULONG)
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define FatAcquireExclusiveVcb(IC, V)
Definition: fatprocs.h:1451
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define FAT_DIRENT_DELETED
Definition: fat.h:337
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
_SEH2_FINALLY
Definition: create.c:4395
unsigned int * PULONG
Definition: retypes.h:1
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1631
#define MAXUSHORT
Definition: typedefs.h:81
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS FatQueryFsFullSizeInfo(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_FULL_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.c:932
VOID FatConstructLabelDirent(IN PIRP_CONTEXT IrpContext, IN OUT PDIRENT Dirent, IN POEM_STRING Label)
Definition: dirsup.c:2440
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:417
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
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:1308
#define NT_ASSERT
Definition: rtlfuncs.h:3312