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
#include "iop.h"
00027
00028
00029
00030
00031
00032 #define RoundNameSize( Length ) ( \
00033
(Length < 64 - 8) ? 64 - 8 : \
00034
(Length < 128 - 8) ? 128 - 8 :\
00035
(Length < 256 - 8) ? 256 - 8 : Length )
00036
00037 #define IO_MAX_REMOUNT_REPARSE_ATTEMPTS 32
00038
00039
#ifdef ALLOC_PRAGMA
00040
#pragma alloc_text(PAGE, IopParseFile)
00041
#pragma alloc_text(PAGE, IopParseDevice)
00042
#pragma alloc_text(PAGE, IopQueryName)
00043
#pragma alloc_text(PAGE, IopCheckBackupRestorePrivilege)
00044
#endif
00045
00046
NTSTATUS
00047 IopCheckDeviceAndDriver(
00048
POPEN_PACKET op,
00049
PDEVICE_OBJECT parseDeviceObject
00050 )
00051 {
00052
NTSTATUS status;
00053 KIRQL irql;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 ExAcquireFastLock( &
IopDatabaseLock, &irql );
00071
00072
if (parseDeviceObject->
DeviceObjectExtension->
ExtensionFlags &
00073 (
DOE_UNLOAD_PENDING |
DOE_DELETE_PENDING |
DOE_REMOVE_PENDING |
DOE_REMOVE_PROCESSED |
DOE_START_PENDING) ||
00074 parseDeviceObject->
Flags &
DO_DEVICE_INITIALIZING) {
00075
00076 status = STATUS_NO_SUCH_DEVICE;
00077
00078 }
else if (parseDeviceObject->
Flags &
DO_EXCLUSIVE &&
00079 parseDeviceObject->
ReferenceCount != 0 &&
00080 op->
RelatedFileObject ==
NULL &&
00081 !(op->
Options &
IO_ATTACH_DEVICE)) {
00082
00083 status = STATUS_ACCESS_DENIED;
00084
00085 }
else {
00086
00087 parseDeviceObject->
ReferenceCount++;
00088 status = STATUS_SUCCESS;
00089
00090 }
00091
00092 ExReleaseFastLock( &
IopDatabaseLock, irql );
00093
00094
return status;
00095 }
00096
00097
PVPB
00098 IopCheckVpbMounted(
00099 IN
POPEN_PACKET op,
00100 IN
PDEVICE_OBJECT parseDeviceObject,
00101 IN OUT PUNICODE_STRING RemainingName,
00102 OUT PNTSTATUS status
00103 )
00104 {
00105
PVPB vpb;
00106 KIRQL irql;
00107 BOOLEAN alertable;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 ExAcquireFastLock( &
IopVpbSpinLock, &irql );
00118
00119 alertable = (op->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) ?
TRUE :
FALSE;
00120
while (!(parseDeviceObject->Vpb->Flags &
VPB_MOUNTED)) {
00121
00122 ExReleaseFastLock( &
IopVpbSpinLock, irql );
00123
00124
00125
00126
00127
00128
00129 *status =
IopMountVolume( parseDeviceObject,
00130 (BOOLEAN) (!RemainingName->Length && !op->RelatedFileObject),
00131
FALSE,
00132 alertable );
00133
00134
00135
00136
00137
00138
if (!
NT_SUCCESS( *status ) || *status == STATUS_USER_APC || *status == STATUS_ALERTED) {
00139
00140
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
00141
00142
if (!
NT_SUCCESS( *status )) {
00143
return NULL;
00144 }
else {
00145 *status = STATUS_WRONG_VOLUME;
00146
return NULL;
00147 }
00148 }
00149
00150 ExAcquireFastLock( &
IopVpbSpinLock, &irql );
00151 }
00152
00153
00154
00155
00156
00157
00158 vpb = parseDeviceObject->Vpb;
00159
00160
00161
00162
00163
00164
if (vpb->
Flags &
VPB_LOCKED) {
00165
00166 *status = STATUS_ACCESS_DENIED;
00167 vpb =
NULL;
00168
00169 }
else {
00170
00171 vpb->
ReferenceCount += 1;
00172 }
00173
00174 ExReleaseFastLock( &
IopVpbSpinLock, irql );
00175
00176
return vpb;
00177 }
00178
00179
VOID
00180 IopDereferenceVpbAndFree(
00181 IN
PVPB Vpb
00182 )
00183 {
00184 KIRQL irql;
00185
PVPB vpb = (
PVPB)
NULL;
00186
00187 ExAcquireFastLock( &
IopVpbSpinLock, &irql );
00188 Vpb->ReferenceCount--;
00189
if ((Vpb->ReferenceCount == 0) &&
00190 (Vpb->RealDevice->Vpb != Vpb) &&
00191 !(Vpb->Flags &
VPB_PERSISTENT)) {
00192 vpb = Vpb;
00193 }
00194 ExReleaseFastLock( &
IopVpbSpinLock, irql );
00195
if (vpb) {
00196
ExFreePool( vpb );
00197 }
00198 }
00199
00200
00201
NTSTATUS
00202 IopParseDevice(
00203 IN PVOID ParseObject,
00204 IN PVOID ObjectType,
00205 IN
PACCESS_STATE AccessState,
00206 IN KPROCESSOR_MODE AccessMode,
00207 IN ULONG Attributes,
00208 IN OUT PUNICODE_STRING CompleteName,
00209 IN OUT PUNICODE_STRING RemainingName,
00210 IN OUT PVOID Context OPTIONAL,
00211 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
00212 OUT PVOID *Object
00213 )
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 {
00290
00291
#define COPY_ATTRIBUTES( n, b, s ) { \
00292
(n)->CreationTime.QuadPart = (b)->CreationTime.QuadPart; \
00293
(n)->LastAccessTime.QuadPart = (b)->LastAccessTime.QuadPart; \
00294
(n)->LastWriteTime.QuadPart = (b)->LastWriteTime.QuadPart; \
00295
(n)->ChangeTime.QuadPart = (b)->ChangeTime.QuadPart; \
00296
(n)->AllocationSize.QuadPart = (s)->AllocationSize.QuadPart; \
00297
(n)->EndOfFile.QuadPart = (s)->EndOfFile.QuadPart; \
00298
(n)->FileAttributes = (b)->FileAttributes; }
00299
00300
PIRP irp;
00301
PIO_STACK_LOCATION irpSp;
00302
POPEN_PACKET op;
00303
PFILE_OBJECT fileObject;
00304
NTSTATUS status;
00305 IO_STATUS_BLOCK ioStatus;
00306
IO_SECURITY_CONTEXT securityContext;
00307
PDEVICE_OBJECT deviceObject;
00308
PDEVICE_OBJECT parseDeviceObject;
00309 BOOLEAN directDeviceOpen;
00310
PVPB vpb;
00311 ACCESS_MASK desiredAccess;
00312
PDUMMY_FILE_OBJECT localFileObject;
00313 BOOLEAN realFileObjectRequired;
00314
KPROCESSOR_MODE modeForPrivilegeCheck;
00315 ULONG retryCount = 0;
00316 BOOLEAN relativeVolumeOpen =
FALSE;
00317
00318
PAGED_CODE();
00319
00320 reparse_loop:
00321
00322
00323
00324
00325
00326 *Object = (PVOID)
NULL;
00327
00328
00329
00330
00331
00332 op = Context;
00333
00334
00335
00336
00337
00338
00339
00340
00341
if (op ==
NULL ||
00342 op->
Type !=
IO_TYPE_OPEN_PACKET ||
00343 op->
Size !=
sizeof(
OPEN_PACKET )) {
00344
00345
return STATUS_OBJECT_TYPE_MISMATCH;
00346 }
00347
00348
00349
00350
00351
00352
00353 parseDeviceObject = (
PDEVICE_OBJECT) ParseObject;
00354
00355
00356
00357
00358
00359
00360
00361
00362
if (op->
RelatedFileObject) {
00363 parseDeviceObject = op->
RelatedFileObject->
DeviceObject;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 status =
IopCheckDeviceAndDriver( op, parseDeviceObject );
00382
00383
if (!
NT_SUCCESS(status)) {
00384
return op->
FinalStatus = status;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
RtlMapGenericMask( &AccessState->RemainingDesiredAccess,
00397 &
IoFileObjectType->
TypeInfo.
GenericMapping );
00398
00399
RtlMapGenericMask( &AccessState->OriginalDesiredAccess,
00400 &
IoFileObjectType->
TypeInfo.
GenericMapping );
00401
00402
SeSetAccessStateGenericMapping( AccessState, &
IoFileObjectType->
TypeInfo.
GenericMapping );
00403
00404 desiredAccess = AccessState->RemainingDesiredAccess;
00405
00406
00407
00408
00409
00410
if (AccessMode !=
KernelMode || op->
Options &
IO_FORCE_ACCESS_CHECK) {
00411 modeForPrivilegeCheck =
UserMode;
00412 }
else {
00413 modeForPrivilegeCheck =
KernelMode;
00414 }
00415
00416
IopCheckBackupRestorePrivilege( AccessState,
00417 &op->
CreateOptions,
00418 modeForPrivilegeCheck,
00419 op->
Disposition
00420 );
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
if ((op->
Override && !RemainingName->Length) ||
00431 AccessState->Flags &
SE_BACKUP_PRIVILEGES_CHECKED) {
00432 desiredAccess |= AccessState->PreviouslyGrantedAccess;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
if (op->
RelatedFileObject) {
00442
if ((op->
RelatedFileObject->
Flags &
FO_VOLUME_OPEN) && RemainingName->Length == 0) {
00443 relativeVolumeOpen =
TRUE;
00444 }
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
if ((AccessMode !=
KernelMode || op->
Options &
IO_FORCE_ACCESS_CHECK) &&
00462 (!op->
RelatedFileObject || relativeVolumeOpen) &&
00463 !op->
Override) {
00464
00465 BOOLEAN subjectContextLocked =
FALSE;
00466 BOOLEAN accessGranted;
00467 ACCESS_MASK grantedAccess;
00468
00469
00470
00471
00472
00473
00474
00475
if (!RemainingName->Length) {
00476
00477 UNICODE_STRING nameString;
00478 PPRIVILEGE_SET privileges =
NULL;
00479
00480
00481
00482
00483
00484
00485
KeEnterCriticalRegion( );
00486
ExAcquireResourceShared( &
IopSecurityResource,
TRUE );
00487
00488
SeLockSubjectContext( &AccessState->SubjectSecurityContext );
00489 subjectContextLocked =
TRUE;
00490
00491 accessGranted =
SeAccessCheck( parseDeviceObject->
SecurityDescriptor,
00492 &AccessState->SubjectSecurityContext,
00493 subjectContextLocked,
00494 desiredAccess,
00495 0,
00496 &privileges,
00497 &
IoFileObjectType->
TypeInfo.
GenericMapping,
00498
UserMode,
00499 &grantedAccess,
00500 &status );
00501
00502
if (privileges) {
00503 (
VOID)
SeAppendPrivileges( AccessState,
00504 privileges );
00505
SeFreePrivileges( privileges );
00506 }
00507
00508
if (accessGranted) {
00509 AccessState->PreviouslyGrantedAccess |= grantedAccess;
00510 AccessState->RemainingDesiredAccess &= ~( grantedAccess | MAXIMUM_ALLOWED );
00511 op->
Override =
TRUE;
00512 }
00513
00514 nameString.Length = 8;
00515 nameString.MaximumLength = 8;
00516 nameString.Buffer =
L"File";
00517
00518
SeOpenObjectAuditAlarm( &nameString,
00519 parseDeviceObject,
00520 CompleteName,
00521 parseDeviceObject->
SecurityDescriptor,
00522 AccessState,
00523
FALSE,
00524 accessGranted,
00525
UserMode,
00526 &AccessState->GenerateOnClose );
00527
00528
ExReleaseResource( &
IopSecurityResource );
00529
KeLeaveCriticalRegion();
00530
00531 }
else {
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
if (!(AccessState->Flags &
TOKEN_HAS_TRAVERSE_PRIVILEGE) ||
00551 parseDeviceObject->
DeviceType == FILE_DEVICE_DISK ||
00552 parseDeviceObject->
DeviceType == FILE_DEVICE_CD_ROM ) {
00553
00554
KeEnterCriticalRegion( );
00555
ExAcquireResourceShared( &
IopSecurityResource,
TRUE );
00556
00557
00558
00559
00560
00561
00562
if ((AccessState->Flags &
TOKEN_IS_RESTRICTED) == 0) {
00563 accessGranted =
SeFastTraverseCheck( parseDeviceObject->
SecurityDescriptor,
00564 FILE_TRAVERSE,
00565
UserMode );
00566 }
else {
00567 accessGranted =
FALSE;
00568 }
00569
00570
if (!accessGranted) {
00571
00572 PPRIVILEGE_SET privileges =
NULL;
00573
00574
00575
00576
00577
00578
00579
00580
00581
SeLockSubjectContext( &AccessState->SubjectSecurityContext );
00582
00583 subjectContextLocked =
TRUE;
00584
00585 accessGranted =
SeAccessCheck( parseDeviceObject->
SecurityDescriptor,
00586 &AccessState->SubjectSecurityContext,
00587 subjectContextLocked,
00588 FILE_TRAVERSE,
00589 0,
00590 &privileges,
00591 &
IoFileObjectType->
TypeInfo.
GenericMapping,
00592
UserMode,
00593 &grantedAccess,
00594 &status );
00595
00596
if (privileges) {
00597
00598 (
VOID)
SeAppendPrivileges( AccessState,
00599 privileges );
00600
SeFreePrivileges( privileges );
00601 }
00602
00603 }
00604
00605
00606
00607
00608
00609
SeTraverseAuditAlarm( &AccessState->OperationID,
00610 parseDeviceObject,
00611 parseDeviceObject->
SecurityDescriptor,
00612 &AccessState->SubjectSecurityContext,
00613 subjectContextLocked,
00614 FILE_TRAVERSE,
00615 (PPRIVILEGE_SET)
NULL,
00616 accessGranted,
00617
UserMode );
00618
ExReleaseResource( &
IopSecurityResource );
00619
KeLeaveCriticalRegion();
00620
00621 }
else {
00622
00623 accessGranted =
TRUE;
00624 }
00625 }
00626
00627
00628
00629
00630
00631
00632
if (subjectContextLocked) {
00633
SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
if (!accessGranted) {
00643
00644
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
00645
return STATUS_ACCESS_DENIED;
00646 }
00647
00648 }
00649
00650 realFileObjectRequired = !(op->
QueryOnly || op->
DeleteOnly);
00651
00652
if (RemainingName->Length == 0 &&
00653 op->
RelatedFileObject ==
NULL &&
00654 ((desiredAccess & ~(SYNCHRONIZE |
00655 FILE_READ_ATTRIBUTES |
00656 READ_CONTROL |
00657 ACCESS_SYSTEM_SECURITY |
00658 WRITE_OWNER |
00659 WRITE_DAC)) == 0) &&
00660 realFileObjectRequired) {
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 directDeviceOpen =
TRUE;
00679
00680 }
else {
00681
00682
00683
00684
00685
00686
00687 directDeviceOpen =
FALSE;
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 vpb =
NULL;
00726
00727
00728
00729
00730
00731
if (op->
RelatedFileObject && (!(op->
RelatedFileObject->
Flags &
FO_DIRECT_DEVICE_OPEN))) {
00732
00733 deviceObject = (
PDEVICE_OBJECT)ParseObject;
00734
00735
if (op->
RelatedFileObject->
Vpb) {
00736
00737 vpb = op->
RelatedFileObject->
Vpb;
00738
00739
00740
00741
00742
00743
00744
ExInterlockedAddUlong( &vpb->
ReferenceCount, 1, &
IopVpbSpinLock );
00745 }
00746
00747 }
else {
00748
00749 deviceObject = parseDeviceObject;
00750
00751
if (parseDeviceObject->Vpb && !directDeviceOpen) {
00752 vpb =
IopCheckVpbMounted( op,
00753 parseDeviceObject,
00754 RemainingName,
00755 &status );
00756
if ( !vpb ) {
00757
return status;
00758 }
00759
00760
00761
00762
00763
00764 deviceObject = vpb->
DeviceObject;
00765 }
00766
00767
00768
00769
00770
00771
if (deviceObject->
AttachedDevice) {
00772 deviceObject =
IoGetAttachedDevice( deviceObject );
00773 }
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783
if ((deviceObject->
Characteristics & FILE_DEVICE_SECURE_OPEN) &&
00784 (op->
RelatedFileObject || RemainingName->Length) && (!relativeVolumeOpen)) {
00785
00786 BOOLEAN subjectContextLocked =
FALSE;
00787 BOOLEAN accessGranted;
00788 ACCESS_MASK grantedAccess;
00789 UNICODE_STRING nameString;
00790 PPRIVILEGE_SET privileges =
NULL;
00791
00792
00793
00794
00795
00796
00797
00798
KeEnterCriticalRegion( );
00799
ExAcquireResourceShared( &
IopSecurityResource,
TRUE );
00800
00801
SeLockSubjectContext( &AccessState->SubjectSecurityContext );
00802 subjectContextLocked =
TRUE;
00803
00804 accessGranted =
SeAccessCheck( parseDeviceObject->
SecurityDescriptor,
00805 &AccessState->SubjectSecurityContext,
00806 subjectContextLocked,
00807 desiredAccess,
00808 0,
00809 &privileges,
00810 &
IoFileObjectType->
TypeInfo.
GenericMapping,
00811
UserMode,
00812 &grantedAccess,
00813 &status );
00814
00815
if (privileges) {
00816 (
VOID)
SeAppendPrivileges( AccessState,
00817 privileges );
00818
SeFreePrivileges( privileges );
00819 }
00820
00821
if (accessGranted) {
00822 AccessState->PreviouslyGrantedAccess |= grantedAccess;
00823 AccessState->RemainingDesiredAccess &= ~( grantedAccess | MAXIMUM_ALLOWED );
00824 }
00825
00826 nameString.Length = 8;
00827 nameString.MaximumLength = 8;
00828 nameString.Buffer =
L"File";
00829
00830
SeOpenObjectAuditAlarm( &nameString,
00831 deviceObject,
00832 CompleteName,
00833 parseDeviceObject->
SecurityDescriptor,
00834 AccessState,
00835
FALSE,
00836 accessGranted,
00837
UserMode,
00838 &AccessState->GenerateOnClose );
00839
00840
SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
00841
ExReleaseResource( &
IopSecurityResource );
00842
KeLeaveCriticalRegion();
00843
00844
if (!accessGranted) {
00845
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
00846
00847
if (vpb) {
00848
IopDereferenceVpbAndFree(vpb);
00849 }
00850
return STATUS_ACCESS_DENIED;
00851 }
00852 }
00853
00854
00855
00856
00857
00858
00859
00860 irp =
IopAllocateIrp( deviceObject->
StackSize,
TRUE );
00861
if (!irp) {
00862
00863
00864
00865
00866
00867
00868
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
00869
00870
if (vpb) {
00871
IopDereferenceVpbAndFree(vpb);
00872 }
00873
return STATUS_INSUFFICIENT_RESOURCES;
00874 }
00875 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
00876 irp->
RequestorMode = AccessMode;
00877 irp->
Flags =
IRP_CREATE_OPERATION |
IRP_SYNCHRONOUS_API |
IRP_DEFER_IO_COMPLETION;
00878
00879 securityContext.
SecurityQos =
SecurityQos;
00880 securityContext.
AccessState = AccessState;
00881 securityContext.
DesiredAccess = desiredAccess;
00882 securityContext.
FullCreateOptions = op->
CreateOptions;
00883
00884
00885
00886
00887
00888
00889 irpSp =
IoGetNextIrpStackLocation( irp );
00890 irpSp->
Control = 0;
00891
00892
if (op->
CreateFileType ==
CreateFileTypeNone) {
00893
00894
00895
00896
00897
00898 irpSp->
MajorFunction =
IRP_MJ_CREATE;
00899 irpSp->
Parameters.Create.EaLength = op->
EaLength;
00900 irpSp->
Flags = (UCHAR) op->
Options;
00901
if (!(Attributes & OBJ_CASE_INSENSITIVE)) {
00902 irpSp->
Flags |=
SL_CASE_SENSITIVE;
00903 }
00904
00905 }
else if (op->
CreateFileType ==
CreateFileTypeNamedPipe) {
00906
00907
00908
00909
00910
00911 irpSp->
MajorFunction =
IRP_MJ_CREATE_NAMED_PIPE;
00912 irpSp->
Parameters.CreatePipe.Parameters = op->
ExtraCreateParameters;
00913
00914 }
else {
00915
00916
00917
00918
00919
00920 irpSp->
MajorFunction =
IRP_MJ_CREATE_MAILSLOT;
00921 irpSp->
Parameters.CreateMailslot.Parameters = op->
ExtraCreateParameters;
00922 }
00923
00924
00925
00926
00927
00928 irp->
Overlay.AllocationSize = op->
AllocationSize;
00929 irp->
AssociatedIrp.SystemBuffer = op->
EaBuffer;
00930 irpSp->
Parameters.Create.Options = (op->
Disposition << 24) | (op->
CreateOptions & 0x00ffffff);
00931 irpSp->
Parameters.Create.FileAttributes = op->
FileAttributes;
00932 irpSp->
Parameters.Create.ShareAccess = op->
ShareAccess;
00933 irpSp->
Parameters.Create.SecurityContext = &securityContext;
00934
00935
00936
00937
00938
00939
00940 irp->
UserIosb = &ioStatus;
00941 irp->
MdlAddress = (
PMDL)
NULL;
00942 irp->
PendingReturned =
FALSE;
00943 irp->
Cancel =
FALSE;
00944 irp->
UserEvent = (
PKEVENT)
NULL;
00945 irp->
CancelRoutine = (
PDRIVER_CANCEL)
NULL;
00946 irp->
Tail.Overlay.AuxiliaryBuffer = (PVOID)
NULL;
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
if (realFileObjectRequired) {
00957
00958 OBJECT_ATTRIBUTES objectAttributes;
00959
00960
00961
00962
00963
00964 InitializeObjectAttributes( &objectAttributes,
00965 (PUNICODE_STRING)
NULL,
00966 Attributes,
00967 (HANDLE)
NULL,
00968 (PSECURITY_DESCRIPTOR)
NULL
00969 );
00970
00971 status =
ObCreateObject(
KernelMode,
00972
IoFileObjectType,
00973 &objectAttributes,
00974 AccessMode,
00975 (PVOID)
NULL,
00976 (ULONG)
sizeof(
FILE_OBJECT ),
00977 0,
00978 0,
00979 (PVOID *) &fileObject );
00980
00981
if (!
NT_SUCCESS( status )) {
00982
IoFreeIrp( irp );
00983
00984
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
00985
00986
if (vpb) {
00987
IopDereferenceVpbAndFree(vpb);
00988 }
00989
return op->
FinalStatus = status;
00990 }
00991
00992 RtlZeroMemory( fileObject,
sizeof(
FILE_OBJECT ) );
00993 fileObject->Type =
IO_TYPE_FILE;
00994 fileObject->Size =
sizeof(
FILE_OBJECT );
00995 fileObject->RelatedFileObject = op->
RelatedFileObject;
00996
if (op->
CreateOptions & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) {
00997 fileObject->
Flags =
FO_SYNCHRONOUS_IO;
00998
if (op->
CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) {
00999 fileObject->Flags |=
FO_ALERTABLE_IO;
01000 }
01001 }
01002
01003
01004
01005
01006
01007
01008
if (fileObject->Flags &
FO_SYNCHRONOUS_IO) {
01009
KeInitializeEvent( &fileObject->Lock, SynchronizationEvent,
FALSE );
01010 fileObject->Waiters = 0;
01011 fileObject->CurrentByteOffset.QuadPart = 0;
01012 }
01013
if (op->
CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) {
01014 fileObject->Flags |=
FO_NO_INTERMEDIATE_BUFFERING;
01015 }
01016
if (op->
CreateOptions & FILE_WRITE_THROUGH) {
01017 fileObject->Flags |=
FO_WRITE_THROUGH;
01018 }
01019
if (op->
CreateOptions & FILE_SEQUENTIAL_ONLY) {
01020 fileObject->Flags |=
FO_SEQUENTIAL_ONLY;
01021 }
01022
if (op->
CreateOptions & FILE_RANDOM_ACCESS) {
01023 fileObject->Flags |=
FO_RANDOM_ACCESS;
01024 }
01025
01026 }
else {
01027
01028
01029
01030
01031
01032
01033
01034
01035 localFileObject = op->
LocalFileObject;
01036 RtlZeroMemory( localFileObject,
sizeof(
DUMMY_FILE_OBJECT ) );
01037 fileObject = (
PFILE_OBJECT) &localFileObject->
ObjectHeader.
Body;
01038 localFileObject->
ObjectHeader.
Type =
IoFileObjectType;
01039 localFileObject->
ObjectHeader.
PointerCount = 1;
01040 }
01041
01042
if (directDeviceOpen) {
01043 fileObject->
Flags |=
FO_DIRECT_DEVICE_OPEN;
01044 }
01045
if (!(Attributes & OBJ_CASE_INSENSITIVE)) {
01046 fileObject->
Flags |=
FO_OPENED_CASE_SENSITIVE;
01047 }
01048
01049 fileObject->
Type =
IO_TYPE_FILE;
01050 fileObject->
Size =
sizeof(
FILE_OBJECT );
01051 fileObject->
RelatedFileObject = op->
RelatedFileObject;
01052 fileObject->
DeviceObject = parseDeviceObject;
01053
01054 irp->
Tail.Overlay.OriginalFileObject = fileObject;
01055 irpSp->
FileObject = fileObject;
01056
01057
01058
01059
01060
01061
01062
if (RemainingName->Length) {
01063 fileObject->
FileName.MaximumLength =
RoundNameSize( RemainingName->Length );
01064 fileObject->
FileName.Buffer =
ExAllocatePoolWithTag(
PagedPool,
01065 fileObject->
FileName.MaximumLength,
01066 'mNoI' );
01067
if (!fileObject->
FileName.Buffer) {
01068
IoFreeIrp( irp );
01069
01070
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
01071
01072
if (vpb) {
01073
IopDereferenceVpbAndFree(vpb);
01074 }
01075 fileObject->
DeviceObject = (
PDEVICE_OBJECT)
NULL;
01076
if (realFileObjectRequired) {
01077
ObDereferenceObject( fileObject );
01078 }
01079
return STATUS_INSUFFICIENT_RESOURCES;
01080 }
01081 }
01082
01083
01084
01085
01086
01087
01088
01089
RtlCopyUnicodeString( &fileObject->
FileName, RemainingName );
01090
01091
01092
01093
01094
01095
01096
01097
if (op->
QueryOnly) {
01098
PFAST_IO_DISPATCH fastIoDispatch = deviceObject->
DriverObject->
FastIoDispatch;
01099 BOOLEAN result;
01100
01101
if (fastIoDispatch &&
01102 fastIoDispatch->
SizeOfFastIoDispatch > FIELD_OFFSET(
FAST_IO_DISPATCH, FastIoQueryOpen ) &&
01103 fastIoDispatch->
FastIoQueryOpen) {
01104
01105
IoSetNextIrpStackLocation( irp );
01106 irpSp->
DeviceObject = deviceObject;
01107 result = (fastIoDispatch->
FastIoQueryOpen)( irp,
01108 op->
NetworkInformation,
01109 deviceObject );
01110
if (result) {
01111 op->
FinalStatus = irp->
IoStatus.Status;
01112 op->
Information = irp->
IoStatus.Information;
01113
01114
01115
01116
01117
01118
01119
if ((op->
FinalStatus == STATUS_REPARSE) &&
01120 irp->
Tail.Overlay.AuxiliaryBuffer) {
01121
ASSERT( op->
Information > IO_REPARSE_TAG_RESERVED_ONE );
01122
ExFreePool( irp->
Tail.Overlay.AuxiliaryBuffer );
01123 irp->
Tail.Overlay.AuxiliaryBuffer =
NULL;
01124 op->
RelatedFileObject = (
PFILE_OBJECT)
NULL;
01125 }
01126
01127
if (fileObject->
FileName.Length) {
01128
ExFreePool( fileObject->
FileName.Buffer );
01129 }
01130
01131
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
01132
01133
if (vpb) {
01134
IopDereferenceVpbAndFree(vpb);
01135 }
01136
01137
#if DBG
01138
irp->
CurrentLocation = irp->
StackCount + 2;
01139
#endif // DBG
01140
01141
IoFreeIrp( irp );
01142
01143
01144
01145
01146
01147
01148
01149 op->
ParseCheck =
OPEN_PACKET_PATTERN;
01150 status = STATUS_SUCCESS;
01151
01152
if (!op->
FullAttributes) {
01153
try {
01154 op->
BasicInformation->FileAttributes = op->
NetworkInformation->FileAttributes;
01155 } except(
EXCEPTION_EXECUTE_HANDLER) {
01156 status = GetExceptionCode();
01157 }
01158 }
01159
01160
return status;
01161
01162 }
else {
01163
01164
01165
01166
01167
01168
01169 irp->
Tail.Overlay.CurrentStackLocation++;
01170 irp->
CurrentLocation++;
01171 }
01172 }
01173 }
01174
01175
01176
01177
01178
01179
01180
KeInitializeEvent( &fileObject->
Event, NotificationEvent,
FALSE );
01181 op->
FileObject = fileObject;
01182
01183
01184
01185
01186
01187
IopQueueThreadIrp( irp );
01188
01189
01190
01191
01192
01193 status =
IoCallDriver( deviceObject, irp );
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
if (status == STATUS_PENDING) {
01216
01217 (
VOID)
KeWaitForSingleObject( &fileObject->
Event,
01218
Executive,
01219
KernelMode,
01220
FALSE,
01221 (PLARGE_INTEGER)
NULL );
01222 status = ioStatus.Status;
01223
01224 }
else {
01225
01226
01227
01228
01229
01230
01231
01232
PKNORMAL_ROUTINE normalRoutine;
01233 PVOID normalContext;
01234 KIRQL irql;
01235
01236
ASSERT( !irp->
PendingReturned );
01237
ASSERT( !irp->
MdlAddress );
01238
01239
01240
01241
01242
01243
if (irp->
IoStatus.Status == STATUS_REPARSE &&
01244 irp->
IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT ) {
01245
01246 PREPARSE_DATA_BUFFER reparseBuffer =
NULL;
01247
01248
ASSERT ( irp->
Tail.Overlay.AuxiliaryBuffer !=
NULL );
01249
01250 reparseBuffer = (PREPARSE_DATA_BUFFER) irp->
Tail.Overlay.AuxiliaryBuffer;
01251
01252
ASSERT( reparseBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT );
01253
ASSERT( reparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
01254
ASSERT( reparseBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
01255
01256
IopDoNameTransmogrify( irp,
01257 fileObject,
01258 reparseBuffer );
01259 }
01260
01261
01262
01263
01264
01265
KeRaiseIrql(
APC_LEVEL, &irql );
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279 ioStatus = irp->
IoStatus;
01280 status = ioStatus.Status;
01281
01282 fileObject->
Event.
Header.
SignalState = 1;
01283
01284
IopDequeueThreadIrp( irp );
01285
01286
01287
01288
01289
01290
01291
if ((irp->
Flags &
IRP_BUFFERED_IO) && (irp->
Flags &
IRP_DEALLOCATE_BUFFER)) {
01292
ExFreePool(irp->
AssociatedIrp.SystemBuffer);
01293 }
01294
01295
IoFreeIrp( irp );
01296
01297
KeLowerIrql( irql );
01298 }
01299
01300
01301
01302
01303
01304
01305 op->
Information = ioStatus.Information;
01306
01307
if (!
NT_SUCCESS( status )) {
01308
int openCancelled;
01309
01310
01311
01312
01313
01314
01315
if (fileObject->
FileName.Length) {
01316
ExFreePool( fileObject->
FileName.Buffer );
01317 fileObject->
FileName.Length = 0;
01318 }
01319
01320 fileObject->
DeviceObject = (
PDEVICE_OBJECT)
NULL;
01321
01322 openCancelled = (fileObject->
Flags &
FO_FILE_OPEN_CANCELLED);
01323
01324
if (realFileObjectRequired) {
01325
ObDereferenceObject( fileObject );
01326 }
01327 op->
FileObject = (
PFILE_OBJECT)
NULL;
01328
01329
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
01330
01331
if ((!openCancelled) && (vpb )) {
01332
IopDereferenceVpbAndFree(vpb);
01333 }
01334
01335
return op->
FinalStatus = status;
01336
01337 }
else if (status == STATUS_REPARSE) {
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
ASSERT(
IO_REPARSE == IO_REPARSE_TAG_RESERVED_ZERO );
01354
01355
if ((ioStatus.Information ==
IO_REPARSE) ||
01356 (ioStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) {
01357
01358
01359
01360
01361
01362
if (CompleteName->MaximumLength < fileObject->
FileName.Length) {
01363
01364 PVOID buffer;
01365
01366 buffer =
ExAllocatePoolWithTag(
PagedPool,
01367 fileObject->
FileName.Length,
01368 'cFoI' );
01369
if (!buffer) {
01370
return op->
FinalStatus = STATUS_INSUFFICIENT_RESOURCES;
01371 }
else {
01372
if (CompleteName->Buffer) {
01373
ExFreePool( CompleteName->Buffer );
01374 }
01375 CompleteName->Buffer = buffer;
01376 CompleteName->MaximumLength = fileObject->
FileName.Length;
01377 }
01378 }
01379
01380
RtlCopyUnicodeString( CompleteName, &fileObject->
FileName );
01381
01382
01383
01384
01385
01386
01387
01388
if (ioStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) {
01389
01390 op->
RelatedFileObject = (
PFILE_OBJECT)
NULL;
01391 }
01392 }
01393
01394
01395
01396
01397
01398
01399
if (fileObject->
FileName.Length) {
01400
ExFreePool( fileObject->
FileName.Buffer );
01401 fileObject->
FileName.Length = 0;
01402 }
01403
01404 fileObject->
DeviceObject = (
PDEVICE_OBJECT)
NULL;
01405
01406
if (realFileObjectRequired) {
01407
ObDereferenceObject( fileObject );
01408 }
01409 op->
FileObject = (
PFILE_OBJECT)
NULL;
01410
01411
IopDecrementDeviceObjectRef( parseDeviceObject,
FALSE );
01412
01413
if (vpb) {
01414
IopDereferenceVpbAndFree(vpb);
01415 }
01416
01417
ASSERT(
IO_REMOUNT == IO_REPARSE_TAG_RESERVED_ONE );
01418
01419
if (ioStatus.Information == IO_REPARSE_TAG_RESERVED_ONE) {
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
if (++retryCount >
IO_MAX_REMOUNT_REPARSE_ATTEMPTS) {
01431
01432
return STATUS_UNSUCCESSFUL;
01433 }
01434
goto reparse_loop;
01435
01436 }
else {
01437
01438
01439
01440
01441
01442
01443 op->
RelatedFileObject = (
PFILE_OBJECT)
NULL;
01444
return STATUS_REPARSE;
01445 }
01446
01447 }
else {
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
PDEVICE_OBJECT deviceObjectThatOpenedFile;
01463
01464 deviceObjectThatOpenedFile =
IoGetRelatedDeviceObject(fileObject);
01465
if (deviceObject != deviceObjectThatOpenedFile) {
01466
01467
01468
01469
01470
if (vpb) {
01471
IopDereferenceVpbAndFree(vpb);
01472 }
01473 vpb = fileObject->
Vpb;
01474
if (vpb) {
01475
ExInterlockedAddUlong(
01476 &vpb->
ReferenceCount, 1, &
IopVpbSpinLock );
01477 }
01478 }
01479
01480
if (realFileObjectRequired) {
01481
01482 *Object = fileObject;
01483 op->
ParseCheck =
OPEN_PACKET_PATTERN;
01484
01485
01486
01487
01488
01489
01490
01491
ObReferenceObject( fileObject );
01492
01493
01494
01495
01496
01497
01498
if ((!fileObject->RelatedFileObject || fileObject->RelatedFileObject->Flags &
FO_VOLUME_OPEN) &&
01499 (!fileObject->FileName.Length)) {
01500
switch (deviceObjectThatOpenedFile->
DeviceType) {
01501
case FILE_DEVICE_DISK_FILE_SYSTEM:
01502
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
01503
case FILE_DEVICE_TAPE_FILE_SYSTEM:
01504
case FILE_DEVICE_FILE_SYSTEM:
01505
01506 fileObject->Flags |=
FO_VOLUME_OPEN;
01507
break;
01508
01509
default:
01510
break;
01511 }
01512 }
01513
01514
return op->
FinalStatus = ioStatus.Status;
01515
01516 }
else {
01517
01518
01519
01520
01521
01522
01523
if (op->
QueryOnly) {
01524
PFAST_IO_DISPATCH fastIoDispatch;
01525 BOOLEAN queryResult =
FALSE;
01526
01527 fastIoDispatch = deviceObjectThatOpenedFile->
DriverObject->
FastIoDispatch;
01528
01529
if (!op->
FullAttributes) {
01530 PFILE_BASIC_INFORMATION basicInfo =
NULL;
01531
01532
01533
01534
01535
01536
01537
try {
01538
01539
if (fastIoDispatch && fastIoDispatch->
FastIoQueryBasicInfo) {
01540 queryResult = fastIoDispatch->
FastIoQueryBasicInfo(
01541 fileObject,
01542
TRUE,
01543 op->
BasicInformation,
01544 &ioStatus,
01545 deviceObjectThatOpenedFile
01546 );
01547 }
01548
if (!queryResult) {
01549 ULONG returnedLength;
01550
01551 basicInfo =
ExAllocatePool(
NonPagedPool,
01552
sizeof( FILE_BASIC_INFORMATION ) );
01553
if (basicInfo) {
01554 status =
IoQueryFileInformation(
01555 fileObject,
01556 FileBasicInformation,
01557
sizeof( FILE_BASIC_INFORMATION ),
01558 basicInfo,
01559 &returnedLength
01560 );
01561
if (
NT_SUCCESS( status )) {
01562 RtlCopyMemory( op->
BasicInformation,
01563 basicInfo,
01564 returnedLength );
01565 }
01566
ExFreePool( basicInfo );
01567 }
else {
01568 status = STATUS_INSUFFICIENT_RESOURCES;
01569 }
01570 }
else {
01571 status = ioStatus.Status;
01572 }
01573 } except(
EXCEPTION_EXECUTE_HANDLER) {
01574
if (basicInfo) {
01575
ExFreePool( basicInfo );
01576 }
01577 status = GetExceptionCode();
01578 }
01579
01580 }
else {
01581
01582
01583
01584
01585
01586
01587
01588
01589
if (fastIoDispatch &&
01590 fastIoDispatch->
SizeOfFastIoDispatch > FIELD_OFFSET(
FAST_IO_DISPATCH, FastIoQueryNetworkOpenInfo ) &&
01591 fastIoDispatch->
FastIoQueryNetworkOpenInfo) {
01592 queryResult = fastIoDispatch->
FastIoQueryNetworkOpenInfo(
01593 fileObject,
01594
TRUE,
01595 op->
NetworkInformation,
01596 &ioStatus,
01597 deviceObjectThatOpenedFile
01598 );
01599 }
01600
if (!queryResult) {
01601 ULONG returnedLength;
01602
01603
01604
01605
01606
01607
01608
01609
01610 status =
IoQueryFileInformation(
01611 fileObject,
01612 FileNetworkOpenInformation,
01613
sizeof( FILE_NETWORK_OPEN_INFORMATION ),
01614 op->
NetworkInformation,
01615 &returnedLength
01616 );
01617
01618
if (!
NT_SUCCESS( status )) {
01619
if (status == STATUS_INVALID_PARAMETER ||
01620 status == STATUS_NOT_IMPLEMENTED) {
01621 FILE_BASIC_INFORMATION basicInfo;
01622 FILE_STANDARD_INFORMATION stdInfo;
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636 status =
IoQueryFileInformation(
01637 fileObject,
01638 FileBasicInformation,
01639
sizeof( FILE_BASIC_INFORMATION ),
01640 &basicInfo,
01641 &returnedLength
01642 );
01643
if (
NT_SUCCESS( status )) {
01644 status =
IoQueryFileInformation(
01645 fileObject,
01646 FileStandardInformation,
01647
sizeof( FILE_STANDARD_INFORMATION ),
01648 &stdInfo,
01649 &returnedLength
01650 );
01651
if (
NT_SUCCESS( status )) {
01652
COPY_ATTRIBUTES( op->
NetworkInformation,
01653 &basicInfo,
01654 &stdInfo );
01655 }
01656 }
01657 }
01658 }
01659 }
01660 }
01661
01662 }
else {
01663
01664
01665
01666
01667
01668
01669
01670 NOTHING;
01671
01672 }
01673
01674 op->
ParseCheck =
OPEN_PACKET_PATTERN;
01675
if (realFileObjectRequired) {
01676
ObDereferenceObject( fileObject );
01677 }
else {
01678
IopDeleteFile( fileObject );
01679 }
01680 op->
FileObject = (
PFILE_OBJECT)
NULL;
01681
01682 op->
FinalStatus = status;
01683
01684
return status;
01685 }
01686 }
01687 }
01688
01689
NTSTATUS
01690 IopParseFile(
01691 IN PVOID ParseObject,
01692 IN PVOID ObjectType,
01693 IN
PACCESS_STATE AccessState,
01694 IN KPROCESSOR_MODE AccessMode,
01695 IN ULONG Attributes,
01696 IN OUT PUNICODE_STRING CompleteName,
01697 IN OUT PUNICODE_STRING RemainingName,
01698 IN OUT PVOID Context OPTIONAL,
01699 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
01700 OUT PVOID *Object
01701 )
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757 {
01758
PDEVICE_OBJECT deviceObject;
01759
POPEN_PACKET op;
01760
01761
PAGED_CODE();
01762
01763
01764
01765
01766
01767 op = (
POPEN_PACKET) Context;
01768
01769
01770
01771
01772
01773
01774
01775
01776
if (op ==
NULL ||
01777 op->
Type !=
IO_TYPE_OPEN_PACKET ||
01778 op->
Size !=
sizeof(
OPEN_PACKET )) {
01779
return STATUS_OBJECT_TYPE_MISMATCH;
01780 }
01781
01782
01783
01784
01785
01786 deviceObject =
IoGetRelatedDeviceObject( (
PFILE_OBJECT) ParseObject );
01787
01788
01789
01790
01791
01792 op->
RelatedFileObject = (
PFILE_OBJECT) ParseObject;
01793
01794
01795
01796
01797
01798
return IopParseDevice( deviceObject,
01799 ObjectType,
01800 AccessState,
01801 AccessMode,
01802 Attributes,
01803 CompleteName,
01804 RemainingName,
01805 Context,
01806
SecurityQos,
01807 Object );
01808 }
01809
01810
NTSTATUS
01811 IopQueryName(
01812 IN PVOID Object,
01813 IN BOOLEAN HasObjectName,
01814 OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
01815 IN ULONG Length,
01816 OUT PULONG ReturnLength
01817 )
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845 {
01846
NTSTATUS status;
01847 ULONG lengthNeeded;
01848
PFILE_OBJECT fileObject;
01849 PUCHAR buffer;
01850 PWSTR p;
01851 POBJECT_NAME_INFORMATION deviceNameInfo;
01852 PFILE_NAME_INFORMATION fileNameInfo;
01853 ULONG length;
01854
01855 UNREFERENCED_PARAMETER( HasObjectName );
01856
01857
PAGED_CODE();
01858
01859
ASSERT( FIELD_OFFSET( FILE_NAME_INFORMATION,
FileName ) <
sizeof( OBJECT_NAME_INFORMATION ) );
01860
01861
01862
01863
01864
01865
01866
if (Length <
sizeof( OBJECT_NAME_INFORMATION )) {
01867
return STATUS_INFO_LENGTH_MISMATCH;
01868 }
01869
01870
01871
01872
01873
01874 buffer =
ExAllocatePoolWithTag(
PagedPool, Length, ' oI' );
01875
if (!buffer) {
01876
return STATUS_INSUFFICIENT_RESOURCES;
01877 }
01878
01879
try {
01880
01881
01882
01883
01884
01885 fileObject = (
PFILE_OBJECT) Object;
01886 deviceNameInfo = (POBJECT_NAME_INFORMATION) buffer;
01887
01888 status =
ObQueryNameString( (PVOID) fileObject->
DeviceObject,
01889 deviceNameInfo,
01890 Length,
01891 &lengthNeeded );
01892
if (!
NT_SUCCESS( status )) {
01893
return status;
01894 }
01895
01896
01897
01898
01899
01900
01901 RtlCopyMemory( ObjectNameInfo,
01902 deviceNameInfo,
01903 lengthNeeded > Length ? Length : lengthNeeded );
01904 p = (PWSTR) (ObjectNameInfo + 1);
01905 ObjectNameInfo->Name.Buffer = p;
01906 p = (PWSTR) ((PCHAR) p + deviceNameInfo->Name.Length);
01907
01908
01909
01910
01911
01912
if (lengthNeeded > Length) {
01913
return STATUS_BUFFER_OVERFLOW;
01914 }
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934 fileNameInfo = (PFILE_NAME_INFORMATION) buffer;
01935 length = Length - lengthNeeded;
01936
01937 length += FIELD_OFFSET( FILE_NAME_INFORMATION,
FileName );
01938
01939
if (KeGetPreviousMode() ==
UserMode ||
01940 !(fileObject->
Flags &
FO_SYNCHRONOUS_IO)) {
01941
01942
01943
01944
01945
01946 status =
IoQueryFileInformation( fileObject,
01947 FileNameInformation,
01948 length,
01949 (PVOID) fileNameInfo,
01950 &lengthNeeded );
01951 }
01952
else {
01953
01954
01955
01956
01957
01958
01959
01960
01961 status =
IopGetFileName( fileObject,
01962 length,
01963 fileNameInfo,
01964 &lengthNeeded );
01965 }
01966
01967
01968
01969
01970
01971
01972
if (
NT_ERROR( status )) {
01973
if (status == STATUS_INVALID_PARAMETER ||
01974 status == STATUS_INVALID_DEVICE_REQUEST ||
01975 status == STATUS_NOT_IMPLEMENTED ||
01976 status == STATUS_INVALID_INFO_CLASS) {
01977 lengthNeeded = FIELD_OFFSET( FILE_NAME_INFORMATION,
FileName );
01978 fileNameInfo->FileNameLength = 0;
01979 fileNameInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
01980 status = STATUS_SUCCESS;
01981 }
01982
else {
01983
return status;
01984 }
01985 }
01986
01987
01988
01989
01990
01991
01992 length = lengthNeeded - FIELD_OFFSET( FILE_NAME_INFORMATION,
FileName );
01993 lengthNeeded = (ULONG)((PUCHAR) p - (PUCHAR) ObjectNameInfo) + fileNameInfo->FileNameLength;
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
if (fileNameInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR) {
02018
return STATUS_OBJECT_PATH_INVALID;
02019 }
02020
02021 RtlMoveMemory( p,
02022 fileNameInfo->FileName,
02023 length );
02024 p = (PWSTR) ((PCH) p + length);
02025 *p =
'\0';
02026 lengthNeeded +=
sizeof( WCHAR );
02027
02028 *ReturnLength = lengthNeeded;
02029
02030 length = (ULONG)((PUCHAR) p - (PUCHAR) ObjectNameInfo);
02031 ObjectNameInfo->Name.Length = (
USHORT) (length -
sizeof( *ObjectNameInfo ));
02032 ObjectNameInfo->Name.MaximumLength = (
USHORT) ((length -
sizeof( *ObjectNameInfo )) +
sizeof( WCHAR ));
02033 }
02034
02035 finally {
02036
02037
02038
02039
02040
02041
ExFreePool( buffer );
02042 }
02043
02044
return status;
02045 }
02046
02047
VOID
02048 IopCheckBackupRestorePrivilege(
02049 IN
PACCESS_STATE AccessState,
02050 IN OUT PULONG CreateOptions,
02051 IN KPROCESSOR_MODE PreviousMode,
02052 IN ULONG Disposition
02053 )
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092 {
02093 ACCESS_MASK desiredAccess;
02094 ACCESS_MASK readAccess;
02095 ACCESS_MASK writeAccess;
02096 PRIVILEGE_SET requiredPrivileges;
02097 BOOLEAN accessGranted;
02098 BOOLEAN keepBackupIntent =
FALSE;
02099 BOOLEAN ForceRestoreCheck =
FALSE;
02100
02101
PAGED_CODE();
02102
02103
02104
02105
02106
02107
02108
if (AccessState->Flags &
SE_BACKUP_PRIVILEGES_CHECKED) {
02109
return;
02110 }
02111
02112
if (*CreateOptions & FILE_OPEN_FOR_BACKUP_INTENT) {
02113 AccessState->Flags |=
SE_BACKUP_PRIVILEGES_CHECKED;
02114
02115 readAccess = READ_CONTROL | ACCESS_SYSTEM_SECURITY | FILE_GENERIC_READ | FILE_TRAVERSE;
02116 writeAccess = WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY | FILE_GENERIC_WRITE | FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | DELETE;
02117
02118 desiredAccess = AccessState->RemainingDesiredAccess;
02119
02120
02121
02122
02123
02124
02125
02126
if (desiredAccess & MAXIMUM_ALLOWED) {
02127 desiredAccess |= ( readAccess | writeAccess );
02128 }
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
if ( Disposition & FILE_OPEN ) {
02140
02141
02142
02143
02144
02145
02146
02147
02148
if (readAccess & desiredAccess) {
02149
02150 requiredPrivileges.PrivilegeCount = 1;
02151 requiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
02152 requiredPrivileges.Privilege[0].Luid =
SeBackupPrivilege;
02153 requiredPrivileges.Privilege[0].Attributes = 0;
02154
02155 accessGranted =
SePrivilegeCheck( &requiredPrivileges,
02156 &AccessState->SubjectSecurityContext,
02157 PreviousMode );
02158
02159
if (accessGranted) {
02160
02161
02162
02163
02164
02165
02166 keepBackupIntent =
TRUE;
02167 (
VOID)
SeAppendPrivileges( AccessState, &requiredPrivileges );
02168 AccessState->PreviouslyGrantedAccess |= ( desiredAccess & readAccess );
02169 AccessState->RemainingDesiredAccess &= ~readAccess;
02170 desiredAccess &= ~readAccess;
02171 AccessState->Flags |=
TOKEN_HAS_BACKUP_PRIVILEGE;
02172 }
02173 }
02174
02175 }
else {
02176
02177 ForceRestoreCheck =
TRUE;
02178 }
02179
02180
02181
02182
02183
02184
02185
02186
02187
if ((writeAccess & desiredAccess) || ForceRestoreCheck) {
02188
02189 requiredPrivileges.PrivilegeCount = 1;
02190 requiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
02191 requiredPrivileges.Privilege[0].Luid =
SeRestorePrivilege;
02192 requiredPrivileges.Privilege[0].Attributes = 0;
02193
02194 accessGranted =
SePrivilegeCheck( &requiredPrivileges,
02195 &AccessState->SubjectSecurityContext,
02196 PreviousMode );
02197
02198
if (accessGranted) {
02199
02200
02201
02202
02203
02204
02205 keepBackupIntent =
TRUE;
02206 (
VOID)
SeAppendPrivileges( AccessState, &requiredPrivileges );
02207 AccessState->PreviouslyGrantedAccess |= (desiredAccess & writeAccess);
02208 AccessState->RemainingDesiredAccess &= ~writeAccess;
02209 AccessState->Flags |=
TOKEN_HAS_RESTORE_PRIVILEGE;
02210 }
02211 }
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
if (!keepBackupIntent) {
02222 *CreateOptions &= ~FILE_OPEN_FOR_BACKUP_INTENT;
02223 }
02224 }
02225 }