Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

288 lines
5.0 KiB

/*++
Copyright (c) 1993 - Colorado Memory Systems, Inc.
All Rights Reserved
Module Name:
erase.c
Abstract:
Does a read pass over the entire tape to create the bad block map and
writes the bad block map to the tape and zeros the tape directory.
Revision History:
--*/
//
// include files
//
#include <ntddk.h>
#include <ntddtape.h>
#include "common.h"
#include "q117.h"
#include "protos.h"
#define FCT_ID 0x0106
dStatus
q117VerifyFormat(
IN OUT PQ117_CONTEXT Context
)
/*++
Routine Description:
Arguments:
Context -
Return Value:
--*/
{
dStatus status;
Context->CurrentTape.CurBadListIndex = 0;
status = q117FillTapeBlocks(
CMD_READ_VERIFY,
0,
Context->CurrentTape.LastSegment,
NULL,
0,
0,
NULL,
Context);
Context->CurrentTape.CurBadListIndex = 0;
return status;
}
dStatus
q117EraseQ (
IN OUT PQ117_CONTEXT Context
)
/*++
Routine Description:
Writes the bad sector map already in memory (put there either by a
call to Init() or Erase()) to the tape and stomps on each entry
in the tape directory.
Arguments:
Context -
Return Value:
--*/
{
dStatus ret; // Return value from other routines called.
LONG i; // generic loop index
PVOLUME_TABLE_ENTRY scrbuf;
PSEGMENT_BUFFER bufferInfo;
PIO_REQUEST ioreq;
if (!q117QueueEmpty(Context)) {
return ERROR_ENCODE(ERR_PROGRAM_FAILURE, FCT_ID, 1);
}
q117ClearVolume(Context);
scrbuf = (PVOLUME_TABLE_ENTRY)q117GetFreeBuffer(&bufferInfo,Context);
if (ret = q117IssIOReq(
scrbuf,
CMD_READ,
(LONG)Context->CurrentTape.VolumeSegment * BLOCKS_PER_SEGMENT,
bufferInfo,
Context)) {
return(ret);
}
ioreq = q117Dequeue(WaitForItem,Context);
ret = ioreq->x.adi_hdr.status;
if (ERROR_DECODE(ret) == ERR_BAD_BLOCK_DETECTED || ret == ERR_NO_ERR) {
//
// correct data segment with Reed-Solomon and Heroic retries
//
ret = q117ReconstructSegment(ioreq,Context);
}
if (ret) {
return ret;
}
//
// stomp on the signatures only
//
for (i = 0;
i < ( ( DATA_BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR ) /
sizeof(VOLUME_TABLE_ENTRY));
i++) {
RtlZeroMemory(&scrbuf[i].Signature, sizeof(scrbuf->Signature));
}
//
// now write it out again!
//
if (ret = q117IssIOReq(
scrbuf,
CMD_WRITE,
(LONG)Context->CurrentTape.VolumeSegment * BLOCKS_PER_SEGMENT,
bufferInfo,
Context)) {
return(ret);
}
ret = q117Dequeue(WaitForItem,Context)->x.adi_hdr.status;
q117ClearVolume(Context);
q117SetTpSt(Context);
return(ret);
}
dStatus
q117EraseS (
IN OUT PQ117_CONTEXT Context
)
/*++
Routine Description:
Init() must be called before calling this routine. Reads the tape
directory to find the ending block of the last backup on the tape
and writes 0's to every sector from the end of the tape directory
up to and including the ending block of the last backup, and then 0's
the tape directory and rewrites the bad sector map by calling
EraseQ().
Arguments:
Context -
Return Value:
--*/
{
dStatus ret; // Return value from other routines called.
PVOID scrbuf;
PSEGMENT_BUFFER bufferInfo;
scrbuf = q117GetFreeBuffer(&bufferInfo, Context);
RtlZeroMemory(scrbuf, BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR);
ret = q117FillTapeBlocks(
CMD_WRITE,
Context->CurrentTape.VolumeSegment,
Context->CurrentTape.LastSegment,
scrbuf,
0,
0,
bufferInfo,
Context);
Context->CurrentOperation.EndOfUsedTape =
Context->CurrentTape.LastUsedSegment =
Context->CurrentTape.VolumeSegment;
q117ClearVolume(Context);
q117SetTpSt(Context);
return(ret);
}
VOID
q117ClearVolume (
IN OUT PQ117_CONTEXT Context
)
/*++
Routine Description:
Clear state information for any active volume.
Arguments:
Context -
Return Value:
--*/
{
#ifndef NO_MARKS
// Clear the mark array
Context->MarkArray.TotalMarks = 0;
Context->CurrentMark = Context->MarkArray.TotalMarks;
Context->MarkArray.MarkEntry[Context->CurrentMark].Offset = 0xffffffff;
#endif
Context->CurrentOperation.Position = TAPE_REWIND;
//
// Destroy the active volume
//
RtlZeroMemory(&Context->ActiveVolume,sizeof(Context->ActiveVolume));
Context->ActiveVolumeNumber = 0;
//
// Set tape to all available
//
Context->CurrentOperation.EndOfUsedTape =
Context->CurrentTape.LastUsedSegment =
Context->CurrentTape.VolumeSegment;
}