# Microsoft Installer Library
# (C) 2003 Martin v. Loewis

import win32com.client.gencache
import win32com.client
import pythoncom, pywintypes
from win32com.client import constants
import re, string, os, sets, glob, subprocess, sys, _winreg, struct

try:
    basestring
except NameError:
    basestring = (str, unicode)

# Partially taken from Wine
datasizemask=      0x00ff
type_valid=        0x0100
type_localizable=  0x0200

typemask=          0x0c00
type_long=         0x0000
type_short=        0x0400
type_string=       0x0c00
type_binary=       0x0800

type_nullable=     0x1000
type_key=          0x2000
# XXX temporary, localizable?
knownbits = datasizemask | type_valid | type_localizable | \
            typemask | type_nullable | type_key

# Summary Info Property IDs
PID_CODEPAGE=1
PID_TITLE=2
PID_SUBJECT=3
PID_AUTHOR=4
PID_KEYWORDS=5
PID_COMMENTS=6
PID_TEMPLATE=7
PID_LASTAUTHOR=8
PID_REVNUMBER=9
PID_LASTPRINTED=11
PID_CREATE_DTM=12
PID_LASTSAVE_DTM=13
PID_PAGECOUNT=14
PID_WORDCOUNT=15
PID_CHARCOUNT=16
PID_APPNAME=18
PID_SECURITY=19

def reset():
    global _directories
    _directories = sets.Set()

def EnsureMSI():
    win32com.client.gencache.EnsureModule('{000C1092-0000-0000-C000-000000000046}', 1033, 1, 0)

def EnsureMSM():
    try:
        win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 1, 0)
    except pywintypes.com_error:
        win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 2, 0)

_Installer=None
def MakeInstaller():
    global _Installer
    if _Installer is None:
        EnsureMSI()
        _Installer = win32com.client.Dispatch('WindowsInstaller.Installer',
                     resultCLSID='{000C1090-0000-0000-C000-000000000046}')
    return _Installer

_Merge=None
def MakeMerge2():
    global _Merge
    if _Merge is None:
        EnsureMSM()
        _Merge = win32com.client.Dispatch("Msm.Merge2.1")
    return _Merge

class Table:
    def __init__(self, name):
        self.name = name
        self.fields = []

    def add_field(self, index, name, type):
        self.fields.append((index,name,type))

    def sql(self):
        fields = []
        keys = []
        self.fields.sort()
        fields = [None]*len(self.fields)
        for index, name, type in self.fields:
            index -= 1
            unk = type & ~knownbits
            if unk:
                print "%s.%s unknown bits %x" % (self.name, name, unk)
            size = type & datasizemask
            dtype = type & typemask
            if dtype == type_string:
                if size:
                    tname="CHAR(%d)" % size
                else:
                    tname="CHAR"
            elif dtype == type_short:
                assert size==2
                tname = "SHORT"
            elif dtype == type_long:
                assert size==4
                tname="LONG"
            elif dtype == type_binary:
                assert size==0
                tname="OBJECT"
            else:
                tname="unknown"
                print "%s.%sunknown integer type %d" % (self.name, name, size)
            if type & type_nullable:
                flags = ""
            else:
                flags = " NOT NULL"
            if type & type_localizable:
                flags += " LOCALIZABLE"
            fields[index] = "`%s` %s%s" % (name, tname, flags)
            if type & type_key:
                keys.append("`%s`" % name)
        fields = ", ".join(fields)
        keys = ", ".join(keys)
        return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys)

    def create(self, db):
        v = db.OpenView(self.sql())
        v.Execute(None)
        v.Close()

class Binary:
    def __init__(self, fname):
        self.name = fname
    def __repr__(self):
        return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name

def gen_schema(destpath, schemapath):
    d = MakeInstaller()
    schema = d.OpenDatabase(schemapath,
            win32com.client.constants.msiOpenDatabaseModeReadOnly)

    # XXX ORBER BY
    v=schema.OpenView("SELECT * FROM _Columns")
    curtable=None
    tables = []
    v.Execute(None)
    f = open(destpath, "wt")
    f.write("from msilib import Table\n")
    while 1:
        r=v.Fetch()
        if not r:break
        name=r.StringData(1)
        if curtable != name:
            f.write("\n%s = Table('%s')\n" % (name,name))
            curtable = name
            tables.append(name)
        f.write("%s.add_field(%d,'%s',%d)\n" %
                (name, r.IntegerData(2), r.StringData(3), r.IntegerData(4)))
    v.Close()

    f.write("\ntables=[%s]\n\n" % (", ".join(tables)))

    # Fill the _Validation table
    f.write("_Validation_records = [\n")
    v = schema.OpenView("SELECT * FROM _Validation")
    v.Execute(None)
    while 1:
        r = v.Fetch()
        if not r:break
        # Table, Column, Nullable
        f.write("(%s,%s,%s," %
                (`r.StringData(1)`, `r.StringData(2)`, `r.StringData(3)`))
        def put_int(i):
            if r.IsNull(i):f.write("None, ")
            else:f.write("%d," % r.IntegerData(i))
        def put_str(i):
            if r.IsNull(i):f.write("None, ")
            else:f.write("%s," % `r.StringData(i)`)
        put_int(4) # MinValue
        put_int(5) # MaxValue
        put_str(6) # KeyTable
        put_int(7) # KeyColumn
        put_str(8) # Category
        put_str(9) # Set
        put_str(10)# Description
        f.write("),\n")
    f.write("]\n\n")

    f.close()

def gen_sequence(destpath, msipath):
    dir = os.path.dirname(destpath)
    d = MakeInstaller()
    seqmsi = d.OpenDatabase(msipath,
            win32com.client.constants.msiOpenDatabaseModeReadOnly)

    v = seqmsi.OpenView("SELECT * FROM _Tables");
    v.Execute(None)
    f = open(destpath, "w")
    print >>f, "import msilib,os;dirname=os.path.dirname(__file__)"
    tables = []
    while 1:
        r = v.Fetch()
        if not r:break
        table = r.StringData(1)
        tables.append(table)
        f.write("%s = [\n" % table)
        v1 = seqmsi.OpenView("SELECT * FROM `%s`" % table)
        v1.Execute(None)
        info = v1.ColumnInfo(constants.msiColumnInfoTypes)
        while 1:
            r = v1.Fetch()
            if not r:break
            rec = []
            for i in range(1,r.FieldCount+1):
                if r.IsNull(i):
                    rec.append(None)
                elif info.StringData(i)[0] in "iI":
                    rec.append(r.IntegerData(i))
                elif info.StringData(i)[0] in "slSL":
                    rec.append(r.StringData(i))
                elif info.StringData(i)[0]=="v":
                    size = r.DataSize(i)
                    bytes = r.ReadStream(i, size, constants.msiReadStreamBytes)
                    bytes = bytes.encode("latin-1") # binary data represented "as-is"
                    if table == "Binary":
                        fname = rec[0]+".bin"
                        open(os.path.join(dir,fname),"wb").write(bytes)
                        rec.append(Binary(fname))
                    else:
                        rec.append(bytes)
                else:
                    raise "Unsupported column type", info.StringData(i)
            f.write(repr(tuple(rec))+",\n")
        v1.Close()
        f.write("]\n\n")
    v.Close()
    f.write("tables=%s\n" % repr(map(str,tables)))
    f.close()

class _Unspecified:pass
def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified):
    "Change the sequence number of an action in a sequence list"
    for i in range(len(seq)):
        if seq[i][0] == action:
            if cond is _Unspecified:
                cond = seq[i][1]
            if seqno is _Unspecified:
                seqno = seq[i][2]
            seq[i] = (action, cond, seqno)
            return
    raise ValueError, "Action not found in sequence"

def add_data(db, table, values):
    d = MakeInstaller()
    v = db.OpenView("SELECT * FROM `%s`" % table)
    count = v.ColumnInfo(0).FieldCount
    r = d.CreateRecord(count)
    for value in values:
        assert len(value) == count, value
        for i in range(count):
            field = value[i]
            if isinstance(field, (int, long)):
                r.SetIntegerData(i+1,field)
            elif isinstance(field, basestring):
                r.SetStringData(i+1,field)
            elif field is None:
                pass
            elif isinstance(field, Binary):
                r.SetStream(i+1, field.name)
            else:
                raise TypeError, "Unsupported type %s" % field.__class__.__name__
        v.Modify(win32com.client.constants.msiViewModifyInsert, r)
        r.ClearData()
    v.Close()

def add_stream(db, name, path):
    d = MakeInstaller()
    v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name)
    r = d.CreateRecord(1)
    r.SetStream(1, path)
    v.Execute(r)
    v.Close()

def init_database(name, schema,
                  ProductName, ProductCode, ProductVersion,
                  Manufacturer,
                  request_uac = False):
    try:
        os.unlink(name)
    except OSError:
        pass
    ProductCode = ProductCode.upper()
    d = MakeInstaller()
    # Create the database
    db = d.OpenDatabase(name,
         win32com.client.constants.msiOpenDatabaseModeCreate)
    # Create the tables
    for t in schema.tables:
        t.create(db)
    # Fill the validation table
    add_data(db, "_Validation", schema._Validation_records)
    # Initialize the summary information, allowing atmost 20 properties
    si = db.GetSummaryInformation(20)
    si.SetProperty(PID_TITLE, "Installation Database")
    si.SetProperty(PID_SUBJECT, ProductName)
    si.SetProperty(PID_AUTHOR, Manufacturer)
    si.SetProperty(PID_TEMPLATE, msi_type)
    si.SetProperty(PID_REVNUMBER, gen_uuid())
    if request_uac:
        wc = 2 # long file names, compressed, original media
    else:
        wc = 2 | 8 # +never invoke UAC
    si.SetProperty(PID_WORDCOUNT, wc)
    si.SetProperty(PID_PAGECOUNT, 200)
    si.SetProperty(PID_APPNAME, "Python MSI Library")
    # XXX more properties
    si.Persist()
    add_data(db, "Property", [
        ("ProductName", ProductName),
        ("ProductCode", ProductCode),
        ("ProductVersion", ProductVersion),
        ("Manufacturer", Manufacturer),
        ("ProductLanguage", "1033")])
    db.Commit()
    return db

def add_tables(db, module):
    for table in module.tables:
        add_data(db, table, getattr(module, table))

def make_id(str):
    #str = str.replace(".", "_") # colons are allowed
    str = str.replace(" ", "_")
    str = str.replace("-", "_")
    str = str.replace("+", "_")
    if str[0] in string.digits:
        str = "_"+str
    assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
    return str

def gen_uuid():
    return str(pythoncom.CreateGuid())

class CAB:
    def __init__(self, name):
        self.name = name
        self.file = open(name+".txt", "wt")
        self.filenames = sets.Set()
        self.index = 0

    def gen_id(self, dir, file):
        logical = _logical = make_id(file)
        pos = 1
        while logical in self.filenames:
            logical = "%s.%d" % (_logical, pos)
            pos += 1
        self.filenames.add(logical)
        return logical

    def append(self, full, file, logical = None):
        if os.path.isdir(full):
            return
        if not logical:
            logical = self.gen_id(dir, file)
        self.index += 1
        if full.find(" ")!=-1:
            print >>self.file, '"%s" %s' % (full, logical)
        else:
            print >>self.file, '%s %s' % (full, logical)
        return self.index, logical

    def commit(self, db):
        self.file.close()
        try:
            os.unlink(self.name+".cab")
        except OSError:
            pass
        for k, v in [(r"Software\Microsoft\VisualStudio\7.1\Setup\VS", "VS7CommonBinDir"),
                     (r"Software\Microsoft\VisualStudio\8.0\Setup\VS", "VS7CommonBinDir"),
                     (r"Software\Microsoft\VisualStudio\9.0\Setup\VS", "VS7CommonBinDir"),
                     (r"Software\Microsoft\Win32SDK\Directories", "Install Dir"),
                    ]:
            try:
                key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k)
                dir = _winreg.QueryValueEx(key, v)[0]
                _winreg.CloseKey(key)
            except (WindowsError, IndexError):
                continue
            cabarc = os.path.join(dir, r"Bin", "cabarc.exe")
            if not os.path.exists(cabarc):
                continue
            break
        else:
            print "WARNING: cabarc.exe not found in registry"
            cabarc = "cabarc.exe"
        cmd = r'"%s" -m lzx:21 n %s.cab @%s.txt' % (cabarc, self.name, self.name)
        p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for line in p.stdout:
            if line.startswith("  -- adding "):
                sys.stdout.write(".")
            else:
                sys.stdout.write(line)
            sys.stdout.flush()
        if not os.path.exists(self.name+".cab"):
            raise IOError, "cabarc failed"
        add_data(db, "Media",
                [(1, self.index, None, "#"+self.name, None, None)])
        add_stream(db, self.name, self.name+".cab")
        os.unlink(self.name+".txt")
        os.unlink(self.name+".cab")
        db.Commit()

_directories = sets.Set()
class Directory:
    def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None):
        """Create a new directory in the Directory table. There is a current component
        at each point in time for the directory, which is either explicitly created
        through start_component, or implicitly when files are added for the first
        time. Files are added into the current component, and into the cab file.
        To create a directory, a base directory object needs to be specified (can be
        None), the path to the physical directory, and a logical directory name.
        Default specifies the DefaultDir slot in the directory table. componentflags
        specifies the default flags that new components get."""
        index = 1
        _logical = make_id(_logical)
        logical = _logical
        while logical in _directories:
            logical = "%s%d" % (_logical, index)
            index += 1
        _directories.add(logical)
        self.db = db
        self.cab = cab
        self.basedir = basedir
        self.physical = physical
        self.logical = logical
        self.component = None
        self.short_names = sets.Set()
        self.ids = sets.Set()
        self.keyfiles = {}
        self.componentflags = componentflags
        if basedir:
            self.absolute = os.path.join(basedir.absolute, physical)
            blogical = basedir.logical
        else:
            self.absolute = physical
            blogical = None
        add_data(db, "Directory", [(logical, blogical, default)])

    def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None):
        """Add an entry to the Component table, and make this component the current for this
        directory. If no component name is given, the directory name is used. If no feature
        is given, the current feature is used. If no flags are given, the directory's default
        flags are used. If no keyfile is given, the KeyPath is left null in the Component
        table."""
        if flags is None:
            flags = self.componentflags
        if uuid is None:
            uuid = gen_uuid()
        else:
            uuid = uuid.upper()
        if component is None:
            component = self.logical
        self.component = component
        if Win64:
            flags |= 256
        if keyfile:
            keyid = self.cab.gen_id(self.absolute, keyfile)
            self.keyfiles[keyfile] = keyid
        else:
            keyid = None
        add_data(self.db, "Component",
                        [(component, uuid, self.logical, flags, None, keyid)])
        if feature is None:
            feature = current_feature
        add_data(self.db, "FeatureComponents",
                        [(feature.id, component)])

    def make_short(self, file):
        file = re.sub(r'[\?|><:/*"+,;=\[\]]', '_', file) # restrictions on short names
        parts = file.split(".")
        if len(parts)>1:
            suffix = parts[-1].upper()
        else:
            suffix = None
        prefix = parts[0].upper()
        if len(prefix) <= 8 and (not suffix or len(suffix)<=3):
            if suffix:
                file = prefix+"."+suffix
            else:
                file = prefix
            assert file not in self.short_names
        else:
            prefix = prefix[:6]
            if suffix:
                suffix = suffix[:3]
            pos = 1
            while 1:
                if suffix:
                    file = "%s~%d.%s" % (prefix, pos, suffix)
                else:
                    file = "%s~%d" % (prefix, pos)
                if file not in self.short_names: break
                pos += 1
                assert pos < 10000
                if pos in (10, 100, 1000):
                    prefix = prefix[:-1]
        self.short_names.add(file)
        return file

    def add_file(self, file, src=None, version=None, language=None):
        """Add a file to the current component of the directory, starting a new one
        one if there is no current component. By default, the file name in the source
        and the file table will be identical. If the src file is specified, it is
        interpreted relative to the current directory. Optionally, a version and a
        language can be specified for the entry in the File table."""
        if not self.component:
            self.start_component(self.logical, current_feature)
        if not src:
            # Allow relative paths for file if src is not specified
            src = file
            file = os.path.basename(file)
        absolute = os.path.join(self.absolute, src)
        assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names
        if self.keyfiles.has_key(file):
            logical = self.keyfiles[file]
        else:
            logical = None
        sequence, logical = self.cab.append(absolute, file, logical)
        assert logical not in self.ids
        self.ids.add(logical)
        short = self.make_short(file)
        full = "%s|%s" % (short, file)
        filesize = os.stat(absolute).st_size
        # constants.msidbFileAttributesVital
        # Compressed omitted, since it is the database default
        # could add r/o, system, hidden
        attributes = 512
        add_data(self.db, "File",
                        [(logical, self.component, full, filesize, version,
                         language, attributes, sequence)])
        if not version:
            # Add hash if the file is not versioned
            filehash = MakeInstaller().FileHash(absolute, 0)
            add_data(self.db, "MsiFileHash",
                     [(logical, 0, filehash.IntegerData(1),
                       filehash.IntegerData(2), filehash.IntegerData(3),
                       filehash.IntegerData(4))])
        # Automatically remove .pyc/.pyo files on uninstall (2)
        # XXX: adding so many RemoveFile entries makes installer unbelievably
        # slow. So instead, we have to use wildcard remove entries
        # if file.endswith(".py"):
        #     add_data(self.db, "RemoveFile",
        #              [(logical+"c", self.component, "%sC|%sc" % (short, file),
        #                self.logical, 2),
        #               (logical+"o", self.component, "%sO|%so" % (short, file),
        #                self.logical, 2)])

    def glob(self, pattern, exclude = None):
        """Add a list of files to the current component as specified in the
        glob pattern. Individual files can be excluded in the exclude list."""
        files = glob.glob1(self.absolute, pattern)
        for f in files:
            if exclude and f in exclude: continue
            self.add_file(f)
        return files

    def remove_pyc(self):
        "Remove .pyc/.pyo files on uninstall"
        add_data(self.db, "RemoveFile",
                 [(self.component+"c", self.component, "*.pyc", self.logical, 2),
                  (self.component+"o", self.component, "*.pyo", self.logical, 2)])

    def removefile(self, key, pattern):
        "Add a RemoveFile entry"
        add_data(self.db, "RemoveFile", [(self.component+key, self.component, pattern, self.logical, 2)])


class Feature:
    def __init__(self, db, id, title, desc, display, level = 1,
                 parent=None, directory = None, attributes=0):
        self.id = id
        if parent:
            parent = parent.id
        add_data(db, "Feature",
                        [(id, parent, title, desc, display,
                          level, directory, attributes)])
    def set_current(self):
        global current_feature
        current_feature = self

class Control:
    def __init__(self, dlg, name):
        self.dlg = dlg
        self.name = name

    def event(self, ev, arg, cond = "1", order = None):
        add_data(self.dlg.db, "ControlEvent",
                 [(self.dlg.name, self.name, ev, arg, cond, order)])

    def mapping(self, ev, attr):
        add_data(self.dlg.db, "EventMapping",
                 [(self.dlg.name, self.name, ev, attr)])

    def condition(self, action, condition):
        add_data(self.dlg.db, "ControlCondition",
                 [(self.dlg.name, self.name, action, condition)])

class RadioButtonGroup(Control):
    def __init__(self, dlg, name, property):
        self.dlg = dlg
        self.name = name
        self.property = property
        self.index = 1

    def add(self, name, x, y, w, h, text, value = None):
        if value is None:
            value = name
        add_data(self.dlg.db, "RadioButton",
                 [(self.property, self.index, value,
                   x, y, w, h, text, None)])
        self.index += 1

class Dialog:
    def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel):
        self.db = db
        self.name = name
        self.x, self.y, self.w, self.h = x,y,w,h
        add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)])

    def control(self, name, type, x, y, w, h, attr, prop, text, next, help):
        add_data(self.db, "Control",
                 [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)])
        return Control(self, name)

    def text(self, name, x, y, w, h, attr, text):
        return self.control(name, "Text", x, y, w, h, attr, None,
                     text, None, None)

    def bitmap(self, name, x, y, w, h, text):
        return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None)

    def line(self, name, x, y, w, h):
        return self.control(name, "Line", x, y, w, h, 1, None, None, None, None)

    def pushbutton(self, name, x, y, w, h, attr, text, next):
        return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None)

    def radiogroup(self, name, x, y, w, h, attr, prop, text, next):
        add_data(self.db, "Control",
                 [(self.name, name, "RadioButtonGroup",
                   x, y, w, h, attr, prop, text, next, None)])
        return RadioButtonGroup(self, name, prop)

    def checkbox(self, name, x, y, w, h, attr, prop, text, next):
        return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None)

def pe_type(path):
    header = open(path, "rb").read(1000)
    # offset of PE header is at offset 0x3c
    pe_offset = struct.unpack("<i", header[0x3c:0x40])[0]
    assert header[pe_offset:pe_offset+4] == "PE\0\0"
    machine = struct.unpack("<H", header[pe_offset+4:pe_offset+6])[0]
    return machine

def set_arch_from_file(path):
    global msi_type, Win64, arch_ext
    machine = pe_type(path)
    if machine == 0x14c:
        # i386
        msi_type = "Intel"
        Win64 = 0
        arch_ext = ''
    elif machine == 0x200:
        # Itanium
        msi_type = "Intel64"
        Win64 = 1
        arch_ext = '.ia64'
    elif machine == 0x8664:
        # AMD64
        msi_type = "x64"
        Win64 = 1
        arch_ext = '.amd64'
    else:
        raise ValueError, "Unsupported architecture"
    msi_type += ";1033"
