📄 fhandler_tape.cc
字号:
{ ret = ERROR_INVALID_PARAMETER; if (buf && (ret = tape_get_pos (&block))) ((struct mtpos *) buf)->mt_blkno = block; } else return fhandler_dev_raw::ioctl (cmd, buf); if (ret != NO_ERROR) { SetLastError (ret); __seterrno (); return -1; } return 0;}/* ------------------------------------------------------------------ *//* Private functions used by `ioctl' *//* ------------------------------------------------------------------ */static inttape_error (DWORD lasterr, const char *txt){ if (lasterr) debug_printf ("%s: error: %d", txt, lasterr); return lasterr;}intfhandler_dev_tape::tape_write_marks (int marktype, DWORD len){ syscall_printf ("write_tapemark"); while (((lasterr = WriteTapemark (get_handle (), marktype, len, FALSE)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; return tape_error (lasterr, "tape_write_marks");}intfhandler_dev_tape::tape_get_pos (unsigned long *ret){ DWORD part, low, high; while (((lasterr = GetTapePosition (get_handle (), TAPE_ABSOLUTE_POSITION, &part, &low, &high)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; if (! tape_error (lasterr, "tape_get_pos") && ret) *ret = low; return lasterr;}static int _tape_set_pos (HANDLE hTape, int mode, long count){ int err; while (((err = SetTapePosition (hTape, mode, 1, count, count < 0 ? -1 : 0, FALSE)) == ERROR_MEDIA_CHANGED) || (err == ERROR_BUS_RESET)) ; return err;}intfhandler_dev_tape::tape_set_pos (int mode, long count, BOOLEAN sfm_func){ unsigned long pos, tgtpos; switch (mode) { case TAPE_SPACE_RELATIVE_BLOCKS: lasterr = tape_get_pos (&pos); if (lasterr) return lasterr; tgtpos = pos + count; while (((lasterr = _tape_set_pos (get_handle (), mode, count)) == ERROR_FILEMARK_DETECTED) || (lasterr == ERROR_SETMARK_DETECTED)) { lasterr = tape_get_pos (&pos); if (lasterr) return lasterr; count = tgtpos - pos; } if (lasterr == ERROR_BEGINNING_OF_MEDIA && ! tgtpos) lasterr = NO_ERROR; break; case TAPE_SPACE_FILEMARKS: if (count < 0) { if (pos > 0) { if ((! _tape_set_pos (get_handle (), TAPE_SPACE_RELATIVE_BLOCKS, -1)) || (sfm_func)) ++count; _tape_set_pos (get_handle (), TAPE_SPACE_RELATIVE_BLOCKS, 1); } while (! (lasterr = _tape_set_pos (get_handle (), mode, -1)) && count++ < 0) ; if (lasterr == ERROR_BEGINNING_OF_MEDIA) { if (! count) lasterr = NO_ERROR; } else if (! sfm_func) lasterr = _tape_set_pos (get_handle (), mode, 1); } else { if (sfm_func) { if (_tape_set_pos (get_handle (), TAPE_SPACE_RELATIVE_BLOCKS, 1) == ERROR_FILEMARK_DETECTED) ++count; _tape_set_pos (get_handle (), TAPE_SPACE_RELATIVE_BLOCKS, -1); } if (! (lasterr = _tape_set_pos (get_handle (), mode, count)) && sfm_func) lasterr = _tape_set_pos (get_handle (), mode, -1); } break; case TAPE_SPACE_SETMARKS: case TAPE_ABSOLUTE_BLOCK: case TAPE_SPACE_END_OF_DATA: case TAPE_REWIND: lasterr = _tape_set_pos (get_handle (), mode, count); break; } return tape_error (lasterr, "tape_set_pos");}intfhandler_dev_tape::tape_erase (int mode){ DWORD varlen; TAPE_GET_DRIVE_PARAMETERS dp; while (((lasterr = GetTapeParameters (get_handle (), GET_TAPE_DRIVE_INFORMATION, (varlen = sizeof dp, &varlen), &dp)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; switch (mode) { case TAPE_ERASE_SHORT: if (! lasterr && ! (dp.FeaturesLow & TAPE_DRIVE_ERASE_SHORT)) mode = TAPE_ERASE_LONG; break; case TAPE_ERASE_LONG: if (! lasterr && ! (dp.FeaturesLow & TAPE_DRIVE_ERASE_LONG)) mode = TAPE_ERASE_SHORT; break; } return tape_error (EraseTape (get_handle (), mode, FALSE), "tape_erase");}intfhandler_dev_tape::tape_prepare (int action){ while (((lasterr = PrepareTape (get_handle (), action, FALSE)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; return tape_error (lasterr, "tape_prepare");}BOOLEANfhandler_dev_tape::tape_get_feature (DWORD parm){ DWORD varlen; TAPE_GET_DRIVE_PARAMETERS dp; while (((lasterr = GetTapeParameters (get_handle (), GET_TAPE_DRIVE_INFORMATION, (varlen = sizeof dp, &varlen), &dp)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; if (lasterr) return FALSE; return ((parm & TAPE_DRIVE_HIGH_FEATURES) ? ((dp.FeaturesHigh & parm) != 0) : ((dp.FeaturesLow & parm) != 0));}intfhandler_dev_tape::tape_get_blocksize (long *min, long *def, long *max, long *cur){ DWORD varlen; TAPE_GET_DRIVE_PARAMETERS dp; TAPE_GET_MEDIA_PARAMETERS mp; while (((lasterr = GetTapeParameters (get_handle (), GET_TAPE_DRIVE_INFORMATION, (varlen = sizeof dp, &varlen), &dp)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; if (lasterr) return tape_error (lasterr, "tape_get_blocksize"); while (((lasterr = GetTapeParameters (get_handle (), GET_TAPE_MEDIA_INFORMATION, (varlen = sizeof dp, &varlen), &mp)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; if (lasterr) return tape_error (lasterr, "tape_get_blocksize"); if (min) *min = (long) dp.MinimumBlockSize; if (def) *def = (long) dp.DefaultBlockSize; if (max) *max = (long) dp.MaximumBlockSize; if (cur) *cur = (long) mp.BlockSize; return tape_error (lasterr, "tape_get_blocksize");}intfhandler_dev_tape::tape_set_blocksize (long count){ long min, max; TAPE_SET_MEDIA_PARAMETERS mp; lasterr = tape_get_blocksize (&min, NULL, &max, NULL); if (lasterr) return lasterr; if (count != 0 && (count < min || count > max)) return tape_error (ERROR_INVALID_PARAMETER, "tape_set_blocksize"); mp.BlockSize = count; return tape_error (SetTapeParameters (get_handle (), SET_TAPE_MEDIA_INFORMATION, &mp), "tape_set_blocksize");}static long longget_ll (PLARGE_INTEGER i){ long long l = 0; l = i->HighPart; l <<= 32; l |= i->LowPart; return l;}intfhandler_dev_tape::tape_status (struct mtget *get){ DWORD varlen; TAPE_GET_DRIVE_PARAMETERS dp; TAPE_GET_MEDIA_PARAMETERS mp; int notape = 0; if (! get) return ERROR_INVALID_PARAMETER; while (((lasterr = GetTapeParameters (get_handle (), GET_TAPE_DRIVE_INFORMATION, (varlen = sizeof dp, &varlen), &dp)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; /* Setting varlen to sizeof DP is by intention, actually! Never set it to sizeof MP which seems to be more correct but results in a ERROR_MORE_DATA error at least on W2K. */ if ((lasterr) || (lasterr = GetTapeParameters (get_handle (), GET_TAPE_MEDIA_INFORMATION, (varlen = sizeof dp, &varlen), &mp))) notape = 1; memset (get, 0, sizeof *get); get->mt_type = MT_ISUNKNOWN; if (! notape && (dp.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING)) { get->mt_remaining = get_ll (&mp.Remaining); get->mt_resid = get->mt_remaining >> 10; } if ((dp.FeaturesHigh & TAPE_DRIVE_SET_BLOCK_SIZE) && ! notape) get->mt_dsreg = mp.BlockSize; else get->mt_dsreg = dp.DefaultBlockSize; if (notape) get->mt_gstat |= GMT_DR_OPEN (-1); if (! notape) { if (dp.FeaturesLow & TAPE_DRIVE_GET_ABSOLUTE_BLK) tape_get_pos ((unsigned long *) &get->mt_blkno); if (! get->mt_blkno) get->mt_gstat |= GMT_BOT (-1); get->mt_gstat |= GMT_ONLINE (-1); if ((dp.FeaturesLow & TAPE_DRIVE_WRITE_PROTECT) && mp.WriteProtected) get->mt_gstat |= GMT_WR_PROT (-1); if (dp.FeaturesLow & TAPE_DRIVE_TAPE_CAPACITY) get->mt_capacity = get_ll (&mp.Capacity); } if ((dp.FeaturesLow & TAPE_DRIVE_COMPRESSION) && dp.Compression) get->mt_gstat |= GMT_HW_COMP (-1); if ((dp.FeaturesLow & TAPE_DRIVE_ECC) && dp.ECC) get->mt_gstat |= GMT_HW_ECC (-1); if ((dp.FeaturesLow & TAPE_DRIVE_PADDING) && dp.DataPadding) get->mt_gstat |= GMT_PADDING (-1); if ((dp.FeaturesLow & TAPE_DRIVE_REPORT_SMKS) && dp.ReportSetmarks) get->mt_gstat |= GMT_IM_REP_EN (-1); get->mt_erreg = lasterr; get->mt_minblksize = dp.MinimumBlockSize; get->mt_maxblksize = dp.MaximumBlockSize; get->mt_defblksize = dp.DefaultBlockSize; get->mt_featureslow = dp.FeaturesLow; get->mt_featureshigh = dp.FeaturesHigh; get->mt_eotwarningzonesize = dp.EOTWarningZoneSize; return 0;}intfhandler_dev_tape::tape_compression (long count){ DWORD varlen; TAPE_GET_DRIVE_PARAMETERS dpg; TAPE_SET_DRIVE_PARAMETERS dps; while (((lasterr = GetTapeParameters (get_handle (), GET_TAPE_DRIVE_INFORMATION, (varlen = sizeof dpg, &varlen), &dpg)) == ERROR_MEDIA_CHANGED) || (lasterr == ERROR_BUS_RESET)) ; if (lasterr) return tape_error (lasterr, "tape_compression"); if (! (dpg.FeaturesLow & TAPE_DRIVE_COMPRESSION)) return ERROR_INVALID_PARAMETER; if (count) { dps.ECC = dpg.ECC; dps.Compression = count ? TRUE : FALSE; dps.DataPadding = dpg.DataPadding; dps.ReportSetmarks = dpg.ReportSetmarks; dps.EOTWarningZoneSize = dpg.EOTWarningZoneSize; lasterr = SetTapeParameters (get_handle (), SET_TAPE_DRIVE_INFORMATION, &dps); if (lasterr) return tape_error (lasterr, "tape_compression"); dpg.Compression = dps.Compression; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -