aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFritz Elfert <felfert@to.com>2002-02-28 20:56:59 +0000
committerFritz Elfert <felfert@to.com>2002-02-28 20:56:59 +0000
commiteecba3b5fcb47a01e6e13ee1940def989f6dd22d (patch)
tree970f3113de0d2b9b0544c1420117e0cf9633abcd /lib
parent12241e0ff5ea242891fc3a8c177e8f55e897f2a3 (diff)
downloadplptools-eecba3b5fcb47a01e6e13ee1940def989f6dd22d.tar.gz
plptools-eecba3b5fcb47a01e6e13ee1940def989f6dd22d.tar.bz2
plptools-eecba3b5fcb47a01e6e13ee1940def989f6dd22d.zip
- Added SIS stuff by Daniel Brahneborg
Diffstat (limited to 'lib')
-rw-r--r--lib/Enum.h6
-rw-r--r--lib/Makefile.am8
-rw-r--r--lib/bufferstore.cc10
-rw-r--r--lib/rfsv32.cc5
-rw-r--r--lib/siscomponentrecord.cpp55
-rw-r--r--lib/siscomponentrecord.h38
-rw-r--r--lib/sisfile.cpp72
-rw-r--r--lib/sisfile.h53
-rw-r--r--lib/sisfileheader.cpp92
-rw-r--r--lib/sisfileheader.h63
-rw-r--r--lib/sisfilerecord.cpp89
-rw-r--r--lib/sisfilerecord.h64
-rw-r--r--lib/sislangrecord.cpp18
-rw-r--r--lib/sislangrecord.h23
-rw-r--r--lib/sisreqrecord.cpp43
-rw-r--r--lib/sisreqrecord.h30
-rw-r--r--lib/sistypes.cpp89
-rw-r--r--lib/sistypes.h32
18 files changed, 782 insertions, 8 deletions
diff --git a/lib/Enum.h b/lib/Enum.h
index e29b8c0..79c2f80 100644
--- a/lib/Enum.h
+++ b/lib/Enum.h
@@ -199,6 +199,12 @@ public:
return *this;
}
+ inline Enum& operator = (const Enum& rhs) {
+ if (&rhs != this)
+ value = rhs.value;
+ return *this;
+ }
+
/**
* returns the enumeration value hold with this
* enum.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 49c9e46..0451077 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -8,10 +8,14 @@ libplp_la_LDFLAGS = $(LIBDEBUG) -version-info $(LIBVERSION)
libplp_la_SOURCES = bufferarray.cc bufferstore.cc iowatch.cc ppsocket.cc \
rfsv16.cc rfsv32.cc rfsvfactory.cc log.cc rfsv.cc rpcs32.cc rpcs16.cc \
- rpcs.cc rpcsfactory.cc psitime.cc Enum.cc plpdirent.cc wprt.cc rclip.cc
+ rpcs.cc rpcsfactory.cc psitime.cc Enum.cc plpdirent.cc wprt.cc \
+ rclip.cc siscomponentrecord.cpp sisfile.cpp sisfileheader.cpp \
+ sisfilerecord.cpp sislangrecord.cpp sisreqrecord.cpp sistypes.cpp
pkginclude_HEADERS = bufferarray.h bufferstore.h iowatch.h ppsocket.h \
rfsv.h rfsv16.h rfsv32.h rfsvfactory.h log.h rpcs32.h rpcs16.h rpcs.h \
- rpcsfactory.h psitime.h Enum.h plpdirent.h wprt.h plpintl.h rclip.h
+ rpcsfactory.h psitime.h Enum.h plpdirent.h wprt.h plpintl.h rclip.h \
+ siscomponentrecord.h sisfile.h sisfileheader.h sisfilerecord.h \
+ sislangrecord.h sisreqrecord.h sistypes.h
maintainer-clean-local:
rm -f Makefile.in
diff --git a/lib/bufferstore.cc b/lib/bufferstore.cc
index 8d7ed45..183ae6c 100644
--- a/lib/bufferstore.cc
+++ b/lib/bufferstore.cc
@@ -55,10 +55,12 @@ bufferStore::bufferStore(const unsigned char *_buff, long _len) {
}
bufferStore &bufferStore::operator =(const bufferStore &a) {
- checkAllocd(a.getLen());
- len = a.getLen();
- memcpy(buff, a.getString(0), len);
- start = 0;
+ if (this != &a) {
+ checkAllocd(a.getLen());
+ len = a.getLen();
+ memcpy(buff, a.getString(0), len);
+ start = 0;
+ }
return *this;
}
diff --git a/lib/rfsv32.cc b/lib/rfsv32.cc
index f1718d2..739844e 100644
--- a/lib/rfsv32.cc
+++ b/lib/rfsv32.cc
@@ -428,12 +428,12 @@ Enum<rfsv::errs> rfsv32::
fread(const u_int32_t handle, unsigned char * const buf, const u_int32_t len, u_int32_t &count)
{
Enum<rfsv::errs> res;
+ bufferStore a;
count = 0;
long l;
unsigned char *p = buf;
do {
- bufferStore a;
a.addDWord(handle);
a.addDWord(((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count));
if (!sendCommand(READ_FILE, a))
@@ -445,6 +445,7 @@ fread(const u_int32_t handle, unsigned char * const buf, const u_int32_t len, u_
count += l;
p += l;
}
+ a.init();
} while ((count < len) && (l > 0));
return res;
}
@@ -499,7 +500,7 @@ copyFromPsion(const char *from, const char *to, void *ptr, cpCallback_t cb)
res = E_PSI_FILE_CANCEL;
}
} while ((len > 0) && (res == E_PSI_GEN_NONE));
- delete[]buff;
+ delete [] buff;
fclose(handle);
op.close();
return res;
diff --git a/lib/siscomponentrecord.cpp b/lib/siscomponentrecord.cpp
new file mode 100644
index 0000000..b4b313a
--- /dev/null
+++ b/lib/siscomponentrecord.cpp
@@ -0,0 +1,55 @@
+
+#include "siscomponentrecord.h"
+#include "sisfile.h"
+
+#include <stdio.h>
+#include <string.h>
+
+SISComponentNameRecord::~SISComponentNameRecord()
+{
+ delete[] m_names;
+}
+
+void
+SISComponentNameRecord::fillFrom(uchar* buf, int base, SISFile* sisFile)
+{
+ int ix = base;
+
+ int n = sisFile->m_header.m_nlangs;
+ m_nameLengths = new uint32[n];
+ m_namePtrs = new uint32[n];
+ m_names = new uchar*[n];
+
+ // First read lengths.
+ //
+ for (int i = 0; i < n; ++i)
+ {
+ m_nameLengths[i] = read32(buf, &ix);
+ }
+
+ // Then read ptrs.
+ //
+ for (int i = 0; i < n; ++i)
+ {
+ m_namePtrs[i] = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Name %d (for %s) is %.*s\n",
+ i,
+ sisFile->getLanguage(i)->m_name,
+ m_nameLengths[i],
+ buf + m_namePtrs[i]);
+ int len = m_nameLengths[i];
+ m_names[i] = new uchar[len + 1];
+ memcpy(m_names[i], buf + m_namePtrs[i], len);
+ m_names[i][len] = 0;
+ }
+ if (logLevel >= 1)
+ printf("%d .. %d (%d bytes): Name records\n", base, ix, ix - base);
+}
+
+uchar*
+SISComponentNameRecord::getName(int no)
+{
+ return m_names[no];
+}
+
diff --git a/lib/siscomponentrecord.h b/lib/siscomponentrecord.h
new file mode 100644
index 0000000..995750d
--- /dev/null
+++ b/lib/siscomponentrecord.h
@@ -0,0 +1,38 @@
+#ifndef _SISCOMPONENTRECORD_H
+#define _SISCOMPONENTRECORD_H
+
+#include "sistypes.h"
+
+class SISFile;
+
+/**
+ * The name of the component in this SIS file.
+ * A single instance holds the names for all languages.
+ */
+class SISComponentNameRecord
+{
+public:
+
+ virtual ~SISComponentNameRecord();
+
+ /**
+ * Populate the fields.
+ */
+ void fillFrom(uchar* buf, int base, SISFile* sisFile);
+
+ uchar* getName(int no);
+
+private:
+
+ uint32* m_nameLengths;
+ uint32* m_namePtrs;
+
+ /**
+ * The extracted names.
+ */
+ uchar** m_names;
+
+};
+
+#endif
+
diff --git a/lib/sisfile.cpp b/lib/sisfile.cpp
new file mode 100644
index 0000000..53b9c24
--- /dev/null
+++ b/lib/sisfile.cpp
@@ -0,0 +1,72 @@
+
+#include "sisfile.h"
+#include "sislangrecord.h"
+#include "sisfilerecord.h"
+#include "sisreqrecord.h"
+
+#include <stdio.h>
+
+void
+SISFile::fillFrom(uchar* buf)
+{
+ int ix = 0;
+ m_header.fillFrom(buf, &ix);
+ if (logLevel >= 2)
+ printf("Ate header, got ix = %d\n", ix);
+ int n;
+
+ // Read languages.
+ //
+ n = m_header.m_nlangs;
+ m_langRecords = new SISLangRecord[n];
+ ix = m_header.m_languagePtr;
+ for (int i = 0; i < n; ++i)
+ m_langRecords[i].fillFrom(buf, &ix);
+
+ // Read requisites.
+ //
+ n = m_header.m_nreqs;
+ m_reqRecords = new SISReqRecord[n];
+ ix = m_header.m_reqPtr;
+ for (int i = 0; i < n; ++i)
+ m_reqRecords[i].fillFrom(buf, &ix, this);
+
+ // Read component names, by language.
+ //
+ ix = m_header.m_componentPtr;
+ m_componentRecord.fillFrom(buf, ix, this);
+
+ // Read files.
+ //
+ n = m_header.m_nfiles;
+ m_fileRecords = new SISFileRecord[n];
+ ix = m_header.m_filesPtr;
+ for (int i = 0; i < n; ++i)
+ m_fileRecords[i].fillFrom(buf, &ix, this);
+
+}
+
+int
+SISFile::getLanguage()
+{
+ return m_header.m_installationLanguage;
+}
+
+LangTableEntry*
+SISFile::getLanguage(int i)
+{
+ return &langTable[m_langRecords[i].m_lang];
+}
+
+uchar*
+SISFile::getName()
+{
+ return m_componentRecord.getName(m_header.m_installationLanguage);
+}
+
+void
+SISFile::setLanguage(int lang)
+{
+ m_header.m_installationLanguage = lang;
+}
+
diff --git a/lib/sisfile.h b/lib/sisfile.h
new file mode 100644
index 0000000..5f0bcd5
--- /dev/null
+++ b/lib/sisfile.h
@@ -0,0 +1,53 @@
+#ifndef _SISFILE_H
+#define _SISFILE_H
+
+#include "sistypes.h"
+#include "sisfileheader.h"
+#include "siscomponentrecord.h"
+
+class SISLangRecord;
+class SISFileRecord;
+class SISReqRecord;
+
+/**
+ * The top level container of a SIS file.
+ * Based on documentation by Alexander Thoukydides <alex@thouky.co.uk>.
+ *
+ * @author Daniel Brahneborg, 2002
+ */
+class SISFile
+{
+public:
+ /**
+ * Populate the fields.
+ */
+ void fillFrom(uchar* buf);
+
+ int getLanguage();
+
+ /**
+ * Find a language entry, based on the sequence number in the SISLangRecord
+ * part of the file.
+ */
+ LangTableEntry* getLanguage(int i);
+
+ /**
+ * Get the name of this component, in the selected language.
+ */
+ uchar* getName();
+
+ void setLanguage(int lang);
+
+ SISFileHeader m_header;
+ SISLangRecord* m_langRecords;
+ SISFileRecord* m_fileRecords;
+ SISReqRecord* m_reqRecords;
+
+private:
+
+ SISComponentNameRecord m_componentRecord;
+
+};
+
+#endif
+
diff --git a/lib/sisfileheader.cpp b/lib/sisfileheader.cpp
new file mode 100644
index 0000000..b9800b2
--- /dev/null
+++ b/lib/sisfileheader.cpp
@@ -0,0 +1,92 @@
+
+#include "sisfileheader.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+SISFileHeader::fillFrom(uchar* buf, int* base)
+{
+ int ix = *base;
+ m_uid1 = read32(buf, &ix);
+ if (logLevel >= 1)
+ printf("Got uid1 = %08x\n", m_uid1);
+ m_uid2 = read32(buf, &ix);
+ if (m_uid2 != 0x1000006d)
+ {
+ printf("Got bad uid2.\n");
+ exit(1);
+ }
+ if (logLevel >= 2)
+ printf("Got uid2 = %08x\n", m_uid2);
+ m_uid3 = read32(buf, &ix);
+ if (m_uid3 != 0x10000419)
+ {
+ printf("Got bad uid3.\n");
+ exit(1);
+ }
+ if (logLevel >= 2)
+ printf("Got uid3 = %08x\n", m_uid3);
+ m_uid4 = read32(buf, &ix);
+// printf("Got uid4 = %08x\n", m_uid4);
+ uint16 crc1 = 0;
+ for (int i = 0; i < 12; i += 2)
+ crc1 = updateCrc(crc1, buf[*base + i]);
+ uint16 crc2 = 0;
+ for (int i = 0; i < 12; i += 2)
+ crc2 = updateCrc(crc2, buf[*base + i + 1]);
+ if (logLevel >= 2)
+ printf("Got first crc = %08x, wanted %08x\n",
+ crc2 << 16 | crc1, m_uid4);
+ if ((crc2 << 16 | crc1) != m_uid4)
+ {
+ printf("Got bad crc.\n");
+ exit(1);
+ }
+ m_crc = read16(buf, &ix);
+ m_nlangs = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got %d languages\n", m_nlangs);
+ m_nfiles = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got %d files\n", m_nfiles);
+ m_nreqs = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got %d reqs\n", m_nreqs);
+ m_installationLanguage = read16(buf, &ix);
+ m_installationFiles = read16(buf, &ix);
+ m_installationDrive = read32(buf, &ix);
+ m_installerVersion = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got installer version: %08x\n", m_installerVersion);
+ m_options = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got options: %04x\n", m_options);
+ m_type = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got type: %0x\n", m_type);
+ m_major = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got major: %d\n", m_major);
+ m_minor = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got minor: %d\n", m_minor);
+ m_minor = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got variant: %d\n", m_variant);
+ m_languagePtr = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Languages begin at %d\n", m_languagePtr);
+ m_filesPtr = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Files begin at %d\n", m_filesPtr);
+ m_reqPtr = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Requisites begin at %d\n", m_reqPtr);
+ m_unknown = read32(buf, &ix);
+ m_componentPtr = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Components begin at %d\n", m_componentPtr);
+ *base = ix;
+}
+
diff --git a/lib/sisfileheader.h b/lib/sisfileheader.h
new file mode 100644
index 0000000..1583365
--- /dev/null
+++ b/lib/sisfileheader.h
@@ -0,0 +1,63 @@
+#ifndef _SISFILEHEADER_H
+#define _SISFILEHEADER_H
+
+#include "sistypes.h"
+
+/**
+ * The first part of a SIS file.
+ */
+class SISFileHeader
+{
+public:
+
+ /**
+ * Populate the fields.
+ */
+ void fillFrom(uchar* buf, int* base);
+
+ enum FileOptions {
+ op_isUnicode = 1,
+ op_isDistributable = 2,
+#ifdef EPOC6
+ op_noCompress = 8,
+ op_shutdownApps = 16,
+#endif
+ };
+
+ enum FileType {
+ FT_App = 0,
+#ifdef EPOC6
+ FT_System = 1,
+ FT_Option = 2,
+ FT_Config = 3,
+ FT_Patch = 4,
+ FT_Upgrade = 5,
+#endif
+ };
+
+ uint32 m_uid1;
+ uint32 m_uid2;
+ uint32 m_uid3;
+ uint32 m_uid4;
+ uint16 m_crc;
+ uint16 m_nlangs;
+ uint16 m_nfiles;
+ uint16 m_nreqs;
+ uint16 m_installationLanguage;
+ uint16 m_installationFiles;
+ uint32 m_installationDrive;
+ uint32 m_installerVersion;
+ uint16 m_options;
+ uint16 m_type;
+ uint16 m_major;
+ uint16 m_minor;
+ uint32 m_variant;
+ uint32 m_languagePtr;
+ uint32 m_filesPtr;
+ uint32 m_reqPtr;
+ uint32 m_unknown;
+ uint32 m_componentPtr;
+};
+
+#endif
+
diff --git a/lib/sisfilerecord.cpp b/lib/sisfilerecord.cpp
new file mode 100644
index 0000000..74b78c5
--- /dev/null
+++ b/lib/sisfilerecord.cpp
@@ -0,0 +1,89 @@
+
+#include "sisfilerecord.h"
+#include "sisfile.h"
+
+#include <stdio.h>
+
+void
+SISFileRecord::fillFrom(uchar* buf, int* base, SISFile* sisFile)
+{
+ int ix = *base;
+ m_flags = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got flags %d\n", m_flags);
+ m_fileType = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got file type %d\n", m_fileType);
+ m_fileDetails = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got file details %d\n", m_fileDetails);
+ m_sourceLength = read32(buf, &ix);
+ m_sourcePtr = read32(buf, &ix);
+// printf("Got source length = %d, source name ptr = %d\n",
+// m_sourceLength, m_sourcePtr);
+ if (logLevel >= 2)
+ if (m_sourceLength > 0)
+ printf("Got source name %.*s\n", m_sourceLength, buf + m_sourcePtr);
+ m_destLength = read32(buf, &ix);
+ m_destPtr = read32(buf, &ix);
+// printf("Got dest length = %d, dest name ptr = %d\n",
+// m_destLength, m_destPtr);
+ if (logLevel >= 2)
+ printf("Got destination name %.*s\n", m_destLength, buf + m_destPtr);
+ switch (m_flags)
+ {
+ case 0: // Only one file.
+ m_fileLengths = new uint32[1];
+ m_filePtrs = new uint32[1];
+ m_fileLengths[0] = read32(buf, &ix);
+ m_filePtrs[0] = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("File is %d bytes long (at %d) (to %d)\n",
+ m_fileLengths[0], m_filePtrs[0],
+ m_fileLengths[0] + m_filePtrs[0]);
+ if (logLevel >= 1)
+ printf("%d .. %d (%d bytes): Single file record type %d, %.*s\n",
+ m_filePtrs[0],
+ m_filePtrs[0] + m_fileLengths[0],
+ m_fileLengths[0],
+ m_fileType,
+ m_destLength, buf + m_destPtr);
+ break;
+
+ case 1: // One file per language.
+ {
+ int n = sisFile->m_header.m_nlangs;
+ m_fileLengths = new uint32[n];
+ m_filePtrs = new uint32[n];
+ for (int i = 0; i < n; ++i)
+ {
+ m_fileLengths[i] = read32(buf, &ix);
+ }
+ for (int i = 0; i < n; ++i)
+ {
+ m_filePtrs[i] = read32(buf, &ix);
+ int len = m_fileLengths[i];
+ if (logLevel >= 2)
+ printf("File %d (for %s) is %d bytes long (at %d)\n",
+ i,
+ sisFile->getLanguage(i)->m_name,
+ len,
+ m_filePtrs[i]);
+ if (logLevel >= 1)
+ printf("%d .. %d (%d bytes): File record (%s) for %.*s\n",
+ m_filePtrs[i],
+ m_filePtrs[i] + len,
+ len,
+ sisFile->getLanguage(i)->m_name,
+ m_destLength, buf + m_destPtr);
+ }
+ break;
+ }
+
+ default:
+ if (logLevel >= 2)
+ printf("Unknown file flags %d\n", m_flags);
+ }
+ *base = ix;
+}
+
diff --git a/lib/sisfilerecord.h b/lib/sisfilerecord.h
new file mode 100644
index 0000000..1187ccf
--- /dev/null
+++ b/lib/sisfilerecord.h
@@ -0,0 +1,64 @@
+#ifndef _SISFILERECORD_H
+#define _SISFILERECORD_H
+
+#include "sistypes.h"
+
+class SISFile;
+
+/**
+ * Information about a file component in a SIS file.
+ *
+ * The file can be for multiple languages, in which case a single
+ * instance holds pointers to contents for all languages.
+ */
+class SISFileRecord
+{
+public:
+
+ /**
+ * Populate the fields.
+ */
+ void fillFrom(uchar* buf, int* base, SISFile* sisFile);
+
+ /**
+ * 1 if multiple lang versions, otherwise 0.
+ */
+ uint32 m_flags;
+
+ /**
+ * Type of file.
+ *
+ * - 0: Standard file.
+ * - 1: Text file to display during installation.
+ * - 2: SIS component.
+ * - 3: File to run during installation/removal.
+ * - 4: Does not exist yet, but will be created when app is run, so
+ * it should not be removed during an upgrade.
+ */
+ uint32 m_fileType;
+
+ /**
+ * If file type is 1:
+ *
+ * - 0: Continue.
+ * - 1: Yes, No (skip next file).
+ * - 2: Yes, No (abort installation).
+ *
+ * If file type is 3:
+ *
+ * - 0: Run during installation.
+ * - 1: Run during removal.
+ * - 2: Run during both installation and removal.
+ */
+ uint32 m_fileDetails;
+
+ uint32 m_sourceLength;
+ uint32 m_sourcePtr;
+ uint32 m_destLength;
+ uint32 m_destPtr;
+ uint32* m_fileLengths;
+ uint32* m_filePtrs;
+};
+
+#endif
+
diff --git a/lib/sislangrecord.cpp b/lib/sislangrecord.cpp
new file mode 100644
index 0000000..c79c45b
--- /dev/null
+++ b/lib/sislangrecord.cpp
@@ -0,0 +1,18 @@
+
+#include "sislangrecord.h"
+
+#include <stdio.h>
+
+void
+SISLangRecord::fillFrom(uchar* buf, int* base)
+{
+ int ix = *base;
+ m_lang = read16(buf, &ix);
+ if (logLevel >= 2)
+ printf("Got language %d (%s)\n", m_lang, langTable[m_lang].m_name);
+ if (logLevel >= 1)
+ printf("%d .. %d (%d bytes): Language record for %s\n",
+ *base, ix, ix - *base, langTable[m_lang].m_name);
+ *base = ix;
+}
+
diff --git a/lib/sislangrecord.h b/lib/sislangrecord.h
new file mode 100644
index 0000000..e532c4e
--- /dev/null
+++ b/lib/sislangrecord.h
@@ -0,0 +1,23 @@
+#ifndef _SISLANGRECORD_H
+#define _SISLANGRECORD_H
+
+#include "sistypes.h"
+
+/**
+ * A simple language record, only containing the epoc specific 16 bit
+ * language number.
+ */
+class SISLangRecord
+{
+public:
+
+ /**
+ * Populate the fields.
+ */
+ void fillFrom(uchar* buf, int* base);
+
+ uint16 m_lang;
+};
+
+#endif
+
diff --git a/lib/sisreqrecord.cpp b/lib/sisreqrecord.cpp
new file mode 100644
index 0000000..978ce48
--- /dev/null
+++ b/lib/sisreqrecord.cpp
@@ -0,0 +1,43 @@
+
+#include "sisreqrecord.h"
+#include "sisfile.h"
+
+#include <stdio.h>
+
+void
+SISReqRecord::fillFrom(uchar* buf, int* base, SISFile* sisFile)
+{
+ int ix = *base;
+
+ m_uid = read32(buf, &ix);
+ m_major = read16(buf, &ix);
+ m_minor = read16(buf, &ix);
+ m_variant = read32(buf, &ix);
+ int n = sisFile->m_header.m_nreqs;
+ m_nameLengths = new uint32[n];
+ m_namePtrs = new uint32[n];
+
+ // First read lengths.
+ //
+ for (int i = 0; i < n; ++i)
+ {
+ m_nameLengths[i] = read32(buf, &ix);
+ }
+
+ // Then read ptrs.
+ //
+ for (int i = 0; i < n; ++i)
+ {
+ m_namePtrs[i] = read32(buf, &ix);
+ if (logLevel >= 2)
+ printf("Name %d (for %s) is %.*s\n",
+ i,
+ sisFile->getLanguage(i)->m_name,
+ m_nameLengths[i],
+ buf + m_namePtrs[i]);
+ }
+ if (logLevel >= 1)
+ printf("%d .. %d (%d bytes): Req record\n", *base, ix, ix - *base);
+ *base = ix;
+}
+
diff --git a/lib/sisreqrecord.h b/lib/sisreqrecord.h
new file mode 100644
index 0000000..bd9aff2
--- /dev/null
+++ b/lib/sisreqrecord.h
@@ -0,0 +1,30 @@
+#ifndef _SISREQRECORD_H
+#define _SISREQRECORD_H
+
+#include "sistypes.h"
+
+class SISFile;
+
+/**
+ * Information about an application that must be installed prior to the
+ * current one.
+ */
+class SISReqRecord
+{
+public:
+
+ /**
+ * Populate the fields.
+ */
+ void fillFrom(uchar* buf, int* base, SISFile* file);
+
+ uint32 m_uid;
+ uint16 m_major;
+ uint16 m_minor;
+ uint32 m_variant;
+ uint32* m_nameLengths;
+ uint32* m_namePtrs;
+};
+
+#endif
+
diff --git a/lib/sistypes.cpp b/lib/sistypes.cpp
new file mode 100644
index 0000000..74ae5ea
--- /dev/null
+++ b/lib/sistypes.cpp
@@ -0,0 +1,89 @@
+
+#include "sistypes.h"
+
+static unsigned int s_crcTable[256];
+
+int logLevel = 0;
+
+void createCRCTable()
+{
+ const unsigned int polynomial = 0x1021;
+ unsigned int index;
+ s_crcTable[0] = 0;
+ for (index = 0; index < 128; index++)
+ {
+ unsigned int carry = s_crcTable[index] & 0x8000;
+ unsigned int temp = (s_crcTable[index] << 1) & 0xffff;
+ s_crcTable[index * 2 + (carry ? 0 : 1)] = temp ^ polynomial;
+ s_crcTable[index * 2 + (carry ? 1 : 0)] = temp;
+ }
+}
+
+uint16 updateCrc(uint16 crc, uchar value)
+{
+ return (crc << 8) ^ s_crcTable[((crc >> 8) ^ value) & 0xff];
+}
+
+uint16 calcCRC(uchar* data, int len)
+{
+ uint16 crc = 0;
+ for (int i = 0; i < len; ++i)
+ {
+ uchar value = data[i];
+ crc = (crc << 8) ^ s_crcTable[((crc >> 8) ^ value) & 0xff];
+ }
+ return crc;
+}
+
+uint16 read16(uchar* buf, int* ix)
+{
+ uchar* p = buf + *ix;
+ *ix += 2;
+ return p[0] | (p[1] << 8);
+}
+
+uint32 read32(uchar* buf, int* ix)
+{
+ uchar* p = buf + *ix;
+ *ix += 4;
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+LangTableEntry langTable[] =
+{
+ { 0, "", "Test" },
+ { 1, "EN", "UK English" },
+ { 2, "FR", "French" },
+ { 3, "GE", "German" },
+ { 4, "SP", "Spanish" },
+ { 5, "IT", "Italian" },
+ { 6, "SW", "Swedish" },
+ { 7, "DA", "Danish" },
+ { 8, "NO", "Norwegian" },
+ { 9, "FI", "Finnish" },
+ { 10, "AM", "American English" },
+ { 11, "SF", "Swiss French" },
+ { 12, "SG", "Swiss German" },
+ { 13, "PO", "Portuguese" },
+ { 14, "TU", "Turkish" },
+ { 15, "IC", "Icelandic" },
+ { 16, "RU", "Russian" },
+ { 17, "HU", "Hungarian" },
+ { 18, "DU", "Dutch" },
+ { 19, "BL", "Belgian Flemish" },
+ { 20, "AU", "Australian English" },
+ { 21, "BG", "Belgian French" },
+ { 22, "AS", "Austrian German" },
+ { 23, "NZ", "New Zealand" },
+ { 24, "IF", "International French" },
+ { 25, "CS", "Czech" },
+ { 26, "SK", "Slovak" },
+ { 27, "PL", "Polish" },
+ { 28, "SL", "Slovenian" },
+ { 29, "TC", "Taiwan Chinese" },
+ { 30, "HK", "Hong Kong" },
+ { 31, "ZH", "PRC Chinese" },
+ { 32, "JA", "Japanese" },
+ { 33, "TH", "Thai" },
+};
+
diff --git a/lib/sistypes.h b/lib/sistypes.h
new file mode 100644
index 0000000..834cf43
--- /dev/null
+++ b/lib/sistypes.h
@@ -0,0 +1,32 @@
+#ifndef _SISTYPES_H
+#define _SISTYPES_H
+
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned char uchar;
+
+extern uint16 read16(uchar* buf, int* ix);
+
+extern uint32 read32(uchar* buf, int* ix);
+
+extern void createCRCTable();
+
+extern uint16 updateCrc(uint16 crc, uchar value);
+
+extern int logLevel;
+
+/**
+ * Holder of a language entry, translating from language numbers to
+ * names.
+ */
+struct LangTableEntry
+{
+ uint16 m_no;
+ char m_code[3];
+ char* m_name;
+};
+
+extern LangTableEntry langTable[];
+
+#endif
+