⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mt.c

📁 MT: windows NT/2000/XP command line tape manipulation written to format a tape windows-XP backup r
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (C) 2001-2002 Peter Weston 
 * peter.weston@holistech.co.uk
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 see end of this file for the full GNU General Public License
 
 MT: windows NT/2000/XP command line tape manipulation
 written to format a tape windows-XP backup refused to write or format... and satisfy my curiosity
 Can be used for crude data recovery (combine seek and read)

 todo: nothing... worked for me.
 coulddo: lots if anyone's interested...
 		absolute position?
		set block size
		start read at n bytes...
		recover/retry errors (maybe reread damaged tape, pad unreadable block, seek over, etc.)
		gui
		write to tape
		fix long int nastyness
		change tape block size (read data from tape, 
		test with other hardware :-)
	 
  build with mingw (V3.2)... no makefile just a: gcc -o mt.exe mt.c
  
changelog:
v0.12		added eject as an alias for unload
v0.13   fixed broken seek number parsing
v0.14   error message tweaks
v0.15   fix for wrong block size during read (from Jason Bingham)
v0.16   add set block size and read variable block lengths
				
*/
#include <stdio.h>
#include <windows.h>

#define VER "v0.16beta"
#define MAX_ERROR_LINE_LENGTH 80
#define VARIABLE_BUFFER_LENGTH 131073  // 128K +1

enum {
	DO_ENDLIST,
	DO_LONGERASE,
	DO_REWIND,
	DO_DRIVESTATUS,
	DO_MEDIASTATUS,
	DO_FORMAT,
	DO_LOAD,
	DO_LOCK,
	DO_TENSION,
	DO_UNLOAD,
	DO_UNLOCK,
	DO_SHORTERASE,
	DO_USAGE,
	DO_PARTITION,
	DO_FIXEDPARTITION,
	DO_INITPARTITION,
	DO_SEEK,
	DO_READ,
	DO_LICENCE,
	DO_READPART,
	DO_BYTESEEK,
	DO_BLOCK,
} DO_ACTIONS;


typedef struct _PARRAY {
	char *txt;
	DWORD bit;
} PARRAY;

typedef struct _OPTARRAY {
	char *txt;
	DWORD bit;
	int params;
} OPTARRAY;


char licencetext[]={"
Copyright (C) 2001-2002 Peter Weston (peter.weston@holistech.co.uk)

this program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

this program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"};

char usagetext[]={"
Copyright (C) 2001-2002 Peter Weston (peter.weston@holistech.co.uk)
Usage: mt command <drive> <param1> <param2> ...
eg. mt erase tape0
Command, one of:
  block\t\t set block size to param1 bytes (eg. mt block 32K)
  drivestatus\t displays the status of the tape drive
  eject\t\t unload the tape
  format\t format the tape (QIC117 only)
  help\t\t display this usage information
  licence\t display licence information
  load\t\t load the tape
  lock\t\t lock the tape
  longerase\t long-erase the specified tape (blanks current partition)
  mediastatus\t display the status of the media
  partition\t (no parameters) create fixed (drive default) partitions
  partition\t (1 parameter) create param1 select partitions
  partition\t (2 parameters) create param1 partitions of size param2 (MB)
  read\t\t (1 parameter) read from tape into file param1
  read\t\t (2 parameters) read param 2 bytes from tape to file param1
  retension\t retension the tape
  rewind\t rewind the tape
  seek\t\t move tape to block param1
  seekbyte\t move tape to byte param1
  shorterase\t short-erase the tape (writes end of tape)
  unload\t unload the tape
  unlock\t unlock the tape

Drive:
  tape0\t\t (default)
  tape1 etc...

Most commands fail if the tape is busy, except mediastatus which waits for
the current operation to complete.

Large numbers can be made by suffixing K (1024), M (K*1024) or G (M*1024)
"};

OPTARRAY opts[]={
	"longerase",DO_LONGERASE,0,
	"rewind",DO_REWIND,0,
	"drivestatus", DO_DRIVESTATUS,0,
	"mediastatus", DO_MEDIASTATUS,0,
	"format", DO_FORMAT,0,
	"load", DO_LOAD,0,
	"lock", DO_LOCK,0,
	"tension", DO_TENSION,0,
	"unload", DO_UNLOAD,0,
	"eject", DO_UNLOAD,0,
	"unlock", DO_UNLOCK,0,
	"shorterase", DO_SHORTERASE,0,
	"help", DO_USAGE,0,
	"partition", DO_FIXEDPARTITION,0,
	"partition", DO_PARTITION,1,
	"partition", DO_INITPARTITION,2,
	"seek", DO_SEEK,1,
	"seekbyte", DO_BYTESEEK,1,
	"read", DO_READ,1,
	"licence",DO_LICENCE,0,
	"read", DO_READPART,2,
	"block", DO_BLOCK,1,
	"",DO_ENDLIST,0
};

PARRAY drivel[]={
	"Hardware compression", TAPE_DRIVE_COMPRESSION,
	"Report if cleaning required",TAPE_DRIVE_CLEAN_REQUESTS,
	"Hardware error correction (ECC)",TAPE_DRIVE_ECC,
	"Soft eject physically ejects",TAPE_DRIVE_EJECT_MEDIA,
	"Must erase from partition start",TAPE_DRIVE_ERASE_BOP_ONLY,
	"Long erase\t\t",TAPE_DRIVE_ERASE_BOP_ONLY,
	"Now erase (immediate erase)",TAPE_DRIVE_ERASE_IMMEDIATE,
	"Short erase\t\t",TAPE_DRIVE_ERASE_SHORT,
	"Creates fixed partitions",TAPE_DRIVE_FIXED,
	"Fixed length blocks\t",TAPE_DRIVE_FIXED_BLOCK,
	"Initiator defined partitions",TAPE_DRIVE_INITIATOR,
	"Data padding\t\t",TAPE_DRIVE_PADDING,
	"Provides absolute block number",TAPE_DRIVE_GET_ABSOLUTE_BLK,
	"Provides logical block number",TAPE_DRIVE_GET_LOGICAL_BLK,
	"Setmark reporting\t",TAPE_DRIVE_REPORT_SMKS,
	"Creates select data partitions",TAPE_DRIVE_SELECT,
	"Set end of medium warning size",TAPE_DRIVE_SET_EOT_WZ_SIZE,
	"Set compression only at partition start",TAPE_DRIVE_SET_CMP_BOP_ONLY,
	"Returns maximum capacity of tape",TAPE_DRIVE_TAPE_CAPACITY,
	"Returns remaining capacity of tape",TAPE_DRIVE_TAPE_REMAINING,
	"Variable length block mode\t",TAPE_DRIVE_VARIABLE_BLOCK,
	"Returns error if write protected",TAPE_DRIVE_WRITE_PROTECT,
	"",0
};

PARRAY driveh[]={
	"Immediate return on absolute seek",TAPE_DRIVE_ABS_BLK_IMMED,
	"Absolute seek\t\t\t",TAPE_DRIVE_ABSOLUTE_BLK,
	"Goto end of data\t\t",TAPE_DRIVE_END_OF_DATA,
	"Seek by filemark count\t\t",TAPE_DRIVE_FILEMARKS,
	"Load and unload\t\t\t",TAPE_DRIVE_LOAD_UNLOAD,
	"Immediate return on load and unload",TAPE_DRIVE_LOAD_UNLD_IMMED,
	"Lock tape in drive\t\t",TAPE_DRIVE_LOCK_UNLOCK,
	"Immediate return on lock and unlock",TAPE_DRIVE_LOCK_UNLK_IMMED,
	"Immediate return on logical block seek",TAPE_DRIVE_LOG_BLK_IMMED,
	"Logical block seek\t",TAPE_DRIVE_LOGICAL_BLK,
	"Relative seek\t\t",TAPE_DRIVE_RELATIVE_BLKS,
	"Backwards seek\t\t",TAPE_DRIVE_REVERSE_POSITION,
	"Immediate rewind\t",TAPE_DRIVE_REWIND_IMMEDIATE,
	"Seek to n consecutive filemarks",TAPE_DRIVE_SEQUENTIAL_FMKS,
	"Seek to n consecutive setmarks",TAPE_DRIVE_SEQUENTIAL_SMKS,
	"Set block size\t\t",TAPE_DRIVE_SET_BLOCK_SIZE,
	"Set hardware compression",TAPE_DRIVE_SET_COMPRESSION,
	"Set hardware error correction",TAPE_DRIVE_SET_ECC,
	"Set data padding\t",TAPE_DRIVE_SET_PADDING,
	"Setmark reporting\t",TAPE_DRIVE_SET_REPORT_SMKS,
	"Seek over n setmarks\t",TAPE_DRIVE_SETMARKS,
	"Immediate spacing\t",TAPE_DRIVE_SPACE_IMMEDIATE,
	"Tape tensioning\t\t",TAPE_DRIVE_TENSION,
	"Immediate tape tensioning",TAPE_DRIVE_TENSION_IMMED,
	"Write filemarks\t\t",TAPE_DRIVE_WRITE_FILEMARKS,
	"Write long filemarks\t",TAPE_DRIVE_WRITE_LONG_FMKS,
	"Immediate write filemarks",TAPE_DRIVE_WRITE_MARK_IMMED,
	"Write setmarks\t\t",TAPE_DRIVE_WRITE_SETMARKS,
	"Write short setmarks\t",TAPE_DRIVE_WRITE_SHORT_FMKS,
	"",0
};

void usage(void) {
  printf("\nMT: command-line tape manipulation similar to the unix mt command %s\n%s",VER,usagetext);
  exit(1);
}

void error(char* txt) {
	LPVOID buff;
	DWORD lasterr;
	
	lasterr = GetLastError();
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS + MAX_ERROR_LINE_LENGTH,
    NULL, lasterr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buff,0,NULL );
	if(buff!=NULL) {
		printf("%s While %s (%d)\n", (LPCTSTR)buff, txt ,lasterr);
		LocalFree(buff);
	} else {
		printf("unknown error %d while %s\n", lasterr, txt);
	}	
}

void printparam(char* txt, BOOLEAN yn) {
	printf("%s: %s\n",txt,(yn) ? "Yes" : "No");
}

void prnfeat(char* txt, DWORD result) {
	printf("%s\t: %s\n",txt,(result!=0) ? "Yes" : "No");
}

void hexdec(char *txt, DWORD val) {
	printf("%s: 0x%.8x (%u)\n",txt,val,val);
}

void hexdeclargeint(char *txt, LARGE_INTEGER val) {
	printf("%s: 0x%.8I64x (%I64u)\n",txt,val,val);
}

void printmediaparams(TAPE_GET_MEDIA_PARAMETERS mediaparams) {
	hexdeclargeint("Capacity (Bytes)\t",mediaparams.Capacity);
	hexdeclargeint("Remaining (Bytes)\t",mediaparams.Remaining);
	hexdec("Block Size\t\t",mediaparams.BlockSize);
	hexdec("Partition Count\t\t",mediaparams.PartitionCount);
	printparam("Write Protected\t\t",mediaparams.WriteProtected);
}

void printdriveparams(TAPE_GET_DRIVE_PARAMETERS driveparams) {
	int count;
	
	printparam("Hardware ECC\t\t",driveparams.ECC);
	printparam("Compression\t\t",driveparams.Compression);
	printparam("Data Padding\t\t",driveparams.DataPadding);
	printparam("Report Setmarks\t\t",driveparams.ReportSetmarks);
	hexdec("Default Block Size\t",driveparams.DefaultBlockSize);
	hexdec("Maximum Block Size\t",driveparams.MaximumBlockSize);
	hexdec("Minimum Block Size\t",driveparams.MinimumBlockSize);
	hexdec("Maximum Partitions\t",driveparams.MaximumPartitionCount);
	hexdec("EOT Warning Zone Size\t",driveparams.EOTWarningZoneSize);
	for(count=0;drivel[count].bit!=0;count++) {
		prnfeat(drivel[count].txt,drivel[count].bit & driveparams.FeaturesLow);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -