mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
4.3 KiB
191 lines
4.3 KiB
/*++
|
|
|
|
Copyright (c) 1993 - Colorado Memory Systems, Inc.
|
|
All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
skipblk.c
|
|
|
|
Abstract:
|
|
|
|
Performs a forward skip of x bytes. Reverse seeks are not handled by this routine.
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
|
|
--*/
|
|
|
|
//
|
|
// include files
|
|
//
|
|
|
|
#include <ntddk.h>
|
|
#include <ntddtape.h>
|
|
#include "common.h"
|
|
#include "q117.h"
|
|
#include "protos.h"
|
|
|
|
#define FCT_ID 0x0121
|
|
|
|
dStatus
|
|
q117SkipBlock (
|
|
IN OUT ULONG *HowMany,
|
|
IN OUT PQ117_CONTEXT Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Skip forward X number of data bytes
|
|
|
|
Arguments:
|
|
|
|
HowMany - points to count of bytes to skip, returns with actual amount
|
|
skipped.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
dStatus ret; // Return value from other routine called.
|
|
SEGMENT cur_seg;
|
|
SEGMENT skippedSegments;
|
|
ULONG bytesLeft;
|
|
|
|
if (*HowMany >= Context->CurrentOperation.BytesOnTape) {
|
|
|
|
//
|
|
// Flag end of tape. This will allow for an append.
|
|
//
|
|
Context->CurrentOperation.Position = TAPE_SPACE_END_OF_DATA;
|
|
|
|
}
|
|
|
|
if (*HowMany > Context->CurrentOperation.BytesOnTape) {
|
|
|
|
return ERROR_ENCODE(ERR_END_OF_VOLUME, FCT_ID, 1);
|
|
}
|
|
|
|
|
|
ret = ERR_NO_ERR;
|
|
|
|
bytesLeft = *HowMany;
|
|
|
|
//
|
|
// count number of segments to skip
|
|
//
|
|
skippedSegments = 0;
|
|
cur_seg = Context->CurrentOperation.LastSegmentRead;
|
|
|
|
while (bytesLeft >= (ULONG)Context->CurrentOperation.SegmentBytesRemaining
|
|
&& !ret) {
|
|
|
|
bytesLeft -= Context->CurrentOperation.SegmentBytesRemaining;
|
|
Context->CurrentOperation.BytesOnTape -=
|
|
Context->CurrentOperation.SegmentBytesRemaining;
|
|
Context->CurrentOperation.BytesRead +=
|
|
Context->CurrentOperation.SegmentBytesRemaining;
|
|
++skippedSegments;
|
|
|
|
if (++cur_seg > Context->CurrentOperation.LastSegment) {
|
|
|
|
q117ClearQueue(Context);
|
|
ret = ERROR_ENCODE(ERR_END_OF_TAPE, FCT_ID, 1);
|
|
skippedSegments = 0;
|
|
cur_seg = Context->CurrentOperation.LastSegmentRead;
|
|
|
|
} else {
|
|
|
|
Context->CurrentOperation.SegmentBytesRemaining =
|
|
q117GoodDataBytes(cur_seg,Context);
|
|
|
|
}
|
|
}
|
|
|
|
if ((ULONG)skippedSegments > Context->SegmentBuffersAvailable) {
|
|
|
|
//
|
|
// We skipped outside the range of buffers that we
|
|
// save queued up to the lower level driver, so
|
|
// Clear the lower level driver's requests, and
|
|
// start reading the segment we skipped to.
|
|
//
|
|
q117ClearQueue(Context);
|
|
Context->CurrentOperation.SegmentBytesRemaining = 0;
|
|
Context->CurrentOperation.CurrentSegment =
|
|
Context->CurrentOperation.LastSegmentRead + skippedSegments;
|
|
|
|
} else {
|
|
|
|
//
|
|
// The request has already been made to read the segment
|
|
// that we skipped to, so just de-queue all requests in
|
|
// front of that request and throw away the data.
|
|
//
|
|
cur_seg = Context->CurrentOperation.LastSegmentRead;
|
|
|
|
while (skippedSegments && !ret) {
|
|
|
|
--skippedSegments;
|
|
|
|
if (Context->CurrentOperation.SegmentBytesRemaining =
|
|
q117GoodDataBytes(++cur_seg,Context)) {
|
|
|
|
ret = q117NewTrkRC(Context);
|
|
|
|
//
|
|
// Ignore Error correction failures on segments that
|
|
// we are skipping.
|
|
//
|
|
if (ERROR_DECODE(ret) == ERR_ECC_FAILED) {
|
|
ret = ERR_NO_ERR;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (!ret) {
|
|
|
|
#ifndef NO_MARKS
|
|
//
|
|
// Force the q117ReadTape code to not hit any file marks
|
|
//
|
|
Context->CurrentMark = Context->MarkArray.TotalMarks;
|
|
#endif
|
|
//
|
|
// Now, skip the number of bytes within the segment we skipped to
|
|
//
|
|
ret = q117ReadTape((PVOID)NULL,&bytesLeft,Context);
|
|
|
|
if ( ERROR_DECODE(ret) == ERR_ECC_FAILED ) {
|
|
ret = ERR_NO_ERR;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#ifndef NO_MARKS
|
|
|
|
//
|
|
// Find our current position in the mark array.
|
|
//
|
|
Context->CurrentMark = 0;
|
|
while (Context->CurrentOperation.BytesRead >
|
|
Context->MarkArray.MarkEntry[Context->CurrentMark].Offset
|
|
) {
|
|
|
|
++Context->CurrentMark;
|
|
|
|
}
|
|
#endif
|
|
|
|
*HowMany = 0;
|
|
|
|
return(ret);
|
|
}
|