chrome/tools/build/win/makecab.py
def WriteCab(output_file, input_file, cab_stored_filename, input_size,
             input_mtimestamp):
  """Reads data from input_file and stores its MSZIP-compressed data
  in output_file.  cab_stored_filename is the filename stored in the
  cab file, input_size is the size of the input file, and input_mtimestamp
  the mtime timestamp of the input file (must be at least midnight 1980-1-1)."""
  # Need to write (all in little-endian)::
  # 36 bytes CFHEADER cab header
  # 8 bytes CFFOLDER (a set of files compressed with the same parameters)
  # 16 bytes + filename (+ 1 byte trailing \0 for filename) CFFFILE
  # Many 8 bytes CFDATA blocks, representing 32kB chunks of uncompressed data,
  # each followed by the compressed data.
  cffile_offset = 36 + 8
  cfdata_offset = cffile_offset + 16 + len(cab_stored_filename) + 1

  chunk_size = 1 << 15
  num_chunks = int((input_size + chunk_size - 1) / chunk_size)

  # https://msdn.microsoft.com/en-us/library/bb417343.aspx#cabinet_format
  # Write CFHEADER.
  CFHEADER = ('<'
    '4s' # signature, 'MSCF'
    'I'  # reserved1, set to 0
    'I'  # cbCabinet, size of file in bytes. Not yet known, filled in later.
    'I'  # reserved2, set to 0

    'I'  # coffFiles, offset of first (and here, only) CFFILE.
    'I'  # reserved3, set to 0
    'B'  # versionMinor, currently 3. Yes, minor version is first.
    'B'  # versionMajor, currently 1.
    'H'  # cFolders, number of CFFOLDER entries.
    'H'  # cFiles, number of CFFILE entries.
    'H'  # flags, for multi-file cabinets. 0 here.

    'H'  # setID, for multi-file cabinets. 0 here.
    'H'  # iCabinet, index in multi-file cabinets. 0 here.
  )
  output_file.write(struct.pack(CFHEADER,
      b'MSCF', 0, 0, 0,
      cffile_offset, 0, 3, 1, 1, 1, 0,
      0, 0))

  # Write single CFFOLDER.
  CFFOLDER = ('<'
    'I'  # coffCabStart, offset of first CFDATA block in this folder.
    'H'  # cCFData, number of CFDATA blocks in this folder.
    'H'  # typeCompress, compression type. 1 means MS-ZIP.
  )
  output_file.write(struct.pack(CFFOLDER, cfdata_offset, num_chunks, 1))

  # Write single CFFILE.
  CFFILE = ('<'
    'I'  # cbFile, uncompressed size of this file in bytes.
    'I'  # uoffFolderStart, uncompressed offset of this file in folder.
    'H'  # iFolder, index into CFFOLDER area.
    'H'  # date, in the format ((year-1980) << 9) + (month << 5) + (day),
         # where month={1..12} and day={1..31}.
    'H'  # time, in the format (hour << 11)+(minute << 5)+(seconds/2),
         # where hour={0..23}.
    'H'  # attribs, 1: read-only
                  # 2: hidden
                  # 4: system file
                  # 0x20: file modified since last backup
                  # 0x40: run after extraction
                  # 0x80: name contains UTF
  )  # Followed by szFile, the file's name.
  assert output_file.tell() == cffile_offset
  mtime = datetime.datetime.fromtimestamp(input_mtimestamp)
  date = (mtime.year - 1980) << 9 | mtime.month << 5 | mtime.day
  # TODO(thakis): hour seems to be off by 1 from makecab.exe (DST?)
  time = mtime.hour << 11 | mtime.minute << 5 | int(mtime.second / 2)
  output_file.write(struct.pack(CFFILE, input_size, 0, 0, date, time, 0))
  output_file.write(cab_stored_filename.encode() + b'\0')

  # Write num_chunks many CFDATA headers, followed by the compressed data.
  assert output_file.tell() == cfdata_offset
  CFDATA = ('<'
    'I'  # checksum. Optional and expensive to compute in Python, so write 0.
    'H'  # cbData, number of compressed bytes in this block.
    'H'  # cbUncomp, size after decompressing. 1 << 15 for all but the last.
  )
  # Read input data in chunks of 32kB, compress and write out compressed data.
  for _ in range(num_chunks):
    chunk = input_file.read(chunk_size)
    # Have to use compressobj instead of compress() so we can pass a negative
    # window size to remove header and trailing checksum.
    # Compression level 6 runs about 8x as fast as makecab.exe's LZX compression
    # while producing a 45% larger file.  (Interestingly, it also runs
    # about 5x as fast as makecab.exe's MSZIP compression while being about
    # 4.8% larger -- so it might be possible to write an LZX compressor that's
    # much faster without being so much larger.)  Compression level 9 isn't
    # very different.  Level 1 is another ~30% faster and 10% larger.
    # Since 6 is ok and the default, let's go with that.
    # Remember: User-shipped bits get recompressed on the signing server.
    zlib_obj = zlib.compressobj(
        zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -zlib.MAX_WBITS)
    compressed = zlib_obj.compress(chunk) + zlib_obj.flush()
    compressed_size = 2 + len(compressed)  # Also count 0x43 0x4b magic header.
    # cab spec: "Each data block represents 32k uncompressed, except that the
    # last block in a folder may be smaller. A two-byte MSZIP signature precedes
    # the compressed encoding in each block, consisting of the bytes 0x43, 0x4B.
    # The maximum compressed size of each MSZIP block is 32k + 12 bytes."
    assert compressed_size <= chunk_size + 12
    output_file.write(struct.pack(CFDATA, 0, compressed_size, len(chunk)))
    output_file.write(b'\x43\x4b')  # MSZIP magic block header.
    output_file.write(compressed)
  outfile_size = output_file.tell()

  # Now go back and fill in missing size in CFHEADER.
  output_file.seek(8)  # cbCabinet, size of file in bytes.
  output_file.write(struct.pack('<I', outfile_size))
Reads data from input_file and stores its MSZIP-compressed data
  in output_file.  cab_stored_filename is the filename stored in the
  cab file, input_size is the size of the input file, and input_mtimestamp
  the mtime timestamp of the input file (must be at least midnight 1980-1-1).
Reads data from input_file and stores its MSZIP-compressed data
in output_file.  cab_stored_filename is the filename stored in the
cab file, input_size is the size of the input file, and input_mtimestamp
the mtime timestamp of the input file (must be at least midnight 1980-1-1).
Reads data from input_file and stores its MSZIP - compressed data in output_file . cab_stored_filename is the filename stored in the cab file input_size is the size of the input file and input_mtimestamp the mtime timestamp of the input file ( must be at least midnight 1980 - 1 - 1 ) .
def WriteCab(output_file, input_file, cab_stored_filename, input_size,
             input_mtimestamp):
  cffile_offset = 36 + 8
  cfdata_offset = cffile_offset + 16 + len(cab_stored_filename) + 1
  chunk_size = 1 << 15
  num_chunks = int((input_size + chunk_size - 1) / chunk_size)
  CFHEADER = ('<'
    '4s' 
    'I'  
    'I'  
    'I'  
    'I'  
    'I'  
    'B'  
    'B'  
    'H'  
    'H'  
    'H'  
    'H'  
    'H'  
  )
  output_file.write(struct.pack(CFHEADER,
      b'MSCF', 0, 0, 0,
      cffile_offset, 0, 3, 1, 1, 1, 0,
      0, 0))
  CFFOLDER = ('<'
    'I'  
    'H'  
    'H'  
  )
  output_file.write(struct.pack(CFFOLDER, cfdata_offset, num_chunks, 1))
  CFFILE = ('<'
    'I'  
    'I'  
    'H'  
    'H'  
    'H'  
    'H'  
  )  
  assert output_file.tell() == cffile_offset
  mtime = datetime.datetime.fromtimestamp(input_mtimestamp)
  date = (mtime.year - 1980) << 9 | mtime.month << 5 | mtime.day
  time = mtime.hour << 11 | mtime.minute << 5 | int(mtime.second / 2)
  output_file.write(struct.pack(CFFILE, input_size, 0, 0, date, time, 0))
  output_file.write(cab_stored_filename.encode() + b'\0')
  assert output_file.tell() == cfdata_offset
  CFDATA = ('<'
    'I'  
    'H'  
    'H'  
  )
  for _ in range(num_chunks):
    chunk = input_file.read(chunk_size)
    zlib_obj = zlib.compressobj(
        zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -zlib.MAX_WBITS)
    compressed = zlib_obj.compress(chunk) + zlib_obj.flush()
    compressed_size = 2 + len(compressed)  
    assert compressed_size <= chunk_size + 12
    output_file.write(struct.pack(CFDATA, 0, compressed_size, len(chunk)))
    output_file.write(b'\x43\x4b')  
    output_file.write(compressed)
  outfile_size = output_file.tell()
  output_file.seek(8)  
  output_file.write(struct.pack('<I', outfile_size))
def WriteCab ( output_file , input_file , cab_stored_filename , input_size , input_mtimestamp ) : cffile_offset = 36 + 8 cfdata_offset = cffile_offset + 16 + len ( cab_stored_filename ) + 1 chunk_size = 1 << 15 num_chunks = int ( ( input_size + chunk_size - 1 ) / chunk_size ) CFHEADER = ( '<' '4s' 'I' 'I' 'I' 'I' 'I' 'B' 'B' 'H' 'H' 'H' 'H' 'H' ) output_file . write ( struct . pack ( CFHEADER , b'MSCF' , 0 , 0 , 0 , cffile_offset , 0 , 3 , 1 , 1 , 1 , 0 , 0 , 0 ) ) CFFOLDER = ( '<' 'I' 'H' 'H' ) output_file . write ( struct . pack ( CFFOLDER , cfdata_offset , num_chunks , 1 ) ) CFFILE = ( '<' 'I' 'I' 'H' 'H' 'H' 'H' ) assert output_file . tell ( ) == cffile_offset mtime = datetime . datetime . fromtimestamp ( input_mtimestamp ) date = ( mtime . year - 1980 ) << 9 | mtime . month << 5 | mtime . day time = mtime . hour << 11 | mtime . minute << 5 | int ( mtime . second / 2 ) output_file . write ( struct . pack ( CFFILE , input_size , 0 , 0 , date , time , 0 ) ) output_file . write ( cab_stored_filename . encode ( ) + b'\0' ) assert output_file . tell ( ) == cfdata_offset CFDATA = ( '<' 'I' 'H' 'H' ) for _ in range ( num_chunks ) : chunk = input_file . read ( chunk_size ) zlib_obj = zlib . compressobj ( zlib . Z_DEFAULT_COMPRESSION , zlib . DEFLATED , - zlib . MAX_WBITS ) compressed = zlib_obj . compress ( chunk ) + zlib_obj . flush ( ) compressed_size = 2 + len ( compressed ) assert compressed_size <= chunk_size + 12 output_file . write ( struct . pack ( CFDATA , 0 , compressed_size , len ( chunk ) ) ) output_file . write ( b'\x43\x4b' ) output_file . write ( compressed ) outfile_size = output_file . tell ( ) output_file . seek ( 8 ) output_file . write ( struct . pack ( '<I' , outfile_size ) )
Reads data from input_file and stores its MSZIP-compressed data
in output_file.
Reads data from input_file and stores its MSZIP - compressed data in output_file .
"""Reads data from input_file and stores its MSZIP-compressed data
  in output_file.  cab_stored_filename is the filename stored in the
  cab file, input_size is the size of the input file, and input_mtimestamp
  the mtime timestamp of the input file (must be at least midnight 1980-1-1).""" # Need to write (all in little-endian):: # 36 bytes CFHEADER cab header # 8 bytes CFFOLDER (a set of files compressed with the same parameters) # 16 bytes + filename (+ 1 byte trailing \0 for filename) CFFFILE # Many 8 bytes CFDATA blocks, representing 32kB chunks of uncompressed data, # each followed by the compressed data. # https://msdn.microsoft.com/en-us/library/bb417343.aspx#cabinet_format # Write CFHEADER. # signature, 'MSCF' # reserved1, set to 0 # cbCabinet, size of file in bytes. Not yet known, filled in later. # reserved2, set to 0 # coffFiles, offset of first (and here, only) CFFILE. # reserved3, set to 0 # versionMinor, currently 3. Yes, minor version is first. # versionMajor, currently 1. # cFolders, number of CFFOLDER entries. # cFiles, number of CFFILE entries. # flags, for multi-file cabinets. 0 here. # setID, for multi-file cabinets. 0 here. # iCabinet, index in multi-file cabinets. 0 here. # Write single CFFOLDER. # coffCabStart, offset of first CFDATA block in this folder. # cCFData, number of CFDATA blocks in this folder. # typeCompress, compression type. 1 means MS-ZIP. # Write single CFFILE. # cbFile, uncompressed size of this file in bytes. # uoffFolderStart, uncompressed offset of this file in folder. # iFolder, index into CFFOLDER area. # date, in the format ((year-1980) << 9) + (month << 5) + (day), # where month={1..12} and day={1..31}. # time, in the format (hour << 11)+(minute << 5)+(seconds/2), # where hour={0..23}. # attribs, 1: read-only # 2: hidden # 4: system file # 0x20: file modified since last backup # 0x40: run after extraction # 0x80: name contains UTF # Followed by szFile, the file's name. # TODO(thakis): hour seems to be off by 1 from makecab.exe (DST?) # Write num_chunks many CFDATA headers, followed by the compressed data. # checksum. Optional and expensive to compute in Python, so write 0. # cbData, number of compressed bytes in this block. # cbUncomp, size after decompressing. 1 << 15 for all but the last. # Read input data in chunks of 32kB, compress and write out compressed data. # Have to use compressobj instead of compress() so we can pass a negative # window size to remove header and trailing checksum. # Compression level 6 runs about 8x as fast as makecab.exe's LZX compression # while producing a 45% larger file.  (Interestingly, it also runs # about 5x as fast as makecab.exe's MSZIP compression while being about # 4.8% larger -- so it might be possible to write an LZX compressor that's # much faster without being so much larger.)  Compression level 9 isn't # very different.  Level 1 is another ~30% faster and 10% larger. # Since 6 is ok and the default, let's go with that. # Remember: User-shipped bits get recompressed on the signing server. # Also count 0x43 0x4b magic header. # cab spec: "Each data block represents 32k uncompressed, except that the # last block in a folder may be smaller. A two-byte MSZIP signature precedes # the compressed encoding in each block, consisting of the bytes 0x43, 0x4B. # The maximum compressed size of each MSZIP block is 32k + 12 bytes." # MSZIP magic block header. # Now go back and fill in missing size in CFHEADER. # cbCabinet, size of file in bytes.
output_file
input_file
cab_stored_filename
input_size
input_mtimestamp