Sunday, April 1st, 2012

Fun with Microsoft CAB files

I wrote a previous blog entry on working with binary files, and thought I would expand on this. This entry will focus on Microsoft's Cabinet format, specifically for Windows CE. I recently obtained a Windows CE 7-based ARM smartbook, and wanted to place Python on it. There is already a Python port for Windows CE devices on the ARM processor, however, it is unmaintained and the CAB file will only install on specific devices, namely nothing over CE 5.0, leaving CE 6.0 and 7.0 in the dark. I read on some forums that a piece of commercial software can edit the CAB files setup information to allow it to install. I thought, hmmm, well using commercial software is an end-users solution, not a programmers. So I went to work and learned as much as I can about the Cabinet format. Thankfully, Microsoft has opened the format to developers, making it really easy to understand how to work with it's format. First I constructed a reader to confirm that it was able to read the data correctly and provide me with the relevant information from the setup configuration for Windows CE. Here is the read script in Python for Cabinet files:

from struct import *
import sys

f = open('PythonCE-25-20061219.PPC2003_ARM.CAB','rb')
print "CAB Signature: %s\n" % f.read(4)
cabhdr = unpack('iiiiibbhhhhh',f.read(32))
print "Offset of CFFILE entry: %d\n" % cabhdr[3]
print "CAB Version: %d.%d\n" % (cabhdr[6],cabhdr[5])
print "Total folders: %d\n" % cabhdr[7]
print "Total files: %d\n" % cabhdr[8]
if cabhdr[9] > 3:
	print "CAB9 > 3"
	resv = unpack('hbb',f.read(4))

cabflr = unpack('ihh',f.read(8))
print "Offset of first file: %d\n" % cabflr[0]
print "Compression used: %d\n" % cabflr[2]
if cabflr[2] > 0:
	print "Unable to work with this type of compression, exiting.\n\n"
	sys.exit()

f.seek(cabflr[0])
cfdata = unpack('iHH',f.read(8))
print "Checksum: %d\n" % cfdata[0]
print "Size of compressed bytes: %d\n" % cfdata[1]
print "Size of uncompressed bytes: %d\n" % cfdata[2]
print "Exact position of first file: %d\n" % f.tell()

print "WinCE CAB Header: %s\n" % f.read(4)
cehdr = unpack('iiiiiiiiiii',f.read(44))
print "Target Arch: %d\n" % cehdr[4]
print "Minimum Windows CE Version: %d.%d\n" % (cehdr[5],cehdr[6])
print "Maximum Windows CE Version: %d.%d\n" % (cehdr[7],cehdr[8])
print "Minimum Buld number: %d.%d\n" % (cehdr[9],cehdr[10])
f.close()

After which I noticed, I didn't require the \n characters to make an end-of-line, so everything is a little spaced out. This is very basic and rough copy I made in about an hour of research and testing. But it works, and that's what matters. It tells me what's wrong with the CAB file and why it cannot install on my particular device. It confirms that it can read the file, for I can run this next script against it to change the required attributes to make it install on my device:

from struct import *
import sys

f = open('PythonCE-25-20061219.PPC2003_ARM.CAB','r+b')
print "CAB Signature: %s\n" % f.read(4)
cabhdr = unpack('iiiiibbhhhhh',f.read(32))
cabflr = unpack('ihh',f.read(8))
if cabflr[2] > 0:
	print "Unable to work with this type of compression, exiting.\n\n"
	sys.exit()
f.seek(cabflr[0])
cfdata = unpack('ihh',f.read(8))
print "Checksum: %d\n" % cfdata[0]
print "Writing new checksum..."
f.seek(cabflr[0])
f.write(pack('ihh',0,cfdata[1],cfdata[2]))
print "done.\n"
f.seek(cabflr[0])
cfdata = unpack('ihh',f.read(8))
print "New Checksum: %d\n" % cfdata[0]
offset = f.tell()
print "WinCE CAB Header: %s\n" % f.read(4)
cehdr = unpack('iiiiiiiiiii',f.read(44))
print "Writing new minimum/maximum versions requirements..."
f.seek(offset+20)
f.write(pack('iiiiiii',0,0,0,0,0,0,0))
print "Done! closing file..."
f.close()
print "All done.!\n\n"

There you have it! Why rely on some commercial software when you are in fact a programmer and can build it yourself within a matter of hours. Mind you, the commercial software does come with a lot of resources to build new CAB files for WinCE devices, but with a little research, a script that can build one can also be made in a matter of days to weeks.

About Me

My Photo
Names Kevin, hugely into UNIX technologies, not just Linux. I've dabbled with the demons, played with the Sun, and now with the Penguins.




Kevin Veroneau Consulting Services
Do you require the services of a Django contractor? Do you need both a website and hosting services? Perhaps I can help.

This Month

If you like what you read, please consider donating to help with hosting costs, and to fund future books to review.

Python Powered | © 2012-2013 Kevin Veroneau