ReactOS 0.4.15-dev-7906-g1b85a5f
volinfo.c File Reference
#include "fatprocs.h"
Include dependency graph for volinfo.c:

Go to the source code of this file.

Macros

#define Dbg   (DEBUG_TRACE_VOLINFO)
 

Functions

NTSTATUS FatQueryFsVolumeInfo (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_VOLUME_INFORMATION Buffer, IN OUT PULONG Length)
 
NTSTATUS FatQueryFsSizeInfo (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
 
NTSTATUS FatQueryFsDeviceInfo (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_DEVICE_INFORMATION Buffer, IN OUT PULONG Length)
 
NTSTATUS FatQueryFsAttributeInfo (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer, IN OUT PULONG Length)
 
NTSTATUS FatQueryFsFullSizeInfo (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_FULL_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
 
NTSTATUS FatSetFsLabelInfo (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_FS_LABEL_INFORMATION Buffer)
 
NTSTATUS FatQueryFsSectorSizeInfo (_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Out_writes_bytes_(*Length) PFILE_FS_SECTOR_SIZE_INFORMATION Buffer, _Inout_ PULONG Length)
 
 _Function_class_ (IRP_MJ_QUERY_VOLUME_INFORMATION)
 
 _Function_class_ (IRP_MJ_SET_VOLUME_INFORMATION)
 
 _Requires_lock_held_ (_Global_critical_region_)
 

Macro Definition Documentation

◆ Dbg

#define Dbg   (DEBUG_TRACE_VOLINFO)

Definition at line 23 of file volinfo.c.

Function Documentation

◆ _Function_class_() [1/2]

_Function_class_ ( IRP_MJ_QUERY_VOLUME_INFORMATION  )

Definition at line 99 of file volinfo.c.

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}
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define CanFsdWait(I)
Definition: cdprocs.h:2001
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define Dbg
Definition: volinfo.c:23
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158

◆ _Function_class_() [2/2]

_Function_class_ ( IRP_MJ_SET_VOLUME_INFORMATION  )

Definition at line 180 of file volinfo.c.

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}

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 261 of file volinfo.c.

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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define VOID
Definition: acefi.h:82
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
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 DebugUnwind(X)
Definition: fatdata.h:315
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
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1640
#define _SEH2_FINALLY
Definition: filesup.c:21
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1330
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
enum _FSINFOCLASS FS_INFORMATION_CLASS
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
struct _IO_STACK_LOCATION::@3978::@3991 QueryVolume
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1564 Parameters
Definition: cdstruc.h:498
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ FatQueryFsAttributeInfo()

NTSTATUS FatQueryFsAttributeInfo ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION  Buffer,
IN OUT PULONG  Length 
)

Definition at line 809 of file volinfo.c.

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}
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
FAT_DATA FatData
Definition: fatdata.c:56
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define L(x)
Definition: ntvdm.h:50
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
BOOLEAN ChicagoMode
Definition: fatstruc.h:87
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by _Requires_lock_held_().

◆ FatQueryFsDeviceInfo()

NTSTATUS FatQueryFsDeviceInfo ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_FS_DEVICE_INFORMATION  Buffer,
IN OUT PULONG  Length 
)

Definition at line 744 of file volinfo.c.

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}
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by _Requires_lock_held_().

◆ FatQueryFsFullSizeInfo()

NTSTATUS FatQueryFsFullSizeInfo ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_FS_FULL_SIZE_INFORMATION  Buffer,
IN OUT PULONG  Length 
)

Definition at line 932 of file volinfo.c.

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}
struct _FILE_FS_FULL_SIZE_INFORMATION FILE_FS_FULL_SIZE_INFORMATION

Referenced by _Requires_lock_held_().

◆ FatQueryFsSectorSizeInfo()

NTSTATUS FatQueryFsSectorSizeInfo ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PVCB  Vcb,
_Out_writes_bytes_ *Length PFILE_FS_SECTOR_SIZE_INFORMATION  Buffer,
_Inout_ PULONG  Length 
)

Definition at line 1317 of file volinfo.c.

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}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ASSERT(a)
Definition: mode.c:44

Referenced by _Requires_lock_held_().

◆ FatQueryFsSizeInfo()

NTSTATUS FatQueryFsSizeInfo ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_FS_SIZE_INFORMATION  Buffer,
IN OUT PULONG  Length 
)

Definition at line 675 of file volinfo.c.

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}
struct _FILE_FS_SIZE_INFORMATION FILE_FS_SIZE_INFORMATION

Referenced by _Requires_lock_held_().

◆ FatQueryFsVolumeInfo()

NTSTATUS FatQueryFsVolumeInfo ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_FS_VOLUME_INFORMATION  Buffer,
IN OUT PULONG  Length 
)

Definition at line 581 of file volinfo.c.

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}

Referenced by _Requires_lock_held_().

◆ FatSetFsLabelInfo()

NTSTATUS FatSetFsLabelInfo ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_FS_LABEL_INFORMATION  Buffer 
)

Definition at line 998 of file volinfo.c.

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}
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define try_return(S)
Definition: cdprocs.h:2179
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:428
VBO * PVBO
Definition: fat.h:39
#define FAT_DIRENT_REALLY_0E5
Definition: fat.h:335
#define FAT_DIRENT_DELETED
Definition: fat.h:337
#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
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
#define FsRtlIsAnsiCharacterLegalFat(C, WILD)
Definition: fsrtlfuncs.h:1611
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)
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP, ULONG, ULONG)
#define NOTHING
Definition: input_list.c:10
#define PCHAR
Definition: match.c:90
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1473
USHORT MaximumLength
Definition: env_spec_w32.h:370
else
Definition: tritemp.h:161
uint16_t * PWSTR
Definition: typedefs.h:56
#define MAXUSHORT
Definition: typedefs.h:83
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156
STRING OEM_STRING
Definition: umtypes.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180