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 >
C/C++ Source or Header  |  1998-06-10  |  118KB  |  3,861 lines

  1. /*    diskdump.c        Ver 3.10    '98. 6. 10
  2.     Auther      : K.Yokogawa
  3.     Computer  : All MS-DOS Machines
  4.     Compiler  : MS-C Ver 6.0 Compact model & MASM Ver 5.10
  5.     Hard Disk の Disk Image の Backup, Restore を行なう
  6.     Bad Cluster の処理のため,sector size >= 512 とする
  7.     少し,Hard Diskの容量が異なっても対処できるようにする(Ver3.0)
  8.  
  9.     write_buf(=check_buf)の内容は次の通り.  1行は16文字で
  10.  
  11.     1 行目      DiskDump Ver 3.0
  12.     2 - 3 行目  start  - end sector
  13.     3 行目終り  FAT32 or FAT16
  14.     4 行目      Total: total sectors
  15.     5 行目      Used: used sectors
  16.     以下はbinary データ
  17.     6 行目 dpb-data             22 byte
  18.      uint    _sector_size;        number of bytes per sector
  19.     char    _cluster_mask;        Sectors/cluster - 1 = 2^n - 1
  20.     char    _cluster_shift;        log base 2 of the cluster size
  21.     uint    _first_fat;            number of reserved (boot) sectors
  22.     char    _num_of_fat;        2 に決め打ち number of copies of the FAT
  23.     uint    _root_entries;        number of root directory entries
  24.     ulong    _first_data_sector;    first data sector on medium
  25.     ulong    _max_cluster;        largest possible cluster number+1
  26.     ulong    _fat_sector;        number of sectors par FAT
  27.     char    ゴミ
  28.  
  29.     uint    used_dir_entry;
  30.     ulong    used_clust;            used_clust+1, cf. _max_clust
  31.     uint     sect/clust;
  32.     uint    ゴミ
  33.  
  34.     8 行目
  35.     ulong    start_sect;
  36.     ulong    r_next_sect;
  37.     ulong     write_start_sect;
  38.     ulong    r_end_sect;
  39.  
  40.     9 - 12 行 ipl 16*4 byte
  41.  
  42.     13 - 32 行 bad cluster table
  43. */
  44.  
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <dos.h>
  49. #include <conio.h>
  50. #include <jstring.h>
  51. #include <process.h>
  52. #include <direct.h>
  53. #include <ctype.h>
  54.  
  55. #define uchar   unsigned char
  56. #define uint    unsigned int
  57. #define ulong   unsigned long int
  58.  
  59. #define YES                1
  60. #define NO                0
  61. #define ERR_RET            -1
  62. #define SUC_RET            1
  63. #define NO_ERROR        0xff
  64.  
  65. #define READ        0
  66. #define WRITE        1
  67.  
  68. #define STOP_KEY    0x3
  69. #define ESC_KEY        0x1b
  70. #define FILE_LENGTH    0x50000000L
  71. #define BUF_UNIT    0x8000L
  72.  
  73. /*     #define S_SIZE    0    */
  74. /*  #define C_S_SIZE 80    */
  75.  
  76. #define C_MASK        2
  77. #define FAT_S        4
  78. #define DIR_E        7
  79. #define DATA_S        9
  80. #define MAX_C        13
  81. #define S_P_FAT        17
  82. #define IPL_B        50        /* ipl の [50]    */
  83. #define C_C_MASK    82
  84. #define C_FAT_S        84
  85. #define C_DIR_E        87
  86. #define C_DATA_S    89
  87. #define C_MAX_C        93
  88. #define C_S_P_FAT    97
  89. #define USED_D        102
  90. #define USED_C        104
  91. #define C_SECT_C    108
  92. #define R_START_S    112
  93. #define R_NEXT_S    116
  94. #define W_START_S    120
  95. #define R_END_S        124
  96. #define C_IPL_B        178        /* ipl の backup の部分    */
  97.  
  98. char buf[0x10000L], buf2[0x10000L], bad_clust[320],
  99.      bad_table[128];
  100. /* bad_table は 64K/byte_par_sect で byte_par_sect >= 512 を仮定 */
  101. int  error_code, win95 = 0, verify = 0, so_32bit, des_32bit, 
  102.      full_dump, big_buf = 0, rewrite_flag = 0;
  103. uint bad_clust_num = 0;    /* bad_clust_num は uint でいいだろう    */
  104. ulong    buf_size, f_s_limit = 0;
  105. char _drive[3], _path[80];
  106.  
  107. /*     uint    _sector_size;        number of bytes per sector
  108.     char    _cluster_mask;        Sectors/cluster - 1 = 2^n - 1
  109.     char    _cluster_shift;        log base 2 of the cluster size
  110.     uint    _first_fat;            number of reserved (boot) sectors
  111.     char    _num_of_fat;        number of copies of the FAT
  112.     uint    _root_entries;        number of root directory entries
  113.     uint->ulong    _first_data_sector;    first data sector on medium
  114.     uint->ulong    _max_cluster;        largest possible cluster number+1
  115.     uint->ulong    _fat_sector;        number of sectors par FAT
  116. uint->ulong は 32bit fatの為の変更
  117. */
  118.  
  119. /* 
  120. ExtDPB:
  121.     Size_DPB        dw      ?        ;size of DPB
  122. DPB:
  123.     DPB_drive       db      ?       ;ドライブ番号(00h=A:,01h=B:,・・・)
  124.     DPB_unit        db      ?       ;論理装置コード番号
  125.     DPB_bySec       dw      ?       ;1レコードのバイト数
  126.     DPB_secClus     db      ?       ;1クラスタのレコード数
  127.     DPB_scount      db      ?       ;クラスタ←→レコードのシフトカウンタ
  128.     DPB_FATsec      dw      ?       ;予約レコード数(FATの開始レコード)
  129.     DPB_numFAT      db      ?       ;FATの数
  130.     DPB_numDIR      dw      ?       ;ルートディレクトリのエントリ総数
  131.     DPB_DataSec     dw      ?       ;データエリア先頭レコード番号
  132.     DPB_maxClusNo   dw      ?       ;最大クラスタ番号(総クラスタ数+1)
  133.     DPB_secFAT      dw      ?       ;1FATのレコード数
  134.     DPB_DIRsec      dw      ?       ;ルートディレクトリ先頭レコード番号
  135.     DPB_DHH_ptr     dd      ?       ;デバイスヘッダへのベクタアドレス
  136.                                     ; reserved ?
  137.     DPB_media       db      ?       ;メディア・ディスクリプタ
  138.     DPB_dflag       db      ?       ;ディスク交換フラグ(未アクセスの時はFFh)
  139.                                     ; first access flag
  140.     DPB_next_ptr    dd      ?       ;次のDPBへのポインタ
  141.                                     ;最後のDPBは FFFF:FFFF 通常これ
  142.     DPB_chgClus     dw      ?       ;最後に変更したクラスタ番号
  143.     DPB_freeClusLow dw      ?       ;未使用クラスタ数(下位)
  144. ;            *** FAT32 の拡張部分 ***
  145.     DPB_freeClusHi  dw      ?       ;未使用クラスタ数(上位)
  146.     DPB_actFAT      dw      ?       ;アクティブFATミラーリング
  147.                                     ;       bits 3-0: アクティブFATの数
  148.                                     ;       bits 6-4: 予約(0)
  149.                                     ;       bit 7: ミラーリングされていない
  150.     DPB_FSIsec      dw      ?       ;ファイルシステム情報のレコード番号
  151.                                     ;(FFFFh=FSIなし)
  152.     DPB_BootBakSec  dw      ?       ;ブートレコードバックアップのレコード
  153.     DPB_DataSec32   dd      ?       ;データエリア先頭レコード番号   (FAT32)
  154.     DPB_maxClusNo32 dd      ?       ;最大クラスタ番号               (FAT32)
  155.     DPB_secFAT32    dd      ?       ;1FATのレコード数           (FAT32)
  156.     DPB_DIRsec32    dd      ?       ;ルートディレクトリ先頭レコード (FAT32)
  157.     DPB_chgClus32   dd      ?       ;最後に変更したクラスタ番号     (FAT32)
  158. */
  159.  
  160. char ext_dfree[44];
  161. /*
  162. ExtFreeSpace    STRUC
  163.         EFS_TrueSize    dw      ?       ;ドライブの実際のサイズ ???
  164.         EFS_StrucVer    dw      ?       ;構造体のバージョン ???
  165.         EFS_secClus     dd      ?       ;1クラスタのレコード数  (圧縮補正)
  166.         EFS_bySec       dd      ?       ;1レコードのバイト数
  167.         EFS_AvailClus   dd      ?       ;使用可能クラスタ数
  168.         EFS_TotalClus   dd      ?       ;ドライブのクラスタ総数
  169.         EFS_AvailSec    dd      ?       ;使用可能物理セクタ数    (圧縮補正)
  170.         EFS_TotalSec    dd      ?       ;ドライブの物理セクタ総数(圧縮補正)
  171.         EFS_AvailUnit   dd      ?       ;使用可能ユニット数      (圧縮補正)
  172.         EFS_TotalUnit   dd      ?       ;ユニット総数            (圧縮補正)
  173.         EFS_reserved    db      8 dup(0) ;予約領域
  174. ExtFreeSpace    ENDS
  175. */
  176.  
  177. char error_msg[9][18] = {"Write protected", "Unit not Exist",
  178.           "Drive not Ready", "Invalid Command", "Data CRC Error",
  179.           "Bad Drive Request", "Seek Error", "No such Media",
  180.           "Sector not found"};
  181.  
  182. /* subroutine by assembler    */
  183. int  abs_read_write(int drive, uint sectors, ulong start_sect, char *buf, int sw);
  184. int  ext_abs_read_write(int drive, uint sectors, ulong start_sect, char *buf, int sw);
  185. int  get_dpb(int drive, char *dpb);
  186. int  get_ext_dpb(int drive, char *ext_dpb);
  187. int  get_version();
  188. int  ioctrl_lock(int drive, int sw);
  189. void get_ext_dfree(char *drive_path, char *buf);
  190. /* void ext_resetdisk(int drive);    */
  191. void resetdisk();
  192. void yjstrupr(char *);
  193. int  getcurdir(int, char *);
  194. void set_24h(void);
  195. int  get_error_code(void);
  196. void reset_24h(void);
  197. int  drive_ready(char drv);
  198.  
  199. void abort_msg(void)
  200. {
  201.     printf("Abort DISKDUMP.EXE\n");
  202. }
  203.  
  204. void ybeep()
  205. {
  206.     putch(0x07);    /* beep    */
  207. }
  208.  
  209. void exit_routine(int num)
  210. {
  211.     ybeep();
  212.     printf("\n");
  213.     reset_24h();
  214.     exit(num);
  215. }
  216.  
  217. void keyclr()
  218. {
  219.     union REGS inregs;
  220.  
  221.     inregs.x.ax = 0xc00;    /* key buffer clear    */
  222.     intdos(&inregs, &inregs);
  223. }
  224.  
  225. void     disp_err_msg()
  226. {
  227.     if(error_code != NO_ERROR){
  228.         ybeep();
  229.         ybeep();
  230.         printf("\n%s\nAbort DISKDUMP.EXE\n", error_msg[error_code]);
  231.         exit_routine(5);
  232.     }
  233. }
  234.  
  235. void disp_msg(int num, char *source, char *dest)
  236. {
  237.     switch(num){
  238.         case 0: 
  239.             printf("\nDISKDUMP.EXE ends successfully.\n");
  240.             break;
  241.         case 10: 
  242.             printf("DISKDUMP.EXE Version 3.10 by K.Yokogawa\n\n");
  243.             printf("Usage is DISKDUMP [options] Source-Drive Destination-Drive\n");
  244.             printf("For instance, DISKDUMP -b  -f A: B:\n");
  245.             printf("Source and Destination-Drive should be of the form \'A:\'\n");
  246.             printf("File Extension is \"DUP\" (\"DDD\", \"DD3\" for p-option)\n");
  247.             printf("Option is -b: Make Backup (default)\n");
  248.             printf("          -r: Restore\n");
  249.             printf("          -p: Use Special Method\n");
  250.             printf("          -t: Test Using Backup 64K, Restore 64K buffer for Special Method\n");
  251.             printf("          -t1: Test Using Backup 64K, Restore 32K buffer for Special Method\n");
  252.             printf("          -t2: Test Using Backup 32K, Restore 64K buffer for Special Method\n");
  253.             printf("          -t3: Test Using Backup 32K, Restore 32K buffer for Special Method\n");
  254.             printf("          -d: Direct Disk Duplicate\n");
  255.             printf("          -l: File Size Limit For Ex. -l630 (630 M bytes, 1 M = 1024 K)\n");
  256.             printf("          -st: Start Sector For Ex. -st12345678\n");
  257.             printf("          -f: Full dump(use with {-b,-p,-d})\n");
  258.             printf("          -v: verify when usual backup (defaut off)\n");
  259.             printf("          -g: Use 64K read-write buffer (Default: 32K buffer)\n");
  260.             printf("In the case of \"-p\" option, the Disk Image of Source is dumped to the data area\n");
  261.             printf("of destination drive directly. In this case, Newly formatted Media is desirable.");
  262.             break;
  263.         case 11: 
  264.             printf("\nIncorrect Source Drive %s !! \n", source);
  265.             abort_msg();
  266.             break;
  267.         case 12: 
  268.             printf("\nIncorrect Destination Drive %s !! \n", dest);
  269.             abort_msg();
  270.             break;
  271.         case 13: 
  272.             printf("\nSource Drive is not ready !!\n");
  273.             abort_msg();
  274.             break;
  275.         case 14: 
  276.             printf("\nDestination Drive is not ready !!\n");
  277.             abort_msg();
  278.             break;
  279.         case 15: 
  280.             printf("\nSource and Destination Drive must be different !!\n");
  281.             abort_msg();
  282.             break;
  283.         case 16: 
  284.             printf("\nDestination Drive has an incorrect disk format !!\n");
  285.             printf("Sector sizes and Cluster sizes must be Same.\n");
  286.             abort_msg();
  287.             break;
  288.         case 17: 
  289.             printf("\nFile %s is not correct format !!\n", source);
  290.             abort_msg();
  291.             break;
  292. /*        case 18: 欠番    */
  293.         case 19: 
  294.             printf("\nUser break !! Abort DISKDUMP.EXE\n");
  295.             break;
  296.         case 20: 
  297.             printf("\nSource drive %s Read Error !!\n", source);
  298.             abort_msg();
  299.             break;
  300.         case 21: 
  301.             printf("\nDestination drive Write Error !!\n");
  302.             abort_msg();
  303.             break;
  304.         case 22: 
  305.             printf("\nFile Read Error !!\n");
  306.             abort_msg();
  307.             break;
  308.         case 23: 
  309.             printf("\nFile Write Error !!\n");
  310.             abort_msg();
  311.             break;
  312.         case 24: 
  313.             printf("\nFile Open Error !!\n");
  314.             abort_msg();
  315.             break;
  316.         case 25: 
  317.             printf("\nFile Close Error !!\n");
  318.             abort_msg();
  319.             break;
  320.         case 26: 
  321.             printf("\nUnknown Disk Type !!\n");
  322.             abort_msg();
  323.             break;
  324.         case 27: 
  325.             printf("\nStart Sector is not used in Source Drive !!\n");
  326.             printf(" or Start Sector exceeds Last Sector of Source Drive !!\n");
  327.             abort_msg();
  328.             break;
  329.         case 28: 
  330.             printf("\nIncorrect source FAT !!\n");
  331.             abort_msg();
  332.             break;
  333.         case 29: 
  334.             printf("\nEnd Sector of Source exceeds End Sector of Destination !!\n");
  335.             printf("It may happen to be a Different Format Disk.\n");
  336.             abort_msg();
  337.             break;
  338.         case 30: 
  339.             printf("\nVerify Error !!\n");
  340.             abort_msg();
  341.             break;
  342.         case 33: 
  343.             printf("\nError at FAT Sectors. This media is broken !!\n");
  344.             abort_msg();
  345.             break;
  346.         case 34: 
  347.             printf("\nSource drive %shas Not enough free area to test !!\n", source);
  348.             abort_msg();
  349.             break;
  350.         case 35: 
  351.             printf("\nSource drive %s has Not enough data to test !!\n", source);
  352.             abort_msg();
  353.             break;
  354. /*        case 36: 欠番        */
  355.         case 37: 
  356.             printf("\n \"-p -G option\" Test ends successfully.\n");
  357.             break;
  358.         case 38: 
  359.             printf("\nDestination drive %s has Not enough free area to test !!\n", dest);
  360.             abort_msg();
  361.             break;
  362.         case 39: 
  363.             printf("\nInsufficient Root directory entries or Data Area.\n");
  364.             printf("Cannnot restore !!\n");
  365.             abort_msg();
  366.             break;
  367.         case 40: 
  368.             printf("\nError at IPL Sectors. Destination Drive is broken !!\n");
  369.             printf("Retry after Disk Format\n");
  370.             abort_msg();
  371.             break;
  372.         case 41: 
  373.             printf("\nIrregular Designation of start_sector\n");
  374.             abort_msg();
  375.             break;
  376.         case 42: 
  377.             printf("\nDestination drive Read Error !!\n");
  378.             abort_msg();
  379.             break;
  380.         case 43: 
  381.             printf("\nError at Directry Entry Sectors !!\n");
  382.             abort_msg();
  383.             break;
  384.         case 44: 
  385.             printf("\nDestination Drive Write Error !!\n");
  386.             abort_msg();
  387.             break;
  388.         case 45: 
  389.             printf("\nInsufficient Data Area in Destination Drive\n");
  390.             abort_msg();
  391.             break;
  392.         case 46: 
  393.             printf("\nError at Clearing Test Area in Source Drive\n");
  394.             abort_msg();
  395.             break;
  396.     }
  397.     exit_routine(num);
  398. }
  399.  
  400. void disp_msg2(int num, char *source, char *dest, ulong start_sect)
  401. {
  402.     char ans;
  403.     int    i;
  404.  
  405.     if(num == 5)
  406.         return;
  407.  
  408.     switch(num){
  409.         case 0:        /* load    */
  410.             printf("\n");
  411.             if(start_sect)
  412.                 printf("From Sector %lu, ", start_sect);
  413.             printf("Drive %s will be Rewrited by the Disk Image file in %s\n", dest, source);
  414.             break;
  415.         case 1:        /* save    */
  416.             printf("\n");
  417.             if(start_sect)
  418.                 printf("From Sector %lu, ", start_sect);
  419.             if(full_dump)
  420.                 printf("Full ");
  421.             printf("Disk Image of drive %s will be saved to %s\n", source, dest);
  422.             break;
  423.         case 2:        /* duplicate    */
  424.             printf("\n");
  425.             if(start_sect)
  426.                 printf("From Sector %lu, ", start_sect);
  427.             printf("Drive %s will be Directly Duplicated to the drive %s\n", source, dest);
  428.             break;
  429.         case 3:        /* load    */
  430.             printf("\n");
  431.             if(start_sect)
  432.                 printf("From Sector %lu, ", start_sect);
  433.             printf("Drive %s will be Rewrited by the Special Disk Image in %s\n", dest, source);
  434.             break;
  435.         case 4:        /* save    */
  436.             printf("\n");
  437.             if(start_sect)
  438.                 printf("From Sector %lu, ", start_sect);
  439.             if(full_dump)
  440.                 printf("Full ");
  441.             printf("Disk Image of drive %s will be saved to %s by Special method\n", source, dest);
  442.             break;
  443.         case 6: 
  444.             printf("\nDestination %s has not enough free area !!\n", dest);
  445.             printf("Insert New Media in Destination Drive.\n");
  446.             break;
  447.         case 7: 
  448.             printf("\nInsert New Media in %s\n", dest);
  449.             break;
  450.         case 8: 
  451.             printf("\nInsert Next Backuped Media in %s\n", source);
  452.             printf("Or Press ESC Key to End\n");
  453.             break;
  454.         case 9:
  455.             break;
  456.         case 10: 
  457.             printf("\nNumber of Bad clusters of %s exceeds 80 !!\n", source);
  458.             break;
  459.         case 11: 
  460.             printf("\nBad Sectors of %s increased after disk format !!\n", source);
  461.             break;
  462.         case 12: 
  463.             printf("\nBad Sectors of %s increased after diskdump !!\n", dest);
  464.             break;
  465.         case 13: 
  466.             printf("\n%s is not found in Source Drive !!\n", source);
  467.             printf("Insert Next Media in source Drive.\n");
  468.             break;
  469.     }
  470.     if(num >= 10){
  471.         ybeep();
  472.         ybeep();
  473.         printf("\nContinue in anyway ? > (y/n)");
  474.         for(i = 0 ; i < 2; i++)
  475.             putch(0x08);
  476.     }else{
  477.         printf("\nAre You Ready ? > (y/n)");
  478.         for(i = 0 ; i < 4; i++)
  479.             putch(0x08);
  480.     }
  481.     keyclr();
  482.     ans = getch();
  483.     printf("\n");
  484.  
  485.     if(num >= 10){
  486.         if((ans =='Y') || (ans == 'y'))
  487.             return;
  488.     }else{
  489.         if((ans =='Y') || (ans == 'y') || (ans == 0xd))
  490.             return;
  491.     }
  492.     ybeep();
  493.     exit_routine(num);
  494. }
  495.  
  496. int disp_msg3(ulong total_data_size)
  497. {
  498.     char ans;
  499.     int    i;
  500.  
  501.     printf("\nSector sizes and Cluster sizes are Same.\n");
  502.     printf("But Amounts of Data Area are Different !!\n");
  503.     printf("\nOriginal Drive has %ld K bytes (1 K = 1024) Data Area.\n\n", total_data_size);
  504.     ybeep();
  505.     ybeep();
  506.     printf("Anyway, Do You Continue ? > (y/n)");
  507.     for(i = 0 ; i < 4; i++)
  508.         putch(0x08);
  509.     keyclr();
  510.     ans = getch();
  511.     printf("\n\n");
  512.  
  513.     if((ans =='Y') || (ans == 'y') || (ans == 0xd))
  514.         return(1);
  515.     else
  516.         return(0);
  517. }
  518.  
  519. void disp_warn(int num, char *drive)
  520. {
  521.     switch(num){
  522.         case 1: 
  523.             printf("Source Drive %s has bad Clusters.\n", drive);
  524.             break;
  525.         case 2: 
  526.             printf("Source Drive %s has unrecorded bad Clusters.\n", drive);
  527.             break;
  528.         case 3: 
  529.             printf("Destination Drive %s has bad Clusters.\n", drive);
  530.             break;
  531.         case 4: 
  532.             printf("Destination Drive %s has unrecorded bad Clusters.\n", drive);
  533.             break;
  534.         case 5: 
  535.             printf("\n\nData Compare Error !!\n");
  536.             printf(" Fails to Test \"-p -G option\" \n\n");
  537.             break;
  538.     }
  539.     ybeep();
  540.     if(num == 5){
  541.         ybeep();
  542.         printf("Press Any key !! ");
  543.         keyclr();
  544.         getch();
  545.         printf("\n");
  546.     }
  547. }
  548.  
  549. int check_end_en(char *str)
  550. {
  551.     if((strlen(str) > 1) 
  552.     && (str[strlen(str)-1] == '\\')
  553.     && (nthctype(str, strlen(str) -2 ) != CT_KJ1))
  554.         return(YES);
  555.     else
  556.         return(NO);
  557. }
  558.  
  559. char ygetch()        /* if key is not pushed return NO, else getch() */
  560. {
  561.     union REGS regs;
  562.  
  563.     regs.h.ah = 0x06;
  564.     regs.h.dl = 0xff;
  565.     intdos(®s, ®s);
  566.     return(regs.h.al);
  567. }
  568.  
  569. void    check_user_break(char *s_d, char *d_d)
  570. {
  571.     char ch;
  572.  
  573.     ch = ygetch();
  574.     if((ch == STOP_KEY) || (ch == ESC_KEY))
  575.         disp_msg(19, s_d, d_d);
  576. }
  577.  
  578. void add_en(char *str)
  579. {
  580.     if((( *str != '\\') || ( *(str+1) != 0)) && !check_end_en(str) )
  581.         strcat(str,"\\");
  582. }
  583.  
  584. void del_en(char *str)
  585. {
  586.     if(((str[0] != '\\') || str[1] != 0) && check_end_en(str) )
  587.         str[strlen(str) - 1] = 0;
  588. }
  589.  
  590. void add_drive(char *d_p)
  591. {
  592.     char directory[80], dummy[3];
  593.  
  594.     if(d_p[1] == ':')
  595.         d_p[0] = (char)toupper(d_p[0]);
  596.     if(d_p[0] == '\\'){
  597.         dummy[0] = _getdrive() + 'A' -1 ;
  598.         dummy[1] = ':' ;
  599.         dummy[2] = 0   ;
  600.         strcpy(directory, d_p);
  601.         strcpy(d_p, dummy);
  602.         strcat(d_p, directory);
  603.     }
  604.     if(d_p[1] != ':'){
  605.         dummy[0] = _getdrive() + 'A' -1 ;
  606.         dummy[1] = ':' ;
  607.         dummy[2] = 0   ;
  608.  
  609.         strcpy(directory, d_p);
  610.         strcpy(d_p, dummy);
  611.         strcat(d_p, directory);
  612.     }
  613. }
  614.  
  615. int change_dir(char *path)
  616. {
  617.     union REGS regs;
  618.     struct SREGS segregs;
  619.  
  620.     segread(&segregs);
  621.     regs.h.ah = 0x3b;    /* change directory    */
  622.     regs.x.dx = FP_OFF(path);
  623.     segregs.ds = FP_SEG(path);
  624.     intdosx(®s, ®s, &segregs);
  625.     if((regs.x.cflag != 0) && (regs.x.ax == 0x03))
  626.         return(ERR_RET);
  627.     else
  628.         return(SUC_RET);
  629. }
  630.  
  631. int    analize_drive_path(char *d_p)
  632. {
  633.     char directory[80];
  634.  
  635.     yjstrupr(d_p);
  636.     if(getcurdir(*d_p - 'A' + 1, directory) != 0)
  637.         error_code = get_error_code();
  638.  
  639.     if(error_code == NO_ERROR){
  640.         _drive[0] = d_p[0] ;
  641.         _drive[1] = ':'    ;
  642.         _drive[2] = 0      ;
  643.         if(d_p[2] == '\\')
  644.             strncpy(_path, d_p + 2 , strlen(d_p) - 1);
  645.         else{    /* d_p[2] != '\\'    */
  646.             strcpy(_path, "\\");
  647.             strcat(_path, directory);
  648.             add_en(_path);
  649.             strcat(_path, d_p + 2);
  650.         }
  651.         del_en(_path);
  652.         return(SUC_RET);
  653.     }else{
  654.         disp_err_msg();    /* and exit    */
  655.         return(ERR_RET);
  656.     }
  657. }
  658.  
  659. int normalize(char *str)    /* パス等の正規化    */
  660. {
  661.     if(analize_drive_path(str) == ERR_RET)
  662.         return(ERR_RET);
  663.     else{
  664.         strcpy(str, _drive);
  665.         strcat(str, _path);
  666.         return(SUC_RET);
  667.     }
  668. }
  669.  
  670. uint uintmax(uint x, uint y)
  671. {
  672.     if(x > y)
  673.         return(x);
  674.     else
  675.         return(y);
  676. }
  677.  
  678. uint uintmin(uint x, uint y)
  679. {
  680.     if(x > y)
  681.         return(y);
  682.     else
  683.         return(x);
  684. }
  685.  
  686. ulong div_upper(ulong x, ulong y)
  687. /*  x / y の切り上げ    */
  688. {
  689.     return((x + y -1) / y);
  690. }
  691.  
  692. int do_read_write(char drive, uint sectors, ulong start_sect, char *bf, 
  693. int sw_32bit, int sw)
  694. {
  695.     if(sw_32bit)
  696.         return(ext_abs_read_write((uint)drive-'A'+1,sectors,start_sect,bf,sw));
  697.     else
  698.         return(abs_read_write((uint)drive-'A',sectors,start_sect,bf,sw));
  699. }
  700.  
  701. int    check_disk_format(char *dpb, char *check_buf)
  702. /*    uint    _sector_size;        number of bytes per sector
  703.     char    _cluster_mask;        Sectors/cluster - 1 = 2^n - 1
  704.     int        num of root entory  if 0 then 32bit FAT
  705.     uint->ulong    _first_data_sector;    first data sector on medium
  706.                                     これが一致すれば,FATもほぼ一致
  707.     uint->ulong    _max_cluster;        largest possible cluster number+1
  708.     の check.  もっと check しても良いし甘くしても良い    */
  709. {
  710.     if((*(uint *)dpb == *(uint *)(check_buf +80))
  711.     && (dpb[C_MASK] == check_buf[C_C_MASK]) 
  712.     && (*(uint *)(dpb +DIR_E) == *(uint *)(check_buf +C_DIR_E))
  713.     && (*(ulong *)(dpb +DATA_S) == *(ulong *)(check_buf +C_DATA_S))
  714.     && (*(ulong *)(dpb +MAX_C) == *(ulong *)(check_buf +C_MAX_C)))
  715.         return(1);    /* 単純 restore 可能    */
  716.     else if((*(uint *)dpb == *(uint *)(check_buf +80)) 
  717.     && (dpb[C_MASK] == check_buf[C_C_MASK]))
  718.         return(2);     /* sect_size, sect_par_cluster 一致     */
  719.     else
  720.         return(0);    /* restore 不可    */
  721. }
  722.  
  723. int    check_dir_entry_etc(char *dpb, char *check_buf)
  724. {
  725.     if((*(uint *)(dpb + DIR_E) >= *(uint *)(check_buf + USED_D)) 
  726.     && (*(ulong *)(dpb + MAX_C) >= *(ulong *)(check_buf + USED_C)))
  727.         return(1);
  728.     else
  729.         return(0);
  730. }
  731.  
  732. shift_ext_dpb(char *dpb, char *ext_dpb)
  733. {
  734.     int i;
  735.  
  736.     for(i = 0; i < 9; i++)
  737.         dpb[i] = ext_dpb[i+4];
  738.     for(i = 9; i < 21; i++)
  739.         dpb[i] = ext_dpb[i+43-9];
  740. }
  741.  
  742. void    shift_dpb(char *dpb)    /* bit32 対応の為にずらす    */
  743. {
  744.     dpb[17] = dpb[13];
  745.     dpb[18] = dpb[14];
  746.     dpb[19] = 0;
  747.     dpb[20] = 0;
  748.  
  749.     dpb[13] = dpb[11];
  750.     dpb[14] = dpb[12];
  751.     dpb[15] = 0;
  752.     dpb[16] = 0;
  753.  
  754.     dpb[9] = dpb[9];
  755.     dpb[10] = dpb[10];
  756.     dpb[11] = 0;
  757.     dpb[12] = 0;
  758. }
  759.  
  760. void set_file_name(char *file_name, char *directory, ulong start_sect, int sw)
  761. {
  762.     char f_name[14];
  763.  
  764.     sprintf(f_name, "%.8lu", start_sect);
  765.     switch(sw){
  766.         case 0:
  767.             strcat(f_name, ".DD3");
  768.             break;
  769.         case 1:
  770.             strcat(f_name, ".DDD");
  771.             break;
  772.         case 2:
  773.             strcat(f_name, ".DUP");
  774.             break;
  775.     }
  776.     strcpy(file_name, directory);
  777.     add_en(file_name);
  778.     strcat(file_name, f_name);
  779. }
  780.  
  781. int     do_compare(char *buf, char *buf2, uint comp_size)
  782. /* 比較し,不一致で 1, 一致で 0 を返す    */
  783. {
  784.     uint i;
  785.  
  786.     for(i = 0; i < comp_size; i++){
  787.         if( *(int *)(buf + 2*i) != *(int *)(buf2 + 2*i)){
  788.             ybeep();
  789.             ybeep();
  790.             break;
  791.         }
  792.     }
  793.     if(i < comp_size)
  794.         return(1);
  795.     else
  796.         return(0);
  797. }
  798.  
  799. void reset_free_clust(char *dest, uint size)
  800. /* OSR2 32bit FAT の時のみ,ioctrl は発行している    */
  801. {
  802.     uint rr_sect;
  803.  
  804.     rr_sect = (uint)div_upper((ulong)4096, (ulong)size);
  805.         /* 1024 byte 読めれば良いが余裕    */
  806.     ext_abs_read_write(*dest - 'A' +1, rr_sect, 0, buf, READ);
  807.     *(long *)(buf + 0x3e8) = 0xffffffff;
  808.     ext_abs_read_write(*dest - 'A' +1, rr_sect, 0, buf, WRITE);
  809. /*    ext_resetdisk(*dest - 'A' +1);    */
  810. }
  811.  
  812. ulong sect2clust(char *dpb, ulong sect, int sw_32bit)
  813. /* sector の入っている cluster を返す    */
  814. /*     (ulong)(*(uint *)(dpb + FAT_S))    
  815.        + (*(ulong *)(dpb + S_P_FAT) * 2) 
  816.     = *(ulong *)(dpb + DATA_S)  (32bit FAT時)
  817.  
  818.     (ulong)(*(uint *)(dpb + FAT_S)) 
  819.     + (*(ulong *)(dpb + S_P_FAT) * 2)
  820.     + ((ulong)(*(uint *)(dpb + DIR_E))*32)
  821.      /(ulong)(*(uint *)dpb)
  822.     = *(ulong *)(dpb + DATA_S) (16bit FAT時)である.    */
  823. {
  824.     ulong    clust;
  825.  
  826.     clust = (sect - *(ulong *)(dpb + DATA_S)) / ((ulong)dpb[C_MASK] +1);
  827.        clust += 2;
  828.     return(clust);
  829. }
  830.  
  831. ulong clust2sect(char *dpb, ulong clust)
  832. /* cluster の先頭 sector を返す    */
  833. {
  834.     return((clust - 2)*((ulong)dpb[C_MASK] +1)+ (*(ulong *)(dpb + DATA_S)));
  835. }
  836.  
  837. ulong    get_true_end_sect(char *dpb, char *drive, ulong *used, int _32bit)
  838. /* 実際は,end_sect +1 を返す.used_clustも使用しているclust+1    */
  839. /* ここで,bad_clust[], bad_clust_num も set する                */
  840. {
  841.     ulong last_clust, max_clust, sect, end_sect;
  842.     uint  i, j, rest_fat, rr_sect, mult_K ,     /* buffer size を何回読むか    */
  843.           rest_sect, num_clust;
  844.  
  845.     for(i = 0; i < 80; i++)
  846.         *(long *)(bad_clust+ 4*i) = 0;
  847.     max_clust = *(ulong *)(dpb + MAX_C) +1;    /* IPL, FAT部分加える    */
  848.  
  849.     if(_32bit){
  850.         if(big_buf)
  851.             num_clust = (uint)(BUF_UNIT / 2);/* 1度に読む FATの cluster 数    */
  852.         else
  853.             num_clust = (uint)(BUF_UNIT / 4);
  854.         mult_K = (uint)(max_clust / (ulong)num_clust);
  855.         rest_fat = (uint)(max_clust - mult_K*(ulong)num_clust);
  856.         rr_sect = (uint)(buf_size / (ulong)(*(uint *)dpb));
  857.  
  858.         for(i = 0; i < mult_K; i++){
  859.             sect = (ulong)(*(uint *)(dpb + FAT_S)) + (ulong)rr_sect*i;
  860.             if(ext_abs_read_write(*drive - 'A' +1, rr_sect, sect, buf, READ))
  861.                 disp_msg(28, drive, "");
  862.             for(j = 0; j < num_clust; j++){
  863.                 if(*(ulong *)(buf + 4*j) == (ulong)0xffffff7){
  864.                     if(bad_clust_num < 80)
  865.                         *(ulong *)(bad_clust + 4*bad_clust_num)
  866.                         = (ulong)i*num_clust + j ;
  867.                     bad_clust_num ++;    /* 不良 cluster */
  868.                 }else if( *(ulong *)(buf + 4*j) != 0)
  869.                     last_clust = (ulong)i*num_clust + j;
  870.             }
  871.         }
  872.         sect = (ulong)(*(uint *)(dpb + FAT_S)) + rr_sect*mult_K;
  873.         rest_sect = (uint)div_upper((ulong)(rest_fat)*4,(ulong)(*(uint *)dpb));
  874.  
  875.         if(rest_sect){
  876.             if(ext_abs_read_write(*drive - 'A' +1, rest_sect, sect,buf,READ))
  877.                 disp_msg(28, drive, "");
  878.             for(j = 0; j < rest_fat; j++){
  879.                 if(*(ulong *)(buf + 4*j) == (ulong)0xffffff7){
  880.                     if(bad_clust_num < 80)
  881.                         *(ulong *)(bad_clust + 4*bad_clust_num) 
  882.                         = (ulong)mult_K*num_clust + j ;
  883.                     bad_clust_num ++;    /* 不良 cluster */
  884.                 }else if( *(ulong *)(buf + 4*j) != 0)
  885.                     last_clust = mult_K*num_clust + j;
  886.             }
  887.         }
  888.     }else{
  889.         if(max_clust <= 0xff4){    /* 12bit_fat    */
  890.             num_clust = 0x4000;    /* 1度に読む FATの cluster 数    */
  891.                                 /* buffer に 0x6000 必要        */
  892.             mult_K = (uint)(max_clust / (ulong)num_clust);
  893.             rr_sect = (uint)((0x6000L / (ulong)(*(uint *)dpb)));    
  894.             rest_fat = (uint)(max_clust - mult_K*(ulong)num_clust);
  895.  
  896.             for(i = 0; i < mult_K; i++){
  897.                 sect = (ulong)(*(uint *)(dpb + FAT_S)) + (ulong)rr_sect*i;
  898.                 if(abs_read_write(*drive - 'A', rr_sect, sect, buf, READ))
  899.                     disp_msg(28, drive, "");
  900.                 for(j = 0; j < num_clust; j++){
  901.                     if(j & 1){    /* 奇数なら    */
  902.                         if(((uchar)(buf[(j*3)/ 2] & 0xf0) == (uchar)0x70)
  903.                         && ((uchar)buf[((j*3)/ 2) +1] == (uchar)0xff)){
  904.                             if(bad_clust_num < 80)
  905.                                 *(uint *)(bad_clust + 2*bad_clust_num) = j;
  906.                             bad_clust_num ++;    /* 不良 cluster */
  907.                         }else if((buf[(j*3)/ 2] & 0xf0) || buf[((j*3)/ 2) +1]) 
  908.                             last_clust = (ulong)i*num_clust + j;
  909.                     }else{    /* 偶数なら    */
  910.                         if(((uchar)buf[(j*3)/ 2] == (uchar)0xf7)
  911.                         && ((uchar)(buf[((j*3)/ 2) +1] & 0x0f)==(uchar)0x0f)){
  912.                             if(bad_clust_num < 80)
  913.                                 *(uint *)(bad_clust + 2*bad_clust_num) = j;
  914.                             bad_clust_num ++;    /* 不良 cluster */
  915.                         }else if((buf[(j*3)/ 2])||((buf[((j*3)/ 2) +1])& 0x0f))
  916.                             last_clust = (ulong)i*num_clust + j;
  917.                     }
  918.                 }
  919.             }
  920.  
  921.             sect = (ulong)(*(uint *)(dpb + FAT_S)) + rr_sect*mult_K;
  922.             rest_sect = (uint)div_upper((ulong)(rest_fat*3 + 1)/2, 
  923.                         (ulong)(*(uint *)dpb));
  924.             if(rest_sect){
  925.                 if(abs_read_write(*drive - 'A', rest_sect, sect, buf, READ))
  926.                     disp_msg(28, drive, "");
  927.                 for(j = 0; j < rest_fat; j++){
  928.                     if(j & 1){    /* 奇数なら    */
  929.                         if(((uchar)(buf[(j*3)/ 2] & 0xf0) == (uchar)0x70)
  930.                         && ((uchar)buf[((j*3)/ 2) +1] == (uchar)0xff)){
  931.                             if(bad_clust_num < 80)
  932.                                 *(uint *)(bad_clust + 2*bad_clust_num) = j;
  933.                             bad_clust_num ++;    /* 不良 cluster */
  934.                         }else if((buf[(j*3)/ 2] & 0xf0) || buf[((j*3)/ 2) +1]) 
  935.                             last_clust = mult_K*num_clust + j;
  936.                     }else{    /* 偶数なら    */
  937.                         if(((uchar)buf[(j*3)/ 2] == (uchar)0xf7)
  938.                         && ((uchar)(buf[((j*3)/ 2) +1] & 0x0f)==(uchar)0x0f)){
  939.                             if(bad_clust_num < 80)
  940.                                 *(uint *)(bad_clust + 2*bad_clust_num) = j;
  941.                             bad_clust_num ++;    /* 不良 cluster */
  942.                         }else if((buf[(j*3)/ 2])||((buf[((j*3)/ 2) +1])& 0x0f))
  943.                             last_clust = mult_K*num_clust + j;
  944.                     }
  945.                 }
  946.             }
  947.         }else{    /* 16bit_fat    */
  948.             if(big_buf)
  949.                 num_clust = (uint)BUF_UNIT;    /* 1度に読む FATの cluster 数    */
  950.             else
  951.                 num_clust = (uint)(BUF_UNIT / 2);
  952.             mult_K = (uint)(max_clust / (ulong)num_clust);
  953.             rest_fat = (uint)(max_clust - mult_K*(ulong)num_clust);
  954.             rr_sect = (uint)(buf_size / (ulong)(*(uint *)dpb));
  955.  
  956.             for(i = 0; i < mult_K; i++){
  957.                 sect = (ulong)(*(uint *)(dpb + FAT_S)) + (ulong)rr_sect*i;
  958.                 if(abs_read_write(*drive - 'A', rr_sect, sect, buf, READ))
  959.                     disp_msg(28, drive, "");
  960.                 for(j = 0; j < num_clust; j++){
  961.                     if(*(uint *)(buf + 2*j) == (uint)0xfff7){
  962.                         if(bad_clust_num < 80)
  963.                             *(uint *)(bad_clust + 2*bad_clust_num) = j;
  964.                         bad_clust_num ++;    /* 不良 cluster */
  965.                     }else if(*(uint *)(buf + 2*j) != 0)
  966.                         last_clust = (ulong)i*num_clust + j;
  967.                 }
  968.             }
  969.             sect = (ulong)(*(uint *)(dpb + FAT_S)) + rr_sect*mult_K;
  970.             rest_sect = (uint)div_upper((ulong)rest_fat*2, 
  971.                         (ulong)(*(uint *)dpb)); 
  972.             if(rest_sect){
  973.                 if(abs_read_write(*drive - 'A', rest_sect, sect, buf, READ))
  974.                     disp_msg(28, drive, "");
  975.                 for(j = 0; j < rest_fat; j++){
  976.                     if(*(uint *)(buf + 2*j) == (uint)0xfff7){
  977.                         if(bad_clust_num < 80)
  978.                             *(uint *)(bad_clust + 2*bad_clust_num) = j;
  979.                         bad_clust_num ++;    /* 不良 cluster */
  980.                     }else if(*(uint *)(buf + 2*j) != 0)
  981.                         last_clust = mult_K*num_clust + j;
  982.                 }
  983.             }
  984.         }
  985.     }
  986.     resetdisk();
  987.  
  988.     end_sect = clust2sect(dpb, last_clust +1);
  989.     *used = last_clust;
  990.     return(end_sect);
  991. }
  992.  
  993. int make_bad_sect_table(char *dpb, uint rr_sect, ulong sect, 
  994.                            char *table, int sw_32bit)
  995. /* if error sector is not recorded return 1, else return 0    */
  996. {
  997.     uint i, j, k;
  998.     ulong clust, s_sect, e_sect;
  999.  
  1000.     if(rewrite_flag)
  1001.         disp_msg(44, "", "");
  1002.  
  1003.     if(bad_clust_num == 0)
  1004.         return(1);
  1005.     for(i = 0; i < rr_sect; i++)
  1006.         table[i] = 0;
  1007.     for(i = 0; (i < bad_clust_num) && (i < 80); i++){
  1008.         if(sw_32bit)
  1009.             clust = *(ulong *)(bad_clust + 4*i);
  1010.         else
  1011.             clust = (ulong)*(uint *)(bad_clust + 2*i);
  1012.         s_sect = clust2sect(dpb, clust);
  1013.         e_sect = clust2sect(dpb, clust +1);
  1014.  
  1015.         j = 0;
  1016.         while(j < rr_sect){
  1017.             if((s_sect <= sect + j) && (sect +j < e_sect)){ 
  1018.                 for(k =0;((k < (uint)(e_sect- s_sect))&&((j+k) < rr_sect));k++)
  1019.                     table[j + k] = 1;    /* 1 cluster 分 mark    */
  1020.                 j += k;
  1021.             }else    /* if(sect +j >= e_sect)... としても早くならないだろう */
  1022.                 j ++;
  1023.         }
  1024.     }
  1025.     for(i = 0; i < rr_sect; i++){
  1026.         if(table[i])
  1027.             break;
  1028.     }
  1029.     if(i == rr_sect)    /* error sector is not recorded    */
  1030.         return(1);
  1031.     else
  1032.         return(0);
  1033. }
  1034.  
  1035. int    get_bad_clust_num()
  1036. {
  1037.     int i, bad = 0;
  1038.  
  1039.     if(des_32bit){
  1040.         for(i = 0; i < 80; i ++){
  1041.             if(*(ulong *)(bad_clust + 4*i))
  1042.                 bad ++;
  1043.             else
  1044.                 break;
  1045.         }
  1046.     }else{
  1047.         for(i = 0; i < 80; i ++){
  1048.             if(*(uint *)(bad_clust + 2*i))
  1049.                 bad ++;
  1050.             else
  1051.                 break;
  1052.         }
  1053.     }
  1054.     return(bad);
  1055. }
  1056.  
  1057. void rewrite_old(char *dest, ulong old_clust, uint dir_clust, char *dest_dpb)
  1058. {    /* xxxx.DAT の FAT の作成    32bit FAT 以外では dir_clust = 1    */
  1059.     ulong sect, ssect, max_clust;
  1060.     uint  sect_p_fat, rr_sect, sect_size;
  1061.  
  1062.     if(old_clust == dir_clust + 1)
  1063.         return;
  1064.  
  1065.     sect_size = *(uint *)dest_dpb;
  1066.     sect_p_fat = *(uint *)(dest_dpb + S_P_FAT);
  1067.     max_clust = *(ulong *)(dest_dpb + MAX_C) +1;
  1068.  
  1069.     if(des_32bit){
  1070.         ssect = (old_clust*4) / (ulong)sect_size;
  1071.         sect = ssect + (ulong)(*(uint *)(dest_dpb + FAT_S));
  1072.         if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,READ))
  1073.             disp_msg(33, "", dest);
  1074.         *(ulong *)(buf + (uint)(old_clust*4L - ssect*sect_size)) = 0L;
  1075.         if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,WRITE))
  1076.             disp_msg(33, "", dest);
  1077.         resetdisk();
  1078.         ext_abs_read_write(*dest-'A'+1,1,sect+sect_p_fat,buf,WRITE);
  1079.         resetdisk();
  1080.  
  1081.         sect = (ulong)(*(uint *)(dest_dpb + FAT_S));
  1082.         if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,READ))
  1083.             disp_msg(33, "", dest);
  1084.         *(ulong *)(buf + (uint)((dir_clust + 1)*4)) = 0x0fffffffL;
  1085.         if(ext_abs_read_write(*dest-'A'+1,1,sect,buf,WRITE))
  1086.             disp_msg(33, "", dest);
  1087.         resetdisk();
  1088.         ext_abs_read_write(*dest-'A'+1,1,sect+sect_p_fat,buf,WRITE);
  1089.         resetdisk();
  1090.     }else{
  1091.         if(max_clust <= (ulong)0xff4){    /* 12bit_fat    */
  1092.             sect = (ulong)(*(uint *)(dest_dpb + FAT_S));
  1093.             rr_sect = (uint)div_upper((max_clust*3 +1)/ 2 , 
  1094.                       (ulong)(*(uint *)dest_dpb));
  1095.             if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
  1096.                 disp_msg(33, "", dest);
  1097.             buf[(uint)((old_clust*3))/ 2] = 0;
  1098.             buf[((uint)(old_clust*3)/2) +1] = 0;
  1099.             if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
  1100.                 disp_msg(33, "", dest);
  1101.             resetdisk();
  1102.             abs_read_write(*dest -'A',rr_sect,sect +sect_p_fat,buf, WRITE);
  1103.             resetdisk();
  1104.  
  1105.             if(abs_read_write(*dest-'A',1,sect,buf,READ))
  1106.                 disp_msg(33, "", dest);
  1107.             buf[4] = (uchar)(buf[4] & 0x0f0) + (uchar)0xf;
  1108.             buf[3] = (uchar)(0x0ff);
  1109.             if(abs_read_write(*dest -'A',1,sect,buf, WRITE))
  1110.                 disp_msg(33, "", dest);
  1111.             resetdisk();
  1112.             abs_read_write(*dest -'A',1,sect +sect_p_fat,buf, WRITE);
  1113.             resetdisk();
  1114.         }else{
  1115.             ssect = (old_clust*2L) / (ulong)sect_size;
  1116.             sect = ssect + (ulong)(*(uint *)(dest_dpb + FAT_S));
  1117.             if(abs_read_write(*dest-'A',1,sect,buf,READ))
  1118.                 disp_msg(33, "", dest);
  1119.             *(uint *)(buf + (uint)(old_clust*2L - ssect*sect_size)) = 0;
  1120.             if(abs_read_write(*dest-'A',1,sect,buf,WRITE))
  1121.                 disp_msg(33, "", dest);
  1122.             resetdisk();
  1123.             abs_read_write(*dest-'A',1,sect+sect_p_fat,buf,WRITE);
  1124.             resetdisk();
  1125.  
  1126.             sect = (ulong)(*(uint *)(dest_dpb + FAT_S));
  1127.             if(abs_read_write(*dest-'A',1,sect,buf,READ))
  1128.                 disp_msg(33, "", dest);
  1129.             *(uint *)(buf + 2) = 0xffff;
  1130.             if(abs_read_write(*dest-'A',1,sect,buf,WRITE))
  1131.                 disp_msg(33, "", dest);
  1132.             resetdisk();
  1133.             abs_read_write(*dest-'A',1,sect+sect_p_fat,buf,WRITE);
  1134.             resetdisk();
  1135.         }
  1136.     }
  1137. }
  1138.  
  1139. void rewrite_fat_to0(char *dest, char *dest_dpb)
  1140. {    /* dest の最初の部分以外の FAT の中身を 0 にする    */
  1141.     ulong     sect;
  1142.     uint     i, j, sect_size, sect_p_fat, start_num, 
  1143.             mult_K, r_sect, rest_sect;
  1144.  
  1145.     sect_p_fat = *(uint *)(dest_dpb + S_P_FAT);
  1146.     sect_size = *(uint *)dest_dpb;
  1147.     mult_K = (uint)(((ulong)sect_size * (ulong)sect_p_fat) / 0x6000);
  1148.             /* 0x6000 は 0x8000以下で3の倍数で選んだ */
  1149.     rest_sect = sect_p_fat - (0x6000 / sect_size)*mult_K;
  1150.     r_sect = 0x6000 / sect_size;
  1151.  
  1152.     for(i = 0; i < mult_K; i++){
  1153.         sect = (ulong)r_sect * (ulong)i;
  1154.         sect += (ulong)(*(uint *)(dest_dpb + FAT_S));
  1155.         if(do_read_write(*dest, r_sect, sect, buf, des_32bit, READ))
  1156.             disp_msg(33, "", dest);
  1157.         if(i == 0)
  1158.             start_num = 4;     /* 12 bit FAT もこれで行く    */
  1159.         else
  1160.             start_num = 0;
  1161.         for(j = start_num; j < (0x6000 / 4); j++)
  1162.             *(ulong *)(buf + 4*j) = 0L;
  1163.         if(do_read_write(*dest, r_sect, sect, buf, des_32bit, WRITE))
  1164.             disp_msg(33, "", dest);
  1165.         resetdisk();
  1166.         do_read_write(*dest, r_sect, sect +sect_p_fat, buf, des_32bit, WRITE);
  1167.         resetdisk();
  1168.     }
  1169.     if(rest_sect){
  1170.         sect = (ulong)r_sect * (ulong)mult_K;
  1171.         sect += (ulong)(*(uint *)(dest_dpb + FAT_S));
  1172.         if(do_read_write(*dest, rest_sect, sect, buf, des_32bit, READ))
  1173.             disp_msg(33, "", dest);
  1174.         if(mult_K == 0)
  1175.             start_num = 4;     /* 12 bit FAT もこれで行く    */
  1176.         else
  1177.             start_num = 0;
  1178.         for(j = start_num; j < ((sect_size*rest_sect) / 4); j++)
  1179.             *(ulong *)(buf + 4*j) = 0L;
  1180.  
  1181.         if(do_read_write(*dest, rest_sect, sect, buf, des_32bit, WRITE))
  1182.             disp_msg(33, "", dest);
  1183.         resetdisk();
  1184.         do_read_write(*dest, rest_sect, sect +sect_p_fat,buf,des_32bit,WRITE);
  1185.         resetdisk();
  1186.     }
  1187. }
  1188.  
  1189. void rewrite_fat(char *dest, ulong w_sect, ulong f_size, char *dest_dpb)
  1190. {
  1191.     ulong     last_clust, sect, clust_num, max_clust;
  1192.     uint     rr_sect, rest_fat, mult_K, num_clust, 
  1193.              i, j, start, start_clust, int_clust_num, s_p_fat,
  1194.             w_s_size, fat_sect;
  1195.  
  1196.     start_clust = (uint)sect2clust(dest_dpb, w_sect, des_32bit);
  1197.     /*  start_clust は十分小さいと想定    */
  1198.     w_s_size = *(uint *)dest_dpb;
  1199.     fat_sect = *(uint *)(dest_dpb + FAT_S);
  1200.     sect = div_upper(f_size, (ulong)w_s_size);
  1201.     last_clust = div_upper(sect, ((ulong)dest_dpb[C_MASK] +1));
  1202.     last_clust-- ;    /* 0,1,2,...,last_clust  に記録する    */
  1203.     last_clust += start_clust;
  1204.     s_p_fat = *(uint *)(dest_dpb + S_P_FAT);
  1205.  
  1206.     if(des_32bit){
  1207.         if(big_buf)
  1208.             num_clust = (uint)(BUF_UNIT / 2);/* 1度に読む FATの cluster 数    */
  1209.         else
  1210.             num_clust = (uint)(BUF_UNIT / 4);
  1211.         mult_K = (uint)(last_clust / (ulong)num_clust);
  1212.         rest_fat = (uint)(last_clust - mult_K*(ulong)num_clust);
  1213.         rr_sect = (uint)(buf_size / (ulong)w_s_size);
  1214.         clust_num = start_clust + 1;
  1215.  
  1216.         for(i = 0; i < mult_K; i++){
  1217.             sect = (buf_size / (ulong)w_s_size) *i + (ulong)fat_sect;
  1218.             if(ext_abs_read_write(*dest -'A'+1,rr_sect,sect,buf,READ))
  1219.                 disp_msg(33, "", dest);
  1220.             if(i == 0)
  1221.                 start = start_clust;
  1222.             else
  1223.                 start = 0;
  1224.             for(j = start; j < num_clust; j++){
  1225.                 *(ulong *)(buf + 4*j) = clust_num;
  1226.                 clust_num ++ ;
  1227.             }
  1228.  
  1229.             if(ext_abs_read_write(*dest -'A'+1,rr_sect,sect,buf,WRITE))
  1230.                 disp_msg(33, "", dest);
  1231.             resetdisk();
  1232.             ext_abs_read_write(*dest -'A'+1,rr_sect,sect +s_p_fat, buf,WRITE);
  1233.             resetdisk();
  1234.         }
  1235.  
  1236.         sect = (buf_size / (ulong)w_s_size)*mult_K + (ulong)fat_sect;
  1237.         rr_sect = (uint)((rest_fat*4 + w_s_size) / (ulong)w_s_size);
  1238.         if(ext_abs_read_write(*dest -'A' +1,rr_sect,sect,buf,READ))
  1239.             disp_msg(33, "", dest);
  1240.         if(mult_K == 0)
  1241.             start = start_clust;
  1242.         else
  1243.             start = 0;
  1244.         for(j = start; j < rest_fat; j++){
  1245.             *(ulong *)(buf + 4*j) = clust_num;
  1246.             clust_num ++ ;
  1247.         }
  1248.         *(ulong *)(buf + 4*rest_fat) = 0x0fffffff;    /* 終了    */
  1249.  
  1250.         for(j = rest_fat + 1; j < num_clust; j++)
  1251.             *(ulong *)(buf + 4*j) = 0;
  1252.  
  1253.         if(ext_abs_read_write(*dest-'A'+1,rr_sect,sect,buf,WRITE))
  1254.             disp_msg(33, "", dest);
  1255.         resetdisk();
  1256.         ext_abs_read_write(*dest-'A'+1, rr_sect,sect +s_p_fat, buf, WRITE);
  1257.         resetdisk();
  1258.     }else{
  1259.         max_clust = *(ulong *)(dest_dpb + MAX_C) +1; /* IPL, FAT部分加える */
  1260.         int_clust_num = start_clust +1;
  1261.         if(max_clust <= (ulong)0xff4){    /* 12bit_fat    */
  1262.             num_clust = 0x4000;    /* 1度に読む FATの cluster 数    */
  1263.                                 /* buffer に 0x6000 必要        */
  1264.             mult_K = (uint)(last_clust / (ulong)num_clust);
  1265.             rr_sect = (uint)(0x6000L / (ulong)w_s_size);    
  1266.             rest_fat = (uint)(last_clust - mult_K*(ulong)num_clust);
  1267.  
  1268.             for(i = 0; i < mult_K; i++){
  1269.                 sect = (ulong)fat_sect + (ulong)rr_sect*i;
  1270.                 if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
  1271.                     disp_msg(33, "", dest);
  1272.                 for(j = start_clust; j < (uint)num_clust; j++){ 
  1273.                     if(j & 1){    /* 奇数なら    */
  1274.                         buf[(j*3)/ 2] = (uchar)(buf[(j*3)/ 2] & 0x00f)
  1275.                                     + (uchar)((int_clust_num & 0x00f) << 4);
  1276.                         buf[((j*3)/2) +1]=(uchar)((int_clust_num & 0xff0) >>4);
  1277.                         int_clust_num ++;
  1278.                     }else{    /* 偶数なら    */
  1279.                         buf[((j*3)/ 2) +1] =(uchar)(buf[((j*3)/ 2) +1] & 0x0f0)
  1280.                                     + (uchar)((int_clust_num & 0xf00) >> 8);
  1281.                         buf[((j*3)/ 2)] = (uchar)(int_clust_num & 0x0ff);
  1282.                         int_clust_num ++;
  1283.                     }
  1284.                 }
  1285.                 if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
  1286.                     disp_msg(33, "", dest);
  1287.                 resetdisk();
  1288.                 abs_read_write(*dest-'A',rr_sect,sect +s_p_fat, buf,WRITE);
  1289.                 resetdisk();
  1290.             }
  1291.             sect = (ulong)fat_sect + rr_sect*mult_K;
  1292.             rr_sect = (uint)div_upper(((ulong)rest_fat*3 + 1) /2, 
  1293.                     (ulong)(*(uint *)dest_dpb));
  1294.  
  1295.             if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
  1296.                 disp_msg(33, "", dest);
  1297.  
  1298.             if(mult_K == 0)
  1299.                 start = start_clust;
  1300.             else
  1301.                 start = 0;
  1302.  
  1303.             for(j = start; j < rest_fat; j++){
  1304.                 if(j & 1){    /* 奇数なら    */
  1305.                     buf[(j*3)/ 2] = (uchar)(buf[(j*3)/ 2] & 0x00f)
  1306.                                 + (uchar)((int_clust_num & 0x00f) << 4);
  1307.                     buf[((j*3)/2) +1]=(uchar)((int_clust_num & 0xff0) >>4);
  1308.                     int_clust_num ++;
  1309.                 }else{    /* 偶数なら    */
  1310.                     buf[((j*3)/ 2) +1] =(uchar)(buf[((j*3)/ 2) +1] & 0x0f0)
  1311.                                 + (uchar)((int_clust_num & 0xf00) >> 8);
  1312.                     buf[((j*3)/ 2)] = (uchar)(int_clust_num & 0x0ff);
  1313.                     int_clust_num ++;
  1314.                 }
  1315.             }
  1316.             if(rest_fat & 1){    /* 最終マーク 奇数なら    */
  1317.                 buf[(rest_fat*3)/ 2] = (uchar)(buf[(rest_fat*3)/ 2] & 0x00f)
  1318.                                 + (uchar)0x00f0;
  1319.                 buf[((rest_fat*3)/2) +1] = (uchar)(0x0ff);
  1320.             }else{    /* 最終マーク 偶数なら    */
  1321.                 buf[((rest_fat*3)/ 2) +1] = (uchar)(0x00f);
  1322.                 buf[((rest_fat*3)/ 2)] = (uchar)0x0ff;
  1323.             }
  1324.             for(j = rest_fat + 1; j < num_clust; j++){
  1325.                 if(j & 1){    /* 奇数なら    */
  1326.                     buf[(j*3)/ 2] = (uchar)(buf[(j*3)/ 2] & 0x00f);
  1327.                     buf[((j*3)/2) +1] = 0;
  1328.                 }else{    /* 偶数なら    */
  1329.                     buf[((j*3)/ 2) +1] =(uchar)(buf[((j*3)/ 2) +1] & 0x0f0);
  1330.                     buf[((j*3)/ 2)] = 0;
  1331.                 }
  1332.             }
  1333.  
  1334.             if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
  1335.                 disp_msg(33, "", dest);
  1336.             resetdisk();
  1337.             abs_read_write(*dest-'A',rr_sect,sect +s_p_fat, buf,WRITE);
  1338.             resetdisk();
  1339.         }else{    /* 16bit_fat    */
  1340.             if(big_buf)
  1341.                 num_clust = (uint)BUF_UNIT;    /* 1度に読む FATの cluster 数    */
  1342.             else
  1343.                 num_clust = (uint)(BUF_UNIT / 2);
  1344.             mult_K = (uint)(last_clust/ num_clust);
  1345.             rest_fat = (uint)(last_clust - mult_K*num_clust);
  1346.             rr_sect = (uint)(buf_size / (ulong)w_s_size);
  1347.  
  1348.             for(i = 0; i < mult_K; i++){
  1349.                 sect = (buf_size / (ulong)w_s_size)*i + (ulong)fat_sect;
  1350.                 if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
  1351.                     disp_msg(33, "", dest);
  1352.                 if(i == 0)
  1353.                     start = start_clust;
  1354.                 else
  1355.                     start = 0;
  1356.                 for(j = start; j < num_clust; j++){
  1357.                     *(uint *)(buf + 2*j) = int_clust_num;
  1358.                     int_clust_num ++ ;
  1359.                 }
  1360.                 if(abs_read_write(*dest -'A',rr_sect,sect,buf, WRITE))
  1361.                     disp_msg(33, "", dest);
  1362.                 resetdisk();
  1363.                 abs_read_write(*dest-'A',rr_sect,sect +s_p_fat,buf,WRITE);
  1364.                 resetdisk();
  1365.             }
  1366.             sect = (buf_size / (ulong)w_s_size)*mult_K + (ulong)fat_sect;
  1367.             rr_sect = (uint)((rest_fat*2 + w_s_size) / (ulong)w_s_size);
  1368.             if(abs_read_write(*dest-'A',rr_sect,sect,buf,READ))
  1369.                 disp_msg(33, "", dest);
  1370.             if(mult_K == 0)
  1371.                 start = start_clust;
  1372.             else
  1373.                 start = 0;
  1374.             for(j = start; j < rest_fat; j++){
  1375.                 *(uint *)(buf + 2*j) = int_clust_num;
  1376.                 int_clust_num ++ ;
  1377.             }
  1378.             *(uint *)(buf + 2*rest_fat) = 0xffff;    /* 終了    */
  1379.             for(j = rest_fat + 1; j < num_clust; j++)
  1380.                 *(uint *)(buf + 2*j) = 0;
  1381.  
  1382.             if(abs_read_write(*dest-'A',rr_sect,sect,buf,WRITE))
  1383.                 disp_msg(33, "", dest);
  1384.             resetdisk();
  1385.             abs_read_write(*dest-'A',rr_sect,sect +s_p_fat,buf,WRITE);
  1386.             resetdisk();
  1387.         }
  1388.     }
  1389. }
  1390.  
  1391. void    write_null_dir_entry(char *d_d, char *dest_dpb)
  1392. {    /* dest の directory entry を 0 で埋める    */
  1393.     ulong i, sect;
  1394.     uint  sect_size, need_sect, rest_sect, ww_sect, dir_entries, mult_K;
  1395.  
  1396.     dir_entries = *(uint *)(dest_dpb + DIR_E);
  1397.     sect_size = *(uint *)dest_dpb;
  1398.     need_sect = (uint)div_upper((ulong)dir_entries, (ulong)(sect_size /32));
  1399.  
  1400.     mult_K = (uint)(((ulong)need_sect*(ulong)sect_size) / buf_size);
  1401.     rest_sect = need_sect - mult_K*(uint)(buf_size / sect_size);
  1402.     for(i = 0; i < buf_size / 4; i++)
  1403.         *(ulong *)(buf + 4*i) = 0L;
  1404.  
  1405.     ww_sect = (uint)(buf_size / sect_size) ;
  1406.     sect = (ulong)(*(uint *)(dest_dpb + FAT_S)) 
  1407.            + *(ulong *)(dest_dpb + S_P_FAT)*2L;
  1408.         /* FAT_start_sect + Num_of_FAT*FAT_sect    */
  1409.  
  1410.     for(i = 0; i < mult_K; i++){
  1411.         if(do_read_write(*d_d, ww_sect, sect, buf, des_32bit, WRITE))
  1412.             disp_msg(33, "", d_d);
  1413.         resetdisk();
  1414.         sect += ww_sect;
  1415.     }
  1416.     if(rest_sect){
  1417.         if(do_read_write(*d_d, rest_sect, sect, buf, des_32bit, WRITE))
  1418.             disp_msg(33, "", d_d);
  1419.         resetdisk();
  1420.     }
  1421. }
  1422.  
  1423. uint get_used_dir_entry(char *source, char *so_dpb)
  1424. {
  1425.     ulong    dir_sect;
  1426.     uint    max_dir_entry, dir_entry = 0, sect_size;
  1427.     int        i, null_check = 0;        /* dir entory 先頭の 00 を check    */
  1428.  
  1429.     if(so_32bit)
  1430.         return(0);
  1431.     else{
  1432.         dir_sect = (ulong)(*(uint *)(so_dpb + FAT_S)) 
  1433.                     + *(ulong *)(so_dpb + S_P_FAT)*2L;
  1434.         max_dir_entry = *(uint *)(so_dpb + DIR_E);
  1435.         sect_size = *(uint *)so_dpb;
  1436.         while( (!null_check) && (dir_entry < max_dir_entry)){
  1437.             if(do_read_write(*source, 1, dir_sect,buf,so_32bit,READ))
  1438.                 disp_msg(11, source, "");
  1439.             resetdisk();
  1440.             for(i = 0; i < (int)(sect_size / 32); i++){
  1441.                 if(buf[i*32] == 0){
  1442.                     null_check = 1;
  1443.                     break;
  1444.                 }else
  1445.                     dir_entry ++;
  1446.             }
  1447.             dir_sect++;
  1448.         }
  1449.         return(dir_entry);
  1450.     }
  1451. }
  1452.  
  1453. void    write_ipl(char *s_d, char *d_d, char *dest_dpb, char *check_buf, 
  1454.         char *f_name)
  1455. /* ipl は Win95 でも ipl の backup 迄は 32K 以内としておく    */
  1456. {
  1457.     FILE     *stream;
  1458.     uint     i, fat_sect22, ipl_backup, ipl_backup2, 
  1459.             w_s_size = *(uint *)dest_dpb, 
  1460.             fat_sect = *(uint *)(check_buf +C_FAT_S),
  1461.             fat_sect2 = *(uint *)(dest_dpb + FAT_S); 
  1462.  
  1463.     if(do_read_write(*d_d, 1, 0, buf, des_32bit, READ))
  1464.         disp_msg(40, "", d_d);
  1465.     resetdisk();
  1466.     if(des_32bit){
  1467.         ipl_backup = *(uint *)(check_buf +C_IPL_B);
  1468.         ipl_backup2 = *(uint *)(buf +IPL_B);
  1469.     }
  1470.  
  1471.     printf("\nNow Writing IPL.\n");
  1472.  
  1473.     if((stream = fopen(f_name, "rb")) == NULL)
  1474.         disp_msg(24, s_d, d_d);
  1475.     fseek(stream, 512, SEEK_SET);
  1476.     if(!fread(buf, fat_sect*w_s_size, 1, stream))
  1477.         disp_msg(22, s_d, d_d);
  1478.     if(fclose(stream))
  1479.         disp_msg(25, s_d, d_d);
  1480.     resetdisk();
  1481.  
  1482.     if(!des_32bit){
  1483.         fat_sect22 = uintmax(fat_sect, fat_sect2);
  1484.         if(do_read_write(*d_d, fat_sect22, 0, buf2, des_32bit, READ))
  1485.             disp_msg(42, s_d, d_d);
  1486.         for(i = 0x0e; i < 0x27; i++)
  1487.             buf[i] = buf2[i];
  1488.  
  1489.         if(fat_sect2 > fat_sect)
  1490.             for(i = w_s_size*fat_sect; i < w_s_size*fat_sect2; i++)
  1491.                 buf[i] = 0;
  1492.         if(do_read_write(*d_d, fat_sect2, 0, buf, des_32bit, WRITE))
  1493.             disp_msg(21, s_d, d_d);
  1494.     }else{
  1495.         if(do_read_write(*d_d, ipl_backup2, 0, buf2, des_32bit, READ))
  1496.             disp_msg(42, s_d, d_d);
  1497.  
  1498.         for(i = 0x0e; i < 0x40; i++)    /* 書き換え    */
  1499.             buf[i] = buf2[i];
  1500.  
  1501.         if(ipl_backup < ipl_backup2){
  1502.             for(i = w_s_size*ipl_backup; i < w_s_size*ipl_backup2;i++)
  1503.                 buf[i] = 0;
  1504.         }
  1505.         if(do_read_write(*d_d, ipl_backup2, 0, buf, des_32bit, WRITE))
  1506.             disp_msg(21, s_d, d_d);
  1507.         if(do_read_write(*d_d, ipl_backup2, (ulong)ipl_backup2, buf, des_32bit,
  1508.         WRITE))
  1509.             disp_msg(21, s_d, d_d);
  1510.         resetdisk();
  1511.  
  1512.         if(ipl_backup2*2 < fat_sect2){
  1513.             for(i = 0; i < w_s_size*(fat_sect2 - ipl_backup2*2); i++)
  1514.                 buf[i] = 0;
  1515.             if(do_read_write(*d_d, fat_sect2 - ipl_backup2*2, (ulong)(ipl_backup2*2), buf, des_32bit,WRITE))
  1516.                 disp_msg(21, s_d, d_d);
  1517.         }
  1518.     }
  1519.     resetdisk();
  1520. }
  1521.  
  1522. void    p_write_ipl(char *s_d, char *d_d, uint rr_sect, char *so_dpb, 
  1523.         char *dest_dpb, char *check_buf)
  1524. /* ipl は Win95 でも ipl の backup 迄は 32K 以内としておく    */
  1525. {
  1526.     ulong     r_sect = *(ulong *)(check_buf + W_START_S);
  1527.     uint     i, fat_sect22, ipl_backup, ipl_backup2,
  1528.             r_s_size = *(uint *)so_dpb, w_s_size = *(uint *)dest_dpb, 
  1529.             fat_sect = *(uint *)(check_buf +C_FAT_S), 
  1530.             fat_sect2 = *(uint *)(dest_dpb + FAT_S); 
  1531.  
  1532.     if(do_read_write(*d_d, 1, 0, buf, des_32bit, READ))
  1533.         disp_msg(40, "", d_d);
  1534.     resetdisk();
  1535.     if(des_32bit){
  1536.         ipl_backup = *(uint *)(check_buf +C_IPL_B);
  1537.         ipl_backup2 = *(uint *)(buf +IPL_B);
  1538.     }
  1539.  
  1540.     printf("\nNow Writing IPL.\n");
  1541.  
  1542.     if(do_read_write(*s_d, rr_sect, r_sect, buf, so_32bit, READ))
  1543.         disp_msg(20, s_d, d_d);
  1544.     if(!des_32bit){
  1545.         fat_sect22 = uintmax(fat_sect, fat_sect2);
  1546.         if(do_read_write(*d_d, fat_sect22, 0, buf2, des_32bit, READ))
  1547.             disp_msg(42, s_d, d_d);
  1548.         for(i = 0x0e; i < 0x27; i++)
  1549.             buf[i] = buf2[i];
  1550.  
  1551.         if(fat_sect2 > fat_sect){
  1552.             for(i = w_s_size*fat_sect; i < w_s_size*fat_sect2; i++)
  1553.                 buf[i] = 0;
  1554.         }
  1555.         if(do_read_write(*d_d, fat_sect2, 0, buf, des_32bit, WRITE))
  1556.             disp_msg(21, s_d, d_d);
  1557.     }else{
  1558.         if(do_read_write(*d_d, ipl_backup2, 0, buf2, des_32bit, READ))
  1559.             disp_msg(42, s_d, d_d);
  1560.  
  1561.         for(i = 0x0e; i < 0x40; i++)    /* 書き換え    */
  1562.             buf[i] = buf2[i];
  1563.         if(ipl_backup < ipl_backup2){
  1564.             for(i = w_s_size*ipl_backup; i < w_s_size*ipl_backup2;i++)
  1565.                 buf[i] = 0;
  1566.         }
  1567.         if(do_read_write(*d_d, ipl_backup2, 0, buf, des_32bit, WRITE))
  1568.             disp_msg(21, s_d, d_d);
  1569.         if(do_read_write(*d_d, ipl_backup2, (ulong)ipl_backup2, buf, des_32bit,WRITE))
  1570.             disp_msg(21, s_d, d_d);
  1571.         resetdisk();
  1572.  
  1573.         if(ipl_backup2*2 < fat_sect2){
  1574.             for(i = 0; i < w_s_size*(fat_sect2 - ipl_backup2*2); i++)
  1575.                 buf[i] = 0;
  1576.             if(do_read_write(*d_d, fat_sect2 - ipl_backup2*2, (ulong)(ipl_backup2*2), buf, des_32bit,WRITE))
  1577.                 disp_msg(21, s_d, d_d);
  1578.         }
  1579.     }
  1580.     resetdisk();
  1581. }
  1582.  
  1583. void    d_write_ipl(char *s_d, char *d_d, uint rw_sect, char *so_dpb, 
  1584.         char *dest_dpb, char *check_buf)
  1585. /* ipl は Win95 でも ipl の backup 迄は 32K 以内としておく    */
  1586. {
  1587.     uint     i, fat_sect22, ipl_backup, ipl_backup2,
  1588.             s_size = *(uint *)so_dpb,
  1589.             fat_sect = *(uint *)(check_buf +C_FAT_S), 
  1590.             fat_sect2 = *(uint *)(dest_dpb + FAT_S); 
  1591.  
  1592.     if(do_read_write(*d_d, 1, 0, buf, des_32bit, READ))
  1593.         disp_msg(40, "", d_d);
  1594.     resetdisk();
  1595.     if(des_32bit){
  1596.         ipl_backup = *(uint *)(check_buf +C_IPL_B);
  1597.         ipl_backup2 = *(uint *)(buf +IPL_B);
  1598.     }
  1599.  
  1600.     printf("\nNow Writing IPL.\n");
  1601.  
  1602.     if(do_read_write(*s_d, rw_sect, 0, buf, so_32bit, READ))
  1603.         disp_msg(20, s_d, d_d);
  1604.     if(!des_32bit){
  1605.         fat_sect22 = uintmax(fat_sect, fat_sect2);
  1606.         if(do_read_write(*d_d, fat_sect22, 0, buf2, des_32bit, READ))
  1607.             disp_msg(42, s_d, d_d);
  1608.         for(i = 0x0e; i < 0x27; i++)
  1609.             buf[i] = buf2[i];
  1610.  
  1611.         if(fat_sect2 > fat_sect)
  1612.             for(i = s_size*fat_sect; i < s_size*fat_sect2; i++)
  1613.                 buf[i] = 0;
  1614.         if(do_read_write(*d_d, fat_sect2, 0, buf, des_32bit, WRITE))
  1615.             disp_msg(21, s_d, d_d);
  1616.     }else{
  1617.         if(do_read_write(*d_d, ipl_backup2, 0, buf2, des_32bit, READ))
  1618.             disp_msg(42, s_d, d_d);
  1619.  
  1620.         for(i = 0x0e; i < 0x40; i++)    /* 書き換え    */
  1621.             buf[i] = buf2[i];
  1622.  
  1623.         if(ipl_backup < ipl_backup2){
  1624.             for(i = s_size*ipl_backup; i < s_size*ipl_backup2;i++)
  1625.                 buf[i] = 0;
  1626.         }
  1627.         if(do_read_write(*d_d, ipl_backup2, 0, buf, des_32bit, WRITE))
  1628.             disp_msg(21, s_d, d_d);
  1629.         if(do_read_write(*d_d, ipl_backup2, (ulong)ipl_backup2, buf, des_32bit,WRITE))
  1630.             disp_msg(21, s_d, d_d);
  1631.         resetdisk();
  1632.  
  1633.         if(ipl_backup2*2 < fat_sect2){
  1634.             for(i = 0; i < s_size*(fat_sect2 - ipl_backup2*2); i++)
  1635.                 buf[i] = 0;
  1636.             if(do_read_write(*d_d, fat_sect2 - ipl_backup2*2, (ulong)(ipl_backup2*2), buf, des_32bit,WRITE))
  1637.                 disp_msg(21, s_d, d_d);
  1638.         }
  1639.     }
  1640.     resetdisk();
  1641. }
  1642.  
  1643. void    write_FAT(char *s_d, char *d_d, char *dest_dpb, 
  1644.         char *check_buf, char *f_name)
  1645. {
  1646.     FILE     *stream;
  1647.     ulong     used_clust, write_pos;
  1648.     uint    need_sect, mult_K, ww_sect, rest_sect, 
  1649.             w_s_size = *(uint *)dest_dpb,
  1650.             fat_sect = *(uint *)(check_buf +C_FAT_S),
  1651.             fat_sect2 = *(uint *)(dest_dpb + FAT_S); 
  1652.     int        fat_type, i;
  1653.  
  1654.     printf("Now Writing FAT.\n");
  1655.     if(des_32bit)
  1656.         fat_type = 32;
  1657.     else if((*(ulong *)(check_buf + C_MAX_C) +1) <= 0xff4)
  1658.         fat_type = 12;
  1659.     else
  1660.         fat_type = 16;
  1661.  
  1662.     rewrite_fat_to0(d_d, dest_dpb);
  1663.  
  1664.     used_clust = *(ulong *)(check_buf +USED_C);
  1665.     switch(fat_type){
  1666.         case 32:
  1667.             need_sect = (uint)div_upper((used_clust +1)*4, (ulong)w_s_size);
  1668.             break;
  1669.         case 16:
  1670.             need_sect = (uint)div_upper((used_clust +1)*2, (ulong)w_s_size);
  1671.             break;
  1672.         case 12:
  1673.             need_sect = (uint)div_upper((used_clust*3 +1)/2, (ulong)w_s_size);
  1674.             break;
  1675.     }
  1676.  
  1677.     ww_sect = (uint)(BUF_UNIT / w_s_size);
  1678.     write_pos = (ulong)fat_sect2;
  1679.  
  1680.     mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / BUF_UNIT);
  1681.     rest_sect = need_sect - mult_K*(uint)(BUF_UNIT / w_s_size);
  1682.  
  1683.     for(i = 0; i < mult_K; i++){
  1684.         if((stream = fopen(f_name, "rb")) == NULL)
  1685.             disp_msg(24, s_d, d_d);
  1686.         fseek(stream, (ulong)(fat_sect+ (BUF_UNIT/w_s_size)*i)*w_s_size +512, SEEK_SET);
  1687.         if(!fread(buf, (uint)BUF_UNIT, 1, stream))
  1688.             disp_msg(22, s_d, d_d);
  1689.         if(fclose(stream))
  1690.             disp_msg(25, s_d, d_d);
  1691.  
  1692.         if(i == 0){
  1693.             if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1694.                 disp_msg(33, s_d, d_d);
  1695.             buf[0] = buf2[0];        /* 識別子書き換え    */
  1696.         }
  1697.         if(do_read_write(*d_d, ww_sect, write_pos, buf, des_32bit, WRITE))
  1698.             disp_msg(21, s_d, d_d);
  1699.         if(do_read_write(*d_d, ww_sect, write_pos + *(ulong *)(dest_dpb 
  1700.         + S_P_FAT), buf, des_32bit,WRITE))
  1701.             disp_msg(21, s_d, d_d);
  1702.         write_pos += ww_sect;
  1703.         resetdisk();
  1704.     }
  1705.     if(rest_sect){
  1706.         if((stream = fopen(f_name, "rb")) == NULL)
  1707.             disp_msg(24, s_d, d_d);
  1708.         fseek(stream, (ulong)(fat_sect+ (BUF_UNIT/w_s_size)*mult_K)*w_s_size +512, SEEK_SET);
  1709.         if(!fread(buf, rest_sect*w_s_size, 1, stream))
  1710.             disp_msg(22, s_d, d_d);
  1711.         if(fclose(stream))
  1712.             disp_msg(25, s_d, d_d);
  1713.  
  1714.         if(mult_K == 0){
  1715.             if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1716.                 disp_msg(33, s_d, d_d);
  1717.             buf[0] = buf2[0];        /* 識別子書き換え    */
  1718.         }
  1719.  
  1720.         if(do_read_write(*d_d, rest_sect, write_pos, buf, des_32bit, WRITE))
  1721.             disp_msg(21, s_d, d_d);
  1722.         if(do_read_write(*d_d, rest_sect, write_pos + *(ulong *)(dest_dpb + 
  1723.         S_P_FAT), buf, des_32bit,WRITE))
  1724.             disp_msg(21, s_d, d_d);
  1725.         resetdisk();
  1726.     }
  1727. }
  1728.  
  1729. void    p_write_FAT(char *s_d, char *d_d, uint rr_sect, char *so_dpb, 
  1730.         char *dest_dpb, char *check_buf)
  1731. {
  1732.     ulong     next_read_sect, used_clust, write_pos,
  1733.              r_sect = *(ulong *)(check_buf + W_START_S);
  1734.     uint    ww_sect, need_sect, mult_K, rest_sect, residue, byte2next_s,
  1735.             r_s_size = *(uint *)so_dpb, w_s_size = *(uint *)dest_dpb,
  1736.             fat_sect = *(uint *)(check_buf +C_FAT_S),
  1737.             fat_sect2 = *(uint *)(dest_dpb + FAT_S); 
  1738.     int        fat_type, i;
  1739.  
  1740.     ww_sect = (uint)(buf_size / (ulong)w_s_size);
  1741.     printf("Now Writing FAT.\n");
  1742.  
  1743.     if(des_32bit)
  1744.         fat_type = 32;
  1745.     else if((*(ulong *)(check_buf + C_MAX_C) +1) <= 0xff4)
  1746.         fat_type = 12;
  1747.     else
  1748.         fat_type = 16;
  1749.  
  1750.     rewrite_fat_to0(d_d, dest_dpb);
  1751.  
  1752.     used_clust = *(ulong *)(check_buf +USED_C);
  1753.     switch(fat_type){
  1754.         case 32:
  1755.             need_sect = (uint)div_upper((used_clust +1)*4, (ulong)w_s_size);
  1756.             break;
  1757.         case 16:
  1758.             need_sect = (uint)div_upper((used_clust +1)*2, (ulong)w_s_size);
  1759.             break;
  1760.         case 12:
  1761.             need_sect = (uint)div_upper((used_clust*3 +1)/2, (ulong)w_s_size);
  1762.             break;
  1763.     }
  1764.  
  1765.     write_pos = (ulong)fat_sect2;
  1766.     next_read_sect = (ulong)(w_s_size*fat_sect) / (ulong)r_s_size;
  1767.     residue = (uint)(((ulong)w_s_size*fat_sect) % (ulong)r_s_size);
  1768.     if(residue){    /* この時 r_s_size は w_s_sizeの倍数        */
  1769.                     /* 従って byte2next_s は w_s_size の倍数    */
  1770.         byte2next_s = r_s_size - residue; /* 次のsectへの端数    */
  1771.         if(do_read_write(*s_d, 1, r_sect +next_read_sect, buf, so_32bit, READ))
  1772.             disp_msg(20, s_d, d_d);
  1773.         if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1774.             disp_msg(33, s_d, d_d);
  1775.         buf[residue] = buf2[0];        /* 識別子書き換え    */
  1776.         if(do_read_write(*d_d,uintmin(need_sect,(uint)(byte2next_s /w_s_size)),
  1777.         write_pos, buf + residue, des_32bit, WRITE))
  1778.             disp_msg(21, s_d, d_d);
  1779.         if(do_read_write(*d_d,uintmin(need_sect,(uint)(byte2next_s /w_s_size)),
  1780.         write_pos + *(ulong *)(dest_dpb + S_P_FAT), buf +residue, des_32bit,
  1781.         WRITE))
  1782.             disp_msg(21, s_d, d_d);
  1783.         resetdisk();
  1784.  
  1785.         if((uint)(byte2next_s /w_s_size) >= need_sect)
  1786.             return;    /* もう書き込む必要はない    */
  1787.         next_read_sect++;
  1788.         write_pos += byte2next_s / w_s_size;
  1789.         need_sect -= byte2next_s / w_s_size;
  1790.     }
  1791.  
  1792.     mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / buf_size);
  1793.     rest_sect = need_sect - mult_K*(uint)(buf_size / w_s_size);
  1794.     for(i = 0; i < mult_K; i++){
  1795.         if(do_read_write(*s_d, rr_sect, r_sect +next_read_sect, buf, so_32bit, 
  1796.         READ))
  1797.             disp_msg(20, s_d, d_d);
  1798.         if((i == 0) && !residue){
  1799.             if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1800.                 disp_msg(33, s_d, d_d);
  1801.             buf[0] = buf2[0];        /* 識別子書き換え    */
  1802.         }
  1803.         if(do_read_write(*d_d, ww_sect, write_pos, buf, des_32bit, WRITE))
  1804.             disp_msg(21, s_d, d_d);
  1805.         if(do_read_write(*d_d, ww_sect, write_pos + *(ulong *)(dest_dpb 
  1806.         + S_P_FAT), buf, des_32bit,WRITE))
  1807.             disp_msg(21, s_d, d_d);
  1808.         r_sect += rr_sect;
  1809.         write_pos += ww_sect;
  1810.         resetdisk();
  1811.     }
  1812.     if(rest_sect){
  1813.         if(do_read_write(*s_d, (uint)div_upper((ulong)rest_sect*w_s_size, 
  1814.         (ulong)r_s_size), r_sect +next_read_sect, buf, so_32bit, READ))
  1815.             disp_msg(20, s_d, d_d);
  1816.         if((mult_K == 0) && !residue){
  1817.             if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1818.                 disp_msg(33, s_d, d_d);
  1819.             buf[0] = buf2[0];        /* 識別子書き換え    */
  1820.         }
  1821.         if(do_read_write(*d_d, rest_sect, write_pos, buf, des_32bit, WRITE))
  1822.             disp_msg(21, s_d, d_d);
  1823.         if(do_read_write(*d_d, rest_sect, write_pos + *(ulong *)(dest_dpb + 
  1824.         S_P_FAT), buf, des_32bit,WRITE))
  1825.             disp_msg(21, s_d, d_d);
  1826.         resetdisk();
  1827.     }
  1828. }
  1829.  
  1830. void    d_write_FAT(char *s_d, char *d_d, uint rw_sect, char *so_dpb, 
  1831.         char *dest_dpb, char *check_buf)
  1832. {
  1833.     ulong     r_sect, used_clust, write_pos;
  1834.     uint    need_sect, mult_K, rest_sect,
  1835.             s_size = *(uint *)so_dpb,
  1836.             fat_sect = *(uint *)(check_buf +C_FAT_S),
  1837.             fat_sect2 = *(uint *)(dest_dpb + FAT_S); 
  1838.     int        fat_type, i;
  1839.  
  1840.     printf("Now Writing FAT.\n");
  1841.  
  1842.     if(des_32bit)
  1843.         fat_type = 32;
  1844.     else if((*(ulong *)(check_buf + C_MAX_C) +1) <= 0xff4)
  1845.         fat_type = 12;
  1846.     else
  1847.         fat_type = 16;
  1848.  
  1849.     rewrite_fat_to0(d_d, dest_dpb);
  1850.     used_clust = *(ulong *)(check_buf +USED_C);
  1851.     switch(fat_type){
  1852.         case 32:
  1853.             need_sect = (uint)div_upper((used_clust +1)*4, (ulong)s_size);
  1854.             break;
  1855.         case 16:
  1856.             need_sect = (uint)div_upper((used_clust +1)*2, (ulong)s_size);
  1857.             break;
  1858.         case 12:
  1859.             need_sect = (uint)div_upper((used_clust*3 +1)/2, (ulong)s_size);
  1860.             break;
  1861.     }
  1862.  
  1863.     write_pos = (ulong)fat_sect2;
  1864.     r_sect = (ulong)fat_sect;
  1865.  
  1866.     mult_K = (uint)((ulong)need_sect*(ulong)s_size / buf_size);
  1867.     rest_sect = need_sect - mult_K*(uint)(buf_size / s_size);
  1868.  
  1869.     for(i = 0; i < mult_K; i++){
  1870.         if(do_read_write(*s_d, rw_sect, r_sect, buf, so_32bit, READ))
  1871.             disp_msg(20, s_d, d_d);
  1872.         if(i == 0){
  1873.             if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1874.                 disp_msg(33, s_d, d_d);
  1875.             buf[0] = buf2[0];        /* 識別子書き換え    */
  1876.         }
  1877.         if(do_read_write(*d_d, rw_sect, write_pos, buf, des_32bit, WRITE))
  1878.             disp_msg(21, s_d, d_d);
  1879.         if(do_read_write(*d_d, rw_sect, write_pos + *(ulong *)(dest_dpb 
  1880.         + S_P_FAT), buf, des_32bit,WRITE))
  1881.             disp_msg(21, s_d, d_d);
  1882.         r_sect += rw_sect;
  1883.         write_pos += rw_sect;
  1884.         resetdisk();
  1885.     }
  1886.     if(rest_sect){
  1887.         if(do_read_write(*s_d, rest_sect, r_sect, buf, so_32bit, READ))
  1888.             disp_msg(20, s_d, d_d);
  1889.         if(mult_K == 0){
  1890.             if(do_read_write(*d_d, 1, (ulong)fat_sect2, buf2, des_32bit, READ))
  1891.                 disp_msg(33, s_d, d_d);
  1892.             buf[0] = buf2[0];        /* 識別子書き換え    */
  1893.         }
  1894.         if(do_read_write(*d_d, rest_sect, write_pos, buf, des_32bit, WRITE))
  1895.             disp_msg(21, s_d, d_d);
  1896.         if(do_read_write(*d_d, rest_sect, write_pos + *(ulong *)(dest_dpb + 
  1897.         S_P_FAT), buf, des_32bit,WRITE))
  1898.             disp_msg(21, s_d, d_d);
  1899.         resetdisk();
  1900.     }
  1901. }
  1902.  
  1903. void    write_dir_entry(char *s_d, char *d_d, char *check_buf, 
  1904.         char *dest_dpb, char *f_name)
  1905. {
  1906.     FILE     *stream;
  1907.     ulong     read_dir_sect, w_sect;
  1908.     uint    ww_sect, need_sect, mult_K, rest_sect,
  1909.             w_s_size = *(uint *)dest_dpb, 
  1910.             used_dir_ent = *(uint *)(check_buf + USED_D);
  1911.     int        i;
  1912.  
  1913.     if(!used_dir_ent)
  1914.         return;
  1915.     ww_sect = (uint)(buf_size / (ulong)w_s_size);
  1916.  
  1917.     printf("Now Writing Directry Entry.\n");
  1918.     write_null_dir_entry(d_d, dest_dpb);
  1919.  
  1920.     need_sect = (uint)div_upper((ulong)used_dir_ent, (ulong)(w_s_size /32));
  1921.     w_sect = (ulong)(*(uint *)(dest_dpb + FAT_S)) 
  1922.             + *(ulong *)(dest_dpb + S_P_FAT)*2;
  1923.     /* 書き込むsectの場所 FAT_start_sect + FAT_sect*2    */
  1924.  
  1925.     read_dir_sect = (ulong)(*(uint *)(check_buf +C_FAT_S)) 
  1926.                    + *(ulong *)(check_buf +C_S_P_FAT)*2;
  1927.     mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / BUF_UNIT);
  1928.     rest_sect = need_sect - mult_K*(uint)(BUF_UNIT / w_s_size);
  1929.  
  1930.     for(i = 0; i < mult_K; i++){
  1931.         if((stream = fopen(f_name, "rb")) == NULL)
  1932.             disp_msg(24, s_d, d_d);
  1933.         fseek(stream, read_dir_sect*(ulong)w_s_size +BUF_UNIT*i +512,SEEK_SET);
  1934.         if(!fread(buf, (uint)BUF_UNIT, 1, stream))
  1935.             disp_msg(22, s_d, d_d);
  1936.         if(fclose(stream))
  1937.             disp_msg(25, s_d, d_d);
  1938.         if(do_read_write(*d_d, ww_sect, w_sect, buf, des_32bit, WRITE))
  1939.             disp_msg(21, s_d, d_d);
  1940.         w_sect += ww_sect;
  1941.         resetdisk();
  1942.     }
  1943.     if(rest_sect){
  1944.         if((stream = fopen(f_name, "rb")) == NULL)
  1945.             disp_msg(24, s_d, d_d);
  1946.         fseek(stream, read_dir_sect*(ulong)w_s_size +BUF_UNIT*mult_K +512, SEEK_SET);
  1947.         if(!fread(buf, rest_sect*w_s_size, 1, stream))
  1948.             disp_msg(22, s_d, d_d);
  1949.         if(fclose(stream))
  1950.             disp_msg(25, s_d, d_d);
  1951.         if(do_read_write(*d_d, rest_sect, w_sect, buf, des_32bit, WRITE))
  1952.             disp_msg(21, s_d, d_d);
  1953.     }
  1954.     resetdisk();
  1955. }
  1956.  
  1957. void    p_write_dir_entry(char *s_d, char *d_d, uint rr_sect, char *check_buf, 
  1958.         char *so_dpb, char *dest_dpb)
  1959. {
  1960.     ulong     so_read_sect_off, read_dir_sect, w_sect,
  1961.             r_sect = *(ulong *)(check_buf + W_START_S);
  1962.     uint    ww_sect, need_sect, residue, byte2next_s, mult_K, rest_sect,
  1963.             r_s_size = *(uint *)so_dpb, w_s_size = *(uint *)dest_dpb,
  1964.             used_dir_ent = *(uint *)(check_buf + USED_D);
  1965.     int        i;
  1966.  
  1967.     if(!used_dir_ent)
  1968.         return;
  1969.  
  1970.     ww_sect = (uint)(buf_size / (ulong)w_s_size);
  1971.     printf("Now Writing Directry Entry.\n");
  1972.     write_null_dir_entry(d_d, dest_dpb);
  1973.  
  1974.     need_sect = (uint)div_upper((ulong)used_dir_ent, (ulong)(w_s_size /32));
  1975.     w_sect = (ulong)(*(uint *)(dest_dpb + FAT_S)) 
  1976.             + *(ulong *)(dest_dpb + S_P_FAT)*2;
  1977.     /* 書き込むsectの場所 FAT_start_sect + FAT_sect*2    */
  1978.  
  1979.     read_dir_sect = (ulong)(*(uint *)(check_buf +C_FAT_S)) 
  1980.                    + *(ulong *)(check_buf +C_S_P_FAT)*2;
  1981.     so_read_sect_off = (read_dir_sect*w_s_size) / r_s_size;
  1982.     residue = (uint)(((ulong)w_s_size*read_dir_sect) % (ulong)r_s_size);
  1983.  
  1984.     if(residue){    /* この時 r_s_size は w_s_sizeの倍数        */
  1985.                     /* 従って byte2next_s は w_s_size の倍数    */
  1986.         byte2next_s = r_s_size - residue; /* 次のsectへの端数    */
  1987.         if(do_read_write(*s_d,1,r_sect +so_read_sect_off, buf, so_32bit,READ))
  1988.             disp_msg(20, s_d, d_d);
  1989.         if(do_read_write(*d_d,uintmin(need_sect,(uint)(byte2next_s /w_s_size)),
  1990.         w_sect, buf +residue, des_32bit, WRITE))
  1991.             disp_msg(21, s_d, d_d);
  1992.         resetdisk();
  1993.  
  1994.         if((uint)(byte2next_s /w_s_size) >= need_sect)
  1995.             return;    /* もう書き込む必要はない    */
  1996.  
  1997.         so_read_sect_off++;
  1998.         w_sect += byte2next_s / w_s_size;
  1999.         need_sect -= byte2next_s / w_s_size;
  2000.     }
  2001.  
  2002.     mult_K = (uint)((ulong)need_sect*(ulong)w_s_size / buf_size);
  2003.     rest_sect = need_sect - mult_K*(uint)(buf_size / w_s_size);
  2004.     for(i = 0; i < mult_K; i++){
  2005.         if(do_read_write(*s_d, rr_sect, r_sect +so_read_sect_off, buf, 
  2006.         so_32bit, READ))
  2007.             disp_msg(20, s_d, d_d);
  2008.         if(do_read_write(*d_d, ww_sect, w_sect, buf, des_32bit, WRITE))
  2009.             disp_msg(21, s_d, d_d);
  2010.         r_sect += rr_sect;
  2011.         w_sect += ww_sect;
  2012.         resetdisk();
  2013.     }
  2014.     if(rest_sect){
  2015.         if(do_read_write(*s_d, (uint)div_upper((ulong)rest_sect*
  2016.         (ulong)w_s_size, (ulong)r_s_size), r_sect +so_read_sect_off, buf, 
  2017.         so_32bit, READ))
  2018.             disp_msg(20, s_d, d_d);
  2019.         if(do_read_write(*d_d, rest_sect, w_sect, buf, des_32bit, WRITE))
  2020.             disp_msg(21, s_d, d_d);
  2021.     }
  2022.     resetdisk();
  2023. }
  2024. void    d_write_dir_entry(char *s_d, char *d_d, uint rw_sect, char *check_buf, 
  2025.         char *so_dpb, char *dest_dpb)
  2026. {
  2027.     ulong    r_sect, w_sect;
  2028.     uint    need_sect, mult_K, rest_sect,
  2029.             s_size = *(uint *)so_dpb,
  2030.             used_dir_ent = *(uint *)(check_buf + USED_D);
  2031.     int        i;
  2032.  
  2033.     if(!used_dir_ent)
  2034.         return;
  2035.     printf("Now Writing Directry Entry.\n");
  2036.     write_null_dir_entry(d_d, dest_dpb);
  2037.  
  2038.     need_sect = (uint)div_upper((ulong)used_dir_ent, (ulong)(s_size /32));
  2039.     w_sect = (ulong)(*(uint *)(dest_dpb + FAT_S)) 
  2040.             + *(ulong *)(dest_dpb + S_P_FAT)*2;
  2041.     /* 書き込むsectの場所 FAT_start_sect + FAT_sect*2    */
  2042.  
  2043.     r_sect = (ulong)(*(uint *)(check_buf +C_FAT_S)) 
  2044.                    + *(ulong *)(check_buf +C_S_P_FAT)*2;
  2045.     mult_K = (uint)((ulong)need_sect*(ulong)s_size / buf_size);
  2046.     rest_sect = need_sect - mult_K*(uint)(buf_size / s_size);
  2047.  
  2048.     for(i = 0; i < mult_K; i++){
  2049.         if(do_read_write(*s_d, rw_sect, r_sect, buf, so_32bit, READ))
  2050.             disp_msg(20, s_d, d_d);
  2051.         if(do_read_write(*d_d, rw_sect, w_sect, buf, des_32bit, WRITE))
  2052.             disp_msg(21, s_d, d_d);
  2053.         r_sect += rw_sect;
  2054.         w_sect += rw_sect;
  2055.         resetdisk();
  2056.     }
  2057.     if(rest_sect){
  2058.         if(do_read_write(*s_d, rest_sect, r_sect, buf, so_32bit, READ))
  2059.             disp_msg(20, s_d, d_d);
  2060.         if(do_read_write(*d_d, rest_sect, w_sect, buf, des_32bit, WRITE))
  2061.             disp_msg(21, s_d, d_d);
  2062.     }
  2063.     resetdisk();
  2064. }
  2065.  
  2066. void    restore(char *source, char *dest, ulong start_sect)
  2067. {
  2068.     FILE     *stream;
  2069.     struct     find_t ffblk;
  2070.     char     file_name[80], check_buf[512], dest_dpb[22], ext_dest_dpb[63];
  2071.     ulong    w_sect, w_next_sect, w_f_next_sect, end_sect, w_end_sect,
  2072.             data_sect, data_sect2, max_clust, data_size;
  2073.     uint    i, w_s_size, ww_sect, done, check_err_record, sect_p_clust;
  2074.     int        data_diff = 0, r_offset = 0, w_offset = 0, 
  2075.             first_time = 1, do_anyway = 0;
  2076.  
  2077.     if(des_32bit){
  2078.         if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
  2079.             disp_msg(12, source, dest);
  2080.     }else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
  2081.         disp_msg(12, source, dest);
  2082.  
  2083.     if(des_32bit)
  2084.         shift_ext_dpb(dest_dpb, ext_dest_dpb);
  2085.     else
  2086.         shift_dpb(dest_dpb);
  2087.  
  2088.     w_s_size = *(uint *)dest_dpb;
  2089.     end_sect = clust2sect(dest_dpb, *(ulong *)(dest_dpb + MAX_C) +1);
  2090.     ww_sect = (uint)(buf_size / (ulong)w_s_size);
  2091.     do{
  2092.         if(win95){
  2093.             ioctrl_lock(*dest - 'A' +1, 0);
  2094.             ioctrl_lock(*source - 'A' +1, 0);
  2095.         }
  2096.         set_file_name(file_name, source, start_sect, 2);
  2097.         do{
  2098.             done = _dos_findfirst(file_name, 0xff, &ffblk);
  2099.             if(done)
  2100.                 disp_msg2(13, file_name, dest, 0);
  2101.         }while(done);
  2102.  
  2103.         if((stream = fopen(file_name, "rb")) == NULL)
  2104.             disp_msg(24, source, dest);
  2105.  
  2106.         if(!fread(check_buf, 512, 1, stream))
  2107.             disp_msg(22, source, dest);
  2108.         if(fclose(stream))
  2109.             disp_msg(25, source, dest);
  2110.  
  2111.         if(start_sect != *(ulong *)(check_buf + R_START_S))
  2112.             disp_msg(17, file_name, dest);
  2113.  
  2114.         if(end_sect    < *(ulong *)(check_buf + R_END_S))
  2115.             disp_msg(29, file_name, dest);
  2116.         else
  2117.             w_end_sect = *(ulong *)(check_buf + R_END_S);
  2118.  
  2119.         data_sect = *(ulong *)(check_buf +C_DATA_S); /* backupのdata_sect */
  2120.         data_sect2 = *(ulong *)(dest_dpb + DATA_S);    /* destのdata_sect      */
  2121.         data_diff = data_sect2 - data_sect;
  2122.  
  2123.         for(i = 0; i < 320; i++)
  2124.             bad_clust[i] = check_buf[192 +i];
  2125.         bad_clust_num = get_bad_clust_num();
  2126.         if(bad_clust_num)
  2127.             disp_warn(3, dest);
  2128.         resetdisk();
  2129.  
  2130.         if(first_time){        /* 最初1回だけ check    */
  2131.             switch(check_disk_format(dest_dpb, check_buf)){
  2132.                 case 0:    
  2133.                     disp_msg(16, source, dest);
  2134.                     break;
  2135.                 case 1:
  2136.                     rewrite_flag = 0;
  2137.                     break;
  2138.                 case 2:    
  2139.                     sect_p_clust = *(uint *)(check_buf +C_SECT_C);
  2140.                     max_clust = *(ulong *)(check_buf +C_MAX_C) -1;
  2141.                     if(w_s_size > 1024)
  2142.                         data_size = max_clust * sect_p_clust 
  2143.                                     * (ulong)(w_s_size / 1024);
  2144.                     else
  2145.                         data_size = (max_clust * sect_p_clust)
  2146.                                      / (ulong)(1024 / w_s_size);
  2147.                     if(!disp_msg3(data_size)){
  2148.                         ybeep();
  2149.                         exit_routine(40);
  2150.                     }
  2151.                     if(!check_dir_entry_etc(dest_dpb, check_buf))
  2152.                         disp_msg(39, source, dest);
  2153.                     else
  2154.                         rewrite_flag = 1;
  2155.                     break;
  2156.             }
  2157.         }
  2158.         if(rewrite_flag){
  2159.             if(end_sect < w_end_sect + data_diff)
  2160.                 disp_msg(45, source, dest);
  2161.         }
  2162.  
  2163.         if((rewrite_flag) && (start_sect < data_sect)){
  2164.             if(start_sect != 0)
  2165.                 disp_msg(41, source, dest);
  2166.             write_ipl(source, dest, dest_dpb, check_buf, file_name);
  2167.             write_FAT(source, dest, dest_dpb, check_buf, file_name);
  2168.             write_dir_entry(source, dest, check_buf, dest_dpb, file_name);
  2169.             r_offset = data_sect;
  2170.             w_offset = data_sect2;
  2171.         }else{
  2172.             r_offset = 0;
  2173.             w_offset = data_diff;
  2174.         }
  2175.  
  2176.         w_next_sect = *(ulong *)(check_buf + R_NEXT_S) + data_diff;
  2177.         w_f_next_sect = w_next_sect - w_offset - start_sect
  2178.                         - ((w_next_sect - w_offset - start_sect) % ww_sect);
  2179.         w_f_next_sect += w_offset + start_sect;
  2180.         /* ここでは,w_sect 等は書き込む sector    */
  2181.  
  2182.         printf("\nNow Restoring from File %s\n", file_name);
  2183.         printf(" [Write to Sectors %lu - %lu ]\n\n", start_sect +w_offset, w_next_sect - 1);
  2184.  
  2185.         for(w_sect = start_sect + w_offset; w_sect < w_f_next_sect; 
  2186.         w_sect += ww_sect){
  2187.             check_user_break(source, dest);
  2188.             printf("Writing Sectors %lu - %lu \n",w_sect,w_sect +ww_sect -1);
  2189.             if((stream = fopen(file_name, "rb")) == NULL)
  2190.                 disp_msg(24, source, dest);
  2191.             fseek(stream, (ulong)w_s_size*(w_sect -start_sect -data_diff)
  2192.              +512, SEEK_SET);
  2193.             if(!fread(buf, (uint)BUF_UNIT, 1, stream))
  2194.                 disp_msg(22, source, dest);
  2195.             if(big_buf){
  2196.                 if(!fread(buf + BUF_UNIT, (uint)BUF_UNIT, 1, stream))
  2197.                     disp_msg(22, source, dest);
  2198.             }
  2199.             if(fclose(stream))
  2200.                 disp_msg(25, source, dest);
  2201.             if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, WRITE)){
  2202.                 /* 以下は rewrite の時は,break するように    */
  2203.                         /* make_bad_sect_table を定義している        */
  2204.                 check_err_record = make_bad_sect_table(dest_dpb,ww_sect,w_sect,
  2205.                                     bad_table,des_32bit);
  2206.                 if(check_err_record && !do_anyway){
  2207.                     disp_msg2(12, source, dest,0);
  2208.                     do_anyway = 1;
  2209.                 }
  2210.                 if(!check_err_record && !do_anyway){
  2211.                     for(i = 0; i < ww_sect; i++){
  2212.                         if(!bad_table[i]){
  2213.                             if(do_read_write(*dest, 1, w_sect +i, 
  2214.                             buf + w_s_size*i, des_32bit, WRITE)){
  2215.                                 disp_msg2(12, source, dest,0);
  2216.                                 do_anyway = 1;
  2217.                             }
  2218.                         }
  2219.                     }
  2220.                 }
  2221.                 if(do_anyway){
  2222.                     if(!check_err_record)
  2223.                         disp_warn(2, source);
  2224.                     for(i = 0; i < ww_sect; i++)
  2225.                         do_read_write(*dest, 1, w_sect +i, 
  2226.                         buf + w_s_size*i, des_32bit, WRITE);
  2227.                 }
  2228.             }
  2229.             resetdisk();
  2230.         }
  2231.  
  2232.         if(w_f_next_sect != w_next_sect){
  2233.             check_user_break(source, dest);
  2234.             printf("Writing Sectors %lu - %lu \n", w_sect, w_next_sect -1);
  2235.  
  2236.             if((stream = fopen(file_name, "rb")) == NULL)
  2237.                 disp_msg(24, source, dest);
  2238.             fseek(stream, (ulong)w_s_size*(w_sect -start_sect -data_diff) 
  2239.             + 512, SEEK_SET);
  2240.  
  2241.             if(big_buf && ((w_next_sect - w_f_next_sect)*(ulong)(w_s_size)) 
  2242.             > BUF_UNIT){
  2243.                 if(!fread(buf, (uint)BUF_UNIT, 1, stream))
  2244.                     disp_msg(22, source, dest);
  2245.                 if(!fread(buf + BUF_UNIT, (uint)((w_next_sect 
  2246.                 - w_f_next_sect)*(ulong)(w_s_size)) -(uint)BUF_UNIT,1,stream))
  2247.                     disp_msg(22, source, dest);
  2248.             }else{
  2249.                 if(!fread(buf, (uint)((w_next_sect - w_f_next_sect)*
  2250.                 (ulong)(w_s_size)), 1, stream))
  2251.                     disp_msg(22, source, dest);
  2252.             }
  2253.             if(fclose(stream))
  2254.                 disp_msg(25, source, dest);
  2255.             if(do_read_write(*dest, (uint)(w_next_sect - w_f_next_sect), 
  2256.             w_sect, buf, des_32bit, WRITE)){
  2257.                     /* 以下は rewrite の時は,break するように    */
  2258.                     /* make_bad_sect_table を定義している        */
  2259.                 check_err_record = make_bad_sect_table(dest_dpb, (uint)
  2260.                 (w_next_sect-w_f_next_sect),w_f_next_sect,bad_table,des_32bit);
  2261.                 if(check_err_record && !do_anyway){
  2262.                     disp_msg2(12, source, dest,0);
  2263.                     do_anyway = 1;
  2264.                 }
  2265.                 if(!check_err_record && !do_anyway){
  2266.                     for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++){
  2267.                         if(!bad_table[i]){
  2268.                             if(do_read_write(*dest, 1, w_f_next_sect +i, 
  2269.                             buf + w_s_size*i, des_32bit, WRITE)){
  2270.                                 disp_msg2(12, source, dest,0);
  2271.                                 do_anyway = 1;
  2272.                             }
  2273.                         }
  2274.                     }
  2275.                 }
  2276.                 if(do_anyway){
  2277.                     if(!check_err_record)
  2278.                         disp_warn(2, source);
  2279.                     for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++)
  2280.                         do_read_write(*dest, 1, w_f_next_sect +i, 
  2281.                         buf + w_s_size*i, des_32bit, WRITE);
  2282.                 }
  2283.             }
  2284.             resetdisk();
  2285.         }
  2286.         start_sect = w_next_sect -data_diff;
  2287.         first_time = 0;
  2288.  
  2289.         if(start_sect < w_end_sect){
  2290.             set_file_name(file_name, source, start_sect, 2);
  2291.             if((stream = fopen(file_name, "rb")) == NULL){
  2292.                 ybeep();
  2293.                 ybeep();
  2294.                 ybeep();
  2295.                 ybeep();
  2296.                 disp_msg2(8, source, dest, 0);
  2297.                 resetdisk();
  2298.             }else
  2299.                 fclose(stream);
  2300.         }
  2301.     }while(start_sect < w_end_sect);
  2302.     if(des_32bit && rewrite_flag)
  2303.         reset_free_clust(dest, w_s_size);
  2304. }
  2305.  
  2306. void    p_restore(char *source, char *dest, ulong start_sect)
  2307. {
  2308.     FILE     *stream;
  2309.     struct     find_t ffblk;
  2310.     char     file_name[80], check_buf[512], 
  2311.              dest_dpb[22], so_dpb[22], ext_dest_dpb[63], ext_so_dpb[63];
  2312.     ulong    r_sect, w_sect, w_next_sect, w_f_next_sect,
  2313.             w_end_sect, end_sect, data_size, max_clust,
  2314.             data_sect, data_sect2, next_read_sect, offset;
  2315.     uint    ww_sect, rr_sect, r_s_size, w_s_size, done, i,
  2316.             check_err_record, sect_p_clust, residue, byte2next_s = 0;
  2317.     int        data_diff, w_offset = 0, r_offset = 0, r_diff_s = 0, w_diff_s = 0,
  2318.             first_time = 1, do_anyway = 0;
  2319.  
  2320.     if(des_32bit){
  2321.         if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
  2322.             disp_msg(12, source, dest);
  2323.     }else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
  2324.         disp_msg(12, source, dest);
  2325.  
  2326.     if(des_32bit)
  2327.         shift_ext_dpb(dest_dpb, ext_dest_dpb);
  2328.     else
  2329.         shift_dpb(dest_dpb);
  2330.  
  2331.     w_s_size = *(uint *)dest_dpb;
  2332.     end_sect = clust2sect(dest_dpb, *(ulong *)(dest_dpb + MAX_C) +1);
  2333.     ww_sect = (uint)(buf_size / (ulong)w_s_size);
  2334.     resetdisk();
  2335.  
  2336.     do{
  2337.         if(win95){
  2338.             ioctrl_lock(*dest - 'A' +1, 0);
  2339.             ioctrl_lock(*source - 'A' +1, 0);
  2340.         }
  2341.  
  2342.         set_file_name(file_name, source, start_sect, 1);
  2343.         do{
  2344.             done = _dos_findfirst(file_name, 0xff, &ffblk);
  2345.             if(done)
  2346.                 disp_msg2(13, file_name, dest, 0);
  2347.         }while(done);
  2348.  
  2349.         if((stream = fopen(file_name, "rb")) == NULL)
  2350.             disp_msg(24, source, dest);
  2351.  
  2352.         if(!fread(check_buf, 512, 1, stream))
  2353.             disp_msg(22, source, dest);
  2354.         if(fclose(stream))
  2355.             disp_msg(25, source, dest);
  2356.  
  2357.         if(so_32bit){
  2358.             if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
  2359.                 disp_msg(11, source, dest);
  2360.         }else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
  2361.             disp_msg(11, source, dest);
  2362.  
  2363.         if(so_32bit)
  2364.             shift_ext_dpb(so_dpb, ext_so_dpb);
  2365.         else
  2366.             shift_dpb(so_dpb);
  2367.  
  2368.         if(start_sect != *(ulong *)(check_buf + R_START_S))
  2369.             disp_msg(17, file_name, dest);
  2370.  
  2371.         if(end_sect    < *(ulong *)(check_buf + R_END_S))
  2372.             disp_msg(29, file_name, dest);
  2373.         else
  2374.             w_end_sect = *(ulong *)(check_buf + R_END_S);
  2375.  
  2376.         data_sect = *(ulong *)(check_buf +C_DATA_S); /* backupのdata_sect */
  2377.         data_sect2 = *(ulong *)(dest_dpb + DATA_S);    /* destのdata_sect      */
  2378.         data_diff = data_sect2 - data_sect;
  2379.         r_s_size = *(uint *)so_dpb;
  2380.         r_sect = *(ulong *)(check_buf + W_START_S);
  2381.         rr_sect = (uint)(buf_size / (ulong)r_s_size);
  2382.  
  2383.         for(i = 0; i < 320; i++)
  2384.             bad_clust[i] = check_buf[192 +i];
  2385.         bad_clust_num = get_bad_clust_num();
  2386.         if(bad_clust_num)
  2387.             disp_warn(3, dest);
  2388.         resetdisk();
  2389.  
  2390.         if(first_time){        /* 最初1回だけ check    */
  2391.             switch(check_disk_format(dest_dpb, check_buf)){
  2392.                 case 0:    
  2393.                     disp_msg(16, source, dest);
  2394.                     break;
  2395.                 case 1:
  2396.                     rewrite_flag = 0;
  2397.                     break;
  2398.                 case 2:    
  2399.                     sect_p_clust = *(uint *)(check_buf +C_SECT_C);
  2400.                     max_clust = *(ulong *)(check_buf +C_MAX_C) -1;
  2401.                     if(w_s_size > 1024)
  2402.                         data_size = max_clust * sect_p_clust 
  2403.                                     * (ulong)(w_s_size / 1024);
  2404.                     else
  2405.                         data_size = (max_clust * sect_p_clust)
  2406.                                      / (ulong)(1024 / w_s_size);
  2407.                     if(!disp_msg3(data_size)){
  2408.                         ybeep();
  2409.                         exit_routine(40);
  2410.                     }
  2411.  
  2412.                     if(!check_dir_entry_etc(dest_dpb, check_buf))
  2413.                         disp_msg(39, source, dest);
  2414.                     else
  2415.                         rewrite_flag = 1;
  2416.                     break;
  2417.             }
  2418.         }
  2419.         if(rewrite_flag){
  2420.             if(end_sect < w_end_sect + data_diff)
  2421.                 disp_msg(45, source, dest);
  2422.         }
  2423.  
  2424.         if(rewrite_flag && (start_sect < data_sect)){
  2425.             if(start_sect != 0)
  2426.                 disp_msg(41, source, dest);
  2427.             p_write_ipl(source, dest, rr_sect, so_dpb, dest_dpb, check_buf);
  2428.             p_write_FAT(source, dest, rr_sect, so_dpb, dest_dpb, check_buf);
  2429.             p_write_dir_entry(source,dest,rr_sect,check_buf, so_dpb, dest_dpb);
  2430.  
  2431.             residue = (uint)(((ulong)w_s_size*data_sect) % (ulong)r_s_size);
  2432.             next_read_sect = (ulong)(w_s_size*data_sect) / (ulong)r_s_size;
  2433.             if(residue){    /* この時 r_s_size は w_s_sizeの倍数        */
  2434.                             /* 従って byte2next_s は w_s_size の倍数    */
  2435.                 byte2next_s = r_s_size - residue; /* 次のsectへの端数    */
  2436.                 if(do_read_write(*source, 1, r_sect +next_read_sect, buf, 
  2437.                 so_32bit, READ))
  2438.                     disp_msg(20, source, dest);
  2439.                 if(do_read_write(*dest, (uint)(byte2next_s / w_s_size),
  2440.                 data_sect2, buf +residue, des_32bit, WRITE))
  2441.                     disp_msg(21, source, dest);
  2442.                 r_diff_s = 1;
  2443.                 w_diff_s = byte2next_s / w_s_size;
  2444.             }
  2445.             r_offset = r_diff_s + (w_s_size*data_sect)/ r_s_size;
  2446.             w_offset = w_diff_s + data_sect2;
  2447.         }else{
  2448.             r_offset = 0;
  2449.             w_offset = data_diff;
  2450.         }
  2451.         w_next_sect = *(ulong *)(check_buf + R_NEXT_S) + data_diff;
  2452.         w_f_next_sect = w_next_sect - w_offset - start_sect
  2453.                         - ((w_next_sect - w_offset - start_sect) % ww_sect);
  2454.         w_f_next_sect += w_offset + start_sect;
  2455.         /* ここでは,w_sect 等は書き込む sector    */
  2456.  
  2457.         set_file_name(file_name, source, start_sect, 0);
  2458.  
  2459.         printf("\nNow Restoring from File %s\n", file_name);
  2460.         printf(" [Write to Sectors %lu - %lu ]\n\n", start_sect +w_offset, w_next_sect - 1);
  2461.  
  2462.         for(w_sect = start_sect +w_offset; w_sect < w_f_next_sect;
  2463.         w_sect += ww_sect){
  2464.  
  2465.             check_user_break(source, dest);
  2466.             printf("Writing Sectors %lu - %lu \n",w_sect, w_sect +ww_sect-1);
  2467.  
  2468.             if(do_read_write(*source,rr_sect,r_sect +r_offset, buf, so_32bit, 
  2469.             READ))
  2470.                 disp_msg(20, source, dest);
  2471.             r_sect += rr_sect;
  2472.  
  2473.             if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, WRITE)){ 
  2474.                 /* 以下は rewrite の時は,break するように    */
  2475.                         /* make_bad_sect_table を定義している        */
  2476.                 check_err_record = make_bad_sect_table(dest_dpb,ww_sect,w_sect,
  2477.                                     bad_table,des_32bit);
  2478.                 if(check_err_record && !do_anyway){
  2479.                     disp_msg2(12, source, dest,0);
  2480.                     do_anyway = 1;
  2481.                 }
  2482.                 if(!check_err_record && !do_anyway){
  2483.                     for(i = 0; i < ww_sect; i++){
  2484.                         if(!bad_table[i]){
  2485.                             if(do_read_write(*dest, 1, w_sect +i, 
  2486.                             buf + w_s_size*i, des_32bit, WRITE)){
  2487.                                 disp_msg2(12, source, dest,0);
  2488.                                 do_anyway = 1;
  2489.                             }
  2490.                         }
  2491.                     }
  2492.                 }
  2493.                 if(do_anyway){
  2494.                     if(!check_err_record)
  2495.                         disp_warn(2, source);
  2496.                     for(i = 0; i < ww_sect; i++)
  2497.                         do_read_write(*dest, 1, w_sect +i, 
  2498.                         buf + w_s_size*i, des_32bit, WRITE);
  2499.                 }
  2500.             }
  2501.             resetdisk();
  2502.         }
  2503.  
  2504.         if(w_f_next_sect != w_next_sect){ /* ここでは w_sect=w_f_next_sect    */
  2505.             check_user_break(source, dest);
  2506.             printf("Writing Sectors %lu - %lu \n", w_sect, w_next_sect -1);
  2507.  
  2508.             if(do_read_write(*source, (uint)div_upper(((w_next_sect    
  2509.             -w_f_next_sect)*w_s_size), (ulong)r_s_size), r_sect +r_offset, 
  2510.             buf, so_32bit, READ))
  2511.                 disp_msg(20, source, dest);
  2512.  
  2513.  
  2514.             if(do_read_write(*dest, (uint)(w_next_sect -w_f_next_sect), 
  2515.             w_sect, buf, des_32bit, WRITE)){
  2516.                     /* 以下は rewrite の時は,break するように    */
  2517.                     /* make_bad_sect_table を定義している        */
  2518.                 check_err_record = make_bad_sect_table(dest_dpb, (uint)
  2519.                 (w_next_sect-w_f_next_sect),w_f_next_sect,bad_table,des_32bit);
  2520.                 if(check_err_record && !do_anyway){
  2521.                     disp_msg2(12, source, dest,0);
  2522.                     do_anyway = 1;
  2523.                 }
  2524.                 if(!check_err_record && !do_anyway){
  2525.                     for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++){
  2526.                         if(!bad_table[i]){
  2527.                             if(do_read_write(*dest, 1, w_f_next_sect +i, 
  2528.                             buf + w_s_size*i, des_32bit, WRITE)){
  2529.                                 disp_msg2(12, source, dest,0);
  2530.                                 do_anyway = 1;
  2531.                             }
  2532.                         }
  2533.                     }
  2534.                 }
  2535.                 if(do_anyway){
  2536.                     if(!check_err_record)
  2537.                         disp_warn(2, source);
  2538.                     for(i = 0; i < (uint)(w_next_sect - w_f_next_sect); i++)
  2539.                         do_read_write(*dest, 1, w_f_next_sect +i, 
  2540.                         buf + w_s_size*i, des_32bit, WRITE);
  2541.                 }
  2542.             }
  2543.             resetdisk();
  2544.         }
  2545.         start_sect = w_next_sect -data_diff;
  2546.         first_time = 0;
  2547.         if(start_sect < w_end_sect){
  2548.             ybeep();
  2549.             ybeep();
  2550.             ybeep();
  2551.             ybeep();
  2552.             disp_msg2(8, source, dest, 0);
  2553.             resetdisk();
  2554.         }
  2555.     }while(start_sect < w_end_sect);
  2556.     if(des_32bit && rewrite_flag)
  2557.         reset_free_clust(dest, w_s_size);
  2558. }
  2559.  
  2560. void    backup(char *source, char *dest, ulong start_sect)
  2561. /* 作る file の size は 1.25G + dest_sect_size 迄にする    */
  2562. {
  2563.     FILE     *stream;
  2564.     struct     diskfree_t dtable;
  2565.     char     file_name[80], tmp[6], write_buf[512], t_buf[10],
  2566.              so_dpb[22], ext_so_dpb[63];
  2567.     ulong    free_byte, sect, next_sect, f_next_sect, r_end_sect, 
  2568.             total_amount, r_max_sect, r_used_sect, r_next_sect, 
  2569.             avail_sect, rest_avail, last_clust, used_clust, f_length;
  2570.     uint    free_space_ok, r_s_size, w_s_size, d_s_p_clust,
  2571.             i, rr_sect, check_err_record, comp_size, mult_K,
  2572.             used_dir_entry; 
  2573.     int        do_anyway = 0;
  2574.  
  2575.     if(f_s_limit)
  2576.         f_length = f_s_limit*1024 - 512;    /* 512 は header 部分    */
  2577.     else
  2578.         f_length = FILE_LENGTH;
  2579.  
  2580.     if(so_32bit){
  2581.         if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
  2582.             disp_msg(11, source, dest);
  2583.     }else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
  2584.         disp_msg(11, source, dest);
  2585.  
  2586.     if(so_32bit)
  2587.         shift_ext_dpb(so_dpb, ext_so_dpb);
  2588.     else
  2589.         shift_dpb(so_dpb);
  2590.     r_s_size = *(uint *)so_dpb;
  2591.     r_max_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
  2592.     rr_sect = (uint)(buf_size / (ulong)r_s_size);
  2593.     r_used_sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
  2594.  
  2595.     if(!full_dump)
  2596.         r_end_sect = r_used_sect;
  2597.     else
  2598.         r_end_sect = r_max_sect;
  2599.  
  2600.     if(start_sect >= r_end_sect)
  2601.         disp_msg(27, source, dest);
  2602.  
  2603.     if(bad_clust_num > 80){
  2604.         disp_msg2(10, source, dest, 0);
  2605.         do_anyway = 1;        /* 強制実行    */
  2606.     }else if(bad_clust_num)
  2607.         disp_warn(1, source);
  2608.  
  2609.     if(r_s_size > 1024)
  2610.         total_amount = (r_end_sect +1)* (ulong)(r_s_size / 1024);
  2611.     else
  2612.         total_amount = (r_end_sect +1)/ (ulong)(1024 / r_s_size);
  2613.     used_dir_entry = get_used_dir_entry(source, so_dpb);
  2614.  
  2615.     printf("Backup Amount is %ld K bytes (1 K = 1024)\n", total_amount);
  2616.  
  2617. /*  以下は write_buf の設定    */
  2618.     strcpy(write_buf, "DiskDump Ver 3.0");    /* 16 文字    */
  2619.     strcat(write_buf, "          -          ");    /* 21 文字    */
  2620.     if(so_32bit)
  2621.         strcat(write_buf, "     FAT32 ");    /* 11 文字    */
  2622.     else
  2623.         strcat(write_buf, "     FAT16 ");    /* 11 文字    FAT12 も含む    */
  2624.     strcat(write_buf, "Total:          ");    /* 16 文字    */
  2625.     sprintf(t_buf, "%.8lu", r_max_sect);
  2626.     for(i = 0; i < 8; i++)
  2627.         write_buf[16*3 + 7 + i] = t_buf[i];
  2628.     strcat(write_buf, "Used:           ");    /* 16 文字    */
  2629.     sprintf(t_buf, "%.8lu", r_used_sect);
  2630.  
  2631.     for(i = 0; i < 8; i++)
  2632.         write_buf[16*4 + 7 + i] = t_buf[i];
  2633.  
  2634.     for (i = 0; i < 22; i++)    /* so_dpb[21] はゴミ    */
  2635.         write_buf[80 +i] = so_dpb[i];
  2636.  
  2637.     *(uint *)(write_buf + USED_D) = used_dir_entry;
  2638.     *(ulong *)(write_buf + USED_C) = used_clust;
  2639.  
  2640.     *(ulong *)(write_buf + R_START_S) = 0L;         /* start_sect    */
  2641.     *(ulong *)(write_buf + R_NEXT_S) = 0L;     /* r_next_sect     */
  2642.                                             /* 取り敢えず 0 を書き込む    */
  2643.     *(ulong *)(write_buf + W_START_S) = 0L; /* 使わない write_start_sect    */
  2644.     *(ulong *)(write_buf + R_END_S) = r_end_sect; /* read_end_sect    */
  2645.  
  2646.     if(win95)
  2647.         ioctrl_lock(*source - 'A' +1, 0);
  2648.     if(do_read_write(*source, 1, 0, buf, so_32bit, READ))    /* ipl read    */
  2649.         disp_msg(11, source, dest);
  2650.     resetdisk();
  2651.     for (i = 0; i < 64; i++)
  2652.         write_buf[128 +i] = buf[i];        /* ipl    */
  2653.     *(uint *)(write_buf + C_SECT_C) = (uint)buf[13];    /* sect/clust    */
  2654.     *(uint *)(write_buf + 110) = 0;    /* ゴミ    */
  2655.  
  2656.     for(i = 0; i < 320; i++)
  2657.         write_buf[192 +i] = bad_clust[i];
  2658.  
  2659.     do{
  2660.         if(win95){
  2661.             ioctrl_lock(*dest - 'A' +1, 0);
  2662.             ioctrl_lock(*source - 'A' +1, 0);
  2663.         }
  2664.         do{
  2665.             if(des_32bit){
  2666.                 tmp[0] = dest[0];
  2667.                 tmp[1] = ':';
  2668.                 tmp[2] = '\\';
  2669.                 tmp[3] = 0 ;
  2670.  
  2671.                 get_ext_dfree(tmp, ext_dfree);
  2672.                 w_s_size = (int)*(ulong *)(ext_dfree + 8);
  2673.                 d_s_p_clust = (int)*(ulong *)(ext_dfree + 4);
  2674.                 avail_sect = *(ulong *)(ext_dfree + 12); /* avail_clusters */
  2675.                 avail_sect *= (long)d_s_p_clust;     /* avail_sect    */
  2676.             }else{
  2677.                 _dos_getdiskfree((uint)(*dest - 'A'+1), &dtable);
  2678.                 free_byte = (ulong)(dtable.sectors_per_cluster)*
  2679.                             (ulong)(dtable.bytes_per_sector)*
  2680.                             (ulong)(dtable.avail_clusters);
  2681.                 d_s_p_clust = (ulong)(dtable.sectors_per_cluster);
  2682.                 w_s_size = dtable.bytes_per_sector;
  2683.                 avail_sect = (ulong)(dtable.avail_clusters);
  2684.                 avail_sect *=  (ulong)(dtable.sectors_per_cluster);
  2685.             }
  2686.             if(f_s_limit){
  2687.                 if(avail_sect >= div_upper(f_length + 512,(ulong)w_s_size))
  2688.                     free_space_ok = 1;
  2689.                 else if(avail_sect >= div_upper(((r_end_sect - start_sect
  2690.                  + 1)*r_s_size), w_s_size))
  2691.                     free_space_ok = 1;
  2692.                 else
  2693.                     free_space_ok = 0;
  2694.             }else{
  2695.                 if(avail_sect >= div_upper(0x10000L +512,(ulong)w_s_size))
  2696.                     /* 64K 以上 free space 必要,overlong 避ける為sect*/
  2697.                     free_space_ok = 1;
  2698.                 else if(avail_sect >= div_upper(((r_end_sect - start_sect
  2699.                  + 1)*r_s_size), w_s_size))
  2700.                     free_space_ok = 1;
  2701.                 else
  2702.                     free_space_ok = 0;
  2703.             }
  2704.             if(!free_space_ok)
  2705.                 disp_msg2(6, source, dest, 0);
  2706.         }while(!free_space_ok);
  2707.  
  2708.         mult_K = (uint)(avail_sect / div_upper((f_length + 512), 
  2709.                 (ulong)w_s_size));
  2710.         /* 1.25G(+α) byte の file がいくつ取れるか    */
  2711.         /* 又は f_s_limit K byte の file がいくつ取れるか    */
  2712.  
  2713.         rest_avail = avail_sect - div_upper((f_length + 512), 
  2714.                     (ulong)w_s_size)*mult_K;
  2715.         if(f_s_limit){
  2716.             if(rest_avail < r_end_sect-start_sect-(f_length /r_s_size)*mult_K)
  2717.                 rest_avail = 0;
  2718.         }else{
  2719.             if((rest_avail < div_upper(0x10000L +512,(ulong)w_s_size))
  2720.             &&(rest_avail < r_end_sect-start_sect-(f_length /r_s_size)*mult_K))
  2721.                 rest_avail = 0;    /* 64K の file が取れなければ無意味    */
  2722.         }
  2723.         if(rest_avail)
  2724.             next_sect = (f_length /r_s_size)*mult_K 
  2725.                         + (rest_avail*w_s_size -512) /r_s_size + start_sect;
  2726.         else
  2727.             next_sect = (f_length /r_s_size)*mult_K +start_sect;
  2728.  
  2729.         if(next_sect > r_end_sect)
  2730.             next_sect = r_end_sect;
  2731.  
  2732.         do{
  2733.             set_file_name(file_name, dest, start_sect, 2);
  2734.             if(mult_K)
  2735.                 r_next_sect = f_length / r_s_size + start_sect;
  2736.             else
  2737.                 r_next_sect = (rest_avail*w_s_size -512)/r_s_size +start_sect;
  2738.             if(r_next_sect > next_sect)
  2739.                 r_next_sect = next_sect;
  2740.  
  2741.             f_next_sect = r_next_sect -start_sect 
  2742.             -((r_next_sect - start_sect) % rr_sect);
  2743.             f_next_sect += start_sect;
  2744.             printf("\nNow making file %s \n", file_name);
  2745.             printf(" [Sectors %lu - %lu ]\n\n", start_sect, r_next_sect - 1);
  2746.  
  2747.             if((stream = fopen(file_name, "wb")) == NULL)
  2748.                 disp_msg(24, source, dest);
  2749.             *(ulong *)(write_buf + R_START_S) = start_sect;
  2750.             *(ulong *)(write_buf + R_NEXT_S) = r_next_sect;
  2751. /*            *(ulong *)(write_buf + W_START_S) = 0L;            */
  2752. /*            *(ulong *)(write_buf + R_END_S) = r_end_sect;既に書いている*/
  2753.  
  2754.             sprintf(t_buf, "%.8lu", start_sect);    /* From: xxxxxxx */
  2755.             for(i = 0; i < 8; i++)
  2756.                 write_buf[17 +i] = t_buf[i];
  2757.             sprintf(t_buf, "%.8lu", r_next_sect -1);/* To: yyyyyyyy   */
  2758.             for(i = 0; i < 8; i++)
  2759.                 write_buf[28 + i] = t_buf[i];
  2760.  
  2761.             for(i = 0; i < 512; i++)
  2762.                 buf[i] = write_buf[i];
  2763.  
  2764.             if(!fwrite(buf, 512, 1, stream))
  2765.                 disp_msg(23, source, dest);
  2766.             if(fclose(stream))
  2767.                 disp_msg(25, source, dest);
  2768.  
  2769.             for(sect = start_sect; sect < f_next_sect; sect += rr_sect){
  2770.                 check_user_break(source, dest);
  2771.  
  2772.                 printf("Dumping Sectors %lu - %lu \n", sect, sect +rr_sect -1);
  2773.                 if(do_read_write(*source,rr_sect,sect,buf,so_32bit,READ)){
  2774.                     check_err_record = make_bad_sect_table(so_dpb, rr_sect, 
  2775.                                         sect, bad_table,so_32bit);
  2776.                     if(check_err_record && !do_anyway){
  2777.                         disp_msg2(11, source, dest,0);
  2778.                         do_anyway = 1;
  2779.                     }
  2780.                     if(!check_err_record && !do_anyway){
  2781.                         for(i = 0; i < rr_sect; i++){
  2782.                             if(!bad_table[i]){
  2783.                                 if(do_read_write(*source, 1, sect + i, 
  2784.                                 buf + r_s_size*i, so_32bit, READ)){
  2785.                                     disp_msg2(11, source, dest,0);
  2786.                                     do_anyway = 1;
  2787.                                 }
  2788.                             }
  2789.                         }
  2790.                     }
  2791.                     if(do_anyway){
  2792.                         if(!check_err_record)
  2793.                             disp_warn(2, source);
  2794.                         for(i = 0; i < rr_sect; i++)
  2795.                             do_read_write(*source, 1, sect + i, 
  2796.                             buf + r_s_size*i, so_32bit, READ);
  2797.                     }
  2798.                 }
  2799.                 resetdisk();
  2800.                 if((stream = fopen(file_name, "ab+")) == NULL)
  2801.                     disp_msg(24, source, dest);
  2802.                 if(!fwrite(buf, (uint)BUF_UNIT, 1, stream))
  2803.                     disp_msg(23, source, dest);
  2804.                 if(big_buf){
  2805.                     if(!fwrite(buf + BUF_UNIT,(uint)BUF_UNIT,1,stream)){
  2806.                         disp_msg(23, source, dest);
  2807.                     }
  2808.                 }
  2809.                 fclose(stream);
  2810.  
  2811.                 if(verify){
  2812.                     stream = fopen(file_name, "ab+");
  2813.                     if(big_buf)
  2814.                         fseek(stream, - BUF_UNIT*2, SEEK_END);
  2815.                     else
  2816.                         fseek(stream, - BUF_UNIT, SEEK_END);
  2817.  
  2818.                     printf("Verifying\n");
  2819.                     if(!fread(buf2, (uint)BUF_UNIT, 1, stream))
  2820.                         disp_msg(30, source, dest);
  2821.                     if(big_buf){
  2822.                         comp_size = (uint)BUF_UNIT;    /*intで比較の為半分に*/
  2823.                         if(!fread(buf2 + BUF_UNIT, (uint)BUF_UNIT,1, stream)){
  2824.                             disp_msg(30, source, dest);
  2825.                         }
  2826.                     }else
  2827.                         comp_size = (uint)(BUF_UNIT / 2);
  2828.  
  2829.                     if(do_compare(buf, buf2, comp_size))
  2830.                         disp_msg(30, source, dest);
  2831.                     fclose(stream);
  2832.                 }
  2833.             }
  2834.  
  2835.             if(f_next_sect != r_next_sect){
  2836.                 check_user_break(source, dest);
  2837.                 printf("Dumping Sectors %lu - %lu \n", f_next_sect, 
  2838.                 r_next_sect -1);
  2839.                 if(do_read_write(*source,(uint)(r_next_sect 
  2840.                 - f_next_sect), f_next_sect, buf, so_32bit, READ)){
  2841.                     check_err_record = make_bad_sect_table(so_dpb, (uint)
  2842.                     (r_next_sect -f_next_sect),f_next_sect,bad_table,so_32bit);
  2843.                     if(check_err_record && !do_anyway){
  2844.                         disp_msg2(11, source, dest,0);
  2845.                         do_anyway = 1;
  2846.                     }
  2847.                     if(!check_err_record && !do_anyway){
  2848.                         for(i = 0; i < (uint)(r_next_sect - f_next_sect); i++){
  2849.                             if(!bad_table[i]){
  2850.                                 if(do_read_write(*source,1,f_next_sect +i
  2851.                                 , buf + r_s_size*i, so_32bit, READ)){
  2852.                                     disp_msg2(11, source, dest,0);
  2853.                                     do_anyway = 1;
  2854.                                 }
  2855.                             }
  2856.                         }
  2857.                     }
  2858.                     if(do_anyway){
  2859.                         if(!check_err_record)
  2860.                             disp_warn(2, source);
  2861.                         for(i = 0; i < (uint)(r_next_sect - f_next_sect); i++)
  2862.                             do_read_write(*source, 1, f_next_sect +i, 
  2863.                             buf + r_s_size*i, so_32bit, READ);
  2864.                     }
  2865.                 }
  2866.                 resetdisk();
  2867.                 if((stream = fopen(file_name, "ab+")) == NULL)
  2868.                     disp_msg(24, source, dest);
  2869.                 if(big_buf && ((r_next_sect-f_next_sect)*(ulong)(r_s_size)) 
  2870.                 > BUF_UNIT){
  2871.                     if(!fwrite(buf, (uint)BUF_UNIT, 1, stream))
  2872.                         disp_msg(23, source, dest);
  2873.                     if(!fwrite(buf + BUF_UNIT, (uint)((r_next_sect 
  2874.                     -f_next_sect)*(ulong)r_s_size) - (uint)BUF_UNIT, 1,stream))
  2875.                         disp_msg(23, source, dest);
  2876.                 }else{
  2877.                     if(!fwrite(buf, (uint)((r_next_sect - f_next_sect)*
  2878.                     (ulong)r_s_size), 1, stream))
  2879.                         disp_msg(23, source, dest);
  2880.                 }
  2881.                 fclose(stream); /*     最終の close でerrorが出るので
  2882.                                     error check なし                */
  2883.  
  2884.                 if(verify){
  2885.                     comp_size =(uint)((r_next_sect-f_next_sect)*(r_s_size/2));
  2886.                     if((stream = fopen(file_name, "ab+")) == NULL)
  2887.                         disp_msg(24, source, dest);
  2888.                     printf("Verifying\n");
  2889.                     fseek(stream, -(ulong)(comp_size*2), SEEK_END);
  2890.                     if(big_buf && ((r_next_sect-f_next_sect)*(ulong)(r_s_size))                     > BUF_UNIT){
  2891.                         if(!fread(buf2, (uint)BUF_UNIT, 1, stream))
  2892.                             disp_msg(30, source, dest);
  2893.                         if(!fread(buf2 + BUF_UNIT, (uint)((r_next_sect -f_next_sect)*(ulong)r_s_size) - (uint)BUF_UNIT, 1,stream))
  2894.                             disp_msg(30, source, dest);
  2895.                     }else{
  2896.                         if(!fread(buf2,(uint)((r_next_sect -f_next_sect)*
  2897.                         (ulong)r_s_size), 1, stream))
  2898.                             disp_msg(30, source, dest);
  2899.                     }
  2900.                     if(do_compare(buf, buf2, comp_size))
  2901.                         disp_msg(30, source, dest);
  2902.                     fclose(stream);
  2903.                 }
  2904.             }
  2905.             start_sect = r_next_sect;
  2906.             if(mult_K)
  2907.                 mult_K --;
  2908.  
  2909.             resetdisk();
  2910.         }while(start_sect < next_sect);
  2911.  
  2912.         start_sect = next_sect;
  2913.         if(start_sect < r_end_sect){
  2914.             ybeep();
  2915.             ybeep();
  2916.             ybeep();
  2917.             ybeep();
  2918.             disp_msg2(7, source, dest, 0);
  2919.             resetdisk();
  2920.         }
  2921.     }while(start_sect < r_end_sect);
  2922. }
  2923.  
  2924. int    check_next_dir_entry(char *t_buf, char *f_name)
  2925. {
  2926.     int j;
  2927.  
  2928.     if((uchar)t_buf[32] == (uchar)0xe5)
  2929.         return (1);
  2930.     if(t_buf[32] == 0)
  2931.         return (1);
  2932.     for(j = 0; j < 8; j++){
  2933.         if(t_buf[32 + j] != f_name[j])
  2934.             return(0);
  2935.     }
  2936.     if(t_buf[32 + 8] != 'D')
  2937.         return(0);
  2938.     if(t_buf[32 + 9] != 'D')
  2939.         return(0);
  2940.     if(t_buf[32 + 10] != '3')
  2941.         return(0);
  2942.  
  2943.     return(1);
  2944. }
  2945.  
  2946. void    p_backup(char *source, char *dest, ulong start_sect)
  2947. {
  2948.     FILE     *stream;
  2949.     char     file_name[80], f_name[14], write_buf[512], t_buf[10],
  2950.              so_dpb[22], dest_dpb[22], ext_so_dpb[63], ext_dest_dpb[63];
  2951.     ulong    free_byte, w_sect, w_end_sect, dir_sect, used_clust,
  2952.             new_sect, old_clust, total_amount,
  2953.             r_sect, r_next_sect, r_f_next_sect, r_end_sect,
  2954.             r_max_sect, r_used_sect;
  2955.     uint    r_s_size, w_s_size, i, j, sect_p_fat,
  2956.             used_dir_entry, dir_clust, rr_sect, ww_sect,
  2957.             check_err_record;
  2958.     int        file_pos_ok = 1, label_skip = 0, do_anyway = 0;
  2959.  
  2960.     if(so_32bit){
  2961.         if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
  2962.             disp_msg(11, source, dest);
  2963.     }else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
  2964.         disp_msg(11, source, dest);
  2965.     if(so_32bit)
  2966.         shift_ext_dpb(so_dpb, ext_so_dpb);
  2967.     else
  2968.         shift_dpb(so_dpb);
  2969.  
  2970.     r_s_size = *(uint *)so_dpb;
  2971.     r_max_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
  2972.     rr_sect = (uint)(buf_size / (ulong)r_s_size);
  2973.     r_used_sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
  2974.  
  2975.     if(!full_dump)
  2976.         r_end_sect = r_used_sect;
  2977.     else
  2978.         r_end_sect = r_max_sect;
  2979.  
  2980.     if(start_sect >= r_end_sect)
  2981.         disp_msg(27, source, dest);
  2982.  
  2983.     if(bad_clust_num > 80){
  2984.         disp_msg2(10, source, dest, start_sect);
  2985.         do_anyway = 1;        /* 強制実行    */
  2986.     }else if(bad_clust_num)
  2987.         disp_warn(1, source);
  2988.  
  2989.     if(r_s_size > 1024)
  2990.         total_amount = (r_end_sect +1) * (ulong)(r_s_size / 1024);
  2991.     else
  2992.         total_amount = (r_end_sect +1) / (ulong)(1024 / r_s_size);
  2993.     used_dir_entry = get_used_dir_entry(source, so_dpb);
  2994.  
  2995.     printf("Backup Amount is %ld K bytes (1 K = 1024)\n", total_amount);
  2996.  
  2997. /*  以下は write_buf の設定    */
  2998.     strcpy(write_buf, "DiskDump Ver 3.0");    /* 16 文字    */
  2999.     strcat(write_buf, "          -          ");    /* 21 文字    */
  3000.     if(so_32bit)
  3001.         strcat(write_buf, "     FAT32 ");    /* 11 文字    */
  3002.     else
  3003.         strcat(write_buf, "     FAT16 ");    /* 11 文字    FAT12 も含む    */
  3004.     strcat(write_buf, "Total:          ");    /* 16 文字    */
  3005.     sprintf(t_buf, "%.8lu", r_max_sect);
  3006.     for(i = 0; i < 8; i++)
  3007.         write_buf[16*3 + 7 + i] = t_buf[i];
  3008.     strcat(write_buf, "Used:           ");    /* 16 文字    */
  3009.     sprintf(t_buf, "%.8lu", r_used_sect);
  3010.     for(i = 0; i < 8; i++)
  3011.         write_buf[16*4 + 7 + i] = t_buf[i];
  3012.     for (i = 0; i < 22; i++)    /* so_dpb[21] はゴミ    */
  3013.         write_buf[80 +i] = so_dpb[i];
  3014.  
  3015.     *(uint *)(write_buf + USED_D) = used_dir_entry;
  3016.     *(ulong *)(write_buf + USED_C) = used_clust;
  3017.  
  3018.     *(ulong *)(write_buf + R_START_S) = 0L;         /* start_sect    */
  3019.     *(ulong *)(write_buf + R_NEXT_S) = 0L;     /* r_next_sect     */
  3020.                                             /* 取り敢えず 0 を書き込む    */
  3021.     *(ulong *)(write_buf + W_START_S) = 0L;     /* write_start_sect    */
  3022.     *(ulong *)(write_buf + R_END_S) = r_end_sect; /* read_end_sect    */
  3023.  
  3024.     if(win95)
  3025.         ioctrl_lock(*source - 'A' +1, 0);
  3026.     if(do_read_write(*source, 1, 0, buf, so_32bit, READ))    /* ipl read    */
  3027.         disp_msg(11, source, dest);
  3028.     resetdisk();
  3029.     for (i = 0; i < 64; i++)
  3030.         write_buf[128 +i] = buf[i];        /* ipl    */
  3031.     *(uint *)(write_buf + C_SECT_C) = (uint)buf[13];    /* sect/clust    */
  3032.     *(uint *)(write_buf + 110) = 0;    /* ゴミ    */
  3033.  
  3034.     for(i = 0; i < 320; i++)
  3035.         write_buf[192 +i] = bad_clust[i];
  3036.  
  3037.     do{
  3038.         if(win95){
  3039.             ioctrl_lock(*dest - 'A' +1, 0);
  3040.             ioctrl_lock(*source - 'A' +1, 0);
  3041.         }
  3042.         if(des_32bit){
  3043.             if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
  3044.                 disp_msg(12, source, dest);
  3045.         }else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
  3046.             disp_msg(12, source, dest);
  3047.         if(des_32bit)
  3048.             shift_ext_dpb(dest_dpb, ext_dest_dpb);
  3049.         else
  3050.             shift_dpb(dest_dpb);
  3051.  
  3052.         sect_p_fat = *(uint *)(dest_dpb + S_P_FAT);
  3053.         w_s_size = *(uint *)dest_dpb;
  3054.  
  3055.     /*    file_name と f_name は同じだが,file_name は full path     */
  3056.         set_file_name(file_name, dest, start_sect, 1);
  3057.         sprintf(f_name, "%.8lu", start_sect);
  3058.         strcat(f_name, ".DDD");
  3059.  
  3060.         if((stream = fopen(file_name, "wb")) == NULL)
  3061.             disp_msg(24, source, dest);
  3062.  
  3063.         if(!fwrite(write_buf, 512, 1, stream))    /* 書いただけでは先頭      */
  3064.             disp_msg(23, source, dest);            /* cluster に入らないので */
  3065.         if(fclose(stream))                        /* 後で書き直す              */
  3066.             disp_msg(25, source, dest);
  3067.  
  3068.         if(des_32bit){
  3069.         /*    root_dir の sector = (root_dir_entry -2)*cluster_par_sect
  3070.                                 + reserved_sect + sect_par_FAT*num_of_FAT */
  3071.             dir_sect = clust2sect(dest_dpb, *(ulong *)(ext_dest_dpb +55));
  3072.             dir_clust = *(uint *)(ext_dest_dpb + 55); /* 通常 2 */
  3073.         }else{
  3074.         /*    root_dir の sector = reserved_sec + sect_par_FAT*num_of_FAT    */
  3075.             dir_sect = (ulong)(*(uint *)(dest_dpb + FAT_S)) 
  3076.                         + *(ulong *)(dest_dpb + S_P_FAT)*2L;
  3077.             dir_clust = 1; /* 32bit FAT との共通化の為 */
  3078.         }
  3079.         if(do_read_write(*dest,1,dir_sect,buf,des_32bit,READ))
  3080.             disp_msg(12, source, dest);
  3081.  
  3082.         if(buf[0x0b] != 0x0f){    /* not long file name    */
  3083.             if((buf[0x0b] & _A_VOLID) == _A_VOLID)
  3084.                 label_skip = 1;
  3085.         }
  3086.  
  3087.         for(j = 0; (j < 8) && file_pos_ok; j++){
  3088.             if(buf[label_skip*32 +j] != f_name[j])
  3089.                 file_pos_ok = 0;
  3090.         }
  3091.         for(j = 8; (j < 11) && file_pos_ok; j++){
  3092.             if(buf[label_skip*32 +j] != f_name[j +1])
  3093.                 file_pos_ok = 0;
  3094.         }
  3095.  
  3096.         if(file_pos_ok){    /* 次は,空か xxxx.DD3 */
  3097.             if(!check_next_dir_entry(buf + label_skip*32, f_name))
  3098.                 file_pos_ok = 0;
  3099.         }
  3100.         if(!file_pos_ok)
  3101.             disp_msg(12, source, dest);
  3102.  
  3103.     /*  以下 directory entory 部分書き換え    */
  3104.         if(des_32bit){
  3105.             for(i = 0; i < 4; i++)
  3106.                 t_buf[i]=buf[label_skip*32 +26 + i];    /* cluster 部分    */
  3107.             old_clust = *(ulong *)t_buf;
  3108.             *(int *)(buf + label_skip*32 +20) = 0;
  3109.             *(int *)(buf + label_skip*32 +26) = dir_clust + 1;
  3110.                 /* XXX.DDD は dir_clust + 1 (通常 3) cluster を使う    */
  3111.         }else{
  3112.             old_clust = (ulong)*(uint *)(buf + label_skip*32 +26);
  3113.             *(int *)(buf + label_skip*32 + 26) = 2;    
  3114.             /* XXX.DDD は 2 cluster を使う    */
  3115.         }
  3116.         new_sect=clust2sect(dest_dpb,(ulong)*(int *)(buf + label_skip*32 +26));
  3117.             /* new_sect は 新しい XXX.DDD の sector    int の値    */
  3118.  
  3119.         for(j = 0; j < 8; j++)
  3120.             buf[label_skip*32 +32 + j] = f_name[j];
  3121.         buf[label_skip*32 +32 +8] = 'D';
  3122.         buf[label_skip*32 +32 +9] = 'D';
  3123.         buf[label_skip*32 +32 +10] = '3';
  3124.         for(j = 11; j < 20; j++)
  3125.             buf[label_skip*32 +32 +j] = buf[label_skip*32 +j];
  3126.         *(int *)(buf + label_skip*32 +32 +20) = 0;
  3127.         for(j = 22; j < 26; j++)
  3128.             buf[32 + label_skip*32 +j] = buf[label_skip*32 +j];
  3129.         if(des_32bit)
  3130.             *(int *)(buf + label_skip*32 +32 +26) = dir_clust + 2;
  3131.                 /* XXX.DD3 は dir_clust + 2 (通常 4) cluster を使う    */
  3132.         else
  3133.             *(int *)(buf + label_skip*32 +32 +26) = 3;    
  3134.             /* XXX.DD3 は 3 cluster を使う file size [buf + 32 +28] は後で    */
  3135.  
  3136.         w_sect = new_sect + (ulong)dest_dpb[C_MASK] + 1; 
  3137.         w_end_sect = clust2sect(dest_dpb, (*(ulong *)(dest_dpb +MAX_C) + 1));
  3138.         if(w_s_size < r_s_size){
  3139.             w_end_sect = (((w_end_sect - w_sect)*w_s_size) /r_s_size)
  3140.                         *(r_s_size /w_s_size);
  3141.             w_end_sect += w_sect;
  3142.         }
  3143.         ww_sect = (uint)(buf_size / (ulong)w_s_size);
  3144.         r_next_sect = start_sect 
  3145.                     + (ulong)(((w_end_sect - w_sect)*w_s_size)/r_s_size);
  3146.  
  3147.         if(r_next_sect >= r_end_sect)
  3148.             r_next_sect = r_end_sect;
  3149.         r_f_next_sect = r_next_sect - ((r_next_sect - start_sect) % rr_sect);
  3150.  
  3151.         *( ulong *)(buf+ label_skip*32 +32+28) 
  3152.         = (r_next_sect -start_sect)*(ulong)r_s_size;
  3153.         /* 2G を越えても表示のみだからこのままにしておく    */
  3154.  
  3155.         for(i = (label_skip +2)*32; i < w_s_size; i++)
  3156.             buf[i] = 0;    /* xxx.DDD, xxx.DD3 以外を消す    */
  3157.  
  3158.         if(do_read_write(*dest,1,dir_sect,buf,des_32bit,WRITE))
  3159.             disp_msg(12, source, dest);
  3160.         resetdisk();
  3161.     /*  directory entory 部分書き換え終り    */
  3162.  
  3163.         rewrite_fat_to0(dest, dest_dpb);
  3164.         rewrite_old(dest, old_clust, dir_clust, dest_dpb);
  3165.         rewrite_fat(dest,  w_sect, (r_next_sect - start_sect)
  3166.         *(ulong)r_s_size, dest_dpb);
  3167.  
  3168.         *(ulong *)(write_buf + R_START_S) = start_sect;
  3169.         *(ulong *)(write_buf + R_NEXT_S) = r_next_sect;
  3170.         *(ulong *)(write_buf + W_START_S) = w_sect;
  3171.         sprintf(t_buf, "%.8lu", start_sect);    /* From: xxxxxxx */
  3172.  
  3173.         for(i = 0; i < 8; i++)
  3174.             write_buf[17 +i] = t_buf[i];
  3175.         sprintf(t_buf, "%.8lu", r_next_sect -1);/* To: yyyyyyyy   */
  3176.         for(i = 0; i < 8; i++)
  3177.             write_buf[28 + i] = t_buf[i];
  3178.  
  3179.         for(i = 0; i < 512; i++)
  3180.             buf[i] = write_buf[i];
  3181.         for(i = 512; i < w_s_size; i++)
  3182.             buf[i] = 0;        /* 書き込みをsect単位にするためにゴミ掃除    */
  3183.  
  3184.         if(do_read_write(*dest,1,new_sect,buf,des_32bit,WRITE))
  3185.             disp_msg(12, source, dest);
  3186.         resetdisk();
  3187.  
  3188.         set_file_name(file_name, dest, start_sect, 0);
  3189.         printf("\nNow Making Backup File %s\n [Sectors %lu - %lu ]\n\n", 
  3190.         file_name, start_sect, r_next_sect - 1);
  3191.  
  3192.         for(r_sect = start_sect; r_sect < r_f_next_sect; r_sect += rr_sect){
  3193.             check_user_break(source, dest);
  3194.             printf("Dumping Sectors %lu - %lu \n", r_sect, r_sect +rr_sect -1);
  3195.             if(do_read_write(*source,rr_sect,r_sect,buf,so_32bit,READ)){
  3196.                 check_err_record = make_bad_sect_table(so_dpb, rr_sect, 
  3197.                                     r_sect, bad_table, so_32bit);
  3198.                 if(check_err_record && !do_anyway){
  3199.                     disp_msg2(11, source, dest,0);
  3200.                     do_anyway = 1;
  3201.                 }
  3202.                 if(!check_err_record && !do_anyway){
  3203.                     for(i = 0; i < rr_sect; i++){
  3204.                         if(!bad_table[i]){
  3205.                             if(do_read_write(*source, 1, r_sect + i, 
  3206.                             buf + r_s_size*i, so_32bit, READ)){
  3207.                                 disp_msg2(11, source, dest,0);
  3208.                                 do_anyway = 1;
  3209.                             }
  3210.                         }
  3211.                     }
  3212.                 }
  3213.                 if(do_anyway){
  3214.                     if(!check_err_record)
  3215.                         disp_warn(2, source);
  3216.                     for(i = 0; i < rr_sect; i++)
  3217.                         do_read_write(*source, 1, r_sect + i, 
  3218.                         buf + r_s_size*i, so_32bit, READ);
  3219.                 }
  3220.             }
  3221.             if(do_read_write(*dest,ww_sect,w_sect,buf,des_32bit,WRITE))
  3222.                 disp_msg(21, source, dest);
  3223.  
  3224.             w_sect += ww_sect;
  3225.             resetdisk();
  3226.         }
  3227.         if(r_f_next_sect != r_next_sect){
  3228.             check_user_break(source, dest);
  3229.             printf("Dumping Sectors %lu - %lu \n", r_f_next_sect,
  3230.             r_next_sect -1);
  3231.  
  3232.             if(do_read_write(*source, (uint)(r_next_sect - r_f_next_sect),
  3233.             r_sect, buf, so_32bit, READ)){
  3234.                 check_err_record = make_bad_sect_table(so_dpb, (uint)
  3235.                 (r_next_sect - r_f_next_sect), r_sect, bad_table, so_32bit);
  3236.                 if(check_err_record && !do_anyway){
  3237.                     disp_msg2(11, source, dest,0);
  3238.                     do_anyway = 1;
  3239.                 }
  3240.                 if(!check_err_record && !do_anyway){
  3241.                     for(i = 0; i < (uint)(r_next_sect - r_f_next_sect); i++){
  3242.                         if(!bad_table[i]){
  3243.                             if(do_read_write(*source, 1, r_sect +i, 
  3244.                             buf + r_s_size*i, so_32bit, READ)){
  3245.                                 disp_msg2(11, source, dest,0);
  3246.                                 do_anyway = 1;
  3247.                             }
  3248.                         }
  3249.                     }
  3250.                 }
  3251.                 if(do_anyway){
  3252.                     if(!check_err_record)
  3253.                         disp_warn(2, source);
  3254.                     for(i = 0; i < (uint)(r_next_sect - r_f_next_sect); i++){
  3255.                         do_read_write(*source, 1, r_sect +i, 
  3256.                         buf + r_s_size*i, so_32bit, READ);
  3257.                     }
  3258.                 }
  3259.             }
  3260.             if(do_read_write(*dest,    (uint)div_upper((r_next_sect 
  3261.             -r_f_next_sect)*r_s_size, (ulong)w_s_size), w_sect,buf,des_32bit,
  3262.             WRITE))
  3263.                 disp_msg(21, source, dest);
  3264.         }
  3265.         start_sect = r_next_sect;
  3266.         resetdisk();
  3267.         if(start_sect < r_end_sect){
  3268.             ybeep();
  3269.             ybeep();
  3270.             ybeep();
  3271.             ybeep();
  3272.             disp_msg2(7, source, dest, 0);
  3273.             resetdisk();
  3274.         }
  3275.     }while(start_sect < r_end_sect);
  3276. }
  3277.  
  3278. void    duplicate(char *source, char *dest, ulong start_sect)
  3279. {
  3280.     ulong    sect, f_end_sect, end_sect, w_end_sect, total_amount, 
  3281.             used_clust, data_sect, data_sect2, data_size, max_clust;
  3282.     uint    rw_sect, sect_size, i, check_err_record, used_dir_entry, 
  3283.             sect_p_clust;
  3284.     char     so_dpb[22], dest_dpb[22], ext_so_dpb[63], ext_dest_dpb[63], 
  3285.             check_buf[512];
  3286.     int        do_anyway = 0, data_diff, w_offset = 0, r_offset = 0;
  3287.  
  3288.     if(win95){
  3289.         ioctrl_lock(*dest - 'A' +1, 0);
  3290.         ioctrl_lock(*source - 'A' +1, 0);
  3291.     }
  3292.  
  3293.     if(so_32bit){
  3294.         if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
  3295.             disp_msg(11, source, dest);
  3296.     }else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
  3297.         disp_msg(11, source, dest);
  3298.     if(so_32bit)
  3299.         shift_ext_dpb(so_dpb, ext_so_dpb);
  3300.     else
  3301.         shift_dpb(so_dpb);
  3302.  
  3303.     if(des_32bit){
  3304.         if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
  3305.             disp_msg(12, source, dest);
  3306.     }else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
  3307.         disp_msg(12, source, dest);
  3308.  
  3309.     if(des_32bit)
  3310.         shift_ext_dpb(dest_dpb, ext_dest_dpb);
  3311.     else
  3312.         shift_dpb(dest_dpb);
  3313.  
  3314.     sect_size = *(uint *)so_dpb;
  3315.     end_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
  3316.     w_end_sect = clust2sect(dest_dpb, *(ulong *)(dest_dpb + MAX_C) +1);
  3317.     sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
  3318.     if(!full_dump)
  3319.         end_sect = sect;
  3320.  
  3321.     data_sect = *(ulong *)(so_dpb + DATA_S); /* sourceのdata_sect */
  3322.     data_sect2 = *(ulong *)(dest_dpb + DATA_S);    /* destのdata_sect      */
  3323.     data_diff = data_sect2 - data_sect;
  3324.     rw_sect = (uint)(buf_size / (ulong)sect_size);
  3325.  
  3326.     if(bad_clust_num > 80){
  3327.         disp_msg2(10, source, dest, start_sect);
  3328.         do_anyway = 1;        /* 強制実行    */
  3329.     }else if(bad_clust_num)
  3330.         disp_warn(1, source);
  3331.  
  3332.     for(i = 0; i < 22; i++)
  3333.         check_buf[80 + i] = so_dpb[i];
  3334.     if(do_read_write(*source, 1, 0, buf, so_32bit, READ))
  3335.         disp_msg(11, source, dest);
  3336.     resetdisk();
  3337.     for(i = 0; i < 64; i++)
  3338.         check_buf[128 + i] = buf[i];
  3339.     sect_p_clust = (uint)buf[13];    /* sect/clust    */
  3340.  
  3341.     used_dir_entry = get_used_dir_entry(source, so_dpb);
  3342.     *(uint *)(check_buf + USED_D) = used_dir_entry;
  3343.     *(ulong *)(check_buf + USED_C) = used_clust;
  3344.     *(uint *)(check_buf + C_SECT_C) = sect_p_clust;
  3345.     *(uint *)(check_buf + 110) = 0;    /* ゴミ    */
  3346.  
  3347.     switch(check_disk_format(dest_dpb, check_buf)){
  3348.         case 0:    
  3349.             disp_msg(16, source, dest);
  3350.             break;
  3351.         case 1:
  3352.             rewrite_flag = 0;
  3353.             break;
  3354.         case 2:    
  3355.             max_clust = *(ulong *)(check_buf +C_MAX_C) -1;
  3356.             if(sect_size > 1024)
  3357.                 data_size = max_clust * sect_p_clust 
  3358.                             * (ulong)(sect_size / 1024);
  3359.             else
  3360.                 data_size = (max_clust * sect_p_clust)
  3361.                              / (ulong)(1024 / sect_size);
  3362.             if(!disp_msg3(data_size)){
  3363.                 ybeep();
  3364.                 exit_routine(40);
  3365.             }
  3366.  
  3367.             if(!check_dir_entry_etc(dest_dpb, check_buf))
  3368.                 disp_msg(39, source, dest);
  3369.             else
  3370.                 rewrite_flag = 1;
  3371.             break;
  3372.     }
  3373.  
  3374.     if(rewrite_flag){
  3375.         if(end_sect + data_diff > w_end_sect)
  3376.             disp_msg(45, source, dest);
  3377.     }
  3378.     if(sect_size > 1024)
  3379.         total_amount = (end_sect +1) * (ulong)(sect_size / 1024);
  3380.     else
  3381.         total_amount = (end_sect +1) / (ulong)(1024 / sect_size);
  3382.     printf("Backup Amount is %ld K bytes (1 K = 1024)\n", total_amount);
  3383.  
  3384.     if(rewrite_flag && (start_sect < data_sect)){
  3385.         if(start_sect != 0)
  3386.             disp_msg(41, source, dest);
  3387.         d_write_ipl(source, dest, rw_sect, so_dpb, dest_dpb, check_buf);
  3388.         d_write_FAT(source, dest, rw_sect, so_dpb, dest_dpb, check_buf);
  3389.         d_write_dir_entry(source,dest,rw_sect,check_buf, so_dpb, dest_dpb);
  3390.         r_offset = data_sect;
  3391.         w_offset = data_sect2;
  3392.     }
  3393.  
  3394.     end_sect += data_diff;
  3395.     f_end_sect = (end_sect - w_offset - start_sect) 
  3396.                 - ((end_sect - w_offset - start_sect) % rw_sect);
  3397.     f_end_sect += w_offset + start_sect;
  3398.         /* ここでは,f_end_sect, sect 等は書き込む sector    */
  3399.  
  3400.     printf("\nNow Duplicating from %c: to %c:\n", *source, *dest);
  3401.     printf(" [Write to Sectors %lu - %lu ]\n\n", start_sect +w_offset, end_sect - 1);
  3402.  
  3403.     for(sect = start_sect + w_offset; sect < f_end_sect; sect += rw_sect){
  3404.         check_user_break(source, dest);
  3405.         printf("Writing Sectors %lu - %lu \n", sect, sect + rw_sect -1);
  3406.  
  3407.         if(do_read_write(*source, rw_sect, sect -data_diff, buf, so_32bit, READ)){
  3408.             /* 以下は rewrite の時は,break するように    */
  3409.             /* make_bad_sect_table を定義している        */
  3410.             check_err_record = make_bad_sect_table(so_dpb, rw_sect,sect,
  3411.                                 bad_table, so_32bit);
  3412.             if(check_err_record && !do_anyway){
  3413.                 disp_msg2(11, source, dest,0);
  3414.                 do_anyway = 1;
  3415.             }
  3416.             if(!check_err_record && !do_anyway){
  3417.                 for(i = 0; i < rw_sect; i++){
  3418.                     if(!bad_table[i]){
  3419.                         if(do_read_write(*source, 1, sect +i, 
  3420.                         buf + sect_size*i, so_32bit, READ)){
  3421.                             disp_msg2(11, source, dest,0);
  3422.                             do_anyway = 1;
  3423.                         }
  3424.                     }
  3425.                 }
  3426.             }
  3427.             if(do_anyway){
  3428.                 if(!check_err_record)
  3429.                     disp_warn(2, source);
  3430.                 for(i = 0; i < rw_sect; i++)
  3431.                     do_read_write(*source, 1, sect + i, 
  3432.                     buf + sect_size*i, so_32bit, READ);
  3433.             }
  3434.         }
  3435.         if(do_read_write(*dest,rw_sect,sect,buf,des_32bit,WRITE))
  3436.             disp_msg(21, source, dest);
  3437.         resetdisk();
  3438.     }
  3439.  
  3440.     if(f_end_sect != end_sect){
  3441.         check_user_break(source, dest);
  3442.         printf("Writing Sectors %lu - %lu\n", sect, end_sect -1);
  3443.         if(do_read_write(*source, (uint)(end_sect - f_end_sect), 
  3444.         sect - data_diff, buf, so_32bit, READ)){
  3445.             /* 以下は rewrite の時は,break するように    */
  3446.             /* make_bad_sect_table を定義している        */
  3447.             check_err_record = make_bad_sect_table(so_dpb, (uint)(end_sect 
  3448.             - f_end_sect), f_end_sect, bad_table, so_32bit);
  3449.             if(check_err_record && !do_anyway){
  3450.                 disp_msg2(11, source, dest,0);
  3451.                     do_anyway = 1;
  3452.             }
  3453.             if(!check_err_record && !do_anyway){
  3454.                 for(i = 0; i < (uint)(end_sect - f_end_sect); i++){
  3455.                     if(!bad_table[i]){
  3456.                         if(do_read_write(*source, 1, f_end_sect +i,
  3457.                         buf + sect_size*i, so_32bit, READ)){
  3458.                             disp_msg2(11, source, dest,0);
  3459.                             do_anyway = 1;
  3460.                         }
  3461.                     }
  3462.                 }
  3463.             }
  3464.             if(do_anyway){
  3465.                 if(!check_err_record)
  3466.                     disp_warn(2, source);
  3467.                 for(i = 0; i < (uint)(end_sect - f_end_sect); i++){
  3468.                     do_read_write(*source, 1, f_end_sect +i,
  3469.                     buf + sect_size*i, so_32bit, READ);
  3470.                 }
  3471.             }
  3472.         }
  3473.         if(do_read_write(*dest,(uint)(end_sect - f_end_sect), sect, buf, des_32bit, WRITE))
  3474.             disp_msg(21, source, dest);
  3475.     }
  3476.     resetdisk();
  3477.     if(des_32bit && rewrite_flag)
  3478.         reset_free_clust(dest, sect_size);
  3479. }
  3480.  
  3481. void    test(char *source, char *dest, int mode)
  3482. /*  read source 0 - r_end_sect, write dest w_start_sect - w_end_sect    */
  3483. /*  read dest w_start_sect - w_end_sect, write source ww_start - ww_end    */
  3484. /*  mode:0 -> BIG to BIG, mode:1 -> BIG to SMALL, mode:2 -> SMALL to BIG*/
  3485. {
  3486.     char     so_dpb[22], dest_dpb[22], ext_so_dpb[63], ext_dest_dpb[63];
  3487.     ulong    sect, w_sect, w_sect2, used_clust, r_end_sect, 
  3488.             w_start_sect, w_end_sect, ww_start_sect, ww_end_sect,
  3489.             so_end_sect, dest_end_sect, t_buf_size;
  3490.     uint    r_s_size, w_s_size, rr_sect, ww_sect, r_s_length, w_s_length, 
  3491.             comp_size;
  3492.     int         err = 0, i;
  3493.  
  3494.     if(so_32bit){
  3495.         if(get_ext_dpb(*source -'A' + 1, ext_so_dpb) == -1)
  3496.             disp_msg(11, source, dest);
  3497.     }else if(get_dpb(*source -'A' + 1, so_dpb) == -1)
  3498.         disp_msg(11, source, dest);
  3499.     if(so_32bit)
  3500.         shift_ext_dpb(so_dpb, ext_so_dpb);
  3501.     else
  3502.         shift_dpb(so_dpb);
  3503.  
  3504.     if(des_32bit){
  3505.         if(get_ext_dpb(*dest -'A' + 1, ext_dest_dpb) == -1)
  3506.             disp_msg(12, source, dest);
  3507.     }else if(get_dpb(*dest -'A' + 1, dest_dpb) == -1)
  3508.         disp_msg(12, source, dest);
  3509.     if(des_32bit)
  3510.         shift_ext_dpb(dest_dpb, ext_dest_dpb);
  3511.     else
  3512.         shift_dpb(dest_dpb);
  3513.  
  3514.     switch(mode){
  3515.         case 2:
  3516.         case 3:
  3517.             t_buf_size = BUF_UNIT;
  3518.             break;
  3519.         default:
  3520.             t_buf_size = BUF_UNIT*2;
  3521.             break;
  3522.     }
  3523.  
  3524.     r_s_size = *(uint *)so_dpb;
  3525.     so_end_sect = clust2sect(so_dpb, *(ulong *)(so_dpb + MAX_C) +1);
  3526.     rr_sect = (uint)(t_buf_size / (ulong)r_s_size);
  3527.     r_s_length = (uint)(0xa0000L/(ulong)r_s_size);
  3528.  
  3529.     ww_start_sect = get_true_end_sect(so_dpb, source, &used_clust, so_32bit);
  3530.     ww_end_sect = ww_start_sect + r_s_length;
  3531.  
  3532.     if(ww_end_sect > so_end_sect)
  3533.         disp_msg(34, source, dest);
  3534.  
  3535.     r_end_sect = r_s_length;    /* 0 - (r_end_sect-1) をtest    */
  3536.     if(r_end_sect >= ww_start_sect)
  3537.         disp_msg(35, source, dest);
  3538.  
  3539.     if(win95){
  3540.         ioctrl_lock(*dest - 'A' +1, 0);
  3541.         ioctrl_lock(*source - 'A' +1, 0);
  3542.     }
  3543.  
  3544.     w_s_size = *(uint *)dest_dpb;
  3545.     ww_sect = (uint)(t_buf_size / (ulong)w_s_size);
  3546.     w_s_length = (uint)(0xa0000L/(ulong)w_s_size);
  3547.  
  3548.     dest_end_sect = clust2sect(dest_dpb,*(ulong *)(dest_dpb + MAX_C) +1);
  3549.     w_start_sect = get_true_end_sect(dest_dpb, dest, &used_clust, des_32bit);
  3550.     if(dest_end_sect < w_start_sect + w_s_length)
  3551.         disp_msg(38, source, dest);
  3552.     w_end_sect = w_start_sect + w_s_length;
  3553.     w_sect = w_start_sect;
  3554.  
  3555.     printf("\n\"-p -G option\" Test Mode.\n");
  3556.     printf("Backup Small Area From %s To %s.\n", source, dest);
  3557.     printf("And Restore Small Area From %s To %s.\n", dest, source);
  3558.  
  3559.     printf("\nTest Amount is 640 K bytes (1 K = 1024 byte)\n");
  3560.     switch(mode){
  3561.         case 0:
  3562.             printf("Test Using Backup 64K, Restore 64K buffer\n");
  3563.             break;
  3564.         case 1:
  3565.             printf("Test Using Backup 64K, Restore 32K buffer\n");
  3566.             break;
  3567.         case 2:
  3568.             printf("Test Using Backup 32K, Restore 64K buffer\n");
  3569.             break;
  3570.         case 3:
  3571.             printf("Test Using Backup 32K, Restore 32K buffer\n");
  3572.             break;
  3573.     }
  3574.  
  3575.     printf("Now Test Backup From %c: To %c:\n", *source, *dest);
  3576.     printf(" [Sectors 0 - %lu ] To [Sectors %ld - %lu ]\n",r_end_sect -1, w_start_sect,w_end_sect -1);
  3577.     disp_msg2(9, source, dest, 0);
  3578.     for(sect = 0; sect < r_end_sect; sect += rr_sect){
  3579.         check_user_break(source, dest);
  3580.         printf("Dumping Sectors %lu - %lu \n", sect, sect + rr_sect -1);
  3581.  
  3582.         if(do_read_write(*source,rr_sect, sect, buf, so_32bit, READ))
  3583.             disp_msg(20, source, dest);
  3584.         if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, WRITE))
  3585.             disp_msg(21, source, dest);
  3586.         w_sect += ww_sect;
  3587.         resetdisk();
  3588.     }
  3589.  
  3590.     switch(mode){
  3591.         case 1:
  3592.         case 3:
  3593.             t_buf_size = BUF_UNIT;
  3594.             break;
  3595.         default:
  3596.             t_buf_size = BUF_UNIT*2;
  3597.             break;
  3598.     }
  3599.     rr_sect = (uint)(t_buf_size / (ulong)r_s_size);    /* read write 逆になる    */
  3600.     ww_sect = (uint)(t_buf_size / (ulong)w_s_size);    /* read write 逆になる    */
  3601.  
  3602.     printf("\nNow Test Restore From %c: To %c:\n", *dest, *source);
  3603.     printf(" [Sectors %ld - %lu ] To [Sectors %ld - %lu ]\n", w_start_sect, 
  3604.     w_end_sect -1, ww_start_sect, ww_end_sect -1);
  3605.  
  3606.     disp_msg2(9, source, dest, 0);
  3607.  
  3608.     sect = 0;
  3609.     w_sect2 = ww_start_sect;
  3610.     for(w_sect = w_start_sect; w_sect < w_end_sect; w_sect += ww_sect){
  3611.         check_user_break(source, dest);
  3612.         printf("Restoring from Sectors %lu - %lu\n",w_sect,w_sect +ww_sect-1);
  3613.         if(do_read_write(*dest, ww_sect, w_sect, buf, des_32bit, READ))
  3614.             disp_msg(20, source, dest);
  3615.         if(do_read_write(*source, rr_sect, w_sect2, buf, so_32bit, WRITE))
  3616.             disp_msg(21, source, dest);
  3617.         sect += rr_sect;
  3618.         w_sect2 += rr_sect;
  3619.         resetdisk();
  3620.     }
  3621.  
  3622.     printf("\nNow Compare Data\n");
  3623.     printf(" [Sectors 0 - %lu ] with [Sectors %ld - %lu ]\n", r_end_sect - 1, 
  3624.     ww_start_sect, ww_end_sect -1);
  3625.  
  3626.     disp_msg2(9, source, dest, 0);
  3627.  
  3628.     t_buf_size = BUF_UNIT;
  3629.     rr_sect = (uint)(t_buf_size / (ulong)r_s_size);    /* read write 共通    */
  3630.     comp_size = (uint)t_buf_size / 2;
  3631.     sect = 0;
  3632.     w_sect2 = ww_start_sect;
  3633.  
  3634.     for(sect = 0; sect < r_end_sect; sect += rr_sect){
  3635.         check_user_break(source, dest);
  3636.         printf("Comparing Sectors %lu - %lu with %ld - %ld\n", 
  3637.         sect, sect + rr_sect -1, w_sect2, w_sect2 + rr_sect -1);
  3638.  
  3639.         if(do_read_write(*source, rr_sect, sect, buf, so_32bit, READ))
  3640.             disp_msg(20, source, dest);
  3641.         if(do_read_write(*source, rr_sect, w_sect2, buf2, so_32bit,READ))
  3642.             disp_msg(20, source, dest);
  3643.  
  3644.         w_sect2 += rr_sect;
  3645.         resetdisk();
  3646.         err = do_compare(buf, buf2, comp_size);
  3647.         if(err)
  3648.             break;
  3649.     }
  3650.     if(err)
  3651.         disp_warn(5, source);
  3652.  
  3653.     for(i = 0; i < 0x4000; i++)        /* clear test area    */
  3654.         *(int *)(buf + 2*i) = 0;
  3655.  
  3656.     printf("\nNow Clear Test Area of Source Drive\n");
  3657.     printf(" [Sectors %ld - %lu ]\n", ww_start_sect, ww_end_sect - 1);
  3658.  
  3659.     disp_msg2(9, source, dest, 0);
  3660.  
  3661.     for(w_sect2 = ww_start_sect; w_sect2 < ww_end_sect; w_sect2 += rr_sect){
  3662.         printf("Clearing Sectors %lu - %lu\n", w_sect2, w_sect2 + rr_sect -1);
  3663.         if(do_read_write(*source, rr_sect, w_sect2, buf, so_32bit, WRITE))
  3664.             disp_msg(46, source, dest);
  3665.         resetdisk();
  3666.     }
  3667.     if(err)
  3668.         exit_routine(36);
  3669.     else
  3670.         disp_msg(37, source, dest);
  3671. }
  3672.  
  3673. int check_osr2_32(char drv)
  3674. {
  3675.     char     dpb[22], ext_dpb[63];
  3676.     int        FAT_32 = -1 ;
  3677.  
  3678.     if(get_dpb((int)drv -'A' + 1, dpb) == 0)
  3679.         FAT_32 = 0 ;
  3680.     else if(win95 && (get_ext_dpb((int)drv -'A' + 1, ext_dpb) == 0))
  3681.         FAT_32 = 1; /* 詳しくは,ipl[11],[12] を調べる    */
  3682.     return(FAT_32);
  3683. }
  3684.  
  3685. void    main(int argc, char *argv[])
  3686. {
  3687.     int  i, help_flag = 0, s_d_flag = 0, pro_flag = 0, test_mode = 0;
  3688.     int  backup_restore = 1;    /*  0:restore, 1:backup, 2: duplicate    */
  3689.     ulong start_sect = 0;        /*  3:p_restore, 4:p_backup                */
  3690.                                 /*  5:test_mode                            */
  3691.     char source[80], dest[80];
  3692.  
  3693.     full_dump = 0;
  3694.     error_code = NO_ERROR;
  3695.     set_24h();
  3696.  
  3697.     for(i = 1; i < argc; i++){
  3698.         if((argv[i][0] == '/') || (argv[i][0] == '-')){
  3699.             switch(toupper(argv[i][1])){
  3700.                 case '?':    help_flag = 1;
  3701.                             break;
  3702.                 case 'R':    backup_restore = 0;
  3703.                             break;
  3704.                 case 'B':    backup_restore = 1;
  3705.                             break;
  3706.                 case 'S':    if(toupper(argv[i][2]) == 'T')
  3707.                                 start_sect = atol(argv[i] + 3);
  3708.                             else
  3709.                                 backup_restore = 1;
  3710.                             break;
  3711.                 case 'L':    f_s_limit = atol(argv[i] + 2);
  3712.                             f_s_limit *= 1024;
  3713.                             if(f_s_limit < 0)
  3714.                                 f_s_limit = 0;
  3715.                             break;
  3716.                 case 'D':    backup_restore = 2;
  3717.                             break;
  3718.                 case 'P':    pro_flag = 3;
  3719.                             break;
  3720.                 case 'F':    full_dump = 1;
  3721.                             break;
  3722.                 case 'G':    big_buf = 1;
  3723.                             break;
  3724.                 case 'T':    backup_restore = 5;    /*  test_mode    */
  3725.                             if(argv[i][2] == '1')
  3726.                                 test_mode = 1;
  3727.                             else if(argv[i][2] == '2')
  3728.                                 test_mode = 2;
  3729.                             else if(argv[i][2] == '3')
  3730.                                 test_mode = 3;
  3731.                             break;
  3732.                 case 'V':    verify = 1;
  3733.                             break;
  3734.             }
  3735.         }else{
  3736.             switch(s_d_flag){
  3737.                 case 0: /* source drive set    */
  3738.                             strcpy(source, argv[i]);
  3739.                             s_d_flag = 1;
  3740.                             break;
  3741.                 case 1: /* destination drive set    */
  3742.                             strcpy(dest, argv[i]);
  3743.                             s_d_flag = 2;
  3744.                             break;
  3745.                 default:    help_flag = 1;
  3746.                             break;
  3747.             }
  3748.         }
  3749.     }
  3750.  
  3751.     if(big_buf)
  3752.         buf_size = BUF_UNIT*2;
  3753.     else
  3754.         buf_size = BUF_UNIT;
  3755.  
  3756.     if((pro_flag) && (backup_restore != 2) && (backup_restore != 5))
  3757.         backup_restore += pro_flag;
  3758.  
  3759.     if ((help_flag == 1) || (s_d_flag != 2))
  3760.         disp_msg(10, source, dest);
  3761.  
  3762.     source[0] = (char)toupper(source[0]);
  3763.     dest[0] = (char)toupper(dest[0]);
  3764.     disp_msg2(backup_restore, source, dest, start_sect);
  3765.  
  3766.     if(drive_ready(*source) != NO_ERROR)
  3767.         disp_msg(13, source, dest);
  3768.     if(drive_ready(*dest) != NO_ERROR)
  3769.         disp_msg(14, source, dest);
  3770.  
  3771.     add_drive(source);
  3772.     add_drive(dest);
  3773.     if(normalize(source) == ERR_RET)
  3774.         disp_msg(11, source, dest);
  3775.     if(normalize(dest) == ERR_RET)
  3776.         disp_msg(12, source, dest);
  3777.  
  3778.     if(get_version() >= 0x700){    /* DOS Ver 7.00 (Windows 95) ?    */
  3779.         win95 = 1;
  3780.     }
  3781.  
  3782.     if(backup_restore == 1){
  3783.          if(remote_connect(*dest)){
  3784.             if(change_dir(dest) == ERR_RET)
  3785.                 disp_msg(12, source, dest);
  3786.         }
  3787.     }
  3788.  
  3789.     switch(backup_restore){
  3790.         case 0:
  3791.             if(strlen(dest) != 3){
  3792.                 dest[3] = 0;
  3793.                 change_dir(dest);
  3794.             }
  3795.             break;
  3796.         case 1:
  3797.             if(strlen(source) != 3){
  3798.                 source[3] = 0;
  3799.                 change_dir(source);
  3800.             }
  3801.             break;
  3802.         case 2:
  3803.         case 3:
  3804.         case 4:
  3805.         case 5:
  3806.             if(strlen(dest) != 3){
  3807.                 dest[3] = 0;
  3808.                 change_dir(dest);
  3809.             }else if(strlen(source) != 3){
  3810.                 source[3] = 0;
  3811.                 change_dir(source);
  3812.             }
  3813.             break;
  3814.     }
  3815.     if(*source == *dest)
  3816.         disp_msg(15, source, dest);
  3817.     switch(backup_restore){
  3818.         case 0:
  3819.             des_32bit = check_osr2_32(*dest);
  3820.             so_32bit = 0;
  3821.             break;
  3822.         case 1:
  3823.             so_32bit= check_osr2_32(*source);
  3824.             des_32bit = 0;
  3825.             break;
  3826.         case 2:
  3827.         case 3:
  3828.         case 4:
  3829.         case 5:
  3830.             so_32bit= check_osr2_32(*source);
  3831.             des_32bit = check_osr2_32(*dest);
  3832.             break;
  3833.     }
  3834.  
  3835.     if((so_32bit == -1) || (des_32bit == -1))
  3836.         disp_msg(26, source, dest);
  3837.  
  3838.     switch(backup_restore){
  3839.         case 0:
  3840.             restore(source, dest, start_sect);
  3841.             break;
  3842.         case 1:
  3843.             backup(source, dest, start_sect);
  3844.             break;
  3845.         case 2:
  3846.             duplicate(source, dest, start_sect);
  3847.             break;
  3848.         case 3:
  3849.             p_restore(source, dest, start_sect);
  3850.             break;
  3851.         case 4:
  3852.             p_backup(source, dest, start_sect);
  3853.             break;
  3854.         case 5:
  3855.             test(source, dest, test_mode);
  3856.             break;
  3857.     }
  3858.     disp_msg(0, source, dest);
  3859. }
  3860.  
  3861.