00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "iop.h"
00028
#pragma hdrstop
00029
#include <ioevent.h>
00030
00031
#ifdef ALLOC_PRAGMA
00032
#pragma alloc_text(PAGE, NtQueryVolumeInformationFile)
00033
#pragma alloc_text(PAGE, NtSetVolumeInformationFile)
00034
#endif
00035
00036
NTSTATUS
00037 NtQueryVolumeInformationFile(
00038 IN HANDLE FileHandle,
00039 OUT PIO_STATUS_BLOCK IoStatusBlock,
00040 OUT PVOID FsInformation,
00041 IN ULONG Length,
00042 IN FS_INFORMATION_CLASS FsInformationClass
00043 )
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 {
00084
PIRP irp;
00085
NTSTATUS status;
00086
PFILE_OBJECT fileObject;
00087
PDEVICE_OBJECT deviceObject;
00088
PKEVENT event = (
PKEVENT)
NULL;
00089
KPROCESSOR_MODE requestorMode;
00090
PIO_STACK_LOCATION irpSp;
00091 IO_STATUS_BLOCK localIoStatus;
00092 BOOLEAN synchronousIo;
00093
00094
PAGED_CODE();
00095
00096
00097
00098
00099
00100
00101 requestorMode = KeGetPreviousMode();
00102
00103
if (requestorMode !=
KernelMode) {
00104
00105
00106
00107
00108
00109
00110
if ((ULONG) FsInformationClass >= FileFsMaximumInformation ||
00111
IopQueryFsOperationLength[FsInformationClass] == 0) {
00112
return STATUS_INVALID_INFO_CLASS;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
if (Length < (ULONG)
IopQueryFsOperationLength[FsInformationClass]) {
00122
return STATUS_INFO_LENGTH_MISMATCH;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
try {
00134
00135
00136
00137
00138
00139
ProbeForWriteIoStatus( IoStatusBlock );
00140
00141
00142
00143
00144
00145
#if defined(_X86_)
00146
ProbeForWrite( FsInformation, Length,
sizeof( ULONG ) );
00147
#elif defined(_WIN64)
00148
00149
00150
00151
00152
00153
if (
PsGetCurrentProcess()->Wow64Process) {
00154
ProbeForWrite( FsInformation, Length,
sizeof( ULONG ) );
00155 }
else {
00156
ProbeForWrite( FsInformation,
00157 Length,
00158
IopQuerySetFsAlignmentRequirement[FsInformationClass] );
00159
00160 }
00161
#else
00162
ProbeForWrite( FsInformation,
00163 Length,
00164
IopQuerySetFsAlignmentRequirement[FsInformationClass] );
00165
#endif
00166
00167 } except(
EXCEPTION_EXECUTE_HANDLER) {
00168
00169
00170
00171
00172
00173
00174
#if DBG
00175
if (GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) {
00176 DbgBreakPoint();
00177 }
00178
#endif // DBG
00179
00180
return GetExceptionCode();
00181
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192 status =
ObReferenceObjectByHandle( FileHandle,
00193
IopQueryFsOperationAccess[FsInformationClass],
00194
IoFileObjectType,
00195 requestorMode,
00196 (PVOID *) &fileObject,
00197
NULL );
00198
if (!
NT_SUCCESS( status )) {
00199
return status;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
if ((fileObject->Flags &
FO_DIRECT_DEVICE_OPEN) &&
00209 FsInformationClass != FileFsDeviceInformation) {
00210
ObDereferenceObject( fileObject );
00211
return STATUS_INVALID_DEVICE_REQUEST;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
if (fileObject->Flags &
FO_SYNCHRONOUS_IO) {
00222
00223 BOOLEAN interrupted;
00224
00225
if (!
IopAcquireFastLock( fileObject )) {
00226 status =
IopAcquireFileObjectLock( fileObject,
00227 requestorMode,
00228 (BOOLEAN) ((fileObject->Flags &
FO_ALERTABLE_IO) != 0),
00229 &interrupted );
00230
if (interrupted) {
00231
ObDereferenceObject( fileObject );
00232
return status;
00233 }
00234 }
00235 synchronousIo =
TRUE;
00236 }
else {
00237 synchronousIo =
FALSE;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
if (FsInformationClass == FileFsDeviceInformation &&
00257 (fileObject->Flags &
FO_DIRECT_DEVICE_OPEN ||
00258 fileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)) {
00259
00260 PFILE_FS_DEVICE_INFORMATION deviceAttributes;
00261 BOOLEAN deviceMounted =
FALSE;
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 deviceObject = fileObject->DeviceObject;
00273
if (deviceObject->
Vpb) {
00274 deviceMounted =
IopGetMountFlag( deviceObject );
00275 }
00276
00277
00278
00279
00280
00281
00282 deviceAttributes = (PFILE_FS_DEVICE_INFORMATION) FsInformation;
00283
00284
try {
00285
00286 deviceAttributes->DeviceType = deviceObject->
DeviceType;
00287 deviceAttributes->Characteristics = deviceObject->
Characteristics;
00288
if (deviceMounted) {
00289 deviceAttributes->Characteristics |= FILE_DEVICE_IS_MOUNTED;
00290 }
00291
00292 IoStatusBlock->Status = STATUS_SUCCESS;
00293 IoStatusBlock->Information =
sizeof( FILE_FS_DEVICE_INFORMATION );
00294 status = STATUS_SUCCESS;
00295
00296 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00297
00298
00299
00300
00301
00302
00303
00304 status = GetExceptionCode();
00305 }
00306
00307
00308
00309
00310
00311
00312
if (fileObject->Flags &
FO_SYNCHRONOUS_IO) {
00313
IopReleaseFileObjectLock( fileObject );
00314 }
00315
00316
00317
00318
00319
00320
ObDereferenceObject( fileObject );
00321
return status;
00322
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
KeClearEvent( &fileObject->Event );
00335
00336
00337
00338
00339
00340 deviceObject =
IoGetRelatedDeviceObject( fileObject );
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
if (!(fileObject->Flags &
FO_SYNCHRONOUS_IO)) {
00351 event =
ExAllocatePool(
NonPagedPool,
sizeof(
KEVENT ) );
00352
if (event ==
NULL) {
00353
ObDereferenceObject( fileObject );
00354
return STATUS_INSUFFICIENT_RESOURCES;
00355 }
00356
KeInitializeEvent( event, SynchronizationEvent,
FALSE );
00357 }
00358
00359
00360
00361
00362
00363
00364 irp =
IoAllocateIrp( deviceObject->
StackSize,
TRUE );
00365
if (!irp) {
00366
00367
00368
00369
00370
00371
00372
if (!(fileObject->Flags &
FO_SYNCHRONOUS_IO)) {
00373
ExFreePool( event );
00374 }
00375
00376
IopAllocateIrpCleanup( fileObject, (
PKEVENT)
NULL );
00377
00378
return STATUS_INSUFFICIENT_RESOURCES;
00379 }
00380 irp->
Tail.Overlay.OriginalFileObject = fileObject;
00381 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
00382 irp->
RequestorMode = requestorMode;
00383
00384
00385
00386
00387
00388
if (synchronousIo) {
00389 irp->
UserEvent = (
PKEVENT)
NULL;
00390 irp->
UserIosb = IoStatusBlock;
00391 }
else {
00392 irp->
UserEvent = event;
00393 irp->
UserIosb = &localIoStatus;
00394 irp->
Flags =
IRP_SYNCHRONOUS_API;
00395 }
00396 irp->
Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)
NULL;
00397
00398
00399
00400
00401
00402
00403 irpSp =
IoGetNextIrpStackLocation( irp );
00404 irpSp->
MajorFunction =
IRP_MJ_QUERY_VOLUME_INFORMATION;
00405 irpSp->
FileObject = fileObject;
00406
00407
00408
00409
00410
00411
00412
00413
00414 irp->
UserBuffer = FsInformation;
00415 irp->
AssociatedIrp.SystemBuffer = (PVOID)
NULL;
00416 irp->
MdlAddress = (
PMDL)
NULL;
00417
00418
00419
00420
00421
00422
00423
try {
00424
00425 irp->
AssociatedIrp.SystemBuffer =
ExAllocatePoolWithQuota(
NonPagedPool,
00426 Length );
00427 } except(
EXCEPTION_EXECUTE_HANDLER) {
00428
00429
00430
00431
00432
00433
00434
00435
IopExceptionCleanup( fileObject,
00436 irp,
00437 (
PKEVENT)
NULL,
00438 event );
00439
00440
return GetExceptionCode();
00441
00442 }
00443
00444 irp->
Flags |= (ULONG) (
IRP_BUFFERED_IO |
00445
IRP_DEALLOCATE_BUFFER |
00446
IRP_INPUT_OPERATION |
00447
IRP_DEFER_IO_COMPLETION);
00448
00449
00450
00451
00452
00453
00454 irpSp->
Parameters.QueryVolume.Length = Length;
00455 irpSp->
Parameters.QueryVolume.FsInformationClass = FsInformationClass;
00456
00457
00458
00459
00460
00461
00462 status =
IopSynchronousServiceTail( deviceObject,
00463 irp,
00464 fileObject,
00465
TRUE,
00466 requestorMode,
00467 synchronousIo,
00468
OtherTransfer );
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
if (!synchronousIo) {
00479
00480 status =
IopSynchronousApiServiceTail( status,
00481 event,
00482 irp,
00483 requestorMode,
00484 &localIoStatus,
00485 IoStatusBlock );
00486 }
00487
00488
return status;
00489 }
00490
00491
NTSTATUS
00492 NtSetVolumeInformationFile(
00493 IN HANDLE FileHandle,
00494 OUT PIO_STATUS_BLOCK IoStatusBlock,
00495 IN PVOID FsInformation,
00496 IN ULONG Length,
00497 IN FS_INFORMATION_CLASS FsInformationClass
00498 )
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 {
00534
PIRP irp;
00535
NTSTATUS status;
00536
PFILE_OBJECT fileObject;
00537
PDEVICE_OBJECT deviceObject;
00538
PKEVENT event = (
PKEVENT)
NULL;
00539
KPROCESSOR_MODE requestorMode;
00540
PIO_STACK_LOCATION irpSp;
00541 IO_STATUS_BLOCK localIoStatus;
00542 PFILE_FS_LABEL_INFORMATION labelInformation;
00543 BOOLEAN synchronousIo;
00544
PDEVICE_OBJECT targetDeviceObject;
00545
00546
PAGED_CODE();
00547
00548
00549
00550
00551
00552 requestorMode = KeGetPreviousMode();
00553
00554
if (requestorMode !=
KernelMode) {
00555
00556
00557
00558
00559
00560
00561
if ((ULONG) FsInformationClass >= FileFsMaximumInformation ||
00562
IopSetFsOperationLength[FsInformationClass] == 0) {
00563
return STATUS_INVALID_INFO_CLASS;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
if (Length < (ULONG)
IopSetFsOperationLength[FsInformationClass]) {
00573
return STATUS_INFO_LENGTH_MISMATCH;
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
try {
00585
00586
00587
00588
00589
00590
ProbeForWriteIoStatus( IoStatusBlock );
00591
00592
00593
00594
00595
00596
#if defined(_X86_)
00597
ProbeForRead( FsInformation, Length,
sizeof( ULONG ) );
00598
#elif defined(_IA64_)
00599
00600
if (
PsGetCurrentProcess()->Wow64Process) {
00601
ProbeForRead( FsInformation, Length,
sizeof( ULONG ) );
00602 }
00603
else {
00604
ProbeForRead( FsInformation,
00605 Length,
00606
IopQuerySetFsAlignmentRequirement[FsInformationClass] );
00607
00608 }
00609
#else
00610
ProbeForRead( FsInformation,
00611 Length,
00612
IopQuerySetFsAlignmentRequirement[FsInformationClass] );
00613
#endif
00614
00615 } except(
EXCEPTION_EXECUTE_HANDLER) {
00616
00617
00618
00619
00620
00621
00622
00623
#if DBG
00624
if (GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) {
00625 DbgBreakPoint();
00626 }
00627
#endif DBG
00628
00629
return GetExceptionCode();
00630
00631 }
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641 status =
ObReferenceObjectByHandle( FileHandle,
00642
IopSetFsOperationAccess[FsInformationClass],
00643
IoFileObjectType,
00644 requestorMode,
00645 (PVOID *) &fileObject,
00646
NULL );
00647
if (!
NT_SUCCESS( status )) {
00648
return status;
00649 }
00650
00651
00652
00653
00654
00655 status =
IoGetRelatedTargetDevice( fileObject, &targetDeviceObject );
00656
00657
if (
NT_SUCCESS( status )) {
00658
00659
00660
00661
00662
00663
00664
00665
ASSERT(targetDeviceObject);
00666
00667 }
else {
00668 targetDeviceObject =
NULL;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
if (fileObject->Flags &
FO_SYNCHRONOUS_IO) {
00680
00681 BOOLEAN interrupted;
00682
00683
if (!
IopAcquireFastLock( fileObject )) {
00684 status =
IopAcquireFileObjectLock( fileObject,
00685 requestorMode,
00686 (BOOLEAN) ((fileObject->Flags &
FO_ALERTABLE_IO) != 0),
00687 &interrupted );
00688
if (interrupted) {
00689
ObDereferenceObject( fileObject );
00690
if (targetDeviceObject !=
NULL) {
00691
ObDereferenceObject( targetDeviceObject );
00692 }
00693
return status;
00694 }
00695 }
00696 synchronousIo =
TRUE;
00697 }
else {
00698
00699
00700
00701
00702
00703
00704
00705
00706 event =
ExAllocatePool(
NonPagedPool,
sizeof(
KEVENT ) );
00707
if (event ==
NULL) {
00708
ObDereferenceObject( fileObject );
00709
if (targetDeviceObject !=
NULL) {
00710
ObDereferenceObject( targetDeviceObject );
00711 }
00712
return STATUS_INSUFFICIENT_RESOURCES;
00713 }
00714
KeInitializeEvent( event, SynchronizationEvent,
FALSE );
00715 synchronousIo =
FALSE;
00716 }
00717
00718
00719
00720
00721
00722
KeClearEvent( &fileObject->Event );
00723
00724
00725
00726
00727
00728 deviceObject =
IoGetRelatedDeviceObject( fileObject );
00729
00730
00731
00732
00733
00734
00735 irp =
IoAllocateIrp( deviceObject->
StackSize,
TRUE );
00736
if (!irp) {
00737
00738
00739
00740
00741
00742
00743
if (!(fileObject->Flags &
FO_SYNCHRONOUS_IO)) {
00744
ExFreePool( event );
00745 }
00746
00747
IopAllocateIrpCleanup( fileObject, (
PKEVENT)
NULL );
00748
00749
if (targetDeviceObject !=
NULL) {
00750
ObDereferenceObject( targetDeviceObject );
00751 }
00752
00753
return STATUS_INSUFFICIENT_RESOURCES;
00754 }
00755 irp->
Tail.Overlay.OriginalFileObject = fileObject;
00756 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
00757 irp->
RequestorMode = requestorMode;
00758
00759
00760
00761
00762
00763
if (synchronousIo) {
00764 irp->
UserEvent = (
PKEVENT)
NULL;
00765 irp->
UserIosb = IoStatusBlock;
00766 }
else {
00767 irp->
UserEvent = event;
00768 irp->
UserIosb = &localIoStatus;
00769 irp->
Flags =
IRP_SYNCHRONOUS_API;
00770 }
00771 irp->
Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)
NULL;
00772
00773
00774
00775
00776
00777
00778 irpSp =
IoGetNextIrpStackLocation( irp );
00779 irpSp->
MajorFunction =
IRP_MJ_SET_VOLUME_INFORMATION;
00780 irpSp->
FileObject = fileObject;
00781
00782
00783
00784
00785
00786
00787
00788
00789 irp->
AssociatedIrp.SystemBuffer = (PVOID)
NULL;
00790 irp->
MdlAddress = (
PMDL)
NULL;
00791
00792
try {
00793
00794 irp->
AssociatedIrp.SystemBuffer =
ExAllocatePoolWithQuota(
NonPagedPool,
00795 Length );
00796 RtlCopyMemory( irp->
AssociatedIrp.SystemBuffer, FsInformation, Length );
00797
00798 } except(
EXCEPTION_EXECUTE_HANDLER) {
00799
00800
00801
00802
00803
00804
00805
00806
00807
IopExceptionCleanup( fileObject,
00808 irp,
00809 (
PKEVENT)
NULL,
00810 event );
00811
00812
if (targetDeviceObject !=
NULL) {
00813
ObDereferenceObject( targetDeviceObject );
00814 }
00815
00816
return GetExceptionCode();
00817
00818 }
00819
00820
00821
00822
00823
00824
00825
if (requestorMode !=
KernelMode &&
00826 FsInformationClass == FileFsLabelInformation) {
00827
00828
00829
00830
00831
00832
00833
00834
00835 labelInformation = (PFILE_FS_LABEL_INFORMATION) irp->
AssociatedIrp.SystemBuffer;
00836
00837
if ((LONG) labelInformation->VolumeLabelLength < 0 ||
00838 labelInformation->VolumeLabelLength +
00839 FIELD_OFFSET( FILE_FS_LABEL_INFORMATION, VolumeLabel ) > Length) {
00840
00841
IopExceptionCleanup( fileObject,
00842 irp,
00843 (
PKEVENT)
NULL,
00844 event );
00845
00846
if (targetDeviceObject !=
NULL) {
00847
ObDereferenceObject( targetDeviceObject );
00848 }
00849
00850
return STATUS_INVALID_PARAMETER;
00851 }
00852 }
00853
00854 irp->
Flags |= (ULONG) (
IRP_BUFFERED_IO |
IRP_DEALLOCATE_BUFFER);
00855
00856
00857
00858
00859
00860
00861 irpSp->
Parameters.SetVolume.Length = Length;
00862 irpSp->
Parameters.SetVolume.FsInformationClass = FsInformationClass;
00863
00864
00865
00866
00867
00868
00869
00870 status =
IopSynchronousServiceTail( deviceObject,
00871 irp,
00872 fileObject,
00873
FALSE,
00874 requestorMode,
00875 synchronousIo,
00876
OtherTransfer );
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
if (!synchronousIo) {
00887
00888 status =
IopSynchronousApiServiceTail( status,
00889 event,
00890 irp,
00891 requestorMode,
00892 &localIoStatus,
00893 IoStatusBlock );
00894 }
00895
00896
00897
00898
00899
00900
if (targetDeviceObject !=
NULL) {
00901
if (
NT_SUCCESS( status )) {
00902
TARGET_DEVICE_CUSTOM_NOTIFICATION ChangeEvent;
00903
00904 ChangeEvent.
Version = 1;
00905 ChangeEvent.
FileObject =
NULL;
00906 ChangeEvent.
NameBufferOffset = -1;
00907 ChangeEvent.
Size = (
USHORT)FIELD_OFFSET(
TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer );
00908
00909 RtlCopyMemory( &ChangeEvent.
Event, &GUID_IO_VOLUME_CHANGE,
sizeof( GUID_IO_VOLUME_CHANGE ));
00910
00911
IoReportTargetDeviceChange( targetDeviceObject, &ChangeEvent );
00912 }
00913
00914
ObDereferenceObject( targetDeviceObject );
00915 }
00916
00917
return status;
00918 }