Virgil Stokes schrieb:
I would appreciate python code for creating *.cab files.
--V. Stokes
Here is some code that I have still laying around. It has never been
used in production and I do not know what you can do with the cab files
it creates, but I have been able to create a cab and open it with winzip.
Thomas
<cab.py>
from ctypes import *
import sys, os, tempfile, glob
BOOL = c_int
ULONG = c_ulong
UINT = c_uint
USHORT = c_ushort
class ERF(Structure):
_fields_ = [("erfOper", c_int),
("erfType", c_int),
("fError", BOOL)]
CB_MAX_CHUNK = 32768
CB_MAX_DISK = 0x7ffffff
CB_MAX_FILENAME = 256
CB_MAX_CABINET_NAME = 256
CB_MAX_CAB_PATH = 256
CB_MAX_DISK_NAME = 256
class CCAB(Structure):
_fields_ = [
("cb", ULONG), # size available for cabinet on this media
("cbFolderThresh", ULONG), # Thresshold for forcing a new Folder
("cbReserveCFHeader", UINT), # Space to reserve in CFHEADER
("cbReserveCFFolder", UINT), # Space to reserve in CFFOLDER
("cbReserveCFData", UINT), # Space to reserve in CFDATA
("iCab", c_int), # sequential numbers for cabinets
("iDisk", c_int), # Disk number
("fFailOnIncompressible", c_int), # TRUE =Fail if a block is incompressible
("setID", USHORT), # Cabinet set ID
("szDisk", c_char * CB_MAX_DISK_NAME), # current disk name
("szCab", c_char * CB_MAX_CABINET_NAME), # current cabinet name
("szCabPath", c_char * CB_MAX_CAB_PATH), # path for creating cabinet
]
cab = cdll.cabinet
class HFCI(object):
_handle = 0
_as_parameter_ = property(lambda self: self._handle)
def __init__(self, fnm, verbose=1):
self.verbose = verbose
self.erf = ERF()
ccab = self.ccab = CCAB()
ccab.cb = 100000000
ccab.cbFolderThresh = 100000
ccab.szCab = os.path.basename(fnm)
dirname = os.path.dirname(fnm)
if not dirname:
dirname = "."
ccab.szCabPath = dirname + "\\"
self._init_callbacks()
self._handle = cab.FCICreate(byref(self.erf),
self.pfn_filedest,
cdll.msvcrt.malloc,
cdll.msvcrt.free,
cdll.msvcrt._open,
cdll.msvcrt._read,
cdll.msvcrt._write,
cdll.msvcrt._close,
cdll.msvcrt._lseek,
cdll.msvcrt._unlink,
self.pfn_gettempfnm,
byref(ccab),
None)
def _init_callbacks(self):
self.pfn_gettempfnm = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p)(self._gettempfnm)
self.pfn_filedest = CFUNCTYPE(c_int)(self._filedest)
self.pfn_status = CFUNCTYPE(c_int, c_int, c_uint, c_uint, c_void_p)(self._status)
self.pfn_getnextcab = CFUNCTYPE(c_int)(self._getnextcab)
self.pfn_getopeninfo = CFUNCTYPE(c_int, c_char_p)(self._getopeninfo)
def _getopeninfo(self, fnm):
if self.verbose:
print "File", fnm
return cdll.msvcrt._open(fnm, os.O_BINARY | os.O_RDONLY)
def _status(self, typeStatus, cb1, cb2, pv):
return 0
def _filedest(self):
return 0
def _getnextcab(self):
return 0
def _gettempfnm(self, pszTempName, cbTempName, pv):
# same as tempfile.mktemp(), but this is deprecated
fh, fnm = tempfile.mkstemp()
os.close(fh)
os.remove(fnm)
cdll.msvcrt.strcpy(pszTempName, fnm)
return 1
def AddFile(self, src, dst=None, compressed=0):
if dst is None:
dst = os.path.basename(src)
cab.FCIAddFile(self,
src,
dst,
0, # fExecute
self.pfn_getnextcab,
self.pfn_status,
self.pfn_getopeninfo,
compressed)
def Close(self):
if self._handle != 0:
cab.FCIFlushCabinet(self,
0, # fGetNextCab
self.pfn_getnextcab,
self.pfn_status)
cab.FCIDestroy(self)
self._handle = 0
if __name__ == "__main__":
import os, glob
hfci = HFCI("my-first.cab", verbose=1)
files = glob.glob(r".\cab\*.*")
for fnm in files:
hfci.AddFile(fnm)
hfci.Close()
<eof>