home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1999 April
/
VPR9904A.BIN
/
Vpr_data
/
Special
/
D_DUMP31
/
D_DUMP31.LZH
/
DISKDUMP.C
next >
Wrap
C/C++ Source or Header
|
1998-06-10
|
118KB
|
3,861 lines
/* diskdump.c Ver 3.10 '98. 6. 10
Auther : K.Yokogawa
Computer : All MS-DOS Machines
Compiler : MS-C Ver 6.0 Compact model & MASM Ver 5.10
Hard Disk の Disk Image の Backup, Restore を行なう
Bad Cluster の処理のため,sector size >= 512 とする
少し,Hard Diskの容量が異なっても対処できるようにする(Ver3.0)
write_buf(=check_buf)の内容は次の通り. 1行は16文字で
1 行目 DiskDump Ver 3.0
2 - 3 行目 start - end sector
3 行目終り FAT32 or FAT16
4 行目 Total: total sectors
5 行目 Used: used sectors
以下はbinary データ
6 行目 dpb-data 22 byte
uint _sector_size; number of bytes per sector
char _cluster_mask; Sectors/cluster - 1 = 2^n - 1
char _cluster_shift; log base 2 of the cluster size
uint _first_fat; number of reserved (boot) sectors
char _num_of_fat; 2 に決め打ち number of copies of the FAT
uint _root_entries; number of root directory entries
ulong _first_data_sector; first data sector on medium
ulong _max_cluster; largest possible cluster number+1
ulong _fat_sector; number of sectors par FAT
char ゴミ
uint used_dir_entry;
ulong used_clust; used_clust+1, cf. _max_clust
uint sect/clust;
uint ゴミ
8 行目
ulong start_sect;
ulong r_next_sect;
ulong write_start_sect;
ulong r_end_sect;
9 - 12 行 ipl 16*4 byte
13 - 32 行 bad cluster table
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <jstring.h>
#include <process.h>
#include <direct.h>
#include <ctype.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long int
#define YES 1
#define NO 0
#define ERR_RET -1
#define SUC_RET 1
#define NO_ERROR 0xff
#define READ 0
#define WRITE 1
#define STOP_KEY 0x3
#define ESC_KEY 0x1b
#define FILE_LENGTH 0x50000000L
#define BUF_UNIT 0x8000L
/* #define S_SIZE 0 */
/* #define C_S_SIZE 80 */
#define C_MASK 2
#define FAT_S 4
#define DIR_E 7
#define DATA_S 9
#define MAX_C 13
#define S_P_FAT 17
#define IPL_B 50 /* ipl の [50] */
#define C_C_MASK 82
#define C_FAT_S 84
#define C_DIR_E 87
#define C_DATA_S 89
#define C_MAX_C 93
#define C_S_P_FAT 97
#define USED_D 102
#define USED_C 104
#define C_SECT_C 108
#define R_START_S 112
#define R_NEXT_S 116
#define W_START_S 120
#define R_END_S 124
#define C_IPL_B 178 /* ipl の backup の部分 */
char buf[0x10000L], buf2[0x10000L], bad_clust[320],
bad_table[128];
/* bad_table は 64K/byte_par_sect で byte_par_sect >= 512 を仮定 */
int error_code, win95 = 0, verify = 0, so_32bit, des_32bit,
full_dump, big_buf = 0, rewrite_flag = 0;
uint bad_clust_num = 0; /* bad_clust_num は uint でいいだろう */
ulong buf_size, f_s_limit = 0;
char _drive[3], _path[80];
/* uint _sector_size; number of bytes per sector
char _cluster_mask; Sectors/cluster - 1 = 2^n - 1
char _cluster_shift; log base 2 of the cluster size
uint _first_fat; number of reserved (boot) sectors
char _num_of_fat; number of copies of the FAT
uint _root_entries; number of root directory entries
uint->ulong _first_data_sector; first data sector on medium
uint->ulong _max_cluster; largest possible cluster number+1
uint->ulong _fat_sector; number of sectors par FAT
uint->ulong は 32bit fatの為の変更
*/
/*
ExtDPB:
Size_DPB dw ? ;size of DPB
DPB:
DPB_drive db ? ;ドライブ番号(00h=A:,01h=B:,・・・)
DPB_unit db ? ;論理装置コード番号
DPB_bySec dw ? ;1レコードのバイト数
DPB_secClus db ? ;1クラスタのレコード数
DPB_scount db ? ;クラスタ←→レコードのシフトカウンタ
DPB_FATsec dw ? ;予約レコード数(FATの開始レコード)
DPB_numFAT db ? ;FATの数
DPB_numDIR dw ? ;ルートディレクトリのエントリ総数
DPB_DataSec dw ? ;データエリア先頭レコード番号
DPB_maxClusNo dw ? ;最大クラスタ番号(総クラスタ数+1)
DPB_secFAT dw ? ;1FATのレコード数
DPB_DIRsec dw ? ;ルートディレクトリ先頭レコード番号
DPB_DHH_ptr dd ? ;デバイスヘッダへのベクタアドレス
; reserved ?
DPB_media db ? ;メディア・ディスクリプタ
DPB_dflag db ? ;ディスク交換フラグ(未アクセスの時はFFh)
; first access flag
DPB_next_ptr dd ? ;次のDPBへのポインタ
;最後のDPBは FFFF:FFFF 通常これ
DPB_chgClus dw ? ;最後に変更したクラスタ番号
DPB_freeClusLow dw ? ;未使用クラスタ数(下位)
; *** FAT32 の拡張部分 ***
DPB_freeClusHi dw ? ;未使用クラスタ数(上位)
DPB_actFAT dw ? ;アクティブFATミラーリング
; bits 3-0: アクティブFATの数
; bits 6-4: 予約(0)
; bit 7: ミラーリングされていない
DPB_FSIsec dw ? ;ファイルシステム情報のレコード番号
;(FFFFh=FSIなし)
DPB_BootBakSec dw ? ;ブートレコードバックアップのレコード
DPB_DataSec32 dd ? ;データエリア先頭レコード番号 (FAT32)
DPB_maxClusNo32 dd ? ;最大クラスタ番号 (FAT32)
DPB_secFAT32 dd ? ;1FATのレコード数 (FAT32)
DPB_DIRsec32 dd ? ;ルートディレクトリ先頭レコード (FAT32)
DPB_chgClus32 dd ? ;最後に変更したクラスタ番号 (FAT32)
*/
char ext_dfree[44];
/*
ExtFreeSpace STRUC
EFS_TrueSize dw ? ;ドライブの実際のサイズ ???
EFS_StrucVer dw ? ;構造体のバージョン ???
EFS_secClus dd ? ;1クラスタのレコード数 (圧縮補正)
EFS_bySec dd ? ;1レコードのバイト数
EFS_AvailClus dd ? ;使用可能クラスタ数
EFS_TotalClus dd ? ;ドライブのクラスタ総数
EFS_AvailSec dd ? ;使用可能物理セクタ数 (圧縮補正)
EFS_TotalSec dd ? ;ドライブの物理セクタ総数(圧縮補正)
EFS_AvailUnit dd ? ;使用可能ユニット数 (圧縮補正)
EFS_TotalUnit dd ? ;ユニット総数 (圧縮補正)
EFS_reserved db 8 dup(0) ;予約領域
ExtFreeSpace ENDS
*/
char error_msg[9][18] = {"Write protected", "Unit not Exist",
"Drive not Ready", "Invalid Command", "Data CRC Error",
"Bad Drive Request", "Seek Error", "No such Media",
"Sector not found"};
/* subroutine by assembler */
int abs_read_write(int drive, uint sectors, ulong start_sect, char *buf, int sw);
int ext_abs_read_write(int drive, uint sectors, ulong start_sect, char *buf, int sw);
int get_dpb(int drive, char *dpb);
int get_ext_dpb(int drive, char *ext_dpb);
int get_version();
int ioctrl_lock(int drive, int sw);
void get_ext_dfree(char *drive_path, char *buf);
/* void ext_resetdisk(int drive); */
void resetdisk();
void yjstrupr(char *);
int getcurdir(int, char *);
void set_24h(void);
int get_error_code(void);
void reset_24h(void);
int drive_ready(char drv);
void abort_msg(void)
{
printf("Abort DISKDUMP.EXE\n");
}
void ybeep()
{
putch(0x07); /* beep */
}
void exit_routine(int num)
{
ybeep();
printf("\n");
reset_24h();
exit(num);
}
void keyclr()
{
union REGS inregs;
inregs.x.ax = 0xc00; /* key buffer clear */
intdos(&inregs, &inregs);
}
void disp_err_msg()
{
if(error_code != NO_ERROR){
ybeep();
ybeep();
printf("\n%s\nAbort DISKDUMP.EXE\n", error_msg[error_code]);
exit_routine(5);
}
}
void disp_msg(int num, char *source, char *dest)
{
switch(num){
case 0:
printf("\nDISKDUMP.EXE ends successfully.\n");
break;
case 10:
printf("DISKDUMP.EXE Version 3.10 by K.Yokogawa\n\n");
printf("Usage is DISKDUMP [options] Source-Drive Destination-Drive\n");
printf("For instance, DISKDUMP -b -f A: B:\n");
printf("Source and Destination-Drive should be of the form \'A:\'\n");
printf("File Extension is \"DUP\" (\"DDD\", \"DD3\" for p-option)\n");
printf("Option is -b: Make Backup (default)\n");
printf(" -r: Restore\n");
printf(" -p: Use Special Method\n");
printf(" -t: Test Using Backup 64K, Restore 64K buffer for Special Method\n");
printf(" -t1: Test Using Backup 64K, Restore 32K buffer for Special Method\n");
printf(" -t2: Test Using Backup 32K, Restore 64K buffer for Special Method\n");
printf(" -t3: Test Using Backup 32K, Restore 32K buffer for Special Method\n");
printf(" -d: Direct Disk Duplicate\n");
printf(" -l: File Size Limit For Ex. -l630 (630 M bytes, 1 M = 1024 K)\n");
printf(" -st: Start Sector For Ex. -st12345678\n");
printf(" -f: Full dump(use with {-b,-p,-d})\n");
printf(" -v: verify when usual backup (defaut off)\n");
printf(" -g: Use 64K read-write buffer (Default: 32K buffer)\n");
printf("In the case of \"-p\" option, the Disk Image of Source is dumped to the data area\n");
printf("of destination drive directly. In this case, Newly formatted Media is desirable.");
break;
case 11:
printf("\nIncorrect Source Drive %s !! \n", source);
abort_msg();
break;
case 12:
printf("\nIncorrect Destination Drive %s !! \n", dest);
abort_msg();
break;
case 13:
printf("\nSource Drive is not ready !!\n");
abort_msg();
break;
case 14:
printf("\nDestination Drive is not ready !!\n");
abort_msg();
break;
case 15:
printf("\nSource and Destination Drive must be different !!\n");
abort_msg();
break;
case 16:
printf("\nDestination Drive has an incorrect disk format !!\n");
printf("Sector sizes and Cluster sizes must be Same.\n");
abort_msg();
break;
case 17:
printf("\nFile %s is not correct format !!\n", source);
abort_msg();
break;
/* case 18: 欠番 */
case 19:
printf("\nUser break !! Abort DISKDUMP.EXE\n");
break;
case 20:
printf("\nSource drive %s Read Error !!\n", source);
abort_msg();
break;
case 21:
printf("\nDestination drive Write Error !!\n");
abort_msg();
break;
case 22:
printf("\nFile Read Error !!\n");
abort_msg();
break;
case 23:
printf("\nFile Write Error !!\n");
abort_msg();
break;
case 24:
printf("\nFile Open Error !!\n");
abort_msg();
break;
case 25:
printf("\nFile Close Error !!\n");
abort_msg();
break;
case 26:
printf("\nUnknown Disk Type !!\n");
abort_msg();
break;
case 27:
printf("\nStart Sector is not used in Source Drive !!\n");
printf(" or Start Sector exceeds Last Sector of Source Drive !!\n");
abort_msg();
break;
case 28:
printf("\nIncorrect source FAT !!\n");
abort_msg();
break;
case 29:
printf("\nEnd Sector of Source exceeds End Sector of Destination !!\n");
printf("It may happen to be a Different Format Disk.\n");
abort_msg();
break;
case 30:
printf("\nVerify Error !!\n");
abort_msg();
break;
case 33:
printf("\nError at FAT Sectors. This media is broken !!\n");
abort_msg();
break;
case 34:
printf("\nSource drive %shas Not enough free area to test !!\n", source);
abort_msg();
break;
case 35:
printf("\nSource drive %s has Not enough data to test !!\n", source);
abort_msg();
break;
/* case 36: 欠番 */
case 37:
printf("\n \"-p -G option\" Test ends successfully.\n");
break;
case 38:
printf("\nDestination drive %s has Not enough free area to test !!\n", dest);
abort_msg();
break;
case 39:
printf("\nInsufficient Root directory entries or Data Area.\n");
printf("Cannnot restore !!\n");
abort_msg();
break;
case 40:
printf("\nError at IPL Sectors. Destination Drive is broken !!\n");
printf("Retry after Disk Format\n");
abort_msg();
break;
case 41:
printf("\nIrregular Designation of start_sector\n");
abort_msg();
break;
case 42:
printf("\nDestination drive Read Error !!\n");
abort_msg();
break;
case 43:
printf("\nError at Directry Entry Sectors !!\n");
abort_msg();
break;
case 44:
printf("\nDestination Drive Write Error !!\n");
abort_msg();
break;
case 45:
printf("\nInsufficient Data Area in Destination Drive\n");
abort_msg();
break;
case 46:
printf("\nError at Clearing Test Area in Source Drive\n");
abort_msg();
break;
}
exit_routine(num);
}
void disp_msg2(int num, char *source, char *dest, ulong start_sect)
{
char ans;
int i;
if(num == 5)
return;
switch(num){
case 0: /* load */
printf("\n");
if(start_sect)
printf("From Sector %lu, ", start_sect);
printf("Drive %s will be Rewrited by the Disk Image file in %s\n", dest, source);
break;
case 1: /* save */
printf("\n");
if(start_sect)
printf("From Sector %lu, ", start_sect);
if(full_dump)
printf("Full ");
printf("Disk Image of drive %s will be saved to %s\n", source, dest);
break;
case 2: /* duplicate */
printf("\n");
if(start_sect)
printf("From Sector %lu, ", start_sect);
printf("Drive %s will be Directly Duplicated to the drive %s\n", source, dest);
break;
case 3: /* load */
printf("\n");
if(start_sect)
printf("From Sector %lu, ", start_sect);
printf("Drive %s will be Rewrited by the Special Disk Image in %s\n", dest, source);
break;
case 4: /* save */
printf("\n");
if(start_sect)
printf("From Sector %lu, ", start_sect);
if(full_dump)
printf("Full ");
printf("Disk Image of drive %s will be saved to %s by Special method\n", source, dest);
break;
case 6:
printf("\nDestination %s has not enough free area !!\n", dest);
printf("Insert New Media in Destination Drive.\n");
break;
case 7:
printf("\nInsert New Media in %s\n", dest);
break;
case 8:
printf("\nInsert Next Backuped Media in %s\n", source);
printf("Or Press ESC Key to End\n");
break;
case 9:
break;
case 10:
printf("\nNumber of Bad clusters of %s exceeds 80 !!\n", source);
break;
case 11:
printf("\nBad Sectors of %s increased after disk format !!\n", source);
break;
case 12:
printf("\nBad Sectors of %s increased after diskdump !!\n", dest);
break;
case 13:
printf("\n%s is not found in Source Drive !!\n", source);
printf("Insert Next Media in source Drive.\n");
break;
}
if(num >= 10){
ybeep();
ybeep();
printf("\nContinue in anyway ? > (y/n)");
for(i = 0 ; i < 2; i++)
putch(0x08);
}else{
printf("\nAre You Ready ? > (y/n)");
for(i = 0 ; i < 4; i++)
putch(0x08);
}
keyclr();
ans = getch();
printf("\n");
if(num >= 10){
if((ans =='Y') || (ans == 'y'))
return;
}else{
if((ans =='Y') || (ans == 'y') || (ans == 0xd))
return;
}
ybeep();
exit_routine(num);
}
int disp_msg3(ulong total_data_size)
{
char ans;
int i;
printf("\nSector sizes and Cluster sizes are Same.\n");
printf("But Amounts of Data Area are Different !!\n");
printf("\nOriginal Drive has %ld K bytes (1 K = 1024) Data Area.\n\n", total_data_size);
ybeep();
ybeep();
printf("Anyway, Do You Continue ? > (y/n)");
for(i = 0 ; i < 4; i++)
putch(0x08);
keyclr();
ans = getch();
printf("\n\n");
if((ans =='Y') || (ans == 'y') || (ans == 0xd))
return(1);
else
return(0);
}
void disp_warn(int num, char *drive)
{
switch(num){
case 1:
printf("Source Drive %s has bad Clusters.\n", drive);
break;
case 2:
printf("Source Drive %s has unrecorded bad Clusters.\n", drive);
break;
case 3:
printf("Destination Drive %s has bad Clusters.\n", drive);
break;
case 4:
printf("Destination Drive %s has unrecorded bad Clusters.\n", drive);
break;
case 5:
printf("\n\nData Compare Error !!\n");
printf(" Fails to Test \"-p -G option\" \n\n");
break;
}
ybeep();
if(num == 5){
ybeep();
printf("Press Any key !! ");
keyclr();
getch();
printf("\n");
}
}
int check_end_en(char *str)
{
if((strlen(str) > 1)
&& (str[strlen(str)-1] == '\\')
&& (nthctype(str, strlen(str) -2 ) != CT_KJ1))
return(YES);
else
return(NO);
}
char ygetch() /* if key is not pushed return NO, else getch() */
{
union REGS regs;
regs.h.ah = 0x06;
regs.h.dl = 0xff;
intdos(®s, ®s);
return(regs.h.al);
}
void check_user_break(char *s_d, char *d_d)
{
char ch;
ch = ygetch();
if((ch == STOP_KEY) || (ch == ESC_KEY))
disp_msg(19, s_d, d_d);
}
void add_en(char *str)
{
if((( *str != '\\') || ( *(str+1) != 0)) && !check_end_en(str) )
strcat(str,"\\");
}
void del_en(char *str)
{
if(((str[0] != '\\') || str[1] != 0) && check_end_en(str) )
str[strlen(str) - 1] = 0;
}
void add_drive(char *d_p)
{
char directory[80], dummy[3];
if(d_p[1] == ':')
d_p[0] = (char)toupper(d_p[0]);
if(d_p[0] == '\\'){
dummy[0] = _getdrive() + 'A' -1 ;
dummy[1] = ':' ;
dummy[2] = 0 ;
strcpy(directory, d_p);
strcpy(d_p, dummy);
strcat(d_p, directory);
}
if(d_p[1] != ':'){
dummy[0] = _getdrive() + 'A' -1 ;
dummy[1] = ':' ;
dummy[2] = 0 ;
strcpy(directory, d_p);
strcpy(d_p, dummy);
strcat(d_p, directory);
}
}
int change_dir(char *path)
{
union REGS regs;
struct SREGS segregs;
segread(&segregs);
regs.h.ah = 0x3b; /* change directory */
regs.x.dx = FP_OFF(path);
segregs.ds = FP_SEG(path);
intdosx(®s, ®s, &segregs);
if((regs.x.cflag != 0) && (regs.x.ax == 0x03))
return(ERR_RET);
else
return(SUC_RET);
}
int analize_drive_path(char *d_p)
{
char directory[80];
yjstrupr(d_p);
if(getcurdir(*d_p - 'A' + 1, directory) != 0)
error_code = get_error_code();
if(error_code == NO_ERROR){
_drive[0] = d_p[0] ;
_drive[1] = ':' ;
_drive[2] = 0 ;
if(d_p[2] == '\\')
strncpy(_path, d_p + 2 , strlen(d_p) - 1);
else{ /* d_p[2] != '\\' */
strcpy(_path, "\\");
strcat(_path, directory);
add_en(_path);
strcat(_path, d_p + 2);
}
del_en(_path);
return(SUC_RET);
}else{
disp_err_msg(); /* and exit */
return(ERR_RET);
}
}
int normalize(char *str) /* パス等の正規化 */
{
if(analize_drive_path(str) == ERR_RET)
return(ERR_RET);
else{
strcpy(str, _drive);
strcat(str, _path);
return(SUC_RET);
}
}
uint uintmax(uint x, uint y)
{
if(x > y)
return(x);
else
return(y);
}
uint uintmin(uint x, uint y)
{
if(x > y)
return(y);
else
return(x);
}
ulong div_upper(ulong x, ulong y)
/* x / y の切り上げ */
{
return((x + y -1) / y);
}
int do_read_write(char drive, uint sectors, ulong start_sect, char *bf,
int sw_32bit, int sw)
{
if(sw_32bit)
return(ext_abs_read_write((uint)drive-'A'+1,sectors,start_sect,bf,sw));
else
return(abs_read_write((uint)drive-'A',sectors,start_sect,bf,sw));
}
int check_disk_format(char *dpb, char *check_buf)
/* uint _sector_size; number of bytes per sector
char _cluster_mask; Sectors/cluster - 1 = 2^n - 1
int num of root entory if 0 then 32bit FAT
uint->ulong _first_data_sector; first data sector on medium
これが一致すれば,FATもほぼ一致
uint->ulong _max_cluster; largest possible cluster number+1
の check. もっと check しても良いし甘くしても良い */
{
if((*(uint *)dpb == *(uint *)(check_buf +80))
&& (dpb[C_MASK] == check_buf[C_C_MASK])
&& (*(uint *)(dpb +DIR_E) == *(uint *)(check_buf +C_DIR_E))
&& (*(ulong *)(dpb +DATA_S) == *(ulong *)(check_buf +C_DATA_S))
&& (*(ulong *)(dpb +MAX_C) == *(ulong *)(check_buf +C_MAX_C)))
return(1); /* 単純 restore 可能 */
else if((*(uint *)dpb == *(uint *)(check_buf +80))
&& (dpb[C_MASK] == check_buf[C_C_MASK]))
return(2); /* sect_size, sect_par_cluster 一致 */
else
return(0); /* restore 不可 */
}
int check_dir_entry_etc(char *dpb, char *check_buf)
{
if((*(uint *)(dpb + DIR_E) >= *(uint *)(check_buf + USED_D))
&& (*(ulong *)(dpb + MAX_C) >= *(ulong *)(check_buf + USED_C)))
return(1);
else
return(0);
}
shift_ext_dpb(char *dpb, char *ext_dpb)
{
int i;
for(i = 0; i < 9; i++)
dpb[i] = ext_dpb[i+4];
for(i = 9; i < 21; i++)
dpb[i] = ext_dpb[i+43-9];
}
void shift_dpb(char *dpb) /* bit32 対応の為にずらす */
{
dpb[17] = dpb[13];
dpb[18] = dpb[14];
dpb[19] = 0;
dpb[20] = 0;
dpb[13] = dpb[11];
dpb[14] = dpb[12];
dpb[15] = 0;
dpb[16] = 0;
dpb[9] = dpb[9];
dpb[10] = dpb[10];
dpb[11] = 0;
dpb[12] = 0;
}
void set_file_name(char *file_name, char *directory, ulong start_sect, int sw)
{
char f_name[14];
sprintf(f_name, "%.8lu", start_sect);
switch(sw){
case 0:
strcat(f_name, ".DD3");
break;
case 1:
strcat(f_name, ".DDD");
break;
case 2:
strcat(f_name, ".DUP");
break;
}
strcpy(file_name, directory);
add_en(file_name);
strcat(file_name, f_name);
}
int do_compare(char *buf, char *buf2, uint comp_size)
/* 比較し,不一致で 1, 一致で 0 を返す */
{
uint i;
for(i = 0; i < comp_size; i++){
if( *(int *)(buf + 2*i) != *(int *)(buf2 + 2*i)){
ybeep();
ybeep();
break;
}
}
if(i < comp_size)
return(1);
else
return(0);
}
void reset_free_clust(char *dest, uint size)
/* OSR2 32bit FAT の時のみ,ioctrl は発行している */
{
uint rr_sect;
rr_sect = (uint)div_upper((ulong)4096, (ulong)size);
/* 1024 byte 読めれば良いが余裕 */
ext_abs_read_write(*dest - 'A' +1, rr_sect, 0, buf, READ);
*(long *)(buf + 0x3e8) = 0xffffffff;
ext_abs_read_write(*dest - 'A' +1, rr_sect, 0, buf, WRITE);
/* ext_resetdisk(*dest - 'A' +1); */
}
ulong sect2clust(char *dpb, ulong sect, int sw_32bit)
/* sector の入っている cluster を返す */
/* (ulong)(*(uint *)(dpb + FAT_S))
+ (*(ulong *)(dpb + S_P_FAT) * 2)
= *(ulong *)(dpb + DATA_S) (32bit FAT時)
(ulong)(*(uint *)(dpb + FAT_S))
+ (*(ulong *)(dpb + S_P_FAT) * 2)
+ ((ulong)(*(uint *)(dpb + DIR_E))*32)
/(ulong)(*(uint *)dpb)
= *(ulong *)(dpb + DATA_S) (16bit FAT時)である. */
{
ulong clust;
clust = (sect - *(ulong *)(dpb + DATA_S)) / ((ulong)dpb[C_MASK] +1);
clust += 2;
return(clust);
}
ulong clust2sect(char *dpb, ulong clust)
/* cluster の先頭 sector を返す */
{
return((clust - 2)*((ulong)dpb[C_MASK] +1)+ (*(ulong *)(dpb + DATA_S)));
}
ulong get_true_end_sect(char *dpb, char *drive, ulong *used, int _32bit)
/* 実際は,end_sect +1 を返す.used_clustも使用しているclust+1 */
/* ここで,bad_clust[], bad_clust_num も set する */
{
ulong last_clust, max_clust, sect, end_sect;
uint i, j, rest_fat, rr_sect, mult_K , /* buffer size を何回読むか */
rest_sect, num_clust;
for(i = 0; i < 80; i++)
*(long *)(bad_clust+ 4*i) = 0;
max_clust = *(ulong *)(dpb + MAX_C) +1; /* IPL, FAT部分加える */
if(_32bit){
if(big_buf)
num_clust = (uint)(BUF_UNIT / 2);/* 1度に読む FATの cluster 数 */
else
num_clust = (uint)(BUF_UNIT / 4);
mult_K = (uint)(max_clust / (ulong)num_clust);
rest_fat = (uint)(max_clust - mult_K*(ulong)num_clust);
rr_sect = (uint)(buf_size / (ulong)(*(uint *)dpb));
for(i = 0; i < mult_K; i++){
sect = (ulong)(*(uint *)(dpb + FAT_S)) + (ulong)rr_sect*i;
if(ext_abs_read_write(*drive - 'A' +1, rr_sect, sect, buf, READ))
disp_msg(28, drive, "");
for(j = 0; j < num_clust; j++){
if(*(ulong *)(buf + 4*j) == (ulong)0xffffff7){
if(bad_clust_num < 80)
*(ulong *)(bad_clust + 4*bad_clust_num)
= (ulong)i*num_clust + j ;
bad_clust_num ++; /* 不良 cluster */
}else if( *(ulong *)(buf + 4*j) != 0)
last_clust = (ulong)i*num_clust + j;
}
}
sect = (ulong)(*(uint *)(dpb + FAT_S)) + rr_sect*mult_K;
rest_sect = (uint)div_upper((ulong)(rest_fat)*4,(ulong)(*(uint *)dpb));
if(rest_sect){
if(ext_abs_read_write(*drive - 'A' +1, rest_sect, sect,buf,READ))
disp_msg(28, drive, "");
for(j = 0; j < rest_fat; j++){
if(*(ulong *)(buf + 4*j) == (ulong)0xffffff7){
if(bad_clust_num < 80)
*(ulong *)(bad_clust + 4*bad_clust_num)
= (ulong)mult_K*num_clust + j ;
bad_clust_num ++; /* 不良 cluster */
}else if( *(ulong *)(buf + 4*j) != 0)
last_clust = mult_K*num_clust + j;
}
}
}else{
if(max_clust <= 0xff4){ /* 12bit_fat */
num_clust = 0x4000; /* 1度に読む FATの cluster 数 */
/* buffer に 0x6000 必要 */
mult_K = (uint)(max_clust / (ulong)num_clust);
rr_sect = (uint)((0x6000L / (ulong)(*(uint *)dpb)));
rest_fat = (uint)(max_clust - mult_K*(ulong)num_clust);
for(i = 0; i < mult_K; i++){
sect = (ulong)(*(uint *)(dpb + FAT_S)) + (ulong)rr_sect*i;
if(abs_read_write(*drive - 'A', rr_sect, sect, buf, READ))
disp_msg(28, drive, "");
for(j = 0; j < num_clust; j++){
if(j & 1){ /* 奇数なら */
if(((uchar)(buf[(j*3)/ 2] & 0xf0) == (uchar)0x70)
&& ((uchar)buf[((j*3)/ 2) +1] == (uchar)0xff)){
if(bad_clust_num < 80)
*(uint *)(bad_clust + 2*bad_clust_num) = j;
bad_clust_num ++; /* 不良 cluster */
}else if((buf[(j*3)/ 2] & 0xf0) || buf[((j*3)/ 2) +1])
last_clust = (ulong)i*num_clust + j;
}else{ /* 偶数なら */
if(((uchar)buf[(j*3)/ 2] == (uchar)0xf7)
&& ((uchar)(buf[((j*3)/ 2) +1] & 0x0f)==(uchar)0x0f)){
if(bad_clust_num < 80)
*(uint *)(bad_clust + 2*bad_clust_num) = j;
bad_clust_num ++; /* 不良 cluster */
}else if((buf[(j*3)/ 2])||((buf[((j*3)/ 2) +1])& 0x0f))
last_clust = (ulong)i*num_clust + j;
}
}
}
sect = (ulong)(*(uint *)(dpb + FAT_S)) + rr_sect*mult_K;
rest_sect = (uint)div_upper((ulong)(rest_fat*3 + 1)/2,
(ulong)(*(uint *)dpb));
if(rest_sect){
if(abs_read_write(*drive - 'A', rest_sect, sect, buf, READ))
disp_msg(28, drive, "");
for(j = 0; j < rest_fat; j++){
if(j & 1){ /* 奇数なら */
if(((uchar)(buf[(j*3)/ 2] & 0xf0) == (uchar)0x70)
&& ((uchar)buf[((j*3)/ 2) +1] == (uchar)0xff)){
if(bad_clust_num < 80)
*(uint *)(bad_clust + 2*bad_clust_num) = j;
bad_clust_num ++; /* 不良 cluster */
}else if((buf[(j*3)/ 2] & 0xf0) || buf[((j*3)/ 2) +1])
last_clust = mult_K*num_clust + j;
}else{ /* 偶数なら */
if(((uchar)buf[(j*3)/ 2] == (uchar)0xf7)
&& ((uchar)(buf[((j*3)/ 2) +1] & 0x0f)==(uchar)0x0f)){
if(bad_clust_num < 80)
*(uint *)(bad_clust + 2*bad_clust_num) = j;
bad_clust_num ++; /* 不良 cluster */
}else if((buf[(j*3)/ 2])||((buf[((j*3)/ 2) +1])& 0x0f))
last_clust = mult_K*num_clust + j;
}
}
}
}else{ /* 16bit_fat */
if(big_buf)
num_clust = (uint)BUF_UNIT; /* 1度に読む FATの cluster 数 */
else
num_clust = (uint)(BUF_UNIT / 2);
mult_K = (uint)(max_clust / (ulong)num_clust);
rest_fat = (uint)(max_clust - mult_K*(ulong)num_clust);
rr_sect = (uint)(buf_size / (ulong)(*(uint *)dpb));
for(i = 0; i < mult_K; i++){
sect = (ulong)(*(uint *)(dpb + FAT_S)) + (ulong)rr_sect*i;
if(abs_read_write(*drive - 'A', rr_sect, sect, buf, READ))
disp_msg(28, drive, "");
for(j = 0; j < num_clust; j++){
if(*(uint *)(buf + 2*j) == (uint)0xfff7){
if(bad_clust_num < 80)
*(uint *)(bad_clust + 2*bad_clust_num) = j;
bad_clust_num ++; /* 不良 cluster */
}else if(*(uint *)(buf + 2*j) != 0)
last_clust = (ulong)i*num_clust + j;
}
}
sect = (ulong)(*(uint *)(dpb + FAT_S)) + rr_sect*mult_K;
rest_sect = (uint)div_upper((ulong)rest_fat*2,
(ulong)(*(uint *)dpb));
if(rest_sect){
if(abs_read_write(*drive - 'A', rest_sect, sect, buf, READ))
disp_msg(28, drive, "");
for(j = 0; j < rest_fat; j++){
if(*(uint *)(buf + 2*j) == (uint)0xfff7){
if(bad_clust_num < 80)
*(uint *)(bad_clust + 2*bad_clust_num) = j;
bad_clust_num ++; /* 不良 cluster */
}else if(*(uint *)(buf + 2*j) != 0)
last_clust = mult_K*num_clust + j;
}
}
}
}
resetdisk();
end_sect = clust2sect(dpb, last_clust +1);
*used = last_clust;
return(end_sect);
}
int make_bad_sect_table(char *dpb, uint rr_sect, ulong sect,
char *table, int sw_32bit)
/* if error sector is not recorded return 1, else return 0 */
{
uint i, j, k;
ulong clust, s_sect, e_sect;
if(rewrite_flag)
disp_msg(44, "", "");
if(bad_clust_num == 0)
return(1);
for(i = 0; i < rr_sect; i++)
table[i] = 0;
for(i = 0; (i < bad_clust_num) && (i < 80); i++){
if(sw_32bit)
clust = *(ulong *)(bad_clust + 4*i);
else
clust = (ulong)*(uint *)(bad_clust + 2*i);
s_sect = clust2sect(dpb, clust);
e_sect = clust2sect(dpb, clust +1);
j = 0;
while(j < rr_sect){
if((s_sect <= sect + j) && (sect +j < e_sect)){
for(k =0;((k < (uint)(e_sect- s_sect))&&((j+k) < rr_sect));k++)
table[j + k] = 1; /* 1 cluster 分 mark */
j += k;
}else /* if(sect +j >= e_sect)... としても早くならないだろう */
j ++;
}
}
for(i = 0; i < rr_sect; i++){
if(table[i])
break;
}
if(i == rr_sect) /* error sector is not recorded */
return(1);
else
return(0);
}
int get_bad_clust_num()
{
int i, bad = 0;
if(des_32bit){
for(i = 0; i < 80; i ++){
if(*(ulong *)(bad_clust + 4*i))
bad ++;
else
break;
}
}else{
for(i = 0; i < 80; i ++){
if(*(uint *)(bad_clust + 2*i))
bad ++;
else
break;
}
}
return(bad);
}
void rewrite_old(char *dest, ulong old_clust, uint dir_clust, char *dest_dpb)
{ /* xxxx.DAT の FAT の作成 32bit FAT 以外では dir_clust = 1 */
ulong sect, ssect, max_clust;
uint sect_p_fat, rr_sect, sect_size;
if(old_clust == dir_clust + 1)
return;
sect_size = *(uint *)dest_dpb;
sect_p_fat = *(uint *)(dest_dpb + S_P_FAT);
max_clust = *(ulong *)(dest_dpb + MAX_C) +1;
if(des_32bit){
ssect = (old_clust*4) / (ulong)sect_size;
sect = ssect + (ulong)(*(uint *)(dest_dpb + FAT_S));
if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,READ))
disp_msg(33, "", dest);
*(ulong *)(buf + (uint)(old_clust*4L - ssect*sect_size)) = 0L;
if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
ext_abs_read_write(*dest-'A'+1,1,sect+sect_p_fat,buf,WRITE);
resetdisk();
sect = (ulong)(*(uint *)(dest_dpb + FAT_S));
if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,READ))
disp_msg(33, "", dest);
*(ulong *)(buf + (uint)((dir_clust + 1)*4)) = 0x0fffffffL;
if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
ext_abs_read_write(*dest-'A'+1,1,sect+sect_p_fat,buf,WRITE);
resetdisk();
}else{
if(max_clust <= (ulong)0xff4){ /* 12bit_fat */
sect = (ulong)(*(uint *)(dest_dpb + FAT_S));
rr_sect = (uint)div_upper((max_clust*3 +1)/ 2 ,
(ulong)(*(uint *)dest_dpb));
if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
buf[(uint)((old_clust*3))/ 2] = 0;
buf[((uint)(old_clust*3)/2) +1] = 0;
if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest -'A',rr_sect,sect +sect_p_fat,buf, WRITE);
resetdisk();
if(abs_read_write(*dest-'A',1,sect,buf,READ))
disp_msg(33, "", dest);
buf[4] = (uchar)(buf[4] & 0x0f0) + (uchar)0xf;
buf[3] = (uchar)(0x0ff);
if(abs_read_write(*dest -'A',1,sect,buf, WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest -'A',1,sect +sect_p_fat,buf, WRITE);
resetdisk();
}else{
ssect = (old_clust*2L) / (ulong)sect_size;
sect = ssect + (ulong)(*(uint *)(dest_dpb + FAT_S));
if(abs_read_write(*dest-'A',1,sect,buf,READ))
disp_msg(33, "", dest);
*(uint *)(buf + (uint)(old_clust*2L - ssect*sect_size)) = 0;
if(abs_read_write(*dest-'A',1,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest-'A',1,sect+sect_p_fat,buf,WRITE);
resetdisk();
sect = (ulong)(*(uint *)(dest_dpb + FAT_S));
if(abs_read_write(*dest-'A',1,sect,buf,READ))
disp_msg(33, "", dest);
*(uint *)(buf + 2) = 0xffff;
if(abs_read_write(*dest-'A',1,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest-'A',1,sect+sect_p_fat,buf,WRITE);
resetdisk();
}
}
}
void rewrite_fat_to0(char *dest, char *dest_dpb)
{ /* dest の最初の部分以外の FAT の中身を 0 にする */
ulong sect;
uint i, j, sect_size, sect_p_fat, start_num,
mult_K, r_sect, rest_sect;
sect_p_fat = *(uint *)(dest_dpb + S_P_FAT);
sect_size = *(uint *)dest_dpb;
mult_K = (uint)(((ulong)sect_size * (ulong)sect_p_fat) / 0x6000);
/* 0x6000 は 0x8000以下で3の倍数で選んだ */
rest_sect = sect_p_fat - (0x6000 / sect_size)*mult_K;
r_sect = 0x6000 / sect_size;
for(i = 0; i < mult_K; i++){
sect = (ulong)r_sect * (ulong)i;
sect += (ulong)(*(uint *)(dest_dpb + FAT_S));
if(do_read_write(*dest, r_sect, sect, buf, des_32bit, READ))
disp_msg(33, "", dest);
if(i == 0)
start_num = 4; /* 12 bit FAT もこれで行く */
else
start_num = 0;
for(j = start_num; j < (0x6000 / 4); j++)
*(ulong *)(buf + 4*j) = 0L;
if(do_read_write(*dest, r_sect, sect, buf, des_32bit, WRITE))
disp_msg(33, "", dest);
resetdisk();
do_read_write(*dest, r_sect, sect +sect_p_fat, buf, des_32bit, WRITE);
resetdisk();
}
if(rest_sect){
sect = (ulong)r_sect * (ulong)mult_K;
sect += (ulong)(*(uint *)(dest_dpb + FAT_S));
if(do_read_write(*dest, rest_sect, sect, buf, des_32bit, READ))
disp_msg(33, "", dest);
if(mult_K == 0)
start_num = 4; /* 12 bit FAT もこれで行く */
else
start_num = 0;
for(j = start_num; j < ((sect_size*rest_sect) / 4); j++)
*(ulong *)(buf + 4*j) = 0L;
if(do_read_write(*dest, rest_sect, sect, buf, des_32bit, WRITE))
disp_msg(33, "", dest);
resetdisk();
do_read_write(*dest, rest_sect, sect +sect_p_fat,buf,des_32bit,WRITE);
resetdisk();
}
}
void rewrite_fat(char *dest, ulong w_sect, ulong f_size, char *dest_dpb)
{
ulong last_clust, sect, clust_num, max_clust;
uint rr_sect, rest_fat, mult_K, num_clust,
i, j, start, start_clust, int_clust_num, s_p_fat,
w_s_size, fat_sect;
start_clust = (uint)sect2clust(dest_dpb, w_sect, des_32bit);
/* start_clust は十分小さいと想定 */
w_s_size = *(uint *)dest_dpb;
fat_sect = *(uint *)(dest_dpb + FAT_S);
sect = div_upper(f_size, (ulong)w_s_size);
last_clust = div_upper(sect, ((ulong)dest_dpb[C_MASK] +1));
last_clust-- ; /* 0,1,2,...,last_clust に記録する */
last_clust += start_clust;
s_p_fat = *(uint *)(dest_dpb + S_P_FAT);
if(des_32bit){
if(big_buf)
num_clust = (uint)(BUF_UNIT / 2);/* 1度に読む FATの cluster 数 */
else
num_clust = (uint)(BUF_UNIT / 4);
mult_K = (uint)(last_clust / (ulong)num_clust);
rest_fat = (uint)(last_clust - mult_K*(ulong)num_clust);
rr_sect = (uint)(buf_size / (ulong)w_s_size);
clust_num = start_clust + 1;
for(i = 0; i < mult_K; i++){
sect = (buf_size / (ulong)w_s_size) *i + (ulong)fat_sect;
if(ext_abs_read_write(*dest -'A'+1,rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
if(i == 0)
start = start_clust;
else
start = 0;
for(j = start; j < num_clust; j++){
*(ulong *)(buf + 4*j) = clust_num;
clust_num ++ ;
}
if(ext_abs_read_write(*dest -'A'+1,rr_sect,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
ext_abs_read_write(*dest -'A'+1,rr_sect,sect +s_p_fat, buf,WRITE);
resetdisk();
}
sect = (buf_size / (ulong)w_s_size)*mult_K + (ulong)fat_sect;
rr_sect = (uint)((rest_fat*4 + w_s_size) / (ulong)w_s_size);
if(ext_abs_read_write(*dest -'A' +1,rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
if(mult_K == 0)
start = start_clust;
else
start = 0;
for(j = start; j < rest_fat; j++){
*(ulong *)(buf + 4*j) = clust_num;
clust_num ++ ;
}
*(ulong *)(buf + 4*rest_fat) = 0x0fffffff; /* 終了 */
for(j = rest_fat + 1; j < num_clust; j++)
*(ulong *)(buf + 4*j) = 0;
if(ext_abs_read_write(*dest-'A'+1,rr_sect,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
ext_abs_read_write(*dest-'A'+1, rr_sect,sect +s_p_fat, buf, WRITE);
resetdisk();
}else{
max_clust = *(ulong *)(dest_dpb + MAX_C) +1; /* IPL, FAT部分加える */
int_clust_num = start_clust +1;
if(max_clust <= (ulong)0xff4){ /* 12bit_fat */
num_clust = 0x4000; /* 1度に読む FATの cluster 数 */
/* buffer に 0x6000 必要 */
mult_K = (uint)(last_clust / (ulong)num_clust);
rr_sect = (uint)(0x6000L / (ulong)w_s_size);
rest_fat = (uint)(last_clust - mult_K*(ulong)num_clust);
for(i = 0; i < mult_K; i++){
sect = (ulong)fat_sect + (ulong)rr_sect*i;
if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
for(j = start_clust; j < (uint)num_clust; j++){
if(j & 1){ /* 奇数なら */
buf[(j*3)/ 2] = (uchar)(buf[(j*3)/ 2] & 0x00f)
+ (uchar)((int_clust_num & 0x00f) << 4);
buf[((j*3)/2) +1]=(uchar)((int_clust_num & 0xff0) >>4);
int_clust_num ++;
}else{ /* 偶数なら */
buf[((j*3)/ 2) +1] =(uchar)(buf[((j*3)/ 2) +1] & 0x0f0)
+ (uchar)((int_clust_num & 0xf00) >> 8);
buf[((j*3)/ 2)] = (uchar)(int_clust_num & 0x0ff);
int_clust_num ++;
}
}
if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest-'A',rr_sect,sect +s_p_fat, buf,WRITE);
resetdisk();
}
sect = (ulong)fat_sect + rr_sect*mult_K;
rr_sect = (uint)div_upper(((ulong)rest_fat*3 + 1) /2,
(ulong)(*(uint *)dest_dpb));
if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
if(mult_K == 0)
start = start_clust;
else
start = 0;
for(j = start; j < rest_fat; j++){
if(j & 1){ /* 奇数なら */
buf[(j*3)/ 2] = (uchar)(buf[(j*3)/ 2] & 0x00f)
+ (uchar)((int_clust_num & 0x00f) << 4);
buf[((j*3)/2) +1]=(uchar)((int_clust_num & 0xff0) >>4);
int_clust_num ++;
}else{ /* 偶数なら */
buf[((j*3)/ 2) +1] =(uchar)(buf[((j*3)/ 2) +1] & 0x0f0)
+ (uchar)((int_clust_num & 0xf00) >> 8);
buf[((j*3)/ 2)] = (uchar)(int_clust_num & 0x0ff);
int_clust_num ++;
}
}
if(rest_fat & 1){ /* 最終マーク 奇数なら */
buf[(rest_fat*3)/ 2] = (uchar)(buf[(rest_fat*3)/ 2] & 0x00f)
+ (uchar)0x00f0;
buf[((rest_fat*3)/2) +1] = (uchar)(0x0ff);
}else{ /* 最終マーク 偶数なら */
buf[((rest_fat*3)/ 2) +1] = (uchar)(0x00f);
buf[((rest_fat*3)/ 2)] = (uchar)0x0ff;
}
for(j = rest_fat + 1; j < num_clust; j++){
if(j & 1){ /* 奇数なら */
buf[(j*3)/ 2] = (uchar)(buf[(j*3)/ 2] & 0x00f);
buf[((j*3)/2) +1] = 0;
}else{ /* 偶数なら */
buf[((j*3)/ 2) +1] =(uchar)(buf[((j*3)/ 2) +1] & 0x0f0);
buf[((j*3)/ 2)] = 0;
}
}
if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest-'A',rr_sect,sect +s_p_fat, buf,WRITE);
resetdisk();
}else{ /* 16bit_fat */
if(big_buf)
num_clust = (uint)BUF_UNIT; /* 1度に読む FATの cluster 数 */
else
num_clust = (uint)(BUF_UNIT / 2);
mult_K = (uint)(last_clust/ num_clust);
rest_fat = (uint)(last_clust - mult_K*num_clust);
rr_sect = (uint)(buf_size / (ulong)w_s_size);
for(i = 0; i < mult_K; i++){
sect = (buf_size / (ulong)w_s_size)*i + (ulong)fat_sect;
if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
if(i == 0)
start = start_clust;
else
start = 0;
for(j = start; j < num_clust; j++){
*(uint *)(buf + 2*j) = int_clust_num;
int_clust_num ++ ;
}
if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest-'A',rr_sect,sect +s_p_fat,buf,WRITE);
resetdisk();
}
sect = (buf_size / (ulong)w_s_size)*mult_K + (ulong)fat_sect;
rr_sect = (uint)((rest_fat*2 + w_s_size) / (ulong)w_s_size);
if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
disp_msg(33, "", dest);
if(mult_K == 0)
start = start_clust;
else
start = 0;
for(j = start; j < rest_fat; j++){
*(uint *)(buf + 2*j) = int_clust_num;
int_clust_num ++ ;
}
*(uint *)(buf + 2*rest_fat) = 0xffff; /* 終了 */
for(j = rest_fat + 1; j < num_clust; j++)
*(uint *)(buf + 2*j) = 0;
if(abs_read_write(*dest-'A',rr_sect,sect,buf,WRITE))
disp_msg(33, "", dest);
resetdisk();
abs_read_write(*dest-'A',rr_sect,sect +s_p_fat,buf,WRITE);
resetdisk();
}
}
}
void write_null_dir_entry(char *d_d, char *dest_dpb)
{ /* dest の directory entry を 0 で埋める */
ulong i, sect;
uint sect_size, need_sect, rest_sect, ww_sect, dir_entries, mult_K;
dir_entries = *(uint *)(dest_dpb + DIR_E);
sect_size = *(uint *)dest_dpb;
need_sect = (uint)div_upper((ulong)dir_entries, (ulong)(sect_size /32));
mult_K = (uint)(((ulong)need_sect*(ulong)sect_size) / buf_size);
rest_sect = need_sect - mult_K*(uint)(buf_size / sect_size);
for(i = 0; i < buf_size / 4; i++)
*(ulong *)(buf + 4*i) = 0L;
ww_sect = (uint)(buf_size / sect_size) ;
sect = (ulong)(*(uint *)(dest_dpb + FAT_S))
+ *(ulong *)(dest_dpb + S_P_FAT)*2L;
/* FAT_start_sect + Num_of_FAT*FAT_sect */
for(i = 0; i < mult_K; i++){
if(do_read_write(*d_d, ww_sect, sect, buf, des_32bit, WRITE))
disp_msg(33, "", d_d);
resetdisk();
sect += ww_sect;
}
if(rest_sect){
if(do_read_write(*d_d, rest_sect, sect, buf, des_32bit, WRITE))
disp_msg(33, "", d_d);
resetdisk();
}
}
uint get_used_dir_entry(char *source, char *so_dpb)
{
ulong dir_sect;
uint max_dir_entry, dir_entry = 0, sect_size;
int i, null_check = 0; /* dir entory 先頭の 00 を check */
if(so_32bit)
return(0);
else{
dir_sect = (ulong)(*(uint *)(so_dpb + FAT_S))
+ *(ulong *)(so_dpb + S_P_FAT)*2L;
max_dir_entry = *(uint *)(so_dpb + DIR_E);
sect_size = *(uint *)so_dpb;
while( (!null_check) && (dir_entry < max_dir_entry)){
if(do_read_write(*source, 1, dir_sect,buf,so_32bit,READ))
disp_msg(11, source, "");
resetdisk();
for(i = 0; i < (int)(sect_size / 32); i++){
if(buf[i*32] == 0){
null_check = 1;
break;
}else
dir_entry ++;
}
dir_sect++;
}
return(dir_entry);
}
}
void write_ipl(char *s_d, char *d_d, char *dest_dpb, char *check_buf,
char *f_name)
/* ipl は Win95 でも ipl の backup 迄は 32K 以内としておく */
{
FILE *stream;
uint i, fat_sect22, ipl_backup, ipl_backup2,
w_s_size = *(uint *)dest_dpb,
fat_sect = *(uint *)(check_buf +C_FAT_S),
fat_sect2 = *(uint *)(dest_dpb + FAT_S);
if(do_read_write(*d_d, 1, 0, buf, des_32bit, READ))
disp_msg(40, "", d_d);
resetdisk();
if(des_32bit){
ipl_backup = *(uint *)(check_buf +C_IPL_B);
ipl_backup2 = *(uint *)(buf +IPL_B);
}
printf("\nNow Writing IPL.\n");
if((stream = fopen(f_name, "rb")) == NULL)
disp_msg(24, s_d, d_d);
fseek(stream, 512, SEEK_SET);
if(!fread(buf, fat_sect*w_s_size, 1, stream))
disp_msg(22, s_d, d_d);
if(fclose(stream))
disp_msg(25, s_d, d_d);
resetdisk();
if(!des_32bit){
fat_sect22 = uintmax(fat_sect, fat_sect2);
if(do_read_write(*d_d, fat_sect22, 0, buf2, des_32bit, READ))
disp_msg(42, s_d, d_d);
for(i = 0x0e; i < 0x27; i++)
buf[i] = buf2[i];
if(fat_sect2 > fat_sect)
for(i = w_s_size*fat_sect; i < w_s_size*fat_sect2; i++)
buf[i] = 0;
if(do_read_write(*d_d, fat_sect2, 0, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
}else{
if(do_read_write(*d_d, ipl_backup2, 0, buf2, des_32bit, READ))
disp_msg(42, s_d, d_d);
for(i = 0x0e; i < 0x40; i++) /* 書き換え */
buf[i] = buf2[i];
if(ipl_backup < ipl_backup2){
for(i = w_s_size*ipl_backup; i < w_s_size*ipl_backup2;i++)
buf[i] = 0;
}
if(do_read_write(*d_d, ipl_backup2, 0, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, ipl_backup2, (ulong)ipl_backup2, buf, des_32bit,
WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
if(ipl_backup2*2 < fat_sect2){
for(i = 0; i < w_s_size*(fat_sect2 - ipl_backup2*2); i++)
buf[i] = 0;
if(do_read_write(*d_d, fat_sect2 - ipl_backup2*2, (ulong)(ipl_backup2*2), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
}
}
resetdisk();
}
void p_write_ipl(char *s_d, char *d_d, uint rr_sect, char *so_dpb,
char *dest_dpb, char *check_buf)
/* ipl は Win95 でも ipl の backup 迄は 32K 以内としておく */
{
ulong r_sect = *(ulong *)(check_buf + W_START_S);
uint i, fat_sect22, ipl_backup, ipl_backup2,
r_s_size = *(uint *)so_dpb, w_s_size = *(uint *)dest_dpb,
fat_sect = *(uint *)(check_buf +C_FAT_S),
fat_sect2 = *(uint *)(dest_dpb + FAT_S);
if(do_read_write(*d_d, 1, 0, buf, des_32bit, READ))
disp_msg(40, "", d_d);
resetdisk();
if(des_32bit){
ipl_backup = *(uint *)(check_buf +C_IPL_B);
ipl_backup2 = *(uint *)(buf +IPL_B);
}
printf("\nNow Writing IPL.\n");
if(do_read_write(*s_d, rr_sect, r_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(!des_32bit){
fat_sect22 = uintmax(fat_sect, fat_sect2);
if(do_read_write(*d_d, fat_sect22, 0, buf2, des_32bit, READ))
disp_msg(42, s_d, d_d);
for(i = 0x0e; i < 0x27; i++)
buf[i] = buf2[i];
if(fat_sect2 > fat_sect){
for(i = w_s_size*fat_sect; i < w_s_size*fat_sect2; i++)
buf[i] = 0;
}
if(do_read_write(*d_d, fat_sect2, 0, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
}else{
if(do_read_write(*d_d, ipl_backup2, 0, buf2, des_32bit, READ))
disp_msg(42, s_d, d_d);
for(i = 0x0e; i < 0x40; i++) /* 書き換え */
buf[i] = buf2[i];
if(ipl_backup < ipl_backup2){
for(i = w_s_size*ipl_backup; i < w_s_size*ipl_backup2;i++)
buf[i] = 0;
}
if(do_read_write(*d_d, ipl_backup2, 0, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, ipl_backup2, (ulong)ipl_backup2, buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
if(ipl_backup2*2 < fat_sect2){
for(i = 0; i < w_s_size*(fat_sect2 - ipl_backup2*2); i++)
buf[i] = 0;
if(do_read_write(*d_d, fat_sect2 - ipl_backup2*2, (ulong)(ipl_backup2*2), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
}
}
resetdisk();
}
void d_write_ipl(char *s_d, char *d_d, uint rw_sect, char *so_dpb,
char *dest_dpb, char *check_buf)
/* ipl は Win95 でも ipl の backup 迄は 32K 以内としておく */
{
uint i, fat_sect22, ipl_backup, ipl_backup2,
s_size = *(uint *)so_dpb,
fat_sect = *(uint *)(check_buf +C_FAT_S),
fat_sect2 = *(uint *)(dest_dpb + FAT_S);
if(do_read_write(*d_d, 1, 0, buf, des_32bit, READ))
disp_msg(40, "", d_d);
resetdisk();
if(des_32bit){
ipl_backup = *(uint *)(check_buf +C_IPL_B);
ipl_backup2 = *(uint *)(buf +IPL_B);
}
printf("\nNow Writing IPL.\n");
if(do_read_write(*s_d, rw_sect, 0, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(!des_32bit){
fat_sect22 = uintmax(fat_sect, fat_sect2);
if(do_read_write(*d_d, fat_sect22, 0, buf2, des_32bit, READ))
disp_msg(42, s_d, d_d);
for(i = 0x0e; i < 0x27; i++)
buf[i] = buf2[i];
if(fat_sect2 > fat_sect)
for(i = s_size*fat_sect; i < s_size*fat_sect2; i++)
buf[i] = 0;
if(do_read_write(*d_d, fat_sect2, 0, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
}else{
if(do_read_write(*d_d, ipl_backup2, 0, buf2, des_32bit, READ))
disp_msg(42, s_d, d_d);
for(i = 0x0e; i < 0x40; i++) /* 書き換え */
buf[i] = buf2[i];
if(ipl_backup < ipl_backup2){
for(i = s_size*ipl_backup; i < s_size*ipl_backup2;i++)
buf[i] = 0;
}
if(do_read_write(*d_d, ipl_backup2, 0, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, ipl_backup2, (ulong)ipl_backup2, buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
if(ipl_backup2*2 < fat_sect2){
for(i = 0; i < s_size*(fat_sect2 - ipl_backup2*2); i++)
buf[i] = 0;
if(do_read_write(*d_d, fat_sect2 - ipl_backup2*2, (ulong)(ipl_backup2*2), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
}
}
resetdisk();
}
void write_FAT(char *s_d, char *d_d, char *dest_dpb,
char *check_buf, char *f_name)
{
FILE *stream;
ulong used_clust, write_pos;
uint need_sect, mult_K, ww_sect, rest_sect,
w_s_size = *(uint *)dest_dpb,
fat_sect = *(uint *)(check_buf +C_FAT_S),
fat_sect2 = *(uint *)(dest_dpb + FAT_S);
int fat_type, i;
printf("Now Writing FAT.\n");
if(des_32bit)
fat_type = 32;
else if((*(ulong *)(check_buf + C_MAX_C) +1) <= 0xff4)
fat_type = 12;
else
fat_type = 16;
rewrite_fat_to0(d_d, dest_dpb);
used_clust = *(ulong *)(check_buf +USED_C);
switch(fat_type){
case 32:
need_sect = (uint)div_upper((used_clust +1)*4, (ulong)w_s_size);
break;
case 16:
need_sect = (uint)div_upper((used_clust +1)*2, (ulong)w_s_size);
break;
case 12:
need_sect = (uint)div_upper((used_clust*3 +1)/2, (ulong)w_s_size);
break;
}
ww_sect = (uint)(BUF_UNIT / w_s_size);
write_pos = (ulong)fat_sect2;
mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / BUF_UNIT);
rest_sect = need_sect - mult_K*(uint)(BUF_UNIT / w_s_size);
for(i = 0; i < mult_K; i++){
if((stream = fopen(f_name, "rb")) == NULL)
disp_msg(24, s_d, d_d);
fseek(stream, (ulong)(fat_sect+ (BUF_UNIT/w_s_size)*i)*w_s_size +512, SEEK_SET);
if(!fread(buf, (uint)BUF_UNIT, 1, stream))
disp_msg(22, s_d, d_d);
if(fclose(stream))
disp_msg(25, s_d, d_d);
if(i == 0){
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[0] = buf2[0]; /* 識別子書き換え */
}
if(do_read_write(*d_d, ww_sect, write_pos, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, ww_sect, write_pos + *(ulong *)(dest_dpb
+ S_P_FAT), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
write_pos += ww_sect;
resetdisk();
}
if(rest_sect){
if((stream = fopen(f_name, "rb")) == NULL)
disp_msg(24, s_d, d_d);
fseek(stream, (ulong)(fat_sect+ (BUF_UNIT/w_s_size)*mult_K)*w_s_size +512, SEEK_SET);
if(!fread(buf, rest_sect*w_s_size, 1, stream))
disp_msg(22, s_d, d_d);
if(fclose(stream))
disp_msg(25, s_d, d_d);
if(mult_K == 0){
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[0] = buf2[0]; /* 識別子書き換え */
}
if(do_read_write(*d_d, rest_sect, write_pos, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, rest_sect, write_pos + *(ulong *)(dest_dpb +
S_P_FAT), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
}
}
void p_write_FAT(char *s_d, char *d_d, uint rr_sect, char *so_dpb,
char *dest_dpb, char *check_buf)
{
ulong next_read_sect, used_clust, write_pos,
r_sect = *(ulong *)(check_buf + W_START_S);
uint ww_sect, need_sect, mult_K, rest_sect, residue, byte2next_s,
r_s_size = *(uint *)so_dpb, w_s_size = *(uint *)dest_dpb,
fat_sect = *(uint *)(check_buf +C_FAT_S),
fat_sect2 = *(uint *)(dest_dpb + FAT_S);
int fat_type, i;
ww_sect = (uint)(buf_size / (ulong)w_s_size);
printf("Now Writing FAT.\n");
if(des_32bit)
fat_type = 32;
else if((*(ulong *)(check_buf + C_MAX_C) +1) <= 0xff4)
fat_type = 12;
else
fat_type = 16;
rewrite_fat_to0(d_d, dest_dpb);
used_clust = *(ulong *)(check_buf +USED_C);
switch(fat_type){
case 32:
need_sect = (uint)div_upper((used_clust +1)*4, (ulong)w_s_size);
break;
case 16:
need_sect = (uint)div_upper((used_clust +1)*2, (ulong)w_s_size);
break;
case 12:
need_sect = (uint)div_upper((used_clust*3 +1)/2, (ulong)w_s_size);
break;
}
write_pos = (ulong)fat_sect2;
next_read_sect = (ulong)(w_s_size*fat_sect) / (ulong)r_s_size;
residue = (uint)(((ulong)w_s_size*fat_sect) % (ulong)r_s_size);
if(residue){ /* この時 r_s_size は w_s_sizeの倍数 */
/* 従って byte2next_s は w_s_size の倍数 */
byte2next_s = r_s_size - residue; /* 次のsectへの端数 */
if(do_read_write(*s_d, 1, r_sect +next_read_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[residue] = buf2[0]; /* 識別子書き換え */
if(do_read_write(*d_d,uintmin(need_sect,(uint)(byte2next_s /w_s_size)),
write_pos, buf + residue, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d,uintmin(need_sect,(uint)(byte2next_s /w_s_size)),
write_pos + *(ulong *)(dest_dpb + S_P_FAT), buf +residue, des_32bit,
WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
if((uint)(byte2next_s /w_s_size) >= need_sect)
return; /* もう書き込む必要はない */
next_read_sect++;
write_pos += byte2next_s / w_s_size;
need_sect -= byte2next_s / w_s_size;
}
mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / buf_size);
rest_sect = need_sect - mult_K*(uint)(buf_size / w_s_size);
for(i = 0; i < mult_K; i++){
if(do_read_write(*s_d, rr_sect, r_sect +next_read_sect, buf, so_32bit,
READ))
disp_msg(20, s_d, d_d);
if((i == 0) && !residue){
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[0] = buf2[0]; /* 識別子書き換え */
}
if(do_read_write(*d_d, ww_sect, write_pos, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, ww_sect, write_pos + *(ulong *)(dest_dpb
+ S_P_FAT), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
r_sect += rr_sect;
write_pos += ww_sect;
resetdisk();
}
if(rest_sect){
if(do_read_write(*s_d, (uint)div_upper((ulong)rest_sect*w_s_size,
(ulong)r_s_size), r_sect +next_read_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if((mult_K == 0) && !residue){
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[0] = buf2[0]; /* 識別子書き換え */
}
if(do_read_write(*d_d, rest_sect, write_pos, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, rest_sect, write_pos + *(ulong *)(dest_dpb +
S_P_FAT), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
}
}
void d_write_FAT(char *s_d, char *d_d, uint rw_sect, char *so_dpb,
char *dest_dpb, char *check_buf)
{
ulong r_sect, used_clust, write_pos;
uint need_sect, mult_K, rest_sect,
s_size = *(uint *)so_dpb,
fat_sect = *(uint *)(check_buf +C_FAT_S),
fat_sect2 = *(uint *)(dest_dpb + FAT_S);
int fat_type, i;
printf("Now Writing FAT.\n");
if(des_32bit)
fat_type = 32;
else if((*(ulong *)(check_buf + C_MAX_C) +1) <= 0xff4)
fat_type = 12;
else
fat_type = 16;
rewrite_fat_to0(d_d, dest_dpb);
used_clust = *(ulong *)(check_buf +USED_C);
switch(fat_type){
case 32:
need_sect = (uint)div_upper((used_clust +1)*4, (ulong)s_size);
break;
case 16:
need_sect = (uint)div_upper((used_clust +1)*2, (ulong)s_size);
break;
case 12:
need_sect = (uint)div_upper((used_clust*3 +1)/2, (ulong)s_size);
break;
}
write_pos = (ulong)fat_sect2;
r_sect = (ulong)fat_sect;
mult_K = (uint)((ulong)need_sect*(ulong)s_size / buf_size);
rest_sect = need_sect - mult_K*(uint)(buf_size / s_size);
for(i = 0; i < mult_K; i++){
if(do_read_write(*s_d, rw_sect, r_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(i == 0){
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[0] = buf2[0]; /* 識別子書き換え */
}
if(do_read_write(*d_d, rw_sect, write_pos, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, rw_sect, write_pos + *(ulong *)(dest_dpb
+ S_P_FAT), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
r_sect += rw_sect;
write_pos += rw_sect;
resetdisk();
}
if(rest_sect){
if(do_read_write(*s_d, rest_sect, r_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(mult_K == 0){
if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
disp_msg(33, s_d, d_d);
buf[0] = buf2[0]; /* 識別子書き換え */
}
if(do_read_write(*d_d, rest_sect, write_pos, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
if(do_read_write(*d_d, rest_sect, write_pos + *(ulong *)(dest_dpb +
S_P_FAT), buf, des_32bit,WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
}
}
void write_dir_entry(char *s_d, char *d_d, char *check_buf,
char *dest_dpb, char *f_name)
{
FILE *stream;
ulong read_dir_sect, w_sect;
uint ww_sect, need_sect, mult_K, rest_sect,
w_s_size = *(uint *)dest_dpb,
used_dir_ent = *(uint *)(check_buf + USED_D);
int i;
if(!used_dir_ent)
return;
ww_sect = (uint)(buf_size / (ulong)w_s_size);
printf("Now Writing Directry Entry.\n");
write_null_dir_entry(d_d, dest_dpb);
need_sect = (uint)div_upper((ulong)used_dir_ent, (ulong)(w_s_size /32));
w_sect = (ulong)(*(uint *)(dest_dpb + FAT_S))
+ *(ulong *)(dest_dpb + S_P_FAT)*2;
/* 書き込むsectの場所 FAT_start_sect + FAT_sect*2 */
read_dir_sect = (ulong)(*(uint *)(check_buf +C_FAT_S))
+ *(ulong *)(check_buf +C_S_P_FAT)*2;
mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / BUF_UNIT);
rest_sect = need_sect - mult_K*(uint)(BUF_UNIT / w_s_size);
for(i = 0; i < mult_K; i++){
if((stream = fopen(f_name, "rb")) == NULL)
disp_msg(24, s_d, d_d);
fseek(stream, read_dir_sect*(ulong)w_s_size +BUF_UNIT*i +512,SEEK_SET);
if(!fread(buf, (uint)BUF_UNIT, 1, stream))
disp_msg(22, s_d, d_d);
if(fclose(stream))
disp_msg(25, s_d, d_d);
if(do_read_write(*d_d, ww_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
w_sect += ww_sect;
resetdisk();
}
if(rest_sect){
if((stream = fopen(f_name, "rb")) == NULL)
disp_msg(24, s_d, d_d);
fseek(stream, read_dir_sect*(ulong)w_s_size +BUF_UNIT*mult_K +512, SEEK_SET);
if(!fread(buf, rest_sect*w_s_size, 1, stream))
disp_msg(22, s_d, d_d);
if(fclose(stream))
disp_msg(25, s_d, d_d);
if(do_read_write(*d_d, rest_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
}
resetdisk();
}
void p_write_dir_entry(char *s_d, char *d_d, uint rr_sect, char *check_buf,
char *so_dpb, char *dest_dpb)
{
ulong so_read_sect_off, read_dir_sect, w_sect,
r_sect = *(ulong *)(check_buf + W_START_S);
uint ww_sect, need_sect, residue, byte2next_s, mult_K, rest_sect,
r_s_size = *(uint *)so_dpb, w_s_size = *(uint *)dest_dpb,
used_dir_ent = *(uint *)(check_buf + USED_D);
int i;
if(!used_dir_ent)
return;
ww_sect = (uint)(buf_size / (ulong)w_s_size);
printf("Now Writing Directry Entry.\n");
write_null_dir_entry(d_d, dest_dpb);
need_sect = (uint)div_upper((ulong)used_dir_ent, (ulong)(w_s_size /32));
w_sect = (ulong)(*(uint *)(dest_dpb + FAT_S))
+ *(ulong *)(dest_dpb + S_P_FAT)*2;
/* 書き込むsectの場所 FAT_start_sect + FAT_sect*2 */
read_dir_sect = (ulong)(*(uint *)(check_buf +C_FAT_S))
+ *(ulong *)(check_buf +C_S_P_FAT)*2;
so_read_sect_off = (read_dir_sect*w_s_size) / r_s_size;
residue = (uint)(((ulong)w_s_size*read_dir_sect) % (ulong)r_s_size);
if(residue){ /* この時 r_s_size は w_s_sizeの倍数 */
/* 従って byte2next_s は w_s_size の倍数 */
byte2next_s = r_s_size - residue; /* 次のsectへの端数 */
if(do_read_write(*s_d,1,r_sect +so_read_sect_off, buf, so_32bit,READ))
disp_msg(20, s_d, d_d);
if(do_read_write(*d_d,uintmin(need_sect,(uint)(byte2next_s /w_s_size)),
w_sect, buf +residue, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
resetdisk();
if((uint)(byte2next_s /w_s_size) >= need_sect)
return; /* もう書き込む必要はない */
so_read_sect_off++;
w_sect += byte2next_s / w_s_size;
need_sect -= byte2next_s / w_s_size;
}
mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / buf_size);
rest_sect = need_sect - mult_K*(uint)(buf_size / w_s_size);
for(i = 0; i < mult_K; i++){
if(do_read_write(*s_d, rr_sect, r_sect +so_read_sect_off, buf,
so_32bit, READ))
disp_msg(20, s_d, d_d);
if(do_read_write(*d_d, ww_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
r_sect += rr_sect;
w_sect += ww_sect;
resetdisk();
}
if(rest_sect){
if(do_read_write(*s_d, (uint)div_upper((ulong)rest_sect*
(ulong)w_s_size, (ulong)r_s_size), r_sect +so_read_sect_off, buf,
so_32bit, READ))
disp_msg(20, s_d, d_d);
if(do_read_write(*d_d, rest_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
}
resetdisk();
}
void d_write_dir_entry(char *s_d, char *d_d, uint rw_sect, char *check_buf,
char *so_dpb, char *dest_dpb)
{
ulong r_sect, w_sect;
uint need_sect, mult_K, rest_sect,
s_size = *(uint *)so_dpb,
used_dir_ent = *(uint *)(check_buf + USED_D);
int i;
if(!used_dir_ent)
return;
printf("Now Writing Directry Entry.\n");
write_null_dir_entry(d_d, dest_dpb);
need_sect = (uint)div_upper((ulong)used_dir_ent, (ulong)(s_size /32));
w_sect = (ulong)(*(uint *)(dest_dpb + FAT_S))
+ *(ulong *)(dest_dpb + S_P_FAT)*2;
/* 書き込むsectの場所 FAT_start_sect + FAT_sect*2 */
r_sect = (ulong)(*(uint *)(check_buf +C_FAT_S))
+ *(ulong *)(check_buf +C_S_P_FAT)*2;
mult_K = (uint)((ulong)need_sect*(ulong)s_size / buf_size);
rest_sect = need_sect - mult_K*(uint)(buf_size / s_size);
for(i = 0; i < mult_K; i++){
if(do_read_write(*s_d, rw_sect, r_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(do_read_write(*d_d, rw_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
r_sect += rw_sect;
w_sect += rw_sect;
resetdisk();
}
if(rest_sect){
if(do_read_write(*s_d, rest_sect, r_sect, buf, so_32bit, READ))
disp_msg(20, s_d, d_d);
if(do_read_write(*d_d, rest_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, s_d, d_d);
}
resetdisk();
}
void restore(char *source, char *dest, ulong start_sect)
{
FILE *stream;
struct find_t ffblk;
char file_name[80], check_buf[512], dest_dpb[22], ext_dest_dpb[63];
ulong w_sect, w_next_sect, w_f_next_sect, end_sect, w_end_sect,
data_sect, data_sect2, max_clust, data_size;
uint i, w_s_size, ww_sect, done, check_err_record, sect_p_clust;
int data_diff = 0, r_offset = 0, w_offset = 0,
first_time = 1, do_anyway = 0;
if(des_32bit){
if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
disp_msg(12, source, dest);
}else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
disp_msg(12, source, dest);
if(des_32bit)
shift_ext_dpb(dest_dpb, ext_dest_dpb);
else
shift_dpb(dest_dpb);
w_s_size = *(uint *)dest_dpb;
end_sect = clust2sect(dest_dpb, *(ulong *)(dest_dpb + MAX_C) +1);
ww_sect = (uint)(buf_size / (ulong)w_s_size);
do{
if(win95){
ioctrl_lock(*dest - 'A' +1, 0);
ioctrl_lock(*source - 'A' +1, 0);
}
set_file_name(file_name, source, start_sect, 2);
do{
done = _dos_findfirst(file_name, 0xff, &ffblk);
if(done)
disp_msg2(13, file_name, dest, 0);
}while(done);
if((stream = fopen(file_name, "rb")) == NULL)
disp_msg(24, source, dest);
if(!fread(check_buf, 512, 1, stream))
disp_msg(22, source, dest);
if(fclose(stream))
disp_msg(25, source, dest);
if(start_sect != *(ulong *)(check_buf + R_START_S))
disp_msg(17, file_name, dest);
if(end_sect < *(ulong *)(check_buf + R_END_S))
disp_msg(29, file_name, dest);
else
w_end_sect = *(ulong *)(check_buf + R_END_S);
data_sect = *(ulong *)(check_buf +C_DATA_S); /* backupのdata_sect */
data_sect2 = *(ulong *)(dest_dpb + DATA_S); /* destのdata_sect */
data_diff = data_sect2 - data_sect;
for(i = 0; i < 320; i++)
bad_clust[i] = check_buf[192 +i];
bad_clust_num = get_bad_clust_num();
if(bad_clust_num)
disp_warn(3, dest);
resetdisk();
if(first_time){ /* 最初1回だけ check */
switch(check_disk_format(dest_dpb, check_buf)){
case 0:
disp_msg(16, source, dest);
break;
case 1:
rewrite_flag = 0;
break;
case 2:
sect_p_clust = *(uint *)(check_buf +C_SECT_C);
max_clust = *(ulong *)(check_buf +C_MAX_C) -1;
if(w_s_size > 1024)
data_size = max_clust * sect_p_clust
* (ulong)(w_s_size / 1024);
else
data_size = (max_clust * sect_p_clust)
/ (ulong)(1024 / w_s_size);
if(!disp_msg3(data_size)){
ybeep();
exit_routine(40);
}
if(!check_dir_entry_etc(dest_dpb, check_buf))
disp_msg(39, source, dest);
else
rewrite_flag = 1;
break;
}
}
if(rewrite_flag){
if(end_sect < w_end_sect + data_diff)
disp_msg(45, source, dest);
}
if((rewrite_flag) && (start_sect < data_sect)){
if(start_sect != 0)
disp_msg(41, source, dest);
write_ipl(source, dest, dest_dpb, check_buf, file_name);
write_FAT(source, dest, dest_dpb, check_buf, file_name);
write_dir_entry(source, dest, check_buf, dest_dpb, file_name);
r_offset = data_sect;
w_offset = data_sect2;
}else{
r_offset = 0;
w_offset = data_diff;
}
w_next_sect = *(ulong *)(check_buf + R_NEXT_S) + data_diff;
w_f_next_sect = w_next_sect - w_offset - start_sect
- ((w_next_sect - w_offset - start_sect) % ww_sect);
w_f_next_sect += w_offset + start_sect;
/* ここでは,w_sect 等は書き込む sector */
printf("\nNow Restoring from File %s\n", file_name);
printf(" [Write to Sectors %lu - %lu ]\n\n", start_sect +w_offset, w_next_sect - 1);
for(w_sect = start_sect + w_offset; w_sect < w_f_next_sect;
w_sect += ww_sect){
check_user_break(source, dest);
printf("Writing Sectors %lu - %lu \n",w_sect,w_sect +ww_sect -1);
if((stream = fopen(file_name, "rb")) == NULL)
disp_msg(24, source, dest);
fseek(stream, (ulong)w_s_size*(w_sect -start_sect -data_diff)
+512, SEEK_SET);
if(!fread(buf, (uint)BUF_UNIT, 1, stream))
disp_msg(22, source, dest);
if(big_buf){
if(!fread(buf + BUF_UNIT, (uint)BUF_UNIT, 1, stream))
disp_msg(22, source, dest);
}
if(fclose(stream))
disp_msg(25, source, dest);
if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, WRITE)){
/* 以下は rewrite の時は,break するように */
/* make_bad_sect_table を定義している */
check_err_record = make_bad_sect_table(dest_dpb,ww_sect,w_sect,
bad_table,des_32bit);
if(check_err_record && !do_anyway){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < ww_sect; i++){
if(!bad_table[i]){
if(do_read_write(*dest, 1, w_sect +i,
buf + w_s_size*i, des_32bit, WRITE)){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < ww_sect; i++)
do_read_write(*dest, 1, w_sect +i,
buf + w_s_size*i, des_32bit, WRITE);
}
}
resetdisk();
}
if(w_f_next_sect != w_next_sect){
check_user_break(source, dest);
printf("Writing Sectors %lu - %lu \n", w_sect, w_next_sect -1);
if((stream = fopen(file_name, "rb")) == NULL)
disp_msg(24, source, dest);
fseek(stream, (ulong)w_s_size*(w_sect -start_sect -data_diff)
+ 512, SEEK_SET);
if(big_buf && ((w_next_sect - w_f_next_sect)*(ulong)(w_s_size))
> BUF_UNIT){
if(!fread(buf, (uint)BUF_UNIT, 1, stream))
disp_msg(22, source, dest);
if(!fread(buf + BUF_UNIT, (uint)((w_next_sect
- w_f_next_sect)*(ulong)(w_s_size)) -(uint)BUF_UNIT,1,stream))
disp_msg(22, source, dest);
}else{
if(!fread(buf, (uint)((w_next_sect - w_f_next_sect)*
(ulong)(w_s_size)), 1, stream))
disp_msg(22, source, dest);
}
if(fclose(stream))
disp_msg(25, source, dest);
if(do_read_write(*dest, (uint)(w_next_sect - w_f_next_sect),
w_sect, buf, des_32bit, WRITE)){
/* 以下は rewrite の時は,break するように */
/* make_bad_sect_table を定義している */
check_err_record = make_bad_sect_table(dest_dpb, (uint)
(w_next_sect-w_f_next_sect),w_f_next_sect,bad_table,des_32bit);
if(check_err_record && !do_anyway){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++){
if(!bad_table[i]){
if(do_read_write(*dest, 1, w_f_next_sect +i,
buf + w_s_size*i, des_32bit, WRITE)){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++)
do_read_write(*dest, 1, w_f_next_sect +i,
buf + w_s_size*i, des_32bit, WRITE);
}
}
resetdisk();
}
start_sect = w_next_sect -data_diff;
first_time = 0;
if(start_sect < w_end_sect){
set_file_name(file_name, source, start_sect, 2);
if((stream = fopen(file_name, "rb")) == NULL){
ybeep();
ybeep();
ybeep();
ybeep();
disp_msg2(8, source, dest, 0);
resetdisk();
}else
fclose(stream);
}
}while(start_sect < w_end_sect);
if(des_32bit && rewrite_flag)
reset_free_clust(dest, w_s_size);
}
void p_restore(char *source, char *dest, ulong start_sect)
{
FILE *stream;
struct find_t ffblk;
char file_name[80], check_buf[512],
dest_dpb[22], so_dpb[22], ext_dest_dpb[63], ext_so_dpb[63];
ulong r_sect, w_sect, w_next_sect, w_f_next_sect,
w_end_sect, end_sect, data_size, max_clust,
data_sect, data_sect2, next_read_sect, offset;
uint ww_sect, rr_sect, r_s_size, w_s_size, done, i,
check_err_record, sect_p_clust, residue, byte2next_s = 0;
int data_diff, w_offset = 0, r_offset = 0, r_diff_s = 0, w_diff_s = 0,
first_time = 1, do_anyway = 0;
if(des_32bit){
if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
disp_msg(12, source, dest);
}else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
disp_msg(12, source, dest);
if(des_32bit)
shift_ext_dpb(dest_dpb, ext_dest_dpb);
else
shift_dpb(dest_dpb);
w_s_size = *(uint *)dest_dpb;
end_sect = clust2sect(dest_dpb, *(ulong *)(dest_dpb + MAX_C) +1);
ww_sect = (uint)(buf_size / (ulong)w_s_size);
resetdisk();
do{
if(win95){
ioctrl_lock(*dest - 'A' +1, 0);
ioctrl_lock(*source - 'A' +1, 0);
}
set_file_name(file_name, source, start_sect, 1);
do{
done = _dos_findfirst(file_name, 0xff, &ffblk);
if(done)
disp_msg2(13, file_name, dest, 0);
}while(done);
if((stream = fopen(file_name, "rb")) == NULL)
disp_msg(24, source, dest);
if(!fread(check_buf, 512, 1, stream))
disp_msg(22, source, dest);
if(fclose(stream))
disp_msg(25, source, dest);
if(so_32bit){
if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
disp_msg(11, source, dest);
}else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
disp_msg(11, source, dest);
if(so_32bit)
shift_ext_dpb(so_dpb, ext_so_dpb);
else
shift_dpb(so_dpb);
if(start_sect != *(ulong *)(check_buf + R_START_S))
disp_msg(17, file_name, dest);
if(end_sect < *(ulong *)(check_buf + R_END_S))
disp_msg(29, file_name, dest);
else
w_end_sect = *(ulong *)(check_buf + R_END_S);
data_sect = *(ulong *)(check_buf +C_DATA_S); /* backupのdata_sect */
data_sect2 = *(ulong *)(dest_dpb + DATA_S); /* destのdata_sect */
data_diff = data_sect2 - data_sect;
r_s_size = *(uint *)so_dpb;
r_sect = *(ulong *)(check_buf + W_START_S);
rr_sect = (uint)(buf_size / (ulong)r_s_size);
for(i = 0; i < 320; i++)
bad_clust[i] = check_buf[192 +i];
bad_clust_num = get_bad_clust_num();
if(bad_clust_num)
disp_warn(3, dest);
resetdisk();
if(first_time){ /* 最初1回だけ check */
switch(check_disk_format(dest_dpb, check_buf)){
case 0:
disp_msg(16, source, dest);
break;
case 1:
rewrite_flag = 0;
break;
case 2:
sect_p_clust = *(uint *)(check_buf +C_SECT_C);
max_clust = *(ulong *)(check_buf +C_MAX_C) -1;
if(w_s_size > 1024)
data_size = max_clust * sect_p_clust
* (ulong)(w_s_size / 1024);
else
data_size = (max_clust * sect_p_clust)
/ (ulong)(1024 / w_s_size);
if(!disp_msg3(data_size)){
ybeep();
exit_routine(40);
}
if(!check_dir_entry_etc(dest_dpb, check_buf))
disp_msg(39, source, dest);
else
rewrite_flag = 1;
break;
}
}
if(rewrite_flag){
if(end_sect < w_end_sect + data_diff)
disp_msg(45, source, dest);
}
if(rewrite_flag && (start_sect < data_sect)){
if(start_sect != 0)
disp_msg(41, source, dest);
p_write_ipl(source, dest, rr_sect, so_dpb, dest_dpb, check_buf);
p_write_FAT(source, dest, rr_sect, so_dpb, dest_dpb, check_buf);
p_write_dir_entry(source,dest,rr_sect,check_buf, so_dpb, dest_dpb);
residue = (uint)(((ulong)w_s_size*data_sect) % (ulong)r_s_size);
next_read_sect = (ulong)(w_s_size*data_sect) / (ulong)r_s_size;
if(residue){ /* この時 r_s_size は w_s_sizeの倍数 */
/* 従って byte2next_s は w_s_size の倍数 */
byte2next_s = r_s_size - residue; /* 次のsectへの端数 */
if(do_read_write(*source, 1, r_sect +next_read_sect, buf,
so_32bit, READ))
disp_msg(20, source, dest);
if(do_read_write(*dest, (uint)(byte2next_s / w_s_size),
data_sect2, buf +residue, des_32bit, WRITE))
disp_msg(21, source, dest);
r_diff_s = 1;
w_diff_s = byte2next_s / w_s_size;
}
r_offset = r_diff_s + (w_s_size*data_sect)/ r_s_size;
w_offset = w_diff_s + data_sect2;
}else{
r_offset = 0;
w_offset = data_diff;
}
w_next_sect = *(ulong *)(check_buf + R_NEXT_S) + data_diff;
w_f_next_sect = w_next_sect - w_offset - start_sect
- ((w_next_sect - w_offset - start_sect) % ww_sect);
w_f_next_sect += w_offset + start_sect;
/* ここでは,w_sect 等は書き込む sector */
set_file_name(file_name, source, start_sect, 0);
printf("\nNow Restoring from File %s\n", file_name);
printf(" [Write to Sectors %lu - %lu ]\n\n", start_sect +w_offset, w_next_sect - 1);
for(w_sect = start_sect +w_offset; w_sect < w_f_next_sect;
w_sect += ww_sect){
check_user_break(source, dest);
printf("Writing Sectors %lu - %lu \n",w_sect, w_sect +ww_sect-1);
if(do_read_write(*source,rr_sect,r_sect +r_offset, buf, so_32bit,
READ))
disp_msg(20, source, dest);
r_sect += rr_sect;
if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, WRITE)){
/* 以下は rewrite の時は,break するように */
/* make_bad_sect_table を定義している */
check_err_record = make_bad_sect_table(dest_dpb,ww_sect,w_sect,
bad_table,des_32bit);
if(check_err_record && !do_anyway){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < ww_sect; i++){
if(!bad_table[i]){
if(do_read_write(*dest, 1, w_sect +i,
buf + w_s_size*i, des_32bit, WRITE)){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < ww_sect; i++)
do_read_write(*dest, 1, w_sect +i,
buf + w_s_size*i, des_32bit, WRITE);
}
}
resetdisk();
}
if(w_f_next_sect != w_next_sect){ /* ここでは w_sect=w_f_next_sect */
check_user_break(source, dest);
printf("Writing Sectors %lu - %lu \n", w_sect, w_next_sect -1);
if(do_read_write(*source, (uint)div_upper(((w_next_sect
-w_f_next_sect)*w_s_size), (ulong)r_s_size), r_sect +r_offset,
buf, so_32bit, READ))
disp_msg(20, source, dest);
if(do_read_write(*dest, (uint)(w_next_sect -w_f_next_sect),
w_sect, buf, des_32bit, WRITE)){
/* 以下は rewrite の時は,break するように */
/* make_bad_sect_table を定義している */
check_err_record = make_bad_sect_table(dest_dpb, (uint)
(w_next_sect-w_f_next_sect),w_f_next_sect,bad_table,des_32bit);
if(check_err_record && !do_anyway){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++){
if(!bad_table[i]){
if(do_read_write(*dest, 1, w_f_next_sect +i,
buf + w_s_size*i, des_32bit, WRITE)){
disp_msg2(12, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++)
do_read_write(*dest, 1, w_f_next_sect +i,
buf + w_s_size*i, des_32bit, WRITE);
}
}
resetdisk();
}
start_sect = w_next_sect -data_diff;
first_time = 0;
if(start_sect < w_end_sect){
ybeep();
ybeep();
ybeep();
ybeep();
disp_msg2(8, source, dest, 0);
resetdisk();
}
}while(start_sect < w_end_sect);
if(des_32bit && rewrite_flag)
reset_free_clust(dest, w_s_size);
}
void backup(char *source, char *dest, ulong start_sect)
/* 作る file の size は 1.25G + dest_sect_size 迄にする */
{
FILE *stream;
struct diskfree_t dtable;
char file_name[80], tmp[6], write_buf[512], t_buf[10],
so_dpb[22], ext_so_dpb[63];
ulong free_byte, sect, next_sect, f_next_sect, r_end_sect,
total_amount, r_max_sect, r_used_sect, r_next_sect,
avail_sect, rest_avail, last_clust, used_clust, f_length;
uint free_space_ok, r_s_size, w_s_size, d_s_p_clust,
i, rr_sect, check_err_record, comp_size, mult_K,
used_dir_entry;
int do_anyway = 0;
if(f_s_limit)
f_length = f_s_limit*1024 - 512; /* 512 は header 部分 */
else
f_length = FILE_LENGTH;
if(so_32bit){
if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
disp_msg(11, source, dest);
}else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
disp_msg(11, source, dest);
if(so_32bit)
shift_ext_dpb(so_dpb, ext_so_dpb);
else
shift_dpb(so_dpb);
r_s_size = *(uint *)so_dpb;
r_max_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
rr_sect = (uint)(buf_size / (ulong)r_s_size);
r_used_sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
if(!full_dump)
r_end_sect = r_used_sect;
else
r_end_sect = r_max_sect;
if(start_sect >= r_end_sect)
disp_msg(27, source, dest);
if(bad_clust_num > 80){
disp_msg2(10, source, dest, 0);
do_anyway = 1; /* 強制実行 */
}else if(bad_clust_num)
disp_warn(1, source);
if(r_s_size > 1024)
total_amount = (r_end_sect +1)* (ulong)(r_s_size / 1024);
else
total_amount = (r_end_sect +1)/ (ulong)(1024 / r_s_size);
used_dir_entry = get_used_dir_entry(source, so_dpb);
printf("Backup Amount is %ld K bytes (1 K = 1024)\n", total_amount);
/* 以下は write_buf の設定 */
strcpy(write_buf, "DiskDump Ver 3.0"); /* 16 文字 */
strcat(write_buf, " - "); /* 21 文字 */
if(so_32bit)
strcat(write_buf, " FAT32 "); /* 11 文字 */
else
strcat(write_buf, " FAT16 "); /* 11 文字 FAT12 も含む */
strcat(write_buf, "Total: "); /* 16 文字 */
sprintf(t_buf, "%.8lu", r_max_sect);
for(i = 0; i < 8; i++)
write_buf[16*3 + 7 + i] = t_buf[i];
strcat(write_buf, "Used: "); /* 16 文字 */
sprintf(t_buf, "%.8lu", r_used_sect);
for(i = 0; i < 8; i++)
write_buf[16*4 + 7 + i] = t_buf[i];
for (i = 0; i < 22; i++) /* so_dpb[21] はゴミ */
write_buf[80 +i] = so_dpb[i];
*(uint *)(write_buf + USED_D) = used_dir_entry;
*(ulong *)(write_buf + USED_C) = used_clust;
*(ulong *)(write_buf + R_START_S) = 0L; /* start_sect */
*(ulong *)(write_buf + R_NEXT_S) = 0L; /* r_next_sect */
/* 取り敢えず 0 を書き込む */
*(ulong *)(write_buf + W_START_S) = 0L; /* 使わない write_start_sect */
*(ulong *)(write_buf + R_END_S) = r_end_sect; /* read_end_sect */
if(win95)
ioctrl_lock(*source - 'A' +1, 0);
if(do_read_write(*source, 1, 0, buf, so_32bit, READ)) /* ipl read */
disp_msg(11, source, dest);
resetdisk();
for (i = 0; i < 64; i++)
write_buf[128 +i] = buf[i]; /* ipl */
*(uint *)(write_buf + C_SECT_C) = (uint)buf[13]; /* sect/clust */
*(uint *)(write_buf + 110) = 0; /* ゴミ */
for(i = 0; i < 320; i++)
write_buf[192 +i] = bad_clust[i];
do{
if(win95){
ioctrl_lock(*dest - 'A' +1, 0);
ioctrl_lock(*source - 'A' +1, 0);
}
do{
if(des_32bit){
tmp[0] = dest[0];
tmp[1] = ':';
tmp[2] = '\\';
tmp[3] = 0 ;
get_ext_dfree(tmp, ext_dfree);
w_s_size = (int)*(ulong *)(ext_dfree + 8);
d_s_p_clust = (int)*(ulong *)(ext_dfree + 4);
avail_sect = *(ulong *)(ext_dfree + 12); /* avail_clusters */
avail_sect *= (long)d_s_p_clust; /* avail_sect */
}else{
_dos_getdiskfree((uint)(*dest - 'A'+1), &dtable);
free_byte = (ulong)(dtable.sectors_per_cluster)*
(ulong)(dtable.bytes_per_sector)*
(ulong)(dtable.avail_clusters);
d_s_p_clust = (ulong)(dtable.sectors_per_cluster);
w_s_size = dtable.bytes_per_sector;
avail_sect = (ulong)(dtable.avail_clusters);
avail_sect *= (ulong)(dtable.sectors_per_cluster);
}
if(f_s_limit){
if(avail_sect >= div_upper(f_length + 512,(ulong)w_s_size))
free_space_ok = 1;
else if(avail_sect >= div_upper(((r_end_sect - start_sect
+ 1)*r_s_size), w_s_size))
free_space_ok = 1;
else
free_space_ok = 0;
}else{
if(avail_sect >= div_upper(0x10000L +512,(ulong)w_s_size))
/* 64K 以上 free space 必要,overlong 避ける為sect*/
free_space_ok = 1;
else if(avail_sect >= div_upper(((r_end_sect - start_sect
+ 1)*r_s_size), w_s_size))
free_space_ok = 1;
else
free_space_ok = 0;
}
if(!free_space_ok)
disp_msg2(6, source, dest, 0);
}while(!free_space_ok);
mult_K = (uint)(avail_sect / div_upper((f_length + 512),
(ulong)w_s_size));
/* 1.25G(+α) byte の file がいくつ取れるか */
/* 又は f_s_limit K byte の file がいくつ取れるか */
rest_avail = avail_sect - div_upper((f_length + 512),
(ulong)w_s_size)*mult_K;
if(f_s_limit){
if(rest_avail < r_end_sect-start_sect-(f_length /r_s_size)*mult_K)
rest_avail = 0;
}else{
if((rest_avail < div_upper(0x10000L +512,(ulong)w_s_size))
&&(rest_avail < r_end_sect-start_sect-(f_length /r_s_size)*mult_K))
rest_avail = 0; /* 64K の file が取れなければ無意味 */
}
if(rest_avail)
next_sect = (f_length /r_s_size)*mult_K
+ (rest_avail*w_s_size -512) /r_s_size + start_sect;
else
next_sect = (f_length /r_s_size)*mult_K +start_sect;
if(next_sect > r_end_sect)
next_sect = r_end_sect;
do{
set_file_name(file_name, dest, start_sect, 2);
if(mult_K)
r_next_sect = f_length / r_s_size + start_sect;
else
r_next_sect = (rest_avail*w_s_size -512)/r_s_size +start_sect;
if(r_next_sect > next_sect)
r_next_sect = next_sect;
f_next_sect = r_next_sect -start_sect
-((r_next_sect - start_sect) % rr_sect);
f_next_sect += start_sect;
printf("\nNow making file %s \n", file_name);
printf(" [Sectors %lu - %lu ]\n\n", start_sect, r_next_sect - 1);
if((stream = fopen(file_name, "wb")) == NULL)
disp_msg(24, source, dest);
*(ulong *)(write_buf + R_START_S) = start_sect;
*(ulong *)(write_buf + R_NEXT_S) = r_next_sect;
/* *(ulong *)(write_buf + W_START_S) = 0L; */
/* *(ulong *)(write_buf + R_END_S) = r_end_sect;既に書いている*/
sprintf(t_buf, "%.8lu", start_sect); /* From: xxxxxxx */
for(i = 0; i < 8; i++)
write_buf[17 +i] = t_buf[i];
sprintf(t_buf, "%.8lu", r_next_sect -1);/* To: yyyyyyyy */
for(i = 0; i < 8; i++)
write_buf[28 + i] = t_buf[i];
for(i = 0; i < 512; i++)
buf[i] = write_buf[i];
if(!fwrite(buf, 512, 1, stream))
disp_msg(23, source, dest);
if(fclose(stream))
disp_msg(25, source, dest);
for(sect = start_sect; sect < f_next_sect; sect += rr_sect){
check_user_break(source, dest);
printf("Dumping Sectors %lu - %lu \n", sect, sect +rr_sect -1);
if(do_read_write(*source,rr_sect,sect,buf,so_32bit,READ)){
check_err_record = make_bad_sect_table(so_dpb, rr_sect,
sect, bad_table,so_32bit);
if(check_err_record && !do_anyway){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < rr_sect; i++){
if(!bad_table[i]){
if(do_read_write(*source, 1, sect + i,
buf + r_s_size*i, so_32bit, READ)){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < rr_sect; i++)
do_read_write(*source, 1, sect + i,
buf + r_s_size*i, so_32bit, READ);
}
}
resetdisk();
if((stream = fopen(file_name, "ab+")) == NULL)
disp_msg(24, source, dest);
if(!fwrite(buf, (uint)BUF_UNIT, 1, stream))
disp_msg(23, source, dest);
if(big_buf){
if(!fwrite(buf + BUF_UNIT,(uint)BUF_UNIT,1,stream)){
disp_msg(23, source, dest);
}
}
fclose(stream);
if(verify){
stream = fopen(file_name, "ab+");
if(big_buf)
fseek(stream, - BUF_UNIT*2, SEEK_END);
else
fseek(stream, - BUF_UNIT, SEEK_END);
printf("Verifying\n");
if(!fread(buf2, (uint)BUF_UNIT, 1, stream))
disp_msg(30, source, dest);
if(big_buf){
comp_size = (uint)BUF_UNIT; /*intで比較の為半分に*/
if(!fread(buf2 + BUF_UNIT, (uint)BUF_UNIT,1, stream)){
disp_msg(30, source, dest);
}
}else
comp_size = (uint)(BUF_UNIT / 2);
if(do_compare(buf, buf2, comp_size))
disp_msg(30, source, dest);
fclose(stream);
}
}
if(f_next_sect != r_next_sect){
check_user_break(source, dest);
printf("Dumping Sectors %lu - %lu \n", f_next_sect,
r_next_sect -1);
if(do_read_write(*source,(uint)(r_next_sect
- f_next_sect), f_next_sect, buf, so_32bit, READ)){
check_err_record = make_bad_sect_table(so_dpb, (uint)
(r_next_sect -f_next_sect),f_next_sect,bad_table,so_32bit);
if(check_err_record && !do_anyway){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < (uint)(r_next_sect - f_next_sect); i++){
if(!bad_table[i]){
if(do_read_write(*source,1,f_next_sect +i
, buf + r_s_size*i, so_32bit, READ)){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < (uint)(r_next_sect - f_next_sect); i++)
do_read_write(*source, 1, f_next_sect +i,
buf + r_s_size*i, so_32bit, READ);
}
}
resetdisk();
if((stream = fopen(file_name, "ab+")) == NULL)
disp_msg(24, source, dest);
if(big_buf && ((r_next_sect-f_next_sect)*(ulong)(r_s_size))
> BUF_UNIT){
if(!fwrite(buf, (uint)BUF_UNIT, 1, stream))
disp_msg(23, source, dest);
if(!fwrite(buf + BUF_UNIT, (uint)((r_next_sect
-f_next_sect)*(ulong)r_s_size) - (uint)BUF_UNIT, 1,stream))
disp_msg(23, source, dest);
}else{
if(!fwrite(buf, (uint)((r_next_sect - f_next_sect)*
(ulong)r_s_size), 1, stream))
disp_msg(23, source, dest);
}
fclose(stream); /* 最終の close でerrorが出るので
error check なし */
if(verify){
comp_size =(uint)((r_next_sect-f_next_sect)*(r_s_size/2));
if((stream = fopen(file_name, "ab+")) == NULL)
disp_msg(24, source, dest);
printf("Verifying\n");
fseek(stream, -(ulong)(comp_size*2), SEEK_END);
if(big_buf && ((r_next_sect-f_next_sect)*(ulong)(r_s_size)) > BUF_UNIT){
if(!fread(buf2, (uint)BUF_UNIT, 1, stream))
disp_msg(30, source, dest);
if(!fread(buf2 + BUF_UNIT, (uint)((r_next_sect -f_next_sect)*(ulong)r_s_size) - (uint)BUF_UNIT, 1,stream))
disp_msg(30, source, dest);
}else{
if(!fread(buf2,(uint)((r_next_sect -f_next_sect)*
(ulong)r_s_size), 1, stream))
disp_msg(30, source, dest);
}
if(do_compare(buf, buf2, comp_size))
disp_msg(30, source, dest);
fclose(stream);
}
}
start_sect = r_next_sect;
if(mult_K)
mult_K --;
resetdisk();
}while(start_sect < next_sect);
start_sect = next_sect;
if(start_sect < r_end_sect){
ybeep();
ybeep();
ybeep();
ybeep();
disp_msg2(7, source, dest, 0);
resetdisk();
}
}while(start_sect < r_end_sect);
}
int check_next_dir_entry(char *t_buf, char *f_name)
{
int j;
if((uchar)t_buf[32] == (uchar)0xe5)
return (1);
if(t_buf[32] == 0)
return (1);
for(j = 0; j < 8; j++){
if(t_buf[32 + j] != f_name[j])
return(0);
}
if(t_buf[32 + 8] != 'D')
return(0);
if(t_buf[32 + 9] != 'D')
return(0);
if(t_buf[32 + 10] != '3')
return(0);
return(1);
}
void p_backup(char *source, char *dest, ulong start_sect)
{
FILE *stream;
char file_name[80], f_name[14], write_buf[512], t_buf[10],
so_dpb[22], dest_dpb[22], ext_so_dpb[63], ext_dest_dpb[63];
ulong free_byte, w_sect, w_end_sect, dir_sect, used_clust,
new_sect, old_clust, total_amount,
r_sect, r_next_sect, r_f_next_sect, r_end_sect,
r_max_sect, r_used_sect;
uint r_s_size, w_s_size, i, j, sect_p_fat,
used_dir_entry, dir_clust, rr_sect, ww_sect,
check_err_record;
int file_pos_ok = 1, label_skip = 0, do_anyway = 0;
if(so_32bit){
if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
disp_msg(11, source, dest);
}else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
disp_msg(11, source, dest);
if(so_32bit)
shift_ext_dpb(so_dpb, ext_so_dpb);
else
shift_dpb(so_dpb);
r_s_size = *(uint *)so_dpb;
r_max_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
rr_sect = (uint)(buf_size / (ulong)r_s_size);
r_used_sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
if(!full_dump)
r_end_sect = r_used_sect;
else
r_end_sect = r_max_sect;
if(start_sect >= r_end_sect)
disp_msg(27, source, dest);
if(bad_clust_num > 80){
disp_msg2(10, source, dest, start_sect);
do_anyway = 1; /* 強制実行 */
}else if(bad_clust_num)
disp_warn(1, source);
if(r_s_size > 1024)
total_amount = (r_end_sect +1) * (ulong)(r_s_size / 1024);
else
total_amount = (r_end_sect +1) / (ulong)(1024 / r_s_size);
used_dir_entry = get_used_dir_entry(source, so_dpb);
printf("Backup Amount is %ld K bytes (1 K = 1024)\n", total_amount);
/* 以下は write_buf の設定 */
strcpy(write_buf, "DiskDump Ver 3.0"); /* 16 文字 */
strcat(write_buf, " - "); /* 21 文字 */
if(so_32bit)
strcat(write_buf, " FAT32 "); /* 11 文字 */
else
strcat(write_buf, " FAT16 "); /* 11 文字 FAT12 も含む */
strcat(write_buf, "Total: "); /* 16 文字 */
sprintf(t_buf, "%.8lu", r_max_sect);
for(i = 0; i < 8; i++)
write_buf[16*3 + 7 + i] = t_buf[i];
strcat(write_buf, "Used: "); /* 16 文字 */
sprintf(t_buf, "%.8lu", r_used_sect);
for(i = 0; i < 8; i++)
write_buf[16*4 + 7 + i] = t_buf[i];
for (i = 0; i < 22; i++) /* so_dpb[21] はゴミ */
write_buf[80 +i] = so_dpb[i];
*(uint *)(write_buf + USED_D) = used_dir_entry;
*(ulong *)(write_buf + USED_C) = used_clust;
*(ulong *)(write_buf + R_START_S) = 0L; /* start_sect */
*(ulong *)(write_buf + R_NEXT_S) = 0L; /* r_next_sect */
/* 取り敢えず 0 を書き込む */
*(ulong *)(write_buf + W_START_S) = 0L; /* write_start_sect */
*(ulong *)(write_buf + R_END_S) = r_end_sect; /* read_end_sect */
if(win95)
ioctrl_lock(*source - 'A' +1, 0);
if(do_read_write(*source, 1, 0, buf, so_32bit, READ)) /* ipl read */
disp_msg(11, source, dest);
resetdisk();
for (i = 0; i < 64; i++)
write_buf[128 +i] = buf[i]; /* ipl */
*(uint *)(write_buf + C_SECT_C) = (uint)buf[13]; /* sect/clust */
*(uint *)(write_buf + 110) = 0; /* ゴミ */
for(i = 0; i < 320; i++)
write_buf[192 +i] = bad_clust[i];
do{
if(win95){
ioctrl_lock(*dest - 'A' +1, 0);
ioctrl_lock(*source - 'A' +1, 0);
}
if(des_32bit){
if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
disp_msg(12, source, dest);
}else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
disp_msg(12, source, dest);
if(des_32bit)
shift_ext_dpb(dest_dpb, ext_dest_dpb);
else
shift_dpb(dest_dpb);
sect_p_fat = *(uint *)(dest_dpb + S_P_FAT);
w_s_size = *(uint *)dest_dpb;
/* file_name と f_name は同じだが,file_name は full path */
set_file_name(file_name, dest, start_sect, 1);
sprintf(f_name, "%.8lu", start_sect);
strcat(f_name, ".DDD");
if((stream = fopen(file_name, "wb")) == NULL)
disp_msg(24, source, dest);
if(!fwrite(write_buf, 512, 1, stream)) /* 書いただけでは先頭 */
disp_msg(23, source, dest); /* cluster に入らないので */
if(fclose(stream)) /* 後で書き直す */
disp_msg(25, source, dest);
if(des_32bit){
/* root_dir の sector = (root_dir_entry -2)*cluster_par_sect
+ reserved_sect + sect_par_FAT*num_of_FAT */
dir_sect = clust2sect(dest_dpb, *(ulong *)(ext_dest_dpb +55));
dir_clust = *(uint *)(ext_dest_dpb + 55); /* 通常 2 */
}else{
/* root_dir の sector = reserved_sec + sect_par_FAT*num_of_FAT */
dir_sect = (ulong)(*(uint *)(dest_dpb + FAT_S))
+ *(ulong *)(dest_dpb + S_P_FAT)*2L;
dir_clust = 1; /* 32bit FAT との共通化の為 */
}
if(do_read_write(*dest,1,dir_sect,buf,des_32bit,READ))
disp_msg(12, source, dest);
if(buf[0x0b] != 0x0f){ /* not long file name */
if((buf[0x0b] & _A_VOLID) == _A_VOLID)
label_skip = 1;
}
for(j = 0; (j < 8) && file_pos_ok; j++){
if(buf[label_skip*32 +j] != f_name[j])
file_pos_ok = 0;
}
for(j = 8; (j < 11) && file_pos_ok; j++){
if(buf[label_skip*32 +j] != f_name[j +1])
file_pos_ok = 0;
}
if(file_pos_ok){ /* 次は,空か xxxx.DD3 */
if(!check_next_dir_entry(buf + label_skip*32, f_name))
file_pos_ok = 0;
}
if(!file_pos_ok)
disp_msg(12, source, dest);
/* 以下 directory entory 部分書き換え */
if(des_32bit){
for(i = 0; i < 4; i++)
t_buf[i]=buf[label_skip*32 +26 + i]; /* cluster 部分 */
old_clust = *(ulong *)t_buf;
*(int *)(buf + label_skip*32 +20) = 0;
*(int *)(buf + label_skip*32 +26) = dir_clust + 1;
/* XXX.DDD は dir_clust + 1 (通常 3) cluster を使う */
}else{
old_clust = (ulong)*(uint *)(buf + label_skip*32 +26);
*(int *)(buf + label_skip*32 + 26) = 2;
/* XXX.DDD は 2 cluster を使う */
}
new_sect=clust2sect(dest_dpb,(ulong)*(int *)(buf + label_skip*32 +26));
/* new_sect は 新しい XXX.DDD の sector int の値 */
for(j = 0; j < 8; j++)
buf[label_skip*32 +32 + j] = f_name[j];
buf[label_skip*32 +32 +8] = 'D';
buf[label_skip*32 +32 +9] = 'D';
buf[label_skip*32 +32 +10] = '3';
for(j = 11; j < 20; j++)
buf[label_skip*32 +32 +j] = buf[label_skip*32 +j];
*(int *)(buf + label_skip*32 +32 +20) = 0;
for(j = 22; j < 26; j++)
buf[32 + label_skip*32 +j] = buf[label_skip*32 +j];
if(des_32bit)
*(int *)(buf + label_skip*32 +32 +26) = dir_clust + 2;
/* XXX.DD3 は dir_clust + 2 (通常 4) cluster を使う */
else
*(int *)(buf + label_skip*32 +32 +26) = 3;
/* XXX.DD3 は 3 cluster を使う file size [buf + 32 +28] は後で */
w_sect = new_sect + (ulong)dest_dpb[C_MASK] + 1;
w_end_sect = clust2sect(dest_dpb, (*(ulong *)(dest_dpb +MAX_C) + 1));
if(w_s_size < r_s_size){
w_end_sect = (((w_end_sect - w_sect)*w_s_size) /r_s_size)
*(r_s_size /w_s_size);
w_end_sect += w_sect;
}
ww_sect = (uint)(buf_size / (ulong)w_s_size);
r_next_sect = start_sect
+ (ulong)(((w_end_sect - w_sect)*w_s_size)/r_s_size);
if(r_next_sect >= r_end_sect)
r_next_sect = r_end_sect;
r_f_next_sect = r_next_sect - ((r_next_sect - start_sect) % rr_sect);
*( ulong *)(buf+ label_skip*32 +32+28)
= (r_next_sect -start_sect)*(ulong)r_s_size;
/* 2G を越えても表示のみだからこのままにしておく */
for(i = (label_skip +2)*32; i < w_s_size; i++)
buf[i] = 0; /* xxx.DDD, xxx.DD3 以外を消す */
if(do_read_write(*dest,1,dir_sect,buf,des_32bit,WRITE))
disp_msg(12, source, dest);
resetdisk();
/* directory entory 部分書き換え終り */
rewrite_fat_to0(dest, dest_dpb);
rewrite_old(dest, old_clust, dir_clust, dest_dpb);
rewrite_fat(dest, w_sect, (r_next_sect - start_sect)
*(ulong)r_s_size, dest_dpb);
*(ulong *)(write_buf + R_START_S) = start_sect;
*(ulong *)(write_buf + R_NEXT_S) = r_next_sect;
*(ulong *)(write_buf + W_START_S) = w_sect;
sprintf(t_buf, "%.8lu", start_sect); /* From: xxxxxxx */
for(i = 0; i < 8; i++)
write_buf[17 +i] = t_buf[i];
sprintf(t_buf, "%.8lu", r_next_sect -1);/* To: yyyyyyyy */
for(i = 0; i < 8; i++)
write_buf[28 + i] = t_buf[i];
for(i = 0; i < 512; i++)
buf[i] = write_buf[i];
for(i = 512; i < w_s_size; i++)
buf[i] = 0; /* 書き込みをsect単位にするためにゴミ掃除 */
if(do_read_write(*dest,1,new_sect,buf,des_32bit,WRITE))
disp_msg(12, source, dest);
resetdisk();
set_file_name(file_name, dest, start_sect, 0);
printf("\nNow Making Backup File %s\n [Sectors %lu - %lu ]\n\n",
file_name, start_sect, r_next_sect - 1);
for(r_sect = start_sect; r_sect < r_f_next_sect; r_sect += rr_sect){
check_user_break(source, dest);
printf("Dumping Sectors %lu - %lu \n", r_sect, r_sect +rr_sect -1);
if(do_read_write(*source,rr_sect,r_sect,buf,so_32bit,READ)){
check_err_record = make_bad_sect_table(so_dpb, rr_sect,
r_sect, bad_table, so_32bit);
if(check_err_record && !do_anyway){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < rr_sect; i++){
if(!bad_table[i]){
if(do_read_write(*source, 1, r_sect + i,
buf + r_s_size*i, so_32bit, READ)){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < rr_sect; i++)
do_read_write(*source, 1, r_sect + i,
buf + r_s_size*i, so_32bit, READ);
}
}
if(do_read_write(*dest,ww_sect,w_sect,buf,des_32bit,WRITE))
disp_msg(21, source, dest);
w_sect += ww_sect;
resetdisk();
}
if(r_f_next_sect != r_next_sect){
check_user_break(source, dest);
printf("Dumping Sectors %lu - %lu \n", r_f_next_sect,
r_next_sect -1);
if(do_read_write(*source, (uint)(r_next_sect - r_f_next_sect),
r_sect, buf, so_32bit, READ)){
check_err_record = make_bad_sect_table(so_dpb, (uint)
(r_next_sect - r_f_next_sect), r_sect, bad_table, so_32bit);
if(check_err_record && !do_anyway){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < (uint)(r_next_sect - r_f_next_sect); i++){
if(!bad_table[i]){
if(do_read_write(*source, 1, r_sect +i,
buf + r_s_size*i, so_32bit, READ)){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < (uint)(r_next_sect - r_f_next_sect); i++){
do_read_write(*source, 1, r_sect +i,
buf + r_s_size*i, so_32bit, READ);
}
}
}
if(do_read_write(*dest, (uint)div_upper((r_next_sect
-r_f_next_sect)*r_s_size, (ulong)w_s_size), w_sect,buf,des_32bit,
WRITE))
disp_msg(21, source, dest);
}
start_sect = r_next_sect;
resetdisk();
if(start_sect < r_end_sect){
ybeep();
ybeep();
ybeep();
ybeep();
disp_msg2(7, source, dest, 0);
resetdisk();
}
}while(start_sect < r_end_sect);
}
void duplicate(char *source, char *dest, ulong start_sect)
{
ulong sect, f_end_sect, end_sect, w_end_sect, total_amount,
used_clust, data_sect, data_sect2, data_size, max_clust;
uint rw_sect, sect_size, i, check_err_record, used_dir_entry,
sect_p_clust;
char so_dpb[22], dest_dpb[22], ext_so_dpb[63], ext_dest_dpb[63],
check_buf[512];
int do_anyway = 0, data_diff, w_offset = 0, r_offset = 0;
if(win95){
ioctrl_lock(*dest - 'A' +1, 0);
ioctrl_lock(*source - 'A' +1, 0);
}
if(so_32bit){
if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
disp_msg(11, source, dest);
}else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
disp_msg(11, source, dest);
if(so_32bit)
shift_ext_dpb(so_dpb, ext_so_dpb);
else
shift_dpb(so_dpb);
if(des_32bit){
if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
disp_msg(12, source, dest);
}else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
disp_msg(12, source, dest);
if(des_32bit)
shift_ext_dpb(dest_dpb, ext_dest_dpb);
else
shift_dpb(dest_dpb);
sect_size = *(uint *)so_dpb;
end_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
w_end_sect = clust2sect(dest_dpb, *(ulong *)(dest_dpb + MAX_C) +1);
sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
if(!full_dump)
end_sect = sect;
data_sect = *(ulong *)(so_dpb + DATA_S); /* sourceのdata_sect */
data_sect2 = *(ulong *)(dest_dpb + DATA_S); /* destのdata_sect */
data_diff = data_sect2 - data_sect;
rw_sect = (uint)(buf_size / (ulong)sect_size);
if(bad_clust_num > 80){
disp_msg2(10, source, dest, start_sect);
do_anyway = 1; /* 強制実行 */
}else if(bad_clust_num)
disp_warn(1, source);
for(i = 0; i < 22; i++)
check_buf[80 + i] = so_dpb[i];
if(do_read_write(*source, 1, 0, buf, so_32bit, READ))
disp_msg(11, source, dest);
resetdisk();
for(i = 0; i < 64; i++)
check_buf[128 + i] = buf[i];
sect_p_clust = (uint)buf[13]; /* sect/clust */
used_dir_entry = get_used_dir_entry(source, so_dpb);
*(uint *)(check_buf + USED_D) = used_dir_entry;
*(ulong *)(check_buf + USED_C) = used_clust;
*(uint *)(check_buf + C_SECT_C) = sect_p_clust;
*(uint *)(check_buf + 110) = 0; /* ゴミ */
switch(check_disk_format(dest_dpb, check_buf)){
case 0:
disp_msg(16, source, dest);
break;
case 1:
rewrite_flag = 0;
break;
case 2:
max_clust = *(ulong *)(check_buf +C_MAX_C) -1;
if(sect_size > 1024)
data_size = max_clust * sect_p_clust
* (ulong)(sect_size / 1024);
else
data_size = (max_clust * sect_p_clust)
/ (ulong)(1024 / sect_size);
if(!disp_msg3(data_size)){
ybeep();
exit_routine(40);
}
if(!check_dir_entry_etc(dest_dpb, check_buf))
disp_msg(39, source, dest);
else
rewrite_flag = 1;
break;
}
if(rewrite_flag){
if(end_sect + data_diff > w_end_sect)
disp_msg(45, source, dest);
}
if(sect_size > 1024)
total_amount = (end_sect +1) * (ulong)(sect_size / 1024);
else
total_amount = (end_sect +1) / (ulong)(1024 / sect_size);
printf("Backup Amount is %ld K bytes (1 K = 1024)\n", total_amount);
if(rewrite_flag && (start_sect < data_sect)){
if(start_sect != 0)
disp_msg(41, source, dest);
d_write_ipl(source, dest, rw_sect, so_dpb, dest_dpb, check_buf);
d_write_FAT(source, dest, rw_sect, so_dpb, dest_dpb, check_buf);
d_write_dir_entry(source,dest,rw_sect,check_buf, so_dpb, dest_dpb);
r_offset = data_sect;
w_offset = data_sect2;
}
end_sect += data_diff;
f_end_sect = (end_sect - w_offset - start_sect)
- ((end_sect - w_offset - start_sect) % rw_sect);
f_end_sect += w_offset + start_sect;
/* ここでは,f_end_sect, sect 等は書き込む sector */
printf("\nNow Duplicating from %c: to %c:\n", *source, *dest);
printf(" [Write to Sectors %lu - %lu ]\n\n", start_sect +w_offset, end_sect - 1);
for(sect = start_sect + w_offset; sect < f_end_sect; sect += rw_sect){
check_user_break(source, dest);
printf("Writing Sectors %lu - %lu \n", sect, sect + rw_sect -1);
if(do_read_write(*source, rw_sect, sect -data_diff, buf, so_32bit, READ)){
/* 以下は rewrite の時は,break するように */
/* make_bad_sect_table を定義している */
check_err_record = make_bad_sect_table(so_dpb, rw_sect,sect,
bad_table, so_32bit);
if(check_err_record && !do_anyway){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < rw_sect; i++){
if(!bad_table[i]){
if(do_read_write(*source, 1, sect +i,
buf + sect_size*i, so_32bit, READ)){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < rw_sect; i++)
do_read_write(*source, 1, sect + i,
buf + sect_size*i, so_32bit, READ);
}
}
if(do_read_write(*dest,rw_sect,sect,buf,des_32bit,WRITE))
disp_msg(21, source, dest);
resetdisk();
}
if(f_end_sect != end_sect){
check_user_break(source, dest);
printf("Writing Sectors %lu - %lu\n", sect, end_sect -1);
if(do_read_write(*source, (uint)(end_sect - f_end_sect),
sect - data_diff, buf, so_32bit, READ)){
/* 以下は rewrite の時は,break するように */
/* make_bad_sect_table を定義している */
check_err_record = make_bad_sect_table(so_dpb, (uint)(end_sect
- f_end_sect), f_end_sect, bad_table, so_32bit);
if(check_err_record && !do_anyway){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
if(!check_err_record && !do_anyway){
for(i = 0; i < (uint)(end_sect - f_end_sect); i++){
if(!bad_table[i]){
if(do_read_write(*source, 1, f_end_sect +i,
buf + sect_size*i, so_32bit, READ)){
disp_msg2(11, source, dest,0);
do_anyway = 1;
}
}
}
}
if(do_anyway){
if(!check_err_record)
disp_warn(2, source);
for(i = 0; i < (uint)(end_sect - f_end_sect); i++){
do_read_write(*source, 1, f_end_sect +i,
buf + sect_size*i, so_32bit, READ);
}
}
}
if(do_read_write(*dest,(uint)(end_sect - f_end_sect), sect, buf, des_32bit, WRITE))
disp_msg(21, source, dest);
}
resetdisk();
if(des_32bit && rewrite_flag)
reset_free_clust(dest, sect_size);
}
void test(char *source, char *dest, int mode)
/* read source 0 - r_end_sect, write dest w_start_sect - w_end_sect */
/* read dest w_start_sect - w_end_sect, write source ww_start - ww_end */
/* mode:0 -> BIG to BIG, mode:1 -> BIG to SMALL, mode:2 -> SMALL to BIG*/
{
char so_dpb[22], dest_dpb[22], ext_so_dpb[63], ext_dest_dpb[63];
ulong sect, w_sect, w_sect2, used_clust, r_end_sect,
w_start_sect, w_end_sect, ww_start_sect, ww_end_sect,
so_end_sect, dest_end_sect, t_buf_size;
uint r_s_size, w_s_size, rr_sect, ww_sect, r_s_length, w_s_length,
comp_size;
int err = 0, i;
if(so_32bit){
if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
disp_msg(11, source, dest);
}else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
disp_msg(11, source, dest);
if(so_32bit)
shift_ext_dpb(so_dpb, ext_so_dpb);
else
shift_dpb(so_dpb);
if(des_32bit){
if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
disp_msg(12, source, dest);
}else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
disp_msg(12, source, dest);
if(des_32bit)
shift_ext_dpb(dest_dpb, ext_dest_dpb);
else
shift_dpb(dest_dpb);
switch(mode){
case 2:
case 3:
t_buf_size = BUF_UNIT;
break;
default:
t_buf_size = BUF_UNIT*2;
break;
}
r_s_size = *(uint *)so_dpb;
so_end_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
rr_sect = (uint)(t_buf_size / (ulong)r_s_size);
r_s_length = (uint)(0xa0000L/(ulong)r_s_size);
ww_start_sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
ww_end_sect = ww_start_sect + r_s_length;
if(ww_end_sect > so_end_sect)
disp_msg(34, source, dest);
r_end_sect = r_s_length; /* 0 - (r_end_sect-1) をtest */
if(r_end_sect >= ww_start_sect)
disp_msg(35, source, dest);
if(win95){
ioctrl_lock(*dest - 'A' +1, 0);
ioctrl_lock(*source - 'A' +1, 0);
}
w_s_size = *(uint *)dest_dpb;
ww_sect = (uint)(t_buf_size / (ulong)w_s_size);
w_s_length = (uint)(0xa0000L/(ulong)w_s_size);
dest_end_sect = clust2sect(dest_dpb,*(ulong *)(dest_dpb + MAX_C) +1);
w_start_sect = get_true_end_sect(dest_dpb, dest, &used_clust, des_32bit);
if(dest_end_sect < w_start_sect + w_s_length)
disp_msg(38, source, dest);
w_end_sect = w_start_sect + w_s_length;
w_sect = w_start_sect;
printf("\n\"-p -G option\" Test Mode.\n");
printf("Backup Small Area From %s To %s.\n", source, dest);
printf("And Restore Small Area From %s To %s.\n", dest, source);
printf("\nTest Amount is 640 K bytes (1 K = 1024 byte)\n");
switch(mode){
case 0:
printf("Test Using Backup 64K, Restore 64K buffer\n");
break;
case 1:
printf("Test Using Backup 64K, Restore 32K buffer\n");
break;
case 2:
printf("Test Using Backup 32K, Restore 64K buffer\n");
break;
case 3:
printf("Test Using Backup 32K, Restore 32K buffer\n");
break;
}
printf("Now Test Backup From %c: To %c:\n", *source, *dest);
printf(" [Sectors 0 - %lu ] To [Sectors %ld - %lu ]\n",r_end_sect -1, w_start_sect,w_end_sect -1);
disp_msg2(9, source, dest, 0);
for(sect = 0; sect < r_end_sect; sect += rr_sect){
check_user_break(source, dest);
printf("Dumping Sectors %lu - %lu \n", sect, sect + rr_sect -1);
if(do_read_write(*source,rr_sect, sect, buf, so_32bit, READ))
disp_msg(20, source, dest);
if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, WRITE))
disp_msg(21, source, dest);
w_sect += ww_sect;
resetdisk();
}
switch(mode){
case 1:
case 3:
t_buf_size = BUF_UNIT;
break;
default:
t_buf_size = BUF_UNIT*2;
break;
}
rr_sect = (uint)(t_buf_size / (ulong)r_s_size); /* read write 逆になる */
ww_sect = (uint)(t_buf_size / (ulong)w_s_size); /* read write 逆になる */
printf("\nNow Test Restore From %c: To %c:\n", *dest, *source);
printf(" [Sectors %ld - %lu ] To [Sectors %ld - %lu ]\n", w_start_sect,
w_end_sect -1, ww_start_sect, ww_end_sect -1);
disp_msg2(9, source, dest, 0);
sect = 0;
w_sect2 = ww_start_sect;
for(w_sect = w_start_sect; w_sect < w_end_sect; w_sect += ww_sect){
check_user_break(source, dest);
printf("Restoring from Sectors %lu - %lu\n",w_sect,w_sect +ww_sect-1);
if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, READ))
disp_msg(20, source, dest);
if(do_read_write(*source, rr_sect, w_sect2, buf, so_32bit, WRITE))
disp_msg(21, source, dest);
sect += rr_sect;
w_sect2 += rr_sect;
resetdisk();
}
printf("\nNow Compare Data\n");
printf(" [Sectors 0 - %lu ] with [Sectors %ld - %lu ]\n", r_end_sect - 1,
ww_start_sect, ww_end_sect -1);
disp_msg2(9, source, dest, 0);
t_buf_size = BUF_UNIT;
rr_sect = (uint)(t_buf_size / (ulong)r_s_size); /* read write 共通 */
comp_size = (uint)t_buf_size / 2;
sect = 0;
w_sect2 = ww_start_sect;
for(sect = 0; sect < r_end_sect; sect += rr_sect){
check_user_break(source, dest);
printf("Comparing Sectors %lu - %lu with %ld - %ld\n",
sect, sect + rr_sect -1, w_sect2, w_sect2 + rr_sect -1);
if(do_read_write(*source, rr_sect, sect, buf, so_32bit, READ))
disp_msg(20, source, dest);
if(do_read_write(*source, rr_sect, w_sect2, buf2, so_32bit,READ))
disp_msg(20, source, dest);
w_sect2 += rr_sect;
resetdisk();
err = do_compare(buf, buf2, comp_size);
if(err)
break;
}
if(err)
disp_warn(5, source);
for(i = 0; i < 0x4000; i++) /* clear test area */
*(int *)(buf + 2*i) = 0;
printf("\nNow Clear Test Area of Source Drive\n");
printf(" [Sectors %ld - %lu ]\n", ww_start_sect, ww_end_sect - 1);
disp_msg2(9, source, dest, 0);
for(w_sect2 = ww_start_sect; w_sect2 < ww_end_sect; w_sect2 += rr_sect){
printf("Clearing Sectors %lu - %lu\n", w_sect2, w_sect2 + rr_sect -1);
if(do_read_write(*source, rr_sect, w_sect2, buf, so_32bit, WRITE))
disp_msg(46, source, dest);
resetdisk();
}
if(err)
exit_routine(36);
else
disp_msg(37, source, dest);
}
int check_osr2_32(char drv)
{
char dpb[22], ext_dpb[63];
int FAT_32 = -1 ;
if(get_dpb((int)drv -'A' + 1, dpb) == 0)
FAT_32 = 0 ;
else if(win95 && (get_ext_dpb((int)drv -'A' + 1, ext_dpb) == 0))
FAT_32 = 1; /* 詳しくは,ipl[11],[12] を調べる */
return(FAT_32);
}
void main(int argc, char *argv[])
{
int i, help_flag = 0, s_d_flag = 0, pro_flag = 0, test_mode = 0;
int backup_restore = 1; /* 0:restore, 1:backup, 2: duplicate */
ulong start_sect = 0; /* 3:p_restore, 4:p_backup */
/* 5:test_mode */
char source[80], dest[80];
full_dump = 0;
error_code = NO_ERROR;
set_24h();
for(i = 1; i < argc; i++){
if((argv[i][0] == '/') || (argv[i][0] == '-')){
switch(toupper(argv[i][1])){
case '?': help_flag = 1;
break;
case 'R': backup_restore = 0;
break;
case 'B': backup_restore = 1;
break;
case 'S': if(toupper(argv[i][2]) == 'T')
start_sect = atol(argv[i] + 3);
else
backup_restore = 1;
break;
case 'L': f_s_limit = atol(argv[i] + 2);
f_s_limit *= 1024;
if(f_s_limit < 0)
f_s_limit = 0;
break;
case 'D': backup_restore = 2;
break;
case 'P': pro_flag = 3;
break;
case 'F': full_dump = 1;
break;
case 'G': big_buf = 1;
break;
case 'T': backup_restore = 5; /* test_mode */
if(argv[i][2] == '1')
test_mode = 1;
else if(argv[i][2] == '2')
test_mode = 2;
else if(argv[i][2] == '3')
test_mode = 3;
break;
case 'V': verify = 1;
break;
}
}else{
switch(s_d_flag){
case 0: /* source drive set */
strcpy(source, argv[i]);
s_d_flag = 1;
break;
case 1: /* destination drive set */
strcpy(dest, argv[i]);
s_d_flag = 2;
break;
default: help_flag = 1;
break;
}
}
}
if(big_buf)
buf_size = BUF_UNIT*2;
else
buf_size = BUF_UNIT;
if((pro_flag) && (backup_restore != 2) && (backup_restore != 5))
backup_restore += pro_flag;
if ((help_flag == 1) || (s_d_flag != 2))
disp_msg(10, source, dest);
source[0] = (char)toupper(source[0]);
dest[0] = (char)toupper(dest[0]);
disp_msg2(backup_restore, source, dest, start_sect);
if(drive_ready(*source) != NO_ERROR)
disp_msg(13, source, dest);
if(drive_ready(*dest) != NO_ERROR)
disp_msg(14, source, dest);
add_drive(source);
add_drive(dest);
if(normalize(source) == ERR_RET)
disp_msg(11, source, dest);
if(normalize(dest) == ERR_RET)
disp_msg(12, source, dest);
if(get_version() >= 0x700){ /* DOS Ver 7.00 (Windows 95) ? */
win95 = 1;
}
if(backup_restore == 1){
if(remote_connect(*dest)){
if(change_dir(dest) == ERR_RET)
disp_msg(12, source, dest);
}
}
switch(backup_restore){
case 0:
if(strlen(dest) != 3){
dest[3] = 0;
change_dir(dest);
}
break;
case 1:
if(strlen(source) != 3){
source[3] = 0;
change_dir(source);
}
break;
case 2:
case 3:
case 4:
case 5:
if(strlen(dest) != 3){
dest[3] = 0;
change_dir(dest);
}else if(strlen(source) != 3){
source[3] = 0;
change_dir(source);
}
break;
}
if(*source == *dest)
disp_msg(15, source, dest);
switch(backup_restore){
case 0:
des_32bit = check_osr2_32(*dest);
so_32bit = 0;
break;
case 1:
so_32bit= check_osr2_32(*source);
des_32bit = 0;
break;
case 2:
case 3:
case 4:
case 5:
so_32bit= check_osr2_32(*source);
des_32bit = check_osr2_32(*dest);
break;
}
if((so_32bit == -1) || (des_32bit == -1))
disp_msg(26, source, dest);
switch(backup_restore){
case 0:
restore(source, dest, start_sect);
break;
case 1:
backup(source, dest, start_sect);
break;
case 2:
duplicate(source, dest, start_sect);
break;
case 3:
p_restore(source, dest, start_sect);
break;
case 4:
p_backup(source, dest, start_sect);
break;
case 5:
test(source, dest, test_mode);
break;
}
disp_msg(0, source, dest);
}