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_DIRSUP)
00029
00030
00031
00032
00033
00034 #define Dbg (UDFS_DEBUG_LEVEL_DIRSUP)
00035
00036
00037
00038
00039
00040 BOOLEAN
00041
UdfLookupDirEntryPostProcessing (
00042 IN
PIRP_CONTEXT IrpContext,
00043 IN
PFCB Fcb,
00044 IN
PDIR_ENUM_CONTEXT DirContext,
00045 IN BOOLEAN ReturnError
00046 );
00047
00048
#ifdef ALLOC_PRAGMA
00049
#pragma alloc_text(PAGE, UdfCleanupDirContext)
00050
#pragma alloc_text(PAGE, UdfFindDirEntry)
00051
#pragma alloc_text(PAGE, UdfInitializeDirContext)
00052
#pragma alloc_text(PAGE, UdfLookupDirEntryPostProcessing)
00053
#pragma alloc_text(PAGE, UdfLookupInitialDirEntry)
00054
#pragma alloc_text(PAGE, UdfLookupNextDirEntry)
00055
#pragma alloc_text(PAGE, UdfUpdateDirNames)
00056
#endif
00057
00058
00059
VOID
00060 UdfInitializeDirContext (
00061 IN
PIRP_CONTEXT IrpContext,
00062 IN
PDIR_ENUM_CONTEXT DirContext
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
ASSERT_IRP_CONTEXT( IrpContext );
00089
00090
00091
00092
00093
00094 RtlZeroMemory( DirContext,
sizeof(
DIR_ENUM_CONTEXT) );
00095 }
00096
00097
00098
VOID
00099 UdfCleanupDirContext (
00100 IN
PIRP_CONTEXT IrpContext,
00101 IN
PDIR_ENUM_CONTEXT DirContext
00102 )
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 {
00121
PAGED_CODE();
00122
00123
00124
00125
00126
00127
ASSERT_IRP_CONTEXT( IrpContext );
00128
00129
00130
00131
00132
00133
UdfFreePool( &DirContext->NameBuffer );
00134
00135
00136
00137
00138
00139
UdfFreePool( &DirContext->ShortObjectName.Buffer );
00140
00141
00142
00143
00144
00145
UdfUnpinData( IrpContext, &DirContext->Bcb );
00146
00147
00148
00149
00150
00151
if (
FlagOn( DirContext->Flags,
DIR_CONTEXT_FLAG_FID_BUFFERED )) {
00152
00153
UdfFreePool( &DirContext->Fid );
00154 }
00155
00156
00157
00158
00159
00160 RtlZeroMemory( DirContext,
sizeof(
DIR_ENUM_CONTEXT ) );
00161 }
00162
00163
00164 BOOLEAN
00165 UdfLookupInitialDirEntry (
00166 IN
PIRP_CONTEXT IrpContext,
00167 IN
PFCB Fcb,
00168 IN
PDIR_ENUM_CONTEXT DirContext,
00169 IN PLONGLONG InitialOffset OPTIONAL
00170 )
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 {
00198 BOOLEAN Result;
00199
00200
PAGED_CODE();
00201
00202
00203
00204
00205
00206
ASSERT_IRP_CONTEXT( IrpContext );
00207
ASSERT_FCB_INDEX( Fcb );
00208
00209
00210
00211
00212
00213
if (Fcb->FileObject ==
NULL) {
00214
00215
UdfCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
00216 }
00217
00218
00219
00220
00221
00222 DirContext->Flags = 0;
00223
00224
if (InitialOffset) {
00225
00226
00227
00228
00229
00230
if (*InitialOffset != 0) {
00231
00232 DirContext->Flags =
DIR_CONTEXT_FLAG_SEEN_NONCONSTANT |
DIR_CONTEXT_FLAG_SEEN_PARENT;
00233 }
00234
00235
00236
00237
00238
00239 DirContext->BaseOffset.QuadPart =
GenericTruncate( *InitialOffset,
VACB_MAPPING_GRANULARITY );
00240 DirContext->ViewOffset = (ULONG)
GenericOffset( *InitialOffset,
VACB_MAPPING_GRANULARITY );
00241
00242 }
else {
00243
00244
00245
00246
00247
00248 DirContext->BaseOffset.QuadPart = 0;
00249 DirContext->ViewOffset = 0;
00250 }
00251
00252
00253
00254
00255
00256 DirContext->ViewLength =
VACB_MAPPING_GRANULARITY;
00257
00258
if (DirContext->BaseOffset.QuadPart + DirContext->ViewLength > Fcb->FileSize.QuadPart) {
00259
00260 DirContext->ViewLength = (ULONG) (Fcb->FileSize.QuadPart - DirContext->BaseOffset.QuadPart);
00261 }
00262
00263
UdfUnpinData( IrpContext, &DirContext->Bcb );
00264
00265
CcMapData( Fcb->FileObject,
00266 &DirContext->BaseOffset,
00267 DirContext->ViewLength,
00268
TRUE,
00269 &DirContext->Bcb,
00270 &DirContext->View );
00271
00272 DirContext->Fid =
Add2Ptr( DirContext->View, DirContext->ViewOffset,
PNSR_FID );
00273
00274
00275
00276
00277
00278
00279
return UdfLookupDirEntryPostProcessing( IrpContext,
00280 Fcb,
00281 DirContext,
00282 (BOOLEAN) (InitialOffset !=
NULL));
00283 }
00284
00285
00286 BOOLEAN
00287 UdfLookupNextDirEntry (
00288 IN
PIRP_CONTEXT IrpContext,
00289 IN
PFCB Fcb,
00290 IN
PDIR_ENUM_CONTEXT DirContext
00291 )
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 {
00312
PAGED_CODE();
00313
00314
00315
00316
00317
00318
ASSERT_IRP_CONTEXT( IrpContext );
00319
ASSERT_FCB_INDEX( Fcb );
00320
00321
00322
00323
00324
00325
if (DirContext->BaseOffset.QuadPart + DirContext->NextFidOffset == Fcb->FileSize.QuadPart) {
00326
00327
return FALSE;
00328 }
00329
00330
00331
00332
00333
00334
if (
FlagOn( DirContext->Flags,
DIR_CONTEXT_FLAG_FID_BUFFERED )) {
00335
00336
ClearFlag( DirContext->Flags,
DIR_CONTEXT_FLAG_FID_BUFFERED );
00337
UdfFreePool( &DirContext->Fid );
00338 }
00339
00340
00341
00342
00343
00344 DirContext->ViewOffset = DirContext->NextFidOffset;
00345 DirContext->Fid =
Add2Ptr( DirContext->View, DirContext->ViewOffset,
PNSR_FID );
00346
00347
00348
00349
00350
00351
00352
return UdfLookupDirEntryPostProcessing( IrpContext,
00353 Fcb,
00354 DirContext,
00355
FALSE );
00356 }
00357
00358
00359
VOID
00360 UdfUpdateDirNames (
00361 IN
PIRP_CONTEXT IrpContext,
00362 IN
PDIR_ENUM_CONTEXT DirContext,
00363 IN BOOLEAN IgnoreCase
00364 )
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 {
00386 PUCHAR NameDstring;
00387 BOOLEAN ContainsIllegal;
00388
00389
USHORT NameLength;
00390
USHORT BufferLength;
00391
USHORT PresentLength;
00392
00393
PAGED_CODE();
00394
00395
00396
00397
00398
00399
ASSERT_IRP_CONTEXT( IrpContext );
00400
00401
DebugTrace(( +1,
Dbg,
"UdfUpdateDirNames\n" ));
00402
00403
00404
00405
00406
00407
if (DirContext->Fid ==
NULL) {
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 DirContext->PureObjectName.Length =
00418 DirContext->CaseObjectName.Length =
00419 DirContext->ObjectName.Length =
UdfUnicodeDirectoryNames[
SELF_ENTRY].Length;
00420
00421 DirContext->PureObjectName.MaximumLength =
00422 DirContext->CaseObjectName.MaximumLength =
00423 DirContext->ObjectName.MaximumLength =
UdfUnicodeDirectoryNames[
SELF_ENTRY].MaximumLength;
00424
00425 DirContext->PureObjectName.Buffer =
00426 DirContext->CaseObjectName.Buffer =
00427 DirContext->ObjectName.Buffer =
UdfUnicodeDirectoryNames[
SELF_ENTRY].Buffer;
00428
00429
00430
00431
00432
00433
DebugTrace(( 0,
Dbg,
"Self Entry case\n" ));
00434
DebugTrace(( -1,
Dbg,
"UdfUpdateDirNames -> VOID\n" ));
00435
00436
return;
00437 }
00438
00439
00440
00441
00442
00443
if (
FlagOn( DirContext->Fid->Flags,
NSR_FID_F_PARENT )) {
00444
00445
00446
00447
00448
00449
00450
if (
FlagOn( DirContext->Flags,
DIR_CONTEXT_FLAG_SEEN_NONCONSTANT ) ||
00451 DirContext->Fid->FileIDLen != 0) {
00452
00453
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
00454 }
00455
00456
00457
00458
00459
00460
SetFlag( DirContext->Flags,
DIR_CONTEXT_FLAG_SEEN_PARENT );
00461
00462
00463
00464
00465
00466 DirContext->PureObjectName.Length =
00467 DirContext->CaseObjectName.Length =
00468 DirContext->ObjectName.Length =
UdfUnicodeDirectoryNames[
PARENT_ENTRY].Length;
00469
00470 DirContext->PureObjectName.MaximumLength =
00471 DirContext->CaseObjectName.MaximumLength =
00472 DirContext->ObjectName.MaximumLength =
UdfUnicodeDirectoryNames[
PARENT_ENTRY].MaximumLength;
00473
00474 DirContext->PureObjectName.Buffer =
00475 DirContext->CaseObjectName.Buffer =
00476 DirContext->ObjectName.Buffer =
UdfUnicodeDirectoryNames[
PARENT_ENTRY].Buffer;
00477
00478
00479
00480
00481
00482
DebugTrace(( 0,
Dbg,
"Parent Entry case\n" ));
00483
DebugTrace(( -1,
Dbg,
"UdfUpdateDirNames -> VOID\n" ));
00484
00485
return;
00486 }
00487
00488
00489
00490
00491
00492
00493 NameDstring =
Add2Ptr( DirContext->Fid,
ISONsrFidConstantSize + DirContext->Fid->ImpUseLen, PUCHAR );
00494
00495
00496
00497
00498
00499
if (!
FlagOn( DirContext->Flags,
DIR_CONTEXT_FLAG_SEEN_PARENT)) {
00500
00501
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
00502 }
00503
00504
00505
00506
00507
00508
SetFlag( DirContext->Flags,
DIR_CONTEXT_FLAG_SEEN_NONCONSTANT );
00509
00510
00511
00512
00513
00514
UdfCheckLegalCS0Dstring( IrpContext,
00515 NameDstring,
00516 DirContext->Fid->FileIDLen,
00517 0,
00518
FALSE );
00519
00520
00521
00522
00523
00524 BufferLength =
00525 NameLength =
Max(
BYTE_COUNT_8_DOT_3,
UdfCS0DstringUnicodeSize( IrpContext,
00526 NameDstring,
00527 DirContext->Fid->FileIDLen) );
00528
00529
00530
00531
00532
00533 ContainsIllegal = (!
UdfCS0DstringContainsLegalCharacters( NameDstring, DirContext->Fid->FileIDLen ) ||
00534 (NameLength /
sizeof( WCHAR )) >
MAX_LEN);
00535
00536
00537
00538
00539
00540
00541
if (ContainsIllegal) {
00542
00543 BufferLength = (NameLength += (
CRC_LEN *
sizeof(WCHAR)));
00544 }
00545
00546
00547
00548
00549
00550
00551
if (IgnoreCase) {
00552
00553 BufferLength += NameLength;
00554 }
00555
00556
00557
00558
00559
00560
if (ContainsIllegal) {
00561
00562 BufferLength += NameLength;
00563
00564 }
else {
00565
00566
00567
00568
00569
00570
00571
00572 DirContext->PureObjectName.Buffer = DirContext->ObjectName.Buffer;
00573 }
00574
00575
DebugTrace(( 0,
Dbg,
00576
"Ob %s%sneeds %d bytes (%d byte chunks), have %d\n",
00577 (IgnoreCase?
"Ic " :
""),
00578 (ContainsIllegal?
"Ci " :
""),
00579 BufferLength,
00580 NameLength,
00581 DirContext->AllocLength ));
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
if ((NameLength > DirContext->ObjectName.MaximumLength) ||
00593 (ContainsIllegal && DirContext->ObjectName.Buffer == DirContext->PureObjectName.Buffer)) {
00594
00595
DebugTrace(( 0,
Dbg,
"Resizing buffers\n" ));
00596
00597
00598
00599
00600
00601
00602
00603
if (DirContext->AllocLength >= BufferLength) {
00604
00605
00606
00607
00608
00609
00610 DirContext->PureObjectName.MaximumLength =
00611 DirContext->CaseObjectName.MaximumLength =
00612 DirContext->ObjectName.MaximumLength = DirContext->AllocLength / (1 +
00613 (IgnoreCase? 1 : 0) +
00614 (ContainsIllegal? 1 : 0));
00615
00616
DebugTrace(( 0,
Dbg,
00617
"... by resplit into %d byte chunks\n",
00618 DirContext->ObjectName.MaximumLength ));
00619
00620
00621
00622
00623
00624 DirContext->PureObjectName.Buffer =
00625 DirContext->CaseObjectName.Buffer =
00626 DirContext->ObjectName.Buffer = DirContext->NameBuffer;
00627
00628 }
else {
00629
00630
DebugTrace(( 0,
Dbg,
"... by allocating new pool\n" ));
00631
00632
00633
00634
00635
00636
UdfFreePool( &DirContext->NameBuffer );
00637 DirContext->AllocLength = 0;
00638
00639
00640
00641
00642
00643 DirContext->PureObjectName.MaximumLength =
00644 DirContext->CaseObjectName.MaximumLength =
00645 DirContext->ObjectName.MaximumLength = NameLength;
00646
00647 DirContext->NameBuffer =
00648 DirContext->PureObjectName.Buffer =
00649 DirContext->CaseObjectName.Buffer =
00650 DirContext->ObjectName.Buffer =
FsRtlAllocatePoolWithTag(
UdfPagedPool,
00651 BufferLength,
00652
TAG_FILE_NAME );
00653
00654 DirContext->AllocLength = BufferLength;
00655 }
00656
00657
00658
00659
00660
00661
00662
if (IgnoreCase) {
00663
00664 DirContext->CaseObjectName.Buffer =
Add2Ptr( DirContext->ObjectName.Buffer,
00665 DirContext->ObjectName.MaximumLength,
00666 PWCHAR );
00667 }
00668
00669
if (ContainsIllegal) {
00670
00671 DirContext->PureObjectName.Buffer =
Add2Ptr( DirContext->CaseObjectName.Buffer,
00672 DirContext->CaseObjectName.MaximumLength,
00673 PWCHAR );
00674 }
00675 }
00676
00677
ASSERT( BufferLength <= DirContext->AllocLength );
00678
00679
00680
00681
00682
00683
UdfConvertCS0DstringToUnicode( IrpContext,
00684 NameDstring,
00685 DirContext->Fid->FileIDLen,
00686 0,
00687 &DirContext->PureObjectName );
00688
00689
00690
00691
00692
00693
if (ContainsIllegal) {
00694
00695
UdfRenderNameToLegalUnicode( IrpContext,
00696 &DirContext->PureObjectName,
00697 &DirContext->ObjectName );
00698
00699
00700
00701
00702
00703 }
else {
00704
00705 DirContext->ObjectName.Length = DirContext->PureObjectName.Length;
00706 }
00707
00708
00709
00710
00711
00712
if (IgnoreCase) {
00713
00714
UdfUpcaseName( IrpContext,
00715 &DirContext->ObjectName,
00716 &DirContext->CaseObjectName );
00717 }
00718
00719
DebugTrace(( -1,
Dbg,
"UdfUpdateDirNames -> VOID\n" ));
00720
00721
return;
00722 }
00723
00724
00725 BOOLEAN
00726 UdfFindDirEntry (
00727 IN
PIRP_CONTEXT IrpContext,
00728 IN
PFCB Fcb,
00729 IN PUNICODE_STRING Name,
00730 IN BOOLEAN IgnoreCase,
00731 IN BOOLEAN ShortName,
00732 IN
PDIR_ENUM_CONTEXT DirContext
00733 )
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 {
00762 PUNICODE_STRING MatchName;
00763
00764
PAGED_CODE();
00765
00766
00767
00768
00769
00770
ASSERT_IRP_CONTEXT( IrpContext );
00771
ASSERT_FCB_INDEX( Fcb );
00772
00773
DebugTrace(( +1,
Dbg,
00774
"UdfFindDirEntry, Fcb=%08x Name=\"%wZ\" Ignore=%u Short=%u, DC=%08x\n",
00775 Fcb,
00776
Name,
00777 IgnoreCase,
00778 ShortName,
00779 DirContext ));
00780
00781
00782
00783
00784
00785
00786
if (ShortName) {
00787
00788 MatchName = &DirContext->ShortObjectName;
00789
00790 }
else {
00791
00792 MatchName = &DirContext->CaseObjectName;
00793 }
00794
00795
00796
00797
00798
00799
00800
UdfLookupInitialDirEntry( IrpContext,
00801 Fcb,
00802 DirContext,
00803
NULL );
00804
00805
00806
00807
00808
00809
do {
00810
00811
00812
00813
00814
00815
if (
FlagOn( DirContext->Fid->Flags,
NSR_FID_F_DELETED )) {
00816
00817
continue;
00818 }
00819
00820
UdfUpdateDirNames( IrpContext,
00821 DirContext,
00822 IgnoreCase );
00823
00824
00825
00826
00827
00828
00829
if (!
FlagOn( DirContext->Flags,
DIR_CONTEXT_FLAG_SEEN_NONCONSTANT )) {
00830
00831
continue;
00832 }
00833
00834
DebugTrace(( 0,
Dbg,
00835
"\"%wZ\" (pure \"%wZ\") @ +%08x\n",
00836 &DirContext->ObjectName,
00837 &DirContext->PureObjectName,
00838 DirContext->ViewOffset ));
00839
00840
00841
00842
00843
00844
00845
if (ShortName) {
00846
00847
00848
00849
00850
00851
if (!
UdfIs8dot3Name( IrpContext, DirContext->ObjectName )) {
00852
00853
00854
00855
00856
00857
if (DirContext->ShortObjectName.Buffer ==
NULL) {
00858
00859 DirContext->ShortObjectName.Buffer =
FsRtlAllocatePoolWithTag(
UdfPagedPool,
00860
BYTE_COUNT_8_DOT_3,
00861
TAG_SHORT_FILE_NAME );
00862 DirContext->ShortObjectName.MaximumLength =
BYTE_COUNT_8_DOT_3;
00863 }
00864
00865
UdfGenerate8dot3Name( IrpContext,
00866 &DirContext->PureObjectName,
00867 &DirContext->ShortObjectName );
00868
00869
DebugTrace(( 0,
Dbg,
00870
"built shortname \"%wZ\"\n", &DirContext->ShortObjectName ));
00871
00872 }
else {
00873
00874
00875
00876
00877
00878
00879
continue;
00880 }
00881 }
00882
00883
if (
UdfFullCompareNames( IrpContext,
00884 MatchName,
00885
Name ) ==
EqualTo) {
00886
00887
00888
00889
00890
00891
DebugTrace(( 0,
Dbg,
"HIT\n" ));
00892
DebugTrace(( -1,
Dbg,
"UdfFindDirEntry -> TRUE\n" ));
00893
00894
return TRUE;
00895 }
00896
00897 }
while (
UdfLookupNextDirEntry( IrpContext,
00898 Fcb,
00899 DirContext ));
00900
00901
00902
00903
00904
00905
DebugTrace(( -1,
Dbg,
"UdfFindDirEntry -> FALSE\n" ));
00906
00907
return FALSE;
00908 }
00909
00910
00911
00912
00913
00914
00915 BOOLEAN
00916 UdfLookupDirEntryPostProcessing (
00917 IN
PIRP_CONTEXT IrpContext,
00918 IN
PFCB Fcb,
00919 IN
PDIR_ENUM_CONTEXT DirContext,
00920 IN BOOLEAN ReturnError
00921 )
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 {
00950 BOOLEAN Result =
TRUE;
00951
00952
PNSR_FID FidBufferC =
NULL;
00953
PNSR_FID FidBuffer =
NULL;
00954
00955
PNSR_FID FidC;
00956
PNSR_FID Fid;
00957
00958 ULONG FidBytesInPreviousView = 0;
00959
00960
PAGED_CODE();
00961
00962
00963
00964
00965
00966
ASSERT_IRP_CONTEXT( IrpContext );
00967
ASSERT_FCB_INDEX( Fcb );
00968
00969
try {
00970
00971
00972
00973
00974
00975
if (DirContext->BaseOffset.QuadPart +
00976 DirContext->ViewOffset +
00977
ISONsrFidConstantSize > Fcb->FileSize.QuadPart) {
00978
00979
DebugTrace(( 0,
Dbg,
00980
"UdfLookupDirEntryPostProcessing: DC %p, constant header overlaps end of dir\n",
00981 DirContext ));
00982
00983
try_leave( Result =
FALSE );
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
if (
GenericTruncatePtr(
Add2Ptr( DirContext->Fid,
ISONsrFidConstantSize - 1, PUCHAR ),
VACB_MAPPING_GRANULARITY ) !=
00993 DirContext->View) {
00994
00995 FidBytesInPreviousView =
GenericRemainderPtr( DirContext->Fid,
VACB_MAPPING_GRANULARITY );
00996
00997
00998
00999
01000
01001
if (FidBytesInPreviousView) {
01002
01003 FidC =
01004 FidBufferC =
FsRtlAllocatePoolWithTag(
UdfPagedPool,
01005
ISONsrFidConstantSize,
01006
TAG_FID_BUFFER );
01007
01008 RtlCopyMemory( FidBufferC,
01009 DirContext->Fid,
01010 FidBytesInPreviousView );
01011 }
01012
01013
01014
01015
01016
01017 DirContext->BaseOffset.QuadPart +=
VACB_MAPPING_GRANULARITY;
01018 DirContext->ViewOffset = 0;
01019
01020
01021
01022
01023
01024 DirContext->ViewLength =
VACB_MAPPING_GRANULARITY;
01025
01026
if (DirContext->BaseOffset.QuadPart + DirContext->ViewLength > Fcb->FileSize.QuadPart) {
01027
01028 DirContext->ViewLength = (ULONG) (Fcb->FileSize.QuadPart - DirContext->BaseOffset.QuadPart);
01029 }
01030
01031
UdfUnpinData( IrpContext, &DirContext->Bcb );
01032
01033
CcMapData( Fcb->FileObject,
01034 &DirContext->BaseOffset,
01035 DirContext->ViewLength,
01036
TRUE,
01037 &DirContext->Bcb,
01038 &DirContext->View );
01039
01040
01041
01042
01043
01044
01045
if (FidBytesInPreviousView) {
01046
01047 RtlCopyMemory(
Add2Ptr( FidBufferC, FidBytesInPreviousView, PUCHAR ),
01048 DirContext->View,
01049
ISONsrFidConstantSize - FidBytesInPreviousView );
01050
01051
01052
01053
01054
01055
01056 }
else {
01057
01058
01059 DirContext->Fid = DirContext->View;
01060 }
01061 }
01062
01063
01064
01065
01066
01067
if (!FidBytesInPreviousView) {
01068
01069 FidC = DirContext->Fid;
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
if (((DirContext->BaseOffset.QuadPart +
01079 DirContext->ViewOffset -
01080 FidBytesInPreviousView +
01081
ISONsrFidSize( FidC ) > Fcb->FileSize.QuadPart) &&
01082
DebugTrace(( 0,
Dbg,
01083
"UdfLookupDirEntryPostProcessing: DC %p, FID (FidC %p, FBIPV %u) overlaps end of dir\n",
01084 DirContext,
01085 FidC,
01086 FidBytesInPreviousView )))
01087 ||
01088
01089 (
ISONsrFidSize( FidC ) >
BlockSize( Fcb->Vcb ) &&
01090
DebugTrace(( 0,
Dbg,
01091
"UdfLookupDirEntryPostProcessing: DC %p, FID (FidC %p) larger than a logical block\n",
01092 DirContext,
01093 FidC )))) {
01094
01095
try_leave( Result =
FALSE );
01096
01097 }
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
if (FidBytesInPreviousView ||
01109
GenericTruncatePtr(
Add2Ptr( DirContext->Fid,
ISONsrFidSize( FidC ) - 1, PUCHAR ),
VACB_MAPPING_GRANULARITY ) !=
01110 DirContext->View) {
01111
01112 Fid =
01113 FidBuffer =
FsRtlAllocatePoolWithTag(
UdfPagedPool,
01114
ISONsrFidSize( FidC ),
01115
TAG_FID_BUFFER );
01116
01117
01118
01119
01120
01121
01122
01123
if (FidBytesInPreviousView) {
01124
01125 RtlCopyMemory( FidBuffer,
01126 FidBufferC,
01127 FidBytesInPreviousView );
01128
01129 }
else {
01130
01131
01132
01133
01134
01135 FidBytesInPreviousView =
GenericRemainderPtr( DirContext->Fid,
VACB_MAPPING_GRANULARITY );
01136
01137 RtlCopyMemory( FidBuffer,
01138 DirContext->Fid,
01139 FidBytesInPreviousView );
01140
01141
01142
01143
01144
01145 DirContext->BaseOffset.QuadPart +=
VACB_MAPPING_GRANULARITY;
01146 DirContext->ViewOffset = 0;
01147
01148
01149
01150
01151
01152 DirContext->ViewLength =
VACB_MAPPING_GRANULARITY;
01153
01154
if (DirContext->BaseOffset.QuadPart + DirContext->ViewLength > Fcb->FileSize.QuadPart) {
01155
01156 DirContext->ViewLength = (ULONG) (Fcb->FileSize.QuadPart - DirContext->BaseOffset.QuadPart);
01157 }
01158
01159
UdfUnpinData( IrpContext, &DirContext->Bcb );
01160
01161
CcMapData( Fcb->FileObject,
01162 &DirContext->BaseOffset,
01163 DirContext->ViewLength,
01164
TRUE,
01165 &DirContext->Bcb,
01166 &DirContext->View );
01167 }
01168
01169
01170
01171
01172
01173 RtlCopyMemory(
Add2Ptr( FidBuffer, FidBytesInPreviousView, PUCHAR ),
01174 DirContext->View,
01175
ISONsrFidSize( FidC ) - FidBytesInPreviousView );
01176
01177 }
else {
01178
01179 Fid = DirContext->Fid;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188 Result =
UdfVerifyDescriptor( IrpContext,
01189 &Fid->
Destag,
01190
DESTAG_ID_NSR_FID,
01191
ISONsrFidSize( Fid ),
01192 Fid->
Destag.
Lbn,
01193 ReturnError );
01194
01195
01196
01197
01198
01199
if (FidBuffer && Result) {
01200
01201
SetFlag( DirContext->Flags,
DIR_CONTEXT_FLAG_FID_BUFFERED );
01202 DirContext->Fid = FidBuffer;
01203 FidBuffer =
NULL;
01204 }
01205
01206 } finally {
01207
01208
UdfFreePool( &FidBuffer );
01209
UdfFreePool( &FidBufferC );
01210 }
01211
01212
if (!ReturnError && !Result) {
01213
01214
UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
01215 }
01216
01217
01218
01219
01220
01221
01222
01223
01224
if (Result) {
01225
01226 DirContext->NextFidOffset = DirContext->ViewOffset +
01227
ISONsrFidSize( Fid );
01228
01229
if (FidBytesInPreviousView) {
01230
01231 DirContext->NextFidOffset -= FidBytesInPreviousView;
01232 }
01233 }
01234
01235
return Result;
01236 }
01237
01238