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_STRUCSUP)
00029
00030
00031
00032
00033
00034 #define Dbg (UDFS_DEBUG_LEVEL_STRUCSUP)
00035
00036
00037
00038
00039
00040 typedef struct _FCB_TABLE_ELEMENT {
00041
00042 FILE_ID FileId;
00043 PFCB Fcb;
00044
00045 }
FCB_TABLE_ELEMENT, *
PFCB_TABLE_ELEMENT;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #define UdfAllocateFcbData(IC) \
00098
ExAllocateFromPagedLookasideList( &UdfFcbDataLookasideList );
00099
00100 #define UdfDeallocateFcbData(IC,F) \
00101
ExFreeToPagedLookasideList( &UdfFcbDataLookasideList, F );
00102
00103 #define UdfAllocateFcbIndex(IC) \
00104
ExAllocateFromPagedLookasideList( &UdfFcbIndexLookasideList );
00105
00106 #define UdfDeallocateFcbIndex(IC,F) \
00107
ExFreeToPagedLookasideList( &UdfFcbIndexLookasideList, F );
00108
00109 #define UdfAllocateFcbNonpaged(IC) \
00110
ExAllocateFromNPagedLookasideList( &UdfFcbNonPagedLookasideList );
00111
00112 #define UdfDeallocateFcbNonpaged(IC,FNP) \
00113
ExFreeToNPagedLookasideList( &UdfFcbNonPagedLookasideList, FNP );
00114
00115 #define UdfAllocateCcb(IC) \
00116
ExAllocateFromPagedLookasideList( &UdfCcbLookasideList );
00117
00118 #define UdfDeallocateCcb(IC,C) \
00119
ExFreeToPagedLookasideList( &UdfCcbLookasideList, C );
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 #define UdfInsertFcbTable(IC,F) { \
00137
FCB_TABLE_ELEMENT _Key; \
00138
_Key.Fcb = (F); \
00139
_Key.FileId = (F)->FileId; \
00140
RtlInsertElementGenericTable( &(F)->Vcb->FcbTable, \
00141
&_Key, \
00142
sizeof( FCB_TABLE_ELEMENT ), \
00143
NULL ); \
00144
}
00145
00146 #define UdfDeleteFcbTable(IC,F) { \
00147
FCB_TABLE_ELEMENT _Key; \
00148
_Key.FileId = (F)->FileId; \
00149
RtlDeleteElementGenericTable( &(F)->Vcb->FcbTable, &_Key ); \
00150
}
00151
00152
00153
00154
00155
00156
00157
00158
INLINE
00159
USHORT
00160 UdfGetPartitionOfCurrentAllocation (
00161 IN
PALLOC_ENUM_CONTEXT AllocContext
00162 )
00163 {
00164
if (AllocContext->AllocType ==
ICBTAG_F_ALLOC_LONG) {
00165
00166
return ((
PLONGAD) AllocContext->Alloc)->Start.Partition;
00167
00168 }
else {
00169
00170
return AllocContext->IcbContext->Active.Partition;
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
INLINE
00180
VOID
00181 UdfInitializeFcbMcb (
00182 IN
PFCB Fcb
00183 )
00184 {
00185
00186
00187
00188
00189
00190
if (
FlagOn( Fcb->FcbState,
FCB_STATE_MCB_INITIALIZED )) {
00191
00192
FsRtlResetLargeMcb( &Fcb->Mcb,
TRUE );
00193
00194 }
else {
00195
00196
FsRtlInitializeLargeMcb( &Fcb->Mcb,
UdfPagedPool );
00197
SetFlag( Fcb->FcbState,
FCB_STATE_MCB_INITIALIZED );
00198 }
00199 }
00200
00201
00202
00203
00204
00205
INLINE
00206
VOID
00207 UdfUninitializeFcbMcb (
00208 IN
PFCB Fcb
00209 )
00210 {
00211
if (
FlagOn( Fcb->FcbState,
FCB_STATE_MCB_INITIALIZED )) {
00212
00213
FsRtlUninitializeLargeMcb( &Fcb->Mcb );
00214
ClearFlag( Fcb->FcbState,
FCB_STATE_MCB_INITIALIZED );
00215 }
00216 }
00217
00218
00219
00220
00221
00222 PVOID
00223
UdfAllocateTable (
00224 IN PRTL_GENERIC_TABLE Table,
00225 IN CLONG ByteSize
00226 );
00227
00228
PFCB_NONPAGED
00229
UdfCreateFcbNonPaged (
00230 IN
PIRP_CONTEXT IrpContext
00231 );
00232
00233
VOID
00234
UdfDeleteFcbNonpaged (
00235 IN
PIRP_CONTEXT IrpContext,
00236 IN
PFCB_NONPAGED FcbNonpaged
00237 );
00238
00239
VOID
00240
UdfDeallocateTable (
00241 IN PRTL_GENERIC_TABLE Table,
00242 IN PVOID Buffer
00243 );
00244
00245 RTL_GENERIC_COMPARE_RESULTS
00246
UdfFcbTableCompare (
00247 IN PRTL_GENERIC_TABLE Table,
00248 IN PVOID id1,
00249 IN PVOID id2
00250 );
00251
00252
VOID
00253
UdfInitializeAllocationContext (
00254 IN
PIRP_CONTEXT IrpContext,
00255 IN
PALLOC_ENUM_CONTEXT AllocContext,
00256 IN
PICB_SEARCH_CONTEXT IcbContext
00257 );
00258
00259 BOOLEAN
00260
UdfGetNextAllocation (
00261 IN
PIRP_CONTEXT IrpContext,
00262 IN
PALLOC_ENUM_CONTEXT AllocContext
00263 );
00264
00265 BOOLEAN
00266
UdfGetNextAllocationPostProcessing (
00267 IN
PIRP_CONTEXT IrpContext,
00268 IN
PALLOC_ENUM_CONTEXT AllocContext
00269 );
00270
00271
VOID
00272
UdfLookupActiveIcbInExtent (
00273 IN
PIRP_CONTEXT IrpContext,
00274 IN
PICB_SEARCH_CONTEXT IcbContext,
00275 IN ULONG Recurse
00276 );
00277
00278
VOID
00279
UdfInitializeEaContext (
00280 IN
PIRP_CONTEXT IrpContext,
00281 IN
PEA_SEARCH_CONTEXT EaContext,
00282 IN
PICB_SEARCH_CONTEXT IcbContext,
00283 IN ULONG EAType,
00284 IN UCHAR EASubType
00285 );
00286
00287 BOOLEAN
00288
UdfLookupEa (
00289 IN
PIRP_CONTEXT IrpContext,
00290 IN
PEA_SEARCH_CONTEXT EaContext
00291 );
00292
00293
#ifdef ALLOC_PRAGMA
00294
#pragma alloc_text(PAGE, UdfAllocateTable)
00295
#pragma alloc_text(PAGE, UdfCleanupIcbContext)
00296
#pragma alloc_text(PAGE, UdfCleanupIrpContext)
00297
#pragma alloc_text(PAGE, UdfCreateCcb)
00298
#pragma alloc_text(PAGE, UdfCreateFcb)
00299
#pragma alloc_text(PAGE, UdfCreateFcbNonPaged)
00300
#pragma alloc_text(PAGE, UdfCreateIrpContext)
00301
#pragma alloc_text(PAGE, UdfDeallocateTable)
00302
#pragma alloc_text(PAGE, UdfDeleteCcb)
00303
#pragma alloc_text(PAGE, UdfDeleteFcb)
00304
#pragma alloc_text(PAGE, UdfDeleteFcbNonpaged)
00305
#pragma alloc_text(PAGE, UdfDeleteVcb)
00306
#pragma alloc_text(PAGE, UdfFcbTableCompare)
00307
#pragma alloc_text(PAGE, UdfFindInParseTable)
00308
#pragma alloc_text(PAGE, UdfGetNextAllocation)
00309
#pragma alloc_text(PAGE, UdfGetNextAllocationPostProcessing)
00310
#pragma alloc_text(PAGE, UdfGetNextFcb)
00311
#pragma alloc_text(PAGE, UdfInitializeAllocationContext)
00312
#pragma alloc_text(PAGE, UdfInitializeAllocations)
00313
#pragma alloc_text(PAGE, UdfInitializeEaContext)
00314
#pragma alloc_text(PAGE, UdfInitializeFcbFromIcbContext)
00315
#pragma alloc_text(PAGE, UdfInitializeIcbContext)
00316
#pragma alloc_text(PAGE, UdfInitializeStackIrpContext)
00317
#pragma alloc_text(PAGE, UdfInitializeVcb)
00318
#pragma alloc_text(PAGE, UdfLookupActiveIcb)
00319
#pragma alloc_text(PAGE, UdfLookupActiveIcbInExtent)
00320
#pragma alloc_text(PAGE, UdfLookupEa)
00321
#pragma alloc_text(PAGE, UdfLookupFcbTable)
00322
#pragma alloc_text(PAGE, UdfTeardownStructures)
00323
#pragma alloc_text(PAGE, UdfUpdateTimestampsFromIcbContext)
00324
#pragma alloc_text(PAGE, UdfUpdateVcbPhase0)
00325
#pragma alloc_text(PAGE, UdfUpdateVcbPhase1)
00326
#pragma alloc_text(PAGE, UdfVerifyDescriptor)
00327
#endif ALLOC_PRAGMA
00328
00329
00330 BOOLEAN
00331 UdfInitializeVcb (
00332 IN
PIRP_CONTEXT IrpContext,
00333 IN OUT
PVCB Vcb,
00334 IN
PDEVICE_OBJECT TargetDeviceObject,
00335 IN
PVPB Vpb,
00336 IN PDISK_GEOMETRY DiskGeometry,
00337 IN ULONG MediaChangeCount
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
00366 {
00367
PAGED_CODE();
00368
00369
00370
00371
00372
00373
00374 RtlZeroMemory( Vcb,
sizeof(
VCB ));
00375
00376
00377
00378
00379
00380 Vcb->NodeTypeCode =
UDFS_NTC_VCB;
00381 Vcb->NodeByteSize =
sizeof(
VCB );
00382
00383
00384
00385
00386
00387
00388
00389 InitializeListHead( &Vcb->DirNotifyList );
00390
FsRtlNotifyInitializeSync( &Vcb->NotifySync );
00391
00392
00393
00394
00395
00396
ExInitializeResource( &Vcb->VcbResource );
00397
ExInitializeResource( &Vcb->FileResource );
00398
ExInitializeFastMutex( &Vcb->VcbMutex );
00399
00400
00401
00402
00403
00404 InsertHeadList( &
UdfData.
VcbQueue, &Vcb->VcbLinks );
00405
00406
00407
00408
00409
00410
00411
ObReferenceObject( TargetDeviceObject );
00412 Vcb->TargetDeviceObject = TargetDeviceObject;
00413 Vcb->Vpb = Vpb;
00414
00415
00416
00417
00418
00419
00420
if (
FlagOn( Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA )) {
00421
00422
SetFlag( Vcb->VcbState,
VCB_STATE_REMOVABLE_MEDIA );
00423 }
00424
00425
00426
00427
00428
00429
RtlInitializeGenericTable( &Vcb->FcbTable,
00430 (PRTL_GENERIC_COMPARE_ROUTINE)
UdfFcbTableCompare,
00431 (PRTL_GENERIC_ALLOCATE_ROUTINE)
UdfAllocateTable,
00432 (PRTL_GENERIC_FREE_ROUTINE)
UdfDeallocateTable,
00433
NULL );
00434
00435
00436
00437
00438
00439 Vcb->VcbCondition =
VcbMountInProgress;
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 Vcb->VcbResidualReference =
UDFS_BASE_RESIDUAL_REFERENCE;
00450 Vcb->VcbResidualUserReference =
UDFS_BASE_RESIDUAL_USER_REFERENCE;
00451
00452 Vcb->VcbReference = 1 + Vcb->VcbResidualReference;
00453
00454
00455
00456
00457
00458 Vcb->SectorSize = DiskGeometry->BytesPerSector;
00459
00460
00461
00462
00463
00464 Vcb->SectorShift =
UdfHighBit( DiskGeometry->BytesPerSector );
00465
00466
00467
00468
00469
00470 Vcb->MediaChangeCount = MediaChangeCount;
00471
00472
return TRUE;
00473 }
00474
00475
00476
VOID
00477 UdfUpdateVcbPhase0 (
00478 IN
PIRP_CONTEXT IrpContext,
00479 IN OUT
PVCB Vcb
00480 )
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 {
00505
ICB_SEARCH_CONTEXT IcbContext;
00506
00507 LONGLONG FileId = 0;
00508
00509
PICBFILE VatIcb =
NULL;
00510
PREGID RegId;
00511 ULONG ThisPass;
00512 ULONG Psn;
00513 ULONG Vsn;
00514 ULONG Lbn;
00515 ULONG SectorCount;
00516
USHORT Reference;
00517
00518 BOOLEAN UnlockVcb =
FALSE;
00519 BOOLEAN CleanupIcbContext =
FALSE;
00520
00521
PBCB Bcb =
NULL;
00522 LARGE_INTEGER
Offset;
00523
00524
PAGED_CODE();
00525
00526
00527
00528
00529
00530
ASSERT_IRP_CONTEXT( IrpContext );
00531
ASSERT_VCB( Vcb );
00532
00533
DebugTrace(( +1,
Dbg,
"UdfUpdateVcbPhase0, Vcb %08x\n", Vcb ));
00534
00535
try {
00536
00538
00539
00540
00542
00543
UdfLockVcb( IrpContext, Vcb );
00544 UnlockVcb =
TRUE;
00545
00546 Vcb->MetadataFcb =
UdfCreateFcb( IrpContext,
00547 *((
PFILE_ID) &FileId),
00548
UDFS_NTC_FCB_INDEX,
00549
NULL );
00550
00551
UdfIncrementReferenceCounts( IrpContext, Vcb->MetadataFcb, 1, 1 );
00552
UdfUnlockVcb( IrpContext, Vcb );
00553 UnlockVcb =
FALSE;
00554
00555
00556
00557
00558
00559 Vcb->MetadataFcb->FileSize.QuadPart =
00560 Vcb->MetadataFcb->ValidDataLength.QuadPart =
00561 Vcb->MetadataFcb->AllocationSize.QuadPart = 0;
00562
00563
00564
00565
00566
00567
UdfLockFcb( IrpContext, Vcb->MetadataFcb );
00568
00569
UdfInitializeVmcb( &Vcb->Vmcb,
00570
UdfPagedPool,
00571 MAXULONG,
00572
SectorSize(Vcb) );
00573
00574
UdfUnlockFcb( IrpContext, Vcb->MetadataFcb );
00575
00576
00577
00578
00579
00580
00581 Vcb->MetadataFcb->Resource = &Vcb->FileResource;
00582
00583
SetFlag( Vcb->MetadataFcb->FcbState,
FCB_STATE_VMCB_MAPPING |
FCB_STATE_INITIALIZED );
00584
00585
00586
00587
00588
00589
UdfCreateInternalStream( IrpContext, Vcb, Vcb->MetadataFcb );
00590
00592
00593
00594
00595
00596
00598
00599
if (
FlagOn( Vcb->Pcb->Flags,
PCB_FLAG_VIRTUAL_PARTITION )) {
00600
00601
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, handling VAT setup\n" ));
00602
00603
00604
00605
00606
00607
00608
if (!Vcb->BoundN || Vcb->BoundN <
ANCHOR_SECTOR) {
00609
00610
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, no end bound was discoverable!\n" ));
00611
00612
UdfRaiseStatus( IrpContext, STATUS_UNRECOGNIZED_VOLUME );
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 Vcb->VcbResidualReference +=
UDFS_CDUDF_RESIDUAL_REFERENCE;
00624 Vcb->VcbResidualUserReference +=
UDFS_CDUDF_RESIDUAL_USER_REFERENCE;
00625
00626 Vcb->VcbReference +=
UDFS_CDUDF_RESIDUAL_REFERENCE;
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 VatIcb =
FsRtlAllocatePoolWithTag(
UdfPagedPool,
00663
UdfRawBufferSize( Vcb,
BlockSize( Vcb )),
00664
TAG_NSR_VDSD);
00665
00666
for (ThisPass = 0; ThisPass < 4; ThisPass++) {
00667
00668
00669
00670
00671
00672
00673 Psn = Vcb->BoundN - ( ThisPass == 0? 152 :
00674 ( ThisPass == 1? 150 :
00675 ( ThisPass == 2? 2 : 0 )));
00676
00677
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, looking at Psn 0x%08x\n", Psn ));
00678
00679
00680
00681
00682
00683
00684
00685
for (Reference = 0;
00686 Reference < Vcb->Pcb->Partitions;
00687 Reference++) {
00688
00689
if (Vcb->Pcb->Partition[Reference].Type ==
Physical &&
00690 Vcb->Pcb->Partition[Reference].Physical.Start <= Psn &&
00691 Vcb->Pcb->Partition[Reference].Physical.Start +
00692 Vcb->Pcb->Partition[Reference].Physical.Length > Psn) {
00693
00694
break;
00695 }
00696 }
00697
00698
00699
00700
00701
00702
00703
if (Reference == Vcb->Pcb->Partitions) {
00704
00705
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... but it isn't in a partition.\n" ));
00706
00707
continue;
00708 }
00709
00710
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... in partition Ref %u.\n", Reference ));
00711
00712
00713
00714
00715
00716
00717 Lbn =
BlocksFromSectors( Vcb, Psn - Vcb->Pcb->Partition[Reference].Physical.Start );
00718
00719
if (!
NT_SUCCESS(
UdfReadSectors( IrpContext,
00720
LlBytesFromSectors( Vcb, Psn ),
00721
UdfRawReadSize( Vcb,
BlockSize( Vcb )),
00722
TRUE,
00723 VatIcb,
00724 Vcb->TargetDeviceObject ))) {
00725
00726
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... but couldn't read it.\n" ));
00727
00728
continue;
00729 }
00730
00731
00732
00733
00734
00735
if (!
UdfVerifyDescriptor( IrpContext,
00736 (
PDESTAG) VatIcb,
00737
DESTAG_ID_NSR_FILE,
00738
BlockSize( Vcb ),
00739 Lbn,
00740
TRUE )) {
00741
00742
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... but it didn't verify.\n" ));
00743
00744
continue;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
if (VatIcb->Icbtag.FileType !=
ICBTAG_FILE_T_NOTSPEC ||
00754 VatIcb->LinkCount) {
00755
00756
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... but the type/linkcount is wrong.\n" ));
00757
00758
continue;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
ASSERT( !
LongOffset(
UDF_CDUDF_MINIMUM_VAT_SIZE ));
00768
00769
if (VatIcb->InfoLength <
UDF_CDUDF_MINIMUM_VAT_SIZE ||
00770 VatIcb->InfoLength >
UDF_CDUDF_MAXIMUM_VAT_SIZE ||
00771
LongOffset( VatIcb->InfoLength )) {
00772
00773
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... but the size looks pretty bogus.\n" ));
00774
00775
continue;
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
if (Vcb->VatFcb) {
00802
00803
UdfResetVmcb( &Vcb->Vmcb );
00804
00805
UdfUnpinData( IrpContext, &Bcb );
00806
00807
CcPurgeCacheSection( Vcb->MetadataFcb->FileObject->SectionObjectPointer,
00808
NULL,
00809 0,
00810
FALSE );
00811
00812
CcPurgeCacheSection( Vcb->VatFcb->FileObject->SectionObjectPointer,
00813
NULL,
00814 0,
00815
FALSE );
00816 }
00817
00818 Vsn =
UdfLookupMetaVsnOfExtent( IrpContext,
00819 Vcb,
00820 Reference,
00821 Lbn,
00822
BlockSize( Vcb ),
00823
TRUE );
00824
00825
if (Vcb->VatFcb ==
NULL) {
00826
00827
00828
00829
00830
00831
UdfLockVcb( IrpContext, Vcb );
00832 UnlockVcb =
TRUE;
00833
00834 Vcb->VatFcb =
UdfCreateFcb( IrpContext,
00835 *((
PFILE_ID) &FileId),
00836
UDFS_NTC_FCB_INDEX,
00837
NULL );
00838
00839
UdfIncrementReferenceCounts( IrpContext, Vcb->VatFcb, 1, 1 );
00840
UdfUnlockVcb( IrpContext, Vcb );
00841 UnlockVcb =
FALSE;
00842
00843
00844
00845
00846
00847
00848 Vcb->VatFcb->Resource = &Vcb->FileResource;
00849 }
00850
00851
00852
00853
00854
00855
00856 Vcb->VatFcb->AllocationSize.QuadPart =
LlSectorAlign( Vcb, VatIcb->InfoLength );
00857
00858 Vcb->VatFcb->FileSize.QuadPart =
00859 Vcb->VatFcb->ValidDataLength.QuadPart = VatIcb->InfoLength;
00860
00861
00862
00863
00864
00865
if (CleanupIcbContext) {
00866
00867
UdfCleanupIcbContext( IrpContext, &IcbContext );
00868
00869 }
else {
00870
00871 RtlZeroMemory( &IcbContext,
sizeof(
ICB_SEARCH_CONTEXT ));
00872 }
00873
00874
00875
00876
00877
00878
00879
00880 IcbContext.
Active.
View = (PVOID) VatIcb;
00881 IcbContext.
Active.
Partition = Reference;
00882 IcbContext.
Active.
Lbn = Lbn;
00883 CleanupIcbContext =
TRUE;
00884
00885
UdfInitializeAllocations( IrpContext,
00886 Vcb->VatFcb,
00887 &IcbContext );
00888
00889
00890
00891
00892
00893
if (!
FlagOn( Vcb->VatFcb->FcbState,
FCB_STATE_INITIALIZED )) {
00894
00895
UdfCreateInternalStream( IrpContext, Vcb, Vcb->VatFcb );
00896
SetFlag( Vcb->VatFcb->FcbState,
FCB_STATE_INITIALIZED );
00897
00898 }
else {
00899
00900
CcSetFileSizes( Vcb->VatFcb->FileObject, (
PCC_FILE_SIZES) &Vcb->VatFcb->AllocationSize );
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
Offset.QuadPart = Vcb->VatFcb->FileSize.QuadPart -
UDF_CDUDF_TRAILING_DATA_SIZE;
00911
00912
CcMapData( Vcb->VatFcb->FileObject,
00913 &
Offset,
00914
sizeof(
REGID),
00915
TRUE,
00916 &Bcb,
00917 &RegId );
00918
00919
if (!
UdfUdfIdentifierContained( RegId,
00920 &
UdfVatTableIdentifier,
00921
UDF_VERSION_150,
00922
UDF_VERSION_RECOGNIZED,
00923
OSCLASS_INVALID,
00924
OSIDENTIFIER_INVALID )) {
00925
00926
00927
00928
00929
00930
continue;
00931 }
00932
00933
00934
00935
00936
00937
break;
00938 }
00939
00940
00941
00942
00943
00944
if (ThisPass == 4) {
00945
00946
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... and so we didn't find a VAT!\n" ));
00947
00948
UdfRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR );
00949 }
00950
00951
00952
00953
00954
00955
00956
for (Reference = 0;
00957 Reference < Vcb->Pcb->Partitions;
00958 Reference++) {
00959
00960
if (Vcb->Pcb->Partition[Reference].Type ==
Virtual) {
00961
00962
break;
00963 }
00964 }
00965
00966
ASSERT( Reference < Vcb->Pcb->Partitions );
00967
00968
00969
00970
00971
00972
00973
Offset.QuadPart = (Vcb->VatFcb->FileSize.QuadPart -
00974
UDF_CDUDF_TRAILING_DATA_SIZE) /
sizeof(ULONG);
00975
00976
ASSERT(
Offset.HighPart == 0 );
00977 Vcb->Pcb->Partition[Reference].Virtual.Length =
Offset.LowPart;
00978
00979
DebugTrace(( 0,
Dbg,
"UdfUpdateVcbPhase0, ... got it!\n" ));
00980 }
00981
00982 } finally {
00983
00984
DebugUnwind(
"UdfUpdateVcbPhase0" );
00985
00986
UdfUnpinData( IrpContext, &Bcb );
00987
if (CleanupIcbContext) {
UdfCleanupIcbContext( IrpContext, &IcbContext ); }
00988
if (UnlockVcb) {
UdfUnlockVcb( IrpContext, Vcb ); }
00989
if (VatIcb) {
ExFreePool( VatIcb ); }
00990 }
00991
00992
DebugTrace(( -1,
Dbg,
"UdfUpdateVcbPhase0 -> VOID\n" ));
00993 }
00994
00995
00996
VOID
00997 UdfUpdateVcbPhase1 (
00998 IN
PIRP_CONTEXT IrpContext,
00999 IN OUT
PVCB Vcb,
01000 IN
PNSR_FSD Fsd
01001 )
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 {
01023
ICB_SEARCH_CONTEXT IcbContext;
01024
01025 LONGLONG FileId = 0;
01026
01027
PFCB Fcb;
01028
01029 BOOLEAN UnlockVcb =
FALSE;
01030 BOOLEAN UnlockFcb =
FALSE;
01031 BOOLEAN CleanupIcbContext =
FALSE;
01032
01033 ULONG Reference;
01034
01035 ULONG BoundSector = 0;
01036
01037
PAGED_CODE();
01038
01039
01040
01041
01042
01043
ASSERT_IRP_CONTEXT( IrpContext );
01044
ASSERT_VCB( Vcb );
01045
01046
DebugTrace(( +1,
Dbg,
"UdfUpdateVcbPhase1, Vcb %08x Fsd %08x\n", Vcb, Fsd ));
01047
01048
01049
01050
01051
01052
try {
01053
01054
01055
01056
01057
01059
01060
01061
01063
01064
UdfLockVcb( IrpContext, Vcb );
01065 UnlockVcb =
TRUE;
01066
01067 Vcb->RootIndexFcb =
UdfCreateFcb( IrpContext,
01068 *((
PFILE_ID) &FileId),
01069
UDFS_NTC_FCB_INDEX,
01070
NULL );
01071
01072
UdfIncrementReferenceCounts( IrpContext, Vcb->RootIndexFcb, 1, 1 );
01073
UdfUnlockVcb( IrpContext, Vcb );
01074 UnlockVcb =
FALSE;
01075
01076
01077
01078
01079
01080
UdfSetFidFromLbAddr( Vcb->RootIndexFcb->FileId, Fsd->IcbRoot.Start );
01081
UdfSetFidDirectory( Vcb->RootIndexFcb->FileId );
01082 Vcb->RootIndexFcb->RootExtentLength = Fsd->IcbRoot.Length.Length;
01083
01084
01085
01086
01087
01088
01089
UdfInitializeIcbContextFromFcb( IrpContext,
01090 &IcbContext,
01091 Vcb->RootIndexFcb );
01092 CleanupIcbContext =
TRUE;
01093
01094
UdfLookupActiveIcb( IrpContext, &IcbContext );
01095
01096
UdfInitializeFcbFromIcbContext( IrpContext,
01097 Vcb->RootIndexFcb,
01098 &IcbContext );
01099
01100
UdfCleanupIcbContext( IrpContext, &IcbContext );
01101 CleanupIcbContext =
FALSE;
01102
01103
01104
01105
01106
01107
UdfCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb );
01108
01110
01111
01112
01113
01115
01116
UdfLockVcb( IrpContext, Vcb );
01117 UnlockVcb =
TRUE;
01118
01119 Vcb->VolumeDasdFcb =
UdfCreateFcb( IrpContext,
01120 *((
PFILE_ID) &FileId),
01121
UDFS_NTC_FCB_DATA,
01122
NULL );
01123
01124
UdfIncrementReferenceCounts( IrpContext, Vcb->VolumeDasdFcb, 1, 1 );
01125
UdfUnlockVcb( IrpContext, Vcb );
01126 UnlockVcb =
FALSE;
01127
01128 Fcb = Vcb->VolumeDasdFcb;
01129
UdfLockFcb( IrpContext, Fcb );
01130 UnlockFcb =
TRUE;
01131
01132
01133
01134
01135
01136
01137
01138
01139
for ( Reference = 0;
01140 Reference < Vcb->Pcb->Partitions;
01141 Reference++ ) {
01142
01143
if (Vcb->Pcb->Partition[Reference].Type ==
Physical &&
01144 Vcb->Pcb->Partition[Reference].Physical.Start +
01145 Vcb->Pcb->Partition[Reference].Physical.Length > BoundSector) {
01146
01147 BoundSector = Vcb->Pcb->Partition[Reference].Physical.Start +
01148 Vcb->Pcb->Partition[Reference].Physical.Length;
01149 }
01150 }
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
UdfInitializeFcbMcb( Fcb );
01169
01170
FsRtlAddLargeMcbEntry( &Fcb->
Mcb,
01171 (LONGLONG) 0,
01172 (LONGLONG) 0,
01173 (LONGLONG) BoundSector );
01174
01175 Fcb->FileSize.QuadPart +=
LlBytesFromSectors( Vcb, BoundSector );
01176
01177 Fcb->AllocationSize.QuadPart =
01178 Fcb->ValidDataLength.QuadPart = Fcb->FileSize.QuadPart;
01179
01180
UdfUnlockFcb( IrpContext, Fcb );
01181 UnlockFcb =
FALSE;
01182
01183
SetFlag( Fcb->
FcbState,
FCB_STATE_INITIALIZED );
01184
01185
01186
01187
01188
01189 Vcb->VolumeDasdFcb->Resource = &Vcb->FileResource;
01190
01191 Vcb->VolumeDasdFcb->FileAttributes = FILE_ATTRIBUTE_READONLY;
01192
01193 } finally {
01194
01195
DebugUnwind(
"UdfUpdateVcbPhase1" );
01196
01197
if (CleanupIcbContext) {
UdfCleanupIcbContext( IrpContext, &IcbContext ); }
01198
01199
if (UnlockFcb) {
UdfUnlockFcb( IrpContext, Fcb ); }
01200
if (UnlockVcb) {
UdfUnlockVcb( IrpContext, Vcb ); }
01201 }
01202
01203
DebugTrace(( -1,
Dbg,
"UdfUpdateVcbPhase1 -> VOID\n" ));
01204
01205
return;
01206 }
01207
01208
01209
VOID
01210 UdfDeleteVcb (
01211 IN
PIRP_CONTEXT IrpContext,
01212 IN OUT
PVCB Vcb
01213 )
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233 {
01234
PAGED_CODE();
01235
01236
ASSERT_EXCLUSIVE_UDFDATA;
01237
ASSERT_EXCLUSIVE_VCB( Vcb );
01238
01239
01240
01241
01242
01243
if (Vcb->Vpb !=
NULL) {
01244
01245
UdfFreePool( &Vcb->Vpb );
01246 }
01247
01248
01249
01250
01251
01252
if (Vcb->Pcb !=
NULL) {
01253
01254
UdfDeletePcb( Vcb->Pcb );
01255 }
01256
01257
01258
01259
01260
01261
if (Vcb->TargetDeviceObject !=
NULL) {
01262
01263
ObDereferenceObject( Vcb->TargetDeviceObject );
01264 }
01265
01266
01267
01268
01269
01270 RemoveEntryList( &Vcb->VcbLinks );
01271
01272
01273
01274
01275
01276
ExDeleteResource( &Vcb->VcbResource );
01277
ExDeleteResource( &Vcb->FileResource );
01278
01279
01280
01281
01282
01283
if (Vcb->NotifySync !=
NULL) {
01284
01285
FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
01286 }
01287
01288
01289
01290
01291
01292
IoDeleteDevice( (
PDEVICE_OBJECT) CONTAINING_RECORD( Vcb,
01293
VOLUME_DEVICE_OBJECT,
01294 Vcb ));
01295
01296
return;
01297 }
01298
01299
01300
PIRP_CONTEXT
01301 UdfCreateIrpContext (
01302 IN
PIRP Irp,
01303 IN BOOLEAN Wait
01304 )
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326 {
01327
PIRP_CONTEXT NewIrpContext =
NULL;
01328
PIO_STACK_LOCATION IrpSp =
IoGetCurrentIrpStackLocation(
Irp );
01329 BOOLEAN IsFsDo =
FALSE;
01330 ULONG
Count;
01331
01332
PAGED_CODE();
01333
01334
for (
Count = 0;
Count <
NUMBER_OF_FS_OBJECTS;
Count++) {
01335
01336
if (IrpSp->
DeviceObject ==
UdfData.
FileSystemDeviceObjects[
Count]) {
01337
01338 IsFsDo =
TRUE;
01339
break;
01340 }
01341 }
01342
01343
01344
01345
01346
01347
01348
01349
if (IsFsDo) {
01350
01351
if (IrpSp->
FileObject !=
NULL &&
01352 IrpSp->
MajorFunction !=
IRP_MJ_CREATE &&
01353 IrpSp->
MajorFunction !=
IRP_MJ_CLEANUP &&
01354 IrpSp->
MajorFunction !=
IRP_MJ_CLOSE) {
01355
01356
ExRaiseStatus( STATUS_INVALID_DEVICE_REQUEST );
01357 }
01358
01359
ASSERT( IrpSp->
FileObject !=
NULL ||
01360
01361 (IrpSp->
MajorFunction ==
IRP_MJ_FILE_SYSTEM_CONTROL &&
01362 IrpSp->
MinorFunction ==
IRP_MN_USER_FS_REQUEST &&
01363 IrpSp->
Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES) ||
01364
01365 (IrpSp->
MajorFunction ==
IRP_MJ_FILE_SYSTEM_CONTROL &&
01366 IrpSp->
MinorFunction ==
IRP_MN_MOUNT_VOLUME ) ||
01367
01368 IrpSp->
MajorFunction ==
IRP_MJ_SHUTDOWN );
01369 }
01370
01371 NewIrpContext =
ExAllocateFromNPagedLookasideList( &
UdfIrpContextLookasideList );
01372
01373 RtlZeroMemory( NewIrpContext,
sizeof(
IRP_CONTEXT ));
01374
01375
01376
01377
01378
01379 NewIrpContext->
NodeTypeCode =
UDFS_NTC_IRP_CONTEXT;
01380 NewIrpContext->
NodeByteSize =
sizeof(
IRP_CONTEXT );
01381
01382
01383
01384
01385
01386 NewIrpContext->
Irp =
Irp;
01387
01388
01389
01390
01391
01392
01393
if (IrpSp->
FileObject !=
NULL) {
01394
01395 NewIrpContext->
RealDevice = IrpSp->
FileObject->
DeviceObject;
01396 }
01397
01398
01399
01400
01401
01402
01403
if (!IsFsDo) {
01404
01405 NewIrpContext->
Vcb = &((
PVOLUME_DEVICE_OBJECT) IrpSp->
DeviceObject)->Vcb;
01406 }
01407
01408
01409
01410
01411
01412 NewIrpContext->
MajorFunction = IrpSp->
MajorFunction;
01413 NewIrpContext->
MinorFunction = IrpSp->
MinorFunction;
01414
01415
01416
01417
01418
01419
if (Wait) {
01420
01421
SetFlag( NewIrpContext->
Flags,
IRP_CONTEXT_FLAG_WAIT );
01422
01423 }
else {
01424
01425
SetFlag( NewIrpContext->
Flags,
IRP_CONTEXT_FLAG_FORCE_POST );
01426 }
01427
01428
01429
01430
01431
01432
return NewIrpContext;
01433 }
01434
01435
01436
VOID
01437 UdfCleanupIrpContext (
01438 IN
PIRP_CONTEXT IrpContext,
01439 IN BOOLEAN Post
01440 )
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461 {
01462
PAGED_CODE();
01463
01464
ASSERT_IRP_CONTEXT( IrpContext );
01465
01466
01467
01468
01469
01470
if (!
FlagOn( IrpContext->Flags,
IRP_CONTEXT_FLAG_MORE_PROCESSING)) {
01471
01472
01473
01474
01475
01476
01477
if (IrpContext->ThreadContext !=
NULL) {
01478
01479
UdfRestoreThreadContext( IrpContext );
01480 }
01481
01482
01483
01484
01485
01486
if (
FlagOn( IrpContext->Flags,
IRP_CONTEXT_FLAG_ALLOC_IO )) {
01487
01488
UdfFreeIoContext( IrpContext->IoContext );
01489 }
01490
01491
01492
01493
01494
01495
if (!
FlagOn( IrpContext->Flags,
IRP_CONTEXT_FLAG_ON_STACK )) {
01496
01497
ExFreeToNPagedLookasideList( &
UdfIrpContextLookasideList, IrpContext );
01498 }
01499
01500
01501
01502
01503
01504 }
else if (Post) {
01505
01506
01507
01508
01509
01510
01511
if (IrpContext->ThreadContext !=
NULL) {
01512
01513
UdfRestoreThreadContext( IrpContext );
01514 }
01515
01516
ClearFlag( IrpContext->Flags,
IRP_CONTEXT_FLAGS_CLEAR_ON_POST );
01517
01518 }
else {
01519
01520
ClearFlag( IrpContext->Flags,
IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY );
01521 }
01522
01523
return;
01524 }
01525
01526
01527
VOID
01528 UdfInitializeStackIrpContext (
01529 OUT
PIRP_CONTEXT IrpContext,
01530 IN
PIRP_CONTEXT_LITE IrpContextLite
01531 )
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553 {
01554
PAGED_CODE();
01555
01556
ASSERT_IRP_CONTEXT_LITE( IrpContextLite );
01557
01558
01559
01560
01561
01562 RtlZeroMemory( IrpContext,
sizeof(
IRP_CONTEXT ));
01563
01564
01565
01566
01567
01568 IrpContext->NodeTypeCode =
UDFS_NTC_IRP_CONTEXT;
01569 IrpContext->NodeByteSize =
sizeof(
IRP_CONTEXT );
01570
01571
01572
01573
01574
01575
SetFlag( IrpContext->Flags,
IRP_CONTEXT_FLAG_ON_STACK );
01576
01577
01578
01579
01580
01581 IrpContext->RealDevice = IrpContextLite->RealDevice;
01582
01583
01584
01585
01586
01587 IrpContext->Vcb = IrpContextLite->Fcb->Vcb;
01588
01589
01590
01591
01592
01593 IrpContext->MajorFunction =
IRP_MJ_CLOSE;
01594
01595
01596
01597
01598
01599
SetFlag( IrpContext->Flags,
IRP_CONTEXT_FLAG_WAIT );
01600
01601
return;
01602 }
01603
01604
01605
VOID
01606 UdfTeardownStructures (
01607 IN
PIRP_CONTEXT IrpContext,
01608 IN
PFCB StartingFcb,
01609 IN BOOLEAN Recursive,
01610 OUT PBOOLEAN RemovedStartingFcb
01611 )
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 {
01646
PVCB Vcb = StartingFcb->Vcb;
01647
PFCB CurrentFcb = StartingFcb;
01648 BOOLEAN AcquiredCurrentFcb =
FALSE;
01649
PFCB ParentFcb =
NULL;
01650
PLCB Lcb;
01651
01652 PLIST_ENTRY ListLinks;
01653 BOOLEAN Abort =
FALSE;
01654 BOOLEAN Removed;
01655
01656
PAGED_CODE();
01657
01658
01659
01660
01661
01662
ASSERT_IRP_CONTEXT( IrpContext );
01663
ASSERT_FCB( StartingFcb );
01664
01665 *RemovedStartingFcb =
FALSE;
01666
01667
01668
01669
01670
01671
01672
DebugTrace(( +1,
Dbg,
01673
"UdfTeardownStructures, StartingFcb %08x %s\n",
01674 StartingFcb,
01675 ( Recursive?
"Recursive" :
"Flat" )));
01676
01677
if (!Recursive) {
01678
01679
01680
01681
01682
01683
01684
if (
FlagOn( IrpContext->TopLevel->Flags,
IRP_CONTEXT_FLAG_IN_TEARDOWN )) {
01685
01686
return;
01687 }
01688
01689
SetFlag( IrpContext->TopLevel->Flags,
IRP_CONTEXT_FLAG_IN_TEARDOWN );
01690 }
01691
01692
01693
01694
01695
01696
try {
01697
01698
01699
01700
01701
01702
do {
01703
01704
01705
01706
01707
01708
01709
if ((
SafeNodeType( CurrentFcb ) !=
UDFS_NTC_FCB_DATA) &&
01710 (CurrentFcb->
FcbUserReference == 0) &&
01711 (CurrentFcb->FileObject !=
NULL)) {
01712
01713
01714
01715
01716
01717
UdfDeleteInternalStream( IrpContext, CurrentFcb );
01718 }
01719
01720
01721
01722
01723
01724
if (CurrentFcb->
FcbReference != 0) {
01725
01726
break;
01727 }
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
for ( ListLinks = CurrentFcb->
ParentLcbQueue.Flink;
01738 ListLinks != &CurrentFcb->
ParentLcbQueue; ) {
01739
01740 Lcb = CONTAINING_RECORD( ListLinks,
LCB, ChildFcbLinks );
01741
01742
ASSERT_LCB( Lcb );
01743
01744
01745
01746
01747
01748
01749 ListLinks = ListLinks->Flink;
01750
01751
01752
01753
01754
01755
01756
if (ParentFcb != Lcb->
ParentFcb) {
01757
01758
01759
01760
01761
01762
01763
if (ParentFcb) {
01764
01765
01766
01767
01768
01769
01770
ASSERT( !Recursive );
01771
01772
UdfTeardownStructures( IrpContext, ParentFcb,
TRUE, &Removed );
01773
01774
if (!Removed) {
01775
01776
UdfReleaseFcb( IrpContext, ParentFcb );
01777 }
01778 }
01779
01780
01781
01782
01783
01784 ParentFcb = Lcb->
ParentFcb;
01785
UdfAcquireFcbExclusive( IrpContext, ParentFcb,
FALSE );
01786 }
01787
01788
01789
01790
01791
01792
UdfLockVcb( IrpContext, Vcb );
01793
01794
01795
01796
01797
01798
if ( Lcb->
Reference != 0 ) {
01799
01800
01801
01802
01803
01804
01805
UdfUnlockVcb( IrpContext, Vcb );
01806
UdfReleaseFcb( IrpContext, ParentFcb );
01807 Abort =
TRUE;
01808
01809
break;
01810 }
01811
01812
01813
01814
01815
01816
ASSERT( Lcb->
ChildFcb == CurrentFcb );
01817
ASSERT( Lcb->
ParentFcb == ParentFcb );
01818
01819
DebugTrace(( +0,
Dbg,
01820
"UdfTeardownStructures, Lcb %08x P %08x <-> C %08x Vcb %d/%d PFcb %d/%d CFcb %d/%d\n",
01821 Lcb,
01822 ParentFcb,
01823 CurrentFcb,
01824 Vcb->
VcbReference,
01825 Vcb->
VcbUserReference,
01826 ParentFcb->
FcbReference,
01827 ParentFcb->
FcbUserReference,
01828 CurrentFcb->
FcbReference,
01829 CurrentFcb->
FcbUserReference ));
01830
01831
UdfRemovePrefix( IrpContext, Lcb );
01832
UdfDecrementReferenceCounts( IrpContext, ParentFcb, 1, 1 );
01833
01834
DebugTrace(( +0,
Dbg,
01835
"UdfTeardownStructures, Vcb %d/%d PFcb %d/%d\n",
01836 Vcb->
VcbReference,
01837 Vcb->
VcbUserReference,
01838 ParentFcb->
FcbReference,
01839 ParentFcb->
FcbUserReference ));
01840
01841
UdfUnlockVcb( IrpContext, Vcb );
01842 }
01843
01844
01845
01846
01847
01848
if (Abort) {
01849
01850
break;
01851 }
01852
01853
01854
01855
01856
01857
01858
UdfLockVcb( IrpContext, Vcb );
01859
01860
if (CurrentFcb->
FcbReference != 0) {
01861
01862
DebugTrace(( +0,
Dbg,
01863
"UdfTeardownStructures, saving Fcb %08x %d/%d\n",
01864 CurrentFcb,
01865 CurrentFcb->
FcbReference,
01866 CurrentFcb->
FcbUserReference ));
01867
01868
01869
01870
01871
01872
UdfUnlockVcb( IrpContext, Vcb );
01873
01874
if (ParentFcb !=
NULL) {
01875
01876
UdfReleaseFcb( IrpContext, ParentFcb );
01877 }
01878
01879
break;
01880 }
01881
01882
01883
01884
01885
01886
if (
FlagOn( CurrentFcb->
FcbState,
FCB_STATE_IN_FCB_TABLE )) {
01887
01888
UdfDeleteFcbTable( IrpContext, CurrentFcb );
01889
ClearFlag( CurrentFcb->
FcbState,
FCB_STATE_IN_FCB_TABLE );
01890
01891 }
01892
01893
01894
01895
01896
01897
01898
DebugTrace(( +0,
Dbg,
01899
"UdfTeardownStructures, toasting Fcb %08x %d/%d\n",
01900 CurrentFcb,
01901 CurrentFcb->
FcbReference,
01902 CurrentFcb->
FcbUserReference ));
01903
01904
UdfUnlockVcb( IrpContext, Vcb );
01905
UdfDeleteFcb( IrpContext, CurrentFcb );
01906
01907
01908
01909
01910
01911 CurrentFcb = ParentFcb;
01912 ParentFcb =
NULL;
01913 AcquiredCurrentFcb =
TRUE;
01914
01915 }
while (CurrentFcb !=
NULL);
01916
01917 } finally {
01918
01919
01920
01921
01922
01923
if (AcquiredCurrentFcb && (CurrentFcb !=
NULL)) {
01924
01925
UdfReleaseFcb( IrpContext, CurrentFcb );
01926 }
01927
01928
01929
01930
01931
01932
if (!Recursive) {
01933
01934
ClearFlag( IrpContext->TopLevel->Flags,
IRP_CONTEXT_FLAG_IN_TEARDOWN );
01935 }
01936 }
01937
01938 *RemovedStartingFcb = (CurrentFcb != StartingFcb);
01939
01940
DebugTrace(( -1,
Dbg,
01941
"UdfTeardownStructures, RemovedStartingFcb -> %c\n",
01942 ( *RemovedStartingFcb?
'T' :
'F' )));
01943
01944
return;
01945 }
01946
01947
01948
PFCB
01949 UdfLookupFcbTable (
01950 IN
PIRP_CONTEXT IrpContext,
01951 IN
PVCB Vcb,
01952 IN
FILE_ID FileId
01953 )
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974 {
01975
FCB_TABLE_ELEMENT Key;
01976
PFCB_TABLE_ELEMENT Hit;
01977
PFCB ReturnFcb =
NULL;
01978
01979
PAGED_CODE();
01980
01981
Key.FileId = FileId;
01982
01983 Hit = (
PFCB_TABLE_ELEMENT)
RtlLookupElementGenericTable( &Vcb->FcbTable, &
Key );
01984
01985
if (Hit !=
NULL) {
01986
01987 ReturnFcb = Hit->
Fcb;
01988 }
01989
01990
return ReturnFcb;
01991
01992 UNREFERENCED_PARAMETER( IrpContext );
01993 }
01994
01995
01996
PFCB
01997 UdfGetNextFcb (
01998 IN
PIRP_CONTEXT IrpContext,
01999 IN
PVCB Vcb,
02000 IN PVOID *RestartKey
02001 )
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 {
02025
PFCB Fcb;
02026
02027
PAGED_CODE();
02028
02029 Fcb = (
PFCB)
RtlEnumerateGenericTableWithoutSplaying( &Vcb->FcbTable, RestartKey );
02030
02031
if (Fcb !=
NULL) {
02032
02033 Fcb = ((
PFCB_TABLE_ELEMENT)(Fcb))->Fcb;
02034 }
02035
02036
return Fcb;
02037 }
02038
02039
02040
PFCB
02041 UdfCreateFcb (
02042 IN
PIRP_CONTEXT IrpContext,
02043 IN FILE_ID FileId,
02044 IN NODE_TYPE_CODE NodeTypeCode,
02045 OUT PBOOLEAN FcbExisted OPTIONAL
02046 )
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073 {
02074
PFCB NewFcb;
02075 BOOLEAN LocalFcbExisted;
02076
02077
PAGED_CODE();
02078
02079
02080
02081
02082
02083
if (!ARGUMENT_PRESENT( FcbExisted )) {
02084
02085 FcbExisted = &LocalFcbExisted;
02086 }
02087
02088
02089
02090
02091
02092 NewFcb =
UdfLookupFcbTable( IrpContext, IrpContext->Vcb, FileId );
02093
02094
02095
02096
02097
02098
if (NewFcb ==
NULL) {
02099
02100
02101
02102
02103
02104
try {
02105
02106
02107
02108
02109
02110
02111
switch (NodeTypeCode) {
02112
02113
case UDFS_NTC_FCB_INDEX:
02114
02115 NewFcb =
UdfAllocateFcbIndex( IrpContext );
02116
02117 RtlZeroMemory( NewFcb,
SIZEOF_FCB_INDEX );
02118
02119 NewFcb->NodeByteSize =
SIZEOF_FCB_INDEX;
02120
02121
break;
02122
02123
case UDFS_NTC_FCB_DATA :
02124
02125 NewFcb =
UdfAllocateFcbData( IrpContext );
02126
02127 RtlZeroMemory( NewFcb,
SIZEOF_FCB_DATA );
02128
02129 NewFcb->NodeByteSize =
SIZEOF_FCB_DATA;
02130
02131
break;
02132
02133
default:
02134
02135
UdfBugCheck( 0, 0, 0 );
02136 }
02137
02138
02139
02140
02141
02142 NewFcb->NodeTypeCode = NodeTypeCode;
02143
02144 NewFcb->
Vcb = IrpContext->Vcb;
02145 NewFcb->
FileId = FileId;
02146
02147 InitializeListHead( &NewFcb->
ParentLcbQueue );
02148 InitializeListHead( &NewFcb->
ChildLcbQueue );
02149
02150
02151
02152
02153
02154 NewFcb->
FcbNonpaged =
UdfCreateFcbNonPaged( IrpContext );
02155
02156 *FcbExisted =
FALSE;
02157
02158 } finally {
02159
02160
DebugUnwind(
"UdfCreateFcb" );
02161
02162
if (AbnormalTermination()) {
02163
02164
UdfFreePool( &NewFcb );
02165 }
02166 }
02167
02168 }
else {
02169
02170 *FcbExisted =
TRUE;
02171 }
02172
02173
return NewFcb;
02174 }
02175
02176
02177
VOID
02178 UdfDeleteFcb (
02179 IN
PIRP_CONTEXT IrpContext,
02180 IN
PFCB Fcb
02181 )
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201 {
02202
PVCB Vcb =
NULL;
02203
02204
PAGED_CODE();
02205
02206
02207
02208
02209
02210
ASSERT_IRP_CONTEXT( IrpContext );
02211
ASSERT_FCB( Fcb );
02212
02213
02214
02215
02216
02217
ASSERT( Fcb->FcbCleanup == 0 );
02218
ASSERT( Fcb->FcbReference == 0 );
02219
02220
ASSERT( IsListEmpty( &Fcb->ChildLcbQueue ));
02221
ASSERT( IsListEmpty( &Fcb->ParentLcbQueue ));
02222
02223
02224
02225
02226
02227
UdfUninitializeFcbMcb( Fcb );
02228
02229
UdfDeleteFcbNonpaged( IrpContext, Fcb->FcbNonpaged );
02230
02231
02232
02233
02234
02235
switch (Fcb->NodeTypeCode) {
02236
02237
case UDFS_NTC_FCB_INDEX:
02238
02239
ASSERT( Fcb->FileObject ==
NULL );
02240
02241
if (Fcb == Fcb->Vcb->RootIndexFcb) {
02242
02243 Vcb = Fcb->Vcb;
02244 Vcb->
RootIndexFcb =
NULL;
02245
02246 }
else if (Fcb == Fcb->Vcb->MetadataFcb) {
02247
02248 Vcb = Fcb->Vcb;
02249 Vcb->
MetadataFcb =
NULL;
02250
02251
UdfUninitializeVmcb( &Vcb->
Vmcb );
02252
02253 }
else if (Fcb == Fcb->Vcb->VatFcb) {
02254
02255 Vcb = Fcb->Vcb;
02256 Vcb->
VatFcb =
NULL;
02257 }
02258
02259
UdfDeallocateFcbIndex( IrpContext, Fcb );
02260
break;
02261
02262
case UDFS_NTC_FCB_DATA :
02263
02264
if (Fcb->FileLock !=
NULL) {
02265
02266
FsRtlFreeFileLock( Fcb->FileLock );
02267 }
02268
02269
FsRtlUninitializeOplock( &Fcb->Oplock );
02270
02271
if (Fcb == Fcb->Vcb->VolumeDasdFcb) {
02272
02273 Vcb = Fcb->Vcb;
02274 Vcb->
VolumeDasdFcb =
NULL;
02275 }
02276
02277
UdfDeallocateFcbData( IrpContext, Fcb );
02278
break;
02279 }
02280
02281
02282
02283
02284
02285
02286
if (Vcb !=
NULL) {
02287
02288 InterlockedDecrement( &Vcb->
VcbReference );
02289 InterlockedDecrement( &Vcb->
VcbUserReference );
02290 }
02291
02292
return;
02293 }
02294
02295
02296
VOID
02297 UdfInitializeFcbFromIcbContext (
02298 IN
PIRP_CONTEXT IrpContext,
02299 IN
PFCB Fcb,
02300 IN
PICB_SEARCH_CONTEXT IcbContext
02301 )
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323 {
02324
EA_SEARCH_CONTEXT EaContext;
02325
PICBFILE Icb;
02326
02327
PVCB Vcb;
02328
02329
PAGED_CODE();
02330
02331
02332
02333
02334
02335
ASSERT_IRP_CONTEXT( IrpContext );
02336
ASSERT_FCB( Fcb );
02337
02338
02339
02340
02341
02342 Icb = IcbContext->Active.View;
02343 Vcb = Fcb->Vcb;
02344
02345
ASSERT( IcbContext->IcbType ==
DESTAG_ID_NSR_FILE && Icb->
Destag.
Ident ==
DESTAG_ID_NSR_FILE );
02346
02347
02348
02349
02350
02351
02352
02353
if (
LongOffset( Icb->
EALength ) ||
02354 FIELD_OFFSET(
ICBFILE, EAs ) + Icb->
EALength + Icb->
AllocLength >
BlockSize( IcbContext->Vcb )) {
02355
02356
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
02357 }
02358
02359
UdfLockFcb( IrpContext, Fcb );
02360
02361
02362
02363
02364
02365
try {
02366
02367
02368
02369
02370
02371
if (Fcb->NodeTypeCode ==
UDFS_NTC_FCB_INDEX && Icb->
Icbtag.
FileType ==
ICBTAG_FILE_T_DIRECTORY) {
02372
02373
SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY );
02374
02375 }
else if (!(Fcb->NodeTypeCode ==
UDFS_NTC_FCB_DATA && Icb->
Icbtag.
FileType ==
ICBTAG_FILE_T_FILE)) {
02376
02377
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
02378 }
02379
02380
SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_READONLY );
02381
02382
02383
02384
02385
02386 Fcb->Resource = &Fcb->Vcb->FileResource;
02387
02388
02389
02390
02391
02392 Fcb->AllocationSize.QuadPart =
LlBlockAlign( Vcb, Icb->
InfoLength );
02393
02394 Fcb->FileSize.QuadPart =
02395 Fcb->ValidDataLength.QuadPart = Icb->
InfoLength;
02396
02397
UdfInitializeAllocations( IrpContext,
02398 Fcb,
02399 IcbContext );
02400
02401
02402
02403
02404
02405
UdfUpdateTimestampsFromIcbContext( IrpContext,
02406 IcbContext,
02407 &Fcb->Timestamps );
02408
02409
02410
02411
02412
02413 Fcb->LinkCount = Icb->
LinkCount;
02414
02415
02416
02417
02418
02419
02420
UdfInsertFcbTable( IrpContext, Fcb );
02421
SetFlag( Fcb->FcbState,
FCB_STATE_IN_FCB_TABLE |
FCB_STATE_INITIALIZED );
02422
02423 } finally {
02424
02425
UdfUnlockFcb( IrpContext, Fcb );
02426 }
02427
02428
return;
02429 }
02430
02431
02432
PCCB
02433 UdfCreateCcb (
02434 IN
PIRP_CONTEXT IrpContext,
02435 IN
PFCB Fcb,
02436 IN
PLCB Lcb OPTIONAL,
02437 IN ULONG Flags
02438 )
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460 {
02461
PCCB NewCcb;
02462
02463
PAGED_CODE();
02464
02465
02466
02467
02468
02469
ASSERT_IRP_CONTEXT( IrpContext );
02470
ASSERT_FCB( Fcb );
02471
ASSERT_OPTIONAL_LCB( Lcb );
02472
02473
02474
02475
02476
02477 NewCcb =
UdfAllocateCcb( IrpContext );
02478
02479
02480
02481
02482
02483 NewCcb->
NodeTypeCode =
UDFS_NTC_CCB;
02484 NewCcb->
NodeByteSize =
sizeof(
CCB );
02485
02486
02487
02488
02489
02490 NewCcb->
Flags = Flags;
02491 NewCcb->
Fcb = Fcb;
02492 NewCcb->
Lcb = Lcb;
02493
02494
02495
02496
02497
02498 NewCcb->
CurrentFileIndex = 0;
02499 NewCcb->
HighestReturnableFileIndex = 0;
02500
02501 NewCcb->
SearchExpression.Length =
02502 NewCcb->
SearchExpression.MaximumLength = 0;
02503 NewCcb->
SearchExpression.Buffer =
NULL;
02504
02505
return NewCcb;
02506 }
02507
02508
02509
VOID
02510 UdfDeleteCcb (
02511 IN
PIRP_CONTEXT IrpContext,
02512 IN
PCCB Ccb
02513 )
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 {
02532
PAGED_CODE();
02533
02534
02535
02536
02537
02538
ASSERT_IRP_CONTEXT( IrpContext );
02539
ASSERT_CCB( Ccb );
02540
02541
if (Ccb->SearchExpression.Buffer !=
NULL) {
02542
02543
UdfFreePool( &Ccb->SearchExpression.Buffer );
02544 }
02545
02546
UdfDeallocateCcb( IrpContext, Ccb );
02547
return;
02548 }
02549
02550
02551 ULONG
02552 UdfFindInParseTable (
02553 IN
PPARSE_KEYVALUE ParseTable,
02554 IN PCHAR Id,
02555 IN ULONG MaxIdLen
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
PAGED_CODE();
02581
02582
while (ParseTable->Key !=
NULL) {
02583
02584
if (RtlEqualMemory(ParseTable->Key, Id, MaxIdLen)) {
02585
02586
break;
02587 }
02588
02589 ParseTable++;
02590 }
02591
02592
return ParseTable->Value;
02593 }
02594
02595
02596
#ifdef UDF_SANITY
02597
02598
02599
02600
02601
02602
typedef enum _VERIFY_FAILURE {
02603
02604 Nothing,
02605 BadLbn,
02606 BadTag,
02607 BadChecksum,
02608 BadCrcLength,
02609 BadCrc,
02610 BadDestagVersion
02611
02612 } VERIFY_FAILURE;
02613
02614
#endif
02615
02616 BOOLEAN
02617 UdfVerifyDescriptor (
02618 IN
PIRP_CONTEXT IrpContext,
02619 IN
PDESTAG Descriptor,
02620 IN USHORT Tag,
02621 IN ULONG Size,
02622 IN ULONG Lbn,
02623 IN BOOLEAN ReturnError
02624 )
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653 {
02654 UCHAR Checksum = 0;
02655 PCHAR CheckPtr;
02656
USHORT Crc;
02657
02658
#ifdef UDF_SANITY
02659
02660 VERIFY_FAILURE FailReason = Nothing;
02661
02662
#endif
02663
02664
02665
02666
02667
02668
ASSERT_IRP_CONTEXT( IrpContext );
02669
02670
PAGED_CODE();
02671
02672
#ifdef UDF_SANITY
02673
02674
if (UdfNoisyVerifyDescriptor) {
02675
02676
goto BeNoisy;
02677 }
02678
02679 RegularEntry:
02680
02681
#endif
02682
02683
02684
02685
02686
02687
02688
02689
#ifdef UDF_SUPPORT_NONSTANDARD_ADAPTEC
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
if (
TRUE)
02700
02701
#else
02702
02703
if (Descriptor->Version ==
DESTAG_VER_CURRENT)
02704
02705
#endif
02706
02707 {
02708
02709
02710
02711
02712
02713
02714
02715
#ifdef UDF_SUPPORT_NONSTANDARD_HP
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
if (
TRUE)
02726
02727
#else
02728
02729
if (Descriptor->Lbn == Lbn)
02730
02731
#endif
02732
{
02733
02734
02735
02736
02737
02738
if (Descriptor->Ident == Tag) {
02739
02740
02741
02742
02743
02744
02745
for (CheckPtr = (PCHAR) Descriptor;
02746 CheckPtr < (PCHAR) Descriptor + FIELD_OFFSET(
DESTAG, Checksum );
02747 CheckPtr++) {
02748
02749 Checksum += *CheckPtr;
02750 }
02751
02752
for (CheckPtr = (PCHAR) Descriptor + FIELD_OFFSET(
DESTAG, Checksum ) +
sizeof(UCHAR);
02753 CheckPtr < (PCHAR) Descriptor +
sizeof(
DESTAG);
02754 CheckPtr++) {
02755
02756 Checksum += *CheckPtr;
02757 }
02758
02759
if (Descriptor->Checksum == Checksum) {
02760
02761
02762
02763
02764
02765
02766
#ifdef UDF_SUPPORT_NONSTANDARD_HP
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
if (!Descriptor->CRCLen ||
02777 Descriptor->CRCLen <=
Size -
sizeof(
DESTAG))
02778
#else
02779
02780
if (Descriptor->CRCLen &&
02781 Descriptor->CRCLen <=
Size -
sizeof(
DESTAG))
02782
02783
#endif
02784
{
02785
02786 Crc =
UdfComputeCrc16( (PCHAR) Descriptor +
sizeof(
DESTAG),
02787 Descriptor->CRCLen );
02788
02789
#ifdef UDF_SUPPORT_NONSTANDARD_HP
02790
02791
02792
02793
02794
02795
02796
02797
if (!Descriptor->CRCLen ||
02798 Descriptor->CRC == Crc)
02799
02800
#else
02801
02802
if (Descriptor->CRC == Crc)
02803
02804
#endif
02805
{
02806
02807
02808
02809
02810
02811
#ifdef UDF_SANITY
02812
if (UdfNoisyVerifyDescriptor) {
02813
02814
DebugTrace(( -1,
Dbg,
"UdfVerifyDescriptor -> TRUE\n" ));
02815 }
02816
#endif
02817
return TRUE;
02818
02819 }
else {
02820
#ifdef UDF_SANITY
02821
FailReason = BadCrc;
02822
goto ReportFailure;
02823
#endif
02824
}
02825
02826 }
else {
02827
#ifdef UDF_SANITY
02828
FailReason = BadCrcLength;
02829
goto ReportFailure;
02830
#endif
02831
}
02832
02833 }
else {
02834
#ifdef UDF_SANITY
02835
FailReason = BadChecksum;
02836
goto ReportFailure;
02837
#endif
02838
}
02839
02840 }
else {
02841
#ifdef UDF_SANITY
02842
FailReason = BadTag;
02843
goto ReportFailure;
02844
#endif
02845
}
02846
02847 }
else {
02848
#ifdef UDF_SANITY
02849
FailReason = BadLbn;
02850
goto ReportFailure;
02851
#endif
02852
}
02853
02854 }
else {
02855
#ifdef UDF_SANITY
02856
FailReason = BadDestagVersion;
02857
goto ReportFailure;
02858
#endif
02859
}
02860
02861
#ifdef UDF_SANITY
02862
02863 BeNoisy:
02864
02865
DebugTrace(( +1,
Dbg,
02866
"UdfVerifyDescriptor, Destag %08x, Tag %x, Size %x, Lbn %x\n",
02867 Descriptor,
02868 Tag,
02869
Size,
02870 Lbn ));
02871
02872
if (FailReason == Nothing) {
02873
02874
goto RegularEntry;
02875
02876 }
else if (!UdfNoisyVerifyDescriptor) {
02877
02878
goto ReallyReportFailure;
02879 }
02880
02881 ReportFailure:
02882
02883
if (!UdfNoisyVerifyDescriptor) {
02884
02885
goto BeNoisy;
02886 }
02887
02888 ReallyReportFailure:
02889
02890
switch (FailReason) {
02891
case BadLbn:
02892
DebugTrace(( 0,
Dbg,
02893
"Lbn mismatch - Lbn %x != expected %x\n",
02894 Descriptor->Lbn,
02895 Lbn ));
02896
break;
02897
02898
case BadTag:
02899
DebugTrace(( 0,
Dbg,
02900
"Tag mismatch - Ident %x != expected %x\n",
02901 Descriptor->Ident,
02902 Tag ));
02903
break;
02904
02905
case BadChecksum:
02906
DebugTrace(( 0,
Dbg,
02907
"Checksum mismatch - Checksum %x != descriptor's %x\n",
02908 Checksum,
02909 Descriptor->Checksum ));
02910
break;
02911
02912
case BadCrcLength:
02913
DebugTrace(( 0,
Dbg,
02914
"CRC'd size bad - CrcLen %x is 0 or > max %x\n",
02915 Descriptor->CRCLen,
02916
Size -
sizeof(
DESTAG) ));
02917
break;
02918
02919
case BadCrc:
02920
DebugTrace(( 0,
Dbg,
02921
"CRC mismatch - Crc %x != descriptor's %x\n",
02922 Crc,
02923 Descriptor->CRC ));
02924
break;
02925
02926
case BadDestagVersion:
02927
DebugTrace(( 0,
Dbg,
02928
"Bad Destag Verion - %x != descriptor's %x\n",
02929
DESTAG_VER_CURRENT,
02930 Descriptor->Version ));
02931
break;
02932
02933
default:
02934
ASSERT(
FALSE );
02935 }
02936
02937
DebugTrace(( -1,
Dbg,
"UdfVerifyDescriptor -> FALSE\n" ));
02938
02939
#endif
02940
02941
if (!ReturnError) {
02942
02943
UdfRaiseStatus( IrpContext, STATUS_CRC_ERROR );
02944 }
02945
02946
return FALSE;
02947 }
02948
02949
02950
VOID
02951 UdfInitializeIcbContextFromFcb (
02952 IN
PIRP_CONTEXT IrpContext,
02953 IN
PICB_SEARCH_CONTEXT IcbContext,
02954 IN
PFCB Fcb
02955 )
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974 {
02975
PAGED_CODE();
02976
02977
02978
02979
02980
02981
ASSERT_IRP_CONTEXT( IrpContext );
02982
ASSERT_FCB( Fcb );
02983
02984 RtlZeroMemory( IcbContext,
sizeof(
ICB_SEARCH_CONTEXT ));
02985
02986 IcbContext->Vcb = Fcb->Vcb;
02987 IcbContext->IcbType =
DESTAG_ID_NSR_FILE;
02988
02989
02990
02991
02992
02993
02994
if (Fcb->RootExtentLength == 0) {
02995
02996
PICBFILE Icb;
02997
02998
02999
03000
03001
03002
03003
03004
UdfMapMetadataView( IrpContext,
03005 &IcbContext->Current,
03006 IcbContext->Vcb,
03007
UdfGetFidPartition( Fcb->FileId ),
03008
UdfGetFidLbn( Fcb->FileId ),
03009
BlockSize( IcbContext->Vcb ));
03010
03011 Icb = IcbContext->Current.View;
03012
03013
03014
03015
03016
03017
03018
if (Icb->
Destag.
Ident ==
DESTAG_ID_NSR_ICBIND ||
03019 Icb->
Destag.
Ident ==
DESTAG_ID_NSR_ICBTRM ||
03020 Icb->
Destag.
Ident ==
DESTAG_ID_NSR_FILE ||
03021 Icb->
Destag.
Ident ==
DESTAG_ID_NSR_UASE ||
03022 Icb->
Destag.
Ident ==
DESTAG_ID_NSR_PINTEG) {
03023
03024
UdfVerifyDescriptor( IrpContext,
03025 &Icb->
Destag,
03026 Icb->
Destag.
Ident,
03027
BlockSize( IcbContext->Vcb ),
03028
UdfGetFidLbn( Fcb->FileId ),
03029
FALSE );
03030 }
else {
03031
03032
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03033 }
03034
03035
03036
03037
03038
03039
03040
03041
03042 Fcb->RootExtentLength = Icb->
Icbtag.
MaxEntries *
BlockSize( IcbContext->Vcb );
03043 }
03044
03045
03046
03047
03048
03049
UdfMapMetadataView( IrpContext,
03050 &IcbContext->Current,
03051 IcbContext->Vcb,
03052
UdfGetFidPartition( Fcb->FileId ),
03053
UdfGetFidLbn( Fcb->FileId ),
03054 Fcb->RootExtentLength );
03055
return;
03056 }
03057
03058
03059
VOID
03060 UdfInitializeIcbContext (
03061 IN
PIRP_CONTEXT IrpContext,
03062 IN
PICB_SEARCH_CONTEXT IcbContext,
03063 IN
PVCB Vcb,
03064 IN USHORT IcbType,
03065 IN USHORT Partition,
03066 IN ULONG Lbn,
03067 IN ULONG Length
03068 )
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094 {
03095
PAGED_CODE();
03096
03097
03098
03099
03100
03101
ASSERT_IRP_CONTEXT( IrpContext );
03102
03103 RtlZeroMemory( IcbContext,
sizeof(
ICB_SEARCH_CONTEXT ));
03104
03105 IcbContext->Vcb = Vcb;
03106 IcbContext->IcbType = IcbType;
03107
03108
03109
03110
03111
03112
UdfMapMetadataView( IrpContext,
03113 &IcbContext->Current,
03114 Vcb,
03115 Partition,
03116 Lbn,
03117 Length );
03118
return;
03119
03120 }
03121
03122
03123
VOID
03124 UdfLookupActiveIcb (
03125 IN
PIRP_CONTEXT IrpContext,
03126 IN
PICB_SEARCH_CONTEXT IcbContext
03127 )
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148 {
03149
PAGED_CODE();
03150
03151
03152
03153
03154
03155
ASSERT_IRP_CONTEXT( IrpContext );
03156
03157
03158
03159
03160
03161
03162
03163
03164
UdfLookupActiveIcbInExtent( IrpContext,
03165 IcbContext,
03166
UDF_ICB_RECURSION_LIMIT );
03167
03168
03169
03170
03171
03172
03173
UdfUnpinView( IrpContext, &IcbContext->Current );
03174
03175
if (IcbContext->Active.View ==
NULL) {
03176
03177
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03178 }
03179 }
03180
03181
03182
VOID
03183 UdfCleanupIcbContext (
03184 IN
PIRP_CONTEXT IrpContext,
03185 IN
PICB_SEARCH_CONTEXT IcbContext
03186 )
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204 {
03205
PAGED_CODE();
03206
03207
03208
03209
03210
03211
ASSERT_IRP_CONTEXT( IrpContext );
03212
03213
UdfUnpinView( IrpContext, &IcbContext->Active );
03214
UdfUnpinView( IrpContext, &IcbContext->Current );
03215
03216 RtlZeroMemory( IcbContext,
sizeof(
ICB_SEARCH_CONTEXT ));
03217 }
03218
03219
03220
VOID
03221 UdfInitializeEaContext (
03222 IN
PIRP_CONTEXT IrpContext,
03223 IN
PEA_SEARCH_CONTEXT EaContext,
03224 IN
PICB_SEARCH_CONTEXT IcbContext,
03225 IN ULONG EAType,
03226 IN UCHAR EASubType
03227 )
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248 {
03249
PICBFILE Icb;
03250
03251
PAGED_CODE();
03252
03253
03254
03255
03256
03257
ASSERT_IRP_CONTEXT( IrpContext );
03258
03259
ASSERT( IcbContext->Active.Bcb && IcbContext->Active.View );
03260
03261 Icb = IcbContext->Active.View;
03262
03263 EaContext->IcbContext = IcbContext;
03264
03265
03266
03267
03268
03269 EaContext->Ea = Icb->
EAs;
03270 EaContext->Remaining = Icb->
EALength;
03271
03272 EaContext->EAType = EAType;
03273 EaContext->EASubType = EASubType;
03274 }
03275
03276
03277 BOOLEAN
03278 UdfLookupEa (
03279 IN
PIRP_CONTEXT IrpContext,
03280 IN
PEA_SEARCH_CONTEXT EaContext
03281 )
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299 {
03300
PICBFILE Icb;
03301
PNSR_EA_GENERIC GenericEa;
03302
03303
PAGED_CODE();
03304
03305
03306
03307
03308
03309
ASSERT_IRP_CONTEXT( IrpContext );
03310
03311
03312
03313
03314
03315
03316
if (EaContext->Remaining == 0) {
03317
03318
return FALSE;
03319
03320 }
else if (EaContext->Remaining <
sizeof(
NSR_EAH )) {
03321
03322
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03323 }
03324
03325
03326
03327
03328
03329
03330 Icb = EaContext->IcbContext->Active.View;
03331
03332
UdfVerifyDescriptor( IrpContext,
03333 &((
PNSR_EAH) EaContext->Ea)->Destag,
03334
DESTAG_ID_NSR_EA,
03335
sizeof(
NSR_EAH ),
03336 Icb->
Destag.
Lbn,
03337
FALSE );
03338
03339
03340
03341
03342
03343
03344
03345 EaContext->Ea =
Add2Ptr( EaContext->Ea,
sizeof(
NSR_EAH ), PVOID );
03346 EaContext->Remaining -=
sizeof(
NSR_EAH );
03347
03348
while (EaContext->Remaining) {
03349
03350 GenericEa = EaContext->Ea;
03351
03352
03353
03354
03355
03356
03357
03358
if (
LongOffsetPtr( EaContext->Ea ) ||
03359 EaContext->Remaining < FIELD_OFFSET(
NSR_EA_GENERIC, EAData ) ||
03360 EaContext->Remaining < GenericEa->
EALength ) {
03361
03362
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03363 }
03364
03365
if (GenericEa->
EAType == EaContext->EAType && GenericEa->
EASubType == EaContext->EASubType) {
03366
03367
return TRUE;
03368 }
03369
03370 EaContext->Ea =
Add2Ptr( EaContext->Ea, GenericEa->
EALength, PVOID );
03371 EaContext->Remaining -= GenericEa->
EALength;
03372 }
03373
03374
03375
03376
03377
03378
if (EaContext->Remaining) {
03379
03380
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03381 }
03382
03383
return FALSE;
03384 }
03385
03386
03387
VOID
03388 UdfInitializeAllocations (
03389 IN
PIRP_CONTEXT IrpContext,
03390 IN
PFCB Fcb,
03391 IN
PICB_SEARCH_CONTEXT IcbContext
03392 )
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412 {
03413
PICBFILE Icb = IcbContext->Active.View;
03414
PAD_GENERIC GenericAd;
03415
03416
ALLOC_ENUM_CONTEXT AllocContext;
03417
03418 LONGLONG RunningOffset;
03419 ULONG Psn;
03420
USHORT Partition;
03421
03422
PVCB Vcb = Fcb->Vcb;
03423
03424 BOOLEAN Result;
03425 BOOLEAN InFileTail =
FALSE;
03426
03427
PAGED_CODE();
03428
03429
03430
03431
03432
03433
ASSERT_IRP_CONTEXT( IrpContext );
03434
ASSERT_FCB( Fcb );
03435
03436
03437
03438
03439
03440
03441
if (Fcb->FileSize.QuadPart == 0) {
03442
03443
return;
03444 }
03445
03446
UdfInitializeAllocationContext( IrpContext,
03447 &AllocContext,
03448 IcbContext );
03449
03450
03451
03452
03453
03454
if (AllocContext.
AllocType ==
ICBTAG_F_ALLOC_IMMEDIATE) {
03455
03456
03457
03458
03459
03460
UdfUninitializeFcbMcb( Fcb );
03461
03462
03463
03464
03465
03466
03467
03468
03469
SetFlag( Fcb->FcbState,
FCB_STATE_EMBEDDED_DATA );
03470
03471 Fcb->EmbeddedVsn =
UdfLookupMetaVsnOfExtent( IrpContext,
03472 Vcb,
03473 IcbContext->Active.Partition,
03474 Icb->
Destag.
Lbn,
03475
BlockSize( Vcb ),
03476
FALSE );
03477
03478
03479
03480
03481
03482 Fcb->EmbeddedOffset = FIELD_OFFSET(
ICBFILE, EAs ) + Icb->
EALength;
03483
03484
03485
03486
03487
03488
if (Icb->
AllocLength != Fcb->FileSize.LowPart) {
03489
03490
DebugTrace(( 0,
Dbg,
"UdfInitializeAllocations, embedded alloc %08x != filesize %08x\n",
03491 Icb->
AllocLength,
03492 Fcb->FileSize.LowPart ));
03493
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03494 }
03495
03496
return;
03497 }
03498
03499
03500
03501
03502
03503
UdfInitializeFcbMcb( Fcb );
03504
03505
03506
03507
03508
03509
03510 RunningOffset = 0;
03511
03512
do {
03513
03514
03515
03516
03517
03518
03519
03520
if (Fcb->FileSize.QuadPart == RunningOffset) {
03521
03522 InFileTail =
TRUE;
03523 }
03524
03525
03526
03527
03528
03529
03530
03531
03532 GenericAd = AllocContext.
Alloc;
03533
03534
if ((!InFileTail && (
BlockOffset( Vcb, RunningOffset ) ||
03535 Fcb->FileSize.QuadPart < RunningOffset)) ||
03536 (InFileTail && GenericAd->
Length.
Type !=
NSRLENGTH_TYPE_UNRECORDED)) {
03537
03538
DebugTrace(( 0,
Dbg,
"UdfInitializeAllocations, InFileTail == %u, bad alloc\n",
03539 InFileTail ));
03540
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03541 }
03542
03543
03544
03545
03546
03547
03548
if (InFileTail) {
03549
03550
continue;
03551 }
03552
03553
03554
03555
03556
03557
if (GenericAd->
Length.
Type ==
NSRLENGTH_TYPE_RECORDED) {
03558
03559
03560
03561
03562
03563 Psn =
UdfLookupPsnOfExtent( IrpContext,
03564 Vcb,
03565
UdfGetPartitionOfCurrentAllocation( &AllocContext ),
03566 GenericAd->
Start,
03567 GenericAd->
Length.
Length );
03568
03569 Result =
FsRtlAddLargeMcbEntry( &Fcb->Mcb,
03570
LlSectorsFromBytes( Vcb, RunningOffset ),
03571 Psn,
03572
SectorsFromBytes( Vcb,
SectorAlign( Vcb, GenericAd->
Length.
Length ) ));
03573
03574
ASSERT( Result );
03575 }
03576
03577 RunningOffset += GenericAd->
Length.
Length;
03578
03579 }
while (
UdfGetNextAllocation( IrpContext, &AllocContext ));
03580
03581
03582
03583
03584
03585
03586
if (Fcb->FileSize.QuadPart != RunningOffset) {
03587
03588
DebugTrace(( 0,
Dbg,
"UdfInitializeAllocations, total descriptors != filesize\n" ));
03589
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03590 }
03591 }
03592
03593
03594
VOID
03595 UdfUpdateTimestampsFromIcbContext (
03596 IN
PIRP_CONTEXT IrpContext,
03597 IN
PICB_SEARCH_CONTEXT IcbContext,
03598 IN
PTIMESTAMP_BUNDLE Timestamps
03599 )
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620 {
03621
EA_SEARCH_CONTEXT EaContext;
03622
PICBFILE Icb;
03623
03624
PAGED_CODE();
03625
03626
03627
03628
03629
03630
ASSERT_IRP_CONTEXT( IrpContext );
03631
03632
03633
03634
03635
03636 Icb = IcbContext->Active.View;
03637
03638
ASSERT( Icb->
Destag.
Ident ==
DESTAG_ID_NSR_FILE );
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
UdfConvertUdfTimeToNtTime( IrpContext,
03650 &Icb->
ModifyTime,
03651 (PLARGE_INTEGER) &Timestamps->ModificationTime );
03652
03653 Timestamps->CreationTime = Timestamps->ModificationTime;
03654
03655
UdfConvertUdfTimeToNtTime( IrpContext,
03656 &Icb->
AccessTime,
03657 (PLARGE_INTEGER) &Timestamps->AccessTime );
03658
03659
03660
03661
03662
03663
03664
UdfInitializeEaContext( IrpContext,
03665 &EaContext,
03666 IcbContext,
03667
EA_TYPE_FILETIMES,
03668
EA_SUBTYPE_BASE );
03669
03670
if (
UdfLookupEa( IrpContext, &EaContext )) {
03671
03672
PNSR_EA_FILETIMES FileTimes = EaContext.
Ea;
03673
03674
if (
FlagOn(FileTimes->
Existence,
EA_FILETIMES_E_CREATION)) {
03675
03676
UdfConvertUdfTimeToNtTime( IrpContext,
03677 &FileTimes->
Stamps[0],
03678 (PLARGE_INTEGER) &Timestamps->CreationTime );
03679 }
03680 }
03681
03682
UdfInitializeEaContext( IrpContext,
03683 &EaContext,
03684 IcbContext,
03685
EA_TYPE_INFOTIMES,
03686
EA_SUBTYPE_BASE );
03687
03688
if (
UdfLookupEa( IrpContext, &EaContext )) {
03689
03690
PNSR_EA_FILETIMES InfoTimes = EaContext.
Ea;
03691 BOOLEAN CreationPresent =
FALSE;
03692
03693
if (
FlagOn(InfoTimes->
Existence,
EA_INFOTIMES_E_CREATION)) {
03694
03695
UdfConvertUdfTimeToNtTime( IrpContext,
03696 &InfoTimes->
Stamps[0],
03697 (PLARGE_INTEGER) &Timestamps->CreationTime );
03698
03699 CreationPresent =
TRUE;
03700 }
03701
03702
if (
FlagOn(InfoTimes->
Existence,
EA_INFOTIMES_E_MODIFICATION)) {
03703
03704
UdfConvertUdfTimeToNtTime( IrpContext,
03705 &InfoTimes->
Stamps[CreationPresent? 1: 0],
03706 (PLARGE_INTEGER) &Timestamps->CreationTime );
03707 }
03708 }
03709 }
03710
03711
03712 BOOLEAN
03713 UdfCreateFileLock (
03714 IN
PIRP_CONTEXT IrpContext OPTIONAL,
03715 IN
PFCB Fcb,
03716 IN BOOLEAN RaiseOnError
03717 )
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742 {
03743 BOOLEAN Result =
TRUE;
03744
PFILE_LOCK FileLock;
03745
03746
PAGED_CODE();
03747
03748
03749
03750
03751
03752
UdfLockFcb( IrpContext, Fcb );
03753
03754
if (Fcb->FileLock !=
NULL) {
03755
03756
UdfUnlockFcb( IrpContext, Fcb );
03757
return TRUE;
03758 }
03759
03760 Fcb->FileLock = FileLock =
03761
FsRtlAllocateFileLock(
NULL,
NULL );
03762
03763
UdfUnlockFcb( IrpContext, Fcb );
03764
03765
03766
03767
03768
03769
if (FileLock ==
NULL) {
03770
03771
if (RaiseOnError) {
03772
03773
ASSERT( ARGUMENT_PRESENT( IrpContext ));
03774
03775
UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
03776 }
03777
03778 Result =
FALSE;
03779 }
03780
03781
return Result;
03782 }
03783
03784
03785
03786
03787
03788
03789
VOID
03790 UdfLookupActiveIcbInExtent (
03791 IN
PIRP_CONTEXT IrpContext,
03792 IN
PICB_SEARCH_CONTEXT IcbContext,
03793 IN ULONG Recurse
03794 )
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818 {
03819
PVCB Vcb = IcbContext->Vcb;
03820
PFCB Fcb = Vcb->
MetadataFcb;
03821
03822 ULONG Length;
03823 ULONG Lbn;
03824
USHORT Partition;
03825
03826 ULONG Vsn;
03827
03828
PICBIND Icb;
03829
03830
PAGED_CODE();
03831
03832
03833
03834
03835
03836 Recurse--;
03837
03838
03839
03840
03841
03842 Partition = IcbContext->Current.Partition;
03843 Lbn = IcbContext->Current.Lbn;
03844 Length = IcbContext->Current.Length;
03845
03846 Icb = IcbContext->Current.View;
03847
03848
03849
03850
03851
03852
do {
03853
03854
switch (Icb->
Destag.
Ident) {
03855
03856
case DESTAG_ID_NSR_ICBIND:
03857
03858
UdfVerifyDescriptor( IrpContext,
03859 &Icb->
Destag,
03860
DESTAG_ID_NSR_ICBIND,
03861
sizeof(
ICBIND ),
03862 Lbn,
03863
FALSE );
03864
03865
03866
03867
03868
03869
if (Icb->
Icb.
Length.
Type ==
NSRLENGTH_TYPE_RECORDED) {
03870
03871
03872
03873
03874
03875
03876
03877
UdfMapMetadataView( IrpContext,
03878 &IcbContext->Current,
03879 Vcb,
03880 Icb->
Icb.
Start.
Partition,
03881 Icb->
Icb.
Start.
Lbn,
03882 Icb->
Icb.
Length.
Length );
03883
03884
if (Length !=
BlockSize( Vcb )) {
03885
03886
03887
03888
03889
03890
if (Recurse == 0) {
03891
03892
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03893 }
03894
03895
UdfLookupActiveIcbInExtent( IrpContext,
03896 IcbContext,
03897 Recurse );
03898
03899
03900
03901
03902
03903
UdfMapMetadataView( IrpContext,
03904 &IcbContext->Current,
03905 Vcb,
03906 Partition,
03907 Lbn,
03908 Length );
03909 }
else {
03910
03911
03912
03913
03914
03915 Partition = IcbContext->Current.Partition;
03916 Lbn = IcbContext->Current.Lbn;
03917 Length = IcbContext->Current.Length;
03918
03919 Icb = IcbContext->Current.View;
03920
03921
continue;
03922 }
03923
03924 }
03925
03926
break;
03927
03928
case DESTAG_ID_NSR_ICBTRM:
03929
03930
UdfVerifyDescriptor( IrpContext,
03931 &Icb->
Destag,
03932
DESTAG_ID_NSR_ICBTRM,
03933
sizeof(
ICBTRM ),
03934 Lbn,
03935
FALSE );
03936
03937
03938
03939
03940
03941
return;
03942
break;
03943
03944
case DESTAG_ID_NOTSPEC:
03945
03946
03947
03948
03949
03950
03951
return;
03952
break;
03953
03954
default:
03955
03956
03957
03958
03959
03960
if (Icb->
Destag.
Ident != IcbContext->IcbType) {
03961
03962
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
03963 }
03964
03965
03966
03967
03968
03969
03970
UdfVerifyDescriptor( IrpContext,
03971 &Icb->
Destag,
03972 Icb->
Destag.
Ident,
03973
BlockSize( Vcb ),
03974 Lbn,
03975
FALSE );
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
UdfMapMetadataView( IrpContext,
03986 &IcbContext->Active,
03987 Vcb,
03988 Partition,
03989 Lbn,
03990
BlockSize( Vcb ) );
03991
03992
break;
03993 }
03994
03995
03996
03997
03998
03999 Lbn++;
04000 Length -=
BlockSize( Vcb );
04001
04002 Icb =
Add2Ptr( Icb,
BlockSize( Vcb ), PVOID );
04003
04004 }
while (Length);
04005 }
04006
04007
04008
04009
04010
04011
04012
VOID
04013 UdfInitializeAllocationContext (
04014 IN
PIRP_CONTEXT IrpContext,
04015 IN
PALLOC_ENUM_CONTEXT AllocContext,
04016 IN
PICB_SEARCH_CONTEXT IcbContext
04017 )
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038 {
04039
PICBFILE Icb;
04040
04041
PAGED_CODE();
04042
04043
04044
04045
04046
04047
ASSERT_IRP_CONTEXT( IrpContext );
04048
04049
ASSERT( IcbContext->Active.View );
04050
04051 AllocContext->IcbContext = IcbContext;
04052
04053
04054
04055
04056
04057 Icb = IcbContext->Active.View;
04058 AllocContext->AllocType =
FlagOn( Icb->
Icbtag.
Flags,
ICBTAG_F_ALLOC_MASK );
04059
04060
04061
04062
04063
04064
if (AllocContext->AllocType ==
ICBTAG_F_ALLOC_IMMEDIATE) {
04065
04066
return;
04067 }
04068
04069
04070
04071
04072
04073
04074 AllocContext->Alloc =
Add2Ptr( Icb->
EAs, Icb->
EALength, PVOID );
04075 AllocContext->Remaining = Icb->
AllocLength;
04076
04077
ASSERT(
LongOffsetPtr( AllocContext->Alloc ) == 0 );
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
if (AllocContext->Remaining == 0 ||
04089 AllocContext->Remaining %
ISOAllocationDescriptorSize( AllocContext->AllocType ) ||
04090 AllocContext->AllocType ==
ICBTAG_F_ALLOC_EXTENDED ||
04091 !
UdfGetNextAllocationPostProcessing( IrpContext, AllocContext )) {
04092
04093
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
04094 }
04095 }
04096
04097
04098
04099
04100
04101
04102 BOOLEAN
04103 UdfGetNextAllocation (
04104 IN
PIRP_CONTEXT IrpContext,
04105 IN
PALLOC_ENUM_CONTEXT AllocContext
04106 )
04107
04108
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127 {
04128
PAGED_CODE();
04129
04130
04131
04132
04133
04134
ASSERT_IRP_CONTEXT( IrpContext );
04135
04136 AllocContext->Remaining -=
ISOAllocationDescriptorSize( AllocContext->AllocType );
04137 AllocContext->Alloc =
Add2Ptr( AllocContext->Alloc,
ISOAllocationDescriptorSize( AllocContext->AllocType ), PVOID );
04138
04139
return UdfGetNextAllocationPostProcessing( IrpContext, AllocContext );
04140 }
04141
04142
04143 BOOLEAN
04144 UdfGetNextAllocationPostProcessing (
04145 IN
PIRP_CONTEXT IrpContext,
04146 IN
PALLOC_ENUM_CONTEXT AllocContext
04147 )
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168 {
04169
PAD_GENERIC GenericAd;
04170
PNSR_ALLOC AllocDesc;
04171
04172
PVCB Vcb = AllocContext->IcbContext->Vcb;
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
if (AllocContext->Remaining == 0) {
04188
04189
return FALSE;
04190 }
04191
04192
while (
TRUE) {
04193
04194 GenericAd = AllocContext->Alloc;
04195
04196
if (GenericAd->
Length.
Length == 0) {
04197
04198
return FALSE;
04199 }
04200
04201
04202
04203
04204
04205
if (GenericAd->
Length.
Type !=
NSRLENGTH_TYPE_CONTINUATION) {
04206
04207
break;
04208 }
04209
04210
04211
04212
04213
04214
if (GenericAd->
Length.
Length >
BlockSize( Vcb )) {
04215
04216
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
04217 }
04218
04219
UdfMapMetadataView( IrpContext,
04220 &AllocContext->IcbContext->Current,
04221 Vcb,
04222
UdfGetPartitionOfCurrentAllocation( AllocContext ),
04223 GenericAd->
Start,
04224
BlockSize( Vcb ) );
04225
04226
04227
04228
04229
04230 AllocDesc = (
PNSR_ALLOC) AllocContext->IcbContext->Current.View;
04231
04232
UdfVerifyDescriptor( IrpContext,
04233 &AllocDesc->
Destag,
04234
DESTAG_ID_NSR_ALLOC,
04235
BlockSize( Vcb ),
04236 AllocContext->IcbContext->Current.Lbn,
04237
FALSE );
04238
04239
04240
04241
04242
04243
04244 AllocContext->Remaining = AllocDesc->
AllocLen;
04245 AllocContext->Alloc =
Add2Ptr( AllocContext->IcbContext->Current.View,
sizeof(
NSR_ALLOC ), PVOID );
04246
04247
04248
04249
04250
04251
04252
if (AllocContext->Remaining == 0 ||
04253 AllocContext->Remaining >
BlockSize( Vcb ) -
sizeof(
NSR_ALLOC ) ||
04254 AllocContext->Remaining %
ISOAllocationDescriptorSize( AllocContext->AllocType )) {
04255
04256
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
04257 }
04258 }
04259
04260
return TRUE;
04261 }
04262
04263
04264
04265
04266
04267
04268
PFCB_NONPAGED
04269 UdfCreateFcbNonPaged (
04270 IN
PIRP_CONTEXT IrpContext
04271 )
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288 {
04289
PFCB_NONPAGED FcbNonpaged;
04290
04291
PAGED_CODE();
04292
04293
04294
04295
04296
04297
04298 FcbNonpaged =
UdfAllocateFcbNonpaged( IrpContext );
04299
04300 RtlZeroMemory( FcbNonpaged,
sizeof(
FCB_NONPAGED ));
04301
04302 FcbNonpaged->
NodeTypeCode =
UDFS_NTC_FCB_NONPAGED;
04303 FcbNonpaged->
NodeByteSize =
sizeof(
FCB_NONPAGED );
04304
04305
ExInitializeResource( &FcbNonpaged->
FcbResource );
04306
ExInitializeFastMutex( &FcbNonpaged->
FcbMutex );
04307
04308
return FcbNonpaged;
04309 }
04310
04311
04312
04313
04314
04315
04316
VOID
04317 UdfDeleteFcbNonpaged (
04318 IN
PIRP_CONTEXT IrpContext,
04319 IN
PFCB_NONPAGED FcbNonpaged
04320 )
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338 {
04339
PAGED_CODE();
04340
04341
ExDeleteResource( &FcbNonpaged->FcbResource );
04342
04343
UdfDeallocateFcbNonpaged( IrpContext, FcbNonpaged );
04344
04345
return;
04346 }
04347
04348
04349
04350
04351
04352
04353 RTL_GENERIC_COMPARE_RESULTS
04354 UdfFcbTableCompare (
04355 IN PRTL_GENERIC_TABLE Table,
04356 IN PVOID id1,
04357 IN PVOID id2
04358 )
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382 {
04383
FILE_ID Id1, Id2;
04384
PAGED_CODE();
04385
04386 Id1 = *((
FILE_ID UNALIGNED *) id1);
04387 Id2 = *((
FILE_ID UNALIGNED *) id2);
04388
04389
if (Id1.QuadPart < Id2.QuadPart) {
04390
04391
return GenericLessThan;
04392
04393 }
else if (Id1.QuadPart > Id2.QuadPart) {
04394
04395
return GenericGreaterThan;
04396
04397 }
else {
04398
04399
return GenericEqual;
04400 }
04401
04402 UNREFERENCED_PARAMETER( Table );
04403 }
04404
04405
04406
04407
04408
04409
04410 PVOID
04411 UdfAllocateTable (
04412 IN PRTL_GENERIC_TABLE Table,
04413 IN CLONG ByteSize
04414 )
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434 {
04435
PAGED_CODE();
04436
04437
return(
FsRtlAllocatePoolWithTag(
UdfPagedPool, ByteSize,
TAG_GENERIC_TABLE ));
04438 }
04439
04440
04441
04442
04443
04444
04445
VOID
04446 UdfDeallocateTable (
04447 IN PRTL_GENERIC_TABLE Table,
04448 IN PVOID Buffer
04449 )
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469 {
04470
PAGED_CODE();
04471
04472
ExFreePool(
Buffer );
04473
04474
return;
04475 UNREFERENCED_PARAMETER( Table );
04476 }
04477