00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "UdfProcs.h"
00023
00024
00025
00026
00027
00028 #define BugCheckFileId (UDFS_BUG_CHECK_CACHESUP)
00029
00030
00031
00032
00033
00034 #define Dbg (UDFS_DEBUG_LEVEL_CACHESUP)
00035
00036
#ifdef ALLOC_PRAGMA
00037
#pragma alloc_text(PAGE, UdfCompleteMdl)
00038
#pragma alloc_text(PAGE, UdfCreateInternalStream)
00039
#pragma alloc_text(PAGE, UdfDeleteInternalStream)
00040
#pragma alloc_text(PAGE, UdfMapMetadataView)
00041
#pragma alloc_text(PAGE, UdfPurgeVolume)
00042
#endif
00043
00044
00045
VOID
00046 UdfCreateInternalStream (
00047 IN
PIRP_CONTEXT IrpContext,
00048 IN
PVCB Vcb,
00049 IN
PFCB Fcb
00050 )
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 {
00073
PFILE_OBJECT StreamFile =
NULL;
00074 BOOLEAN DecrementReference =
FALSE;
00075
00076
PAGED_CODE();
00077
00078
00079
00080
00081
00082
ASSERT_IRP_CONTEXT( IrpContext );
00083
ASSERT_FCB_INDEX( Fcb );
00084
00085
00086
00087
00088
00089
00090
UdfLockFcb( IrpContext, Fcb );
00091
00092
if (Fcb->FileObject !=
NULL) {
00093
00094
UdfUnlockFcb( IrpContext, Fcb );
00095
return;
00096 }
00097
00098
00099
00100
00101
00102
try {
00103
00104
00105
00106
00107
00108
00109 StreamFile =
IoCreateStreamFileObject(
NULL, Vcb->Vpb->RealDevice );
00110
00111
if (StreamFile ==
NULL) {
00112
00113
UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
00114 }
00115
00116
00117
00118
00119
00120 StreamFile->
ReadAccess =
TRUE;
00121 StreamFile->
WriteAccess =
FALSE;
00122 StreamFile->
DeleteAccess =
FALSE;
00123
00124 StreamFile->
SectionObjectPointer = &Fcb->FcbNonpaged->SegmentObject;
00125
00126
00127
00128
00129
00130
UdfSetFileObject( IrpContext,
00131 StreamFile,
00132
StreamFileOpen,
00133 Fcb,
00134
NULL );
00135
00136
00137
00138
00139
00140
00141
00142
00143
UdfLockVcb( IrpContext, Vcb );
00144
00145
DebugTrace(( +1,
Dbg,
00146
"UdfCreateInternalStream, Fcb %08x Vcb %d/%d Fcb %d/%d\n",
00147 Fcb,
00148 Vcb->VcbReference,
00149 Vcb->VcbUserReference,
00150 Fcb->FcbReference,
00151 Fcb->FcbUserReference ));
00152
00153
UdfIncrementReferenceCounts( IrpContext, Fcb, 2, 0 );
00154
UdfUnlockVcb( IrpContext, Vcb );
00155 DecrementReference =
TRUE;
00156
00157
00158
00159
00160
00161
CcInitializeCacheMap( StreamFile,
00162 (
PCC_FILE_SIZES)&Fcb->AllocationSize,
00163
TRUE,
00164 &
UdfData.
CacheManagerCallbacks,
00165 Fcb );
00166
00167
00168
00169
00170
00171 Fcb->FileObject = StreamFile;
00172 StreamFile =
NULL;
00173
00174 } finally {
00175
00176
DebugUnwind(
"UdfCreateInternalStream" );
00177
00178
00179
00180
00181
00182
if (StreamFile !=
NULL) {
00183
00184
ObDereferenceObject( StreamFile );
00185 Fcb->FileObject =
NULL;
00186 }
00187
00188
00189
00190
00191
00192
if (DecrementReference) {
00193
00194
UdfLockVcb( IrpContext, Vcb );
00195
UdfDecrementReferenceCounts( IrpContext, Fcb, 1, 0 );
00196
00197
DebugTrace(( -1,
Dbg,
00198
"UdfCreateInternalStream, Vcb %d/%d Fcb %d/%d\n",
00199 Vcb->VcbReference,
00200 Vcb->VcbUserReference,
00201 Fcb->FcbReference,
00202 Fcb->FcbUserReference ));
00203
00204
UdfUnlockVcb( IrpContext, Vcb );
00205 }
00206
00207
UdfUnlockFcb( IrpContext, Fcb );
00208 }
00209
00210
return;
00211 }
00212
00213
00214
VOID
00215 UdfDeleteInternalStream (
00216 IN
PIRP_CONTEXT IrpContext,
00217 IN
PFCB Fcb
00218 )
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 {
00240
PFILE_OBJECT FileObject;
00241
00242
PAGED_CODE();
00243
00244
ASSERT_IRP_CONTEXT( IrpContext );
00245
ASSERT_FCB( Fcb );
00246
00247
00248
00249
00250
00251
UdfLockFcb( IrpContext, Fcb );
00252
00253
00254
00255
00256
00257 FileObject = Fcb->FileObject;
00258 Fcb->FileObject =
NULL;
00259
00260
00261
00262
00263
00264
UdfUnlockFcb( IrpContext, Fcb );
00265
00266
00267
00268
00269
00270
if (FileObject !=
NULL) {
00271
00272
if (FileObject->
PrivateCacheMap !=
NULL) {
00273
00274
CcUninitializeCacheMap( FileObject,
NULL,
NULL );
00275 }
00276
00277
ObDereferenceObject( FileObject );
00278 }
00279
00280
return;
00281 }
00282
00283
00284
NTSTATUS
00285 UdfCompleteMdl (
00286 IN
PIRP_CONTEXT IrpContext,
00287 IN
PIRP Irp
00288 )
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 {
00308
PFILE_OBJECT FileObject;
00309
00310
PAGED_CODE();
00311
00312
00313
00314
00315
00316 FileObject =
IoGetCurrentIrpStackLocation(
Irp )->FileObject;
00317
00318
CcMdlReadComplete( FileObject,
Irp->
MdlAddress );
00319
00320
00321
00322
00323
00324
Irp->
MdlAddress =
NULL;
00325
00326
00327
00328
00329
00330
UdfCompleteRequest( IrpContext,
Irp, STATUS_SUCCESS );
00331
00332
return STATUS_SUCCESS;
00333 }
00334
00335
00336
VOID
00337 UdfMapMetadataView (
00338 IN
PIRP_CONTEXT IrpContext,
00339 IN
PMAPPED_PVIEW View,
00340 IN
PVCB Vcb,
00341 IN USHORT Partition,
00342 IN ULONG Lbn,
00343 IN ULONG Length
00344 )
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 {
00371 LARGE_INTEGER
Offset;
00372 ULONG Vsn;
00373
00374
ASSERT_IRP_CONTEXT( IrpContext );
00375
00376
00377
00378
00379
00380
UdfUnpinView( IrpContext, View );
00381
00382
00383
00384
00385
00386 View->Partition = Partition;
00387 View->Lbn = Lbn;
00388 View->Length = Length;
00389
00390
00391
00392
00393
00394 Vsn =
UdfLookupMetaVsnOfExtent( IrpContext,
00395 Vcb,
00396 Partition,
00397 Lbn,
00398 Length,
00399
FALSE );
00400
00401
Offset.QuadPart =
LlBytesFromSectors( Vcb, Vsn );
00402
00403
00404
00405
00406
00407
CcMapData( Vcb->MetadataFcb->FileObject,
00408 &
Offset,
00409 Length,
00410
TRUE,
00411 &View->Bcb,
00412 &View->View );
00413 }
00414
00415
00416
NTSTATUS
00417 UdfPurgeVolume (
00418 IN
PIRP_CONTEXT IrpContext,
00419 IN
PVCB Vcb,
00420 IN BOOLEAN DismountUnderway
00421 )
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 {
00449
NTSTATUS Status = STATUS_SUCCESS;
00450
00451 PVOID RestartKey =
NULL;
00452
PFCB ThisFcb =
NULL;
00453
PFCB NextFcb;
00454
00455 BOOLEAN RemovedFcb;
00456
00457
PAGED_CODE();
00458
00459
00460
00461
00462
00463
UdfFspClose( Vcb );
00464
00465
00466
00467
00468
00469
UdfAcquireAllFiles( IrpContext, Vcb );
00470
00471
00472
00473
00474
00475
while (
TRUE) {
00476
00477
00478
00479
00480
00481
UdfLockVcb( IrpContext, Vcb );
00482 NextFcb =
UdfGetNextFcb( IrpContext, Vcb, &RestartKey );
00483
00484
00485
00486
00487
00488
if (NextFcb !=
NULL) {
00489
00490 NextFcb->
FcbReference += 1;
00491 }
00492
00493
00494
00495
00496
00497
00498
if (ThisFcb !=
NULL) {
00499
00500 ThisFcb->
FcbReference -= 1;
00501
00502
UdfUnlockVcb( IrpContext, Vcb );
00503
00504
UdfTeardownStructures( IrpContext, ThisFcb,
FALSE, &RemovedFcb );
00505
00506 }
else {
00507
00508
UdfUnlockVcb( IrpContext, Vcb );
00509 }
00510
00511
00512
00513
00514
00515
if (NextFcb ==
NULL) {
00516
00517
break;
00518 }
00519
00520
00521
00522
00523
00524 ThisFcb = NextFcb;
00525
00526
00527
00528
00529
00530
if (ThisFcb->
FcbNonpaged->
SegmentObject.
ImageSectionObject !=
NULL) {
00531
00532
MmFlushImageSection( &ThisFcb->
FcbNonpaged->
SegmentObject,
MmFlushForWrite );
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
if ((ThisFcb->
FcbNonpaged->
SegmentObject.
DataSectionObject !=
NULL) &&
00542 !
CcPurgeCacheSection( &ThisFcb->
FcbNonpaged->
SegmentObject,
00543
NULL,
00544 0,
00545
FALSE ) &&
00546 (
Status == STATUS_SUCCESS)) {
00547
00548
Status = STATUS_UNABLE_TO_DELETE_SECTION;
00549 }
00550
00551
00552
00553
00554
00555
if (DismountUnderway &&
00556 (
SafeNodeType( ThisFcb ) !=
UDFS_NTC_FCB_DATA) &&
00557 (ThisFcb->FileObject !=
NULL)) {
00558
00559
UdfDeleteInternalStream( IrpContext, ThisFcb );
00560 }
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
if (DismountUnderway) {
00571
00572
if (Vcb->RootIndexFcb !=
NULL) {
00573
00574 ThisFcb = Vcb->RootIndexFcb;
00575 InterlockedIncrement( &ThisFcb->
FcbReference );
00576
00577
if ((ThisFcb->
FcbNonpaged->
SegmentObject.
DataSectionObject !=
NULL) &&
00578 !
CcPurgeCacheSection( &ThisFcb->
FcbNonpaged->
SegmentObject,
00579
NULL,
00580 0,
00581
FALSE ) &&
00582 (
Status == STATUS_SUCCESS)) {
00583
00584
Status = STATUS_UNABLE_TO_DELETE_SECTION;
00585 }
00586
00587
UdfDeleteInternalStream( IrpContext, ThisFcb );
00588 InterlockedDecrement( &ThisFcb->
FcbReference );
00589
UdfTeardownStructures( IrpContext, ThisFcb,
FALSE, &RemovedFcb );
00590 }
00591
00592
if (Vcb->MetadataFcb !=
NULL) {
00593
00594 ThisFcb = Vcb->MetadataFcb;
00595 InterlockedIncrement( &ThisFcb->
FcbReference );
00596
00597
if ((ThisFcb->
FcbNonpaged->
SegmentObject.
DataSectionObject !=
NULL) &&
00598 !
CcPurgeCacheSection( &ThisFcb->
FcbNonpaged->
SegmentObject,
00599
NULL,
00600 0,
00601
FALSE ) &&
00602 (
Status == STATUS_SUCCESS)) {
00603
00604
Status = STATUS_UNABLE_TO_DELETE_SECTION;
00605 }
00606
00607
UdfDeleteInternalStream( IrpContext, ThisFcb );
00608 InterlockedDecrement( &ThisFcb->
FcbReference );
00609
UdfTeardownStructures( IrpContext, ThisFcb,
FALSE, &RemovedFcb );
00610 }
00611
00612
if (Vcb->VatFcb !=
NULL) {
00613
00614 ThisFcb = Vcb->VatFcb;
00615 InterlockedIncrement( &ThisFcb->
FcbReference );
00616
00617
if ((ThisFcb->
FcbNonpaged->
SegmentObject.
DataSectionObject !=
NULL) &&
00618 !
CcPurgeCacheSection( &ThisFcb->
FcbNonpaged->
SegmentObject,
00619
NULL,
00620 0,
00621
FALSE ) &&
00622 (
Status == STATUS_SUCCESS)) {
00623
00624
Status = STATUS_UNABLE_TO_DELETE_SECTION;
00625 }
00626
00627
UdfDeleteInternalStream( IrpContext, ThisFcb );
00628 InterlockedDecrement( &ThisFcb->
FcbReference );
00629
UdfTeardownStructures( IrpContext, ThisFcb,
FALSE, &RemovedFcb );
00630 }
00631
00632
if (Vcb->VolumeDasdFcb !=
NULL) {
00633
00634 ThisFcb = Vcb->VolumeDasdFcb;
00635 InterlockedIncrement( &ThisFcb->
FcbReference );
00636
00637
if ((ThisFcb->
FcbNonpaged->
SegmentObject.
DataSectionObject !=
NULL) &&
00638 !
CcPurgeCacheSection( &ThisFcb->
FcbNonpaged->
SegmentObject,
00639
NULL,
00640 0,
00641
FALSE ) &&
00642 (
Status == STATUS_SUCCESS)) {
00643
00644
Status = STATUS_UNABLE_TO_DELETE_SECTION;
00645 }
00646
00647 InterlockedDecrement( &ThisFcb->
FcbReference );
00648
UdfTeardownStructures( IrpContext, ThisFcb,
FALSE, &RemovedFcb );
00649 }
00650 }
00651
00652
00653
00654
00655
00656
UdfReleaseAllFiles( IrpContext, Vcb );
00657
00658
return Status;
00659 }
00660