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

📄 ddcopy16.cpp

📁 ddcopy的硬盘拷贝源码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			// 读入数据块到 buf 中
			csize = fread (buf, 1, (size_t) size, FILES[0]);
			if (csize != size){
				// 数据异常
				free (buf);
				printf ("Data block read error! 1:(%ld %ld)\n", csize, size);
				return (-1);
			}

			// 对压缩数据进行解压处理,结果存入 buffer 中
			size = (unsigned short) lzss.UnCompress (buf, (unsigned long) csize, buffer);

			free (buf);
		} 
		else { // c == 0 无压缩
			// 读入数据块到 buf 中
			csize = fread (buffer, 1, (size_t) size, FILES[0]);
			if (csize != size){
				// 数据异常
				printf ("Data block read error! 2:(%ld %ld)\n", csize, size);
				return (-1);
			}
		}		

		// 计算数据块数目
		blks = size >> 9;
	} 
	
	return (blks);
}


short read_sour_disk (unsigned char * buffer)
{
	short rblks;
	static short step = BLOCKS;

	if (step > Blocks){
		step = Blocks;
	} else if (step < Blocks){
		step ++;
	}

	rblks = _diskop ((unsigned char) disks[0] + 0x7f, 0x42, buffer, starts[0], step);
	if (rblks < 0){
		// 出现读错误,则改变步长 /2
		step = 1;
		
		// 如果出现读错误,则只读入一个扇区
		rblks = _diskop ((unsigned char) disks[0] + 0x7f, 0x42, buffer, starts[0], 1);
		if (rblks < 0){
			// 如果读一个扇区错,则显示出错信息
			printf ("\nError reading source disk %d sector %ld! (ENO:%02X)\n", disks[0], starts[0], ErrorNum);
			if (show_confirm_msg ("Do you want to continue? (y/n/a)")){
				// 跳过坏扇区
				memset (buffer, 0xff, 512);
				rblks = 1;
			} else {
				return (-1);
			}
		}
	}

	starts[0] += rblks;
	return (rblks);
}


short copy_to_disks (short wblks, unsigned char * buffer)
{
	short i, j;
	short blks;

	for (i=1; disks[i]; i++){
		blks = _diskop ((unsigned char) disks[i] + 0x7f, 0x43, buffer, starts[i], wblks);
		if (blks < 0){
			// 出现写入错误,则逐一扇区写入
			for (j=0; j<wblks; j++){
				blks = _diskop ((unsigned char) disks[i] + 0x7f, 0x43, 
					buffer+(j<<9), starts[i]+j, 1);
				if (blks < 0){
					printf ("\nError writing destination disk %d sector %ld! (ENO:%02X)\n", disks[i], starts[i]+j, ErrorNum);
					if (show_confirm_msg ("Do you want to continue? (y/n/a)") == 0){
						return (-1);
					}
				}
			}
		}
		starts[i] += wblks;
	}
	
	return (wblks);
}


short run (void)
{
	unsigned char * buffer;
	unsigned char * buf;
	unsigned char * data;
	unsigned char c;
	short i;
	short blks;
	short cnt = 0;
	long pos;
	long secs;
	unsigned long copied = 0;
	unsigned long size, csize;
	time_t first, second;

	buffer = (unsigned char *) malloc ((Blocks+10) << 9);
	buf    = (unsigned char *) malloc ((Blocks+10) << 9);
	if (buffer == NULL || buf == NULL){
		perror ("Buffer");
		return (-5);
	}

	first = time(NULL);

	// 读入数据源
	for (; (blks = read_sour (buffer)) > 0; ){
		copied += blks;

		if (copied > sectors[0]){
			blks = sectors[0] - (copied - blks);
			copied = sectors [0];
		}

		size = ((unsigned long)blks) << 9;

if (cnt++ == 50){
	cnt = 0;
} else if (cnt == 2){
	second = time(NULL);
	secs = second - first;
	if (secs == 0) secs = 1;
	printf ("\rFinished:%ld/%ld MB. Time:%ld/%ld min. Speed:%ld MB/min  \b\b",
		copied>>11, sectors[0]>>11,
		secs/60L, sectors[0]/60L*secs/copied, (copied>>11)*60L/secs);
}

if (kbhit ()){
	if (getch () == 0x1b){
		short confirm = conf.confirm;
		conf.confirm = 1;
		if (show_confirm_msg("\nAre you sure to exit? (y/n)")){
			break;
		}
		conf.confirm = confirm;
	}
}

		// 写入目标磁盘
		if (disks[1]){
			if (copy_to_disks (blks, buffer) < 0){
				return (-1);
			}
		}

		if (conf.compress && FILES[1]){
			// 目标文件压缩模式,并且指定了目标文件

			// 压缩源数据
			csize = lzss.Compress (buffer, size, buf);

			if (csize < size - 3){
				// 压缩结果可用
				c = 1;
				data = buf;
			} else {
				// 压缩结果不可用
				c = 0;
				csize = size;
				data = buffer;
			}
		} else { 
			// 非压缩模式
			c = 0;
			csize = size;
			data = buffer;
		}

		// 写入目标文件
		for (i=1; FILES[i]; i++){

			// 写入数据块压缩标志
			fputc (c, FILES[i]);
			
			// 写入数据块长度
			fwrite (&csize, 2, 1, FILES[i]);

			// 写入数据
			if (fwrite ((char *) data, (size_t) csize, 1, FILES[i]) < 1){
				printf ("Error writing image file %s!\n", imgfiles[i]);
				return (-1);
			}

			if (conf.imgsize){
				// 分卷模式
				pos = ftell (FILES[i]);
				if (pos == -1){
					perror (imgfiles[i]);
					return (-1);
					
				} else if ((pos >> 20) >= conf.imgsize){
					// 容量超出,进行分卷操作

					// 写入下一分卷序号
					fputc (nextvolume[i]+2, FILES[i]);
					fclose (FILES[i]);

					// 形成下一分卷文件名
					sprintf (imgfiles[i]+strlen(imgfiles[i])-2, "%02d", nextvolume[i]+1);
					nextvolume[i] ++;

					printf ("\nCreate next volume: %s\n", imgfiles[i]);

					// 打开下一分卷
					if (NULL == (FILES[i] = fopen (imgfiles[i], "wb"))){
						perror (imgfiles[i]);
						return (-1);
					}
				}
			}
		}

		// 如果实际读入小于计划读入的块数,则结束拷贝
		if (copied == sectors [0]){
			printf ("\nCopy over\n");
			break;
		}
	}

	// 写入结束标志 0xaa
	if (copied == sectors [0]){
		for (i=1; FILES[i]; i++){
			fputc (0xaa, FILES[i]);
			fclose (FILES[i]);
		}
	}

	free (buffer);
	free (buf);
	return (0);
}


short init_run (void)
{
	short i, j;
	short overwrite = 1;
	char imgmode;
	char header [32] = {' '};

	// 如果源是文件,则设置为从文件读,否则设置为从磁盘读
	read_sour = imgfiles[0] ? read_sour_file : read_sour_disk;

	if (imgfiles[0]){
		// 打开源文件
		if (NULL == (FILES[0] = fopen (imgfiles[0], "rb"))){
			perror (imgfiles[0]);
			return (-1);
		}
		// 读入文件头信息
		fread (header, 32, 1, FILES[0]);
		
		// 从文件头读入映像文件包含的扇区数、数据块的大小、映像文件模式(磁盘拷贝、分区拷贝)
		sscanf (header, "%s %s %8lx%2x%2x", title, ver, &sectors[0], &Blocks, &imgmode);

		// 判断源文件数据模式与当前设置的拷贝模式是否相同, 即:是否都为"磁盘模式"或都为"分区模式"
		if (imgmode != conf.diskmode){
			printf ("The image file format is %s mode!\n", imgmode?"disk":"partition");
			return (-1);
		}
		
	} else if (conf.diskmode == 1) {
		// 设置源磁盘数据
		if (get_disk_info (disks[0], &starts[0], &sectors[0])){
			printf ("Error read source disk (%d) parameters!\n", disks[0]);
			return (-1);
		}
		
	} else if (conf.diskmode == 0) {
		// 设置源磁盘分区数据
		if (get_disk_part_info (disks[0], parts[0], &starts[0], &sectors[0])){
			printf ("Error read source disk (%d) partition (%d) parameters!\n", disks[0], parts[0]);
			return (-1);
		}
		
	} else {
		printf ("Bad source disk mode info\n");
		return (-1);
	}
	
	// 如果在命令行指定了拷贝的扇区数,则设置拷贝扇区数为源扇区与指定扇区数中最少的一个
	if (conf.copysectors) {
		sectors[0] = sectors[0] > conf.copysectors ? conf.copysectors : sectors[0];
	}

	// 打开目标文件
	for (i=1, j=1; imgfiles[i]; i++){
		// 判断目标文件是否与源文件相同
		if (strcmp (imgfiles[0], imgfiles[i]) == 0){
			printf ("The destination file and the source file are the same!\n", imgfiles[0]);
			return (-1);
		}
		
		// 判断目标文件是否存在
		if (file_exists (imgfiles[i])){
			printf ("The file \"%s\" already exist.", imgfiles[i]);
			overwrite = show_confirm_msg ("\nDo you want to overwrite the file? (y/n)");
		}

		if (overwrite){
			FILES[j] = fopen (imgfiles[i], "wb");
			if (NULL == FILES[j]){
				perror (imgfiles[i]);
				return (-1);
			}
			// 写入文件头信息
			sprintf (header, "%s %s %08lx%02x%02x", title, ver, sectors[0], Blocks, conf.diskmode);
			fwrite (header, 32, 1, FILES[j]);
			j++;
		}
	}

	// 设置目标磁盘数据
	for (i=1; disks[i]; i++){
		if (conf.diskmode == 1){
			if (disks[i] == disks[0]){
				// 源盘与目标盘为同一硬盘
				printf ("The source disk and the destination disk are the same!\n");
				return (-1);
			}
			// 读取硬盘参数
			if (get_disk_info (disks[i], &starts[i], &sectors[i])){
				printf ("Error read destination disk (%d) parameters!\n", disks[i]);
				return (-1);
			}
			if (sectors[0] > sectors[i]){
				// 源容量大于目标盘容量
				printf ("The size of source disk is larger than destinatiton.\n");
				if (show_confirm_msg ("Do you want to use the smaller size?")){
					// 设置拷贝容量等于目标盘容量
					sectors[0] = sectors[i];
				} else {
					return (-1);
				}
			}
		}
		else if (conf.diskmode == 0){
			if (disks[i] == disks[0] && parts[i] == parts[0]){
				// 源盘分区与目标盘分区为同一分区
				printf ("The source partition and the destination partition are the same!\n");
				return (-1);
			}
			// 读取硬盘分区参数
			if (get_disk_part_info (disks[i], parts[i], &starts[i], &sectors[i])){
				printf ("Error read destination disk (%d) partition (%d) parameters!\n", disks[i], parts[i]);
				return (-1);
			}
			if (sectors[0] > sectors[i]){
				// 源盘分区容量大于目标盘分区容量
				printf ("The size of source partition is larger than destinatiton.\n");
				if (show_confirm_msg ("Do you want to use the smaller size?")){
					// 设置拷贝容量等于目标盘容量
					sectors[0] = sectors[i];
				} else {
					return (-1);
				}
			}
		} else {
			printf ("Bad dest disk mode!(%d)\n", conf.diskmode);
			return (-4);
		}
	}

	// 没有指明目标
	if (disks[1] == 0 && FILES[1] == NULL){
		printf ("There is no destination specified!\n");
		return (-1);
	}

	return (0);
}


void main (short argc, unsigned char * argv [])
{
	char cmd_line [CMDBUFF] = "ddcopy ";
	short pos = 7;
	short i;
	char * dl = cmd_line;

	print_program_help (PR_LOGO);

	for (i=1; i<argc; i++){
		pos += sprintf (&cmd_line[pos], "%s ", argv[i]);
	}

	if (argc > 1){
		read_args (dl);
	} else {
		conf.printhelp = PR_CMDLINE|PR_OPTIONS|PR_INFO;
	}

	if (conf.defaultmode){
		for (i=0; ;i++){
			disks [i] = i+1;
			if (get_disk_info (disks[i], &starts[i], &sectors[i])){
				break;
			}
		}
	}

	if (conf.printhelp){
		// 显示帮助信息
		print_program_help (conf.printhelp);
		
	} else if (conf.showinfo){
		// 显示硬盘信息
		show_disks_info ();
		
	} else {
		// 初始化
		if (init_run()){
			// 初始化错
			printf ("Program initiated failed!\n");
		} else {
			// 开始拷贝
			show_data ();
			
			if (disks[1]){
				printf ("WARNING: All data on destination disk will be overwrite!\n");
				if (show_confirm_msg ("Do you want to continue? (y/n)")){
					run ();
				}
			} else {
 				run ();
			}
		}
	}

	exit (0);
}

⌨️ 快捷键说明

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