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

📄 ddcopy16.cpp

📁 ddcopy的硬盘拷贝源码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 * "cmd" must be Diskread(0x42) or Diskwrite(0x43)
 * @return >=0: 成功,读写的数据块数
 * @return -1: 失败
 */
short _diskop (unsigned char drv, unsigned char cmd,
		   unsigned char * buffer, unsigned long startlow, unsigned short copyblks)
{
	/* 磁盘存取数据包结构 */
	struct disk_address_packet {
		unsigned char size_of_packet;
		unsigned char reserved;
		unsigned short number_of_blocks_to_transfer;
		unsigned short transfer_buffer_offset;
		unsigned short transfer_buffer_segment;
		unsigned long starting_absolute_block_low;
		unsigned long starting_absolute_block_high;
	};
	struct disk_address_packet dap;
	unsigned char av;

	unsigned char * pt = (unsigned char *) &dap;

	dap.size_of_packet = sizeof (dap);
	dap.reserved = 0;
	dap.number_of_blocks_to_transfer = copyblks;
	dap.transfer_buffer_offset = FP_OFF(buffer);
	dap.transfer_buffer_segment = FP_SEG(buffer);
	dap.starting_absolute_block_low = startlow;
	dap.starting_absolute_block_high = 0;

	asm {
		push ds
		push si
		mov ah, cmd
		mov dl, drv
		lds  si, DWORD PTR pt
		int  13h
		pop si
		pop ds
		mov av, ah
		jc  error
	}
	return (dap.number_of_blocks_to_transfer);

  error:
  //	printf ("(%02X) ", av);
	ErrorNum = av;
	return (-1);
}


/**
 * 读取指定硬盘信息
 * @param drv 硬盘ID号: 80h, 81h, ...
 * @param df 硬盘信息结构指针
 * @return  0 成功
 * @return -1 失败
 */
short _get_disk_info (unsigned char drv, struct _diskinfo * df)
{
	unsigned char av;
	unsigned char * p = (unsigned char *) df;

	/* 数据块长度 */
	df->size_of_buffer = 0x1a;

	asm {
		push ds
		push si
		mov ah, 48h
		mov dl, drv
		lds  si, DWORD PTR p
		int  13h
		pop  si
		pop  ds
		mov av, ah
		jc   error
	}
	return (0);

error:
	return (-1);
}


/**
 * 读取指定硬盘信息
 * @param disk 硬盘序号: 1, 2, ...
 * @param start 硬盘开始扇区.
 * @param sector 硬盘扇区总数.
 * @return  0 成功;
 * @return -1 失败.
 */
short get_disk_info (short disk, unsigned long * start, unsigned long * sector)
{
	struct _diskinfo df;

	// 读指定的硬盘参数
	if (_get_disk_info (disk+0x7f, &df)){
		return (-1);
	}
	// 设置硬盘总扇区数
	sector[0] = df.total_number_of_sectors_low;

	// 设置起始扇区
	start[0] = 0L;

	return (0);
}


/**
 * 读取指定硬盘的指定分区信息
 * @param disk 硬盘序号: 1, 2, ...
 * @param part 分区序号.
 * @param start 分区的开始扇区.
 * @param sector 分区的扇区总数.
 * @return  0 成功;
 * @return -1 失败.
 */
short get_disk_part_info (short disk, short part, unsigned long * start, unsigned long * sector)
{
	unsigned char buffer [512];
	unsigned char partition_records[64];
	struct _partinfo {
		unsigned char boot_indicator;
		unsigned char partition_start_head;
		unsigned char partition_start_sector;
		unsigned char partition_start_track;
		unsigned char operating_system_indicator;
		unsigned char partition_end_head;
		unsigned char partition_end_sector;
		unsigned char partition_end_track;
		unsigned long sectors_preceding_partition;
		unsigned long length_of_partition_in_sectors;
	} * _partinfo = (struct _partinfo *) partition_records;

	// 读入硬盘第一扇区
	if (0 >= _diskop ((unsigned char) disk+ 0x7f, 0x42, buffer, 0, 1)){
		// 主引导扇区读错误
		printf ("Error read MBR (Main Boot Record) on disk %x.\n", disk);
		return (-1);
	}

	// 判断主引导扇区是否可用
	if (buffer [510] != 0x55 || buffer [511] != 0xAA){
		// 主引导扇区标志错
		printf ("Invalid MBR (Main Boot Record) flag (%02X%02X)!\n", buffer[510], buffer[511]);
		return (-1);
	}
	
	// 读入分区信息表
	memcpy (partition_records, &buffer[446], 64);

	// 设置指定分区的起始扇区和所占扇区数
	start[0] = _partinfo[part-1].sectors_preceding_partition;
	sector[0] = _partinfo[part-1].length_of_partition_in_sectors;
	
	return (0);
}


/**
 * 显示所有硬盘的信息
 */
void show_disks_info (void)
{
	short i, j;
	
	for (i=1; ; i++){
		if (get_disk_info (i, &starts[0], &sectors[0])){
			break;
		} else {
			printf ("\nDisk %d, total size %ld MB\n", i, sectors[0]/2048);
			for (j=1; j<=4; j++){
				starts[0] = sectors[0] = 0;
				get_disk_part_info (i, j, &starts[0], &sectors[0]);
				printf ("    Partition %d, size of partition: %ld MB\tsectors preceding: %ld\n",
					j, sectors[0]/2048L, starts[0]);
			}
		}
	}
}


/**
 * 分析程序命令行参数
 */
void read_args (char * args)
{
	char arg0[CMDBUFF], arg1[CMDBUFF], arg2[CMDBUFF];
	char res[CMDBUFF], res1[CMDBUFF], res2[CMDBUFF];
	char sour[CMDBUFF], dest[CMDBUFF];
	char * endptr;
	short i, j;

	while (1 != sscanf (args, "%s -%[^-] %[^\n]", arg0, arg1, arg2)){

		if (arg1[0] == 'y'){
			conf.confirm = 0;

		} else if (arg1[0] == 'h'){
			conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
			break;

		} else if (arg1[0] == 's'){
			conf.showinfo = 1;
			break;

		} else if (arg1[0] == 'f'){
			conf.defaultmode = 1;
			conf.diskmode = 1;
			break;

		} else if (arg1[0] == 'c'){
			conf.compress= 1;

		} else if (arg1[0] == 'v'){
			if (2 == sscanf (arg1, "%s %s ", res1, res2)){
				if (sscanf (res2, "%[0-9] ", res) && strlen (res) == strlen(res2)){
					conf.imgsize = atoi (res);
				} else {
					conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
				}
			}
		} else if (arg1[0] == 'e'){
			if (2 == sscanf (arg1, "%s %s ", res1, res2)){
				if (sscanf (res2, "%[0-9] ", res) && strlen (res) == strlen(res2)){
					conf.copysectors = strtoul (res, &endptr, 10);
				} else {
					conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
				}
			}
		} else if (arg1[0] == 'd'){

			// 磁盘拷贝模式
			conf.diskmode = 1;

			if (2 == sscanf (arg1, "%*s s = %s d = %[^\n] ", sour, dest)){
				// 读入源参数信息
				if (sscanf (sour, "%[0-9] ", res) && strlen (res) == strlen (sour)){
					disks [0] = atoi (sour);
				} else {
					imgfiles[0] = strdup (sour);
				}

				i = 1;
				j = 1;
				// 读入目标参数信息
				while (sscanf(dest, "%[^,] , %[^\n] ", res, dest)){
					// 去除末尾的空格
					while (dest[strlen(dest)-1] == ' '){
						dest[strlen(dest)-1] = 0;
					}
					while (res [strlen(res)-1] == ' '){
						res[strlen(res)-1] = 0;
					}

					if (sscanf (res, "%[0-9]", res1) && strlen (res) == strlen (res1)){
						disks [i++] = atoi (res);
					} else {
						imgfiles [j++] = strdup (res);
					}
					if (strcmp (res, dest) == 0){
						break;
					}
				}
			}
			else {
				conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
				break;
			}
		}
		else if (arg1[0] == 'p'){  

			// 分区拷贝模式
			conf.diskmode = 0;

			if (2 == sscanf (arg1, "%*s s = %s d = %[^\n] ", sour, dest)){
				// 读入源参数信息
				if (sscanf (sour, "%[0-9: ] ", res) && strlen (res) == strlen (sour)){
					if (2 != sscanf (sour, "%[0-9] : %[0-9] ", res, res1)){
						// 分区参数不完整
						printf ("Invalid source parameters:(%s)\n", arg1);
						conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
						break;
					}
					disks [0] = atoi (res);
					parts [0] = atoi (res1);
				} else {
					imgfiles[0] = strdup (sour);
				}

				i = 1;
				j = 1;
				// 读入目标参数信息
				while (sscanf(dest, "%[^,] , %[^\n] ", res, dest)){
					// 去除末尾的空格
					while (dest[strlen(dest)-1] == ' '){
						dest[strlen(dest)-1] = 0;
					}
					while (res [strlen(res)-1] == ' '){
						res[strlen(res)-1] = 0;
					}

					if (sscanf (res, "%[0-9: ]", res1) && strlen (res) == strlen (res1)){
						sscanf (res, "%[0-9] : %[0-9] ", res1, res2);
						disks [i] = atoi (res1);
						parts [i++] = atoi (res2);
					} else {
						imgfiles[j++] = strdup (res);
					}
					if (strcmp (res, dest) == 0){
						break;
					}
				}
			}
			else {
				conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
				break;
			}
		}
		else {
			printf ("Bad option: -%c\n", arg1[0]);
			conf.printhelp = PR_CMDLINE | PR_OPTIONS |PR_EXAMPLE;
			break;
		}

		sprintf (args, "%s %s", arg0, arg2);
		arg2[0] = 0;
	}
}


void show_data (void)
{
	short i = 0;

	printf ("\n");
	if (disks[0]){
		if (conf.diskmode){
			printf ("Sour disk %d, size %ld MB.\n", disks[0], sectors[0]/2048L);
		} else {
			printf ("Sour disk %d partition %d, begin sector %ld, size %ld MB.\n", 
				disks[0], parts[0], starts[0], sectors[0]/2048L);
		}
	} else {
		printf ("Sour imgfile %s\n", imgfiles[0]);
	}

	for (i=1; disks[i]; i++){
		if (conf.diskmode){
			printf ("Dest disk %d, size %ld MB.\n", disks[i], sectors[i]/2048L);
		} else {
			printf ("Dest disk %d partition %d, begin sector %ld, size %ld MB.\n", 
				disks[i], parts[i], starts[i], sectors[i]/2048L);
		}
	}
	for (i=1; imgfiles[i]; i++){
		printf ("Dest imgfile %s\n", imgfiles[i]);
	}
	printf ("\n");
}


// 判断文件是否存在
// 0: 不存在
// 1: 存在

short file_exists (char * filename)
{
	FILE * FP;
	short ret;
	
	FP = fopen (filename, "rb");
	if (FP == NULL){
		ret = 0;
	} else {
		ret = 1;
		fclose (FP);
	}	
	return (ret);
}


// 读源数据文件
// 返回读入的数据块数 blocks (512 bytes)
short read_sour_file (unsigned char * buffer)
{
	unsigned char * buf;
	unsigned long size, csize;
	unsigned char c;
	short blks;
	
  readnextvol:
  	
	// 读入数据块压缩状态标志到 c 中
	if (fread (&c, 1, 1, FILES[0]) != 1){
		// 未读到数据文件标志
		printf ("Bad source file flag.\n");
		return (-1);
	}

	if (c == 0xaa){
		// 遇到数据文件结束标志:0xaa
		return (0);

	} else if (c > 1){
		// 当前文件存在分卷 (c 表示下一分卷序号)
		
		// 关闭当前源数据文件
		fclose (FILES[0]);

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

		// 打开下一分卷
		if (NULL == (FILES[0] = fopen (imgfiles[0], "rb"))){
			perror (imgfiles[0]);
			return (-1);
		}
		
		// 重新读入数据压缩标志
		goto readnextvol;
		
	} else{ // c==1 || c==0
		// 读入数据块大小到 size 中
		size = 0;
		if (fread (&size, 2, 1, FILES[0]) != 1){
			// 数据异常
			printf ("Data error (1)!\n");
			return (-1);
		}
		if (size > (Blocks << 9)){
			// 数据异常
			printf ("Data block is too large! (%d)\n", size);
			printf ("The image file may be changed!\n");
			return (-1);
		}

		if (c == 1){
			buf = (unsigned char *) malloc ((size_t) size);
			if (buf == NULL){
				perror ("buf");
				return (-1);
			}

⌨️ 快捷键说明

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