Exemplo n.º 1
0
BOOL TapeErase( BOOL Erase_Type     // I - Short or long erase.
               )
{
   if( SupportedFeature( TAPE_DRIVE_ERASE_BOP_ONLY ) )

      RewindTape( ) ;

   if( Erase_Type )

      printf( "Erase tape (Long).\n" ) ;

   else printf( "Erase tape (Short).\n" ) ;

   if( EraseTape( gb_Tape_Handle,
                  (Erase_Type) ? TAPE_ERASE_LONG : TAPE_ERASE_SHORT ,
                  0
                ) ) {

      DisplayDriverError( GetLastError( ) ) ;
      return TEST_ERROR ;
   }

   else { RewindTape( ) ;
          return SUCCESS ;
   }
}
Exemplo n.º 2
0
static
int w32_internal_mtop ( HANDLE hFile, U32* pStat, struct mtop* mtop, ifd_t ifd )
{
    int rc = 0;

    ASSERT( pStat && mtop );    // (sanity check)

    // General technique: do the i/o, save results, update the
    // device status (based on the results), then check results...

    switch ( mtop->mt_op )
    {
    case MTLOAD:    // (load media)
    {
        if ( 1 != mtop->mt_count )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            do
            {
                errno = PrepareTape( hFile, TAPE_LOAD, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTUNLOAD:  // (unload media)
    case MTOFFL:    // (make media offline (same as unload))
    {
        if ( 1 != mtop->mt_count )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            do
            {
                errno = PrepareTape( hFile, TAPE_UNLOAD, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTSEEK:    // (position media)
    {
        do
        {
            errno = SetTapePosition( hFile, TAPE_LOGICAL_BLOCK, 0, mtop->mt_count, 0, FALSE );
            errno = w32_internal_rc ( pStat );
        }
        while ( EINTR == errno );
    }
    break;

    case MTREW:     // (rewind)
    {
        if ( 1 != mtop->mt_count )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            do
            {
                errno = SetTapePosition( hFile, TAPE_REWIND, 0, 0, 0, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTFSF:     // (FORWARD  space FILE)
    case MTBSF:     // (BACKWARD space FILE)
    {
        if ( !mtop->mt_count )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            LARGE_INTEGER liCount;

            liCount.QuadPart = mtop->mt_count;

            if ( MTBSF == mtop->mt_op )
                liCount.QuadPart = -liCount.QuadPart; // (negative == backwards)

            do
            {
                errno = SetTapePosition( hFile, TAPE_SPACE_FILEMARKS, 0, liCount.LowPart, liCount.HighPart, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTFSR:     // (FORWARD  space BLOCK)
    case MTBSR:     // (BACKWARD space BLOCK)
    {
        if ( !mtop->mt_count )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            LARGE_INTEGER liCount;

            liCount.QuadPart = mtop->mt_count;

            if ( MTBSR == mtop->mt_op )
                liCount.QuadPart = -liCount.QuadPart; // (negative == backwards)

            do
            {
                errno = SetTapePosition( hFile, TAPE_SPACE_RELATIVE_BLOCKS, 0, liCount.LowPart, liCount.HighPart, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTSETBLK:  // (set blocksize)
    {
        TAPE_SET_MEDIA_PARAMETERS  media_parms;

        media_parms.BlockSize = mtop->mt_count;

        do
        {
            errno = SetTapeParameters( hFile, SET_TAPE_MEDIA_INFORMATION, &media_parms );
            errno = w32_internal_rc ( pStat );
        }
        while ( EINTR == errno );
    }
    break;

    case MTEOTWARN:   // (set EOT Warning Zone size in bytes)
    {
        TAPE_SET_DRIVE_PARAMETERS   set_drive_parms;

        set_drive_parms.ECC                = g_drive_parms[ifd].ECC;
        set_drive_parms.Compression        = g_drive_parms[ifd].Compression;
        set_drive_parms.DataPadding        = g_drive_parms[ifd].DataPadding;
        set_drive_parms.ReportSetmarks     = g_drive_parms[ifd].ReportSetmarks;
        set_drive_parms.EOTWarningZoneSize = mtop->mt_count;

        do
        {
            errno = SetTapeParameters( hFile, SET_TAPE_DRIVE_INFORMATION, &set_drive_parms );
            errno = w32_internal_rc ( pStat );
        }
        while ( EINTR == errno );
    }
    break;

    case MTWEOF:    // (write TAPEMARK)
    {
        if ( mtop->mt_count < 0 )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            // PROGRAMMING NOTE: We prefer "long" filemarks over any other type
            // because, according to the SDK documentaion:
            //
            //    "A short filemark contains a short erase gap that cannot be
            //     overwritten unless the write operation is performed from the
            //     beginning of the partition or from an earlier long filemark."
            //
            //    "A long filemark contains a long erase gap that allows an
            //     application to position the tape at the beginning of the filemark
            //     and to overwrite the filemark and the erase gap."
            //
            // Thus if TAPE_LONG_FILEMARKS is not supported we try ONLY the generic
            // TAPE_FILEMARKS variety and return an error if that fails; we do NOT
            // ever attempt the TAPE_SHORT_FILEMARKS or TAPE_SETMARKS variety.

            DWORD  dwTapemarkType = TAPE_LONG_FILEMARKS;

            if ( !( g_drive_parms[ifd].FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS ) )
                dwTapemarkType = TAPE_FILEMARKS;

            do
            {
                errno = WriteTapemark( hFile, dwTapemarkType, mtop->mt_count, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTERASE: // (write erase gap or erase entire tape (data security erase))
    {
        if (1
                && 0 != mtop->mt_count  // (0 == write erase gap at current position)
                && 1 != mtop->mt_count  // (1 == erases the remainder of entire tape)
           )
        {
            errno = EINVAL;
            rc = -1;
        }
        else
        {
            DWORD  dwEraseType  =
                mtop->mt_count ? TAPE_ERASE_LONG : TAPE_ERASE_SHORT;

            do
            {
                errno = EraseTape( hFile, dwEraseType, FALSE );
                errno = w32_internal_rc ( pStat );
            }
            while ( EINTR == errno );
        }
    }
    break;

    case MTNOP:         // (no operation)
    {
        errno = 0;
        rc = 0;
    }
    break;

    default:        // (invalid/unsupported tape operation)
    {
        errno = EINVAL;
        rc = -1;
    }
    break;
    }

    return (rc = (0 == errno || ENOSPC == errno) ? 0 : /* errno != 0 && errno != ENOSPC */ -1);
}
Exemplo n.º 3
0
int win32_tape_device::tape_op(struct mtop *mt_com)
{
   DWORD result = NO_ERROR;
   int   index;

   if (m_fd < 3 || m_fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) ||
       TapeHandleTable[m_fd - 3].OSHandle == INVALID_HANDLE_VALUE) {
      errno = EBADF;
      return -1;
   }

   PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[m_fd - 3];
   switch (mt_com->mt_op) {
   case MTRESET:
   case MTNOP:
   case MTSETDRVBUFFER:
      break;
   case MTRAS1:
   case MTRAS2:
   case MTRAS3:
   case MTSETDENSITY:
      errno = ENOTTY;
      result = (DWORD)-1;
      break;
   case MTFSF:
      for (index = 0; index < mt_com->mt_count; index++) {
         result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, 1, 0, FALSE);
         if (result == NO_ERROR) {
            pHandleInfo->ulFile++;
            pHandleInfo->bEOF = true;
            pHandleInfo->bEOT = false;
         }
      }
      break;
   case MTBSF:
      for (index = 0; index < mt_com->mt_count; index++) {
         result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, (DWORD)-1, ~0, FALSE);
         if (result == NO_ERROR) {
            pHandleInfo->ulFile--;
            pHandleInfo->bBlockValid = false;
            pHandleInfo->bEOD = false;
            pHandleInfo->bEOF = false;
            pHandleInfo->bEOT = false;
         }
      }
      break;
   case MTFSR:
      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_RELATIVE_BLOCKS, 0, mt_com->mt_count, 0, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOD = false;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
      } else if (result == ERROR_FILEMARK_DETECTED) {
         pHandleInfo->bEOF = true;
      }
      break;
   case MTBSR:
      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_RELATIVE_BLOCKS, 0, -mt_com->mt_count, ~0, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOD = false;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
      } else if (result == ERROR_FILEMARK_DETECTED) {
         pHandleInfo->ulFile--;
         pHandleInfo->bBlockValid = false;
         pHandleInfo->bEOD = false;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
      }
      break;
   case MTWEOF:
      result = WriteTapemark(pHandleInfo->OSHandle, TAPE_FILEMARKS, mt_com->mt_count, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOF = true;
         pHandleInfo->bEOT = false;
         pHandleInfo->ulFile += mt_com->mt_count;
         pHandleInfo->bBlockValid = true;
         pHandleInfo->ullFileStart = 0;
      }
      break;
   case MTREW:
      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_REWIND, 0, 0, 0, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOD = false;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
         pHandleInfo->ulFile = 0;
         pHandleInfo->bBlockValid = true;
         pHandleInfo->ullFileStart = 0;
      }
      break;
   case MTOFFL:
      result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOAD, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOD = false;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
         pHandleInfo->ulFile = 0;
         pHandleInfo->ullFileStart = 0;
      }
      break;
   case MTRETEN:
      result = PrepareTape(pHandleInfo->OSHandle, TAPE_TENSION, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOD = false;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
         pHandleInfo->ulFile = 0;
         pHandleInfo->bBlockValid = true;
         pHandleInfo->ullFileStart = 0;
      }
      break;
   case MTBSFM:
      for (index = 0; index < mt_com->mt_count; index++) {
         result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, (DWORD)-1, ~0, FALSE);
         if (result == NO_ERROR) {
            result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, 1, 0, FALSE);
            pHandleInfo->bEOD = false;
            pHandleInfo->bEOF = false;
            pHandleInfo->bEOT = false;
         }
      }
      break;
   case MTFSFM:
      for (index = 0; index < mt_com->mt_count; index++) {
         result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, mt_com->mt_count, 0, FALSE);
         if (result == NO_ERROR) {
            result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, (DWORD)-1, ~0, FALSE);
            pHandleInfo->bEOD = false;
            pHandleInfo->bEOF = false;
            pHandleInfo->bEOT = false;
         }
      }
      break;
   case MTEOM:
      while (1) {
         result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, 1, 0, FALSE);
         if (result != NO_ERROR) {
            pHandleInfo->bEOF = false;

            if (result == ERROR_END_OF_MEDIA) {
               pHandleInfo->bEOD = true;
               pHandleInfo->bEOT = true;
               return 0;
            }
            if (result == ERROR_NO_DATA_DETECTED) {
               pHandleInfo->bEOD = true;
               pHandleInfo->bEOT = false;
               return 0;
            }
            break;
         } else {
            pHandleInfo->bEOF = true;
            pHandleInfo->ulFile++;
         }
      }
      break;
   case MTERASE:
      result = EraseTape(pHandleInfo->OSHandle, TAPE_ERASE_LONG, FALSE);
      if (result == NO_ERROR) {
         pHandleInfo->bEOD = true;
         pHandleInfo->bEOF = false;
         pHandleInfo->bEOT = false;
         pHandleInfo->ulFile = 0;
         pHandleInfo->bBlockValid = true;
         pHandleInfo->ullFileStart = 0;
      }
      break;
   case MTSETBLK: {
      TAPE_SET_MEDIA_PARAMETERS SetMediaParameters;

      SetMediaParameters.BlockSize = mt_com->mt_count;
      result = SetTapeParameters(pHandleInfo->OSHandle, SET_TAPE_MEDIA_INFORMATION, &SetMediaParameters);
      break;
   }
   case MTSEEK: {
      TAPE_POSITION_INFO TapePositionInfo;

      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, 0, mt_com->mt_count, 0, FALSE);

      memset(&TapePositionInfo, 0, sizeof(TapePositionInfo));
      DWORD dwPosResult = GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo);
      if (dwPosResult == NO_ERROR && TapePositionInfo.FileSetValid) {
         pHandleInfo->ulFile = (ULONG)TapePositionInfo.FileNumber;
      } else {
         pHandleInfo->ulFile = ~0U;
      }
      break;
   }
   case MTTELL: {
      DWORD partition;
      DWORD offset;
      DWORD offsetHi;

      result = GetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, &partition, &offset, &offsetHi);
      if (result == NO_ERROR) {
         return offset;
      }
      break;
   }
   case MTFSS:
      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_SETMARKS, 0, mt_com->mt_count, 0, FALSE);
      break;
   case MTBSS:
      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_SETMARKS, 0, -mt_com->mt_count, ~0, FALSE);
      break;
   case MTWSM:
      result = WriteTapemark(pHandleInfo->OSHandle, TAPE_SETMARKS, mt_com->mt_count, FALSE);
      break;
   case MTLOCK:
      result = PrepareTape(pHandleInfo->OSHandle, TAPE_LOCK, FALSE);
      break;
   case MTUNLOCK:
      result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOCK, FALSE);
      break;
   case MTLOAD:
      result = PrepareTape(pHandleInfo->OSHandle, TAPE_LOAD, FALSE);
      break;
   case MTUNLOAD:
      result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOAD, FALSE);
      break;
   case MTCOMPRESSION: {
      TAPE_GET_DRIVE_PARAMETERS  GetDriveParameters;
      TAPE_SET_DRIVE_PARAMETERS  SetDriveParameters;
      DWORD                      size;

      size = sizeof(GetDriveParameters);

      result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &size, &GetDriveParameters);

      if (result == NO_ERROR) {
         SetDriveParameters.ECC = GetDriveParameters.ECC;
         SetDriveParameters.Compression = (BOOLEAN)mt_com->mt_count;
         SetDriveParameters.DataPadding = GetDriveParameters.DataPadding;
         SetDriveParameters.ReportSetmarks = GetDriveParameters.ReportSetmarks;
         SetDriveParameters.EOTWarningZoneSize = GetDriveParameters.EOTWarningZoneSize;

         result = SetTapeParameters(pHandleInfo->OSHandle, SET_TAPE_DRIVE_INFORMATION, &SetDriveParameters);
      }
      break;
   }
   case MTSETPART:
      result = SetTapePosition(pHandleInfo->OSHandle, TAPE_LOGICAL_BLOCK, mt_com->mt_count, 0, 0, FALSE);
      break;
   case MTMKPART:
      if (mt_com->mt_count == 0) {
         result = CreateTapePartition(pHandleInfo->OSHandle, TAPE_INITIATOR_PARTITIONS, 1, 0);
      } else {
         result = CreateTapePartition(pHandleInfo->OSHandle, TAPE_INITIATOR_PARTITIONS, 2, mt_com->mt_count);
      }
      break;
   default:
      errno = ENOTTY;
      result = (DWORD)-1;
      break;
   }

   if ((result == NO_ERROR && pHandleInfo->bEOF) ||
       (result == ERROR_FILEMARK_DETECTED && mt_com->mt_op == MTFSR)) {

      TAPE_POSITION_INFO TapePositionInfo;

      if (GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo) == NO_ERROR) {
         pHandleInfo->bBlockValid = true;
         pHandleInfo->ullFileStart = TapePositionInfo.BlockNumber;
      }
   }

   switch (result) {
   case NO_ERROR:
   case (DWORD)-1:   /* Error has already been translated into errno */
      break;
   case ERROR_FILEMARK_DETECTED:
      errno = EIO;
      break;
   case ERROR_END_OF_MEDIA:
      pHandleInfo->bEOT = true;
      errno = EIO;
      break;
   case ERROR_NO_DATA_DETECTED:
      pHandleInfo->bEOD = true;
      errno = EIO;
      break;
   case ERROR_NO_MEDIA_IN_DRIVE:
      pHandleInfo->bEOF = false;
      pHandleInfo->bEOT = false;
      pHandleInfo->bEOD = false;
      errno = ENOMEDIUM;
      break;
   case ERROR_INVALID_HANDLE:
   case ERROR_ACCESS_DENIED:
   case ERROR_LOCK_VIOLATION:
      errno = EBADF;
      break;
   default:
      errno = EIO;
      break;
   }

   return result == NO_ERROR ? 0 : -1;
}