00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "lfsprocs.h"
00023
00024
00025
00026
00027
00028 #define Dbg (DEBUG_TRACE_QUERY)
00029
00030
#undef MODULE_POOL_TAG
00031 #define MODULE_POOL_TAG ('QsfL')
00032
00033
VOID
00034
LfsFindLogRecord (
00035 IN
PLFCB Lfcb,
00036 IN OUT
PLCB Lcb,
00037 IN LSN Lsn,
00038 OUT PLFS_RECORD_TYPE RecordType,
00039 OUT TRANSACTION_ID *TransactionId,
00040 OUT PLSN UndoNextLsn,
00041 OUT PLSN PreviousLsn,
00042 OUT PULONG BufferLength,
00043 OUT PVOID *Buffer
00044 );
00045
00046 BOOLEAN
00047
LfsFindClientNextLsn (
00048 IN
PLFCB Lfcb,
00049 IN
PLCB Lcb,
00050 OUT PLSN Lsn
00051 );
00052
00053 BOOLEAN
00054
LfsSearchForwardByClient (
00055 IN
PLFCB Lfcb,
00056 IN OUT
PLCB Lcb,
00057 OUT PLSN Lsn
00058 );
00059
00060
#ifdef ALLOC_PRAGMA
00061
#pragma alloc_text(PAGE, LfsFindClientNextLsn)
00062
#pragma alloc_text(PAGE, LfsFindLogRecord)
00063
#pragma alloc_text(PAGE, LfsQueryLastLsn)
00064
#pragma alloc_text(PAGE, LfsReadLogRecord)
00065
#pragma alloc_text(PAGE, LfsReadNextLogRecord)
00066
#pragma alloc_text(PAGE, LfsSearchForwardByClient)
00067
#pragma alloc_text(PAGE, LfsTerminateLogQuery)
00068
#endif
00069
00070
00071
VOID
00072 LfsReadLogRecord (
00073 IN LFS_LOG_HANDLE LogHandle,
00074 IN LSN FirstLsn,
00075 IN LFS_CONTEXT_MODE ContextMode,
00076 OUT PLFS_LOG_CONTEXT Context,
00077 OUT PLFS_RECORD_TYPE RecordType,
00078 OUT TRANSACTION_ID *TransactionId,
00079 OUT PLSN UndoNextLsn,
00080 OUT PLSN PreviousLsn,
00081 OUT PULONG BufferLength,
00082 OUT PVOID *Buffer
00083 )
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 {
00131
volatile NTSTATUS Status = STATUS_SUCCESS;
00132
00133
PLFS_CLIENT_RECORD ClientRecord;
00134
00135
PLCH Lch;
00136
00137
PLFCB Lfcb;
00138
00139
PLCB Lcb =
NULL;
00140
00141
PAGED_CODE();
00142
00143
DebugTrace( +1,
Dbg,
"LfsReadLogRecord: Entered\n", 0 );
00144
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00145
DebugTrace( 0,
Dbg,
"First Lsn (Low) -> %08lx\n", FirstLsn.LowPart );
00146
DebugTrace( 0,
Dbg,
"First Lsn (High) -> %08lx\n", FirstLsn.HighPart );
00147
DebugTrace( 0,
Dbg,
"Context Mode -> %08lx\n", ContextMode );
00148
00149 Lch = (
PLCH) LogHandle;
00150
00151
00152
00153
00154
00155
switch (ContextMode) {
00156
00157
case LfsContextUndoNext :
00158
case LfsContextPrevious :
00159
case LfsContextForward :
00160
00161
break;
00162
00163
default:
00164
00165
DebugTrace( 0,
Dbg,
"Invalid context mode -> %08x\n", ContextMode );
00166
ExRaiseStatus( STATUS_INVALID_PARAMETER );
00167 }
00168
00169
00170
00171
00172
00173
LfsValidateLch( Lch );
00174
00175
00176
00177
00178
00179
try {
00180
00181
00182
00183
00184
00185
try {
00186
00187
00188
00189
00190
00191
LfsAcquireLch( Lch );
00192 Lfcb = Lch->
Lfcb;
00193
00194
00195
00196
00197
00198
if (Lfcb ==
NULL) {
00199
00200
ExRaiseStatus( STATUS_ACCESS_DENIED );
00201 }
00202
00203
00204
00205
00206
00207
LfsValidateClientId( Lfcb, Lch );
00208
00209
00210
00211
00212
00213 ClientRecord =
Add2Ptr( Lfcb->
ClientArray,
00214 Lch->
ClientArrayByteOffset,
00215
PLFS_CLIENT_RECORD );
00216
00217
if (!
LfsVerifyClientLsnInRange( Lfcb, ClientRecord, FirstLsn )) {
00218
00219
ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR );
00220 }
00221
00222
00223
00224
00225
00226
LfsReleaseLch( Lch );
00227
00228
00229
00230
00231
00232
LfsAllocateLcb( Lfcb, &Lcb );
00233
00234
LfsInitializeLcb( Lcb,
00235 Lch->
ClientId,
00236 ContextMode );
00237
00238
00239
00240
00241
00242
LfsFindLogRecord( Lfcb,
00243 Lcb,
00244 FirstLsn,
00245 RecordType,
00246 TransactionId,
00247 UndoNextLsn,
00248 PreviousLsn,
00249 BufferLength,
00250
Buffer );
00251
00252
00253
00254
00255
00256 *Context = Lcb;
00257 Lcb =
NULL;
00258
00259 } finally {
00260
00261
DebugUnwind(
LfsReadLogRecord );
00262
00263
00264
00265
00266
00267
LfsReleaseLch( Lch );
00268
00269
00270
00271
00272
00273
if (Lcb !=
NULL) {
00274
00275
LfsDeallocateLcb( Lfcb, Lcb );
00276 }
00277
00278
DebugTrace( 0,
Dbg,
"Context -> %08lx\n", *Context );
00279
DebugTrace( 0,
Dbg,
"Buffer Length -> %08lx\n", *BufferLength );
00280
DebugTrace( 0,
Dbg,
"Buffer -> %08lx\n", *
Buffer );
00281
DebugTrace( -1,
Dbg,
"LfsReadLogRecord: Exit\n", 0 );
00282 }
00283
00284 } except (
LfsExceptionFilter( GetExceptionInformation() )) {
00285
00286
Status = GetExceptionCode();
00287 }
00288
00289
if (
Status != STATUS_SUCCESS) {
00290
00291
ExRaiseStatus(
Status );
00292 }
00293
00294
return;
00295 }
00296
00297
00298 BOOLEAN
00299 LfsReadNextLogRecord (
00300 IN LFS_LOG_HANDLE LogHandle,
00301 IN OUT LFS_LOG_CONTEXT Context,
00302 OUT PLFS_RECORD_TYPE RecordType,
00303 OUT TRANSACTION_ID *TransactionId,
00304 OUT PLSN UndoNextLsn,
00305 OUT PLSN PreviousLsn,
00306 OUT PLSN Lsn,
00307 OUT PULONG BufferLength,
00308 OUT PVOID *Buffer
00309 )
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 {
00352
volatile NTSTATUS Status = STATUS_SUCCESS;
00353
00354
PLCH Lch;
00355
00356
PLFCB Lfcb;
00357
00358
PLCB Lcb;
00359
00360 BOOLEAN FoundNextLsn;
00361
00362 BOOLEAN UnwindRememberLcbFields;
00363
PBCB UnwindRecordHeaderBcb;
00364
PLFS_RECORD_HEADER UnwindRecordHeader;
00365 PVOID UnwindCurrentLogRecord;
00366 BOOLEAN UnwindAuxilaryBuffer;
00367
00368
PAGED_CODE();
00369
00370
DebugTrace( +1,
Dbg,
"LfsReadNextLogRecord: Entered\n", 0 );
00371
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00372
DebugTrace( 0,
Dbg,
"Context -> %08lx\n", Context );
00373
00374 FoundNextLsn =
FALSE;
00375
00376 UnwindRememberLcbFields =
FALSE;
00377
00378 Lch = (
PLCH) LogHandle;
00379 Lcb = (
PLCB) Context;
00380
00381
00382
00383
00384
00385
LfsValidateLch( Lch );
00386
00387
00388
00389
00390
00391
try {
00392
00393
00394
00395
00396
00397
try {
00398
00399
00400
00401
00402
00403
LfsAcquireLch( Lch );
00404 Lfcb = Lch->
Lfcb;
00405
00406
00407
00408
00409
00410
if (Lfcb ==
NULL) {
00411
00412
ExRaiseStatus( STATUS_ACCESS_DENIED );
00413 }
00414
00415
00416
00417
00418
00419
LfsValidateClientId( Lfcb, Lch );
00420
00421
00422
00423
00424
00425
LfsValidateLcb( Lcb, Lch );
00426
00427
00428
00429
00430
00431 UnwindRememberLcbFields =
TRUE;
00432
00433 UnwindRecordHeaderBcb = Lcb->
RecordHeaderBcb;
00434 Lcb->
RecordHeaderBcb =
NULL;
00435
00436 UnwindRecordHeader = Lcb->
RecordHeader;
00437 UnwindCurrentLogRecord = Lcb->
CurrentLogRecord;
00438
00439 UnwindAuxilaryBuffer = Lcb->
AuxilaryBuffer;
00440 Lcb->
AuxilaryBuffer =
FALSE;
00441
00442
00443
00444
00445
00446
00447
if (
LfsFindClientNextLsn( Lfcb, Lcb, Lsn )) {
00448
00449
00450
00451
00452
00453
LfsReleaseLfcb( Lfcb );
00454
00455
00456
00457
00458
00459 Lcb->
CurrentLogRecord =
NULL;
00460 Lcb->
AuxilaryBuffer =
FALSE;
00461
00462
00463
00464
00465
00466
LfsFindLogRecord( Lfcb,
00467 Lcb,
00468 *Lsn,
00469 RecordType,
00470 TransactionId,
00471 UndoNextLsn,
00472 PreviousLsn,
00473 BufferLength,
00474
Buffer );
00475
00476 FoundNextLsn =
TRUE;
00477 }
00478
00479 } finally {
00480
00481
DebugUnwind(
LfsReadNextLogRecord );
00482
00483
00484
00485
00486
00487
00488
if (UnwindRememberLcbFields) {
00489
00490
if (AbnormalTermination()) {
00491
00492
00493
00494
00495
00496
00497
00498
if (Lcb->
RecordHeaderBcb !=
NULL) {
00499
00500
CcUnpinData( Lcb->
RecordHeaderBcb );
00501
00502 }
00503
00504
if (Lcb->
CurrentLogRecord !=
NULL
00505 && Lcb->
AuxilaryBuffer ==
TRUE) {
00506
00507
LfsFreeSpanningBuffer( Lcb->
CurrentLogRecord );
00508 }
00509
00510 Lcb->
RecordHeaderBcb = UnwindRecordHeaderBcb;
00511 Lcb->
RecordHeader = UnwindRecordHeader;
00512 Lcb->
CurrentLogRecord = UnwindCurrentLogRecord;
00513 Lcb->
AuxilaryBuffer = UnwindAuxilaryBuffer;
00514
00515
00516
00517
00518
00519
00520 }
else if (FoundNextLsn ) {
00521
00522
if (UnwindRecordHeaderBcb !=
NULL) {
00523
00524
CcUnpinData( UnwindRecordHeaderBcb );
00525 }
00526
00527
if (UnwindCurrentLogRecord !=
NULL
00528 && UnwindAuxilaryBuffer ==
TRUE) {
00529
00530
LfsFreeSpanningBuffer( UnwindCurrentLogRecord );
00531 }
00532
00533
00534
00535
00536
00537
00538 }
else {
00539
00540
if (UnwindRecordHeaderBcb !=
NULL) {
00541
00542
if (Lcb->
RecordHeaderBcb !=
NULL) {
00543
00544
CcUnpinData( UnwindRecordHeaderBcb );
00545
00546 }
else {
00547
00548 Lcb->
RecordHeaderBcb = UnwindRecordHeaderBcb;
00549 }
00550 }
00551
00552
if (UnwindAuxilaryBuffer) {
00553
00554
if (Lcb->
CurrentLogRecord == UnwindCurrentLogRecord) {
00555
00556 Lcb->
AuxilaryBuffer =
TRUE;
00557
00558 }
else {
00559
00560
LfsFreeSpanningBuffer( UnwindCurrentLogRecord );
00561 }
00562 }
00563 }
00564 }
00565
00566
00567
00568
00569
00570
LfsReleaseLch( Lch );
00571
00572
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn->LowPart );
00573
DebugTrace( 0,
Dbg,
"Lsn (High) -> %08lx\n", Lsn->HighPart );
00574
DebugTrace( 0,
Dbg,
"Buffer Length -> %08lx\n", *BufferLength );
00575
DebugTrace( 0,
Dbg,
"Buffer -> %08lx\n", *
Buffer );
00576
DebugTrace( -1,
Dbg,
"LfsReadNextLogRecord: Exit\n", 0 );
00577 }
00578
00579 } except (
LfsExceptionFilter( GetExceptionInformation() )) {
00580
00581
Status = GetExceptionCode();
00582 }
00583
00584
if (
Status != STATUS_SUCCESS) {
00585
00586
ExRaiseStatus(
Status );
00587 }
00588
00589
return FoundNextLsn;
00590 }
00591
00592
00593
VOID
00594 LfsTerminateLogQuery (
00595 IN LFS_LOG_HANDLE LogHandle,
00596 IN LFS_LOG_CONTEXT Context
00597 )
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 {
00622
PLCH Lch;
00623
PLCB Lcb;
00624
00625
PLFCB Lfcb;
00626
00627
PAGED_CODE();
00628
00629
DebugTrace( +1,
Dbg,
"LfsTerminateLogQuery: Entered\n", 0 );
00630
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00631
DebugTrace( 0,
Dbg,
"Context -> %08lx\n", Context );
00632
00633 Lch = (
PLCH) LogHandle;
00634 Lcb = (
PLCB) Context;
00635
00636
00637
00638
00639
00640
LfsValidateLch( Lch );
00641
00642
00643
00644
00645
00646
try {
00647
00648
00649
00650
00651
00652
LfsAcquireLch( Lch );
00653 Lfcb = Lch->
Lfcb;
00654
00655
00656
00657
00658
00659
if (Lfcb ==
NULL) {
00660
00661
try_return( NOTHING );
00662 }
00663
00664
00665
00666
00667
00668
LfsValidateClientId( Lfcb, Lch );
00669
00670
00671
00672
00673
00674
LfsValidateLcb( Lcb, Lch );
00675
00676
00677
00678
00679
00680
LfsDeallocateLcb( Lfcb, Lcb );
00681
00682 try_exit: NOTHING;
00683 } finally {
00684
00685
DebugUnwind(
LfsTerminateLogQuery );
00686
00687
00688
00689
00690
00691
LfsReleaseLch( Lch );
00692
00693
DebugTrace( -1,
Dbg,
"LfsTerminateLogQuery: Exit\n", 0 );
00694 }
00695
00696
return;
00697 }
00698
00699
00700
LSN
00701 LfsQueryLastLsn (
00702 IN LFS_LOG_HANDLE LogHandle
00703 )
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 {
00723
PLCH Lch;
00724
00725
PLFCB Lfcb;
00726
00727
LSN LastLsn;
00728
00729
PAGED_CODE();
00730
00731
DebugTrace( +1,
Dbg,
"LfsQueryLastLsn: Entered\n", 0 );
00732
DebugTrace( 0,
Dbg,
"Log Handle -> %08lx\n", LogHandle );
00733
00734 Lch = (
PLCH) LogHandle;
00735
00736
00737
00738
00739
00740
LfsValidateLch( Lch );
00741
00742
00743
00744
00745
00746
try {
00747
00748
00749
00750
00751
00752
LfsAcquireLch( Lch );
00753 Lfcb = Lch->
Lfcb;
00754
00755
00756
00757
00758
00759
if (Lfcb ==
NULL) {
00760
00761
ExRaiseStatus( STATUS_ACCESS_DENIED );
00762 }
00763
00764
00765
00766
00767
00768
LfsValidateClientId( Lfcb, Lch );
00769
00770
00771
00772
00773
00774
00775
00776
if (
FlagOn( Lfcb->
Flags,
LFCB_NO_LAST_LSN )) {
00777
00778 LastLsn =
LfsZeroLsn;
00779
00780 }
else {
00781
00782 LastLsn = Lfcb->
RestartArea->
CurrentLsn;
00783 }
00784
00785 } finally {
00786
00787
DebugUnwind(
LfsQueryLastLsn );
00788
00789
00790
00791
00792
00793
LfsReleaseLch( Lch );
00794
00795
DebugTrace( 0,
Dbg,
"Last Lsn (Low) -> %08lx\n", LastLsn.LowPart );
00796
DebugTrace( 0,
Dbg,
"Last Lsn (High) -> %08lx\n", LastLsn.HighPart );
00797
DebugTrace( -1,
Dbg,
"LfsQueryLastLsn: Exit\n", 0 );
00798 }
00799
00800
return LastLsn;
00801 }
00802
00803
00804
00805
00806
00807
00808
VOID
00809 LfsFindLogRecord (
00810 IN
PLFCB Lfcb,
00811 IN OUT
PLCB Lcb,
00812 IN LSN Lsn,
00813 OUT PLFS_RECORD_TYPE RecordType,
00814 OUT TRANSACTION_ID *TransactionId,
00815 OUT PLSN UndoNextLsn,
00816 OUT PLSN PreviousLsn,
00817 OUT PULONG BufferLength,
00818 OUT PVOID *Buffer
00819 )
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 {
00859 PCHAR NewBuffer;
00860 BOOLEAN UsaError;
00861 LONGLONG LogRecordLength;
00862 ULONG PageOffset;
00863
00864
PAGED_CODE();
00865
00866
DebugTrace( +1,
Dbg,
"LfsFindLogRecord: Entered\n", 0 );
00867
DebugTrace( 0,
Dbg,
"Lfcb -> %08lx\n", Lfcb );
00868
DebugTrace( 0,
Dbg,
"Context Block -> %08lx\n", Lcb );
00869
DebugTrace( 0,
Dbg,
"Lsn (Low) -> %08lx\n", Lsn.LowPart );
00870
00871 NewBuffer =
NULL;
00872
00873
00874
00875
00876
00877
try {
00878
00879
00880
00881
00882
00883
if (Lcb->RecordHeader ==
NULL) {
00884
00885
LfsPinOrMapLogRecordHeader( Lfcb,
00886 Lsn,
00887
FALSE,
00888
FALSE,
00889 &UsaError,
00890 &Lcb->RecordHeader,
00891 &Lcb->RecordHeaderBcb );
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
if ( Lsn.QuadPart != Lcb->RecordHeader->ThisLsn.QuadPart ) {
00901
00902
ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR );
00903 }
00904
00905
00906
00907
00908
00909
00910 LogRecordLength = Lcb->RecordHeader->ClientDataLength + Lfcb->RecordHeaderLength;
00911
00912
if ( LogRecordLength >= Lfcb->TotalAvailable ) {
00913
00914
ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR );
00915 }
00916
00917
00918
00919
00920
00921
00922
if (!
FlagOn( Lcb->RecordHeader->Flags,
LOG_RECORD_MULTI_PAGE )) {
00923
00924
00925
00926
00927
00928
00929 PageOffset =
LfsLsnToPageOffset( Lfcb, Lsn );
00930
00931
if ((PageOffset + Lcb->RecordHeader->ClientDataLength + Lfcb->RecordHeaderLength)
00932 > (ULONG)Lfcb->LogPageSize) {
00933
00934
ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR );
00935 }
00936
00937 Lcb->CurrentLogRecord =
Add2Ptr( Lcb->RecordHeader,
LFS_RECORD_HEADER_SIZE, PVOID );
00938 Lcb->AuxilaryBuffer =
FALSE;
00939
00940
00941
00942
00943
00944 }
else {
00945
00946 NewBuffer =
LfsAllocateSpanningBuffer( Lfcb, Lcb->RecordHeader->ClientDataLength );
00947
00948
00949
00950
00951
00952
LfsCopyReadLogRecord( Lfcb,
00953 Lcb->RecordHeader,
00954 NewBuffer );
00955
00956 Lcb->CurrentLogRecord = NewBuffer;
00957
00958 Lcb->AuxilaryBuffer =
TRUE;
00959
00960 NewBuffer =
NULL;
00961 }
00962
00963
00964
00965
00966
00967 *RecordType = Lcb->RecordHeader->RecordType;
00968 *TransactionId = Lcb->RecordHeader->TransactionId;
00969
00970 *UndoNextLsn = Lcb->RecordHeader->ClientUndoNextLsn;
00971 *PreviousLsn = Lcb->RecordHeader->ClientPreviousLsn;
00972
00973 *
Buffer = Lcb->CurrentLogRecord;
00974 *BufferLength = Lcb->RecordHeader->ClientDataLength;
00975
00976 } finally {
00977
00978
DebugUnwind(
LfsFindLogRecord );
00979
00980
00981
00982
00983
00984
00985
if (NewBuffer !=
NULL) {
00986
00987
LfsFreeSpanningBuffer( NewBuffer );
00988 }
00989
00990
DebugTrace( 0,
Dbg,
"Buffer Length -> %08lx\n", *BufferLength );
00991
DebugTrace( 0,
Dbg,
"Buffer -> %08lx\n", *
Buffer );
00992
DebugTrace( -1,
Dbg,
"LfsFindLogRecord: Exit\n", 0 );
00993 }
00994
00995
return;
00996 }
00997
00998
00999
01000
01001
01002
01003 BOOLEAN
01004 LfsFindClientNextLsn (
01005 IN
PLFCB Lfcb,
01006 IN
PLCB Lcb,
01007 OUT PLSN Lsn
01008 )
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 {
01032
LSN NextLsn;
01033 BOOLEAN NextLsnFound;
01034
01035
PLFS_CLIENT_RECORD ClientRecord;
01036
01037
PAGED_CODE();
01038
01039
DebugTrace( +1,
Dbg,
"LfsFindClientNextLsn: Entered\n", 0 );
01040
DebugTrace( 0,
Dbg,
"Lcb -> %08lx\n", Lcb );
01041
01042 ClientRecord = Lfcb->ClientArray + Lcb->ClientId.ClientIndex;
01043
01044
01045
01046
01047
01048
01049
switch (Lcb->ContextMode) {
01050
01051
case LfsContextUndoNext:
01052
case LfsContextPrevious:
01053
01054 NextLsn = (Lcb->ContextMode ==
LfsContextUndoNext
01055 ? Lcb->RecordHeader->ClientUndoNextLsn
01056 : Lcb->RecordHeader->ClientPreviousLsn);
01057
01058
if ( NextLsn.QuadPart == 0 ) {
01059
01060 NextLsnFound =
FALSE;
01061
01062 }
else if (
LfsVerifyClientLsnInRange( Lfcb, ClientRecord, NextLsn )) {
01063
01064 BOOLEAN UsaError;
01065
01066
LfsPinOrMapLogRecordHeader( Lfcb,
01067 NextLsn,
01068
FALSE,
01069
FALSE,
01070 &UsaError,
01071 &Lcb->RecordHeader,
01072 &Lcb->RecordHeaderBcb );
01073
01074 NextLsnFound =
TRUE;
01075
01076 }
else {
01077
01078 NextLsnFound =
FALSE;
01079 }
01080
01081
break;
01082
01083
case LfsContextForward:
01084
01085
01086
01087
01088
01089 NextLsnFound =
LfsSearchForwardByClient( Lfcb, Lcb, &NextLsn );
01090
break;
01091
01092
default:
01093
01094 NextLsnFound =
FALSE;
01095
break;
01096 }
01097
01098
if (NextLsnFound) {
01099
01100 *Lsn = NextLsn;
01101 }
01102
01103
DebugTrace( 0,
Dbg,
"NextLsn (Low) -> %08lx\n", NextLsn.LowPart );
01104
DebugTrace( 0,
Dbg,
"NextLsn (High) -> %08lx\n", NextLsn.HighPart );
01105
DebugTrace( -1,
Dbg,
"LfsFindClientNextLsn: Exit -> %08x\n", NextLsnFound );
01106
01107
return NextLsnFound;
01108 }
01109
01110
01111
01112
01113
01114
01115 BOOLEAN
01116 LfsSearchForwardByClient (
01117 IN
PLFCB Lfcb,
01118 IN OUT
PLCB Lcb,
01119 OUT PLSN Lsn
01120 )
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 {
01144
PLFS_RECORD_HEADER CurrentRecordHeader;
01145
PBCB CurrentBcb;
01146
01147 BOOLEAN FoundNextLsn;
01148
01149
LSN CurrentLsn;
01150
01151
PAGED_CODE();
01152
01153
DebugTrace( +1,
Dbg,
"LfsSearchForwardByClient: Entered\n", 0 );
01154
DebugTrace( 0,
Dbg,
"Lcb -> %08lx\n", Lcb );
01155
01156
01157
01158
01159
01160
01161
01162
01163 CurrentRecordHeader = Lcb->RecordHeader;
01164
01165 CurrentBcb =
NULL;
01166
01167
01168
01169
01170
01171
try {
01172
01173
01174
01175
01176
01177 FoundNextLsn =
FALSE;
01178
01179
01180
01181
01182
01183
while (
LfsFindNextLsn( Lfcb, CurrentRecordHeader, &CurrentLsn )) {
01184
01185 BOOLEAN UsaError;
01186
01187
01188
01189
01190
01191
if (CurrentBcb !=
NULL) {
01192
01193
CcUnpinData( CurrentBcb );
01194 CurrentBcb =
NULL;
01195 }
01196
01197
01198
01199
01200
01201
LfsPinOrMapLogRecordHeader( Lfcb,
01202 CurrentLsn,
01203
FALSE,
01204
FALSE,
01205 &UsaError,
01206 &CurrentRecordHeader,
01207 &CurrentBcb );
01208
01209
01210
01211
01212
01213
01214
if (
LfsClientIdMatch( &CurrentRecordHeader->
ClientId,
01215 &Lcb->ClientId )
01216 && CurrentRecordHeader->
RecordType ==
LfsClientRecord) {
01217
01218
01219
01220
01221
01222 Lcb->RecordHeader = CurrentRecordHeader;
01223 Lcb->RecordHeaderBcb = CurrentBcb;
01224
01225 CurrentBcb =
NULL;
01226 FoundNextLsn =
TRUE;
01227
01228 *Lsn = CurrentLsn;
01229
break;
01230 }
01231 }
01232
01233 } finally {
01234
01235
DebugUnwind(
LfsSearchForwardByClient );
01236
01237
01238
01239
01240
01241
if (CurrentBcb !=
NULL) {
01242
01243
CcUnpinData( CurrentBcb );
01244 }
01245
01246
DebugTrace( 0,
Dbg,
"NextLsn (Low) -> %08lx\n", Lsn->LowPart );
01247
DebugTrace( 0,
Dbg,
"NextLsn (High) -> %08lx\n", Lsn->HighPart );
01248
DebugTrace( -1,
Dbg,
"LfsSearchForwardByClient: Exit -> %08x\n", FoundNextLsn );
01249 }
01250
01251
return FoundNextLsn;
01252 }