📄 recovery.c
字号:
single_pad_r=malloc_msg(DEFAULT_PROTPAD_SIZE+2); protpad_bck=malloc_msg(protpad_size+2); astream=file_open_noarch(name, m_rb); if(file_exists(protname)) { xstream=file_open_noarch(protname, m_rb); rd_offset=0L; } else { xstream=astream; rd_offset=chk_prot_sig(xstream, sig_offset); if(rd_offset==0L) { if(test_mode) { msg_cprintf(0, M_NO_PROT_DATA); nputlf(); return(0); } else error(M_NO_PROT_DATA); } } fseek(astream, 0L, SEEK_END); ifile_size=ftell(astream); if(rd_offset!=0L) ifile_size=rd_offset-6L; fseek(xstream, rd_offset, SEEK_SET); fread(single_pad, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(single_pad+4, DEFAULT_PROTPAD_SIZE-4); /* Possible XRJ damage */ if(mget_dword(&single_pad[0])!=crc32term|| mget_word (&single_pad[4])!=0x1111) { fseek(xstream, (long)DEFAULT_PROTPAD_SIZE*3+rd_offset, SEEK_SET); fread(single_pad, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(single_pad+4, DEFAULT_PROTPAD_SIZE-4); if(mget_dword(&single_pad[0])!=crc32term|| mget_word (&single_pad[4])!=0x1111) error(M_RECOVERY_CRC_DAMAGED); } fseek(xstream, rd_offset, SEEK_SET); total_blocks=mget_word(&single_pad[6]); orig_ifile_size=mget_dword(&single_pad[10]); if(ifile_size==orig_ifile_size) { fseek(astream, 0L, SEEK_SET); msg_cprintf(0, M_WORKING); for(cur_stream=0; cur_stream<total_blocks; cur_stream++) { msg_cprintf(0, (FMSG *)prot_ticker); ins_lf=1; damage_level=0; fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+rd_offset, SEEK_SET); fread(single_pad, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(single_pad+4, DEFAULT_PROTPAD_SIZE-4); if (mget_dword(&single_pad[0])!=crc32term) damage_level=2; fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+ 3L*(unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks+rd_offset, SEEK_SET); fread(single_pad_r, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(single_pad_r+4, DEFAULT_PROTPAD_SIZE-4); if(mget_dword(&single_pad_r[0])!=crc32term) { if(damage_level==2) { if(ins_lf) { nputlf(); ins_lf=0; } msg_cprintf(0, M_RECOVERY_2CRC_DAMAGED); abort_recovery(); } damage_level=1; } for(pad_ctr=0; pad_ctr<DEFAULT_PROTPAD_SIZE-14; pad_ctr++) { single_pad[pad_ctr]=single_pad[pad_ctr+14]; single_pad_r[pad_ctr]=single_pad_r[pad_ctr+14]; } fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+(unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks+rd_offset, SEEK_SET); fread(protpad, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(protpad+4, DEFAULT_PROTPAD_SIZE-4); damage_flag=(mget_dword(&protpad[0])!=crc32term)?1:0; if(!damage_flag) { for(pad_ctr=0; pad_ctr<DEFAULT_PROTPAD_SIZE-4; pad_ctr++) protpad[pad_ctr]=protpad[pad_ctr+4]; for(pad_ctr=0; pad_ctr<pad1_size; pad_ctr++) { if(damage_level==2) protpad[pad_ctr+protpad_size-pad1_size]=single_pad_r[pad_ctr]; else protpad[pad_ctr+protpad_size-pad1_size]=single_pad[pad_ctr]; } } fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+2L* (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks+rd_offset, SEEK_SET); fread(protpad_r, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(protpad_r+4, DEFAULT_PROTPAD_SIZE-4); pad_damage_flag=(mget_dword(&protpad_r[0])!=crc32term)?1:0; if(!pad_damage_flag) { for(pad_ctr=0; pad_ctr<DEFAULT_PROTPAD_SIZE-4; pad_ctr++) protpad_r[pad_ctr]=protpad_r[pad_ctr+4]; for(pad_ctr=0; pad_ctr<pad1_size; pad_ctr++) { if(damage_level==2) protpad_r[pad_ctr+protpad_size-pad1_size]= single_pad_r[pad1_size+pad_ctr]; else protpad_r[pad_ctr+protpad_size-pad1_size]= single_pad[pad1_size+pad_ctr]; } } cur_section=0; block_offset=(unsigned long)cur_stream*(unsigned long)DEFAULT_PROTPAD_SIZE; while(block_offset<ifile_size) { fseek(astream, block_offset, SEEK_SET); section_size=(int)min((unsigned long)DEFAULT_PROTPAD_SIZE, (ifile_size-block_offset)); section_size=fread(protpad_bck+1, 1, section_size, astream); protpad_bck[0]='\0'; for(pad_ctr=section_size+1; pad_ctr<protpad_size; pad_ctr++) protpad_bck[pad_ctr]='\0'; crc32term=(unsigned long) crc16_for_block(protpad_bck+1, DEFAULT_PROTPAD_SIZE); crc32_for_block(protpad_bck+1, DEFAULT_PROTPAD_SIZE); if(damage_level==0||damage_level==1) { if(mget_word(&single_pad[(pad1_size<<1)+((cur_section<<2)>>1)])!= (unsigned short)(crc32term%65536L)) goto recovery; } if(damage_level==0||damage_level==2) { if(mget_word (&single_pad_r[(pad1_size<<1)+((cur_section<<2)>>1)])!= (unsigned short)(crc32term>>16)) goto recovery; } block_offset+=(unsigned long) DEFAULT_PROTPAD_SIZE*(unsigned long)total_blocks; cur_section++; } } if(test_mode==2) goto recovery; } else {recovery: nputlf(); if(test_mode!=1) { atstream=ostream=file_open_noarch(rec_name, m_wbp); fseek(astream, 0L, SEEK_SET); errors=0; for(dest_file_size=min(ifile_size, orig_ifile_size); dest_file_size>0; dest_file_size-=(unsigned long)section_size) { section_size=min(DEFAULT_PROTPAD_SIZE, dest_file_size); if(fread(single_pad, 1, section_size, astream)!=section_size) break; if(fwrite(single_pad, 1, section_size, ostream)!=section_size) break; } for(dest_file_size= (ifile_size>=orig_ifile_size)?0:orig_ifile_size-ifile_size; dest_file_size>0; dest_file_size-=(unsigned long)section_size) { section_size=min(DEFAULT_PROTPAD_SIZE, dest_file_size); if(fwrite(single_pad, 1, section_size, ostream)!=section_size) break; } fseek(ostream, 0L, SEEK_END); if(ftell(ostream)!=orig_ifile_size) error(M_DISK_FULL); ifile_size=orig_ifile_size; for(cur_stream=0; cur_stream<total_blocks; cur_stream++) { msg_cprintf(0, (FMSG *)prot_ticker); ins_lf=1; damage_level=0; fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE*(unsigned long)cur_stream+ rd_offset, SEEK_SET); fread(single_pad, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(single_pad+4, DEFAULT_PROTPAD_SIZE-4); if(mget_dword(&single_pad[0])!=crc32term) damage_level=2; fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+3L*(unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks+rd_offset, SEEK_SET); fread(single_pad_r, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(single_pad_r+4, DEFAULT_PROTPAD_SIZE-4); if(mget_dword(&single_pad_r[0])!=crc32term) { if(damage_level==2) { if(ins_lf) { nputlf(); ins_lf=0; } msg_cprintf(0, M_RECOVERY_2CRC_DAMAGED); abort_recovery(); } damage_level=1; } for(pad_ctr=0; pad_ctr<DEFAULT_PROTPAD_SIZE-14; pad_ctr++) { single_pad[pad_ctr]=single_pad[pad_ctr+14]; single_pad_r[pad_ctr]=single_pad_r[pad_ctr+14]; } fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+(unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks+rd_offset, SEEK_SET); fread(protpad, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(protpad+4, DEFAULT_PROTPAD_SIZE-4); damage_flag=(mget_dword(&protpad[0])!=crc32term)?1:0; if(!damage_flag) { for(pad_ctr=0; pad_ctr<DEFAULT_PROTPAD_SIZE-4; pad_ctr++) protpad[pad_ctr]=protpad[pad_ctr+4]; for(pad_ctr=0; pad_ctr<pad1_size; pad_ctr++) { if(damage_level==2) protpad[pad_ctr+protpad_size-pad1_size]=single_pad_r[pad_ctr]; else protpad[pad_ctr+protpad_size-pad1_size]=single_pad[pad_ctr]; } } fseek(xstream, (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)cur_stream+2L* (unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks+rd_offset, SEEK_SET); fread(protpad_r, 1, DEFAULT_PROTPAD_SIZE, xstream); crc32term=CRC_MASK; crc32_for_block(protpad_r+4, DEFAULT_PROTPAD_SIZE-4); pad_damage_flag=(mget_dword(&protpad_r[0])!=crc32term)?1:0; if(!pad_damage_flag) { for(pad_ctr=0; pad_ctr<DEFAULT_PROTPAD_SIZE-4; pad_ctr++) protpad_r[pad_ctr]=protpad_r[pad_ctr+4]; for(pad_ctr=0; pad_ctr<pad1_size; pad_ctr++) { if(damage_level==2) protpad_r[pad_ctr+protpad_size-pad1_size]= single_pad_r[pad1_size+pad_ctr]; else protpad_r[pad_ctr+protpad_size-pad1_size]= single_pad[pad1_size+pad_ctr]; } } cur_section=0; bck_pad_flag=pad_flag=-1; block_offset=(unsigned long)cur_stream*(unsigned long)DEFAULT_PROTPAD_SIZE; while(block_offset<ifile_size) { fseek(ostream, block_offset, SEEK_SET); section_size=fread(protpad_bck+1, 1, DEFAULT_PROTPAD_SIZE, ostream); protpad_bck[0]='\0'; for(pad_ctr=section_size+1; pad_ctr<protpad_size; pad_ctr++) protpad_bck[pad_ctr]='\0'; data_damage=0; crc32term=(unsigned long) crc16_for_block(protpad_bck+1, DEFAULT_PROTPAD_SIZE); crc32_for_block(protpad_bck+1, DEFAULT_PROTPAD_SIZE); if(damage_level==0||damage_level==1) { if (mget_word (&single_pad[(pad1_size<<1)+((cur_section<<2)>>1)])!= (unsigned short)(crc32term%65536L)) data_damage=1; } if(damage_level==0||damage_level==2) { if (mget_word (&single_pad_r[(pad1_size<<1)+((cur_section<<2)>>1)])!= (unsigned short)(crc32term>>16)) data_damage=1; } if(data_damage) { errors++; if(ins_lf) { nputlf(); ins_lf=0; } msg_cprintf(0, M_SECTION_DAMAGED, cur_stream, cur_section); if(bck_pad_flag==-1) { bck_pad_flag=cur_section; rec_size=section_size; } else if(pad_flag==-1) { pad_flag=cur_section; bck_rec_size=section_size; } else abort_recovery(); } else { for(pad_ctr=0; pad_ctr<protpad_size; pad_ctr++) { protpad[pad_ctr]^=protpad_bck[pad_ctr]; protpad_r[pad_ctr]^=protpad_bck[(pad_ctr+cur_section)%protpad_size]; } } block_offset+=(unsigned long)DEFAULT_PROTPAD_SIZE* (unsigned long)total_blocks; cur_section++; } if(bck_pad_flag!=-1) { if(damage_flag!=0&&pad_damage_flag!=0&&bck_pad_flag!=-1) abort_recovery(); else { if(damage_flag==0&&pad_damage_flag==0) { if(pad_flag==-1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -