+extern int crndata_len;
+extern int crn_decompressed_size;
+extern char*license_text;
+
+#include "background.c"
+#endif
+
+typedef struct _filelist
+{
+ const char*filename;
+ struct _filelist*next;
+ char type;
+} filelist_t;
+
+static filelist_t* registerFile(filelist_t*next, const char*filename, char type)
+{
+ filelist_t*file = malloc(sizeof(filelist_t));
+ file->filename = strdup(filename);
+ file->type = type;
+ file->next = next;
+ return file;
+}
+
+static filelist_t* readFileList(char*filename)
+{
+ FILE*fi = fopen(filename, "rb");
+ if(!fi) {
+ return 0;
+ }
+ fseek(fi, 0, SEEK_END);
+ int len = ftell(fi);
+ fseek(fi, 0, SEEK_SET);
+ char*data = malloc(len+1);
+ fread(data, len, 1, fi);
+ fclose(fi);
+ int t=0;
+ char*line = data;
+ filelist_t*list = 0,*lpos=0;;
+ while(t<len) {
+ if(data[t]=='\r' || data[t]=='\n') {
+ data[t++] = 0;
+ if(strchr("DFI", line[0]) && line[1]==' ' && line[2]!=' ') {
+ filelist_t*f = malloc(sizeof(filelist_t));
+ f->type=line[0];
+ f->filename=strdup(line+2);
+ f->next = 0;
+ if(!list) {
+ list = lpos = f;
+ } else {
+ lpos->next = f;
+ lpos = f;
+ }
+ } else {
+ // skip line- this usually only happens if somebody tampered
+ // with the file
+ }
+ while(t<len && (data[t]=='\0' || data[t]=='\r' || data[t]=='\n'))
+ t++;
+ line = &data[t];
+ } else {
+ t++;
+ }
+ }
+ return list;
+}
+
+static void writeFileList(filelist_t*file, const char*filename)
+{
+ FILE*fi = fopen(filename, "wb");
+ fprintf(fi, "[%s installed files]\r\n", SOFTWARE_NAME);
+ if(!fi) {
+ char buf[1024];
+ sprintf(buf, "Couldn't write file %s", filename);
+ MessageBox(0, buf, INSTALLER_NAME, MB_OK|MB_ICONERROR);
+ do_abort=1;
+ exit(1);
+ }
+ while(file) {
+ fprintf(fi, "%c %s\r\n", file->type, file->filename);
+ file = file->next;
+ }
+ fclose(fi);
+}
+
+static filelist_t*installedFiles = 0;
+
+static void addFile(const char*filename)
+{
+ installedFiles = registerFile(installedFiles, filename, 'F');
+}
+static void addDir(const char*filename)
+{
+ installedFiles = registerFile(installedFiles, filename, 'D');
+}
+
+static void handleTemplateFile(const char*filename)
+{
+ FILE*fi = fopen(filename, "rb");
+ fseek(fi, 0, SEEK_END);
+ int len = ftell(fi);
+ fseek(fi, 0, SEEK_SET);
+ char*file = malloc(len+1);
+ fread(file, len, 1, fi);
+ fclose(fi);
+ int l = strlen(install_path);
+ fi = fopen(filename, "wb");
+ char*pos = file;
+ char*lastpos = file;
+ while(1) {
+ pos = strstr(pos, "%%PATH%%");
+ if(!pos) {
+ pos = &file[len];
+ break;
+ }
+ if(pos!=lastpos)
+ fwrite(lastpos, pos-lastpos, 1, fi);
+ fwrite(install_path, l, 1, fi);
+ pos+=8; // length of "%%PATH%%"
+ lastpos = pos;
+ }
+ fwrite(lastpos, pos-lastpos, 1, fi);
+ fclose(fi);
+ free(file);
+}
+
+static int setRegistryEntry(char*key,char*value)
+{
+ HKEY hkey1;
+ HKEY hkey2;
+ int ret1 = -1, ret2= -1;
+ ret1 = RegCreateKey(HKEY_CURRENT_USER, key, &hkey1);
+ if(config_forAllUsers) {
+ ret2 = RegCreateKey(HKEY_LOCAL_MACHINE, key, &hkey2);
+ }
+
+ if(ret1 && ret2) {
+ fprintf(stderr, "registry: CreateKey %s failed\n", key);
+ return 0;
+ }
+ if(ret1) {
+ installedFiles = registerFile(installedFiles, key, 'k');
+ }
+ if(ret2) {
+ installedFiles = registerFile(installedFiles, key, 'K');
+ }
+
+ if(!ret1)
+ ret1 = RegSetValue(hkey1, NULL, REG_SZ, value, strlen(value)+1);
+ if(!ret2)
+ ret2 = RegSetValue(hkey2, NULL, REG_SZ, value, strlen(value)+1);
+ if(ret1 && ret2) {
+ fprintf(stderr, "registry: SetValue %s failed\n", key);
+ return 0;
+ }
+ return 1;
+}
+
+
+static char* getRegistryEntry(char*path)
+{
+ int res = 0;
+ HKEY key;
+ long rc;
+ long size = 0;
+ DWORD type;
+ char*buf;
+ rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_ALL_ACCESS/* KEY_READ*/, &key);
+ if (rc != ERROR_SUCCESS) {
+ fprintf(stderr, "RegOpenKeyEx failed\n");
+ return 0;
+ }
+ rc = RegQueryValueEx(key, NULL, 0, 0, 0, (LPDWORD)&size) ;
+ if(rc != ERROR_SUCCESS) {
+ fprintf(stderr, "RegQueryValueEx(1) failed: %d\n", rc);
+ return 0;
+ }
+ buf = (char*)malloc(size+1);
+ rc = RegQueryValueEx(key, NULL, 0, &type, (BYTE*)buf, (LPDWORD)&size);
+ if(rc != ERROR_SUCCESS) {
+ fprintf(stderr, "RegQueryValueEx(2) failed: %d\n", rc);
+ return 0;
+ }
+ if(type == REG_SZ || type == REG_EXPAND_SZ) {
+ while(size && buf[size-1] == '\0')
+ --size;
+ buf[size] = 0;
+ /* TODO: convert */
+ return buf;
+ } else if(type == REG_BINARY) {
+ return buf;
+ }
+}
+
+static int has_full_access = 0;
+static char hasFullAccess()
+{
+ /* find out whether we can write keys in HKEY_LOCAL_MACHINE */
+ HKEY hKey;
+ int ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0,
+ KEY_CREATE_SUB_KEY, &hKey);
+ if(!ret) {
+ RegCloseKey(hKey);
+ return 1;
+ } else {
+ return 0;
+ }
+}