📄 ddcopy16.cpp
字号:
// 读入数据块到 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, §ors[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], §ors[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], §ors[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], §ors[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], §ors[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], §ors[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 + -