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 static CONFIGURATION_INFORMATION ConfigurationInformation = {
00033 0,
00034 0,
00035 0,
00036 0,
00037 0,
00038 0,
00039 0,
00040
FALSE,
00041
FALSE,
00042
sizeof(
CONFIGURATION_INFORMATION),
00043 0
00044 };
00045
00046
00047
00048
00049
00050 LOGICAL
IoCountOperations =
TRUE;
00051
00052
#ifdef ALLOC_PRAGMA
00053
#pragma alloc_text(PAGE, IoAttachDevice)
00054
#pragma alloc_text(PAGE, IoCancelThreadIo)
00055
#pragma alloc_text(PAGE, IoCheckDesiredAccess)
00056
#pragma alloc_text(PAGE, IoCheckEaBufferValidity)
00057
#pragma alloc_text(PAGE, IoCheckFunctionAccess)
00058
#pragma alloc_text(PAGE, IoCheckQuotaBufferValidity)
00059
#pragma alloc_text(PAGE, IoCheckShareAccess)
00060
#pragma alloc_text(PAGE, IoConnectInterrupt)
00061
#pragma alloc_text(PAGE, IoCreateController)
00062
#pragma alloc_text(PAGE, IoCreateDevice)
00063
#pragma alloc_text(PAGE, IoCreateFile)
00064
#pragma alloc_text(PAGE, IoCreateNotificationEvent)
00065
#pragma alloc_text(PAGE, IoCreateStreamFileObject)
00066
#pragma alloc_text(PAGE, IoCreateSymbolicLink)
00067
#pragma alloc_text(PAGE, IoCreateSynchronizationEvent)
00068
#pragma alloc_text(PAGE, IoCreateUnprotectedSymbolicLink)
00069
#pragma alloc_text(PAGE, IoDeleteController)
00070
#pragma alloc_text(PAGE, IoDeleteSymbolicLink)
00071
#pragma alloc_text(PAGE, IoDisconnectInterrupt)
00072
#pragma alloc_text(PAGE, IoEnqueueIrp)
00073
#pragma alloc_text(PAGE, IoFastQueryNetworkAttributes)
00074
#pragma alloc_text(PAGE, IoGetConfigurationInformation)
00075
#pragma alloc_text(PAGE, IoGetDeviceObjectPointer)
00076
#pragma alloc_text(PAGE, IoInitializeTimer)
00077
#pragma alloc_text(PAGE, IoQueryFileInformation)
00078
#pragma alloc_text(PAGE, IoQueryVolumeInformation)
00079
#pragma alloc_text(PAGE, IoPageFileCreated)
00080
#pragma alloc_text(PAGE, IoRegisterBootDriverReinitialization)
00081
#pragma alloc_text(PAGE, IoRegisterDriverReinitialization)
00082
#pragma alloc_text(PAGE, IoRegisterFileSystem)
00083
#pragma alloc_text(PAGE, IoRegisterFsRegistrationChange)
00084
#pragma alloc_text(PAGE, IoRegisterLastChanceShutdownNotification)
00085
#pragma alloc_text(PAGE, IoRegisterShutdownNotification)
00086
#pragma alloc_text(PAGE, IoRemoveShareAccess)
00087
#pragma alloc_text(PAGE, IoSetInformation)
00088
#pragma alloc_text(PAGE, IoSetShareAccess)
00089
#pragma alloc_text(PAGE, IoUnregisterFileSystem)
00090
#pragma alloc_text(PAGE, IoUnregisterFsRegistrationChange)
00091
#pragma alloc_text(PAGE, IoUpdateShareAccess)
00092
#pragma alloc_text(PAGE, IoVerifyVolume)
00093
#pragma alloc_text(PAGE, IopCreateVpb)
00094
#pragma alloc_text(PAGE, IoCancelFileOpen)
00095
#pragma alloc_text(PAGELK, IoShutdownSystem)
00096
#pragma alloc_text(PAGELK, IoUnregisterShutdownNotification)
00097
#endif
00098
00099
VOID
00100 IoAcquireCancelSpinLock(
00101 OUT PKIRQL Irql
00102 )
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 {
00123 KIRQL oldIrql;
00124
00125
00126
00127
00128
00129 ExAcquireSpinLock( &
IopCancelSpinLock, &oldIrql );
00130 *Irql = oldIrql;
00131 }
00132
00133
VOID
00134 IoAcquireVpbSpinLock(
00135 OUT PKIRQL Irql
00136 )
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 {
00157 KIRQL oldIrql;
00158
00159
00160
00161
00162
00163 ExAcquireSpinLock( &
IopVpbSpinLock, &oldIrql );
00164 *Irql = oldIrql;
00165 }
00166
00167
00168
NTSTATUS
00169 IoAllocateAdapterChannel(
00170 IN
PADAPTER_OBJECT AdapterObject,
00171 IN
PDEVICE_OBJECT DeviceObject,
00172 IN ULONG NumberOfMapRegisters,
00173 IN PDRIVER_CONTROL ExecutionRoutine,
00174 IN PVOID Context
00175 )
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 {
00214
#if !defined(NO_LEGACY_DRIVERS)
00215
PWAIT_CONTEXT_BLOCK wcb;
00216
00217 wcb = &DeviceObject->Queue.Wcb;
00218
00219 wcb->
DeviceObject = DeviceObject;
00220 wcb->
CurrentIrp = DeviceObject->CurrentIrp;
00221 wcb->
DeviceContext = Context;
00222
00223
return(
HalAllocateAdapterChannel( AdapterObject,
00224 wcb,
00225 NumberOfMapRegisters,
00226 ExecutionRoutine ) );
00227
#else
00228
return( (*((
PDMA_ADAPTER)AdapterObject)->DmaOperations->
00229 AllocateAdapterChannel)( (
PDMA_ADAPTER)AdapterObject,
00230 DeviceObject,
00231 NumberOfMapRegisters,
00232 ExecutionRoutine,
00233 Context) );
00234
00235
#endif // NO_LEGACY_DRIVERS
00236
}
00237
00238
00239
VOID
00240 IoAllocateController(
00241 IN
PCONTROLLER_OBJECT ControllerObject,
00242 IN
PDEVICE_OBJECT DeviceObject,
00243 IN PDRIVER_CONTROL ExecutionRoutine,
00244 IN PVOID Context
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
IO_ALLOCATION_ACTION action;
00287
00288
00289
00290
00291
00292
00293 DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine;
00294 DeviceObject->Queue.Wcb.DeviceContext = Context;
00295
00296
00297
00298
00299
00300
00301
00302
00303
if (!
KeInsertDeviceQueue( &ControllerObject->DeviceWaitQueue,
00304 &DeviceObject->Queue.Wcb.WaitQueueEntry )) {
00305
00306
00307
00308
00309
00310
00311 action = ExecutionRoutine( DeviceObject,
00312 DeviceObject->CurrentIrp,
00313 0,
00314 Context );
00315
00316
00317
00318
00319
00320
00321
if (action ==
DeallocateObject) {
00322
IoFreeController( ControllerObject );
00323 }
00324 }
00325 }
00326
00327
NTSTATUS
00328 IoAllocateDriverObjectExtension(
00329 IN
PDRIVER_OBJECT DriverObject,
00330 IN PVOID ClientIdentificationAddress,
00331 IN ULONG DriverObjectExtensionSize,
00332 OUT PVOID *DriverObjectExtension
00333 )
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 {
00365 KIRQL irql;
00366 BOOLEAN inserted =
FALSE;
00367
PIO_CLIENT_EXTENSION extension;
00368
PIO_CLIENT_EXTENSION newExtension;
00369
00370 *DriverObjectExtension =
NULL;
00371
00372 newExtension =
ExAllocatePoolWithTag(
NonPagedPool,
00373 DriverObjectExtensionSize +
00374
sizeof(
IO_CLIENT_EXTENSION ),
00375 'virD');
00376
00377
if (newExtension ==
NULL) {
00378
return(STATUS_INSUFFICIENT_RESOURCES);
00379 }
00380
00381 RtlZeroMemory( newExtension,
00382 DriverObjectExtensionSize +
00383
sizeof(
IO_CLIENT_EXTENSION )
00384 );
00385
00386 newExtension->
ClientIdentificationAddress = ClientIdentificationAddress;
00387
00388 ExAcquireFastLock( &
IopDatabaseLock, &irql );
00389
extension = DriverObject->DriverExtension->ClientDriverExtension;
00390
while (
extension !=
NULL) {
00391
00392
if (
extension->ClientIdentificationAddress == ClientIdentificationAddress) {
00393
break;
00394 }
00395
00396
extension =
extension->NextExtension;
00397 }
00398
00399
if (
extension ==
NULL) {
00400
00401
00402
00403
00404
00405
00406 newExtension->
NextExtension =
00407 DriverObject->DriverExtension->ClientDriverExtension;
00408 DriverObject->DriverExtension->ClientDriverExtension = newExtension;
00409 inserted =
TRUE;
00410 }
00411
00412 ExReleaseFastLock( &
IopDatabaseLock, irql );
00413
00414
if (!inserted) {
00415
ExFreePool( newExtension );
00416
return(STATUS_OBJECT_NAME_COLLISION);
00417 }
00418
00419
00420
00421
00422
00423 *DriverObjectExtension = newExtension + 1;
00424
return(STATUS_SUCCESS);
00425 }
00426
00427 PVOID
00428 IoAllocateErrorLogEntry(
00429 IN PVOID IoObject,
00430 IN UCHAR EntrySize
00431 )
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 {
00460
PDEVICE_OBJECT deviceObject;
00461
PDRIVER_OBJECT driverObject;
00462
00463
00464
00465
00466
00467
if (IoObject ==
NULL) {
00468
return(
NULL);
00469 }
00470
00471
00472
00473
00474
00475 deviceObject = IoObject;
00476
00477
00478
00479
00480
00481
00482
00483
if (deviceObject->
Type ==
IO_TYPE_DEVICE) {
00484
00485 driverObject = deviceObject->
DriverObject;
00486
00487 }
else if (deviceObject->
Type ==
IO_TYPE_DRIVER) {
00488
00489 driverObject = (
PDRIVER_OBJECT) IoObject;
00490 deviceObject =
NULL;
00491
00492 }
else {
00493
00494
return(
NULL);
00495
00496 }
00497
00498
return (
IopAllocateErrorLogEntry(
00499 deviceObject,
00500 driverObject,
00501 EntrySize));
00502
00503 }
00504
00505 PVOID
00506 IoAllocateGenericErrorLogEntry(
00507 IN UCHAR EntrySize
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
00535
00536
00537 {
00538
return(
IopAllocateErrorLogEntry(
NULL,
NULL, EntrySize));
00539 }
00540
00541 PVOID
00542 IopAllocateErrorLogEntry(
00543 IN
PDEVICE_OBJECT deviceObject,
00544 IN
PDRIVER_OBJECT driverObject,
00545 IN UCHAR EntrySize
00546 )
00547 {
00548
PERROR_LOG_ENTRY elEntry;
00549 PVOID returnValue;
00550
NTSTATUS status;
00551 KIRQL oldIrql;
00552 ULONG size;
00553
00554
00555
00556
00557
00558
if (EntrySize <
sizeof(IO_ERROR_LOG_PACKET) ||
00559 EntrySize > ERROR_LOG_MAXIMUM_SIZE) {
00560
00561
return(
NULL);
00562 }
00563
00564
00565
00566
00567
00568 EntrySize = (UCHAR) ((EntrySize +
sizeof(PVOID) - 1) & ~(
sizeof(PVOID) - 1));
00569
00570
00571
00572
00573
00574 size =
sizeof(
ERROR_LOG_ENTRY) + EntrySize;
00575
00576
00577
00578
00579
00580 ExAcquireSpinLock(&
IopErrorLogAllocationLock, &oldIrql);
00581
00582
try{
00583
00584
if (
IopErrorLogAllocation >
IOP_MAXIMUM_LOG_ALLOCATION) {
00585
00586
00587
00588
00589
00590
return(
NULL);
00591 }
00592
00593
00594
00595
00596
00597
IopErrorLogAllocation += size;
00598
00599
00600
00601
00602
00603 elEntry =
ExAllocatePoolWithTag(
NonPagedPool, size, 'rEoI' );
00604
00605
if (elEntry ==
NULL) {
00606
00607
00608
00609
00610
00611
IopErrorLogAllocation -= size;
00612
00613
return(
NULL);
00614 }
00615
00616
00617
00618
00619
00620
00621
if (deviceObject !=
NULL) {
00622
00623
ObReferenceObject( deviceObject );
00624 }
00625
00626
if (driverObject !=
NULL) {
00627
00628
ObReferenceObject( driverObject );
00629 }
00630
00631
00632
00633
00634
00635 RtlZeroMemory(elEntry, size);
00636
00637 elEntry->
Type =
IO_TYPE_ERROR_LOG;
00638 elEntry->
Size = (
USHORT) size;
00639 elEntry->
DeviceObject = deviceObject;
00640 elEntry->
DriverObject = driverObject;
00641
00642 returnValue = elEntry+1;
00643
00644 } finally {
00645 ExReleaseSpinLock(&
IopErrorLogAllocationLock, oldIrql);
00646 }
00647
00648
return returnValue;
00649 }
00650
00651
PIRP
00652 IoAllocateIrp(
00653 IN CCHAR StackSize,
00654 IN BOOLEAN ChargeQuota
00655 )
00656 {
00657
return (
pIoAllocateIrp(StackSize, ChargeQuota));
00658 }
00659
00660
00661
PIRP
00662 IopAllocateIrpPrivate(
00663 IN CCHAR StackSize,
00664 IN BOOLEAN ChargeQuota
00665 )
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 {
00689
USHORT allocateSize;
00690 UCHAR fixedSize;
00691
PIRP irp;
00692 UCHAR lookasideAllocation;
00693
PNPAGED_LOOKASIDE_LIST lookasideList;
00694 UCHAR mustSucceed;
00695
PP_NPAGED_LOOKASIDE_NUMBER number;
00696
USHORT packetSize;
00697 PKPRCB prcb;
00698
00699
00700
00701
00702
00703
00704
00705 irp =
NULL;
00706 fixedSize = 0;
00707 mustSucceed = 0;
00708 packetSize =
IoSizeOfIrp(StackSize);
00709 allocateSize = packetSize;
00710
if ((StackSize <= (CCHAR)
IopLargeIrpStackLocations) &&
00711 ((ChargeQuota ==
FALSE) || (
IopLookasideIrpFloat <
IopLookasideIrpLimit))) {
00712 fixedSize =
IRP_ALLOCATED_FIXED_SIZE;
00713 number =
LookasideSmallIrpList;
00714
if (StackSize != 1) {
00715 allocateSize =
IoSizeOfIrp((CCHAR)
IopLargeIrpStackLocations);
00716 number =
LookasideLargeIrpList;
00717 }
00718
00719 prcb =
KeGetCurrentPrcb();
00720 lookasideList = prcb->PPLookasideList[number].P;
00721 lookasideList->
L.
TotalAllocates += 1;
00722 irp = (
PIRP)
ExInterlockedPopEntrySList(&lookasideList->
L.
ListHead,
00723 &lookasideList->
Lock);
00724
00725
if (irp ==
NULL) {
00726 lookasideList->
L.
AllocateMisses += 1;
00727 lookasideList = prcb->PPLookasideList[number].
L;
00728 lookasideList->
L.
TotalAllocates += 1;
00729 irp = (
PIRP)
ExInterlockedPopEntrySList(&lookasideList->
L.
ListHead,
00730 &lookasideList->
Lock);
00731 }
00732 }
00733
00734
00735
00736
00737
00738
00739 lookasideAllocation = 0;
00740
if (!irp) {
00741
if (fixedSize != 0) {
00742 lookasideList->
L.
AllocateMisses += 1;
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
if (ChargeQuota) {
00753
try {
00754 irp =
ExAllocatePoolWithQuotaTag(
NonPagedPool, allocateSize,' prI');
00755
00756 } except(
EXCEPTION_EXECUTE_HANDLER) {
00757 NOTHING;
00758 }
00759
00760 }
else {
00761
00762
00763
00764
00765
00766
00767
00768 irp =
ExAllocatePoolWithTag(
NonPagedPool, allocateSize, ' prI');
00769
if (!irp) {
00770 mustSucceed =
IRP_ALLOCATED_MUST_SUCCEED;
00771
if (KeGetPreviousMode() ==
KernelMode ) {
00772 irp =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
00773 allocateSize,
00774 ' prI');
00775 }
00776 }
00777 }
00778
00779
if (!irp) {
00780
return NULL;
00781 }
00782
00783 }
else {
00784
if (ChargeQuota !=
FALSE) {
00785 lookasideAllocation =
IRP_LOOKASIDE_ALLOCATION;
00786 InterlockedIncrement( &
IopLookasideIrpFloat );
00787 }
00788 ChargeQuota =
FALSE;
00789 }
00790
00791
00792
00793
00794
00795
IopInitializeIrp(irp, packetSize, StackSize);
00796 irp->
AllocationFlags = (fixedSize | lookasideAllocation | mustSucceed);
00797
if (ChargeQuota) {
00798 irp->
AllocationFlags |=
IRP_QUOTA_CHARGED;
00799 }
00800
00801
return irp;
00802 }
00803
00804
PMDL
00805 IoAllocateMdl(
00806 IN PVOID VirtualAddress,
00807 IN ULONG Length,
00808 IN BOOLEAN SecondaryBuffer,
00809 IN BOOLEAN ChargeQuota,
00810 IN OUT
PIRP Irp OPTIONAL
00811 )
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 {
00850 ULONG allocateSize;
00851
USHORT fixedSize;
00852
PMDL mdl;
00853
USHORT mustSucceed;
00854 ULONG size;
00855
PMDL tmpMdlPtr;
00856
00857
ASSERT(Length);
00858
00859
00860
00861
00862
00863
00864
if (Length & 0x80000000) {
00865
return NULL;
00866 }
00867
00868
00869
00870
00871
00872 mdl =
NULL;
00873 fixedSize = 0;
00874 mustSucceed = 0;
00875 size =
COMPUTE_PAGES_SPANNED(VirtualAddress, Length);
00876
if (size >
IOP_FIXED_SIZE_MDL_PFNS) {
00877 allocateSize =
sizeof(
MDL) + (
sizeof(PFN_NUMBER) * size);
00878
if (allocateSize > MAXUSHORT) {
00879
return NULL;
00880 }
00881
00882 }
else {
00883 fixedSize =
MDL_ALLOCATED_FIXED_SIZE;
00884 allocateSize =
sizeof(
MDL) + (
sizeof(PFN_NUMBER) *
IOP_FIXED_SIZE_MDL_PFNS);
00885 mdl = (
PMDL)
ExAllocateFromPPNPagedLookasideList(
LookasideMdlList);
00886 }
00887
00888
if (!mdl) {
00889 mdl =
ExAllocatePoolWithTag(
NonPagedPool, allocateSize, ' ldM');
00890
if (!mdl) {
00891
if (KeGetPreviousMode() ==
KernelMode) {
00892 mustSucceed =
MDL_ALLOCATED_MUST_SUCCEED;
00893 mdl =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
00894 allocateSize,
00895 ' ldM' );
00896 }
00897
00898
if (!mdl) {
00899
return NULL;
00900 }
00901 }
00902 }
00903
00904
00905
00906
00907
00908
MmInitializeMdl(mdl, VirtualAddress, Length);
00909 mdl->
MdlFlags |= (fixedSize | mustSucceed);
00910
00911
00912
00913
00914
00915
00916
if (
Irp) {
00917
if (!SecondaryBuffer) {
00918
Irp->
MdlAddress = mdl;
00919
00920 }
else {
00921 tmpMdlPtr =
Irp->
MdlAddress;
00922
while (tmpMdlPtr->
Next !=
NULL) {
00923 tmpMdlPtr = tmpMdlPtr->
Next;
00924 }
00925
00926 tmpMdlPtr->
Next = mdl;
00927 }
00928 }
00929
00930
return mdl;
00931 }
00932
00933
NTSTATUS
00934 IoAsynchronousPageWrite(
00935 IN
PFILE_OBJECT FileObject,
00936 IN
PMDL MemoryDescriptorList,
00937 IN PLARGE_INTEGER StartingOffset,
00938 IN PIO_APC_ROUTINE ApcRoutine,
00939 IN PVOID ApcContext,
00940 OUT PIO_STATUS_BLOCK IoStatusBlock,
00941 OUT
PIRP *Irp OPTIONAL
00942 )
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 {
00985
PIRP irp;
00986
PIO_STACK_LOCATION irpSp;
00987
PDEVICE_OBJECT deviceObject;
00988
NTSTATUS status;
00989
00990
00991
00992
00993
00994
00995 deviceObject =
IoGetRelatedDeviceObject( FileObject );
00996
00997
00998
00999
01000
01001 irp =
IoAllocateIrp( deviceObject->
StackSize,
FALSE );
01002
if (!irp) {
01003
return STATUS_INSUFFICIENT_RESOURCES;
01004 }
01005
01006
01007
01008
01009
01010
01011
01012
01013
if (ARGUMENT_PRESENT(
Irp)) {
01014 *
Irp = irp;
01015 }
01016
01017
01018
01019
01020
01021
01022
01023 irpSp =
IoGetNextIrpStackLocation( irp );
01024
01025
01026
01027
01028
01029 irp->
MdlAddress = MemoryDescriptorList;
01030 irp->
Flags =
IRP_PAGING_IO |
IRP_NOCACHE;
01031 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
01032 irp->
Tail.Overlay.OriginalFileObject = FileObject;
01033 irp->
UserBuffer = (PVOID) ((PCHAR) MemoryDescriptorList->StartVa + MemoryDescriptorList->ByteOffset);
01034 irp->
RequestorMode =
KernelMode;
01035 irp->
UserIosb = IoStatusBlock;
01036 irp->
Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
01037 irp->
Overlay.AsynchronousParameters.UserApcContext = ApcContext;
01038
01039
01040
01041
01042
01043 irpSp->
MajorFunction =
IRP_MJ_WRITE;
01044 irpSp->
Parameters.Write.Length = MemoryDescriptorList->ByteCount;
01045 irpSp->
Parameters.Write.ByteOffset = *StartingOffset;
01046 irpSp->
FileObject = FileObject;
01047
01048
01049
01050
01051
01052
01053 status =
IoCallDriver( deviceObject, irp );
01054
01055
if (
NT_ERROR( status )) {
01056 IoStatusBlock->Status = status;
01057 IoStatusBlock->Information = 0;
01058 ApcRoutine( ApcContext, IoStatusBlock, 0 );
01059 status = STATUS_PENDING;
01060 }
01061
01062
return status;
01063 }
01064
01065
01066
NTSTATUS
01067 IoAttachDevice(
01068 IN
PDEVICE_OBJECT SourceDevice,
01069 IN PUNICODE_STRING TargetDevice,
01070 OUT
PDEVICE_OBJECT *AttachedDevice
01071 )
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100 {
01101
NTSTATUS status;
01102
PDEVICE_OBJECT targetDevice;
01103
PFILE_OBJECT fileObject;
01104 OBJECT_ATTRIBUTES objectAttributes;
01105 HANDLE fileHandle;
01106 IO_STATUS_BLOCK ioStatus;
01107
01108
PAGED_CODE();
01109
01110
01111
01112
01113
01114
01115
01116 InitializeObjectAttributes( &objectAttributes,
01117 TargetDevice,
01118 0,
01119 (HANDLE)
NULL,
01120 (PSECURITY_DESCRIPTOR)
NULL );
01121
01122 status =
ZwOpenFile( &fileHandle,
01123 FILE_READ_ATTRIBUTES,
01124 &objectAttributes,
01125 &ioStatus,
01126 0,
01127 FILE_NON_DIRECTORY_FILE |
IO_ATTACH_DEVICE_API );
01128
01129
if (
NT_SUCCESS( status )) {
01130
01131
01132
01133
01134
01135
01136 status =
ObReferenceObjectByHandle( fileHandle,
01137 0,
01138
IoFileObjectType,
01139
KernelMode,
01140 (PVOID *) &fileObject,
01141
NULL );
01142
if (
NT_SUCCESS( status )) {
01143
01144
01145
01146
01147
01148
01149 targetDevice =
IoGetRelatedDeviceObject( fileObject );
01150 (
VOID) ZwClose( fileHandle );
01151
01152 }
else {
01153
01154
return status;
01155 }
01156
01157 }
else {
01158
01159
return status;
01160
01161 }
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 *AttachedDevice =
IoAttachDeviceToDeviceStack( SourceDevice, targetDevice );
01173
if(!*AttachedDevice) {
01174 status = STATUS_NO_SUCH_DEVICE;
01175 }
01176
01177
01178
01179
01180
01181
01182
01183
ObDereferenceObject( fileObject );
01184
01185
01186
01187
01188
01189
return status;
01190 }
01191
01192
NTSTATUS
01193 IoAttachDeviceByPointer(
01194 IN
PDEVICE_OBJECT SourceDevice,
01195 IN
PDEVICE_OBJECT TargetDevice
01196 )
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 {
01224
PDEVICE_OBJECT deviceObject;
01225
NTSTATUS status;
01226
01227
01228
01229
01230
01231
01232 deviceObject =
IoAttachDeviceToDeviceStack( SourceDevice, TargetDevice );
01233
if( deviceObject ==
NULL ){
01234 status = STATUS_NO_SUCH_DEVICE;
01235 }
else {
01236 status = STATUS_SUCCESS;
01237 }
01238
01239
return status;
01240 }
01241
01242
PDEVICE_OBJECT
01243 IoAttachDeviceToDeviceStack(
01244 IN
PDEVICE_OBJECT SourceDevice,
01245 IN
PDEVICE_OBJECT TargetDevice
01246 )
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 {
01276
PDEVICE_OBJECT deviceObject;
01277
PDEVOBJ_EXTENSION sourceExtension;
01278 KIRQL irql;
01279
01280
01281
01282
01283
01284
01285 sourceExtension = SourceDevice->DeviceObjectExtension;
01286
01287
01288
01289
01290
01291
01292 ExAcquireFastLock( &
IopDatabaseLock, &irql );
01293
01294
01295
01296
01297
01298
01299
01300
IOV_ATTACH_DEVICE_TO_DEVICE_STACK(SourceDevice, TargetDevice);
01301
01302 deviceObject =
IoGetAttachedDevice( TargetDevice );
01303
01304
01305
01306
01307
01308
01309
ASSERT( sourceExtension->
AttachedTo ==
NULL );
01310
01311
01312
01313
01314
01315
01316
if (deviceObject->
Flags &
DO_DEVICE_INITIALIZING ||
01317 deviceObject->
DeviceObjectExtension->
ExtensionFlags &
01318 (
DOE_UNLOAD_PENDING |
DOE_DELETE_PENDING |
DOE_REMOVE_PENDING |
DOE_REMOVE_PROCESSED)) {
01319
01320
01321
01322
01323
01324
01325 deviceObject = (
PDEVICE_OBJECT)
NULL;
01326
01327 }
else {
01328
01329
01330
01331
01332
01333 deviceObject->
AttachedDevice = SourceDevice;
01334 deviceObject->
Spare1++;
01335
01336
01337
01338
01339
01340 SourceDevice->StackSize = (UCHAR) (deviceObject->
StackSize + 1);
01341 SourceDevice->AlignmentRequirement = deviceObject->
AlignmentRequirement;
01342 SourceDevice->SectorSize = deviceObject->
SectorSize;
01343
01344
if (deviceObject->
DeviceObjectExtension->
ExtensionFlags &
DOE_START_PENDING) {
01345 SourceDevice->DeviceObjectExtension->ExtensionFlags |=
DOE_START_PENDING;
01346 }
01347
01348
01349
01350
01351
01352 sourceExtension->
AttachedTo = deviceObject;
01353 }
01354 ExReleaseFastLock( &
IopDatabaseLock, irql );
01355
01356
return deviceObject;
01357 }
01358
01359
PIRP
01360 IoBuildAsynchronousFsdRequest(
01361 IN ULONG MajorFunction,
01362 IN
PDEVICE_OBJECT DeviceObject,
01363 IN OUT PVOID Buffer OPTIONAL,
01364 IN ULONG Length OPTIONAL,
01365 IN PLARGE_INTEGER StartingOffset OPTIONAL,
01366 IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL
01367 )
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416 {
01417
PIRP irp;
01418
PIO_STACK_LOCATION irpSp;
01419
01420
01421
01422
01423
01424
01425 irp =
IoAllocateIrp( DeviceObject->StackSize,
FALSE );
01426
if (!irp) {
01427
return irp;
01428 }
01429
01430
01431
01432
01433
01434 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
01435
01436
01437
01438
01439
01440
01441 irpSp =
IoGetNextIrpStackLocation( irp );
01442
01443
01444
01445
01446
01447 irpSp->
MajorFunction = (UCHAR) MajorFunction;
01448
01449
if (MajorFunction !=
IRP_MJ_FLUSH_BUFFERS &&
01450 MajorFunction !=
IRP_MJ_SHUTDOWN &&
01451 MajorFunction !=
IRP_MJ_PNP &&
01452 MajorFunction !=
IRP_MJ_POWER) {
01453
01454
01455
01456
01457
01458
01459
01460
if (DeviceObject->Flags &
DO_BUFFERED_IO) {
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471 irp->
AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned,
01472 Length,
01473 ' oI' );
01474
if (irp->
AssociatedIrp.SystemBuffer ==
NULL) {
01475
IoFreeIrp( irp );
01476
return (
PIRP)
NULL;
01477 }
01478
01479
if (MajorFunction ==
IRP_MJ_WRITE) {
01480 RtlCopyMemory( irp->
AssociatedIrp.SystemBuffer,
Buffer, Length );
01481 irp->
Flags =
IRP_BUFFERED_IO |
IRP_DEALLOCATE_BUFFER;
01482 }
else {
01483 irp->
Flags =
IRP_BUFFERED_IO |
IRP_DEALLOCATE_BUFFER |
IRP_INPUT_OPERATION;
01484 irp->
UserBuffer =
Buffer;
01485 }
01486
01487 }
else if (DeviceObject->Flags &
DO_DIRECT_IO) {
01488
01489
01490
01491
01492
01493
01494
01495 irp->
MdlAddress =
IoAllocateMdl(
Buffer,
01496 Length,
01497
FALSE,
01498
FALSE,
01499 (
PIRP)
NULL );
01500
if (irp->
MdlAddress ==
NULL) {
01501
IoFreeIrp( irp );
01502
return (
PIRP)
NULL;
01503 }
01504
01505
try {
01506
MmProbeAndLockPages( irp->
MdlAddress,
01507
KernelMode,
01508 (
LOCK_OPERATION) (MajorFunction ==
IRP_MJ_READ ?
IoWriteAccess :
IoReadAccess) );
01509 } except(
EXCEPTION_EXECUTE_HANDLER) {
01510
if (irp->
MdlAddress !=
NULL) {
01511
IoFreeMdl( irp->
MdlAddress );
01512 }
01513
IoFreeIrp( irp );
01514
return (
PIRP)
NULL;
01515 }
01516
01517 }
else {
01518
01519
01520
01521
01522
01523
01524 irp->
UserBuffer =
Buffer;
01525 }
01526
01527
01528
01529
01530
01531
01532
01533
if (MajorFunction ==
IRP_MJ_WRITE) {
01534 irpSp->
Parameters.Write.Length = Length;
01535 irpSp->
Parameters.Write.ByteOffset = *StartingOffset;
01536 }
else {
01537 irpSp->
Parameters.Read.Length = Length;
01538 irpSp->
Parameters.Read.ByteOffset = *StartingOffset;
01539 }
01540 }
01541
01542
01543
01544
01545
01546
01547 irp->
UserIosb = IoStatusBlock;
01548
return irp;
01549 }
01550
01551
PIRP
01552 IoBuildDeviceIoControlRequest(
01553 IN ULONG IoControlCode,
01554 IN
PDEVICE_OBJECT DeviceObject,
01555 IN PVOID InputBuffer OPTIONAL,
01556 IN ULONG InputBufferLength,
01557 OUT PVOID OutputBuffer OPTIONAL,
01558 IN ULONG OutputBufferLength,
01559 IN BOOLEAN InternalDeviceIoControl,
01560 IN
PKEVENT Event,
01561 OUT PIO_STATUS_BLOCK IoStatusBlock
01562 )
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611 {
01612
PIRP irp;
01613
PIO_STACK_LOCATION irpSp;
01614 ULONG method;
01615
01616
01617
01618
01619
01620
01621 irp =
IoAllocateIrp( DeviceObject->StackSize,
FALSE );
01622
if (!irp) {
01623
return irp;
01624 }
01625
01626
01627
01628
01629
01630
01631 irpSp =
IoGetNextIrpStackLocation( irp );
01632
01633
01634
01635
01636
01637
01638
if (InternalDeviceIoControl) {
01639 irpSp->
MajorFunction =
IRP_MJ_INTERNAL_DEVICE_CONTROL;
01640 }
else {
01641 irpSp->
MajorFunction =
IRP_MJ_DEVICE_CONTROL;
01642 }
01643
01644
01645
01646
01647
01648
01649 irpSp->
Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
01650 irpSp->
Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
01651 irpSp->
Parameters.DeviceIoControl.IoControlCode = IoControlCode;
01652
01653
01654
01655
01656
01657
01658 method = IoControlCode & 3;
01659
01660
01661
01662
01663
01664
01665
switch ( method ) {
01666
01667
case 0:
01668
01669
01670
01671
01672
01673
01674
01675
if (InputBufferLength != 0 || OutputBufferLength != 0) {
01676 irp->
AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned,
01677 InputBufferLength > OutputBufferLength ? InputBufferLength : OutputBufferLength,
01678 ' oI' );
01679
if (irp->
AssociatedIrp.SystemBuffer ==
NULL) {
01680
IoFreeIrp( irp );
01681
return (
PIRP)
NULL;
01682 }
01683
if (ARGUMENT_PRESENT( InputBuffer )) {
01684 RtlCopyMemory( irp->
AssociatedIrp.SystemBuffer,
01685 InputBuffer,
01686 InputBufferLength );
01687 }
01688 irp->
Flags =
IRP_BUFFERED_IO |
IRP_DEALLOCATE_BUFFER;
01689 irp->
UserBuffer = OutputBuffer;
01690
if (ARGUMENT_PRESENT( OutputBuffer )) {
01691 irp->
Flags |=
IRP_INPUT_OPERATION;
01692 }
01693 }
else {
01694 irp->
Flags = 0;
01695 irp->
UserBuffer = (PVOID)
NULL;
01696 }
01697
01698
break;
01699
01700
case 1:
01701
case 2:
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
if (ARGUMENT_PRESENT( InputBuffer )) {
01712 irp->
AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned,
01713 InputBufferLength,
01714 ' oI' );
01715
if (irp->
AssociatedIrp.SystemBuffer ==
NULL) {
01716
IoFreeIrp( irp );
01717
return (
PIRP)
NULL;
01718 }
01719 RtlCopyMemory( irp->
AssociatedIrp.SystemBuffer,
01720 InputBuffer,
01721 InputBufferLength );
01722 irp->
Flags =
IRP_BUFFERED_IO |
IRP_DEALLOCATE_BUFFER;
01723 }
else {
01724 irp->
Flags = 0;
01725 }
01726
01727
if (ARGUMENT_PRESENT( OutputBuffer )) {
01728 irp->
MdlAddress =
IoAllocateMdl( OutputBuffer,
01729 OutputBufferLength,
01730
FALSE,
01731
FALSE,
01732 (
PIRP)
NULL );
01733
if (irp->
MdlAddress ==
NULL) {
01734
if (ARGUMENT_PRESENT( InputBuffer )) {
01735
ExFreePool( irp->
AssociatedIrp.SystemBuffer );
01736 }
01737
IoFreeIrp( irp );
01738
return (
PIRP)
NULL;
01739 }
01740
01741
try {
01742
01743
MmProbeAndLockPages( irp->
MdlAddress,
01744
KernelMode,
01745 (
LOCK_OPERATION) ((method == 1) ?
IoReadAccess :
IoWriteAccess) );
01746
01747 } except (
EXCEPTION_EXECUTE_HANDLER) {
01748
01749
if (irp->
MdlAddress !=
NULL) {
01750
IoFreeMdl( irp->
MdlAddress );
01751 }
01752
01753
if (ARGUMENT_PRESENT( InputBuffer )) {
01754
ExFreePool( irp->
AssociatedIrp.SystemBuffer );
01755 }
01756
01757
IoFreeIrp( irp );
01758
return (
PIRP)
NULL;
01759 }
01760 }
01761
01762
break;
01763
01764
case 3:
01765
01766
01767
01768
01769
01770
01771
01772 irp->
UserBuffer = OutputBuffer;
01773 irpSp->
Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
01774 }
01775
01776
01777
01778
01779
01780
01781
01782
01783 irp->
UserIosb = IoStatusBlock;
01784 irp->
UserEvent =
Event;
01785
01786
01787
01788
01789
01790
01791
01792
01793 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
01794
IopQueueThreadIrp( irp );
01795
01796
01797
01798
01799
01800
return irp;
01801 }
01802
01803
VOID
01804 IoBuildPartialMdl(
01805 IN
PMDL SourceMdl,
01806 IN OUT
PMDL TargetMdl,
01807 IN PVOID VirtualAddress,
01808 IN ULONG Length
01809 )
01810
01811
01812
01813
01814
01815
01816
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 ULONG_PTR baseVa;
01847 ULONG offset;
01848 ULONG newLength;
01849 ULONG pageOffset;
01850 PPFN_NUMBER basePointer;
01851 PPFN_NUMBER copyPointer;
01852
01853
01854
01855
01856
01857
01858
01859 baseVa = (ULONG_PTR)
MmGetMdlBaseVa( SourceMdl );
01860 offset = (ULONG) ((ULONG_PTR)VirtualAddress - baseVa) -
MmGetMdlByteOffset(SourceMdl);
01861
01862
if (Length == 0) {
01863 newLength =
MmGetMdlByteCount( SourceMdl ) - offset;
01864 }
else {
01865 newLength = Length;
01866
01867
01868
01869 }
01870
01871
01872
01873
01874
01875
01876
01877 TargetMdl->Process = SourceMdl->Process;
01878
01879 TargetMdl->StartVa = (PVOID)
PAGE_ALIGN( VirtualAddress );
01880 pageOffset = ((ULONG)((ULONG_PTR) TargetMdl->StartVa - (ULONG_PTR) SourceMdl->StartVa)) >>
PAGE_SHIFT;
01881
01882
01883 TargetMdl->ByteCount = newLength;
01884 TargetMdl->ByteOffset =
BYTE_OFFSET( VirtualAddress );
01885 newLength =
COMPUTE_PAGES_SPANNED( VirtualAddress, newLength );
01886
if (((TargetMdl->Size -
sizeof(
MDL )) /
sizeof (PFN_NUMBER)) < newLength ) {
01887
KeBugCheck( TARGET_MDL_TOO_SMALL );
01888 }
01889
01890
01891
01892
01893
01894
01895
01896 TargetMdl->MdlFlags &= (
MDL_ALLOCATED_FIXED_SIZE |
MDL_ALLOCATED_MUST_SUCCEED);
01897 TargetMdl->MdlFlags |= SourceMdl->MdlFlags & (
MDL_SOURCE_IS_NONPAGED_POOL |
01898
MDL_MAPPED_TO_SYSTEM_VA |
01899
MDL_IO_PAGE_READ);
01900 TargetMdl->MdlFlags |=
MDL_PARTIAL;
01901
01902
#if DBG
01903
if (TargetMdl->MdlFlags &
MDL_MAPPED_TO_SYSTEM_VA) {
01904 TargetMdl->MdlFlags |=
MDL_PARENT_MAPPED_SYSTEM_VA;
01905 }
01906
#endif //DBG
01907
01908
01909
01910
01911
01912 TargetMdl->MappedSystemVa = (PUCHAR)SourceMdl->MappedSystemVa + offset;
01913
01914
01915
01916
01917
01918
01919
01920 basePointer =
MmGetMdlPfnArray(SourceMdl);
01921 basePointer += pageOffset;
01922 copyPointer =
MmGetMdlPfnArray(TargetMdl);
01923
01924
while (newLength > 0) {
01925 *copyPointer = *basePointer;
01926 copyPointer++;
01927 basePointer++;
01928 newLength--;
01929 }
01930 }
01931
01932
PIRP
01933 IoBuildSynchronousFsdRequest(
01934 IN ULONG MajorFunction,
01935 IN
PDEVICE_OBJECT DeviceObject,
01936 IN OUT PVOID Buffer OPTIONAL,
01937 IN ULONG Length OPTIONAL,
01938 IN PLARGE_INTEGER StartingOffset OPTIONAL,
01939 IN
PKEVENT Event,
01940 OUT PIO_STATUS_BLOCK IoStatusBlock
01941 )
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992 {
01993
PIRP irp;
01994
01995
01996
01997
01998
01999 irp =
IoBuildAsynchronousFsdRequest( MajorFunction,
02000 DeviceObject,
02001
Buffer,
02002 Length,
02003 StartingOffset,
02004 IoStatusBlock );
02005
if (irp ==
NULL) {
02006
return irp;
02007 }
02008
02009
02010
02011
02012
02013
02014
02015 irp->
UserEvent =
Event;
02016
02017
02018
02019
02020
02021
02022
IopQueueThreadIrp( irp );
02023
return irp;
02024 }
02025
02026
#if DBG && PNP_IO_TRACE
02027
PCHAR pnpmf[] = {
02028
"START_DEVICE",
02029
"QUERY_REMOVE_DEVICE",
02030
"REMOVE_DEVICE",
02031
"CANCEL_REMOVE_DEVICE",
02032
"STOP_DEVICE",
02033
"QUERY_STOP_DEVICE",
02034
"CANCEL_STOP_DEVICE",
02035
"QUERY_DEVICE_RELATIONS",
02036
"QUERY_INTERFACE",
02037
"QUERY_CAPABILITIES",
02038
"QUERY_RESOURCES",
02039
"QUERY_RESOURCE_REQUIREMENTS",
02040
"QUERY_DEVICE_TEXT",
02041
"FILTER_RESOURCE_REQUIREMENTS",
02042
"obsolete minor function!!!",
02043
"READ_CONFIG",
02044
"WRITE_CONFIG",
02045
"EJECT",
02046
"SET_LOCK",
02047
"QUERY_ID",
02048
"QUERY_PNP_DEVICE_STATE",
02049
"QUERY_BUS_INFORMATION",
02050
"USAGE_NOTIFICATION"
02051 };
02052 PCHAR pnpUsageMf[] = {
02053
"*** Undefined ***",
02054
"Paging",
02055
"Hibernation",
02056
"DumpFile"
02057 };
02058
#endif
02059
02060
02061
NTSTATUS
02062
FASTCALL
02063 IopfCallDriver(
02064 IN
PDEVICE_OBJECT DeviceObject,
02065 IN OUT
PIRP Irp
02066 )
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 {
02088
PIO_STACK_LOCATION irpSp;
02089
PDRIVER_OBJECT driverObject;
02090
NTSTATUS status;
02091
02092
02093
02094
02095
02096
ASSERT(
Irp->
Type ==
IO_TYPE_IRP );
02097
02098
02099
02100
02101
Irp->
CurrentLocation--;
02102
02103
if (
Irp->
CurrentLocation <= 0) {
02104
KeBugCheckEx( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR)
Irp, 0, 0, 0 );
02105 }
02106
02107 irpSp =
IoGetNextIrpStackLocation(
Irp );
02108
Irp->
Tail.Overlay.CurrentStackLocation = irpSp;
02109
02110
02111
02112
02113
02114
02115 irpSp->
DeviceObject = DeviceObject;
02116
02117
02118
02119
02120
02121 driverObject = DeviceObject->DriverObject;
02122
02123
PERFINFO_DRIVER_MAJORFUNCTION_CALL(
Irp, irpSp, driverObject);
02124
02125 status = driverObject->
MajorFunction[irpSp->
MajorFunction]( DeviceObject,
02126
Irp );
02127
02128
PERFINFO_DRIVER_MAJORFUNCTION_RETURN(
Irp, irpSp, driverObject);
02129
02130
return status;
02131 }
02132
02133
NTSTATUS
02134
FASTCALL
02135 IofCallDriver(
02136 IN
PDEVICE_OBJECT DeviceObject,
02137 IN OUT
PIRP Irp
02138 )
02139 {
02140
02141
02142
02143
02144
return pIofCallDriver(DeviceObject,
Irp);
02145 }
02146
02147
02148 BOOLEAN
02149 IoCancelIrp(
02150 IN
PIRP Irp
02151 )
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180 {
02181
PDRIVER_CANCEL cancelRoutine;
02182 KIRQL irql;
02183 BOOLEAN returnValue;
02184
02185
02186
ASSERT(
Irp->
Type ==
IO_TYPE_IRP );
02187
02188
if (
IopVerifierOn) {
02189
if (
IOV_CANCEL_IRP(
Irp, &returnValue)) {
02190
return returnValue;
02191 }
02192 }
02193
02194
02195
02196
02197
02198
IoAcquireCancelSpinLock( &irql );
02199
02200
02201
02202
02203
02204
Irp->
Cancel =
TRUE;
02205
02206
02207
02208
02209
02210
02211 cancelRoutine = (
PDRIVER_CANCEL) InterlockedExchangePointer( (PVOID *) &
Irp->
CancelRoutine,
02212
NULL );
02213
02214
if (cancelRoutine) {
02215
if (
Irp->
CurrentLocation > (CCHAR) (
Irp->
StackCount + 1)) {
02216
KeBugCheckEx( CANCEL_STATE_IN_COMPLETED_IRP, (ULONG_PTR)
Irp, 0, 0, 0 );
02217 }
02218
Irp->
CancelIrql = irql;
02219
02220 cancelRoutine(
Irp->
Tail.Overlay.CurrentStackLocation->DeviceObject,
02221
Irp );
02222
02223
02224
02225
02226
return(
TRUE);
02227
02228 }
else {
02229
02230
02231
02232
02233
02234
02235
IoReleaseCancelSpinLock( irql );
02236
02237
return(
FALSE);
02238 }
02239 }
02240
02241
VOID
02242 IoCancelThreadIo(
02243 IN
PETHREAD Thread
02244 )
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265 {
02266 PLIST_ENTRY header;
02267 PLIST_ENTRY entry;
02268 KIRQL irql;
02269
PETHREAD thread;
02270
PIRP irp;
02271 ULONG count;
02272 LARGE_INTEGER interval;
02273
02274
PAGED_CODE();
02275
02276 DBG_UNREFERENCED_PARAMETER( Thread );
02277
02278 thread =
PsGetCurrentThread();
02279
02280
02281
02282
02283
02284
02285
KeRaiseIrql(
APC_LEVEL, &irql );
02286
02287 header = &thread->
IrpList;
02288 entry = thread->
IrpList.Flink;
02289
02290
02291
02292
02293
02294
while (header != entry) {
02295 irp = CONTAINING_RECORD( entry,
IRP, ThreadListEntry );
02296
IoCancelIrp( irp );
02297 entry = entry->Flink;
02298 }
02299
02300
02301
02302
02303
02304
02305 count = 0;
02306 interval.QuadPart = -10 * 1000 * 100;
02307
02308
while (!IsListEmpty( &Thread->IrpList )) {
02309
02310
02311
02312
02313
02314
02315
02316
KeLowerIrql( irql );
02317
KeDelayExecutionThread(
KernelMode,
FALSE, &interval );
02318
02319
if (count++ > 3000) {
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
IopDisassociateThreadIrp();
02331 }
02332
02333
KeRaiseIrql(
APC_LEVEL, &irql );
02334 }
02335
02336
KeLowerIrql( irql );
02337 }
02338
02339
NTSTATUS
02340 IoCheckDesiredAccess(
02341 IN OUT PACCESS_MASK DesiredAccess,
02342 IN ACCESS_MASK GrantedAccess
02343 )
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369 {
02370
PAGED_CODE();
02371
02372
02373
02374
02375
02376
RtlMapGenericMask( DesiredAccess,
02377 &
IoFileObjectType->
TypeInfo.
GenericMapping );
02378
02379
02380
02381
02382
02383
02384
if (!
SeComputeDeniedAccesses( GrantedAccess, *DesiredAccess )) {
02385
return STATUS_SUCCESS;
02386 }
else {
02387
return STATUS_ACCESS_DENIED;
02388 }
02389 }
02390
02391
NTSTATUS
02392 IoCheckEaBufferValidity(
02393 IN PFILE_FULL_EA_INFORMATION EaBuffer,
02394 IN ULONG EaLength,
02395 OUT PULONG ErrorOffset
02396 )
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423 #define
ALIGN_LONG( Address ) ( (ULONG) ((Address + 3) & ~3) )
02424
02425
#define GET_OFFSET_LENGTH( CurrentEa, EaBase ) ( \
02426
(ULONG) ((PCHAR) CurrentEa - (PCHAR) EaBase) )
02427
02428 {
02429 LONG tempLength;
02430 ULONG entrySize;
02431 PFILE_FULL_EA_INFORMATION eas;
02432
02433
PAGED_CODE();
02434
02435
02436
02437
02438
02439
02440
02441 eas = EaBuffer;
02442 tempLength = EaLength;
02443
02444
for (;;) {
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
if (tempLength < FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0])) {
02460
02461 *ErrorOffset =
GET_OFFSET_LENGTH( eas, EaBuffer );
02462
return STATUS_EA_LIST_INCONSISTENT;
02463 }
02464
02465 entrySize = FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0] ) +
02466 eas->EaNameLength + 1 + eas->EaValueLength;
02467
02468
02469
02470
02471
02472
if ((ULONG) tempLength < entrySize) {
02473
02474 *ErrorOffset =
GET_OFFSET_LENGTH( eas, EaBuffer );
02475
return STATUS_EA_LIST_INCONSISTENT;
02476 }
02477
02478
02479
02480
02481
02482
if (eas->EaName[eas->EaNameLength] !=
'\0') {
02483
02484 *ErrorOffset =
GET_OFFSET_LENGTH( eas, EaBuffer );
02485
return STATUS_EA_LIST_INCONSISTENT;
02486 }
02487
02488
if (eas->NextEntryOffset) {
02489
02490
02491
02492
02493
02494
02495
02496
if (
ALIGN_LONG( entrySize ) != eas->NextEntryOffset ||
02497 (LONG) eas->NextEntryOffset < 0) {
02498 *ErrorOffset =
GET_OFFSET_LENGTH( eas, EaBuffer );
02499
return STATUS_EA_LIST_INCONSISTENT;
02500
02501 }
else {
02502
02503
02504
02505
02506
02507
02508
02509 tempLength -= eas->NextEntryOffset;
02510
if (tempLength < 0) {
02511 *ErrorOffset =
GET_OFFSET_LENGTH( eas, EaBuffer );
02512
return STATUS_EA_LIST_INCONSISTENT;
02513 }
02514 eas = (PFILE_FULL_EA_INFORMATION) ((PCHAR) eas + eas->NextEntryOffset);
02515
02516 }
02517
02518 }
else {
02519
02520
02521
02522
02523
02524
02525
02526 tempLength -= entrySize;
02527
break;
02528
02529 }
02530 }
02531
02532
02533
02534
02535
02536
02537
02538
if (tempLength < 0) {
02539 *ErrorOffset =
GET_OFFSET_LENGTH( eas, EaBuffer );
02540
return STATUS_EA_LIST_INCONSISTENT;
02541 }
02542
02543
return STATUS_SUCCESS;
02544 }
02545
02546
NTSTATUS
02547 IoCheckFunctionAccess(
02548 IN ACCESS_MASK GrantedAccess,
02549 IN UCHAR MajorFunction,
02550 IN UCHAR MinorFunction,
02551 IN ULONG IoControlCode,
02552 IN PVOID Arg1 OPTIONAL,
02553 IN PVOID Arg2 OPTIONAL
02554 )
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602 {
02603
NTSTATUS status = STATUS_SUCCESS;
02604 PFILE_INFORMATION_CLASS FileInformationClass;
02605 PFS_INFORMATION_CLASS FsInformationClass;
02606 SECURITY_INFORMATION SecurityInformation;
02607 ACCESS_MASK DesiredAccess;
02608
02609 UNREFERENCED_PARAMETER( MinorFunction );
02610
02611
PAGED_CODE();
02612
02613
02614
02615
02616
02617
02618 FileInformationClass = (PFILE_INFORMATION_CLASS)Arg1;
02619 FsInformationClass = (PFS_INFORMATION_CLASS)Arg2;
02620
02621
switch( MajorFunction ) {
02622
02623
case IRP_MJ_CREATE:
02624
case IRP_MJ_CLOSE:
02625
02626
break;
02627
02628
case IRP_MJ_READ:
02629
02630
if (
SeComputeDeniedAccesses( GrantedAccess, FILE_READ_DATA )) {
02631 status = STATUS_ACCESS_DENIED;
02632 }
02633
break;
02634
02635
case IRP_MJ_WRITE:
02636
02637
if (!
SeComputeGrantedAccesses( GrantedAccess, FILE_WRITE_DATA | FILE_APPEND_DATA )) {
02638 status = STATUS_ACCESS_DENIED;
02639 }
02640
break;
02641
02642
case IRP_MJ_QUERY_INFORMATION:
02643
02644
if (
IopQueryOperationAccess[*FileInformationClass] != 0) {
02645
if (
SeComputeDeniedAccesses( GrantedAccess,
IopQueryOperationAccess[*FileInformationClass] )) {
02646 status = STATUS_ACCESS_DENIED;
02647 }
02648 }
02649
break;
02650
02651
case IRP_MJ_SET_INFORMATION:
02652
02653
if (
IopSetOperationAccess[*FileInformationClass] != 0) {
02654
if (
SeComputeDeniedAccesses( GrantedAccess,
IopSetOperationAccess[*FileInformationClass] )) {
02655 status = STATUS_ACCESS_DENIED;
02656 }
02657 }
02658
break;
02659
02660
case IRP_MJ_QUERY_EA:
02661
02662
if (
SeComputeDeniedAccesses( GrantedAccess, FILE_READ_EA )) {
02663 status = STATUS_ACCESS_DENIED;
02664 }
02665
break;
02666
02667
case IRP_MJ_SET_EA:
02668
02669
if (
SeComputeDeniedAccesses( GrantedAccess, FILE_WRITE_EA )) {
02670 status = STATUS_ACCESS_DENIED;
02671 }
02672
break;
02673
02674
case IRP_MJ_FLUSH_BUFFERS:
02675
02676
if (
SeComputeDeniedAccesses( GrantedAccess, FILE_WRITE_DATA )) {
02677 status = STATUS_ACCESS_DENIED;
02678 }
02679
break;
02680
02681
case IRP_MJ_QUERY_VOLUME_INFORMATION:
02682
02683
if (
SeComputeDeniedAccesses( GrantedAccess,
IopQueryFsOperationAccess[*FsInformationClass] )) {
02684 status = STATUS_ACCESS_DENIED;
02685 }
02686
break;
02687
02688
case IRP_MJ_SET_VOLUME_INFORMATION:
02689
02690
if (
SeComputeDeniedAccesses( GrantedAccess,
IopSetFsOperationAccess[*FsInformationClass] )) {
02691 status = STATUS_ACCESS_DENIED;
02692 }
02693
break;
02694
02695
case IRP_MJ_DIRECTORY_CONTROL:
02696
02697
if (
SeComputeDeniedAccesses( GrantedAccess, FILE_LIST_DIRECTORY )) {
02698 status = STATUS_ACCESS_DENIED;
02699 }
02700
break;
02701
02702
case IRP_MJ_FILE_SYSTEM_CONTROL:
02703
case IRP_MJ_DEVICE_CONTROL:
02704
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
02705
02706 {
02707 ULONG accessMode = (IoControlCode >> 14) & 3;
02708
02709
if (accessMode != FILE_ANY_ACCESS) {
02710
02711
02712
02713
02714
02715
02716
02717
if (!(
SeComputeGrantedAccesses( GrantedAccess, accessMode ))) {
02718 status = STATUS_ACCESS_DENIED;
02719 }
02720 }
02721
02722 }
02723
break;
02724
02725
case IRP_MJ_LOCK_CONTROL:
02726
02727
if (!
SeComputeGrantedAccesses( GrantedAccess, FILE_READ_DATA | FILE_WRITE_DATA )) {
02728 status = STATUS_ACCESS_DENIED;
02729 }
02730
break;
02731
02732
case IRP_MJ_SET_SECURITY:
02733
02734 SecurityInformation = *((PSECURITY_INFORMATION)Arg1);
02735
SeSetSecurityAccessMask(SecurityInformation, &DesiredAccess);
02736
02737
if (
SeComputeDeniedAccesses( GrantedAccess, DesiredAccess )) {
02738 status = STATUS_ACCESS_DENIED;
02739 }
02740
break;
02741
02742
case IRP_MJ_QUERY_SECURITY:
02743
02744 SecurityInformation = *((PSECURITY_INFORMATION)Arg1);
02745
SeQuerySecurityAccessMask(SecurityInformation, &DesiredAccess);
02746
02747
if (
SeComputeDeniedAccesses( GrantedAccess, DesiredAccess )) {
02748 status = STATUS_ACCESS_DENIED;
02749 }
02750
break;
02751
default:
02752
02753 status = STATUS_INVALID_DEVICE_REQUEST;
02754 }
02755
return status;
02756 }
02757
02758
NTKERNELAPI
02759
NTSTATUS
02760 IoCheckQuerySetFileInformation(
02761 IN FILE_INFORMATION_CLASS FileInformationClass,
02762 IN ULONG Length,
02763 IN BOOLEAN SetOperation
02764 )
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791 {
02792 PCHAR operationLength;
02793
02794
02795
02796
02797
02798
02799
if ((ULONG) FileInformationClass >= FileMaximumInformation) {
02800
return STATUS_INVALID_INFO_CLASS;
02801 }
02802
02803
02804
02805
02806
02807 operationLength = SetOperation ?
IopSetOperationLength :
IopQueryOperationLength;
02808
02809
if (!operationLength[FileInformationClass]) {
02810
return STATUS_INVALID_INFO_CLASS;
02811 }
02812
if (Length < (ULONG) operationLength[FileInformationClass]) {
02813
return STATUS_INFO_LENGTH_MISMATCH;
02814 }
02815
02816
return STATUS_SUCCESS;
02817 }
02818
NTKERNELAPI
02819
NTSTATUS
02820 IoCheckQuerySetVolumeInformation(
02821 IN FS_INFORMATION_CLASS FsInformationClass,
02822 IN ULONG Length,
02823 IN BOOLEAN SetOperation
02824 )
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851 {
02852 PCHAR operationLength;
02853
02854 operationLength = SetOperation ?
IopSetFsOperationLength :
IopQueryFsOperationLength;
02855
02856
02857
02858
02859
02860
if ((ULONG) FsInformationClass >= FileFsMaximumInformation ||
02861 operationLength[ FsInformationClass ] == 0 ) {
02862
02863
return STATUS_INVALID_INFO_CLASS;
02864 }
02865
02866
if (Length < (ULONG) operationLength[FsInformationClass]) {
02867
return STATUS_INFO_LENGTH_MISMATCH;
02868 }
02869
02870
return STATUS_SUCCESS;
02871 }
02872
02873
NTSTATUS
02874 IoCheckQuotaBufferValidity(
02875 IN PFILE_QUOTA_INFORMATION QuotaBuffer,
02876 IN ULONG QuotaLength,
02877 OUT PULONG ErrorOffset
02878 )
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906 #
if defined(_X86_)
02907 #define
REQUIRED_QUOTA_ALIGNMENT sizeof( ULONG )
02908
#else
02909
#define REQUIRED_QUOTA_ALIGNMENT sizeof( ULONGLONG )
02910
#endif
02911
02912
#define ALIGN_QUAD( Address ) ( (ULONG) ((Address + 7) & ~7) )
02913
02914
#define GET_OFFSET_LENGTH( CurrentEntry, QuotaBase ) (\
02915
(ULONG) ((PCHAR) CurrentEntry - (PCHAR) QuotaBase) )
02916
02917 {
02918 LONG tempLength;
02919 ULONG entrySize;
02920 PFILE_QUOTA_INFORMATION quotas;
02921
02922
PAGED_CODE();
02923
02924
02925
02926
02927
02928
02929
02930 quotas = QuotaBuffer;
02931 tempLength = QuotaLength;
02932
02933
02934
02935
02936
02937
if ((ULONG_PTR) quotas & (
REQUIRED_QUOTA_ALIGNMENT - 1)) {
02938 *ErrorOffset = 0;
02939
return STATUS_DATATYPE_MISALIGNMENT;
02940 }
02941
02942
for (;;) {
02943
02944 ULONG sidLength;
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
if (tempLength < FIELD_OFFSET( FILE_QUOTA_INFORMATION, Sid ) ||
02955 !
RtlValidSid( "as->Sid )) {
02956
goto error_exit;
02957 }
02958
02959 sidLength =
RtlLengthSid( ("as->Sid) );
02960 entrySize = FIELD_OFFSET( FILE_QUOTA_INFORMATION, Sid ) + sidLength;
02961
02962
02963
02964
02965
02966
if ((ULONG) tempLength < entrySize ||
02967 quotas->SidLength != sidLength) {
02968
goto error_exit;
02969 }
02970
02971
if (quotas->NextEntryOffset) {
02972
02973
02974
02975
02976
02977
02978
02979
if (entrySize > quotas->NextEntryOffset ||
02980 quotas->NextEntryOffset & (
REQUIRED_QUOTA_ALIGNMENT - 1) ||
02981 (LONG) quotas->NextEntryOffset < 0) {
02982
goto error_exit;
02983
02984 }
else {
02985
02986
02987
02988
02989
02990
02991
02992 tempLength -= quotas->NextEntryOffset;
02993
if (tempLength < 0) {
02994
goto error_exit;
02995 }
02996 quotas = (PFILE_QUOTA_INFORMATION) ((PCHAR) quotas + quotas->NextEntryOffset);
02997 }
02998
02999 }
else {
03000
03001
03002
03003
03004
03005
03006
03007 tempLength -= entrySize;
03008
break;
03009 }
03010 }
03011
03012
03013
03014
03015
03016
03017
03018
if (tempLength < 0) {
03019
goto error_exit;
03020 }
03021
03022
return STATUS_SUCCESS;
03023
03024 error_exit:
03025
03026 *ErrorOffset =
GET_OFFSET_LENGTH( quotas, QuotaBuffer );
03027
return STATUS_QUOTA_LIST_INCONSISTENT;
03028
03029 }
03030
03031
NTSTATUS
03032 IoCheckShareAccess(
03033 IN ACCESS_MASK DesiredAccess,
03034 IN ULONG DesiredShareAccess,
03035 IN OUT
PFILE_OBJECT FileObject,
03036 IN OUT
PSHARE_ACCESS ShareAccess,
03037 IN BOOLEAN Update
03038 )
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085 {
03086 ULONG ocount;
03087
03088
PAGED_CODE();
03089
03090
03091
03092
03093
03094
03095
03096 FileObject->ReadAccess = (BOOLEAN) ((DesiredAccess & (FILE_EXECUTE
03097 | FILE_READ_DATA)) != 0);
03098 FileObject->WriteAccess = (BOOLEAN) ((DesiredAccess & (FILE_WRITE_DATA
03099 | FILE_APPEND_DATA)) != 0);
03100 FileObject->DeleteAccess = (BOOLEAN) ((DesiredAccess & DELETE) != 0);
03101
03102
03103
03104
03105
03106
03107
if (FileObject->ReadAccess ||
03108 FileObject->WriteAccess ||
03109 FileObject->DeleteAccess) {
03110
03111 FileObject->SharedRead = (BOOLEAN) ((DesiredShareAccess & FILE_SHARE_READ) != 0);
03112 FileObject->SharedWrite = (BOOLEAN) ((DesiredShareAccess & FILE_SHARE_WRITE) != 0);
03113 FileObject->SharedDelete = (BOOLEAN) ((DesiredShareAccess & FILE_SHARE_DELETE) != 0);
03114
03115
03116
03117
03118
03119
03120 ocount = ShareAccess->OpenCount;
03121
03122
if ( (FileObject->ReadAccess && (ShareAccess->SharedRead < ocount))
03123 ||
03124 (FileObject->WriteAccess && (ShareAccess->SharedWrite < ocount))
03125 ||
03126 (FileObject->DeleteAccess && (ShareAccess->SharedDelete < ocount))
03127 ||
03128 ((ShareAccess->Readers != 0) && !FileObject->SharedRead)
03129 ||
03130 ((ShareAccess->Writers != 0) && !FileObject->SharedWrite)
03131 ||
03132 ((ShareAccess->Deleters != 0) && !FileObject->SharedDelete)
03133 ) {
03134
03135
03136
03137
03138
03139
03140
return STATUS_SHARING_VIOLATION;
03141
03142
03143
03144
03145
03146
03147
03148 }
else if (Update) {
03149
03150 ShareAccess->OpenCount++;
03151
03152 ShareAccess->Readers += FileObject->ReadAccess;
03153 ShareAccess->Writers += FileObject->WriteAccess;
03154 ShareAccess->Deleters += FileObject->DeleteAccess;
03155
03156 ShareAccess->SharedRead += FileObject->SharedRead;
03157 ShareAccess->SharedWrite += FileObject->SharedWrite;
03158 ShareAccess->SharedDelete += FileObject->SharedDelete;
03159 }
03160 }
03161
return STATUS_SUCCESS;
03162 }
03163
03164
VOID
03165
FASTCALL
03166 IofCompleteRequest(
03167 IN
PIRP Irp,
03168 IN CCHAR PriorityBoost
03169 )
03170 {
03171
03172
03173
03174
03175
pIofCompleteRequest(
Irp,
PriorityBoost);
03176 }
03177
03178
VOID
03179
FASTCALL
03180 IopfCompleteRequest(
03181 IN
PIRP Irp,
03182 IN CCHAR PriorityBoost
03183 )
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247 #define
ZeroIrpStackLocation( IrpSp ) { \
03248 (IrpSp)->MinorFunction = 0; \
03249 (IrpSp)->Flags = 0; \
03250 (IrpSp)->Control = 0 ; \
03251 (IrpSp)->Parameters.Others.Argument1 = 0; \
03252 (IrpSp)->Parameters.Others.Argument2 = 0; \
03253 (IrpSp)->Parameters.Others.Argument3 = 0; \
03254 (IrpSp)->Parameters.Others.Argument4 = 0; \
03255 (IrpSp)->FileObject = (
PFILE_OBJECT)
NULL; }
03256
03257 {
03258
PIRP masterIrp;
03259
NTSTATUS status;
03260
PIO_STACK_LOCATION stackPointer;
03261
PMDL mdl;
03262
PETHREAD thread;
03263
PFILE_OBJECT fileObject;
03264 KIRQL irql;
03265 PVOID saveAuxiliaryPointer =
NULL;
03266
03267
03268
03269
03270
03271
03272
if (
Irp->
CurrentLocation > (CCHAR) (
Irp->
StackCount + 1) ||
03273
Irp->
Type !=
IO_TYPE_IRP) {
03274
KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR) Irp, __LINE__, 0, 0 );
03275 }
03276
03277
03278
03279
03280
03281
ASSERT(
Irp->
Type == IO_TYPE_IRP );
03282
03283
03284
03285
03286
03287
03288
ASSERT( !
Irp->
CancelRoutine );
03289
03290
03291
03292
03293
03294
03295
03296
03297
ASSERT(
Irp->
IoStatus.Status != STATUS_PENDING );
03298
03299
03300
03301
03302
03303
03304
03305
ASSERT(
Irp->
IoStatus.Status != 0xffffffff );
03306
03307
03308
03309
03310
03311
03312
ASSERT( !(
Irp->
Flags & IRP_PAGING_IO &&
Irp->
IoStatus.Status == STATUS_QUOTA_EXCEEDED ) );
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
for (stackPointer =
IoGetCurrentIrpStackLocation( Irp ),
03324
Irp->
CurrentLocation++,
03325
Irp->
Tail.Overlay.CurrentStackLocation++;
03326
Irp->
CurrentLocation <= (CCHAR) (
Irp->
StackCount + 1);
03327 stackPointer++,
03328
Irp->
CurrentLocation++,
03329
Irp->
Tail.Overlay.CurrentStackLocation++) {
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
Irp->
PendingReturned = stackPointer->
Control &
SL_PENDING_RETURNED;
03341
03342
if ( (
NT_SUCCESS(
Irp->
IoStatus.Status ) &&
03343 stackPointer->
Control &
SL_INVOKE_ON_SUCCESS) ||
03344 (!
NT_SUCCESS(
Irp->
IoStatus.Status ) &&
03345 stackPointer->
Control &
SL_INVOKE_ON_ERROR) ||
03346 (
Irp->
Cancel &&
03347 stackPointer->
Control &
SL_INVOKE_ON_CANCEL)
03348 ) {
03349
03350
03351
03352
03353
03354
03355
03356
ZeroIrpStackLocation( stackPointer );
03357
03358
PERFINFO_DRIVER_COMPLETIONROUTINE_CALL(Irp, stackPointer);
03359
03360 status = stackPointer->
CompletionRoutine( (
PDEVICE_OBJECT) (
Irp->
CurrentLocation == (CCHAR) (
Irp->
StackCount + 1) ?
03361 (
PDEVICE_OBJECT) NULL :
03362
IoGetCurrentIrpStackLocation( Irp )->DeviceObject),
03363 Irp,
03364 stackPointer->
Context );
03365
03366
PERFINFO_DRIVER_COMPLETIONROUTINE_RETURN(Irp, stackPointer);
03367
03368
if (status == STATUS_MORE_PROCESSING_REQUIRED) {
03369
03370
03371
03372
03373
03374
03375
03376
03377
return;
03378 }
03379
03380 }
else {
03381
if (
Irp->
PendingReturned &&
Irp->
CurrentLocation <=
Irp->
StackCount) {
03382
IoMarkIrpPending( Irp );
03383 }
03384
ZeroIrpStackLocation( stackPointer );
03385 }
03386 }
03387
03388
03389
03390
03391
03392
03393
03394
if (
Irp->
Flags &
IRP_ASSOCIATED_IRP) {
03395 ULONG count;
03396 masterIrp =
Irp->
AssociatedIrp.MasterIrp;
03397 count =
ExInterlockedAddUlong( (PULONG) &masterIrp->
AssociatedIrp.IrpCount,
03398 0xffffffff,
03399 &IopDatabaseLock );
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
Irp->
Tail.Overlay.Thread = masterIrp->
Tail.Overlay.Thread;
03413
IopFreeIrpAndMdls( Irp );
03414
if (count == 1) {
03415
IoCompleteRequest( masterIrp, PriorityBoost );
03416 }
03417
return;
03418 }
03419
03420
03421
03422
03423
03424
03425
if ((
Irp->
IoStatus.Status == STATUS_REPARSE ) &&
03426 (
Irp->
IoStatus.Information > IO_REPARSE_TAG_RESERVED_RANGE)) {
03427
03428
if (
Irp->
IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) {
03429
03430
03431
03432
03433
03434
03435
ASSERT(
Irp->
Tail.Overlay.AuxiliaryBuffer != NULL );
03436
03437 saveAuxiliaryPointer = (PVOID)
Irp->
Tail.Overlay.AuxiliaryBuffer;
03438
03439
03440
03441
03442
03443
03444
Irp->
Tail.Overlay.AuxiliaryBuffer =
NULL;
03445 }
else {
03446
03447
03448
03449
03450
03451
03452
Irp->
IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED;
03453 }
03454 }
03455
03456
03457
03458
03459
03460
03461
03462
03463
if (
Irp->
Tail.Overlay.AuxiliaryBuffer) {
03464
ExFreePool(
Irp->
Tail.Overlay.AuxiliaryBuffer );
03465
Irp->
Tail.Overlay.AuxiliaryBuffer =
NULL;
03466 }
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
if (
Irp->
Flags & (
IRP_PAGING_IO |
IRP_CLOSE_OPERATION)) {
03512
if (
Irp->
Flags & (
IRP_SYNCHRONOUS_PAGING_IO |
IRP_CLOSE_OPERATION)) {
03513 ULONG flags;
03514
03515 flags =
Irp->
Flags &
IRP_SYNCHRONOUS_PAGING_IO;
03516 *
Irp->
UserIosb =
Irp->
IoStatus;
03517 (
VOID)
KeSetEvent(
Irp->
UserEvent, PriorityBoost, FALSE );
03518
if (flags) {
03519
IoFreeIrp( Irp );
03520 }
03521 }
else {
03522 thread =
Irp->
Tail.Overlay.Thread;
03523
KeInitializeApc( &
Irp->
Tail.Apc,
03524 &thread->
Tcb,
03525
Irp->
ApcEnvironment,
03526 IopCompletePageWrite,
03527 (PKRUNDOWN_ROUTINE) NULL,
03528 (PKNORMAL_ROUTINE) NULL,
03529 KernelMode,
03530 (PVOID) NULL );
03531 (
VOID)
KeInsertQueueApc( &
Irp->
Tail.Apc,
03532 (PVOID) NULL,
03533 (PVOID) NULL,
03534 PriorityBoost );
03535 }
03536
return;
03537 }
03538
03539
03540
03541
03542
03543
if (
Irp->
MdlAddress !=
NULL) {
03544
03545
03546
03547
03548
03549 mdl =
Irp->
MdlAddress;
03550
while (mdl !=
NULL) {
03551
MmUnlockPages( mdl );
03552 mdl = mdl->
Next;
03553 }
03554 }
03555
03556
03557
03558
03559
03560
03561
03562
03563
if (
Irp->
Flags &
IRP_DEFER_IO_COMPLETION && !
Irp->
PendingReturned) {
03564
03565
if ((
Irp->
IoStatus.Status == STATUS_REPARSE ) &&
03566 (
Irp->
IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) {
03567
03568
03569
03570
03571
03572
03573
Irp->
Tail.Overlay.AuxiliaryBuffer = saveAuxiliaryPointer;
03574 }
03575
03576
return;
03577 }
03578
03579
03580
03581
03582
03583
03584 thread =
Irp->
Tail.Overlay.Thread;
03585 fileObject =
Irp->
Tail.Overlay.OriginalFileObject;
03586
03587
if (!
Irp->
Cancel) {
03588
03589
KeInitializeApc( &
Irp->
Tail.Apc,
03590 &thread->
Tcb,
03591
Irp->
ApcEnvironment,
03592 IopCompleteRequest,
03593 IopAbortRequest,
03594 (PKNORMAL_ROUTINE) NULL,
03595 KernelMode,
03596 (PVOID) NULL );
03597
03598 (
VOID)
KeInsertQueueApc( &
Irp->
Tail.Apc,
03599 fileObject,
03600 (PVOID) saveAuxiliaryPointer,
03601 PriorityBoost );
03602 }
else {
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618 ExAcquireSpinLock( &IopCompletionLock, &irql );
03619
03620 thread =
Irp->
Tail.Overlay.Thread;
03621
03622
if (thread) {
03623
03624
KeInitializeApc( &
Irp->
Tail.Apc,
03625 &thread->
Tcb,
03626
Irp->
ApcEnvironment,
03627 IopCompleteRequest,
03628 IopAbortRequest,
03629 (PKNORMAL_ROUTINE) NULL,
03630 KernelMode,
03631 (PVOID) NULL );
03632
03633 (
VOID)
KeInsertQueueApc( &
Irp->
Tail.Apc,
03634 fileObject,
03635 (PVOID) saveAuxiliaryPointer,
03636 PriorityBoost );
03637
03638 ExReleaseSpinLock( &IopCompletionLock, irql );
03639
03640 }
else {
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650 ExReleaseSpinLock( &IopCompletionLock, irql );
03651
03652
ASSERT(
Irp->
Cancel );
03653
03654
03655
03656
03657
03658
IopDropIrp( Irp, fileObject );
03659
03660 }
03661 }
03662 }
03663
03664
NTSTATUS
03665 IoConnectInterrupt(
03666 OUT
PKINTERRUPT *InterruptObject,
03667 IN PKSERVICE_ROUTINE ServiceRoutine,
03668 IN PVOID ServiceContext,
03669 IN PKSPIN_LOCK SpinLock OPTIONAL,
03670 IN ULONG Vector,
03671 IN KIRQL Irql,
03672 IN KIRQL SynchronizeIrql,
03673 IN KINTERRUPT_MODE InterruptMode,
03674 IN BOOLEAN ShareVector,
03675 IN KAFFINITY ProcessorEnableMask,
03676 IN BOOLEAN FloatingSave
03677 )
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733 {
03734 CCHAR count;
03735 BOOLEAN builtinUsed;
03736
PKINTERRUPT interruptObject;
03737 ULONG processorMask;
03738
NTSTATUS status;
03739
PIO_INTERRUPT_STRUCTURE interruptStructure;
03740 PKSPIN_LOCK spinLock;
03741
03742
PAGED_CODE();
03743
03744
03745
03746
03747
03748 *
InterruptObject = (
PKINTERRUPT)
NULL;
03749 status = STATUS_SUCCESS;
03750
03751
03752
03753
03754
03755
03756
03757 processorMask = ProcessorEnableMask &
KeActiveProcessors;
03758 count = 0;
03759
03760
while (processorMask) {
03761
if (processorMask & 1) {
03762 count++;
03763 }
03764 processorMask >>= 1;
03765 }
03766
03767
03768
03769
03770
03771
03772
if (count) {
03773 interruptStructure =
ExAllocatePoolWithTag(
NonPagedPool,
03774 ((count - 1) *
sizeof(
KINTERRUPT )) +
03775
sizeof(
IO_INTERRUPT_STRUCTURE ),
03776 'nioI' );
03777
if (interruptStructure ==
NULL) {
03778 status = STATUS_INSUFFICIENT_RESOURCES;
03779 }
03780 }
else {
03781 status = STATUS_INVALID_PARAMETER;
03782 }
03783
03784
03785
03786
03787
03788
03789
03790
if (ARGUMENT_PRESENT( SpinLock )) {
03791 spinLock = SpinLock;
03792 }
else {
03793 spinLock = &interruptStructure->
SpinLock;
03794 }
03795
03796
03797
03798
03799
03800
03801
if (
NT_SUCCESS( status )) {
03802
03803
03804
03805
03806
03807
03808
03809 *
InterruptObject = &interruptStructure->
InterruptObject;
03810
03811
03812
03813
03814
03815
03816 interruptObject = (
PKINTERRUPT) (interruptStructure + 1);
03817 builtinUsed =
FALSE;
03818 processorMask = ProcessorEnableMask &
KeActiveProcessors;
03819
03820
03821
03822
03823
03824
03825 RtlZeroMemory( interruptStructure,
sizeof(
IO_INTERRUPT_STRUCTURE ) );
03826
03827
03828
03829
03830
03831
03832
03833
03834
for (count = 0; processorMask; count++, processorMask >>= 1) {
03835
if (processorMask & 1) {
03836
KeInitializeInterrupt( builtinUsed ?
03837 interruptObject :
03838 &interruptStructure->
InterruptObject,
03839 ServiceRoutine,
03840 ServiceContext,
03841 spinLock,
03842 Vector,
03843 Irql,
03844 SynchronizeIrql,
03845 InterruptMode,
03846 ShareVector,
03847 count,
03848 FloatingSave );
03849
03850
if (!
KeConnectInterrupt( builtinUsed ?
03851 interruptObject :
03852 &interruptStructure->
InterruptObject )) {
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
if (builtinUsed) {
03871
IoDisconnectInterrupt( &interruptStructure->
InterruptObject );
03872 }
else {
03873
ExFreePool( interruptStructure );
03874 }
03875 status = STATUS_INVALID_PARAMETER;
03876
break;
03877 }
03878
03879
03880
03881
03882
03883
03884
03885
03886
if (builtinUsed) {
03887 interruptStructure->
InterruptArray[count] = interruptObject++;
03888
03889 }
else {
03890
03891
03892
03893
03894
03895
03896
03897 builtinUsed =
TRUE;
03898 }
03899
03900 }
03901 }
03902 }
03903
03904
03905
03906
03907
03908
03909
if (!
NT_SUCCESS( status )) {
03910 *
InterruptObject = (
PKINTERRUPT)
NULL;
03911 }
03912
03913
return status;
03914 }
03915
03916
PCONTROLLER_OBJECT
03917 IoCreateController(
03918 IN ULONG Size
03919 )
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938 {
03939 OBJECT_ATTRIBUTES objectAttributes;
03940
PCONTROLLER_OBJECT controllerObject;
03941 HANDLE handle;
03942
NTSTATUS status;
03943
03944
PAGED_CODE();
03945
03946
03947
03948
03949
03950
03951 InitializeObjectAttributes( &objectAttributes,
03952 (PUNICODE_STRING)
NULL,
03953 0,
03954 (HANDLE)
NULL,
03955 (PSECURITY_DESCRIPTOR)
NULL );
03956
03957
03958
03959
03960
03961 status =
ObCreateObject(
KernelMode,
03962
IoControllerObjectType,
03963 &objectAttributes,
03964
KernelMode,
03965 (PVOID)
NULL,
03966 (ULONG)
sizeof(
CONTROLLER_OBJECT ) +
Size,
03967 0,
03968 0,
03969 (PVOID *) &controllerObject );
03970
if (
NT_SUCCESS( status )) {
03971
03972
03973
03974
03975
03976 status =
ObInsertObject( controllerObject,
03977
NULL,
03978 FILE_READ_DATA | FILE_WRITE_DATA,
03979 1,
03980 (PVOID *) &controllerObject,
03981 &handle );
03982
03983
03984
03985
03986
03987
if (!
NT_SUCCESS( status )) {
03988 controllerObject = (
PCONTROLLER_OBJECT)
NULL;
03989 }
else {
03990
03991
03992
03993
03994
03995
03996 (
VOID)
NtClose( handle );
03997
03998
03999
04000
04001
04002 RtlZeroMemory( controllerObject,
sizeof(
CONTROLLER_OBJECT ) +
Size );
04003
04004
04005
04006
04007
04008 controllerObject->Type =
IO_TYPE_CONTROLLER;
04009 controllerObject->Size = (
USHORT) (
sizeof(
CONTROLLER_OBJECT ) +
Size);
04010 controllerObject->ControllerExtension = (PVOID) (controllerObject + 1);
04011
04012
04013
04014
04015
04016
KeInitializeDeviceQueue( &controllerObject->DeviceWaitQueue );
04017 }
04018 }
else {
04019 controllerObject = (
PCONTROLLER_OBJECT)
NULL;
04020 }
04021
04022
return controllerObject;
04023 }
04024
04025
VOID
04026 IopInsertRemoveDevice(
04027 IN
PDRIVER_OBJECT DriverObject,
04028 IN
PDEVICE_OBJECT DeviceObject,
04029 IN BOOLEAN Insert
04030 )
04031
04032 {
04033 KIRQL irql;
04034
04035 ExAcquireSpinLock( &
IopDatabaseLock, &irql );
04036
if (Insert) {
04037 DeviceObject->NextDevice = DriverObject->DeviceObject;
04038 DriverObject->DeviceObject = DeviceObject;
04039 }
04040
else {
04041
PDEVICE_OBJECT *prevPoint;
04042
04043 prevPoint = &DeviceObject->
DriverObject->
DeviceObject;
04044
while (*prevPoint != DeviceObject) {
04045 prevPoint = &(*prevPoint)->
NextDevice;
04046 }
04047 *prevPoint = DeviceObject->
NextDevice;
04048 }
04049 ExReleaseSpinLock( &
IopDatabaseLock, irql );
04050 }
04051
04052
VOID
04053 IopCreateVpb (
04054 IN
PDEVICE_OBJECT DeviceObject
04055 )
04056 {
04057
PVPB Vpb;
04058
04059 Vpb =
ExAllocatePoolWithTag(
04060
NonPagedPoolMustSucceed,
04061
sizeof(
VPB ),
04062 ' bpV'
04063 );
04064
04065 RtlZeroMemory (Vpb,
sizeof(
VPB));
04066 Vpb->
Type =
IO_TYPE_VPB;
04067 Vpb->
Size =
sizeof(
VPB );
04068 Vpb->
RealDevice = DeviceObject;
04069 DeviceObject->
Vpb = Vpb;
04070 }
04071
04072
NTSTATUS
04073 IoCreateDevice(
04074 IN
PDRIVER_OBJECT DriverObject,
04075 IN ULONG DeviceExtensionSize,
04076 IN PUNICODE_STRING DeviceName OPTIONAL,
04077 IN DEVICE_TYPE DeviceType,
04078 IN ULONG DeviceCharacteristics,
04079 IN BOOLEAN Exclusive,
04080 OUT
PDEVICE_OBJECT *DeviceObject
04081 )
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125 {
04126 OBJECT_ATTRIBUTES objectAttributes;
04127
PDEVICE_OBJECT deviceObject;
04128
PDEVOBJ_EXTENSION deviceObjectExt;
04129 HANDLE handle;
04130 BOOLEAN deviceHasName;
04131
CHAR localSecurityDescriptor[SECURITY_DESCRIPTOR_MIN_LENGTH];
04132 PSECURITY_DESCRIPTOR securityDescriptor;
04133 PACL acl;
04134 PACE_HEADER ace;
04135 PSID sid;
04136 PACCESS_MASK mask;
04137 ULONG i;
04138 ULONG RoundedSize;
04139
NTSTATUS status;
04140
USHORT sectorSize = 0;
04141 LONG nextUniqueDeviceObjectNumber;
04142 UNICODE_STRING autoGeneratedDeviceName;
04143 BOOLEAN retryWithNewName =
FALSE;
04144 WCHAR deviceNameBuffer[17];
04145
04146
PAGED_CODE();
04147
04148 acl =
NULL;
04149
04150
04151
04152
04153
04154
04155
04156
do {
04157
04158
if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME) {
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168 nextUniqueDeviceObjectNumber = InterlockedIncrement( &
IopUniqueDeviceObjectNumber );
04169 swprintf( deviceNameBuffer,
L"\\Device\\%08lx", nextUniqueDeviceObjectNumber );
04170
04171
if (retryWithNewName) {
04172
04173
04174
04175
04176
04177
04178
04179
04180 retryWithNewName =
FALSE;
04181
goto attemptDeviceObjectCreation;
04182
04183 }
else {
04184
04185
04186
04187
04188
04189
04190
04191
04192
RtlInitUnicodeString( &autoGeneratedDeviceName, deviceNameBuffer );
04193 DeviceName = &autoGeneratedDeviceName;
04194 }
04195 }
04196
04197
04198
04199
04200
04201
04202 deviceHasName = (BOOLEAN) (ARGUMENT_PRESENT( DeviceName ) ?
TRUE :
FALSE);
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222 securityDescriptor =
IopCreateDefaultDeviceSecurityDescriptor(
04223 DeviceType,
04224 DeviceCharacteristics,
04225 deviceHasName,
04226 localSecurityDescriptor,
04227 &acl,
04228
NULL);
04229
04230
switch ( DeviceType ) {
04231
04232
case FILE_DEVICE_DISK_FILE_SYSTEM:
04233
04234 sectorSize = 512;
04235
break;
04236
04237
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
04238
04239 sectorSize = 2048;
04240
break;
04241
04242
case FILE_DEVICE_DISK:
04243
case FILE_DEVICE_VIRTUAL_DISK:
04244
04245 sectorSize = 512;
04246
break;
04247 }
04248
04249 attemptDeviceObjectCreation:
04250
04251
04252
04253
04254
04255
04256
04257
04258 InitializeObjectAttributes( &objectAttributes,
04259 DeviceName,
04260 0,
04261 (HANDLE)
NULL,
04262 securityDescriptor );
04263
04264
04265
if (Exclusive) {
04266 objectAttributes.Attributes |= OBJ_EXCLUSIVE;
04267 }
else {
04268 objectAttributes.Attributes |= 0;
04269 }
04270
04271
if (deviceHasName) {
04272 objectAttributes.Attributes |= OBJ_PERMANENT;
04273 }
04274
04275
04276
04277
04278
04279 RoundedSize = (
sizeof(
DEVICE_OBJECT ) + DeviceExtensionSize)
04280 %
sizeof (LONGLONG);
04281
if (RoundedSize) {
04282 RoundedSize =
sizeof (LONGLONG) - RoundedSize;
04283 }
04284
04285 RoundedSize += DeviceExtensionSize;
04286
04287 status =
ObCreateObject(
KernelMode,
04288
IoDeviceObjectType,
04289 &objectAttributes,
04290
KernelMode,
04291 (PVOID)
NULL,
04292 (ULONG)
sizeof(
DEVICE_OBJECT ) +
sizeof (
DEVOBJ_EXTENSION ) +
04293 RoundedSize,
04294 0,
04295 0,
04296 (PVOID *) &deviceObject );
04297
04298
if ((status == STATUS_OBJECT_NAME_COLLISION) &&
04299 (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME)) {
04300
04301
04302
04303
04304
04305
04306 retryWithNewName =
TRUE;
04307 }
04308
04309 }
while (retryWithNewName);
04310
04311
if (!
NT_SUCCESS( status )) {
04312
04313
04314
04315
04316
04317
04318 deviceObject = (
PDEVICE_OBJECT)
NULL;
04319
04320 }
else {
04321
04322
04323
04324
04325
04326
04327
04328 RtlZeroMemory( deviceObject,
04329
sizeof(
DEVICE_OBJECT ) +
sizeof (
DEVOBJ_EXTENSION ) +
04330 RoundedSize );
04331
04332
04333
04334
04335
04336 deviceObjectExt = (
PDEVOBJ_EXTENSION) (((PCHAR) deviceObject) +
04337
sizeof (
DEVICE_OBJECT) + RoundedSize);
04338
04339 deviceObjectExt->
DeviceObject = deviceObject;
04340 deviceObject->
DeviceObjectExtension = deviceObjectExt;
04341
04342
04343
04344
04345
04346
04347
04348 deviceObjectExt->
Type =
IO_TYPE_DEVICE_OBJECT_EXTENSION;
04349 deviceObjectExt->
Size = 0;
04350
04351
PoInitializeDeviceObject(deviceObjectExt);
04352
04353
04354
04355
04356
04357 deviceObject->
Type =
IO_TYPE_DEVICE;
04358 deviceObject->
Size = (
USHORT) (
sizeof(
DEVICE_OBJECT ) + DeviceExtensionSize);
04359
04360
04361
04362
04363
04364
04365 deviceObject->
DeviceType = DeviceType;
04366 deviceObject->
Characteristics = DeviceCharacteristics;
04367
04368
04369
04370
04371
04372
04373
04374
04375
if ((DeviceType == FILE_DEVICE_DISK) ||
04376 (DeviceType == FILE_DEVICE_TAPE) ||
04377 (DeviceType == FILE_DEVICE_CD_ROM) ||
04378 (DeviceType == FILE_DEVICE_VIRTUAL_DISK)) {
04379
04380
IopCreateVpb (deviceObject);
04381
KeInitializeEvent( &deviceObject->
DeviceLock,
04382 SynchronizationEvent,
04383
TRUE );
04384 }
04385
04386
04387
04388
04389 deviceObject->
AlignmentRequirement = HalGetDmaAlignmentRequirement() - 1;
04390 deviceObject->
SectorSize = sectorSize;
04391 deviceObject->
Flags =
DO_DEVICE_INITIALIZING;
04392
04393
if (Exclusive) {
04394 deviceObject->
Flags |=
DO_EXCLUSIVE;
04395 }
04396
if (deviceHasName) {
04397 deviceObject->
Flags |=
DO_DEVICE_HAS_NAME;
04398 }
04399
04400
if(DeviceExtensionSize) {
04401 deviceObject->
DeviceExtension = deviceObject + 1;
04402 }
else {
04403 deviceObject->
DeviceExtension =
NULL;
04404 }
04405
04406 deviceObject->
StackSize = 1;
04407
switch ( DeviceType ) {
04408
04409
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
04410
case FILE_DEVICE_DISK_FILE_SYSTEM:
04411
case FILE_DEVICE_FILE_SYSTEM:
04412
case FILE_DEVICE_NETWORK_FILE_SYSTEM:
04413
case FILE_DEVICE_TAPE_FILE_SYSTEM:
04414
04415
04416
04417
04418
04419
04420 InitializeListHead( &deviceObject->
Queue.ListEntry );
04421
break;
04422
04423
default:
04424
04425
04426
04427
04428
04429
04430
KeInitializeDeviceQueue( &deviceObject->
DeviceQueue );
04431
break;
04432 }
04433
04434
04435
04436
04437
04438 status =
ObInsertObject( deviceObject,
04439
NULL,
04440 FILE_READ_DATA | FILE_WRITE_DATA,
04441 1,
04442 (PVOID *) &deviceObject,
04443 &handle );
04444
04445
if (
NT_SUCCESS( status )) {
04446
04447
04448
04449
04450
04451
04452
04453
04454
ObReferenceObject( DriverObject );
04455
04456
ASSERT((DriverObject->Flags &
DRVO_UNLOAD_INVOKED) == 0);
04457
04458
04459
04460
04461
04462
04463
04464 deviceObject->DriverObject = DriverObject;
04465
04466
IopInsertRemoveDevice( DriverObject, deviceObject,
TRUE );
04467
if (deviceObject->Vpb) {
04468
PoVolumeDevice(deviceObject);
04469 }
04470
04471 (
VOID)
NtClose( handle );
04472
04473 }
else {
04474
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485 deviceObject = (
PDEVICE_OBJECT)
NULL;
04486 }
04487 }
04488
04489
04490
04491
04492
04493
if (acl !=
NULL) {
04494
ExFreePool( acl );
04495 }
04496
04497 *DeviceObject = deviceObject;
04498
return status;
04499 }
04500
04501
NTSTATUS
04502 IoCreateFile(
04503 OUT PHANDLE FileHandle,
04504 IN ACCESS_MASK DesiredAccess,
04505 IN POBJECT_ATTRIBUTES ObjectAttributes,
04506 OUT PIO_STATUS_BLOCK IoStatusBlock,
04507 IN PLARGE_INTEGER AllocationSize OPTIONAL,
04508 IN ULONG FileAttributes,
04509 IN ULONG ShareAccess,
04510 IN ULONG Disposition,
04511 IN ULONG CreateOptions,
04512 IN PVOID EaBuffer OPTIONAL,
04513 IN ULONG EaLength,
04514 IN CREATE_FILE_TYPE CreateFileType,
04515 IN PVOID ExtraCreateParameters OPTIONAL,
04516 IN ULONG Options
04517 )
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583 {
04584
KPROCESSOR_MODE requestorMode;
04585
NTSTATUS status;
04586 HANDLE handle;
04587
OPEN_PACKET openPacket;
04588 BOOLEAN SuccessfulIoParse;
04589 LARGE_INTEGER initialAllocationSize;
04590
04591
PAGED_CODE();
04592
04593
04594
04595
04596
04597 requestorMode = KeGetPreviousMode();
04598
04599
if (Options &
IO_NO_PARAMETER_CHECKING) {
04600 requestorMode =
KernelMode;
04601 }
04602
04603
if (requestorMode !=
KernelMode || Options &
IO_CHECK_CREATE_PARAMETERS) {
04604
04605
04606
04607
04608
04609
if (
04610
04611
04612
04613
04614
04615
04616 (
FileAttributes & ~FILE_ATTRIBUTE_VALID_FLAGS)
04617
04618 ||
04619
04620
04621
04622
04623
04624 (ShareAccess & ~FILE_SHARE_VALID_FLAGS)
04625
04626 ||
04627
04628
04629
04630
04631
04632 (Disposition > FILE_MAXIMUM_DISPOSITION)
04633
04634 ||
04635
04636
04637
04638
04639
04640 (CreateOptions & ~FILE_VALID_OPTION_FLAGS)
04641
04642 ||
04643
04644
04645
04646
04647
04648
04649
04650 (CreateOptions & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT) &&
04651 (!(DesiredAccess & SYNCHRONIZE)))
04652
04653 ||
04654
04655
04656
04657
04658
04659
04660
04661 (CreateOptions & FILE_DELETE_ON_CLOSE &&
04662 (!(DesiredAccess & DELETE)))
04663
04664 ||
04665
04666
04667
04668
04669
04670
04671 ((CreateOptions & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) ==
04672 (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
04673
04674 ||
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692 ((CreateOptions & FILE_DIRECTORY_FILE)
04693 && !(CreateOptions & FILE_NON_DIRECTORY_FILE)
04694 && ((CreateOptions & ~(FILE_DIRECTORY_FILE |
04695 FILE_SYNCHRONOUS_IO_ALERT |
04696 FILE_SYNCHRONOUS_IO_NONALERT |
04697 FILE_WRITE_THROUGH |
04698 FILE_COMPLETE_IF_OPLOCKED |
04699 FILE_OPEN_FOR_BACKUP_INTENT |
04700 FILE_DELETE_ON_CLOSE |
04701 FILE_OPEN_FOR_FREE_SPACE_QUERY |
04702 FILE_OPEN_BY_FILE_ID |
04703 FILE_OPEN_REPARSE_POINT))
04704 || ((Disposition != FILE_CREATE)
04705 && (Disposition != FILE_OPEN)
04706 && (Disposition != FILE_OPEN_IF))
04707 )
04708 )
04709
04710 ||
04711
04712
04713
04714
04715
04716
04717 ((CreateOptions & FILE_COMPLETE_IF_OPLOCKED) &&
04718 (CreateOptions & FILE_RESERVE_OPFILTER))
04719
04720 ||
04721
04722
04723
04724
04725
04726
04727
04728 (CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING &&
04729 (DesiredAccess & FILE_APPEND_DATA)) ) {
04730
04731
return STATUS_INVALID_PARAMETER;
04732 }
04733
04734
04735
04736
04737
04738
if (CreateFileType ==
CreateFileTypeNone) {
04739
04740 NOTHING;
04741
04742 }
else if (CreateFileType ==
CreateFileTypeNamedPipe) {
04743
04744
if (!ARGUMENT_PRESENT( ExtraCreateParameters ) ) {
04745
04746
return STATUS_INVALID_PARAMETER;
04747
04748 }
else {
04749
04750
PNAMED_PIPE_CREATE_PARAMETERS NamedPipeCreateParameters;
04751
04752 NamedPipeCreateParameters = ExtraCreateParameters;
04753
04754
04755
04756
04757
04758
04759
if (
04760
04761
04762
04763
04764
04765
04766 (NamedPipeCreateParameters->
NamedPipeType >
04767 FILE_PIPE_MESSAGE_TYPE)
04768
04769 ||
04770
04771
04772
04773
04774
04775
04776 (NamedPipeCreateParameters->
ReadMode >
04777 FILE_PIPE_MESSAGE_MODE)
04778
04779 ||
04780
04781
04782
04783
04784
04785
04786 (NamedPipeCreateParameters->
CompletionMode >
04787 FILE_PIPE_COMPLETE_OPERATION)
04788
04789 ||
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799
04800 (ShareAccess & FILE_SHARE_DELETE)
04801
04802 ||
04803
04804
04805
04806
04807
04808
04809
04810 (Disposition < FILE_OPEN || Disposition > FILE_OPEN_IF)
04811
04812 ||
04813
04814
04815
04816
04817
04818
04819
04820 (CreateOptions & ~FILE_VALID_PIPE_OPTION_FLAGS)) {
04821
return STATUS_INVALID_PARAMETER;
04822 }
04823
04824 }
04825
04826 }
else if (CreateFileType ==
CreateFileTypeMailslot) {
04827
04828
if (!ARGUMENT_PRESENT( ExtraCreateParameters ) ) {
04829
04830
return STATUS_INVALID_PARAMETER;
04831
04832 }
else {
04833
04834
PMAILSLOT_CREATE_PARAMETERS mailslotCreateParameters;
04835
04836 mailslotCreateParameters = ExtraCreateParameters;
04837
04838
04839
04840
04841
04842
04843
if (
04844
04845
04846
04847
04848
04849
04850 (ShareAccess & FILE_SHARE_DELETE)
04851
04852 ||
04853
04854
04855
04856
04857
04858
04859 !(ShareAccess & ~FILE_SHARE_WRITE)
04860
04861 ||
04862
04863
04864
04865
04866
04867
04868 (Disposition != FILE_CREATE)
04869
04870 ||
04871
04872
04873
04874
04875
04876
04877
04878 (CreateOptions & ~FILE_VALID_MAILSLOT_OPTION_FLAGS)) {
04879
return STATUS_INVALID_PARAMETER;
04880 }
04881 }
04882 }
04883 }
04884
04885
if (requestorMode !=
KernelMode) {
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895 openPacket.
EaBuffer = (PFILE_FULL_EA_INFORMATION)
NULL;
04896
04897
try {
04898
04899
04900
04901
04902
04903
04904
ProbeAndWriteHandle( FileHandle, 0
L );
04905
04906
04907
04908
04909
04910
ProbeForWriteIoStatus( IoStatusBlock );
04911
04912
04913
04914
04915
04916
04917
if (ARGUMENT_PRESENT( AllocationSize )) {
04918
ProbeForRead( AllocationSize,
04919
sizeof( LARGE_INTEGER ),
04920
sizeof( ULONG ) );
04921 initialAllocationSize = *AllocationSize;
04922 }
else {
04923 initialAllocationSize.QuadPart = 0;
04924 }
04925
04926 } except(
EXCEPTION_EXECUTE_HANDLER) {
04927
04928
04929
04930
04931
04932
04933
04934
return GetExceptionCode();
04935 }
04936
04937
04938
04939
04940
04941
04942
if (ARGUMENT_PRESENT( EaBuffer ) && EaLength) {
04943
04944 ULONG errorOffset;
04945
04946
try {
04947
04948
ProbeForRead( EaBuffer, EaLength,
sizeof( ULONG ) );
04949 openPacket.
EaBuffer =
ExAllocatePoolWithQuotaTag(
NonPagedPool,
04950 EaLength,
04951 'aEoI' );
04952 openPacket.
EaLength = EaLength;
04953 RtlCopyMemory( openPacket.
EaBuffer, EaBuffer, EaLength );
04954
04955
04956
04957
04958
04959
04960 status =
IoCheckEaBufferValidity( openPacket.
EaBuffer,
04961 EaLength,
04962 &errorOffset );
04963
04964
if (!
NT_SUCCESS( status )) {
04965 IoStatusBlock->Status = status;
04966 IoStatusBlock->Information = errorOffset;
04967
ExRaiseStatus( status );
04968 }
04969
04970 } except(
EXCEPTION_EXECUTE_HANDLER) {
04971
04972
04973
04974
04975
04976
04977
04978
if (openPacket.
EaBuffer !=
NULL) {
04979
ExFreePool( openPacket.
EaBuffer );
04980 }
04981
04982
return GetExceptionCode();
04983
04984 }
04985
04986 }
else {
04987
04988
04989
04990
04991
04992 openPacket.
EaBuffer = (PVOID)
NULL;
04993 openPacket.
EaLength = 0
L;
04994 }
04995
04996 }
else {
04997
04998
04999
05000
05001
05002
05003
05004
if (CreateOptions &
IO_ATTACH_DEVICE_API) {
05005 Options |=
IO_ATTACH_DEVICE;
05006 CreateOptions &= ~
IO_ATTACH_DEVICE_API;
05007
05008 }
05009
05010
if (ARGUMENT_PRESENT( AllocationSize )) {
05011 initialAllocationSize = *AllocationSize;
05012 }
else {
05013 initialAllocationSize.QuadPart = 0;
05014 }
05015
05016
if (ARGUMENT_PRESENT( EaBuffer ) && EaLength) {
05017
05018 ULONG errorOffset;
05019
05020 openPacket.
EaBuffer =
ExAllocatePoolWithTag(
NonPagedPool,
05021 EaLength,
05022 'aEoI' );
05023
if (!openPacket.
EaBuffer) {
05024
return STATUS_INSUFFICIENT_RESOURCES;
05025 }
05026 openPacket.
EaLength = EaLength;
05027 RtlCopyMemory( openPacket.
EaBuffer, EaBuffer, EaLength );
05028
05029
05030
05031
05032
05033
05034 status =
IoCheckEaBufferValidity( openPacket.
EaBuffer,
05035 EaLength,
05036 &errorOffset );
05037
05038
if (!
NT_SUCCESS( status )) {
05039
ExFreePool(openPacket.
EaBuffer);
05040 IoStatusBlock->Status = status;
05041 IoStatusBlock->Information = errorOffset;
05042
return status;
05043 }
05044
05045 }
else {
05046 openPacket.
EaBuffer = (PVOID)
NULL;
05047 openPacket.
EaLength = 0
L;
05048 }
05049 }
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060 openPacket.
Type =
IO_TYPE_OPEN_PACKET;
05061 openPacket.
Size =
sizeof(
OPEN_PACKET );
05062 openPacket.
ParseCheck = 0
L;
05063 openPacket.
AllocationSize = initialAllocationSize;
05064 openPacket.
CreateOptions = CreateOptions;
05065 openPacket.
FileAttributes = (
USHORT)
FileAttributes;
05066 openPacket.
ShareAccess = (
USHORT) ShareAccess;
05067 openPacket.
Disposition = Disposition;
05068 openPacket.
Override =
FALSE;
05069 openPacket.
QueryOnly =
FALSE;
05070 openPacket.
DeleteOnly =
FALSE;
05071 openPacket.
Options = Options;
05072 openPacket.
RelatedFileObject = (
PFILE_OBJECT)
NULL;
05073 openPacket.
CreateFileType = CreateFileType;
05074 openPacket.
ExtraCreateParameters = ExtraCreateParameters;
05075
05076
05077
05078
05079
05080 openPacket.
FinalStatus = STATUS_SUCCESS;
05081
05082
05083
05084
05085
05086
05087
05088 openPacket.
FileObject = (
PFILE_OBJECT)
NULL;
05089
05090
05091
05092
05093
05094
IopUpdateOtherOperationCount();
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110 status =
ObOpenObjectByName(
ObjectAttributes,
05111 (
POBJECT_TYPE)
NULL,
05112 requestorMode,
05113
NULL,
05114 DesiredAccess,
05115 &openPacket,
05116 &handle );
05117
05118
05119
05120
05121
05122
05123
05124
if (openPacket.
EaBuffer) {
05125
ExFreePool( openPacket.
EaBuffer );
05126 }
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140 SuccessfulIoParse = (BOOLEAN) (openPacket.
ParseCheck ==
OPEN_PACKET_PATTERN);
05141
05142
if (!
NT_SUCCESS( status ) || !SuccessfulIoParse) {
05143
05144
if (
NT_SUCCESS( status )) {
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157 ZwClose( handle );
05158 status = STATUS_OBJECT_TYPE_MISMATCH;
05159 }
05160
05161
05162
05163
05164
05165
05166
05167
05168
if (!
NT_SUCCESS( openPacket.
FinalStatus )) {
05169 status = openPacket.
FinalStatus;
05170
05171
if (
NT_WARNING( status )) {
05172
05173
try {
05174
05175 IoStatusBlock->Status = openPacket.
FinalStatus;
05176 IoStatusBlock->Information = openPacket.
Information;
05177
05178 } except(
EXCEPTION_EXECUTE_HANDLER) {
05179
05180 status = GetExceptionCode();
05181
05182 }
05183
05184 }
05185
05186 }
else if (openPacket.
FileObject !=
NULL && !SuccessfulIoParse) {
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
if (openPacket.
FileObject->
FileName.Length != 0) {
05209
ExFreePool( openPacket.
FileObject->
FileName.Buffer );
05210 }
05211 openPacket.
FileObject->
DeviceObject = (
PDEVICE_OBJECT)
NULL;
05212
ObDereferenceObject( openPacket.
FileObject );
05213 }
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
if ((status == STATUS_OBJECT_NAME_NOT_FOUND) &&
05235 (openPacket.
Information == IO_REPARSE_TAG_MOUNT_POINT)) {
05236
05237 status = STATUS_REPARSE_POINT_NOT_RESOLVED;
05238 }
05239
05240 }
else {
05241
05242
05243
05244
05245
05246
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258 openPacket.
FileObject->
Flags |=
FO_HANDLE_CREATED;
05259
05260
ASSERT( openPacket.
FileObject->
Type ==
IO_TYPE_FILE );
05261
05262
try {
05263
05264
05265
05266
05267
05268 *FileHandle = handle;
05269
05270
05271
05272
05273
05274 IoStatusBlock->Information = openPacket.
Information;
05275 IoStatusBlock->Status = openPacket.
FinalStatus;
05276 status = openPacket.
FinalStatus;
05277
05278 } except(
EXCEPTION_EXECUTE_HANDLER) {
05279
05280 status = GetExceptionCode();
05281
05282 }
05283
05284 }
05285
05286
05287
05288
05289
05290
05291
if (SuccessfulIoParse && openPacket.
FileObject !=
NULL) {
05292
ObDereferenceObject( openPacket.
FileObject );
05293 }
05294
05295
return status;
05296 }
05297
05298
PKEVENT
05299 IoCreateNotificationEvent(
05300 IN PUNICODE_STRING EventName,
05301 OUT PHANDLE EventHandle
05302 )
05303
05304
05305
05306
05307
05308
05309
05310
05311
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324 {
05325 OBJECT_ATTRIBUTES objectAttributes;
05326
NTSTATUS status;
05327 HANDLE eventHandle;
05328
PKEVENT eventObject;
05329
05330
PAGED_CODE();
05331
05332
05333
05334
05335
05336 InitializeObjectAttributes( &objectAttributes,
05337
EventName,
05338 OBJ_OPENIF,
05339 (HANDLE)
NULL,
05340 (PSECURITY_DESCRIPTOR)
NULL );
05341
05342
05343
05344
05345
05346 status = ZwCreateEvent( &eventHandle,
05347 EVENT_ALL_ACCESS,
05348 &objectAttributes,
05349 NotificationEvent,
05350
TRUE );
05351
if (!
NT_SUCCESS( status )) {
05352
return (
PKEVENT)
NULL;
05353 }
05354
05355
05356
05357
05358
05359
05360 (
VOID)
ObReferenceObjectByHandle( eventHandle,
05361 0,
05362
ExEventObjectType,
05363
KernelMode,
05364 (PVOID *) &eventObject,
05365
NULL );
05366
ObDereferenceObject( eventObject );
05367
05368
05369
05370
05371
05372 *
EventHandle = eventHandle;
05373
05374
return eventObject;
05375 }
05376
05377
PFILE_OBJECT
05378 IoCreateStreamFileObject(
05379 IN
PFILE_OBJECT FileObject OPTIONAL,
05380 IN
PDEVICE_OBJECT DeviceObject OPTIONAL
05381 )
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417 {
05418
PFILE_OBJECT newFileObject;
05419 OBJECT_ATTRIBUTES objectAttributes;
05420 HANDLE handle;
05421
NTSTATUS status;
05422
05423
PAGED_CODE();
05424
05425
05426
05427
05428
05429
05430
if (ARGUMENT_PRESENT( FileObject )) {
05431 DeviceObject = FileObject->DeviceObject;
05432 }
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
ExInterlockedAddUlong( &DeviceObject->ReferenceCount, 1, &
IopDatabaseLock );
05443
05444
05445
05446
05447
05448
05449 InitializeObjectAttributes( &objectAttributes,
05450 (PUNICODE_STRING)
NULL,
05451 0,
05452 (HANDLE)
NULL,
05453 (PSECURITY_DESCRIPTOR)
NULL );
05454
05455
05456
05457
05458
05459 status =
ObCreateObject(
KernelMode,
05460
IoFileObjectType,
05461 &objectAttributes,
05462 0,
05463 (PVOID)
NULL,
05464 (ULONG)
sizeof(
FILE_OBJECT ),
05465 (ULONG)
sizeof(
FILE_OBJECT ),
05466 0,
05467 (PVOID *) &newFileObject );
05468
05469
if (!
NT_SUCCESS( status )) {
05470
IopDecrementDeviceObjectRef( DeviceObject,
FALSE );
05471
ExRaiseStatus( status );
05472 }
05473
05474
05475
05476
05477
05478 RtlZeroMemory( newFileObject,
sizeof(
FILE_OBJECT ) );
05479 newFileObject->Type =
IO_TYPE_FILE;
05480 newFileObject->Size =
sizeof(
FILE_OBJECT );
05481 newFileObject->DeviceObject = DeviceObject;
05482 newFileObject->Flags =
FO_STREAM_FILE;
05483
KeInitializeEvent( &newFileObject->Event, SynchronizationEvent,
FALSE );
05484
05485
05486
05487
05488
05489
05490
05491 status =
ObInsertObject( newFileObject,
05492
NULL,
05493 FILE_READ_DATA,
05494 1,
05495 (PVOID *) &newFileObject,
05496 &handle );
05497
05498
if (!
NT_SUCCESS( status )) {
05499
ExRaiseStatus( status );
05500 }
05501
05502
05503
05504
05505
05506
05507 newFileObject->Flags |=
FO_HANDLE_CREATED;
05508
ASSERT( newFileObject->Type ==
IO_TYPE_FILE );
05509
05510
05511
05512
05513
05514
05515
if (DeviceObject->Vpb) {
05516
05517
ExInterlockedAddUlong( &DeviceObject->Vpb->ReferenceCount,
05518 1,
05519 &
IopVpbSpinLock );
05520 }
05521
05522
05523
05524
05525
05526 status =
NtClose( handle );
05527
05528
ASSERT(
NT_SUCCESS( status ) );
05529
05530
return newFileObject;
05531 }
05532
05533
05534
PFILE_OBJECT
05535 IoCreateStreamFileObjectLite(
05536 IN
PFILE_OBJECT FileObject OPTIONAL,
05537 IN
PDEVICE_OBJECT DeviceObject OPTIONAL
05538 )
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562
05563
05564
05565
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576
05577
05578 {
05579
PFILE_OBJECT newFileObject;
05580 OBJECT_ATTRIBUTES objectAttributes;
05581 HANDLE handle;
05582
NTSTATUS status;
05583
05584
PAGED_CODE();
05585
05586
05587
05588
05589
05590
05591
if (ARGUMENT_PRESENT( FileObject )) {
05592 DeviceObject = FileObject->DeviceObject;
05593 }
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
ExInterlockedAddUlong( &DeviceObject->ReferenceCount, 1, &
IopDatabaseLock );
05604
05605
05606
05607
05608
05609
05610 InitializeObjectAttributes( &objectAttributes,
05611 (PUNICODE_STRING)
NULL,
05612 0,
05613 (HANDLE)
NULL,
05614 (PSECURITY_DESCRIPTOR)
NULL );
05615
05616
05617
05618
05619
05620 status =
ObCreateObject(
KernelMode,
05621
IoFileObjectType,
05622 &objectAttributes,
05623 0,
05624 (PVOID)
NULL,
05625 (ULONG)
sizeof(
FILE_OBJECT ),
05626 (ULONG)
sizeof(
FILE_OBJECT ),
05627 0,
05628 (PVOID *) &newFileObject );
05629
05630
if (!
NT_SUCCESS( status )) {
05631
IopDecrementDeviceObjectRef( DeviceObject,
FALSE );
05632
ExRaiseStatus( status );
05633 }
05634
05635
05636
05637
05638
05639 RtlZeroMemory( newFileObject,
sizeof(
FILE_OBJECT ) );
05640 newFileObject->Type =
IO_TYPE_FILE;
05641 newFileObject->Size =
sizeof(
FILE_OBJECT );
05642 newFileObject->DeviceObject = DeviceObject;
05643 newFileObject->Flags =
FO_STREAM_FILE;
05644
KeInitializeEvent( &newFileObject->Event, SynchronizationEvent,
FALSE );
05645
05646
05647
05648
05649
05650
ObFreeObjectCreateInfoBuffer(
OBJECT_TO_OBJECT_HEADER(newFileObject)->ObjectCreateInfo);
05651
OBJECT_TO_OBJECT_HEADER(newFileObject)->ObjectCreateInfo =
NULL;
05652
05653 newFileObject->Flags |=
FO_HANDLE_CREATED;
05654
ASSERT( newFileObject->Type ==
IO_TYPE_FILE );
05655
05656
05657
05658
05659
05660
05661
if (DeviceObject->Vpb) {
05662
05663
ExInterlockedAddUlong( &DeviceObject->Vpb->ReferenceCount,
05664 1,
05665 &
IopVpbSpinLock );
05666 }
05667
05668
return newFileObject;
05669 }
05670
05671
05672
05673
05674
NTSTATUS
05675 IoCreateSymbolicLink(
05676 IN PUNICODE_STRING SymbolicLinkName,
05677 IN PUNICODE_STRING DeviceName
05678 )
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698 {
05699 OBJECT_ATTRIBUTES objectAttributes;
05700 HANDLE linkHandle;
05701
NTSTATUS status;
05702
05703
PAGED_CODE();
05704
05705
05706
05707
05708
05709 InitializeObjectAttributes( &objectAttributes,
05710 SymbolicLinkName,
05711 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
05712 (HANDLE)
NULL,
05713
SePublicDefaultUnrestrictedSd );
05714
05715
05716
05717
05718
05719
05720
05721 status = ZwCreateSymbolicLinkObject( &linkHandle,
05722 SYMBOLIC_LINK_ALL_ACCESS,
05723 &objectAttributes,
05724 DeviceName );
05725
if (
NT_SUCCESS( status )) {
05726 ZwClose( linkHandle );
05727 }
05728
05729
return status;
05730 }
05731
05732
PKEVENT
05733 IoCreateSynchronizationEvent(
05734 IN PUNICODE_STRING EventName,
05735 OUT PHANDLE EventHandle
05736 )
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759 {
05760 OBJECT_ATTRIBUTES objectAttributes;
05761
NTSTATUS status;
05762 HANDLE eventHandle;
05763
PKEVENT eventObject;
05764
05765
PAGED_CODE();
05766
05767
05768
05769
05770
05771 InitializeObjectAttributes( &objectAttributes,
05772
EventName,
05773 OBJ_OPENIF,
05774 (HANDLE)
NULL,
05775 (PSECURITY_DESCRIPTOR)
NULL );
05776
05777
05778
05779
05780
05781 status = ZwCreateEvent( &eventHandle,
05782 EVENT_ALL_ACCESS,
05783 &objectAttributes,
05784 SynchronizationEvent,
05785
TRUE );
05786
if (!
NT_SUCCESS( status )) {
05787
return (
PKEVENT)
NULL;
05788 }
05789
05790
05791
05792
05793
05794
05795 (
VOID)
ObReferenceObjectByHandle( eventHandle,
05796 0,
05797
ExEventObjectType,
05798
KernelMode,
05799 (PVOID *) &eventObject,
05800
NULL );
05801
ObDereferenceObject( eventObject );
05802
05803
05804
05805
05806
05807 *
EventHandle = eventHandle;
05808
05809
return eventObject;
05810 }
05811
05812
NTSTATUS
05813 IoCreateUnprotectedSymbolicLink(
05814 IN PUNICODE_STRING SymbolicLinkName,
05815 IN PUNICODE_STRING DeviceName
05816 )
05817
05818
05819
05820
05821
05822
05823
05824
05825
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839
05840
05841
05842
05843
05844 {
05845 OBJECT_ATTRIBUTES objectAttributes;
05846 HANDLE linkHandle;
05847
NTSTATUS status;
05848 SECURITY_DESCRIPTOR securityDescriptor;
05849
05850
PAGED_CODE();
05851
05852
05853
05854
05855
05856 status =
RtlCreateSecurityDescriptor( &securityDescriptor,
05857 SECURITY_DESCRIPTOR_REVISION1 );
05858
if (!
NT_SUCCESS( status )) {
05859
return status;
05860 }
05861
05862 status =
RtlSetDaclSecurityDescriptor ( &securityDescriptor,
05863
TRUE,
05864
NULL,
05865
TRUE );
05866
if (!
NT_SUCCESS( status )) {
05867
return status;
05868 }
05869
05870
05871
05872
05873
05874 InitializeObjectAttributes( &objectAttributes,
05875 SymbolicLinkName,
05876 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
05877 (HANDLE)
NULL,
05878 &securityDescriptor );
05879
05880
05881
05882
05883
05884
05885
05886 status = ZwCreateSymbolicLinkObject( &linkHandle,
05887 SYMBOLIC_LINK_ALL_ACCESS,
05888 &objectAttributes,
05889 DeviceName );
05890
if (
NT_SUCCESS( status )) {
05891 ZwClose( linkHandle );
05892 }
05893
05894
return status;
05895 }
05896
05897
VOID
05898 IoDeleteController(
05899 IN
PCONTROLLER_OBJECT ControllerObject
05900 )
05901
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923 {
05924
PAGED_CODE();
05925
05926
05927
05928
05929
05930
05931
05932
ObDereferenceObject( ControllerObject );
05933 }
05934
05935
VOID
05936 IopRemoveTimerFromTimerList(
05937 IN
PIO_TIMER timer
05938 )
05939 {
05940 KIRQL irql;
05941
05942 ExAcquireFastLock( &
IopTimerLock, &irql );
05943 RemoveEntryList( &timer->TimerList );
05944
if (timer->TimerFlag) {
05945
IopTimerCount--;
05946 }
05947 ExReleaseFastLock( &
IopTimerLock, irql );
05948 }
05949
05950
VOID
05951 IoDeleteDevice(
05952 IN
PDEVICE_OBJECT DeviceObject
05953 )
05954
05955
05956
05957
05958
05959
05960
05961
05962
05963
05964
05965
05966
05967
05968
05969
05970
05971
05972
05973
05974
05975
05976 {
05977 KIRQL irql;
05978
05979
IOV_DELETE_DEVICE(DeviceObject);
05980
05981
05982
05983
05984
05985
05986
if (DeviceObject->Flags &
DO_SHUTDOWN_REGISTERED) {
05987
IoUnregisterShutdownNotification( DeviceObject );
05988 }
05989
05990
05991
05992
05993
05994
05995
if (DeviceObject->Timer) {
05996
PIO_TIMER timer;
05997
05998 timer = DeviceObject->Timer;
05999
IopRemoveTimerFromTimerList(timer);
06000
ExFreePool( timer );
06001 }
06002
06003
06004
06005
06006
06007
06008
06009
if (DeviceObject->Flags &
DO_DEVICE_HAS_NAME) {
06010
ObMakeTemporaryObject( DeviceObject );
06011 }
06012
06013
06014
06015
06016
06017
06018
PoRunDownDeviceObject(DeviceObject);
06019
06020
06021
06022
06023
06024 ExAcquireSpinLock( &
IopDatabaseLock, &irql );
06025
06026 DeviceObject->DeviceObjectExtension->ExtensionFlags |=
DOE_DELETE_PENDING;
06027
06028
if (!DeviceObject->ReferenceCount) {
06029
IopCompleteUnloadOrDelete( DeviceObject, irql );
06030 }
else {
06031 ExReleaseSpinLock( &
IopDatabaseLock, irql );
06032 }
06033 }
06034
06035
06036
NTSTATUS
06037 IopDeleteSessionSymLinks(
06038 IN PUNICODE_STRING LinkName
06039 )
06040
06041
06042
06043
06044
06045
06046
06047
06048
06049
06050
06051
06052
06053
06054
06055
06056
06057
06058
06059 {
06060
06061
NTSTATUS Status = STATUS_SUCCESS;
06062 UNICODE_STRING UnicodeString;
06063 UNICODE_STRING SymbolicLinkName;
06064 OBJECT_ATTRIBUTES Attributes;
06065 HANDLE
DirectoryHandle;
06066 HANDLE linkHandle;
06067 POBJECT_DIRECTORY_INFORMATION DirInfo;
06068 BOOLEAN RestartScan;
06069 ULONG Context = 0;
06070 ULONG ReturnedLength;
06071 PWCHAR NameBuf;
06072 PUCHAR DirInfoBuffer;
06073 ULONG
Size;
06074 WCHAR Prefix[13];
06075
06076
06077
06078
06079
06080
06081
06082
if (LinkName->Length < (
sizeof(
L"\\DosDevices\\"))) {
06083
return STATUS_SUCCESS;
06084 }
06085
RtlInitUnicodeString( &UnicodeString,
L"\\DosDevices\\" );
06086
06087 wcsncpy(Prefix,LinkName->Buffer,(
sizeof(
L"\\DosDevices\\")/
sizeof(WCHAR)) - 1);
06088
RtlInitUnicodeString( &SymbolicLinkName, Prefix);
06089
06090
if (
RtlCompareUnicodeString(&UnicodeString, &SymbolicLinkName,
TRUE)) {
06091
06092
return STATUS_SUCCESS;
06093
06094 }
06095
06096
06097
06098
06099
06100
RtlInitUnicodeString( &UnicodeString,
L"\\Sessions" );
06101
06102 InitializeObjectAttributes( &Attributes,
06103 &UnicodeString,
06104 OBJ_CASE_INSENSITIVE,
06105
NULL,
06106
NULL
06107 );
06108
06109
Status = ZwOpenDirectoryObject( &
DirectoryHandle,
06110 DIRECTORY_QUERY,
06111 &Attributes
06112 );
06113
if (
NT_SUCCESS(
Status )) {
06114
06115
06116
06117
06118
06119
06120
Size = (LinkName->Length + 128) *
sizeof(WCHAR);
06121 NameBuf = (PWCHAR)
ExAllocatePoolWithTag(
PagedPool,
Size, ' oI');
06122
06123
if (NameBuf ==
NULL) {
06124
return STATUS_INSUFFICIENT_RESOURCES;
06125 }
06126
06127 SymbolicLinkName.Buffer = (PWSTR)NameBuf;
06128 SymbolicLinkName.Length = (
USHORT)
Size;
06129 SymbolicLinkName.MaximumLength = (
USHORT)
Size;
06130
06131
06132
06133
06134
06135
Size = 4096;
06136 DirInfoBuffer = (PUCHAR)
ExAllocatePoolWithTag(
PagedPool,
Size, ' oI');
06137
06138
if (DirInfoBuffer ==
NULL) {
06139
ExFreePool(NameBuf);
06140
return STATUS_INSUFFICIENT_RESOURCES;
06141 }
06142
06143 RestartScan =
TRUE;
06144 DirInfo = (POBJECT_DIRECTORY_INFORMATION)DirInfoBuffer;
06145
06146
06147
while (
TRUE) {
06148
06149
Status = ZwQueryDirectoryObject(
DirectoryHandle,
06150 (PVOID)DirInfo,
06151
Size,
06152
TRUE,
06153 RestartScan,
06154 &Context,
06155 &ReturnedLength
06156 );
06157
06158 RestartScan =
FALSE;
06159
06160
06161
06162
06163
06164
if (!
NT_SUCCESS(
Status )) {
06165
if (
Status == STATUS_NO_MORE_ENTRIES) {
06166
Status = STATUS_SUCCESS;
06167 }
06168
06169
break;
06170 }
06171
06172
06173
06174
06175
06176
06177
RtlInitUnicodeString( &UnicodeString,
L"\\Sessions\\" );
06178
RtlCopyUnicodeString( &SymbolicLinkName, &UnicodeString );
06179
RtlAppendUnicodeStringToString( &SymbolicLinkName, &(DirInfo->Name) );
06180
RtlAppendUnicodeStringToString( &SymbolicLinkName, LinkName );
06181
06182
06183
06184
06185 InitializeObjectAttributes( &Attributes,
06186 &SymbolicLinkName,
06187 OBJ_CASE_INSENSITIVE,
06188
NULL,
06189
NULL );
06190
06191
06192
06193
06194
06195
06196
Status = ZwOpenSymbolicLinkObject( &linkHandle,
06197 DELETE,
06198 &Attributes );
06199
if (
NT_SUCCESS(
Status )) {
06200
06201
06202
06203
06204
06205
06206
06207
Status = ZwMakeTemporaryObject( linkHandle );
06208
if (
NT_SUCCESS(
Status )) {
06209 ZwClose( linkHandle );
06210 }
06211 }
06212
06213
06214
06215 }
06216
06217 ZwClose(
DirectoryHandle);
06218
ExFreePool(NameBuf);
06219
ExFreePool(DirInfoBuffer);
06220 }
06221
06222
return Status;
06223 }
06224
06225
06226
NTSTATUS
06227 IoDeleteSymbolicLink(
06228 IN PUNICODE_STRING SymbolicLinkName
06229 )
06230
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250 {
06251 OBJECT_ATTRIBUTES objectAttributes;
06252 HANDLE linkHandle;
06253
NTSTATUS status;
06254
06255
PAGED_CODE();
06256
06257
06258
06259
06260
06261 InitializeObjectAttributes( &objectAttributes,
06262 SymbolicLinkName,
06263 OBJ_CASE_INSENSITIVE,
06264 (HANDLE)
NULL,
06265 (PSECURITY_DESCRIPTOR)
NULL );
06266
06267
06268
06269
06270
06271
06272 status = ZwOpenSymbolicLinkObject( &linkHandle,
06273 DELETE,
06274 &objectAttributes );
06275
if (
NT_SUCCESS( status )) {
06276
06277
06278
06279
06280
06281
06282
06283 status = ZwMakeTemporaryObject( linkHandle );
06284
if (
NT_SUCCESS( status )) {
06285 ZwClose( linkHandle );
06286 }
06287
06288
if (
ExVerifySuite(TerminalServer) ==
TRUE) {
06289
IopDeleteSessionSymLinks( SymbolicLinkName );
06290 }
06291 }
06292
06293
06294
return status;
06295 }
06296
06297
VOID
06298 IoDetachDevice(
06299 IN OUT
PDEVICE_OBJECT TargetDevice
06300 )
06301
06302
06303
06304
06305
06306
06307
06308
06309
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320 {
06321 KIRQL irql;
06322
PDEVICE_OBJECT detachingDevice;
06323
PDEVOBJ_EXTENSION detachingExtension;
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333 ExAcquireSpinLock( &
IopDatabaseLock, &irql );
06334
06335
06336
06337
06338
06339
06340
06341
IOV_DETACH_DEVICE(TargetDevice);
06342
06343 detachingDevice = TargetDevice->
AttachedDevice;
06344 detachingExtension = detachingDevice->
DeviceObjectExtension;
06345
ASSERT( detachingExtension->
AttachedTo == TargetDevice );
06346
06347
06348
06349
06350
06351 detachingExtension->
AttachedTo =
NULL;
06352 TargetDevice->AttachedDevice =
NULL;
06353
06354
if (TargetDevice->DeviceObjectExtension->ExtensionFlags &
06355 (
DOE_UNLOAD_PENDING |
DOE_DELETE_PENDING |
DOE_REMOVE_PENDING) &&
06356 !TargetDevice->ReferenceCount) {
06357
IopCompleteUnloadOrDelete( TargetDevice, irql );
06358 }
else {
06359 ExReleaseSpinLock( &
IopDatabaseLock, irql );
06360 }
06361 }
06362
06363
VOID
06364 IoDisconnectInterrupt(
06365 IN
PKINTERRUPT InterruptObject
06366 )
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379
06380
06381
06382
06383
06384
06385
06386
06387
06388 {
06389
PIO_INTERRUPT_STRUCTURE interruptStructure;
06390 ULONG i;
06391
06392
PAGED_CODE();
06393
06394
06395
06396
06397
06398
06399 interruptStructure = CONTAINING_RECORD(
InterruptObject,
06400
IO_INTERRUPT_STRUCTURE,
06401
InterruptObject );
06402
06403
06404
06405
06406
06407
06408
KeDisconnectInterrupt( &interruptStructure->
InterruptObject );
06409
06410
06411
06412
06413
06414
06415
for (i = 0; i <
MAXIMUM_PROCESSORS; i++) {
06416
if (interruptStructure->
InterruptArray[i] !=
NULL) {
06417
KeDisconnectInterrupt( interruptStructure->
InterruptArray[i] );
06418 }
06419 }
06420
06421
06422
06423
06424
06425
ExFreePool( interruptStructure );
06426 }
06427
06428
VOID
06429 IoEnqueueIrp(
06430 IN
PIRP Irp
06431 )
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445
06446
06447
06448
06449
06450
06451 {
06452
PAGED_CODE();
06453
06454
06455
06456
06457
06458
IopQueueThreadIrp(
Irp );
06459
return;
06460 }
06461
06462 BOOLEAN
06463 IoFastQueryNetworkAttributes(
06464 IN POBJECT_ATTRIBUTES ObjectAttributes,
06465 IN ACCESS_MASK DesiredAccess,
06466 IN ULONG OpenOptions,
06467 OUT PIO_STATUS_BLOCK IoStatus,
06468 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
06469 )
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479
06480
06481
06482
06483
06484
06485
06486
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506 {
06507 HANDLE handle;
06508
NTSTATUS status;
06509
OPEN_PACKET openPacket;
06510
DUMMY_FILE_OBJECT localFileObject;
06511
06512
06513
06514
06515
06516
06517
06518 RtlZeroMemory( &openPacket,
sizeof(
OPEN_PACKET ) );
06519
06520 openPacket.
Type =
IO_TYPE_OPEN_PACKET;
06521 openPacket.
Size =
sizeof(
OPEN_PACKET );
06522 openPacket.
ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
06523 openPacket.
Disposition = FILE_OPEN;
06524 openPacket.
CreateOptions = OpenOptions | FILE_OPEN_REPARSE_POINT;
06525 openPacket.
Options =
IO_FORCE_ACCESS_CHECK;
06526 openPacket.
NetworkInformation =
Buffer;
06527 openPacket.
QueryOnly =
TRUE;
06528 openPacket.
FullAttributes =
TRUE;
06529 openPacket.
LocalFileObject = &localFileObject;
06530
06531
06532
06533
06534
06535
06536
06537 status =
ObOpenObjectByName(
ObjectAttributes,
06538 (
POBJECT_TYPE)
NULL,
06539
KernelMode,
06540
NULL,
06541 DesiredAccess,
06542 &openPacket,
06543 &handle );
06544
06545
06546
06547
06548
06549
06550
06551
06552
if (openPacket.
ParseCheck !=
OPEN_PACKET_PATTERN) {
06553
06554
06555
06556
06557
06558
06559 IoStatus->Status = status;
06560 }
else {
06561
06562
06563
06564
06565
06566
06567 IoStatus->Status = openPacket.
FinalStatus;
06568 IoStatus->Information = openPacket.
Information;
06569 }
06570
return TRUE;
06571 }
06572
06573
VOID
06574 IoFreeController(
06575 IN
PCONTROLLER_OBJECT ControllerObject
06576 )
06577
06578
06579
06580
06581
06582
06583
06584
06585
06586
06587
06588
06589
06590
06591
06592
06593
06594
06595
06596
06597
06598
06599
06600 {
06601
PKDEVICE_QUEUE_ENTRY packet;
06602
PDEVICE_OBJECT deviceObject;
06603
IO_ALLOCATION_ACTION action;
06604
06605
06606
06607
06608
06609
06610 packet =
KeRemoveDeviceQueue( &ControllerObject->DeviceWaitQueue );
06611
if (packet !=
NULL) {
06612 deviceObject = CONTAINING_RECORD( packet,
06613
DEVICE_OBJECT,
06614 Queue.Wcb.WaitQueueEntry );
06615 action = deviceObject->
Queue.Wcb.DeviceRoutine( deviceObject,
06616 deviceObject->
CurrentIrp,
06617 0,
06618 deviceObject->
Queue.Wcb.DeviceContext );
06619
06620
06621
06622
06623
06624
06625
if (action ==
DeallocateObject) {
06626
IoFreeController( ControllerObject );
06627 }
06628 }
06629 }
06630
06631
VOID
06632 IoFreeIrp(
06633 IN
PIRP Irp
06634 )
06635 {
06636
pIoFreeIrp(
Irp);
06637 }
06638
06639
06640
VOID
06641 IopFreeIrp(
06642 IN
PIRP Irp
06643 )
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653
06654
06655
06656
06657
06658
06659
06660
06661 {
06662
PNPAGED_LOOKASIDE_LIST lookasideList;
06663
PP_NPAGED_LOOKASIDE_NUMBER number;
06664 PKPRCB prcb;
06665
06666
06667
06668
06669
06670
ASSERT(
Irp->
Type ==
IO_TYPE_IRP );
06671
06672
if (
Irp->
Type !=
IO_TYPE_IRP) {
06673
KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR)
Irp, __LINE__, 0, 0 );
06674 }
06675
06676
06677
ASSERT(IsListEmpty(&(
Irp)->ThreadListEntry));
06678
Irp->
Type = 0;
06679
06680
06681
06682
06683
06684
06685
ASSERT(
Irp->
CurrentLocation >=
Irp->
StackCount );
06686
06687
06688
06689
06690
06691
if (
Irp->
AllocationFlags &
IRP_LOOKASIDE_ALLOCATION) {
06692
Irp->
AllocationFlags ^=
IRP_LOOKASIDE_ALLOCATION;
06693 InterlockedDecrement( &
IopLookasideIrpFloat );
06694 }
06695
if (!(
Irp->
AllocationFlags &
IRP_ALLOCATED_FIXED_SIZE) ||
06696 (
Irp->
AllocationFlags &
IRP_ALLOCATED_MUST_SUCCEED) ||
06697 (
IopLookasideIrpFloat >=
IopLookasideIrpLimit)) {
06698
ExFreePool(
Irp );
06699
06700 }
else {
06701 number =
LookasideSmallIrpList;
06702
if (
Irp->
StackCount != 1) {
06703 number =
LookasideLargeIrpList;
06704 }
06705
06706 prcb =
KeGetCurrentPrcb();
06707 lookasideList = prcb->PPLookasideList[number].P;
06708 lookasideList->
L.
TotalFrees += 1;
06709
if (
ExQueryDepthSList( &lookasideList->
L.
ListHead ) >= lookasideList->
L.
Depth ) {
06710 lookasideList->
L.
FreeMisses += 1;
06711 lookasideList = prcb->PPLookasideList[number].
L;
06712 lookasideList->
L.
TotalFrees += 1;
06713
if (
ExQueryDepthSList( &lookasideList->
L.
ListHead ) >= lookasideList->
L.
Depth) {
06714 lookasideList->
L.
FreeMisses += 1;
06715
ExFreePool(
Irp );
06716
06717 }
else {
06718
if (
Irp->
AllocationFlags &
IRP_QUOTA_CHARGED) {
06719
Irp->
AllocationFlags ^=
IRP_QUOTA_CHARGED;
06720
ExReturnPoolQuota(
Irp );
06721 }
06722
06723
ExInterlockedPushEntrySList( &lookasideList->
L.
ListHead,
06724 (PSINGLE_LIST_ENTRY)
Irp,
06725 &lookasideList->
Lock );
06726 }
06727
06728 }
else {
06729
if (
Irp->
AllocationFlags &
IRP_QUOTA_CHARGED) {
06730
Irp->
AllocationFlags ^=
IRP_QUOTA_CHARGED;
06731
ExReturnPoolQuota(
Irp );
06732 }
06733
06734
ExInterlockedPushEntrySList( &lookasideList->
L.
ListHead,
06735 (PSINGLE_LIST_ENTRY)
Irp,
06736 &lookasideList->
Lock );
06737 }
06738 }
06739
06740
return;
06741 }
06742
06743
VOID
06744 IoFreeMdl(
06745 IN
PMDL Mdl
06746 )
06747
06748
06749
06750
06751
06752
06753
06754
06755
06756
06757
06758
06759
06760
06761
06762
06763
06764
06765
06766 {
06767
PNPAGED_LOOKASIDE_LIST lookasideList;
06768
06769
06770
06771
06772
06773
06774
06775
MmPrepareMdlForReuse(Mdl);
06776
if (((Mdl->MdlFlags &
MDL_ALLOCATED_FIXED_SIZE) == 0) ||
06777 ((Mdl->MdlFlags &
MDL_ALLOCATED_MUST_SUCCEED) != 0)) {
06778
ExFreePool(Mdl);
06779
06780 }
else {
06781
ExFreeToPPNPagedLookasideList(
LookasideMdlList, Mdl);
06782 }
06783 }
06784
06785
PDEVICE_OBJECT
06786 IoGetAttachedDevice(
06787 IN
PDEVICE_OBJECT DeviceObject
06788 )
06789
06790
06791
06792
06793
06794
06795
06796
06797
06798
06799
06800
06801
06802
06803
06804
06805
06806
06807
06808
06809
06810
06811
06812
06813
06814 {
06815
06816
06817
06818
06819
06820
06821
while (DeviceObject->AttachedDevice) {
06822 DeviceObject = DeviceObject->
AttachedDevice;
06823 }
06824
06825
return DeviceObject;
06826 }
06827
06828
PDEVICE_OBJECT
06829 IoGetAttachedDeviceReference(
06830 IN
PDEVICE_OBJECT DeviceObject
06831 )
06832
06833
06834
06835
06836
06837
06838
06839
06840
06841
06842
06843
06844
06845
06846
06847
06848
06849
06850
06851 {
06852 KIRQL irql;
06853
06854 ExAcquireFastLock( &
IopDatabaseLock, &irql );
06855 DeviceObject =
IoGetAttachedDevice (DeviceObject);
06856
ObReferenceObject (DeviceObject);
06857 ExReleaseFastLock( &
IopDatabaseLock, irql );
06858
return DeviceObject;
06859 }
06860
06861
PDEVICE_OBJECT
06862 IoGetBaseFileSystemDeviceObject(
06863 IN
PFILE_OBJECT FileObject
06864 )
06865
06866
06867
06868
06869
06870
06871
06872
06873
06874
06875
06876
06877
06878
06879
06880
06881
06882
06883
06884
06885
06886 {
06887
PDEVICE_OBJECT deviceObject;
06888
06889
06890
06891
06892
06893
if (FileObject->Vpb !=
NULL && FileObject->Vpb->DeviceObject !=
NULL) {
06894 deviceObject = FileObject->
Vpb->
DeviceObject;
06895
06896
06897
06898
06899
06900
06901
06902 }
else if (!(FileObject->Flags &
FO_DIRECT_DEVICE_OPEN) &&
06903 FileObject->DeviceObject->Vpb !=
NULL &&
06904 FileObject->DeviceObject->Vpb->DeviceObject !=
NULL) {
06905
06906 deviceObject = FileObject->DeviceObject->
Vpb->
DeviceObject;
06907
06908
06909
06910
06911
06912 }
else {
06913
06914 deviceObject = FileObject->DeviceObject;
06915 }
06916
06917
ASSERT( deviceObject !=
NULL );
06918
06919
06920
06921
06922
06923
return deviceObject;
06924 }
06925
06926
PCONFIGURATION_INFORMATION
06927 IoGetConfigurationInformation( VOID )
06928
06929
06930
06931
06932
06933
06934
06935
06936
06937
06938
06939
06940
06941
06942
06943
06944
06945
06946
06947
06948 {
06949
PAGED_CODE();
06950
06951
06952
06953
06954
06955
06956
return (&
ConfigurationInformation);
06957 }
06958
06959
PEPROCESS
06960 IoGetCurrentProcess( VOID )
06961
06962
06963
06964
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988
06989 {
06990
06991
06992
06993
06994
return PsGetCurrentProcess();
06995 }
06996
06997
NTSTATUS
06998 IoGetDeviceObjectPointer(
06999 IN PUNICODE_STRING ObjectName,
07000 IN ACCESS_MASK DesiredAccess,
07001 OUT
PFILE_OBJECT *FileObject,
07002 OUT
PDEVICE_OBJECT *DeviceObject
07003 )
07004
07005
07006
07007
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017
07018
07019
07020
07021
07022
07023
07024
07025
07026
07027
07028
07029
07030
07031
07032
07033
07034
07035
07036
07037 {
07038
PFILE_OBJECT fileObject;
07039 OBJECT_ATTRIBUTES objectAttributes;
07040 HANDLE fileHandle;
07041 IO_STATUS_BLOCK ioStatus;
07042
NTSTATUS status;
07043
07044
PAGED_CODE();
07045
07046
07047
07048
07049
07050 InitializeObjectAttributes( &objectAttributes,
07051 ObjectName,
07052 0,
07053 (HANDLE)
NULL,
07054 (PSECURITY_DESCRIPTOR)
NULL );
07055
07056 status =
ZwOpenFile( &fileHandle,
07057 DesiredAccess,
07058 &objectAttributes,
07059 &ioStatus,
07060 0,
07061 FILE_NON_DIRECTORY_FILE );
07062
07063
if (
NT_SUCCESS( status )) {
07064
07065
07066
07067
07068
07069
07070 status =
ObReferenceObjectByHandle( fileHandle,
07071 0,
07072
IoFileObjectType,
07073
KernelMode,
07074 (PVOID *) &fileObject,
07075
NULL );
07076
if (
NT_SUCCESS( status )) {
07077
07078 *FileObject = fileObject;
07079
07080
07081
07082
07083 *DeviceObject =
IoGetRelatedDeviceObject( fileObject );
07084 }
07085
07086 (
VOID) ZwClose( fileHandle );
07087 }
07088
07089
return status;
07090 }
07091
07092
PDEVICE_OBJECT
07093 IoGetDeviceToVerify(
07094 IN
PETHREAD Thread
07095 )
07096
07097
07098
07099
07100
07101
07102
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112
07113
07114
07115
07116
07117
07118
07119
07120
07121 {
07122
07123
07124
07125
07126
return Thread->DeviceToVerify;
07127 }
07128
07129
NTKERNELAPI
07130 PVOID
07131 IoGetDriverObjectExtension(
07132 IN
PDRIVER_OBJECT DriverObject,
07133 IN PVOID ClientIdentificationAddress
07134 )
07135
07136
07137
07138
07139
07140
07141
07142
07143
07144
07145
07146
07147
07148
07149
07150
07151
07152
07153
07154
07155
07156
07157
07158 {
07159 KIRQL irql;
07160
PIO_CLIENT_EXTENSION extension;
07161
07162 ExAcquireFastLock( &
IopDatabaseLock, &irql );
07163
extension = DriverObject->DriverExtension->ClientDriverExtension;
07164
while (
extension !=
NULL) {
07165
07166
if (
extension->ClientIdentificationAddress == ClientIdentificationAddress) {
07167
break;
07168 }
07169
07170
extension =
extension->NextExtension;
07171 }
07172
07173 ExReleaseFastLock( &
IopDatabaseLock, irql );
07174
07175
if (
extension ==
NULL) {
07176
return NULL;
07177 }
07178
07179
return extension + 1;
07180 }
07181
07182 PGENERIC_MAPPING
07183 IoGetFileObjectGenericMapping(
07184 VOID
07185 )
07186
07187
07188
07189
07190
07191
07192
07193
07194
07195
07196
07197
07198
07199
07200
07201
07202
07203 {
07204
07205
07206
07207
07208
return &
IopFileMapping;
07209 }
07210
07211 PVOID
07212 IoGetInitialStack(
07213 VOID
07214 )
07215
07216
07217
07218
07219
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236
07237
07238 {
07239
07240
07241
07242
07243
return PsGetCurrentThread()->Tcb.InitialStack;
07244 }
07245
07246
PDEVICE_OBJECT
07247 IoGetRelatedDeviceObject(
07248 IN
PFILE_OBJECT FileObject
07249 )
07250
07251
07252
07253
07254
07255
07256
07257
07258
07259
07260
07261
07262
07263
07264
07265
07266
07267
07268
07269
07270
07271
07272
07273
07274 {
07275
PDEVICE_OBJECT deviceObject;
07276
07277
07278
07279
07280
07281
07282
07283
07284
if (FileObject->Vpb !=
NULL && FileObject->Vpb->DeviceObject !=
NULL) {
07285
07286
ASSERT(!(FileObject->Flags &
FO_DIRECT_DEVICE_OPEN));
07287 deviceObject = FileObject->
Vpb->
DeviceObject;
07288
07289
07290
07291
07292
07293
07294
07295
07296
07297
07298 }
else if (!(FileObject->Flags &
FO_DIRECT_DEVICE_OPEN) &&
07299 FileObject->DeviceObject->Vpb !=
NULL &&
07300 FileObject->DeviceObject->Vpb->DeviceObject !=
NULL) {
07301
07302 deviceObject = FileObject->DeviceObject->
Vpb->
DeviceObject;
07303
07304
07305
07306
07307
07308
07309 }
else {
07310
07311 deviceObject = FileObject->DeviceObject;
07312 }
07313
07314
ASSERT( deviceObject !=
NULL );
07315
07316
07317
07318
07319
07320
07321
07322
if (deviceObject->
AttachedDevice !=
NULL) {
07323 deviceObject =
IoGetAttachedDevice( deviceObject );
07324 }
07325
07326
return deviceObject;
07327 }
07328
07329 ULONG
07330 IoGetRequestorProcessId(
07331 IN
PIRP Irp
07332 )
07333
07334
07335
07336
07337
07338
07339
07340
07341
07342
07343
07344
07345
07346
07347
07348
07349
07350
07351
07352 {
07353
PEPROCESS process;
07354
07355 process =
IoGetRequestorProcess(
Irp );
07356
if (process !=
NULL) {
07357
07358
07359
07360
07361
07362
return HandleToUlong( process->
UniqueProcessId );
07363 }
else {
07364
07365
07366
07367
07368
07369
return 0;
07370 }
07371 }
07372
07373
PEPROCESS
07374 IoGetRequestorProcess(
07375 IN
PIRP Irp
07376 )
07377
07378
07379
07380
07381
07382
07383
07384
07385
07386
07387
07388
07389
07390
07391
07392
07393
07394
07395
07396 {
07397
07398
07399
07400
07401
if (
Irp->
Tail.Overlay.Thread) {
07402
return THREAD_TO_PROCESS(
Irp->
Tail.Overlay.Thread );
07403 }
else {
07404
return NULL;
07405 }
07406 }
07407
07408
PIRP
07409 IoGetTopLevelIrp(
07410 VOID
07411 )
07412
07413
07414
07415
07416
07417
07418
07419
07420
07421
07422
07423
07424
07425
07426
07427
07428
07429
07430
07431
07432
07433
07434
07435 {
07436
07437
07438
07439
07440
return (
PIRP) (
PsGetCurrentThread()->TopLevelIrp);
07441 }
07442
07443
VOID
07444 IoInitializeIrp(
07445 IN OUT
PIRP Irp,
07446 IN USHORT PacketSize,
07447 IN CCHAR StackSize
07448 )
07449
07450
07451
07452
07453
07454
07455
07456
07457
07458
07459
07460
07461
07462
07463
07464
07465
07466
07467
07468
07469
07470 {
07471
IOV_INITIALIZE_IRP(
Irp, PacketSize, StackSize);
07472
07473
07474
07475
07476
07477 RtlZeroMemory(
Irp, PacketSize );
07478
07479
07480
07481
07482
07483
07484
Irp->
Type = (CSHORT)
IO_TYPE_IRP;
07485
Irp->
Size = (
USHORT) PacketSize;
07486
Irp->
StackCount = (CCHAR) StackSize;
07487
Irp->
CurrentLocation = (CCHAR) (StackSize + 1);
07488
Irp->
ApcEnvironment =
KeGetCurrentApcEnvironment();
07489 InitializeListHead (&(
Irp)->ThreadListEntry);
07490
Irp->
Tail.Overlay.CurrentStackLocation =
07491 ((
PIO_STACK_LOCATION) ((UCHAR *) (
Irp) +
07492
sizeof(
IRP ) +
07493 ( (StackSize) *
sizeof(
IO_STACK_LOCATION ))));
07494 }
07495
07496
VOID
07497 IoReuseIrp(
07498
PIRP Irp,
07499 NTSTATUS Status)
07500
07501
07502
07503
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516 {
07517
07518
USHORT PacketSize;
07519 CCHAR StackSize;
07520 UCHAR AllocationFlags;
07521
07522
07523
ASSERT(
Irp->
CancelRoutine ==
NULL) ;
07524
07525
07526
07527
07528
07529
ASSERT(IsListEmpty(&
Irp->
ThreadListEntry)) ;
07530
07531 AllocationFlags =
Irp->
AllocationFlags;
07532 StackSize =
Irp->
StackCount;
07533 PacketSize =
IoSizeOfIrp(StackSize);
07534
IopInitializeIrp(
Irp, PacketSize, StackSize);
07535
Irp->
AllocationFlags = AllocationFlags;
07536
Irp->
IoStatus.Status =
Status;
07537
07538 }
07539
07540
07541
07542
NTSTATUS
07543 IoInitializeTimer(
07544 IN
PDEVICE_OBJECT DeviceObject,
07545 IN PIO_TIMER_ROUTINE TimerRoutine,
07546 IN PVOID Context
07547 )
07548
07549
07550
07551
07552
07553
07554
07555
07556
07557
07558
07559
07560
07561
07562
07563
07564
07565
07566
07567
07568
07569
07570 {
07571
PIO_TIMER timer;
07572
07573
PAGED_CODE();
07574
07575
07576
07577
07578
07579
07580 timer = DeviceObject->Timer;
07581
if (!timer) {
07582 timer =
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(
IO_TIMER ), 'iToI' );
07583
if (!timer) {
07584
return STATUS_INSUFFICIENT_RESOURCES;
07585 }
07586
07587
07588
07589
07590
07591
07592 RtlZeroMemory( timer,
sizeof(
IO_TIMER ) );
07593 timer->
Type =
IO_TYPE_TIMER;
07594 timer->
DeviceObject = DeviceObject;
07595 DeviceObject->
Timer = timer;
07596 }
07597
07598
07599
07600
07601
07602
07603
07604
07605 timer->
TimerRoutine = TimerRoutine;
07606 timer->
Context = Context;
07607
07608
ExInterlockedInsertTailList( &
IopTimerQueueHead,
07609 &timer->
TimerList,
07610 &
IopTimerLock );
07611
return STATUS_SUCCESS;
07612 }
07613
07614 BOOLEAN
07615 IoIsOperationSynchronous(
07616 IN
PIRP Irp
07617 )
07618
07619
07620
07621
07622
07623
07624
07625
07626
07627
07628
07629
07630
07631
07632
07633
07634
07635
07636
07637
07638
07639
07640
07641
07642
07643
07644
07645
07646 {
07647
07648
07649
07650
07651
07652
07653
07654
07655
07656
07657
07658
07659
07660
07661
if ((
IoGetCurrentIrpStackLocation(
Irp )->FileObject->Flags &
FO_SYNCHRONOUS_IO ||
07662
Irp->
Flags &
IRP_SYNCHRONOUS_API ||
07663
Irp->
Flags &
IRP_SYNCHRONOUS_PAGING_IO) &&
07664 !(
Irp->
Flags &
IRP_PAGING_IO &&
07665 !(
Irp->
Flags &
IRP_SYNCHRONOUS_PAGING_IO))) {
07666
return TRUE;
07667 }
else {
07668
return FALSE;
07669 }
07670 }
07671
07672 BOOLEAN
07673 IoIsSystemThread(
07674 IN
PETHREAD Thread
07675 )
07676
07677
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687
07688
07689
07690
07691
07692
07693
07694
07695
07696
07697
07698
07699
07700 {
07701
return (BOOLEAN)
IS_SYSTEM_THREAD(Thread);
07702 }
07703
07704 BOOLEAN
07705 IoIsValidNameGraftingBuffer(
07706 IN
PIRP Irp,
07707 IN PREPARSE_DATA_BUFFER ReparseBuffer
07708 )
07709
07710
07711
07712
07713
07714
07715
07716
07717
07718
07719
07720
07721
07722
07723
07724
07725
07726
07727
07728
07729
07730
07731
07732
07733
07734
07735
07736
07737
07738
07739
07740
07741
07742 {
07743
PIO_STACK_LOCATION thisStackPointer =
NULL;
07744 UNICODE_STRING drivePath;
07745
07746
ASSERT( FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0] ) ==
07747 FIELD_OFFSET( REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0] ) );
07748
ASSERT( ReparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
07749
07750
07751
07752
07753
07754
if (ReparseBuffer->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT) {
07755
07756
07757
07758
07759
07760
return FALSE;
07761 }
07762
07763
07764
07765
07766
07767
if (ReparseBuffer->ReparseDataLength <
07768 (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) - REPARSE_DATA_BUFFER_HEADER_SIZE)) {
07769
07770
07771
07772
07773
07774
07775
return FALSE;
07776 }
07777
07778
07779
07780
07781
07782 thisStackPointer =
IoGetCurrentIrpStackLocation(
Irp );
07783
07784
07785
07786
07787
07788
07789
07790
07791
07792
if ((thisStackPointer->
Parameters.FileSystemControl.OutputBufferLength > 0) &&
07793 (thisStackPointer->
Parameters.FileSystemControl.OutputBufferLength <
07794 (ULONG)(FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) +
07795 ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength +
07796 ReparseBuffer->MountPointReparseBuffer.PrintNameLength +
07797 2 *
sizeof( UNICODE_NULL )))) {
07798
07799
07800
07801
07802
07803
07804
07805
07806
07807
07808
07809
07810
07811
return FALSE;
07812 }
07813
07814
07815
07816
07817
07818
07819
07820
07821
07822
07823
if (ReparseBuffer->MountPointReparseBuffer.SubstituteNameOffset != 0) {
07824
07825
07826
07827
07828
07829
return FALSE;
07830 }
07831
07832
07833
07834
07835
07836
if (ReparseBuffer->MountPointReparseBuffer.PrintNameOffset !=
07837 (ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength +
sizeof( UNICODE_NULL )) ) {
07838
07839
07840
07841
07842
07843
return FALSE;
07844 }
07845
07846
07847
07848
07849
07850
07851
if (ReparseBuffer->ReparseDataLength !=
07852 (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) - REPARSE_DATA_BUFFER_HEADER_SIZE) +
07853 ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength +
07854 ReparseBuffer->MountPointReparseBuffer.PrintNameLength +
07855 2 *
sizeof( UNICODE_NULL )) {
07856
07857
07858
07859
07860
07861
return FALSE;
07862 }
07863
07864
07865
07866
07867
07868
07869 {
07870
07871
07872
07873
07874
07875
07876
07877
07878
if ((ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength > 6) &&
07879 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] ==
L'\\') &&
07880 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[1] ==
L'\\') &&
07881 !((ReparseBuffer->MountPointReparseBuffer.PathBuffer[2] ==
L'.') ||
07882 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[2] ==
L'?'))) {
07883
07884
07885
07886
07887
07888
return FALSE;
07889 }
07890
07891
07892
07893
07894
07895
07896
if ((ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength > 16) &&
07897 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] ==
L'\\') &&
07898 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[1] ==
L'?') &&
07899 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[2] ==
L'?') &&
07900 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[3] ==
L'\\') &&
07901 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[4] ==
L'U') &&
07902 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[5] ==
L'N') &&
07903 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[6] ==
L'C') &&
07904 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[7] ==
L'\\')) {
07905
07906
07907
07908
07909
07910
return FALSE;
07911 }
07912
07913
07914
07915
07916
07917
07918
07919
if ((ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength > 12) &&
07920 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] ==
L'\\') &&
07921 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[1] ==
L'?') &&
07922 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[2] ==
L'?') &&
07923 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[3] ==
L'\\') &&
07924 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[5] ==
L':')) {
07925
07926
NTSTATUS status;
07927 UNICODE_STRING linkValue;
07928 OBJECT_ATTRIBUTES objectAttributes;
07929 HANDLE linkHandle;
07930 PWCHAR linkValueBuffer =
NULL;
07931 WCHAR pathNameValue[
sizeof(
L"\\??\\C:\0")];
07932
07933 RtlCopyMemory( &pathNameValue,
L"\\??\\C:\0",
sizeof(
L"\\??\\C:\0") );
07934
07935
RtlInitUnicodeString( &drivePath, pathNameValue );
07936
07937
07938
07939
07940
07941 drivePath.Buffer[4] = ReparseBuffer->MountPointReparseBuffer.PathBuffer[4];
07942
07943 InitializeObjectAttributes( &objectAttributes,
07944 &drivePath,
07945 OBJ_CASE_INSENSITIVE,
07946 (HANDLE)
NULL,
07947 (PSECURITY_DESCRIPTOR)
NULL );
07948
07949 status = ZwOpenSymbolicLinkObject( &linkHandle,
07950 SYMBOLIC_LINK_QUERY,
07951 &objectAttributes );
07952
07953
#if DBG
07954
07955
#endif // DBG
07956
07957
if (
NT_SUCCESS( status ) ) {
07958
07959
07960
07961
07962
07963 linkValueBuffer =
ExAllocatePoolWithTag(
NonPagedPool,
07964 2 * 260,
07965 ' oI' );
07966
if ( !linkValueBuffer ) {
07967
07968
07969
07970
07971
07972
NtClose( linkHandle );
07973
return FALSE;
07974 }
07975
07976 linkValue.Buffer = linkValueBuffer;
07977 linkValue.Length = 0;
07978 linkValue.MaximumLength = (
USHORT)(2 * 260);
07979
07980 status = ZwQuerySymbolicLinkObject( linkHandle,
07981 &linkValue,
07982
NULL );
07983
NtClose( linkHandle );
07984
07985
#if DBG
07986
07987
#endif // DBG
07988
07989
if (
NT_SUCCESS( status ) ) {
07990
07991
07992
07993
07994
07995
07996
if ((linkValue.Buffer[ 0] ==
L'\\') &&
07997 (linkValue.Buffer[ 1] ==
L'D') &&
07998 (linkValue.Buffer[ 2] ==
L'e') &&
07999 (linkValue.Buffer[ 3] ==
L'v') &&
08000 (linkValue.Buffer[ 4] ==
L'i') &&
08001 (linkValue.Buffer[ 5] ==
L'c') &&
08002 (linkValue.Buffer[ 6] ==
L'e') &&
08003 (linkValue.Buffer[ 7] ==
L'\\') &&
08004 (linkValue.Buffer[ 8] ==
L'L') &&
08005 (linkValue.Buffer[ 9] ==
L'a') &&
08006 (linkValue.Buffer[10] ==
L'n') &&
08007 (linkValue.Buffer[14] ==
L'R') &&
08008 (linkValue.Buffer[15] ==
L'e') &&
08009 (linkValue.Buffer[16] ==
L'd') &&
08010 (linkValue.Buffer[17] ==
L'i') &&
08011 (linkValue.Buffer[18] ==
L'r') &&
08012 (linkValue.Buffer[23] ==
L'r') &
08013 (linkValue.Buffer[24] ==
L'\\')) {
08014
08015
08016
08017
08018
08019
ExFreePool( linkValueBuffer );
08020
08021
return FALSE;
08022 }
08023
08024
08025
08026
08027
08028
08029
08030
08031
if (!((linkValue.Buffer[ 0] ==
L'\\') &&
08032 (linkValue.Buffer[ 1] ==
L'D') &&
08033 (linkValue.Buffer[ 2] ==
L'e') &&
08034 (linkValue.Buffer[ 3] ==
L'v') &&
08035 (linkValue.Buffer[ 4] ==
L'i') &&
08036 (linkValue.Buffer[ 5] ==
L'c') &&
08037 (linkValue.Buffer[ 6] ==
L'e') &&
08038 (linkValue.Buffer[ 7] ==
L'\\') &&
08039 (linkValue.Buffer[ 8] ==
L'H') &&
08040 (linkValue.Buffer[ 9] ==
L'a') &&
08041 (linkValue.Buffer[10] ==
L'r') &&
08042 (linkValue.Buffer[11] ==
L'd') &&
08043 (linkValue.Buffer[12] ==
L'd') &&
08044 (linkValue.Buffer[13] ==
L'i') &&
08045 (linkValue.Buffer[14] ==
L's') &&
08046 (linkValue.Buffer[15] ==
L'k'))) {
08047
08048
08049
08050
08051
08052
ExFreePool( linkValueBuffer );
08053
08054
return FALSE;
08055 }
08056 }
08057
08058
08059
08060
08061
08062
ExFreePool( linkValueBuffer );
08063 }
08064 }
08065 }
08066
08067
08068
08069
08070
08071
08072
08073
08074
08075 {
08076 UNICODE_STRING volumeName;
08077
08078
if (
08079
08080
08081
08082
08083
08084 ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength < 12 ) {
08085
08086
return FALSE;
08087 }
08088
08089
08090
08091
08092
08093
08094
08095
08096 volumeName.Length =
08097 volumeName.MaximumLength = ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength;
08098 volumeName.Buffer = (PWSTR) ReparseBuffer->MountPointReparseBuffer.PathBuffer;
08099
08100
08101
08102
08103
08104
08105
if ( !((ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] ==
L'\\') &&
08106 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[1] ==
L'?') &&
08107 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[2] ==
L'?') &&
08108 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[3] ==
L'\\') &&
08109
08110
08111
08112 (ReparseBuffer->MountPointReparseBuffer.PathBuffer[5] ==
L':'))
08113
08114 &&
08115
08116 !MOUNTMGR_IS_VOLUME_NAME( &volumeName ) ) {
08117
08118
return FALSE;
08119 }
08120 }
08121
08122
08123
08124
08125
08126
return TRUE;
08127 }
08128
08129
VOID
08130 IopDoNameTransmogrify(
08131 IN
PIRP Irp,
08132 IN
PFILE_OBJECT FileObject,
08133 IN PREPARSE_DATA_BUFFER ReparseBuffer
08134 )
08135
08136
08137
08138
08139
08140
08141
08142
08143
08144
08145
08146
08147
08148
08149
08150
08151
08152
08153
08154
08155
08156
08157
08158
08159
08160
08161
08162
08163 {
08164
USHORT pathLength = 0;
08165
USHORT neededBufferLength = 0;
08166 PVOID outBuffer =
NULL;
08167 PWSTR pathBuffer =
NULL;
08168
08169
08170
08171
08172
08173
08174
ASSERT(
Irp->
IoStatus.Status == STATUS_REPARSE );
08175
ASSERT(
Irp->
IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT );
08176
08177
ASSERT(
Irp->
Tail.Overlay.AuxiliaryBuffer !=
NULL );
08178
08179
ASSERT( ReparseBuffer !=
NULL );
08180
ASSERT( ReparseBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT );
08181
ASSERT( ReparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
08182
ASSERT( ReparseBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
08183
08184
#if DBG
08185
08186
08187
#endif // DBG
08188
08189
08190
08191
08192
08193
08194
08195
08196
08197
if (ReparseBuffer->ReparseDataLength >=
08198 (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) - REPARSE_DATA_BUFFER_HEADER_SIZE)) {
08199
08200
if (MAXIMUM_REPARSE_DATA_BUFFER_SIZE <
08201 (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) +
08202 ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength +
08203 ReparseBuffer->MountPointReparseBuffer.PrintNameLength)) {
08204
08205
Irp->
IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
08206 }
08207 }
else {
08208
Irp->
IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
08209 }
08210
08211
08212
08213
08214
08215
08216
08217
08218
08219
08220
08221
08222
08223
if (
NT_SUCCESS(
Irp->
IoStatus.Status )) {
08224
08225 pathBuffer = (PWSTR)((PCHAR)ReparseBuffer->MountPointReparseBuffer.PathBuffer +
08226 ReparseBuffer->MountPointReparseBuffer.SubstituteNameOffset);
08227 pathLength = ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength;
08228 }
08229
08230
08231
08232
08233
08234
08235
08236
08237
08238
08239
08240
if (ReparseBuffer->Reserved < 0) {
08241
08242
08243
08244
08245
08246
Irp->
IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
08247 }
08248
08249
if (
NT_SUCCESS(
Irp->
IoStatus.Status )) {
08250
08251
08252
08253
08254
08255
08256
if (((
USHORT)MAXUSHORT - ReparseBuffer->Reserved ) > (pathLength +(
USHORT)
sizeof(UNICODE_NULL))) {
08257 neededBufferLength = pathLength + ReparseBuffer->Reserved +
sizeof( UNICODE_NULL );
08258
08259
08260
08261
08262
if (FileObject->FileName.MaximumLength < neededBufferLength) {
08263 outBuffer =
ExAllocatePoolWithTag(
PagedPool,
08264 neededBufferLength,
08265 'cFoI' );
08266
if (!outBuffer) {
08267
Irp->
IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
08268 }
08269 }
else {
08270 outBuffer = FileObject->FileName.Buffer;
08271 }
08272 }
else {
08273
Irp->
IoStatus.Status = STATUS_NAME_TOO_LONG;
08274 }
08275 }
08276
08277
08278
08279
08280
08281
08282
08283
if (
NT_SUCCESS(
Irp->
IoStatus.Status )) {
08284
08285
if (ReparseBuffer->Reserved) {
08286
08287 RtlMoveMemory ( (PCHAR)outBuffer + pathLength,
08288 (PCHAR)FileObject->FileName.Buffer +
08289 (FileObject->FileName.Length - ReparseBuffer->Reserved),
08290 ReparseBuffer->Reserved );
08291 }
08292
08293
08294
08295
08296
08297
08298
if (pathLength) {
08299
08300 RtlCopyMemory( (PCHAR)outBuffer,
08301 (PCHAR)pathBuffer,
08302 pathLength );
08303 }
08304
08305 FileObject->FileName.Length = neededBufferLength -
sizeof( UNICODE_NULL );
08306
08307
08308
08309
08310
08311
if (outBuffer != FileObject->FileName.Buffer) {
08312
08313
if (FileObject->FileName.Buffer !=
NULL) {
08314
ExFreePool( FileObject->FileName.Buffer );
08315 }
08316 FileObject->FileName.Buffer = outBuffer;
08317 FileObject->FileName.MaximumLength = neededBufferLength;
08318 ((PWSTR)outBuffer)[ (neededBufferLength /
sizeof( WCHAR ))-1 ] = UNICODE_NULL;
08319 }
08320 }
08321
08322
08323
08324
08325
08326
08327
ExFreePool( ReparseBuffer );
08328 ReparseBuffer =
NULL;
08329
08330
08331
08332
08333
08334
Irp->
IoStatus.Information = IO_REPARSE_TAG_RESERVED_ZERO;
08335 }
08336
08337
PIRP
08338 IoMakeAssociatedIrp(
08339 IN
PIRP Irp,
08340 IN CCHAR StackSize
08341 )
08342
08343
08344
08345
08346
08347
08348
08349
08350
08351
08352
08353
08354
08355
08356
08357
08358
08359
08360
08361
08362
08363
08364
08365
08366
08367
08368
08369 {
08370
USHORT allocateSize;
08371 UCHAR fixedSize;
08372
PIRP associatedIrp;
08373
PNPAGED_LOOKASIDE_LIST lookasideList;
08374 UCHAR mustSucceed;
08375
PP_NPAGED_LOOKASIDE_NUMBER number;
08376
USHORT packetSize;
08377 PKPRCB prcb;
08378
08379
08380
08381
08382
08383
08384
08385 associatedIrp =
NULL;
08386 fixedSize = 0;
08387 mustSucceed = 0;
08388 packetSize =
IoSizeOfIrp(StackSize);
08389 allocateSize = packetSize;
08390
if (StackSize <= (CCHAR)
IopLargeIrpStackLocations) {
08391 fixedSize =
IRP_ALLOCATED_FIXED_SIZE;
08392 number =
LookasideSmallIrpList;
08393
if (StackSize != 1) {
08394 allocateSize =
IoSizeOfIrp((CCHAR)
IopLargeIrpStackLocations);
08395 number =
LookasideLargeIrpList;
08396 }
08397
08398 prcb =
KeGetCurrentPrcb();
08399 lookasideList = prcb->PPLookasideList[number].P;
08400 lookasideList->
L.
TotalAllocates += 1;
08401 associatedIrp = (
PIRP)
ExInterlockedPopEntrySList(&lookasideList->
L.
ListHead,
08402 &lookasideList->
Lock);
08403
08404
if (associatedIrp ==
NULL) {
08405 lookasideList->
L.
AllocateMisses += 1;
08406 lookasideList = prcb->PPLookasideList[number].
L;
08407 lookasideList->
L.
TotalAllocates += 1;
08408 associatedIrp = (
PIRP)
ExInterlockedPopEntrySList(&lookasideList->
L.
ListHead,
08409 &lookasideList->
Lock);
08410 }
08411 }
08412
08413
08414
08415
08416
08417
08418
if (!associatedIrp) {
08419
if (fixedSize != 0) {
08420 lookasideList->
L.
AllocateMisses += 1;
08421 }
08422
08423
08424
08425
08426
08427
08428
08429 associatedIrp =
ExAllocatePoolWithTag(
NonPagedPool, allocateSize, ' prI');
08430
if (!associatedIrp) {
08431
if (KeGetPreviousMode() ==
KernelMode) {
08432 mustSucceed =
IRP_ALLOCATED_MUST_SUCCEED;
08433 associatedIrp =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
08434 allocateSize,
08435 ' prI' );
08436 }
08437
08438
if (!associatedIrp) {
08439
return NULL;
08440 }
08441 }
08442
08443 }
08444
08445
08446
08447
08448
08449
IopInitializeIrp(associatedIrp, packetSize, StackSize);
08450 associatedIrp->
Flags |=
IRP_ASSOCIATED_IRP;
08451 associatedIrp->
AllocationFlags |= (fixedSize | mustSucceed);
08452
08453
08454
08455
08456
08457 associatedIrp->
Tail.Overlay.Thread =
Irp->
Tail.Overlay.Thread;
08458
08459
08460
08461
08462
08463 associatedIrp->
AssociatedIrp.MasterIrp =
Irp;
08464
return associatedIrp;
08465 }
08466
08467 BOOLEAN
08468 IoPageFileCreated(
08469 IN HANDLE FileHandle
08470 )
08471
08472
08473
08474
08475
08476
08477
08478
08479
08480
08481
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491
08492
08493
08494
08495
08496
08497 {
08498
PFILE_OBJECT fileObject;
08499
PDEVICE_OBJECT deviceObject;
08500
NTSTATUS status;
08501 BOOLEAN result;
08502
08503
PAGED_CODE();
08504
08505
return IopConfigureCrashDump( FileHandle );
08506 }
08507
08508
NTSTATUS
08509 IoPageRead(
08510 IN
PFILE_OBJECT FileObject,
08511 IN
PMDL MemoryDescriptorList,
08512 IN PLARGE_INTEGER StartingOffset,
08513 IN
PKEVENT Event,
08514 OUT PIO_STATUS_BLOCK IoStatusBlock
08515 )
08516
08517
08518
08519
08520
08521
08522
08523
08524
08525
08526
08527
08528
08529
08530
08531
08532
08533
08534
08535
08536
08537
08538
08539
08540
08541
08542
08543
08544
08545
08546
08547
08548
08549
08550
08551
08552
08553
08554
08555
08556
08557
08558
08559 {
08560
PIRP irp;
08561
PIO_STACK_LOCATION irpSp;
08562
PDEVICE_OBJECT deviceObject;
08563
08564
08565
08566
08567
08568
08569
if (
MmIsRecursiveIoFault()) {
08570 *
CcMissCounter += (MemoryDescriptorList->ByteCount +
PAGE_SIZE - 1) >>
PAGE_SHIFT;
08571 }
08572
08573
08574
08575
08576
08577
08578 deviceObject =
IoGetRelatedDeviceObject( FileObject );
08579
08580
08581
08582
08583
08584 irp =
IoAllocateIrp( deviceObject->
StackSize,
FALSE );
08585
if (!irp) {
08586
return STATUS_INSUFFICIENT_RESOURCES;
08587 }
08588
08589
08590
08591
08592
08593
08594
08595 irpSp =
IoGetNextIrpStackLocation( irp );
08596
08597
08598
08599
08600
08601 irp->
MdlAddress = MemoryDescriptorList;
08602 irp->
Flags =
IRP_PAGING_IO |
IRP_NOCACHE |
IRP_SYNCHRONOUS_PAGING_IO |
IRP_INPUT_OPERATION;
08603 irp->
RequestorMode =
KernelMode;
08604 irp->
UserIosb = IoStatusBlock;
08605 irp->
UserEvent =
Event;
08606 irp->
UserBuffer = (PVOID) ((PCHAR) MemoryDescriptorList->StartVa + MemoryDescriptorList->ByteOffset);
08607 irp->
Tail.Overlay.OriginalFileObject = FileObject;
08608 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
08609
08610
08611
08612
08613
08614 irpSp->
MajorFunction =
IRP_MJ_READ;
08615 irpSp->
FileObject = FileObject;
08616 irpSp->
Parameters.Read.Length = MemoryDescriptorList->ByteCount;
08617 irpSp->
Parameters.Read.ByteOffset = *StartingOffset;
08618
08619
08620
08621
08622
08623
08624
return IoCallDriver( deviceObject, irp );
08625 }
08626
08627
NTSTATUS
08628 IoQueryFileInformation(
08629 IN
PFILE_OBJECT FileObject,
08630 IN FILE_INFORMATION_CLASS FileInformationClass,
08631 IN ULONG Length,
08632 OUT PVOID FileInformation,
08633 OUT PULONG ReturnedLength
08634 )
08635
08636
08637
08638
08639
08640
08641
08642
08643
08644
08645
08646
08647
08648
08649
08650
08651
08652
08653
08654
08655
08656
08657
08658
08659
08660
08661
08662
08663
08664
08665
08666
08667 {
08668
PAGED_CODE();
08669
08670
08671
08672
08673
08674
return IopQueryXxxInformation( FileObject,
08675 FileInformationClass,
08676 Length,
08677 FileInformation,
08678 ReturnedLength,
08679
TRUE );
08680 }
08681
08682
NTSTATUS
08683 IoQueryVolumeInformation(
08684 IN
PFILE_OBJECT FileObject,
08685 IN FS_INFORMATION_CLASS FsInformationClass,
08686 IN ULONG Length,
08687 OUT PVOID FsInformation,
08688 OUT PULONG ReturnedLength
08689 )
08690
08691
08692
08693
08694
08695
08696
08697
08698
08699
08700
08701
08702
08703
08704
08705
08706
08707
08708
08709
08710
08711
08712
08713
08714
08715
08716
08717
08718
08719
08720
08721
08722 {
08723
PAGED_CODE();
08724
08725
08726
08727
08728
08729
return IopQueryXxxInformation( FileObject,
08730 FsInformationClass,
08731 Length,
08732 FsInformation,
08733 ReturnedLength,
08734
FALSE );
08735 }
08736
08737
VOID
08738 IoQueueThreadIrp(
08739 IN
PIRP Irp
08740 )
08741
08742
08743
08744
08745
08746
08747
08748
08749
08750
08751
08752
08753
08754
08755
08756
08757
08758
08759
08760 {
08761
08762
08763
08764
08765
IopQueueThreadIrp(
Irp );
08766 }
08767
08768
VOID
08769 IoRaiseHardError(
08770 IN
PIRP Irp,
08771 IN
PVPB Vpb OPTIONAL,
08772 IN
PDEVICE_OBJECT RealDeviceObject
08773 )
08774
08775
08776
08777
08778
08779
08780
08781
08782
08783
08784
08785
08786
08787
08788
08789
08790
08791
08792
08793
08794
08795
08796
08797
08798
08799
08800
08801
08802
08803
08804
08805
08806
08807
08808
08809
08810 {
08811
PIO_STACK_LOCATION IrpSp;
08812
08813
08814
08815
08816
08817
08818
if (
Irp->
Tail.Overlay.Thread->HardErrorsAreDisabled) {
08819
08820
08821
08822
08823
08824
08825
08826
if (
Irp->
Flags &
IRP_INPUT_OPERATION) {
08827
Irp->
IoStatus.Information = 0;
08828 }
08829
08830
IoCompleteRequest(
Irp,
IO_DISK_INCREMENT );
08831
08832
return;
08833 }
08834
08835
08836
08837
08838
08839
08840
08841
08842
08843 IrpSp =
IoGetCurrentIrpStackLocation(
Irp);
08844
08845
if ((
Irp->
Flags == (
IRP_PAGING_IO |
08846
IRP_NOCACHE |
08847
IRP_SYNCHRONOUS_PAGING_IO |
08848
IRP_INPUT_OPERATION)) ||
08849 (IrpSp->
MajorFunction ==
IRP_MJ_CLEANUP)) {
08850
08851
PIOP_APC_HARD_ERROR_PACKET packet;
08852
08853 packet =
ExAllocatePoolWithTag(
NonPagedPool,
08854
sizeof(
IOP_APC_HARD_ERROR_PACKET ),
08855 'rEoI' );
08856
08857
if ( packet ==
NULL ) {
08858
08859
IoCompleteRequest(
Irp,
IO_DISK_INCREMENT );
08860
return;
08861 }
08862
08863
ExInitializeWorkItem( &packet->
Item,
IopStartApcHardError, packet );
08864 packet->
Irp =
Irp;
08865 packet->
Vpb = Vpb;
08866 packet->
RealDeviceObject = RealDeviceObject;
08867
08868
ExQueueWorkItem( &packet->
Item,
CriticalWorkQueue );
08869
08870 }
else {
08871
08872
PKAPC apc;
08873
08874
08875
08876
08877
08878
08879 apc =
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(
KAPC ), 'CPAK' );
08880
08881
08882
08883
08884
08885
08886
if ( apc ==
NULL ) {
08887
08888
IoCompleteRequest(
Irp,
IO_DISK_INCREMENT );
08889
return;
08890 }
08891
08892
KeInitializeApc( apc,
08893 &
Irp->
Tail.Overlay.Thread->Tcb,
08894
Irp->
ApcEnvironment,
08895
IopDeallocateApc,
08896
IopAbortRequest,
08897
IopRaiseHardError,
08898
KernelMode,
08899
Irp );
08900
08901 (
VOID)
KeInsertQueueApc( apc,
08902 Vpb,
08903 RealDeviceObject,
08904 0 );
08905 }
08906 }
08907
08908 BOOLEAN
08909 IoRaiseInformationalHardError(
08910 IN NTSTATUS ErrorStatus,
08911 IN PUNICODE_STRING String OPTIONAL,
08912 IN
PKTHREAD Thread OPTIONAL
08913 )
08914
08915
08916
08917
08918
08919
08920
08921
08922
08923
08924
08925
08926
08927
08928
08929
08930
08931
08932
08933
08934
08935
08936
08937
08938
08939
08940
08941
08942
08943
08944
08945
08946
08947
08948
08949
08950
08951
08952 #define
ArePacketsEquivalent(P1,P2) ( \
08953 (P1->ErrorStatus == P2->ErrorStatus) && \
08954 ((!P1->String.Buffer && !P2->String.Buffer) || \
08955 ((P1->String.Length == P2->String.Length) && \
08956 (RtlEqualMemory(P1->String.Buffer, \
08957 P2->String.Buffer, \
08958 P1->String.Length)))) \
08959 )
08960
08961 {
08962 KIRQL oldIrql;
08963 PVOID stringBuffer;
08964 PLIST_ENTRY links;
08965
08966
PIOP_HARD_ERROR_PACKET hardErrorPacket;
08967
08968
08969
08970
08971
08972
if (ARGUMENT_PRESENT(Thread) ?
08973 CONTAINING_RECORD(Thread,
ETHREAD, Tcb)->HardErrorsAreDisabled :
08974
PsGetCurrentThread()->HardErrorsAreDisabled) {
08975
08976
return FALSE;
08977 }
08978
08979
08980
08981
08982
08983
if ( ErrorStatus == STATUS_VDM_HARD_ERROR ||
08984 ErrorStatus == STATUS_UNHANDLED_EXCEPTION ||
08985 ErrorStatus == STATUS_SERVICE_NOTIFICATION ) {
08986
return FALSE;
08987 }
08988
08989
08990
08991
08992
08993
08994
08995
if ( !ARGUMENT_PRESENT( Thread ) &&
08996 (
KeReadStateSemaphore( &
IopHardError.
WorkQueueSemaphore ) >=
08997
IOP_MAXIMUM_OUTSTANDING_HARD_ERRORS) ) {
08998
08999
return FALSE;
09000 }
else {
09001
if (
IopHardError.
NumPendingApcPopups >
IOP_MAXIMUM_OUTSTANDING_HARD_ERRORS) {
09002
return FALSE;
09003 }
09004 }
09005
09006
09007
09008
09009
09010 hardErrorPacket =
ExAllocatePoolWithTag(
NonPagedPool,
09011
sizeof(
IOP_HARD_ERROR_PACKET),
09012 'rEoI');
09013
09014
if (!hardErrorPacket) {
return FALSE; }
09015
09016
09017
09018
09019
09020 RtlZeroMemory( hardErrorPacket,
sizeof(
IOP_HARD_ERROR_PACKET) );
09021
09022 hardErrorPacket->
ErrorStatus = ErrorStatus;
09023
09024
09025
09026
09027
09028
if ( ARGUMENT_PRESENT(
String ) &&
String->Length ) {
09029
09030 stringBuffer =
ExAllocatePoolWithTag(
NonPagedPool,
09031
String->Length,
09032 'rEoI' );
09033
09034
if (!stringBuffer) {
09035
ExFreePool( hardErrorPacket );
09036
return FALSE;
09037 }
09038
09039 hardErrorPacket->
String.Length =
String->Length;
09040 hardErrorPacket->
String.MaximumLength =
String->Length;
09041
09042 hardErrorPacket->
String.Buffer = stringBuffer;
09043
09044 RtlCopyMemory( stringBuffer,
String->Buffer,
String->Length );
09045 }
09046
09047
09048
09049
09050
09051
09052
if ( ARGUMENT_PRESENT( Thread ) ) {
09053
09054
PKAPC apc;
09055
09056
09057
09058
09059
09060
09061 apc =
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(
KAPC ), 'CPAK' );
09062
09063
09064
09065
09066
09067
09068
if ( apc ==
NULL ) {
09069
09070
if ( hardErrorPacket->
String.Buffer ) {
09071
ExFreePool( hardErrorPacket->
String.Buffer );
09072 }
09073
09074
ExFreePool( hardErrorPacket );
09075
09076
return FALSE;
09077 }
09078
09079 InterlockedIncrement(&
IopHardError.
NumPendingApcPopups);
09080
KeInitializeApc( apc,
09081 Thread,
09082
CurrentApcEnvironment,
09083
IopDeallocateApc,
09084
NULL,
09085
IopRaiseInformationalHardError,
09086
KernelMode,
09087 hardErrorPacket );
09088
09089 (
VOID)
KeInsertQueueApc( apc,
NULL,
NULL, 0 );
09090
09091 }
else {
09092
09093
09094
09095
09096
09097 ExAcquireSpinLock( &
IopHardError.
WorkQueueSpinLock, &oldIrql );
09098
09099
09100
09101
09102
09103
if (
KeReadStateSemaphore( &
IopHardError.
WorkQueueSemaphore ) >=
09104
IOP_MAXIMUM_OUTSTANDING_HARD_ERRORS ) {
09105
09106 ExReleaseSpinLock( &
IopHardError.
WorkQueueSpinLock, oldIrql );
09107
09108
if ( hardErrorPacket->
String.Buffer ) {
09109
ExFreePool( hardErrorPacket->
String.Buffer );
09110 }
09111
ExFreePool( hardErrorPacket );
09112
return FALSE;
09113 }
09114
09115
09116
09117
09118
09119
if (
IopCurrentHardError &&
09120
ArePacketsEquivalent( hardErrorPacket,
IopCurrentHardError )) {
09121
09122 ExReleaseSpinLock( &
IopHardError.
WorkQueueSpinLock, oldIrql );
09123
09124
if ( hardErrorPacket->
String.Buffer ) {
09125
ExFreePool( hardErrorPacket->
String.Buffer );
09126 }
09127
ExFreePool( hardErrorPacket );
09128
return FALSE;
09129 }
09130
09131
09132
09133
09134
09135 links =
IopHardError.
WorkQueue.Flink;
09136
09137
while (links != &
IopHardError.
WorkQueue) {
09138
09139
PIOP_HARD_ERROR_PACKET queueHardErrorPacket;
09140
09141 queueHardErrorPacket = CONTAINING_RECORD( links,
09142
IOP_HARD_ERROR_PACKET,
09143 WorkQueueLinks );
09144
09145
if (
ArePacketsEquivalent( hardErrorPacket,
09146 queueHardErrorPacket )) {
09147
09148 ExReleaseSpinLock( &
IopHardError.
WorkQueueSpinLock, oldIrql );
09149
09150
if ( hardErrorPacket->
String.Buffer ) {
09151
ExFreePool( hardErrorPacket->
String.Buffer );
09152 }
09153
ExFreePool( hardErrorPacket );
09154
return FALSE;
09155 }
09156
09157 links = links->Flink;
09158 }
09159
09160
09161
09162
09163
09164 InsertTailList( &
IopHardError.
WorkQueue,
09165 &hardErrorPacket->
WorkQueueLinks );
09166
09167
09168
09169
09170
09171
09172 (
VOID)
KeReleaseSemaphore( &
IopHardError.
WorkQueueSemaphore,
09173 0,
09174 1
L,
09175
FALSE );
09176
09177
09178
09179
09180
09181
09182
if ( !
IopHardError.
ThreadStarted ) {
09183
IopHardError.
ThreadStarted =
TRUE;
09184
ExQueueWorkItem( &
IopHardError.
ExWorkItem,
DelayedWorkQueue );
09185 }
09186
09187
09188
09189
09190
09191
09192
09193 ExReleaseSpinLock( &
IopHardError.
WorkQueueSpinLock, oldIrql );
09194 }
09195
09196
return TRUE;
09197 }
09198
09199
VOID
09200 IoRegisterBootDriverReinitialization(
09201 IN
PDRIVER_OBJECT DriverObject,
09202 IN PDRIVER_REINITIALIZE DriverReinitializationRoutine,
09203 IN PVOID Context
09204 )
09205
09206
09207
09208
09209
09210
09211
09212
09213
09214
09215
09216
09217
09218
09219
09220
09221
09222
09223
09224
09225
09226
09227
09228
09229
09230
09231
09232
09233 {
09234
PREINIT_PACKET reinitEntry;
09235
09236
PAGED_CODE();
09237
09238
09239
09240
09241
09242
09243
09244 reinitEntry =
ExAllocatePoolWithTag(
NonPagedPool,
09245
sizeof(
REINIT_PACKET ),
09246 'iRoI' );
09247
if (!reinitEntry) {
09248
return;
09249 }
09250
09251 DriverObject->Flags |=
DRVO_BOOTREINIT_REGISTERED;
09252 reinitEntry->
DriverObject = DriverObject;
09253 reinitEntry->
DriverReinitializationRoutine = DriverReinitializationRoutine;
09254 reinitEntry->
Context = Context;
09255
09256
ExInterlockedInsertTailList( &
IopBootDriverReinitializeQueueHead,
09257 &reinitEntry->
ListEntry,
09258 &
IopDatabaseLock );
09259 }
09260
09261
VOID
09262 IoRegisterDriverReinitialization(
09263 IN
PDRIVER_OBJECT DriverObject,
09264 IN PDRIVER_REINITIALIZE DriverReinitializationRoutine,
09265 IN PVOID Context
09266 )
09267
09268
09269
09270
09271
09272
09273
09274
09275
09276
09277
09278
09279
09280
09281
09282
09283
09284
09285
09286
09287
09288
09289
09290
09291
09292
09293
09294
09295 {
09296
PREINIT_PACKET reinitEntry;
09297
09298
PAGED_CODE();
09299
09300
09301
09302
09303
09304
09305
09306 reinitEntry =
ExAllocatePoolWithTag(
NonPagedPool,
09307
sizeof(
REINIT_PACKET ),
09308 'iRoI' );
09309
if (!reinitEntry) {
09310
return;
09311 }
09312
09313 DriverObject->Flags |=
DRVO_REINIT_REGISTERED;
09314 reinitEntry->
DriverObject = DriverObject;
09315 reinitEntry->
DriverReinitializationRoutine = DriverReinitializationRoutine;
09316 reinitEntry->
Context = Context;
09317
09318
ExInterlockedInsertTailList( &
IopDriverReinitializeQueueHead,
09319 &reinitEntry->
ListEntry,
09320 &
IopDatabaseLock );
09321 }
09322
09323
VOID
09324 IoRegisterFileSystem(
09325 IN OUT
PDEVICE_OBJECT DeviceObject
09326 )
09327
09328
09329
09330
09331
09332
09333
09334
09335
09336
09337
09338
09339
09340
09341
09342
09343
09344
09345
09346 {
09347
PNOTIFICATION_PACKET nPacket;
09348 PLIST_ENTRY listHead =
NULL;
09349 PLIST_ENTRY entry;
09350
09351
PAGED_CODE();
09352
09353
09354
09355
09356
09357 (
VOID)
ExAcquireResourceExclusive( &
IopDatabaseResource,
TRUE );
09358
09359
09360
09361
09362
09363
09364
09365
if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) {
09366 listHead = &
IopNetworkFileSystemQueueHead;
09367 }
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
09368 listHead = &
IopCdRomFileSystemQueueHead;
09369 }
else if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) {
09370 listHead = &
IopDiskFileSystemQueueHead;
09371 }
else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM) {
09372 listHead = &
IopTapeFileSystemQueueHead;
09373 }
09374
09375
09376
09377
09378
09379
09380
if (listHead !=
NULL) {
09381
if (DeviceObject->Flags &
DO_LOW_PRIORITY_FILESYSTEM ) {
09382 InsertTailList( listHead->Blink,
09383 &DeviceObject->Queue.ListEntry );
09384 }
else {
09385 InsertHeadList( listHead,
09386 &DeviceObject->Queue.ListEntry );
09387 }
09388 }
09389
09390
09391
09392
09393
09394 DeviceObject->Flags &= ~
DO_DEVICE_INITIALIZING;
09395
09396
09397
09398
09399
09400
09401 entry =
IopFsNotifyChangeQueueHead.Flink;
09402
while (entry != &
IopFsNotifyChangeQueueHead) {
09403 nPacket = CONTAINING_RECORD( entry,
NOTIFICATION_PACKET, ListEntry );
09404 entry = entry->Flink;
09405 nPacket->
NotificationRoutine( DeviceObject,
TRUE );
09406 }
09407
09408
09409
09410
09411
09412
ExReleaseResource( &
IopDatabaseResource );
09413
09414
09415
09416
09417
09418
ExInterlockedAddUlong( &DeviceObject->ReferenceCount, 1, &
IopDatabaseLock );
09419 }
09420
09421
NTSTATUS
09422 IoRegisterFsRegistrationChange(
09423 IN
PDRIVER_OBJECT DriverObject,
09424 IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine
09425 )
09426
09427
09428
09429
09430
09431
09432
09433
09434
09435
09436
09437
09438
09439
09440
09441
09442
09443
09444
09445
09446
09447
09448 {
09449
PNOTIFICATION_PACKET nPacket;
09450
09451
PAGED_CODE();
09452
09453
09454
09455
09456
09457
09458 nPacket =
ExAllocatePoolWithTag(
PagedPool,
09459
sizeof(
NOTIFICATION_PACKET ),
09460 'sFoI' );
09461
if (!nPacket) {
09462
return STATUS_INSUFFICIENT_RESOURCES;
09463 }
09464
09465
09466
09467
09468
09469
09470 nPacket->
DriverObject = DriverObject;
09471 nPacket->
NotificationRoutine = DriverNotificationRoutine;
09472
09473
ExAcquireResourceExclusive( &
IopDatabaseResource,
TRUE );
09474 InsertTailList( &
IopFsNotifyChangeQueueHead, &nPacket->
ListEntry );
09475
ExReleaseResource( &
IopDatabaseResource );
09476
09477
09478
09479
09480
09481
ObReferenceObject( DriverObject );
09482
09483
return STATUS_SUCCESS;
09484 }
09485
09486
NTSTATUS
09487 IoRegisterLastChanceShutdownNotification(
09488 IN
PDEVICE_OBJECT DeviceObject
09489 )
09490
09491
09492
09493
09494
09495
09496
09497
09498
09499
09500
09501
09502
09503
09504
09505
09506
09507
09508
09509
09510 {
09511
PSHUTDOWN_PACKET shutdown;
09512
09513
PAGED_CODE();
09514
09515
09516
09517
09518
09519
09520 shutdown =
ExAllocatePoolWithTag(
NonPagedPool,
09521
sizeof(
SHUTDOWN_PACKET ),
09522 'hSoI' );
09523
if (!shutdown) {
09524
return STATUS_INSUFFICIENT_RESOURCES;
09525 }
09526
09527
09528
09529
09530
09531
09532
09533 shutdown->
DeviceObject = DeviceObject;
09534
09535
ExInterlockedInsertHeadList( &
IopNotifyLastChanceShutdownQueueHead,
09536 &shutdown->
ListEntry,
09537 &
IopDatabaseLock );
09538
09539
09540
09541
09542
09543
09544 DeviceObject->Flags |=
DO_SHUTDOWN_REGISTERED;
09545
09546
return STATUS_SUCCESS;
09547 }
09548
09549
NTSTATUS
09550 IoRegisterShutdownNotification(
09551 IN
PDEVICE_OBJECT DeviceObject
09552 )
09553
09554
09555
09556
09557
09558
09559
09560
09561
09562
09563
09564
09565
09566
09567
09568
09569
09570
09571
09572
09573 {
09574
PSHUTDOWN_PACKET shutdown;
09575
09576
PAGED_CODE();
09577
09578
09579
09580
09581
09582
09583 shutdown =
ExAllocatePoolWithTag(
NonPagedPool,
09584
sizeof(
SHUTDOWN_PACKET ),
09585 'hSoI' );
09586
if (!shutdown) {
09587
return STATUS_INSUFFICIENT_RESOURCES;
09588 }
09589
09590
09591
09592
09593
09594
09595
09596 shutdown->
DeviceObject = DeviceObject;
09597
09598
ExInterlockedInsertHeadList( &
IopNotifyShutdownQueueHead,
09599 &shutdown->
ListEntry,
09600 &
IopDatabaseLock );
09601
09602
09603
09604
09605
09606
09607 DeviceObject->Flags |=
DO_SHUTDOWN_REGISTERED;
09608
09609
return STATUS_SUCCESS;
09610 }
09611
09612
VOID
09613 IoReleaseCancelSpinLock(
09614 IN KIRQL Irql
09615 )
09616
09617
09618
09619
09620
09621
09622
09623
09624
09625
09626
09627
09628
09629
09630
09631
09632
09633
09634
09635 {
09636
09637
09638
09639
09640 ExReleaseSpinLock( &
IopCancelSpinLock, Irql );
09641 }
09642
09643
VOID
09644 IoReleaseVpbSpinLock(
09645 IN KIRQL Irql
09646 )
09647
09648
09649
09650
09651
09652
09653
09654
09655
09656
09657
09658
09659
09660
09661
09662
09663
09664
09665
09666 {
09667
09668
09669
09670
09671 ExReleaseSpinLock( &
IopVpbSpinLock, Irql );
09672 }
09673
09674
VOID
09675 IoRemoveShareAccess(
09676 IN
PFILE_OBJECT FileObject,
09677 IN OUT
PSHARE_ACCESS ShareAccess
09678 )
09679
09680
09681
09682
09683
09684
09685
09686
09687
09688
09689
09690
09691
09692
09693
09694
09695
09696
09697
09698
09699
09700 {
09701
PAGED_CODE();
09702
09703
09704
09705
09706
09707
09708
09709
09710
if (FileObject->ReadAccess ||
09711 FileObject->WriteAccess ||
09712 FileObject->DeleteAccess) {
09713
09714
09715
09716
09717
09718 ShareAccess->OpenCount--;
09719
09720
09721
09722
09723
09724
09725
if (FileObject->ReadAccess) {
09726 ShareAccess->Readers--;
09727 }
09728
09729
if (FileObject->WriteAccess) {
09730 ShareAccess->Writers--;
09731 }
09732
09733
if (FileObject->DeleteAccess) {
09734 ShareAccess->Deleters--;
09735 }
09736
09737
09738
09739
09740
09741
09742
if (FileObject->SharedRead) {
09743 ShareAccess->SharedRead--;
09744 }
09745
09746
if (FileObject->SharedWrite) {
09747 ShareAccess->SharedWrite--;
09748 }
09749
09750
if (FileObject->SharedDelete) {
09751 ShareAccess->SharedDelete--;
09752 }
09753 }
09754 }
09755
09756
VOID
09757 IoSetDeviceToVerify(
09758 IN
PETHREAD Thread,
09759 IN
PDEVICE_OBJECT DeviceObject
09760 )
09761
09762
09763
09764
09765
09766
09767
09768
09769
09770
09771
09772
09773
09774
09775
09776
09777
09778
09779
09780
09781
09782
09783
09784
09785
09786
09787 {
09788
09789
09790
09791
09792 Thread->DeviceToVerify = DeviceObject;
09793 }
09794
09795
VOID
09796 IoSetHardErrorOrVerifyDevice(
09797 IN
PIRP Irp,
09798 IN
PDEVICE_OBJECT DeviceObject
09799 )
09800
09801
09802
09803
09804
09805
09806
09807
09808
09809
09810
09811
09812
09813
09814
09815
09816
09817
09818
09819
09820
09821
09822 {
09823
09824
09825
09826
09827
09828
09829
ASSERT(
Irp->
Tail.Overlay.Thread !=
NULL );
09830
09831
Irp->
Tail.Overlay.Thread->DeviceToVerify = DeviceObject;
09832 }
09833
09834
NTSTATUS
09835 IoSetInformation(
09836 IN
PFILE_OBJECT FileObject,
09837 IN FILE_INFORMATION_CLASS FileInformationClass,
09838 IN ULONG Length,
09839 IN PVOID FileInformation
09840 )
09841
09842
09843
09844
09845
09846
09847
09848
09849
09850
09851
09852
09853
09854
09855
09856
09857
09858
09859
09860
09861
09862
09863
09864
09865
09866
09867
09868
09869
09870
09871 {
09872
PIRP irp;
09873
NTSTATUS status;
09874
PDEVICE_OBJECT deviceObject;
09875
KEVENT event;
09876
PIO_STACK_LOCATION irpSp;
09877 IO_STATUS_BLOCK localIoStatus;
09878 HANDLE targetHandle =
NULL;
09879 BOOLEAN synchronousIo;
09880
09881
PAGED_CODE();
09882
09883
09884
09885
09886
09887
09888
09889
ObReferenceObject( FileObject );
09890
09891
09892
09893
09894
09895
09896
09897
09898
if (FileObject->Flags &
FO_SYNCHRONOUS_IO) {
09899
09900 BOOLEAN interrupted;
09901
09902
if (!
IopAcquireFastLock( FileObject )) {
09903 status =
IopAcquireFileObjectLock( FileObject,
09904
KernelMode,
09905 (BOOLEAN) ((FileObject->Flags &
FO_ALERTABLE_IO) != 0),
09906 &interrupted );
09907
if (interrupted) {
09908
ObDereferenceObject( FileObject );
09909
return status;
09910 }
09911 }
09912
KeClearEvent( &FileObject->Event );
09913 synchronousIo =
TRUE;
09914 }
else {
09915
KeInitializeEvent( &event, SynchronizationEvent,
FALSE );
09916 synchronousIo =
FALSE;
09917 }
09918
09919
09920
09921
09922
09923 deviceObject =
IoGetRelatedDeviceObject( FileObject );
09924
09925
09926
09927
09928
09929
09930
09931 irp =
IoAllocateIrp( deviceObject->
StackSize,
TRUE );
09932
if (!irp) {
09933
09934
09935
09936
09937
09938
09939
IopAllocateIrpCleanup( FileObject, (
PKEVENT)
NULL );
09940
09941
return STATUS_INSUFFICIENT_RESOURCES;
09942 }
09943 irp->
Tail.Overlay.OriginalFileObject = FileObject;
09944 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
09945 irp->
RequestorMode =
KernelMode;
09946
09947
09948
09949
09950
09951
if (synchronousIo) {
09952 irp->
UserEvent = (
PKEVENT)
NULL;
09953 }
else {
09954 irp->
UserEvent = &event;
09955 irp->
Flags =
IRP_SYNCHRONOUS_API;
09956 }
09957 irp->
UserIosb = &localIoStatus;
09958
09959
09960
09961
09962
09963
09964 irpSp =
IoGetNextIrpStackLocation( irp );
09965 irpSp->
MajorFunction =
IRP_MJ_SET_INFORMATION;
09966 irpSp->
FileObject = FileObject;
09967
09968
09969
09970
09971
09972
09973 irp->
AssociatedIrp.SystemBuffer = FileInformation;
09974 irp->
Flags |=
IRP_BUFFERED_IO;
09975
09976
09977
09978
09979
09980 irpSp->
Parameters.SetFile.Length = Length;
09981 irpSp->
Parameters.SetFile.FileInformationClass = FileInformationClass;
09982
09983
09984
09985
09986
09987
IopQueueThreadIrp( irp );
09988
09989
09990
09991
09992
09993
09994
09995
09996
09997
09998
if (FileInformationClass == FileModeInformation) {
09999
10000 PFILE_MODE_INFORMATION modeBuffer = FileInformation;
10001
10002
10003
10004
10005
10006
if (!(FileObject->Flags &
FO_NO_INTERMEDIATE_BUFFERING)) {
10007
if (modeBuffer->Mode & FILE_WRITE_THROUGH) {
10008 FileObject->Flags |=
FO_WRITE_THROUGH;
10009 }
else {
10010 FileObject->Flags &= ~
FO_WRITE_THROUGH;
10011 }
10012 }
10013
10014
if (modeBuffer->Mode & FILE_SEQUENTIAL_ONLY) {
10015 FileObject->Flags |=
FO_SEQUENTIAL_ONLY;
10016 }
else {
10017 FileObject->Flags &= ~
FO_SEQUENTIAL_ONLY;
10018 }
10019
10020
if (modeBuffer->Mode &
FO_SYNCHRONOUS_IO) {
10021
if (modeBuffer->Mode & FILE_SYNCHRONOUS_IO_ALERT) {
10022 FileObject->Flags |=
FO_ALERTABLE_IO;
10023 }
else {
10024 FileObject->Flags &= ~
FO_ALERTABLE_IO;
10025 }
10026 }
10027
10028 status = STATUS_SUCCESS;
10029
10030
10031
10032
10033
10034 irp->
IoStatus.Status = status;
10035 irp->
IoStatus.Information = 0;
10036
10037
IoSetNextIrpStackLocation( irp );
10038
IoCompleteRequest( irp, 0 );
10039
10040 }
else if (FileInformationClass == FileRenameInformation ||
10041 FileInformationClass == FileLinkInformation ||
10042 FileInformationClass == FileMoveClusterInformation) {
10043
10044
10045
10046
10047
10048
10049 PFILE_RENAME_INFORMATION renameBuffer = FileInformation;
10050
10051
10052
10053
10054
10055
10056
10057
if (FileInformationClass == FileMoveClusterInformation) {
10058 irpSp->
Parameters.SetFile.ClusterCount =
10059 ((FILE_MOVE_CLUSTER_INFORMATION *) renameBuffer)->ClusterCount;
10060 }
else {
10061 irpSp->
Parameters.SetFile.ReplaceIfExists = renameBuffer->ReplaceIfExists;
10062 }
10063
10064
10065
10066
10067
10068
10069
if (renameBuffer->FileName[0] == (UCHAR) OBJ_NAME_PATH_SEPARATOR ||
10070 renameBuffer->RootDirectory !=
NULL) {
10071
10072
10073
10074
10075
10076
10077
10078
10079 status =
IopOpenLinkOrRenameTarget( &targetHandle,
10080 irp,
10081 renameBuffer,
10082 FileObject );
10083
if (!
NT_SUCCESS( status )) {
10084
IoSetNextIrpStackLocation( irp );
10085
IoCompleteRequest( irp, 2 );
10086
10087 }
else {
10088
10089
10090
10091
10092
10093
10094
10095 status =
IoCallDriver( deviceObject, irp );
10096
10097 }
10098
10099 }
else {
10100
10101
10102
10103
10104
10105
10106
10107 status =
IoCallDriver( deviceObject, irp );
10108
10109 }
10110
10111 }
else {
10112
10113
10114
10115
10116
10117
10118 status =
IoCallDriver( deviceObject, irp );
10119
10120 }
10121
10122
10123
10124
10125
10126
10127
10128
10129
if (synchronousIo) {
10130
if (status == STATUS_PENDING) {
10131 status =
KeWaitForSingleObject( &FileObject->Event,
10132
Executive,
10133
KernelMode,
10134 (BOOLEAN) ((FileObject->Flags &
FO_ALERTABLE_IO) != 0),
10135 (PLARGE_INTEGER)
NULL );
10136
if (status == STATUS_ALERTED) {
10137
IopCancelAlertedRequest( &FileObject->Event, irp );
10138 }
10139 status = localIoStatus.Status;
10140 }
10141
IopReleaseFileObjectLock( FileObject );
10142
10143 }
else {
10144
10145
10146
10147
10148
10149
10150
10151
10152
if (status == STATUS_PENDING) {
10153 (
VOID)
KeWaitForSingleObject( &event,
10154
Executive,
10155
KernelMode,
10156
FALSE,
10157 (PLARGE_INTEGER)
NULL );
10158 status = localIoStatus.Status;
10159 }
10160 }
10161
10162
10163
10164
10165
10166
10167
if (targetHandle != (HANDLE)
NULL) {
10168
NtClose( targetHandle );
10169 }
10170
10171
return status;
10172 }
10173
10174
VOID
10175 IoSetShareAccess(
10176 IN ACCESS_MASK DesiredAccess,
10177 IN ULONG DesiredShareAccess,
10178 IN OUT
PFILE_OBJECT FileObject,
10179 OUT
PSHARE_ACCESS ShareAccess
10180 )
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206 {
10207
PAGED_CODE();
10208
10209
10210
10211
10212
10213 FileObject->ReadAccess = (BOOLEAN) ((DesiredAccess & (FILE_EXECUTE
10214 | FILE_READ_DATA)) != 0);
10215 FileObject->WriteAccess = (BOOLEAN) ((DesiredAccess & (FILE_WRITE_DATA
10216 | FILE_APPEND_DATA)) != 0);
10217 FileObject->DeleteAccess = (BOOLEAN) ((DesiredAccess & DELETE) != 0);
10218
10219
10220
10221
10222
10223
10224
10225
if (FileObject->ReadAccess ||
10226 FileObject->WriteAccess ||
10227 FileObject->DeleteAccess) {
10228
10229
10230
10231
10232
10233
10234 FileObject->SharedRead = (BOOLEAN) ((DesiredShareAccess & FILE_SHARE_READ) != 0);
10235 FileObject->SharedWrite = (BOOLEAN) ((DesiredShareAccess & FILE_SHARE_WRITE) != 0);
10236 FileObject->SharedDelete = (BOOLEAN) ((DesiredShareAccess & FILE_SHARE_DELETE) != 0);
10237
10238
10239
10240
10241
10242 ShareAccess->OpenCount = 1;
10243
10244
10245
10246
10247
10248
10249 ShareAccess->Readers = FileObject->ReadAccess;
10250 ShareAccess->Writers = FileObject->WriteAccess;
10251 ShareAccess->Deleters = FileObject->DeleteAccess;
10252
10253
10254
10255
10256
10257
10258 ShareAccess->SharedRead = FileObject->SharedRead;
10259 ShareAccess->SharedWrite = FileObject->SharedWrite;
10260 ShareAccess->SharedDelete = FileObject->SharedDelete;
10261
10262 }
else {
10263
10264
10265
10266
10267
10268
10269
10270 ShareAccess->OpenCount = 0;
10271 ShareAccess->Readers = 0;
10272 ShareAccess->Writers = 0;
10273 ShareAccess->Deleters = 0;
10274 ShareAccess->SharedRead = 0;
10275 ShareAccess->SharedWrite = 0;
10276 ShareAccess->SharedDelete = 0;
10277 }
10278 }
10279
10280 BOOLEAN
10281 IoSetThreadHardErrorMode(
10282 IN BOOLEAN EnableHardErrors
10283 )
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304 {
10305
PETHREAD thread;
10306 BOOLEAN oldFlag;
10307
10308
10309
10310
10311
10312
10313 thread =
PsGetCurrentThread();
10314 oldFlag = !thread->
HardErrorsAreDisabled;
10315 thread->
HardErrorsAreDisabled = !EnableHardErrors;
10316
10317
return oldFlag;
10318 }
10319
10320
VOID
10321 IoSetTopLevelIrp(
10322 IN
PIRP Irp
10323 )
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348 {
10349
10350
10351
10352
10353
10354 (
PIRP) (
PsGetCurrentThread())->TopLevelIrp =
Irp;
10355
return;
10356 }
10357
10358
VOID
10359 IoShutdownSystem (
10360 IN ULONG Phase
10361 )
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382 {
10383 PLIST_ENTRY entry;
10384
PSHUTDOWN_PACKET shutdown;
10385
PDEVICE_OBJECT deviceObject;
10386
PIRP irp;
10387
KEVENT event;
10388 IO_STATUS_BLOCK ioStatus;
10389 PVOID unlockHandle;
10390
10391
PAGED_CODE();
10392
10393
10394
10395
10396
10397
10398
KeInitializeEvent( &event, NotificationEvent,
FALSE );
10399
10400
if (Phase == 0) {
10401
10402
10403
10404
10405
10406
10407
10408
while ((entry =
ExInterlockedRemoveHeadList( &
IopNotifyShutdownQueueHead, &
IopDatabaseLock )) !=
NULL) {
10409 shutdown = CONTAINING_RECORD( entry,
SHUTDOWN_PACKET, ListEntry );
10410
10411
10412
10413
10414
10415
10416 deviceObject =
IoGetAttachedDevice( shutdown->
DeviceObject );
10417
10418 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_SHUTDOWN,
10419 deviceObject,
10420 (PVOID)
NULL,
10421 0,
10422 (PLARGE_INTEGER)
NULL,
10423 &event,
10424 &ioStatus );
10425
10426
if (
IoCallDriver( deviceObject, irp ) == STATUS_PENDING) {
10427
#if DBG
10428
PUNICODE_STRING DeviceName = ObGetObjectName( shutdown->
DeviceObject );
10429
10430
DbgPrint(
"IO: Waiting for shutdown of device object (%x) - %wZ\n",
10431 shutdown->
DeviceObject,
10432 DeviceName
10433 );
10434
#endif // DBG
10435
(
VOID)
KeWaitForSingleObject( &event,
10436
Executive,
10437
KernelMode,
10438
FALSE,
10439 (PLARGE_INTEGER)
NULL );
10440 }
10441
10442
ExFreePool( shutdown );
10443
KeClearEvent( &event );
10444 }
10445
10446 }
else if (Phase == 1) {
10447
10448
#if defined(REMOTE_BOOT)
10449
10450
10451
10452
10453
10454 IopShutdownCsc();
10455
#endif // defined(REMOTE_BOOT)
10456
10457
10458
10459
10460
10461
ExAcquireResourceShared( &
IopDatabaseResource,
TRUE );
10462
10463
10464
10465
10466
10467
10468
for (entry =
IopDiskFileSystemQueueHead.Flink;
10469 entry != &
IopDiskFileSystemQueueHead;
10470 entry = entry->Flink) {
10471
10472 deviceObject = CONTAINING_RECORD( entry,
DEVICE_OBJECT, Queue.ListEntry );
10473
if (deviceObject->
AttachedDevice) {
10474 deviceObject =
IoGetAttachedDevice( deviceObject );
10475 }
10476
10477
10478
10479
10480
10481
10482 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_SHUTDOWN,
10483 deviceObject,
10484 (PVOID)
NULL,
10485 0,
10486 (PLARGE_INTEGER)
NULL,
10487 &event,
10488 &ioStatus );
10489
if (
IoCallDriver( deviceObject, irp ) == STATUS_PENDING) {
10490
#if DBG
10491
PUNICODE_STRING DeviceName = ObGetObjectName( deviceObject );
10492
10493
DbgPrint(
"IO: Waiting for shutdown of device object (%x) - %wZ\n",
10494 deviceObject,
10495 DeviceName
10496 );
10497
#endif // DBG
10498
(
VOID)
KeWaitForSingleObject( &event,
10499
Executive,
10500
KernelMode,
10501
FALSE,
10502 (PLARGE_INTEGER)
NULL );
10503 }
10504
10505
KeClearEvent( &event );
10506 }
10507
10508
10509
10510
10511
10512
10513
10514
while ((entry =
ExInterlockedRemoveHeadList( &
IopNotifyLastChanceShutdownQueueHead, &
IopDatabaseLock )) !=
NULL) {
10515 shutdown = CONTAINING_RECORD( entry,
SHUTDOWN_PACKET, ListEntry );
10516
10517
10518
10519
10520
10521
10522 deviceObject =
IoGetAttachedDevice( shutdown->
DeviceObject );
10523
10524 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_SHUTDOWN,
10525 deviceObject,
10526 (PVOID)
NULL,
10527 0,
10528 (PLARGE_INTEGER)
NULL,
10529 &event,
10530 &ioStatus );
10531
10532
if (
IoCallDriver( deviceObject, irp ) == STATUS_PENDING) {
10533
#if DBG
10534
PUNICODE_STRING DeviceName = ObGetObjectName( shutdown->
DeviceObject );
10535
10536
DbgPrint(
"IO: Waiting for last chance shutdown of device object (%x) - %wZ\n",
10537 shutdown->
DeviceObject,
10538 DeviceName
10539 );
10540
#endif // DBG
10541
(
VOID)
KeWaitForSingleObject( &event,
10542
Executive,
10543
KernelMode,
10544
FALSE,
10545 (PLARGE_INTEGER)
NULL );
10546 }
10547
10548
ExFreePool( shutdown );
10549
KeClearEvent( &event );
10550 }
10551
10552
10553
10554
10555
10556
10557
10558 }
10559
10560
return ;
10561 }
10562
10563
VOID
10564 IoStartNextPacket(
10565 IN
PDEVICE_OBJECT DeviceObject,
10566 IN BOOLEAN Cancelable
10567 )
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590 {
10591 KIRQL cancelIrql;
10592
PIRP irp;
10593
PKDEVICE_QUEUE_ENTRY packet;
10594
10595
10596
10597
10598
10599
10600
if (Cancelable) {
10601
IoAcquireCancelSpinLock( &cancelIrql );
10602 }
10603
10604
10605
10606
10607
10608 DeviceObject->CurrentIrp = (
PIRP)
NULL;
10609
10610
10611
10612
10613
10614
10615 packet =
KeRemoveDeviceQueue( &DeviceObject->DeviceQueue );
10616
10617
if (packet) {
10618 irp = CONTAINING_RECORD( packet,
IRP, Tail.Overlay.DeviceQueueEntry );
10619
10620
10621
10622
10623
10624
10625 DeviceObject->CurrentIrp = irp;
10626
if (Cancelable) {
10627
IoReleaseCancelSpinLock( cancelIrql );
10628 }
10629
10630
10631
10632
10633
10634 DeviceObject->DriverObject->DriverStartIo( DeviceObject, irp );
10635 }
else {
10636
10637
10638
10639
10640
10641
10642
if (Cancelable) {
10643
IoReleaseCancelSpinLock( cancelIrql );
10644 }
10645 }
10646 }
10647
10648
VOID
10649 IoStartNextPacketByKey(
10650 IN
PDEVICE_OBJECT DeviceObject,
10651 IN BOOLEAN Cancelable,
10652 IN ULONG Key
10653 )
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678 {
10679 KIRQL cancelIrql;
10680
PIRP irp;
10681
PKDEVICE_QUEUE_ENTRY packet;
10682
10683
10684
10685
10686
10687
10688
if (Cancelable) {
10689
IoAcquireCancelSpinLock( &cancelIrql );
10690 }
10691
10692
10693
10694
10695
10696 DeviceObject->CurrentIrp = (
PIRP)
NULL;
10697
10698
10699
10700
10701
10702
10703 packet =
KeRemoveByKeyDeviceQueue( &DeviceObject->DeviceQueue,
Key );
10704
10705
if (packet) {
10706 irp = CONTAINING_RECORD( packet,
IRP, Tail.Overlay.DeviceQueueEntry );
10707
10708
10709
10710
10711
10712
10713 DeviceObject->CurrentIrp = irp;
10714
10715
if (Cancelable) {
10716
IoReleaseCancelSpinLock( cancelIrql );
10717 }
10718
10719 DeviceObject->DriverObject->DriverStartIo( DeviceObject, irp );
10720
10721 }
else {
10722
10723
10724
10725
10726
10727
10728
if (Cancelable) {
10729
IoReleaseCancelSpinLock( cancelIrql );
10730 }
10731 }
10732 }
10733
10734
VOID
10735 IoStartPacket(
10736 IN
PDEVICE_OBJECT DeviceObject,
10737 IN
PIRP Irp,
10738 IN PULONG Key OPTIONAL,
10739 IN PDRIVER_CANCEL CancelFunction OPTIONAL
10740 )
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770 {
10771 KIRQL oldIrql;
10772 KIRQL cancelIrql;
10773 BOOLEAN i;
10774
10775
10776
10777
10778
10779
KeRaiseIrql(
DISPATCH_LEVEL, &oldIrql );
10780
10781
10782
10783
10784
10785
10786
10787
10788
if (CancelFunction) {
10789
IoAcquireCancelSpinLock( &cancelIrql );
10790
Irp->
CancelRoutine = CancelFunction;
10791 }
10792
10793
10794
10795
10796
10797
10798
10799
if (
Key) {
10800 i =
KeInsertByKeyDeviceQueue( &DeviceObject->DeviceQueue,
10801 &
Irp->
Tail.Overlay.DeviceQueueEntry,
10802 *
Key );
10803 }
else {
10804 i =
KeInsertDeviceQueue( &DeviceObject->DeviceQueue,
10805 &
Irp->
Tail.Overlay.DeviceQueueEntry );
10806 }
10807
10808
10809
10810
10811
10812
10813
10814
if (!i) {
10815
10816 DeviceObject->CurrentIrp =
Irp;
10817
10818
if (CancelFunction) {
10819
10820
IoReleaseCancelSpinLock( cancelIrql );
10821 }
10822
10823
10824
10825
10826
10827
10828 DeviceObject->DriverObject->DriverStartIo( DeviceObject,
Irp );
10829
10830 }
else {
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
if (CancelFunction) {
10843
if (
Irp->
Cancel) {
10844
Irp->
CancelIrql = cancelIrql;
10845
Irp->
CancelRoutine = (
PDRIVER_CANCEL)
NULL;
10846 CancelFunction( DeviceObject,
Irp );
10847 }
else {
10848
IoReleaseCancelSpinLock( cancelIrql );
10849 }
10850 }
10851 }
10852
10853
10854
10855
10856
10857
10858
KeLowerIrql( oldIrql );
10859 }
10860
10861
10862
VOID
10863 IoStartTimer(
10864 IN
PDEVICE_OBJECT DeviceObject
10865 )
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883 {
10884
PIO_TIMER timer;
10885 KIRQL irql;
10886
10887
10888
10889
10890
10891 timer = DeviceObject->Timer;
10892
10893
10894
10895
10896
10897
if (!(DeviceObject->DeviceObjectExtension->ExtensionFlags &
10898 (
DOE_UNLOAD_PENDING |
DOE_DELETE_PENDING |
DOE_REMOVE_PENDING |
DOE_REMOVE_PROCESSED))) {
10899
10900
10901
10902
10903
10904
10905
10906 ExAcquireFastLock( &
IopTimerLock, &irql );
10907
if (!timer->
TimerFlag) {
10908 timer->
TimerFlag =
TRUE;
10909
IopTimerCount++;
10910 }
10911 ExReleaseFastLock( &
IopTimerLock, irql );
10912 }
10913 }
10914
10915
VOID
10916 IoStopTimer(
10917 IN
PDEVICE_OBJECT DeviceObject
10918 )
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937 {
10938 KIRQL irql;
10939
PIO_TIMER timer;
10940
10941
10942
10943
10944
10945
10946 timer = DeviceObject->Timer;
10947
10948 ExAcquireFastLock( &
IopTimerLock, &irql );
10949
if (timer->
TimerFlag) {
10950 timer->
TimerFlag =
FALSE;
10951
IopTimerCount--;
10952 }
10953 ExReleaseFastLock( &
IopTimerLock, irql );
10954 }
10955
10956
NTSTATUS
10957 IoSynchronousPageWrite(
10958 IN
PFILE_OBJECT FileObject,
10959 IN
PMDL MemoryDescriptorList,
10960 IN PLARGE_INTEGER StartingOffset,
10961 IN
PKEVENT Event,
10962 OUT PIO_STATUS_BLOCK IoStatusBlock
10963 )
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001 {
11002
PIRP irp;
11003
PIO_STACK_LOCATION irpSp;
11004
PDEVICE_OBJECT deviceObject;
11005
11006
11007
11008
11009
11010
if (
CcIsFileCached(FileObject)) {
11011
CcDataFlushes += 1;
11012
CcDataPages += (MemoryDescriptorList->ByteCount +
PAGE_SIZE - 1) >>
PAGE_SHIFT;
11013 }
11014
11015
11016
11017
11018
11019
11020 deviceObject =
IoGetRelatedDeviceObject( FileObject );
11021
11022
11023
11024
11025
11026 irp =
IoAllocateIrp( deviceObject->
StackSize,
FALSE );
11027
if (!irp) {
11028
return STATUS_INSUFFICIENT_RESOURCES;
11029 }
11030
11031
11032
11033
11034
11035
11036
11037 irpSp =
IoGetNextIrpStackLocation( irp );
11038
11039
11040
11041
11042
11043 irp->
MdlAddress = MemoryDescriptorList;
11044 irp->
Flags =
IRP_PAGING_IO |
IRP_NOCACHE |
IRP_SYNCHRONOUS_PAGING_IO;
11045
11046 irp->
RequestorMode =
KernelMode;
11047 irp->
UserIosb = IoStatusBlock;
11048 irp->
UserEvent =
Event;
11049 irp->
UserBuffer = (PVOID) ((PCHAR) MemoryDescriptorList->StartVa + MemoryDescriptorList->ByteOffset);
11050 irp->
Tail.Overlay.OriginalFileObject = FileObject;
11051 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
11052
11053
11054
11055
11056
11057 irpSp->
MajorFunction =
IRP_MJ_WRITE;
11058 irpSp->
Parameters.Write.Length = MemoryDescriptorList->ByteCount;
11059 irpSp->
Parameters.Write.ByteOffset = *StartingOffset;
11060 irpSp->
FileObject = FileObject;
11061
11062
11063
11064
11065
11066
11067
return IoCallDriver( deviceObject, irp );
11068 }
11069
11070
PEPROCESS
11071 IoThreadToProcess(
11072 IN
PETHREAD Thread
11073 )
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097 {
11098
11099
11100
11101
11102
return THREAD_TO_PROCESS( Thread );
11103 }
11104
11105
VOID
11106 IoUnregisterFileSystem(
11107 IN OUT
PDEVICE_OBJECT DeviceObject
11108 )
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128 {
11129
PNOTIFICATION_PACKET nPacket;
11130 PLIST_ENTRY entry;
11131
11132
PAGED_CODE();
11133
11134
11135
11136
11137
11138 (
VOID)
ExAcquireResourceExclusive( &
IopDatabaseResource,
TRUE );
11139
11140
11141
11142
11143
11144
11145
11146
11147 RemoveEntryList( &DeviceObject->Queue.ListEntry );
11148
11149
11150
11151
11152
11153
11154 entry =
IopFsNotifyChangeQueueHead.Flink;
11155
while (entry != &
IopFsNotifyChangeQueueHead) {
11156 nPacket = CONTAINING_RECORD( entry,
NOTIFICATION_PACKET, ListEntry );
11157 entry = entry->Flink;
11158 nPacket->
NotificationRoutine( DeviceObject,
FALSE );
11159 }
11160
11161
11162
11163
11164
11165
ExReleaseResource( &
IopDatabaseResource );
11166
11167
11168
11169
11170
11171
ExInterlockedAddUlong( &DeviceObject->ReferenceCount,
11172 0xffffffff,
11173 &
IopDatabaseLock );
11174
11175 }
11176
11177
VOID
11178 IoUnregisterFsRegistrationChange(
11179 IN
PDRIVER_OBJECT DriverObject,
11180 IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine
11181 )
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203 {
11204
PNOTIFICATION_PACKET nPacket;
11205 PLIST_ENTRY entry;
11206
11207
PAGED_CODE();
11208
11209
11210
11211
11212
11213
ExAcquireResourceExclusive( &
IopDatabaseResource,
TRUE );
11214
11215
11216
11217
11218
11219
11220
for (entry =
IopFsNotifyChangeQueueHead.Flink;
11221 entry != &
IopFsNotifyChangeQueueHead;
11222 entry = entry->Flink) {
11223 nPacket = CONTAINING_RECORD( entry,
NOTIFICATION_PACKET, ListEntry );
11224
if (nPacket->
DriverObject == DriverObject &&
11225 nPacket->
NotificationRoutine == DriverNotificationRoutine) {
11226 RemoveEntryList( entry );
11227
ExFreePool( nPacket );
11228
break;
11229 }
11230 }
11231
11232
ExReleaseResource( &
IopDatabaseResource );
11233
11234
ObDereferenceObject( DriverObject );
11235
11236 }
11237
11238
VOID
11239 IoUnregisterShutdownNotification(
11240 IN
PDEVICE_OBJECT DeviceObject
11241 )
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261 {
11262 PLIST_ENTRY entry;
11263
PSHUTDOWN_PACKET shutdown;
11264 KIRQL irql;
11265 PVOID unlockHandle;
11266
11267
PAGED_CODE();
11268
11269
11270
11271
11272
11273 unlockHandle = MmLockPagableCodeSection(
IoUnregisterShutdownNotification );
11274
11275
11276
11277
11278
11279
11280
11281 ExAcquireSpinLock( &
IopDatabaseLock, &irql );
11282
11283
for (entry =
IopNotifyShutdownQueueHead.Flink;
11284 entry != &
IopNotifyShutdownQueueHead;
11285 entry = entry->Flink) {
11286
11287
11288
11289
11290
11291
11292 shutdown = CONTAINING_RECORD( entry,
SHUTDOWN_PACKET, ListEntry );
11293
if (shutdown->
DeviceObject == DeviceObject) {
11294 RemoveEntryList( entry );
11295 entry = entry->Blink;
11296
ExFreePool( shutdown );
11297 }
11298 }
11299
11300
for (entry =
IopNotifyLastChanceShutdownQueueHead.Flink;
11301 entry != &
IopNotifyLastChanceShutdownQueueHead;
11302 entry = entry->Flink) {
11303
11304
11305
11306
11307
11308
11309 shutdown = CONTAINING_RECORD( entry,
SHUTDOWN_PACKET, ListEntry );
11310
if (shutdown->
DeviceObject == DeviceObject) {
11311 RemoveEntryList( entry );
11312 entry = entry->Blink;
11313
ExFreePool( shutdown );
11314 }
11315 }
11316
11317
11318
11319
11320
11321 ExReleaseSpinLock( &
IopDatabaseLock, irql );
11322
11323
MmUnlockPagableImageSection( unlockHandle );
11324
11325 DeviceObject->Flags &= ~
DO_SHUTDOWN_REGISTERED;
11326
11327 }
11328
11329
VOID
11330 IoUpdateShareAccess(
11331 IN OUT
PFILE_OBJECT FileObject,
11332 IN OUT
PSHARE_ACCESS ShareAccess
11333 )
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358 {
11359
PAGED_CODE();
11360
11361
11362
11363
11364
11365
11366
if (FileObject->ReadAccess ||
11367 FileObject->WriteAccess ||
11368 FileObject->DeleteAccess) {
11369
11370
11371
11372
11373
11374
11375 ShareAccess->OpenCount++;
11376
11377 ShareAccess->Readers += FileObject->ReadAccess;
11378 ShareAccess->Writers += FileObject->WriteAccess;
11379 ShareAccess->Deleters += FileObject->DeleteAccess;
11380
11381 ShareAccess->SharedRead += FileObject->SharedRead;
11382 ShareAccess->SharedWrite += FileObject->SharedWrite;
11383 ShareAccess->SharedDelete += FileObject->SharedDelete;
11384 }
11385 }
11386
11387
11388
NTSTATUS
11389 IoVerifyVolume(
11390 IN
PDEVICE_OBJECT DeviceObject,
11391 IN BOOLEAN AllowRawMount
11392 )
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424 {
11425
NTSTATUS status;
11426
KEVENT event;
11427
PIRP irp;
11428 IO_STATUS_BLOCK ioStatus;
11429
PIO_STACK_LOCATION irpSp;
11430 BOOLEAN verifySkipped =
FALSE;
11431
PDEVICE_OBJECT fsDeviceObject;
11432
11433
PAGED_CODE();
11434
11435
11436
11437
11438
11439
11440 status =
KeWaitForSingleObject( &DeviceObject->DeviceLock,
11441
Executive,
11442
KernelMode,
11443
FALSE,
11444 (PLARGE_INTEGER)
NULL );
11445
11446
ASSERT( status == STATUS_SUCCESS );
11447
11448
11449
11450
11451
11452
11453
if (!(DeviceObject->Vpb->Flags &
VPB_MOUNTED)) {
11454
11455 verifySkipped =
TRUE;
11456
11457 status = STATUS_SUCCESS;
11458
11459 }
else {
11460
11461
11462
11463
11464
11465
11466
KeInitializeEvent( &event, NotificationEvent,
FALSE );
11467 status = STATUS_UNSUCCESSFUL;
11468
11469
11470
11471
11472
11473
11474
11475
11476 fsDeviceObject = DeviceObject->
Vpb->
DeviceObject;
11477
while (fsDeviceObject->
AttachedDevice) {
11478 fsDeviceObject = fsDeviceObject->
AttachedDevice;
11479 }
11480 irp =
IoAllocateIrp( fsDeviceObject->
StackSize,
FALSE );
11481
if (!irp) {
11482
11483
KeSetEvent( &DeviceObject->DeviceLock, 0,
FALSE );
11484
return STATUS_INSUFFICIENT_RESOURCES;
11485 }
11486 irp->
Flags =
IRP_MOUNT_COMPLETION |
IRP_SYNCHRONOUS_PAGING_IO;
11487 irp->
RequestorMode =
KernelMode;
11488 irp->
UserEvent = &event;
11489 irp->
UserIosb = &ioStatus;
11490 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
11491 irpSp =
IoGetNextIrpStackLocation( irp );
11492 irpSp->
MajorFunction =
IRP_MJ_FILE_SYSTEM_CONTROL;
11493 irpSp->
MinorFunction =
IRP_MN_VERIFY_VOLUME;
11494 irpSp->
Flags = AllowRawMount ?
SL_ALLOW_RAW_MOUNT : 0;
11495 irpSp->
Parameters.VerifyVolume.Vpb = DeviceObject->Vpb;
11496 irpSp->
Parameters.VerifyVolume.DeviceObject = DeviceObject->Vpb->DeviceObject;
11497
11498 status =
IoCallDriver( fsDeviceObject, irp );
11499
11500
11501
11502
11503
11504
if (status == STATUS_PENDING) {
11505 (
VOID)
KeWaitForSingleObject( &event,
11506
Executive,
11507
KernelMode,
11508
FALSE,
11509 (PLARGE_INTEGER)
NULL );
11510 status = ioStatus.Status;
11511 }
11512 }
11513
11514
11515
11516
11517
11518
11519
if ((status == STATUS_WRONG_VOLUME) || verifySkipped) {
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
IopCreateVpb (DeviceObject);
11530
PoVolumeDevice (DeviceObject);
11531
11532
11533
11534
11535
11536
if (!
NT_SUCCESS(
IopMountVolume( DeviceObject, AllowRawMount,
TRUE,
FALSE ) )) {
11537 DeviceObject->Flags &= ~
DO_VERIFY_VOLUME;
11538 }
11539 }
11540
11541
11542
11543
11544
11545
KeSetEvent( &DeviceObject->DeviceLock, 0,
FALSE );
11546
11547
11548
11549
11550
11551
11552
return status;
11553 }
11554
11555
VOID
11556 IoWriteErrorLogEntry(
11557 IN OUT PVOID ElEntry
11558 )
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578 {
11579
PERROR_LOG_ENTRY entry;
11580 KIRQL oldIrql;
11581
11582
11583
11584
11585
11586
11587
11588 entry = ((
PERROR_LOG_ENTRY) ElEntry) - 1;
11589
11590
if (
IopErrorLogDisabledThisBoot) {
11591
11592
11593
11594
11595
if (entry->
DeviceObject !=
NULL) {
11596
11597
11598
11599
11600
ObDereferenceObject (entry->
DeviceObject);
11601 }
11602
if (entry->
DriverObject !=
NULL) {
11603
ObDereferenceObject (entry->
DriverObject);
11604 }
11605
ExFreePool (entry);
11606
return;
11607
11608 }
11609
11610
11611
11612
11613
11614
KeQuerySystemTime( (PVOID) &entry->
TimeStamp );
11615
11616 ExAcquireSpinLock( &
IopErrorLogLock, &oldIrql );
11617
11618
11619
11620
11621
11622 InsertTailList( &
IopErrorLogListHead, &entry->
ListEntry );
11623
11624
11625
11626
11627
11628
if (!
IopErrorLogPortPending) {
11629
11630
IopErrorLogPortPending =
TRUE;
11631
11632
ExInitializeWorkItem( &
IopErrorLogWorkItem,
IopErrorLogThread,
NULL );
11633
ExQueueWorkItem( &
IopErrorLogWorkItem,
DelayedWorkQueue );
11634
11635 }
11636
11637 ExReleaseSpinLock(&
IopErrorLogLock, oldIrql);
11638 }
11639
11640
NTSTATUS
11641 IoGetBootDiskInformation(
11642 IN OUT
PBOOTDISK_INFORMATION BootDiskInformation,
11643 IN ULONG Size
11644 )
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669 {
11670
PLOADER_PARAMETER_BLOCK LoaderBlock =
NULL;
11671 STRING arcBootDeviceString;
11672 UCHAR deviceNameBuffer[128];
11673 STRING deviceNameString;
11674 UNICODE_STRING deviceNameUnicodeString;
11675
PDEVICE_OBJECT deviceObject;
11676 UCHAR arcNameBuffer[128];
11677 STRING arcNameString;
11678 UNICODE_STRING arcNameUnicodeString;
11679
PFILE_OBJECT fileObject;
11680
NTSTATUS status;
11681 IO_STATUS_BLOCK ioStatusBlock;
11682 DISK_GEOMETRY diskGeometry;
11683 PDRIVE_LAYOUT_INFORMATION driveLayout;
11684 PLIST_ENTRY listEntry;
11685
PARC_DISK_SIGNATURE diskBlock;
11686 ULONG diskNumber;
11687 ULONG partitionNumber;
11688 PCHAR arcName;
11689 PULONG buffer;
11690
PIRP irp;
11691
KEVENT event;
11692 LARGE_INTEGER offset;
11693 ULONG checkSum;
11694 ULONG i;
11695 BOOLEAN singleBiosDiskFound;
11696 BOOLEAN bootDiskFound =
FALSE;
11697 BOOLEAN systemDiskFound =
FALSE;
11698
PARC_DISK_INFORMATION arcInformation;
11699 ULONG totalDriverDisksFound =
IoGetConfigurationInformation()->
DiskCount;
11700 STRING arcSystemDeviceString;
11701 STRING osLoaderPathString;
11702 UNICODE_STRING osLoaderPathUnicodeString;
11703 PARTITION_INFORMATION PartitionInfo;
11704
11705
if (
IopLoaderBlock ==
NULL) {
11706
return STATUS_TOO_LATE;
11707 }
11708
11709
if (
Size <
sizeof(
BOOTDISK_INFORMATION)) {
11710
return STATUS_INVALID_PARAMETER;
11711 }
11712
11713 LoaderBlock = (
PLOADER_PARAMETER_BLOCK)
IopLoaderBlock;
11714 arcInformation = LoaderBlock->
ArcDiskInformation;
11715
11716
11717
11718
11719
11720 singleBiosDiskFound = (arcInformation->
DiskSignatures.Flink->Flink ==
11721 &arcInformation->
DiskSignatures) ? (
TRUE) : (
FALSE);
11722
11723
11724
11725
11726
11727
RtlInitAnsiString( &arcBootDeviceString,
11728 LoaderBlock->
ArcBootDeviceName );
11729
11730
11731
11732
11733
RtlInitAnsiString( &arcSystemDeviceString,
11734 LoaderBlock->
ArcHalDeviceName );
11735
11736
11737
11738
11739
11740
11741
11742
for (diskNumber = 0;
11743 diskNumber < totalDriverDisksFound;
11744 diskNumber++) {
11745
11746
11747
11748
11749
11750
sprintf( deviceNameBuffer,
11751
"\\Device\\Harddisk%d\\Partition0",
11752 diskNumber );
11753
RtlInitAnsiString( &deviceNameString, deviceNameBuffer );
11754 status =
RtlAnsiStringToUnicodeString( &deviceNameUnicodeString,
11755 &deviceNameString,
11756
TRUE );
11757
if (!
NT_SUCCESS( status )) {
11758
continue;
11759 }
11760
11761 status =
IoGetDeviceObjectPointer( &deviceNameUnicodeString,
11762 FILE_READ_ATTRIBUTES,
11763 &fileObject,
11764 &deviceObject );
11765
RtlFreeUnicodeString( &deviceNameUnicodeString );
11766
11767
if (!
NT_SUCCESS( status )) {
11768
continue;
11769 }
11770
11771
11772
11773
11774
11775 irp =
IoBuildDeviceIoControlRequest( IOCTL_DISK_GET_DRIVE_GEOMETRY,
11776 deviceObject,
11777
NULL,
11778 0,
11779 &diskGeometry,
11780
sizeof(DISK_GEOMETRY),
11781
FALSE,
11782 &event,
11783 &ioStatusBlock );
11784
if (!irp) {
11785
ObDereferenceObject( fileObject );
11786
continue;
11787 }
11788
11789
KeInitializeEvent( &event,
11790 NotificationEvent,
11791
FALSE );
11792 status =
IoCallDriver( deviceObject,
11793 irp );
11794
11795
if (status == STATUS_PENDING) {
11796
KeWaitForSingleObject( &event,
11797
Suspended,
11798
KernelMode,
11799
FALSE,
11800
NULL );
11801 status = ioStatusBlock.Status;
11802 }
11803
11804
if (!
NT_SUCCESS( status )) {
11805
ObDereferenceObject( fileObject );
11806
continue;
11807 }
11808
11809
11810
11811
11812
11813 status =
IoReadPartitionTable( deviceObject,
11814 diskGeometry.BytesPerSector,
11815
TRUE,
11816 &driveLayout );
11817
11818
ObDereferenceObject( fileObject );
11819
11820
if (!
NT_SUCCESS( status )) {
11821
continue;
11822 }
11823
11824
11825
11826
11827
11828
if (diskGeometry.BytesPerSector < 512) {
11829 diskGeometry.BytesPerSector = 512;
11830 }
11831
11832
11833
11834
11835
11836
11837
11838
for (listEntry = arcInformation->
DiskSignatures.Flink;
11839 listEntry != &arcInformation->
DiskSignatures;
11840 listEntry = listEntry->Flink) {
11841
11842
11843
11844
11845
11846 diskBlock = CONTAINING_RECORD( listEntry,
11847
ARC_DISK_SIGNATURE,
11848 ListEntry );
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
if ((singleBiosDiskFound && (totalDriverDisksFound == 1)) ||
11859 (diskBlock->
Signature == driveLayout->Signature &&
11860 diskBlock->
ValidPartitionTable)) {
11861
11862
11863
11864
11865
11866
sprintf( deviceNameBuffer,
11867
"\\Device\\Harddisk%d\\Partition0",
11868 diskNumber );
11869
RtlInitAnsiString( &deviceNameString, deviceNameBuffer );
11870 status =
RtlAnsiStringToUnicodeString( &deviceNameUnicodeString,
11871 &deviceNameString,
11872
TRUE );
11873
if (!
NT_SUCCESS( status )) {
11874
continue;
11875 }
11876
11877
11878
11879
11880
11881 arcName = diskBlock->
ArcName;
11882
sprintf( arcNameBuffer,
11883
"\\ArcName\\%s",
11884 arcName );
11885
RtlInitAnsiString( &arcNameString, arcNameBuffer );
11886 status =
RtlAnsiStringToUnicodeString( &arcNameUnicodeString,
11887 &arcNameString,
11888
TRUE );
11889
if (!
NT_SUCCESS( status )) {
11890
continue;
11891 }
11892
11893
11894
11895
11896
11897
for (partitionNumber = 0;
11898 partitionNumber < driveLayout->PartitionCount;
11899 partitionNumber++) {
11900
11901
11902
11903
11904
11905
sprintf( deviceNameBuffer,
11906
"\\Device\\Harddisk%d\\Partition%d",
11907 diskNumber,
11908 partitionNumber+1 );
11909
RtlInitAnsiString( &deviceNameString, deviceNameBuffer );
11910 status =
RtlAnsiStringToUnicodeString(
11911 &deviceNameUnicodeString,
11912 &deviceNameString,
11913
TRUE );
11914
if (!
NT_SUCCESS( status )) {
11915
continue;
11916 }
11917
11918
11919
11920
11921
11922
11923
sprintf( arcNameBuffer,
11924
"%spartition(%d)",
11925 arcName,
11926 partitionNumber+1 );
11927
RtlInitAnsiString( &arcNameString, arcNameBuffer );
11928
if (
RtlEqualString( &arcNameString,
11929 &arcBootDeviceString,
11930
TRUE )) {
11931 BootDiskInformation->BootDeviceSignature =
11932 driveLayout->Signature;
11933
11934
11935
11936
11937 status =
IoGetDeviceObjectPointer(
11938 &deviceNameUnicodeString,
11939 FILE_READ_ATTRIBUTES,
11940 &fileObject,
11941 &deviceObject );
11942
RtlFreeUnicodeString( &deviceNameUnicodeString );
11943
11944
if (!
NT_SUCCESS( status )) {
11945
continue;
11946 }
11947
11948
11949
11950
11951
11952 irp =
IoBuildDeviceIoControlRequest(
11953 IOCTL_DISK_GET_PARTITION_INFO,
11954 deviceObject,
11955
NULL,
11956 0,
11957 &PartitionInfo,
11958
sizeof(PARTITION_INFORMATION),
11959
FALSE,
11960 &event,
11961 &ioStatusBlock );
11962
if (!irp) {
11963
ObDereferenceObject( fileObject );
11964
continue;
11965 }
11966
11967
KeInitializeEvent( &event,
11968 NotificationEvent,
11969
FALSE );
11970 status =
IoCallDriver( deviceObject,
11971 irp );
11972
11973
if (status == STATUS_PENDING) {
11974
KeWaitForSingleObject( &event,
11975
Suspended,
11976
KernelMode,
11977
FALSE,
11978
NULL );
11979 status = ioStatusBlock.Status;
11980 }
11981
11982
if (!
NT_SUCCESS( status )) {
11983
ObDereferenceObject( fileObject );
11984
continue;
11985 }
11986 BootDiskInformation->BootPartitionOffset =
11987 PartitionInfo.StartingOffset.QuadPart;
11988 bootDiskFound =
TRUE;
11989 }
11990
11991
11992
11993
11994
if (
RtlEqualString( &arcNameString,
11995 &arcSystemDeviceString,
11996
TRUE )) {
11997 BootDiskInformation->SystemDeviceSignature =
11998 driveLayout->Signature;
11999
12000
12001
12002
12003 status =
IoGetDeviceObjectPointer(
12004 &deviceNameUnicodeString,
12005 FILE_READ_ATTRIBUTES,
12006 &fileObject,
12007 &deviceObject );
12008
RtlFreeUnicodeString( &deviceNameUnicodeString );
12009
12010
if (!
NT_SUCCESS( status )) {
12011
continue;
12012 }
12013
12014
12015
12016
12017
12018 irp =
IoBuildDeviceIoControlRequest(
12019 IOCTL_DISK_GET_PARTITION_INFO,
12020 deviceObject,
12021
NULL,
12022 0,
12023 &PartitionInfo,
12024
sizeof(PARTITION_INFORMATION),
12025
FALSE,
12026 &event,
12027 &ioStatusBlock );
12028
if (!irp) {
12029
ObDereferenceObject( fileObject );
12030
continue;
12031 }
12032
12033
KeInitializeEvent( &event,
12034 NotificationEvent,
12035
FALSE );
12036 status =
IoCallDriver( deviceObject,
12037 irp );
12038
12039
if (status == STATUS_PENDING) {
12040
KeWaitForSingleObject( &event,
12041
Suspended,
12042
KernelMode,
12043
FALSE,
12044
NULL );
12045 status = ioStatusBlock.Status;
12046 }
12047
12048
if (!
NT_SUCCESS( status )) {
12049
ObDereferenceObject( fileObject );
12050
continue;
12051 }
12052 BootDiskInformation->SystemPartitionOffset =
12053 PartitionInfo.StartingOffset.QuadPart;
12054 systemDiskFound =
TRUE;
12055 }
12056 }
12057 }
12058 }
12059
ExFreePool( driveLayout );
12060 }
12061
return STATUS_SUCCESS;
12062 }
12063
12064
12065
12066
12067
12068
#ifdef IoCallDriver
12069
#undef IoCallDriver
12070
#endif
12071
12072
NTSTATUS
12073 IoCallDriver(
12074 IN
PDEVICE_OBJECT DeviceObject,
12075 IN OUT
PIRP Irp
12076 )
12077 {
12078
return IofCallDriver (DeviceObject,
Irp);
12079 }
12080
12081
12082
12083
#ifdef IoCompleteRequest
12084
#undef IoCompleteRequest
12085
#endif
12086
12087
VOID
12088 IoCompleteRequest(
12089 IN
PIRP Irp,
12090 IN CCHAR PriorityBoost
12091 )
12092 {
12093
IofCompleteRequest (
Irp,
PriorityBoost);
12094 }
12095
12096
12097 PSECURITY_DESCRIPTOR
12098 IopCreateDefaultDeviceSecurityDescriptor(
12099 IN DEVICE_TYPE DeviceType,
12100 IN ULONG DeviceCharacteristics,
12101 IN BOOLEAN DeviceHasName,
12102 IN PUCHAR Buffer,
12103 OUT PACL *AllocatedAcl,
12104 OUT PSECURITY_INFORMATION SecurityInformation OPTIONAL
12105 )
12106 {
12107 PSECURITY_DESCRIPTOR descriptor = (PSECURITY_DESCRIPTOR)
Buffer;
12108
12109
NTSTATUS status;
12110
12111
if(ARGUMENT_PRESENT(SecurityInformation)) {
12112 (*SecurityInformation) = 0;
12113 }
12114
12115 *AllocatedAcl =
NULL;
12116
12117
switch ( DeviceType ) {
12118
12119
case FILE_DEVICE_DISK_FILE_SYSTEM:
12120
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
12121
case FILE_DEVICE_FILE_SYSTEM:
12122
case FILE_DEVICE_TAPE_FILE_SYSTEM: {
12123
12124
12125
12126
12127
12128
RtlCreateSecurityDescriptor(descriptor,
12129 SECURITY_DESCRIPTOR_REVISION );
12130
12131
RtlSetDaclSecurityDescriptor(descriptor,
12132
TRUE,
12133
SePublicDefaultUnrestrictedDacl,
12134
FALSE );
12135
12136
if(ARGUMENT_PRESENT(SecurityInformation)) {
12137 (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
12138 }
12139
12140
break;
12141 }
12142
12143
case FILE_DEVICE_CD_ROM:
12144
case FILE_DEVICE_MASS_STORAGE:
12145
case FILE_DEVICE_DISK:
12146
case FILE_DEVICE_VIRTUAL_DISK:
12147
case FILE_DEVICE_NETWORK_FILE_SYSTEM:
12148
case FILE_DEVICE_DFS_FILE_SYSTEM:
12149
case FILE_DEVICE_NETWORK: {
12150
12151
if ((DeviceHasName) &&
12152 ((DeviceCharacteristics & FILE_FLOPPY_DISKETTE) != 0)) {
12153
12154 status =
RtlCreateSecurityDescriptor(
12155 descriptor,
12156 SECURITY_DESCRIPTOR_REVISION );
12157
12158
ASSERT(
NT_SUCCESS( status ) );
12159
12160 status =
RtlSetDaclSecurityDescriptor(
12161 descriptor,
12162
TRUE,
12163
SePublicOpenUnrestrictedDacl,
12164
FALSE );
12165
12166
ASSERT(
NT_SUCCESS( status ) );
12167
12168
if(ARGUMENT_PRESENT(SecurityInformation)) {
12169 (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
12170 }
12171
12172 }
else {
12173
12174 UCHAR i;
12175 PACL acl;
12176 BOOLEAN aceFound;
12177 BOOLEAN aceFoundForCDROM;
12178 PACCESS_ALLOWED_ACE ace;
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197 acl =
ExAllocatePoolWithTag(
12198
PagedPool,
12199
SePublicDefaultUnrestrictedDacl->AclSize,
12200 'eSoI' );
12201
12202
if (!acl) {
12203
return NULL;
12204 }
12205
12206 RtlCopyMemory( acl,
12207
SePublicDefaultUnrestrictedDacl,
12208
SePublicDefaultUnrestrictedDacl->AclSize );
12209
12210
12211
12212
12213
12214 aceFound =
FALSE;
12215 aceFoundForCDROM =
FALSE;
12216
12217
for ( i = 0, status =
RtlGetAce(acl, 0, &ace);
12218
NT_SUCCESS(status);
12219 i++, status =
RtlGetAce(acl, i, &ace)) {
12220
12221 PSID sid;
12222
12223 sid = &(ace->SidStart);
12224
if (
RtlEqualSid(
SeAliasAdminsSid, sid )) {
12225 PACCESS_MASK mask;
12226
12227 ace->Mask |= ( GENERIC_READ |
12228 GENERIC_WRITE |
12229 GENERIC_EXECUTE );
12230
12231 aceFound =
TRUE;
12232 }
12233
12234
if (DeviceType == FILE_DEVICE_CD_ROM) {
12235
12236
if (
RtlEqualSid(
SeWorldSid, sid )) {
12237 ace->Mask |= GENERIC_READ;
12238 aceFoundForCDROM =
TRUE;
12239 }
12240 }
12241 }
12242
12243
12244
12245
12246
12247
12248
12249
ASSERT(aceFound ==
TRUE);
12250
12251
if (DeviceType == FILE_DEVICE_CD_ROM) {
12252
ASSERT(aceFoundForCDROM ==
TRUE);
12253 }
12254
12255
12256
12257
12258
12259
RtlCreateSecurityDescriptor( descriptor,
12260 SECURITY_DESCRIPTOR_REVISION );
12261
12262
RtlSetDaclSecurityDescriptor( descriptor,
12263
TRUE,
12264 acl,
12265
FALSE );
12266
12267
if(ARGUMENT_PRESENT(SecurityInformation)) {
12268 (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
12269 }
12270
12271 *AllocatedAcl = acl;
12272 }
12273
12274
break;
12275 }
12276
12277
default: {
12278
12279 status =
RtlCreateSecurityDescriptor( descriptor,
12280 SECURITY_DESCRIPTOR_REVISION );
12281
ASSERT(
NT_SUCCESS( status ) );
12282
12283 status =
RtlSetDaclSecurityDescriptor( descriptor,
12284
TRUE,
12285
SePublicOpenUnrestrictedDacl,
12286
FALSE );
12287
12288
if(ARGUMENT_PRESENT(SecurityInformation)) {
12289 (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
12290 }
12291
12292
break;
12293 }
12294 }
12295
12296
return descriptor;
12297 }
12298
12299
12300
NTSTATUS
12301 IoGetRequestorSessionId(
12302 IN
PIRP Irp,
12303 OUT PULONG pSessionId
12304 )
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326 {
12327
PEPROCESS Process;
12328
12329
12330
12331
12332
12333
if (
Irp->
Tail.Overlay.Thread) {
12334 Process =
THREAD_TO_PROCESS(
Irp->
Tail.Overlay.Thread );
12335 *pSessionId = Process->
SessionId;
12336
return(STATUS_SUCCESS);
12337 }
12338
12339 *pSessionId = (ULONG) -1;
12340
return(STATUS_UNSUCCESSFUL);
12341 }
12342
12343
12344
VOID
12345 IopUpdateOtherOperationCount(
12346 VOID
12347 )
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368 {
12369
if (
IoCountOperations ==
TRUE) {
12370
IoOtherOperationCount += 1;
12371
ExInterlockedAddLargeStatistic( &
THREAD_TO_PROCESS(
PsGetCurrentThread())->OtherOperationCount, 1);
12372 }
12373 }
12374
12375
12376
VOID
12377 IopUpdateReadOperationCount(
12378 VOID
12379 )
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401 {
12402
if (
IoCountOperations ==
TRUE) {
12403
IoReadOperationCount += 1;
12404
ExInterlockedAddLargeStatistic( &
THREAD_TO_PROCESS(
PsGetCurrentThread())->ReadOperationCount, 1);
12405 }
12406 }
12407
12408
12409
VOID
12410 IopUpdateWriteOperationCount(
12411 VOID
12412 )
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433 {
12434
if (
IoCountOperations ==
TRUE) {
12435
IoWriteOperationCount += 1;
12436
ExInterlockedAddLargeStatistic( &
THREAD_TO_PROCESS(
PsGetCurrentThread())->WriteOperationCount, 1);
12437 }
12438 }
12439
12440
VOID
12441 IopUpdateOtherTransferCount(
12442 IN ULONG TransferCount
12443 )
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464 {
12465
if (
IoCountOperations ==
TRUE) {
12466
ExInterlockedAddLargeStatistic( &
IoOtherTransferCount, TransferCount );
12467
ExInterlockedAddLargeStatistic( &
THREAD_TO_PROCESS(
PsGetCurrentThread())->OtherTransferCount, TransferCount);
12468 }
12469 }
12470
12471
12472
VOID
12473 IopUpdateReadTransferCount(
12474 IN ULONG TransferCount
12475 )
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496 {
12497
if (
IoCountOperations ==
TRUE) {
12498
ExInterlockedAddLargeStatistic( &
IoReadTransferCount, TransferCount );
12499
ExInterlockedAddLargeStatistic( &
THREAD_TO_PROCESS(
PsGetCurrentThread())->ReadTransferCount, TransferCount);
12500 }
12501 }
12502
12503
VOID
12504 IopUpdateWriteTransferCount(
12505 IN ULONG TransferCount
12506 )
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527 {
12528
if (
IoCountOperations ==
TRUE) {
12529
ExInterlockedAddLargeStatistic( &
IoWriteTransferCount, TransferCount );
12530
ExInterlockedAddLargeStatistic( &
THREAD_TO_PROCESS(
PsGetCurrentThread())->WriteTransferCount, TransferCount);
12531 }
12532 }
12533
12534
VOID
12535 IoCancelFileOpen(
12536 IN
PDEVICE_OBJECT DeviceObject,
12537 IN
PFILE_OBJECT FileObject
12538 )
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571 {
12572
PIRP irp;
12573
PIO_STACK_LOCATION irpSp;
12574
PFAST_IO_DISPATCH fastIoDispatch;
12575
NTSTATUS status;
12576
KEVENT event;
12577 KIRQL irql;
12578 IO_STATUS_BLOCK ioStatusBlock;
12579
PVPB vpb;
12580 BOOLEAN referenceCountDecremented;
12581
12582
12583
12584
12585
12586
12587
ASSERT(!(FileObject->Flags &
FO_HANDLE_CREATED));
12588
12589
12590
12591
12592
12593
12594
KeInitializeEvent( &event, SynchronizationEvent,
FALSE );
12595
12596
12597
12598
12599
12600
KeClearEvent( &FileObject->Event );
12601
12602
12603
12604
12605
12606
12607 irp =
IopAllocateIrpMustSucceed( DeviceObject->StackSize );
12608 irp->
Tail.Overlay.OriginalFileObject = FileObject;
12609 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
12610 irp->
RequestorMode =
KernelMode;
12611
12612
12613
12614
12615
12616 irp->
UserEvent = &event;
12617 irp->
UserIosb = &irp->
IoStatus;
12618 irp->
Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)
NULL;
12619 irp->
Flags =
IRP_SYNCHRONOUS_API |
IRP_CLOSE_OPERATION;
12620
12621
12622
12623
12624
12625
12626
12627 irpSp =
IoGetNextIrpStackLocation( irp );
12628 irpSp->
MajorFunction =
IRP_MJ_CLEANUP;
12629 irpSp->
FileObject = FileObject;
12630
12631
12632
12633
12634
12635
IopQueueThreadIrp( irp );
12636
12637
12638
12639
12640
12641 status =
IoCallDriver( DeviceObject, irp );
12642
12643
12644
12645
12646
12647
if (status == STATUS_PENDING) {
12648 (
VOID)
KeWaitForSingleObject( &event,
12649
UserRequest,
12650
KernelMode,
12651
FALSE,
12652 (PLARGE_INTEGER)
NULL );
12653 }
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
KeRaiseIrql(
APC_LEVEL, &irql );
12667
IopDequeueThreadIrp( irp );
12668
KeLowerIrql( irql );
12669
12670
12671
12672
12673
12674
IoReuseIrp( irp , STATUS_SUCCESS);
12675
12676
12677
12678
12679
12680
KeClearEvent( &FileObject->Event );
12681
KeClearEvent(&event);
12682
12683
12684
12685
12686
12687
12688 irpSp =
IoGetNextIrpStackLocation( irp );
12689
12690
12691
12692
12693
12694 irpSp->
MajorFunction =
IRP_MJ_CLOSE;
12695 irpSp->
FileObject = FileObject;
12696 irp->
UserIosb = &ioStatusBlock;
12697 irp->
UserEvent = &event;
12698 irp->
Tail.Overlay.OriginalFileObject = FileObject;
12699 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
12700 irp->
AssociatedIrp.SystemBuffer = (PVOID)
NULL;
12701 irp->
Flags =
IRP_CLOSE_OPERATION |
IRP_SYNCHRONOUS_API;
12702
12703
12704
12705
12706
12707
IopQueueThreadIrp( irp );
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721 vpb = FileObject->Vpb;
12722
12723
if (vpb && !(FileObject->Flags &
FO_DIRECT_DEVICE_OPEN)) {
12724
ExInterlockedAddUlong( &vpb->
ReferenceCount,
12725 0xffffffff,
12726 &
IopVpbSpinLock );
12727 FileObject->Flags |=
FO_FILE_OPEN_CANCELLED;
12728 }
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741 status =
IoCallDriver( DeviceObject, irp );
12742
12743
if (status == STATUS_PENDING) {
12744 (
VOID)
KeWaitForSingleObject( &event,
12745
Executive,
12746
KernelMode,
12747
FALSE,
12748 (PLARGE_INTEGER)
NULL );
12749 }
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
KeRaiseIrql(
APC_LEVEL, &irql );
12774
IopDequeueThreadIrp( irp );
12775
KeLowerIrql( irql );
12776
12777
IoFreeIrp( irp );
12778
12779 }
12780
12781
VOID
12782 IoRetryIrpCompletions(
12783 VOID
12784 )
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819 {
12820 PLIST_ENTRY header;
12821 PLIST_ENTRY entry;
12822 KIRQL irql;
12823
PETHREAD thread;
12824
PIRP irp;
12825 PVOID saveAuxiliaryPointer =
NULL;
12826
PFILE_OBJECT fileObject;
12827
12828
12829 thread =
PsGetCurrentThread();
12830
12831
ASSERT(KeGetCurrentIrql() ==
APC_LEVEL);
12832
12833
12834
12835
12836
12837
12838 header = &thread->
IrpList;
12839 entry = thread->
IrpList.Flink;
12840
12841
12842
12843
12844
12845
while (header != entry) {
12846
12847 irp = CONTAINING_RECORD( entry,
IRP, ThreadListEntry );
12848 entry = entry->Flink;
12849
12850
if (irp->
Flags &
IRP_RETRY_IO_COMPLETION) {
12851
12852
ASSERT(!(irp->
Flags &
IRP_CREATE_OPERATION));
12853
12854 irp->
Flags &= ~
IRP_RETRY_IO_COMPLETION;
12855 fileObject = irp->
Tail.Overlay.OriginalFileObject;
12856
IopCompleteRequest(
12857 &irp->
Tail.Apc,
12858
NULL,
12859
NULL,
12860 &fileObject,
12861 &saveAuxiliaryPointer);
12862 }
12863 }
12864 }