00217 :
00218
00219 This routine interfaces to
the NT Object
Manager. It
is invoked when
00220
the object system
is given
the name of an entity to create or open and
the
00221 name translates to a device object. This routine
is specified as
the parse
00222 routine
for all device objects.
00223
00224 In
the normal
case of an
NtCreateFile,
the user specifies either
the name
00225 of a device or of a
file. In
the former situation,
this routine
is invoked
00226 with a pointer to
the device and a null (
"") string. For this case, the
00227 routine simply allocates an
IRP, fills it in, and passes it to the driver
00228 for the device. The driver will then perform whatever rudimentary functions
00229 are necessary and will return a status code indicating whether an error was
00230 incurred. This status code is remembered in the Open Packet (OP).
00231
00232 In the latter situation, the name string to be opened/created is non-null.
00233 That is, it contains the remainder of the pathname to the file that is to
00234 be opened or created. For this case, the routine allocates an IRP, fills
00235 it in, and passes it to the driver for the device. The driver may then
00236 need to take further action or it may complete the request immediately. If
00237 it needs to perform some work asynchronously, then it can queue the request
00238 and return a status of STATUS_PENDING. This allows this routine and its
00239 caller to return to the user so that he can continue. Otherwise, the open/
00240 create is basically finished.
00241
00242 If the driver supports symbolic links, then it is also possible for the
00243 driver to return a new name. This name will be returned to the Object
00244 Manager as a new name to look up. The parsing will then begin again from
00245 the start.
00246
00247 It is also the responsibility of this routine to create a file object for
00248 the file, if the name specifies a file. The file object's address is
00249 returned to the NtCreateFile service through the OP.
00250
00251 Arguments:
00252
00253 ParseObject - Pointer to the device object the name translated into.
00254
00255 ObjectType - Type of the object being opened.
00256
00257 AccessState - Running security access state information for operation.
00258
00259 AccessMode - Access mode of the original caller.
00260
00261 Attributes - Attributes to be applied to the object.
00262
00263 CompleteName - Complete name of the object.
00264
00265 RemainingName - Remaining name of the object.
00266
00267 Context - Pointer to an Open Packet (OP) from NtCreateFile service.
00268
00269 SecurityQos - Optional security quality of service indicator.
00270
00271 Object - The address of a variable to receive the created file object, if
00272 any.
00273
00274 Return Value:
00275
00276 The function return value is one of the following:
00277
00278 a) Success - This indicates that the function succeeded and the object
00279 parameter contains the address of the created file object.
00280
00281 b) Error - This indicates that the file was not found or created and
00282 no file object was created.
00283
00284 c) Reparse - This indicates that the remaining name string has been
00285 replaced by a new name that is to be parsed.
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 }