private void CheckError(UInt32 code) { switch (code) { case 1102: // ERROR_BEGINNING_OF_MEDIA beginningMediaDetected = true; break; case 1100: // ERROR_END_OF_MEDIA endMediaDetected = true; break; case 1103: // ERROR_SETMARK_DETECTED setMarkDetected = true; break; case 1101: // ERROR_FILEMARK_DETECTED fileMarkDetected = true; break; case 1104: // ERROR_NO_DATA_DETECTED endOfDataDetected = true; break; case 19: // ERROR_WRITE_PROTECT throw(new WriteProtectedException()); default: TapeDriveFunctions.CheckGeneralError(code); break; } }
////////////////////////////////////////////// /// <summary> /// Constructs a tape drive with the given integer ID. /// All tape drives under windows have an ID, starting at 0. /// </summary> /// <param name="tapeID">ID of tape</param> public TapeDrive(int tapeID) { // check OS version first if (Environment.OSVersion.Platform != PlatformID.Win32NT) { throw(new PlatformNotSupportedException("Tape drive access requires WindowsNT 4 or higher")); } tapeHandle = TapeDriveFunctions.CreateFile(@"\\.\TAPE" + tapeID, 0x80000000 | 0x40000000, // (GENERIC_READ | GENERIC_WRITE) read/write access 0, // not used null, // not used 3, // (OPEN_EXISTING) required for tape devices 0, // not used 0); // not used if (tapeHandle == 0) { throw(new TapeDriveNotFoundException()); } info = TapeDriveFunctions.GetTapeDriveParameters(this); setInfo.Compression = info.Compression; setInfo.DataPadding = info.DataPadding; setInfo.ECC = info.ECC; setInfo.EOTWarningZoneSize = info.EOTWarningZoneSize; setInfo.ReportSetmarks = info.ReportSetmarks; tapeStream = new TapeStream(this); }
/// <summary> /// Seeks to a specified position within the stream /// </summary> /// <param name="offset">offset from SeekOrigin to seek to</param> /// <param name="seekTo">where seeking should begin</param> /// <returns>new stream position</returns> public override long Seek(long offset, SeekOrigin seekTo) { long position = 0; switch (seekTo) { case SeekOrigin.Begin: position = offset; break; case SeekOrigin.Current: position = Position + offset; break; case SeekOrigin.End: position = Length + offset; break; } UInt32 lowBits, highBits; lowBits = (UInt32)position; highBits = (UInt32)(position >> 32); CheckError(TapeDriveFunctions.SetTapePosition(tapeDrive.Handle, 0, 0, lowBits, highBits, false)); return(position); }
/// <summary> /// Writes data to the tapedrive /// </summary> /// <param name="buffer">byte buffer to copy from</param> /// <param name="offset">integer offset within buffer to start copying data from</param> /// <param name="count">number of bytes to copy</param> public override void Write(byte[] buffer, int offset, int count) { UInt32 bytesWritten; byte[] buffer2 = new byte[count]; Array.Copy(buffer, offset, buffer2, 0, count); TapeDriveFunctions.WriteFile(tapeDrive.Handle, buffer2, (UInt32)count, out bytesWritten, null); }
/// <summary> /// Closes connection to the tape drive /// </summary> public void Close() { if (tapeHandle != 0) { if (Loaded) { UnLoad(); } TapeDriveFunctions.CloseHandle(tapeHandle); tapeHandle = 0; } }
/// <summary> /// Reads data from the tapedrive /// </summary> /// <param name="buffer">byte buffer to copy into</param> /// <param name="offset">integer offset within buffer to start copying data to</param> /// <param name="count">number of bytes to copy</param> /// <returns>number of bytes read</returns> public override int Read(byte[] buffer, int offset, int count) { UInt32 bytesRead; byte[] buffer2 = new byte[count]; TapeDriveFunctions.ReadFile(tapeDrive.Handle, buffer2, (UInt32)count, out bytesRead, null); Array.Copy(buffer2, 0, buffer, offset, (int)bytesRead); return((int)bytesRead); }
private void CheckError(UInt32 code) { switch (code) { case 1105: // ERROR_PARTITION_FAILURE throw(new TapeDriveException("Format failed: Tape could not be partitioned")); case 1108: // ERROR_UNABLE_TO_LOCK_MEDIA throw(new LockFailedException()); case 1109: // ERROR_UNABLE_TO_UNLOAD_MEDIA break; default: TapeDriveFunctions.CheckGeneralError(code); break; } }
/// <summary> /// Used by all Format() functions to call CreateTapePartition() /// </summary> /// <param name="option">Win32 option to send</param> /// <param name="count"></param> /// <param name="size"></param> private void FormatHelper(FormatOption option, UInt32 count, UInt32 size) { CheckError(TapeDriveFunctions.CreateTapePartition(tapeHandle, (UInt32)option, count, size)); }
/// <summary> /// Called by all functions that require PrepareTape() /// </summary> /// <param name="option">PrepareType option</param> /// <param name="immediate">If true, return immediately. /// If false, return after operation has finished</param> private void Prepare(PrepareOption option, bool immediate) { CheckError(TapeDriveFunctions.PrepareTape(tapeHandle, (UInt32)option, immediate)); }
/// <summary> /// Writes an end of data mark at the current position /// </summary> public void WriteEndOfDataMark() { CheckError(TapeDriveFunctions.EraseTape(tapeDrive.Handle, 0, false)); }
/// <summary> /// Writes the specified number of set marks to the current position /// </summary> /// <param name="count">Number of set marks to write</param> public void WriteSetMark(uint count) { CheckError(TapeDriveFunctions.WriteTapemark(tapeDrive.Handle, 0, count, false)); }
/// <summary> /// Erases the tape from the current position to the end of partition. /// </summary> public void Erase() { CheckError(TapeDriveFunctions.EraseTape(tapeDrive.Handle, 1, false)); }
/// <summary> /// Flushes buffers to the drive /// </summary> public override void Flush() { TapeDriveFunctions.FlushFileBuffers(tapeDrive.Handle); }