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

📄 mt.c

📁 MT: windows NT/2000/XP command line tape manipulation written to format a tape windows-XP backup r
💻 C
📖 第 1 页 / 共 3 页
字号:
	}
	for(count=0;driveh[count].bit!=0;count++) {
		prnfeat(driveh[count].txt,driveh[count].bit & driveparams.FeaturesHigh);
	}
}

void closeh(HANDLE tapedrive) {
	if (CloseHandle(tapedrive)==FALSE) error("closing tape handle");
}

void errorclose(char *txt, HANDLE tapedrive) {
	error(txt);
	closeh(tapedrive);
	exit(1);
}

void preptape(HANDLE tapedrive, DWORD cmd, char *txt) {
	if (PrepareTape(tapedrive,cmd,FALSE)!=NO_ERROR) {
		errorclose(txt,tapedrive);
	} else {
		printf("%s completed OK\n", txt);
	}
}

void doerase(HANDLE tapedrive, DWORD cmd, char *txt) {
	if (EraseTape(tapedrive,cmd,TRUE)!=NO_ERROR) {
		errorclose(txt,tapedrive);
	} else {
		printf("%s completed OK\n",txt);
	}
}

DWORD64 GetNumber(char *txt) {
	unsigned char unit=0; // number of bits to shift result
	DWORD64 number=0;
	unsigned char c;
	for (c=0;(c<100) && (txt[c]!='\0');c++) {
		switch (txt[c]) {
			case 'k':
			case 'K':
				unit=10; // 1Kb in bits to shift
				break;
			case 'm':
			case 'M':
				unit=20;  // 1Mb in bits to shift
				break;
			case 'G':
			case 'g':
				unit=30; // 1Gb in bits to shift
				break;
		}
		if ((txt[c]<'0') || (txt[c]>'9')) txt[c]='\0';
	}
	sscanf(txt,"%I64d",&number);
	return number<<unit;
}

#define getdword(a) ((DWORD) (GetNumber(a) & 0xffffffff))  // tisk

DWORD getdeviceblocksize(HANDLE tapedrive) {
	TAPE_GET_DRIVE_PARAMETERS driveparams;
	DWORD junk;
	
	junk =sizeof(TAPE_GET_DRIVE_PARAMETERS);
	if (GetTapeParameters(tapedrive,GET_TAPE_DRIVE_INFORMATION,&junk,&driveparams)!=NO_ERROR) {
		errorclose("getting tape drive information (block size)",tapedrive);
	} else {  // warn about block size under 1KB or over 1Mb
		if ((driveparams.DefaultBlockSize<1024) || (driveparams.DefaultBlockSize>1048576)) {
			printf("Warning: Drive reports block size as %d bytes\n",driveparams.DefaultBlockSize);
		}
		return driveparams.DefaultBlockSize;
	}
}

DWORD getmediablocksize(HANDLE tapedrive) {
	TAPE_GET_MEDIA_PARAMETERS mediaparams;
	DWORD junk;
	junk =sizeof(TAPE_GET_MEDIA_PARAMETERS);
	if (GetTapeParameters(tapedrive,GET_TAPE_MEDIA_INFORMATION,&junk,&mediaparams)!=NO_ERROR) {
		errorclose("getting tape drive information (block size)",tapedrive);
	} else {
		return mediaparams.BlockSize;
	}
}

void setmediablocksize(HANDLE tapedrive, DWORD blocks) {
	TAPE_SET_MEDIA_PARAMETERS mediaparams;

	mediaparams.BlockSize = blocks;
	if (SetTapeParameters(tapedrive,SET_TAPE_MEDIA_INFORMATION,&mediaparams)!=NO_ERROR) {
		printf("Use drivestatus to check the block size (%u) is supported by the drive\n",blocks);
		errorclose("setting block size",tapedrive);
	}
}

void printtapeposition(HANDLE tapedrive) {
	DWORD part, posl, posh;
	DWORD64 bytePosition;
	if (GetTapePosition(tapedrive,TAPE_ABSOLUTE_POSITION,&part, &posl, &posh)!=NO_ERROR) {
		errorclose("getting tape position",tapedrive);
	} else {
		printf("Current Partition\t: %u\n",part);
		printf("Absolute Block Position\t: 0x%.8x 0x%.8x (%d %d)\n",posh, posl,posh, posl);
		bytePosition=(((DWORD64)posh<<32)+posl)*getdeviceblocksize(tapedrive);
		printf("Absolute Byte Position\t: 0x%.16I64x\n",bytePosition);
	}
	if (GetTapeStatus(tapedrive)!=NO_ERROR) {
		errorclose("getting tape status", tapedrive);
	} else {
		printf("Status\t\t\t: Ready\n");
	}
}

BOOL variableblocks(HANDLE tapedrive) {
	TAPE_GET_DRIVE_PARAMETERS driveparams;
	DWORD junk;
	junk =sizeof(TAPE_GET_DRIVE_PARAMETERS);
	if (GetTapeParameters(tapedrive,GET_TAPE_DRIVE_INFORMATION,&junk,&driveparams)!=NO_ERROR) {
		errorclose("getting drive information (variable block support)",tapedrive);
	} else {
		return (driveparams.FeaturesLow & TAPE_DRIVE_VARIABLE_BLOCK);
	}
}

void readtape(HANDLE tapedrive, char *filename, char *length) {
	LPVOID buff;
	HANDLE outf;
	DWORD bytesread;
	DWORD byteswritten;
	DWORD result;
	DWORD readbuffersize;
	DWORD64 toread;
	DWORD64 total=0;

	if (variableblocks(tapedrive)) {		// v0.16
		readbuffersize=VARIABLE_BUFFER_LENGTH;
		setmediablocksize(tapedrive,0);
	} else {
		readbuffersize=getmediablocksize(tapedrive);  // v0.15 media not device block size
	}
	if (length[0]=='\0') { 
		toread=-1;   // setting an unsigned to -1?
	} else {
		toread=GetNumber(length);
	}
	printtapeposition(tapedrive);
  buff=VirtualAlloc(NULL,readbuffersize,MEM_COMMIT,PAGE_READWRITE);
  if (buff==NULL) errorclose("allocating buffer",tapedrive);
	outf = CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	if (outf==INVALID_HANDLE_VALUE) errorclose("opening output file",tapedrive);
	result = ReadFile(tapedrive,buff,readbuffersize,&bytesread,NULL);
	while ((bytesread>0) && (result!=0) && ((toread==-1) || (total<toread)))  {
		total+=bytesread;
		printf("Bytes read: %I64d\r",total);
		if (WriteFile(outf,buff,bytesread,&byteswritten,NULL)==0) {
			closeh(outf);
			errorclose("writing file",tapedrive);
		}
		result = ReadFile(tapedrive,buff,readbuffersize,&bytesread,NULL);
	}
	closeh(outf);
	if (result==0) errorclose("reading tape",tapedrive);
	printf("Read %I64d bytes (rounded up to nearest %d byte block)\n",total,readbuffersize);
	printtapeposition(tapedrive);
}

int main(int argc, char **argv) {
	char filename[512]="//./";
	HANDLE tapedrive;
	TAPE_GET_DRIVE_PARAMETERS driveparams;
	TAPE_GET_MEDIA_PARAMETERS mediaparameters;
	DWORD junk;
	int command=DO_ENDLIST;
	DWORD64 position;
	int count;
	int p1;
	
	if (argc<2) usage();
	if ((argc>2) && (strncasecmp(argv[2],"tape",4)==0)) {
		strncat(filename,argv[2],500);
		p1=3;
	} else {
		strncat(filename,"tape0",200);
		p1=2;
	}
	
	for (count=0; opts[count].bit!=0; count++) {
		if ((strcasecmp(argv[1],opts[count].txt)==0) && (argc==p1+opts[count].params)) {
			command=opts[count].bit;
			break;
		}
	}
	if ((command==DO_ENDLIST) || (command==DO_USAGE))  usage();
	tapedrive=CreateFile(filename,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,0,NULL);
	if (tapedrive==INVALID_HANDLE_VALUE) {
		error("opening tape drive");
		exit(1);
	}
	switch(command) {
		case DO_LONGERASE:
			doerase(tapedrive,TAPE_ERASE_LONG,"long erase");
			break;
		case DO_SHORTERASE: 
			doerase(tapedrive,TAPE_ERASE_SHORT,"short erase");
			break;
		case DO_FORMAT:
			preptape(tapedrive,TAPE_FORMAT,"formatting. Try longerase for non QIC117 tape drives");
			break;
		case DO_LOAD:
			preptape(tapedrive,TAPE_LOAD,"loading");
			break;
		case DO_LOCK:
			preptape(tapedrive,TAPE_LOCK,"locking");
			break;
		case DO_TENSION:
			preptape(tapedrive,TAPE_TENSION,"retensioning");
			break;
		case DO_UNLOAD:
			preptape(tapedrive,TAPE_UNLOAD,"unloading");
			break;
		case DO_UNLOCK:
			preptape(tapedrive,TAPE_UNLOCK,"unlocking");
			break;
		case DO_FIXEDPARTITION:
			if (CreateTapePartition(tapedrive,TAPE_FIXED_PARTITIONS,0,0)!=NO_ERROR) {
				errorclose("fixed partitioning",tapedrive);
			} else {
				printf("Partitioned OK\n");
			}
			break;
		case DO_INITPARTITION:
			if (CreateTapePartition(tapedrive,TAPE_INITIATOR_PARTITIONS,getdword(argv[p1]),getdword(argv[p1+1]))!=NO_ERROR) {
				errorclose("initiator partitioning",tapedrive);
			} else {
				printf("Partitioned OK\n");
			}
			break;
		case DO_PARTITION:
			if (CreateTapePartition(tapedrive,TAPE_SELECT_PARTITIONS,getdword(argv[p1]),0)!=NO_ERROR) {
				errorclose("select partitioning",tapedrive);
			} else {
				printf("Partitioned OK\n");
			}
			break;
		case DO_REWIND: 
			if (SetTapePosition(tapedrive,TAPE_REWIND,0,0,0,TRUE)!=NO_ERROR) {
				errorclose("rewinding",tapedrive);
			} else {
				printtapeposition(tapedrive);
			}
			break;
		case DO_DRIVESTATUS:
			junk =sizeof(TAPE_GET_DRIVE_PARAMETERS);
			if (GetTapeParameters(tapedrive,GET_TAPE_DRIVE_INFORMATION,&junk,&driveparams)!=NO_ERROR) {
				errorclose("getting tape drive information",tapedrive);
			} else {
				printdriveparams(driveparams);
			}
			break;
		case DO_MEDIASTATUS:
			junk =sizeof(TAPE_GET_MEDIA_PARAMETERS);
			if (GetTapeParameters(tapedrive,GET_TAPE_MEDIA_INFORMATION,&junk,&mediaparameters)!=NO_ERROR) {
				errorclose("getting media information",tapedrive);
			} else {
				printmediaparams(mediaparameters);
				printtapeposition(tapedrive);
			}
			break;
		case DO_SEEK:
		case DO_BYTESEEK:
			position = GetNumber(argv[p1]);
			if (command==DO_BYTESEEK) position=position/getdeviceblocksize(tapedrive);
			if (SetTapePosition(tapedrive,TAPE_ABSOLUTE_BLOCK,0,(DWORD) (position & 0xffffffff),(DWORD) ((position>>32) & 0xffffffff),FALSE)!=NO_ERROR) {
				errorclose("setting position",tapedrive);
			} else {
				printtapeposition(tapedrive);
			}
			break;
		case DO_READ:
			readtape(tapedrive,argv[p1],"");
			break;
		case DO_LICENCE:
			printf("%s",licencetext);
			break;
		case DO_READPART:
			readtape(tapedrive,argv[p1],argv[p1+1]);
			break;
		case DO_BLOCK:
			setmediablocksize(tapedrive,GetNumber(argv[p1]));
			break;

⌨️ 快捷键说明

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