home *** CD-ROM | disk | FTP | other *** search
/ Popular Software (Premium Edition) / mycd.iso / TOOLS / ACE11B / TECHNOTE.DOC < prev    next >
Encoding:
Text File  |  1997-12-19  |  11.5 KB  |  316 lines

  1.                                       Copyright by Marcel Lemke, December 1997
  2.  
  3.  
  4.     Technical information of the archiver ACE v1.1
  5.    ────────────────────────────────────────────────
  6.  
  7.  
  8.      1. Block format
  9.      2. Block types
  10.        2.1. Archive header
  11.        2.2. File block
  12.        2.3. Recovery record
  13.  
  14.      3. Archive processing
  15.      4. Building CRCs
  16.        4.1. C source
  17.        4.2. Pascal source
  18.  
  19.  
  20. ──────────────────────────────────────────────────────────────────────────────
  21.  
  22.  
  23.   1. Block format
  24.  ─────────────────
  25.  
  26.     The whole archive consists of blocks which vary in size.
  27.  
  28.     Structure:
  29.  
  30.     bytes   meaning       discription
  31.  
  32.      2      HEAD_CRC      CRC16 over block up from HEAD_TYPE
  33.      2      HEAD_SIZE     size of the block up from HEAD_TYPE
  34.  
  35.      1      HEAD_TYPE     indicates type of block (see chapter 2.)
  36.      2      HEAD_FLAGS    flags related to the block and its content
  37.                             for all blocks these flags are valid:
  38.  
  39.                              bit  discription
  40.  
  41.                               0   ADDSIZE field present
  42.                               1   Block includes a comment
  43.  
  44.     [4]     ADDSIZE       an optional field which represents the size of
  45.                           an additional block without specified structure
  46.                            (no HEAD_CRC, HEAD_SIZE etc.)
  47.      ?      OTHER FIELDS
  48.  
  49.  
  50.   2. Block types
  51.  ────────────────
  52.  
  53.    2.1. Archive header
  54.   ─────────────────────
  55.       The archive header is the first block of each archive or volume.
  56.  
  57.       Structure:
  58.  
  59.       bytes   meaning       discription
  60.  
  61.        2      HEAD_CRC      CRC16 over block up from HEAD_TYPE
  62.        2      HEAD_SIZE     size of the block up from HEAD_TYPE
  63.  
  64.        1      HEAD_TYPE     archive header type is 0
  65.        2      HEAD_FLAGS    contains most important information about the
  66.                             archive
  67.  
  68.                                bit  discription
  69.  
  70.                                 0   0  (no ADDSIZE field)
  71.                                 1   presence of a main comment
  72.  
  73.                                 9   SFX-archive
  74.                                 10  dictionary size limited to 256K
  75.                                     (because of a junior SFX)
  76.                                 11  archive consists of multiple volumes
  77.                                 12  main header contains AV-string
  78.                                 13  recovery record present
  79.                                 14  archive is locked
  80.                                 15  archive is solid
  81.  
  82.        7      ACESIGN       fixed string: '**ACE**' serves to find the
  83.                               archive header
  84.  
  85.        1      VER_MODIFIED  last version of ACE used to modify the archive
  86.        1      VER_CREATED   version used to create the archive
  87.        1      HOST_CREATED  HOST-OS for ACE used to create the archive
  88.  
  89.                                value   host
  90.  
  91.                                 0      MS-DOS
  92.                                 1      OS/2
  93.                                 2      Win32
  94.                                 3      Unix
  95.                                 4      MAC-OS
  96.                                 5      Win NT
  97.                                 6      Primos
  98.                                 7      APPLE GS
  99.                                 8      ATARI
  100.                                 9      VAX VMS
  101.                                 10     AMIGA
  102.                                 11     NEXT
  103.  
  104.        1      VOLUME_NUM        which volume of a multi-volume-archive is it?
  105.        4      TIME_CREATED      date and time in MS-DOS format
  106.        8      RESERVED          8 bytes reserved for the future
  107.       [1]     AV_SIZE           size of the following AV string
  108.       [?]     AV                the AV string itself
  109.       [2]     COMMENT_SIZE      compressed size of the following comment
  110.       [?]     COMMENT           compressed data of comment
  111.        ?      RESERVED
  112.  
  113.       Comments are compressed using simple LZP+huffman. Sources how to create
  114.       those compressed comments might be published sometime.
  115.  
  116.    2.2. File block
  117.   ─────────────────
  118.       Directories are stored in this type of block, too. There is no extra
  119.       block structure.
  120.  
  121.       Structure:
  122.  
  123.       bytes   meaning       discription
  124.  
  125.        2      HEAD_CRC      CRC16 over block up from HEAD_TYPE
  126.        2      HEAD_SIZE     size of the block up from HEAD_TYPE
  127.  
  128.        1      HEAD_TYPE     file header type is 1
  129.        2      HEAD_FLAGS
  130.                                bit  discription
  131.  
  132.                                 0   1 (ADDSIZE field present)
  133.                                 1   presence of file comment
  134.  
  135.                                 12  file continued from previous volume
  136.                                 13  file continues on the next volume
  137.                                 14  file encrypted with password
  138.                                 15  solid-flag: file compressed using data
  139.                                       of previous files of the archive
  140.  
  141.        4      PACK_SIZE     this is the ADDSIZE field;
  142.                             the additional block contains compressed file data
  143.                               without exception
  144.        4      ORIG_SIZE     the original size of the file
  145.        4      FTIME         file date and file time in MS-DOS format
  146.        4      ATTR          attributes of the file
  147.        4      CRC32         checksum over the compressed file
  148.        4      TECH_INFO
  149.  
  150.                bytes
  151.                 1           type of compression
  152.                               0  store
  153.                               1  ACE_LZ77_1
  154.  
  155.                 1           quality of compression
  156.                               0  fastest
  157.                               1  fast
  158.                               2  normal
  159.                               3  good
  160.                               4  best
  161.  
  162.                 2           parameter for decompression
  163.  
  164.        2      RESERVED
  165.        2      FNAME_SIZE    size of filename string in bytes
  166.        1      FNAME         filename string (OEM)
  167.       [2]     COMM_SIZE     compressed size of file comment
  168.       [?]     COMMENT       file comment
  169.        ?      RESERVED
  170.     -------------------------------------------
  171.       compressed file data (size is PACK_SIZE)
  172.  
  173.  
  174.    2.3. Recovery record
  175.   ──────────────────────
  176.       The protection by recovery records works this way:
  177.       See the whole archive as a sequence of blocks with a defined length.
  178.       Build checksums over these blocks to determine (later) whether a block
  179.       has been damaged or not. Xor all blocks to one.
  180.       Save this xor-block and the checksums. To restore a damaged block
  181.       all undamaged blocks have to be xor'd with the xor-block.
  182.  
  183.  
  184.       Structure:
  185.  
  186.        2      HEAD_CRC      CRC16 over block up from HEAD_TYPE
  187.        2      HEAD_SIZE     size of the block up from HEAD_TYPE
  188.  
  189.        1      HEAD_TYPE     header type of recovery records is 2
  190.        2      HEAD_FLAGS
  191.                                bit  discription
  192.  
  193.                                 0   1 (ADDSIZE field present)
  194.        4      REC_BLK_SIZE  ADDSIZE field; size of recovery data
  195.        7      ACESIGN       string: '**ACE**';
  196.                               allows search for this block with destroyed
  197.                               archive structure
  198.        4      REL_STRT      relative start (to this block) of the data this
  199.                               block is mode of
  200.        4      NUM_BLKS      number of blocks the data is splitten in
  201.        4      CL_SIZE       size of these blocks
  202.        2      REC_CRC       CRC16 over recovery data
  203.     ------------------------
  204.       recovery data:
  205.  
  206.        2      1st CRC16     CRC over the first block of the archive
  207.        2      2nd CRC16     CRC over the second block of the archive
  208.        .      .
  209.        .      .
  210.        2  NUM_BLKSth CRC16  CRC over the last block (up to the recovery
  211.                               record) of the archive
  212.       CL_SIZE XOR-DATA      contains the xor'd data of all the blocks
  213.                               the archive has been splitten in for this
  214.                               process
  215.  
  216.   3. Archive processing
  217.  ───────────────────────
  218.  
  219.     For processing an archive you first need to get the start offset of it
  220.     in a certain file. The way to do so is:
  221.  
  222.       1.) search for the acesign ('**ACE**')
  223.       2.) read a block from (acesign_position-7)
  224.             (because the acesign is at offset 7 in the archive header)
  225.       3.) build the checksum of this block and check it against HEAD_CRC;
  226.             if they do not match go to step 1.)
  227.  
  228.     After you got the start you can read one block after another like this:
  229.       1.) read HEAD_CRC and HEAD_SIZE
  230.       2.) read HEAD_SIZE bytes;
  231.            build the CRC of them and check it against HEAD_CRC;
  232.            the archive is broken if the CRCs do not match
  233.       3.) interpret the contents of the block
  234.       4.) skip ADDSIZE bytes if ADDSIZE is present
  235.     Do so until the EOF of the archive.
  236.  
  237.     See next chapter how to build CRCs.
  238.  
  239.  
  240.   4. Building CRCs
  241.  ──────────────────
  242.  
  243.     This chapter contains sources how to build a "CRC32". The full 32 bits
  244.     are needed at the file checksums only. In the headers there are only
  245.     the lower 16 bits of a CRC32 value saved.
  246.  
  247.     To initialize "getcrc" just call "make_crc_table". To get a CRC of a
  248.     block inititalize your CRC variable with CRC_MASK. Then use getcrc to
  249.     update this variable.
  250.  
  251.     example how to check the CRC of an header:
  252.       make_crctable();                                // only once
  253.       ...
  254.       crc=CRC_MASK;                                   // initialize CRC
  255.       crc=getcrc(crc,&head.HEAD_TYPE,head.HEAD_SIZE); // update CRC
  256.  
  257.                                                       // check lower 16 bits
  258.       if (UWORD(crc)!=UWORD(head.HEAD_CRC)) error_archive_broken();
  259.  
  260.    4.1. C source
  261.   ───────────────
  262.  
  263. ──────cut────────────   ────────────   ────────────   ────────────
  264.         #define CRCPOLY 0xEDB88320
  265.         #define CRC_MASK 0xFFFFFFFF
  266.  
  267.         make_crctable()
  268.         {
  269.         unsigned r,i,j;
  270.           for (i=0;i<=255;i++) {
  271.             for (r=i,j=8;j;j--)
  272.               r=(r&1)?(r>>1)^CRCPOLY:(r>>1);
  273.             crctable[i] = r;
  274.           }
  275.         }
  276.  
  277.         unsigned long getcrc(unsigned long crc,unsigned char *addr,int len)
  278.         {
  279.           while (len--)
  280.             crc=crctable[(unsigned char)crc^(*addr++)]^(crc>>8);
  281.           return(crc);
  282.         }
  283. ──────cut────────────   ────────────   ────────────   ────────────
  284.  
  285.    4.2. Pascal source
  286.   ────────────────────
  287.  
  288. ──────cut────────────   ────────────   ────────────   ────────────
  289.         const CRCPOLY=$EDB88320;CRC_MASK=$FFFFFFFF;
  290.         type tbytear=array[0..60000] of byte;
  291.              tbptr=^tbytear;
  292.  
  293.         procedure make_crctable;
  294.         var i,j:integer;
  295.             r:longint;
  296.         begin
  297.           for i:=0 to 255 do begin
  298.             r:=i;
  299.             for j:=8 downto 1 do
  300.               if (r and 1)>0 then r:=(r shr 1) xor CRCPOLY else r:=r shr 1;
  301.             crctable[i]:=r;
  302.           end;
  303.         end;
  304.  
  305.         function getcrc(crc:longint;addr:tbptr;len:integer):longint;
  306.         var i:word;
  307.         begin
  308.           i:=0;
  309.           while (len>0) do begin
  310.             crc:=crctable[(byte(crc)) xor (addr^[i])] xor (longint(crc) shr 8);
  311.             dec(len);inc(i);
  312.           end;
  313.           getcrc:=crc;
  314.         end;
  315. ──────cut────────────   ────────────   ────────────   ────────────
  316.