Пример #1
0
BOOL GetTapeParms(
   DWORD *total_low,       // O - tape capacity lower 32 bits
   DWORD *total_high,      // O - tape capacity upper 32 bits
   DWORD *freespace_low,   // O - free space remaining lower 32 bits
   DWORD *freespace_high,  // O - free space remaining upper 32 bits
   DWORD *blk_size,        // O - block size
   DWORD *part,            // O - number of partitions
   BOOL  *write_protect    // O - write protect on/off
    )

{

   TAPE_GET_MEDIA_PARAMETERS parms ;
   DWORD status ;
   DWORD StructSize ;

   if( gb_Tape_Handle != NULL ) {

   sizeof( TAPE_GET_MEDIA_PARAMETERS ) ;

      status = GetTapeParameters( gb_Tape_Handle,
                                  GET_TAPE_MEDIA_INFORMATION,
                                  &StructSize,
                                  &parms ) ;
      // If call to GetTapeParameters is successful, copy data to return

      if( status == NO_ERROR ) {

         *total_low      = parms.Capacity.LowPart ;
         *total_high     = parms.Capacity.HighPart ;
         *freespace_low  = parms.Remaining.LowPart ;
         *freespace_high = parms.Remaining.HighPart ;
         *blk_size       = parms.BlockSize ;
         *part	         = parms.PartitionCount ;
         *write_protect  = parms.WriteProtected ;

      }

      else { DisplayDriverError( GetLastError( ) ) ;
                return TEST_ERROR ;
      }
   }

   return SUCCESS ;

}
Пример #2
0
DLL_EXPORT
ufd_t w32_open_tape ( const char* path, int oflag, ... )
{
    ifd_t       ifd;
    HANDLE      hFile;
    char        szTapeDeviceName[10];
    const char* pszTapeDevNum;
    DWORD       dwDesiredAccess, dwSizeofDriveParms, dwRetCode;

    // Reserve an fd number right away and bail if none available...
    if ( (ifd = w32_alloc_ifd()) < 0 )
        return -1;

    // If they specified a Windows device name,
    // use it as-is.

    if (1
            && strnfilenamecmp( path, "\\\\.\\", 4 ) == 0
            &&                  path            [4]  != 0
       )
    {
        strlcpy( szTapeDeviceName, path, sizeof(szTapeDeviceName) );
    }
    else // (not a Windows device name)
    {
        // The device name is a Cygwin/*nix device name.
        // Name must be either "/dev/nst0" or "/dev/st0"

        if (1
                &&  strnfilenamecmp( path, "/dev/", 5 ) == 0
                &&  (
                    strnfilenamecmp( (pszTapeDevNum=path+8)-3, "nst", 3 ) == 0
                    ||
                    strnfilenamecmp( (pszTapeDevNum=path+7)-2, "st",  2 ) == 0
                )
                &&  strlen(pszTapeDevNum) == 1
                &&  isdigit(*pszTapeDevNum)
           )
        {
            // Change it to a Windows device name (e.g. \\.\Tape0)

            strlcpy( szTapeDeviceName, WIN32_TAPE_DEVICE_NAME, sizeof(szTapeDeviceName) );
            szTapeDeviceName[8] = *pszTapeDevNum;
            szTapeDeviceName[9] = 0;

            // PROGRAMMING NOTE: the "rewind at close" option (implied by
            // virtue of the filename being "/dev/st0" and not "/dev/nst0")
            // was handled (detected/remembered) by the higher-level caller.
        }
        else
        {
            VERIFY( w32_free_ifd( ifd ) == 0 );
            errno = EINVAL;     // (bad device name)
            return -1;          // (open failure)
        }
    }

    // We only support O_BINARY with either O_RDWR or O_RDONLY

    if (1
            && (( O_BINARY | O_RDWR  ) != oflag)
            && (( O_BINARY | O_RDONLY) != oflag)
       )
    {
        VERIFY( w32_free_ifd( ifd ) == 0 );
        errno = EINVAL;     // (invalid open flags)
        return -1;          // (open failure)
    }

    // Set desired access

    dwDesiredAccess = GENERIC_READ;

    if ( oflag & O_RDWR )
        dwDesiredAccess |= GENERIC_WRITE;

    // Open the tape drive...

    hFile = CreateFile
            (
                szTapeDeviceName,   // filename
                dwDesiredAccess,    // desired access
                0,                  // share mode (0 == exclusive)
                NULL,               // security == default
                OPEN_EXISTING,      // "file" (device actually) must already exist
                0,                  // no special access flags needed
                NULL                // not using template
            );

    if ( INVALID_HANDLE_VALUE == hFile )
    {
        int save_errno = w32_trans_w32error( GetLastError() );
        VERIFY( w32_free_ifd( ifd ) == 0 );
        errno = save_errno;
        return -1;
    }

    // Save drive parameters for later...

    memset( &g_drive_parms[ifd], 0, sizeof(TAPE_GET_DRIVE_PARAMETERS) );
    dwSizeofDriveParms = sizeof(TAPE_GET_DRIVE_PARAMETERS);

    do
    {
        dwRetCode = GetTapeParameters
                    (
                        hFile,
                        GET_TAPE_DRIVE_INFORMATION,
                        &dwSizeofDriveParms,
                        &g_drive_parms[ifd]
                    );
    }
    while ((NO_ERROR != dwRetCode)              // (if not normal completion,
            &&                                          // check for retry conditions)
            (0
             || ERROR_MEDIA_CHANGED == dwRetCode     // (likely but unimportant; retry)
             || ERROR_BUS_RESET     == dwRetCode     // (unlikely but possible;  retry)
            ));

    // Did that work?

    if (NO_ERROR != dwRetCode)
    {
        int save_errno = w32_trans_w32error( GetLastError() );
        CloseHandle( hFile );
        VERIFY( w32_free_ifd( ifd ) == 0 );
        errno = save_errno;
        return -1;
    }

    ASSERT( NO_ERROR == dwRetCode );
    ASSERT( sizeof(TAPE_GET_DRIVE_PARAMETERS) == dwSizeofDriveParms );

    // Save control info & return their file descriptor...

    g_handles [ ifd ]  = hFile;                     // (WIN32 handle)
    g_fnames  [ ifd ]  = strdup( path );            // (for posterity)
    g_fstats  [ ifd ]  = GMT_ONLINE (0xFFFFFFFF);   // (initial status)
    g_BOTmsk  [ ifd ]  = 0xFFFFFFFF;                // (BOT block-id mask)
    g_BOTbot  [ ifd ]  = 0x00000000;                // (BOT block-id value)

    return W32STAPE_IFD2UFD( ifd );                 // (user fd result)
}
Пример #3
0
static
int w32_internal_mtget ( HANDLE hFile, U32* pStat, struct mtget* mtget, ifd_t ifd )
{
    TAPE_GET_MEDIA_PARAMETERS   media_parms;
    DWORD                       dwRetCode, dwSize, dwLogicalPosition;

    ASSERT( pStat && mtget );

    mtget->mt_resid   =   0;            // (unknown/unsupported)
    mtget->mt_erreg   =   0;            // (unknown/unsupported)
    mtget->mt_fileno  =  -1;            // (unknown/unsupported)
    mtget->mt_blkno   =  -1;            // (unknown as of yet; set further below)
    mtget->mt_type    =  MT_ISSCSI2;    // "Generic ANSI SCSI-2 tape unit"
    mtget->mt_gstat   =  -1;            // (purposely invalid; set correctly below)

    // Reset the mounted status; it will get set further below...

    *pStat &= ~GMT_DR_OPEN (0xFFFFFFFF);

    // Attempt to retrieve the status of the tape-drive...

    dwRetCode = w32_get_tape_status( hFile );

    // Windows returns 'ERROR_NOT_READY' if no tape is mounted
    // instead of the usual expected 'ERROR_NO_MEDIA_IN_DRIVE'

    if ( ERROR_NOT_READY == dwRetCode )
        dwRetCode = ERROR_NO_MEDIA_IN_DRIVE;

    // If there is not tape mounted OR a new tape was mounted,
    // then the following status bits are now unknown/obsolete

    if (0
            || ERROR_NO_MEDIA_IN_DRIVE == dwRetCode
            || ERROR_MEDIA_CHANGED     == dwRetCode
       )
    {
        // (these statuse are now obsolete)
        *pStat  &=  ~GMT_WR_PROT (0xFFFFFFFF);
        *pStat  &=  ~GMT_BOT     (0xFFFFFFFF);
        *pStat  &=  ~GMT_EOT     (0xFFFFFFFF);
        *pStat  &=  ~GMT_EOD     (0xFFFFFFFF);
        *pStat  &=  ~GMT_EOF     (0xFFFFFFFF);
        *pStat  &=  ~GMT_SM      (0xFFFFFFFF);
    }

    // There's no sense trying to get media parameters
    // unless there's some media loaded on the drive!

    if ( ERROR_NO_MEDIA_IN_DRIVE == dwRetCode )
    {
        *pStat |= GMT_DR_OPEN (0xFFFFFFFF);     // (no tape mounted in drive)
        mtget->mt_gstat = *pStat;               // (return current status)
        return 0;                               // (nothing more we can do)
    }

    // A tape appears to be mounted on the drive...
    // Retrieve the media parameters information...

    dwSize = sizeof(media_parms);
    memset( &media_parms, 0, dwSize );
    dwRetCode = GetTapeParameters( hFile, GET_TAPE_MEDIA_INFORMATION, &dwSize, &media_parms );
    ASSERT( sizeof(media_parms) == dwSize );

    if ( NO_ERROR == dwRetCode )
    {
        mtget->mt_dsreg = media_parms.BlockSize;

        if (media_parms.WriteProtected)
            *pStat |=  GMT_WR_PROT (0xFFFFFFFF);
        else
            *pStat &= ~GMT_WR_PROT (0xFFFFFFFF);
    }
    else
        mtget->mt_dsreg = 0;    // (unknown; variable blocks presumed)

    // Lastly, attempt to determine if we are at BOT (i.e. load-point)...

    if ( 0 != ( errno = w32_internal_mtpos( hFile, pStat, &dwLogicalPosition, NULL, ifd ) ) )
    {
        mtget->mt_gstat = *pStat;
        return -1;
    }

    mtget->mt_blkno = dwLogicalPosition;

    if ( ( dwLogicalPosition & g_BOTmsk[ ifd ] ) == g_BOTbot[ ifd ] )
        *pStat |=  GMT_BOT (0xFFFFFFFF);
    else
        *pStat &= ~GMT_BOT (0xFFFFFFFF);

    mtget->mt_gstat = *pStat;
    return 0;
}
Пример #4
0
int win32_tape_device::tape_get(struct mtget *mt_get)
{
   TAPE_POSITION_INFO pos_info;
   BOOL result;

   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];

   if (GetTapePositionInfo(pHandleInfo->OSHandle, &pos_info) != NO_ERROR) {
      return -1;
   }

   DWORD density = 0;
   DWORD blocksize = 0;

   result = GetDensityBlockSize(pHandleInfo->OSHandle, &density, &blocksize);

   if (result != NO_ERROR) {
      TAPE_GET_DRIVE_PARAMETERS drive_params;
      DWORD size;

      size = sizeof(drive_params);
      result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &size, &drive_params);
      if (result == NO_ERROR) {
         blocksize = drive_params.DefaultBlockSize;
      }
   }

   mt_get->mt_type = MT_ISSCSI2;

   /*
    * Partition #
    */
   mt_get->mt_resid = pos_info.PartitionBlockValid ? pos_info.Partition : (ULONG)-1;

   /*
    * Density / Block Size
    */
   mt_get->mt_dsreg = ((density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK) |
                      ((blocksize << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK);

   mt_get->mt_gstat = 0x00010000;  /* Immediate report mode.*/
   if (pHandleInfo->bEOF) {
      mt_get->mt_gstat |= 0x80000000;     /* GMT_EOF */
   }

   if (pos_info.PartitionBlockValid && pos_info.BlockNumber == 0) {
      mt_get->mt_gstat |= 0x40000000;     /* GMT_BOT */
   }

   if (pHandleInfo->bEOT) {
      mt_get->mt_gstat |= 0x20000000;     /* GMT_EOT */
   }

   if (pHandleInfo->bEOD) {
      mt_get->mt_gstat |= 0x08000000;     /* GMT_EOD */
   }

   TAPE_GET_MEDIA_PARAMETERS  media_params;
   DWORD size = sizeof(media_params);

   result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_MEDIA_INFORMATION, &size, &media_params);

   if (result == NO_ERROR && media_params.WriteProtected) {
      mt_get->mt_gstat |= 0x04000000;     /* GMT_WR_PROT */
   }

   result = GetTapeStatus(pHandleInfo->OSHandle);

   if (result != NO_ERROR) {
      if (result == ERROR_NO_MEDIA_IN_DRIVE) {
         mt_get->mt_gstat |= 0x00040000;  /* GMT_DR_OPEN */
      }
   } else {
      mt_get->mt_gstat |= 0x01000000;     /* GMT_ONLINE */
   }

   /*
    * Recovered Error Count
    */
   mt_get->mt_erreg = 0;

   /*
    * File Number
    */
   mt_get->mt_fileno = (__daddr_t)pHandleInfo->ulFile;

   /*
    * Block Number
    */
   mt_get->mt_blkno = (__daddr_t)(pHandleInfo->bBlockValid ? pos_info.BlockNumber - pHandleInfo->ullFileStart : (ULONGLONG)-1);

   return 0;
}
Пример #5
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;
}
Пример #6
0
int win32_tape_device::d_open(const char *pathname, int flags, int mode)
{
   HANDLE hDevice = INVALID_HANDLE_VALUE;
   char szDeviceName[256] = "\\\\.\\";
   int idxFile;
   DWORD dwResult;

   for (idxFile = 0; idxFile < (int)NUMBER_HANDLE_ENTRIES; idxFile++) {
      if (TapeHandleTable[idxFile].OSHandle == INVALID_HANDLE_VALUE) {
         break;
      }
   }

   if (idxFile >= (int)NUMBER_HANDLE_ENTRIES) {
      return EMFILE;
   }

   memset(&TapeHandleTable[idxFile], 0, sizeof(TapeHandleTable[idxFile]));
   if (!IsPathSeparator(pathname[0])) {
       bstrncpy(&szDeviceName[4], pathname, sizeof(szDeviceName) - 4);
   } else {
       bstrncpy(&szDeviceName[0], pathname, sizeof(szDeviceName));
   }

   hDevice = CreateFile(szDeviceName, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, NULL);

   if (hDevice != INVALID_HANDLE_VALUE) {
      PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[idxFile];

      memset(pHandleInfo, 0, sizeof(*pHandleInfo));

      pHandleInfo->OSHandle = hDevice;

      TAPE_GET_DRIVE_PARAMETERS TapeDriveParameters;
      DWORD dwSize = sizeof(TapeDriveParameters);

      dwResult = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &dwSize, &TapeDriveParameters);
      if (dwResult == NO_ERROR) {
         pHandleInfo->FeaturesLow = TapeDriveParameters.FeaturesLow;
         pHandleInfo->FeaturesHigh = TapeDriveParameters.FeaturesHigh;
      }

      TAPE_POSITION_INFO TapePositionInfo;

      dwResult = GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo);

      if (dwResult == NO_ERROR) {
         if (TapePositionInfo.AtPartitionStart || TapePositionInfo.AtPartitionEnd ||
             (TapePositionInfo.PartitionBlockValid && TapePositionInfo.BlockNumber == 0)) {
            pHandleInfo->ulFile = 0;
            pHandleInfo->bBlockValid = true;
            pHandleInfo->ullFileStart = 0;
         } else if (TapePositionInfo.FileSetValid) {
            pHandleInfo->ulFile = (ULONG)TapePositionInfo.FileNumber;
         }
      }
   } else {
      DWORD dwError = GetLastError();

      switch (dwError) {
      case ERROR_FILE_NOT_FOUND:
      case ERROR_PATH_NOT_FOUND:
         errno = ENOENT;
         break;
      case ERROR_TOO_MANY_OPEN_FILES:
         errno = EMFILE;
         break;
      case ERROR_ACCESS_DENIED:
      case ERROR_SHARING_VIOLATION:
      case ERROR_LOCK_VIOLATION:
      case ERROR_INVALID_NAME:
         errno = EACCES;
         break;
      case ERROR_FILE_EXISTS:
         errno = EEXIST;
         break;
      case ERROR_INVALID_PARAMETER:
         errno = EINVAL;
         break;
      default:
         errno = EACCES;
         break;
      }

      return(int) -1;
   }

   return (int)idxFile + 3;
}