This is a program to extract/compile car NAV .KWI extensions. Unfortunately, I do not know anything about Python though I will love to learn some time very soon. Could you help me compile this into an executable file for windows 7?
Will be reatly appreciated.
#!/usr/bin/env python
#
# kiwi
#
# Copyright 2009 Bert Vermeulen <bert@biot.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import os
import sys
from getopt import getopt
import string
from datetime import datetime
import struct
EXTRACT_BUFSIZE = 1024 * 1024
def usage():
print """usage: kiwi [-v|-x] [-o outputdir] -d <dvd directory>
-v list modules contained in the LOADING.KWI FILE
-x extract modules from the LOADING.KWI file
-d directory where the DVD is mounted
-o target dir to extract modules into"""
sys.exit(1)
def is_printable(text):
for i in text:
if i not in string.printable + '\x00':
return False
return True
def show_date(stamp):
date = datetime.fromtimestamp(stamp)
datestr = "%d-%.2d-%.2d" % (date.year, date.month, date.day)
return datestr
def maybe_dump(text):
if is_printable(text):
return text
else:
hex = ''
for i in text:
hex += "%.2x " % int(ord(i))
return hex
def show_kwi_info(lo):
print "number of systems found:", lo['num_systems']
syscnt = 1
for s in lo['systems']:
print "System %s\n Manufacturer ID: %s" % (syscnt, maybe_dump(s['mid']))
print " Number of modules in this system:", len(s['modules'])
modcnt = 1
for modname, modversion, category, startdate, enddate, title, info, address, size in s['modules']:
print " Module %d:" % modcnt
print "\tName:", modname
print "\tVersion:", modversion
print "\tCategory:", category
if startdate:
print "\tValid from:", show_date(startdate)
if enddate:
print "\tValid until:", show_date(enddate)
print "\tAddress: 0x%X" % address
size += 0.0
if size > 1024 * 1024:
size /= 1024 * 1024
unit = "MB"
elif size > 1024:
size /= 1024
unit = "KB"
else:
unit = "bytes"
print "\tSize: %.1f %s" % (size, unit)
print
modcnt += 1
syscnt += 1
def extract_modules(path, targetdir, system=1):
try:
lo = kiwi.parse_loading(path)
if lo['num_systems'] < system:
raise Exception, "only %s systems found" % lo['num_systems']
if not os.path.exists(targetdir):
os.mkdir(targetdir)
s = lo['systems'][system-1]
print "extracting modules into %s..." % targetdir
fp = open(path)
for modname, modversion, category, startdate, enddate, title, info, address, size in s['modules']:
print " ", modname
fp.seek(address)
cnt = 0
outfile = open(targetdir + '/' + modname, 'w')
while True:
if cnt + EXTRACT_BUFSIZE > size:
chunksize = size - cnt
else:
chunksize = EXTRACT_BUFSIZE
buf = fp.read(chunksize)
outfile.write(buf)
cnt += chunksize
if len(buf) < EXTRACT_BUFSIZE:
break
outfile.close()
fp.close()
except Exception, msg:
print "Error:", str(msg)
module_categories = [
'Initial program',
'Program',
'Library',
'Data'
]
def parse_loading(path):
lostruct = {}
fp = open(path)
data = fp.read(4)
num_systems, dummy = struct.unpack_from(">HH", data)
lostruct['num_systems'] = num_systems
offset = 4
lostruct['systems'] = []
for s in range(num_systems):
system = {}
fp.seek(offset)
data = fp.read(16)
mid, num_modules, dummy = struct.unpack_from(">12sHH", data)
offset += 16
system['mid'] = mid
system['modules'] = []
# get Module Identification Information blocks
for m in range(num_modules):
fp.seek(offset)
data = fp.read(64)
cat, modname, modversion = struct.unpack_from(">cxxx52s4s", data)
offset += 64
cat = ord(cat)
category = module_categories[cat & 3]
if cat & 64:
category += " (Test module)"
if cat & 128:
category += " (Diagnostic service module)"
modname = modname.rstrip('\x00')
system['modules'].append([modname, modversion, category])
# get Module Management Information blocks
address_multiplier = 0
for m in range(num_modules):
fp.seek(offset)
data = fp.read(256)
startdate, enddate, title, info, address, size = struct.unpack_from(">HH64s182sIH", data)
offset += 256
# dates are in number of days since 1997-01-01 00:00:00. that's
# 852073200 seconds since the unix epoch, convert to that
# if it's 0 no date is set, so preserve that
if startdate:
startdate += 852073200 + (startdate * 86400)
if enddate:
enddate += 852073200 + (enddate * 86400)
# address is either in 2048-byte sized blocks, or some odd 3-byte
# block size. try to grok this by the first one we
# see, which will be right past this this Loading Module Management
# block we're parsing now
if m == 0:
if address < 0x100:
# too small to be an absolute address
address_multiplier = 2048
elif (address >> 8) < 0x100:
address_multiplier = 8
else:
address_multiplier = 1
address *= address_multiplier
# size is in 2048-byte sized blocks
size *= 2048
system['modules'][m] += [startdate, enddate, title, info, address, size]
lostruct['systems'].append(system)
return lostruct
#
# main
#
opts, args = getopt(sys.argv[1:], "vxd:o:")
mode = dvddir = targetdir = None
for opt, arg in opts:
if opt == '-v':
if mode:
usage()
else:
mode = 'view'
elif opt == '-x':
if mode:
usage()
else:
mode = 'extract'
elif opt == '-d':
dvddir = arg
elif opt == '-o':
targetdir = arg
if not mode or not dvddir:
usage()
try:
path = dvddir + '/LOADING.KWI'
if not os.path.exists(path):
print "no LOADING.KWI found in %s" % dvddir
sys.exit(1)
except Exception, msg:
print "failed to open %s: %s" % (path, str(msg))
sys.exit(1)
else:
if mode == 'view':
kwi_info = parse_loading(path)
show_kwi_info(kwi_info)
elif mode == 'extract':
if not targetdir:
print "please set a target directory to extract into."
usage()
else:
extract_modules(path, targetdir)