From d6e5f7ae7b48fd09a366a6fa7efaf9b72d40275f Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 15 May 2017 18:46:48 +0100 Subject: All the remaining function stubs I appear to need. Now I can get an idea of what sequence of calls WiX actually expects to use to build an MSI. --- fake-lib.c | 70 ++++++++++++++++++++++++++++++++++++ fake-msi.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- fake-winterop.c | 6 ++-- 3 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 fake-lib.c diff --git a/fake-lib.c b/fake-lib.c new file mode 100644 index 0000000..f8dbea4 --- /dev/null +++ b/fake-lib.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static char *ascii(const char16_t *wstr, bool translate_slashes) +{ + size_t len = 0; + for (const char16_t *wp = wstr; *wp; wp++) + len++; + char *ret = malloc(len + 1); + char *p = ret; + for (const char16_t *wp = wstr; *wp; wp++) + *p++ = (*wp == '\\' && translate_slashes ? '/' : + *wp < 0x80 ? *wp : + '?'); + *p = '\0'; + return ret; +} + +static void system_argv(const char *cmd, ...) +{ + int nargs, nchars; + const char *word; + va_list ap; + + va_start(ap, cmd); + nargs = 1; /* terminating NULL */ + nchars = 0; + for (word = cmd; word; word = va_arg(ap, const char *)) { + nargs++; + nchars += 1 + strlen(word); + } + va_end(ap); + + char *args[nargs], chars[nchars]; + char **argp = args, *charp = chars; + va_start(ap, cmd); + for (word = cmd; word; word = va_arg(ap, const char *)) { + *argp++ = charp; + strcpy(charp, word); + charp += 1 + strlen(word); + } + va_end(ap); + *argp++ = NULL; + + pid_t pid = fork(); + if (pid < 0) + err(1, "fork"); + + if (pid == 0) { + execvp(args[0], args); + warn("execvp"); + _exit(127); + } + + int status; + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid"); + if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) + errx(1, "subcommand failed"); +} diff --git a/fake-msi.c b/fake-msi.c index 1302e8c..3bf1475 100644 --- a/fake-msi.c +++ b/fake-msi.c @@ -7,9 +7,117 @@ #include #include +#include + +static char *ascii(const char16_t *wstr, bool translate_slashes) +{ + size_t len = 0; + for (const char16_t *wp = wstr; *wp; wp++) + len++; + char *ret = malloc(len + 1); + char *p = ret; + for (const char16_t *wp = wstr; *wp; wp++) + *p++ = (*wp == '\\' && translate_slashes ? '/' : + *wp < 0x80 ? *wp : + '?'); + *p = '\0'; + return ret; +} + +static void c16cpy(char16_t *out, uint32_t *outsize, char *s) +{ + uint32_t retlen = 0; + while (retlen < *outsize) { + char16_t c = (out[retlen] = (unsigned char)*s++); + if (!c) + break; + retlen++; + } + *outsize = retlen; +} + uint32_t MsiGetFileVersionW(const char16_t *filename, char16_t *version, uint32_t *version_size, char16_t *language, uint32_t *language_size) { - errx(1, "NYI: MsiGetFileVersion"); + warnx("FIXME: MsiGetFileVersion(%s)", ascii(filename, true)); + if (version) { + c16cpy(version, version_size, "0.1.2.3"); + } + if (language) { + c16cpy(language, language_size, "2057"); + } + return 0; +} + +uint32_t MsiOpenDatabaseW(const char16_t *filename, + const char16_t *persist, + void **handle) +{ + char *file = ascii(filename, true); + warnx("FIXME: MsiOpenDatabaseW(%s,%p)", file, persist); + close(open(file, O_WRONLY | O_CREAT, 0666)); + *handle = (void *)1; + return 0; +} + +uint32_t MsiCloseHandle(void *handle) +{ + warnx("FIXME: MsiCloseHandle(%p)", handle); + return 0; +} + +uint32_t MsiDatabaseImportW(void *handle, const char16_t *folder, + const char16_t *file) +{ + warnx("FIXME: MsiDatabaseImport(%p,%s,%s)", handle, ascii(folder, true), + ascii(file, true)); + return 0; +} + +uint32_t MsiDatabaseOpenViewW(void *handle, const char16_t *query, + void **outhandle) +{ + warnx("FIXME: MsiDatabaseOpenView(%p,%s)", handle, ascii(query, false)); + *outhandle = (void *)2; + return 0; +} + +uint32_t MsiViewExecute(void *handle, void *params) +{ + warnx("FIXME: MsiViewExecute(%p)", handle); + return 0; +} + +void *MsiCreateRecord(uint32_t nparams) +{ + warnx("FIXME: MsiCreateRecord(%u)", (unsigned)nparams); + return (void *)3; +} + +uint32_t MsiRecordSetStringW(void *handle, uint32_t field, char16_t *value) +{ + warnx("FIXME: MsiRecordSetString(%p,%u,%s)", handle, (unsigned)field, + ascii(value, false)); + return 0; +} + +uint32_t MsiRecordSetStreamW(void *handle, uint32_t field, char16_t *path) +{ + warnx("FIXME: MsiRecordSetStream(%p,%u,%s)", handle, (unsigned)field, + ascii(path, true)); + return 0; +} + +uint32_t MsiViewModify(void *vhandle, uint32_t mode, void *rechandle) +{ + warnx("FIXME: MsiViewModify(%p,%u,%p)", + vhandle, (unsigned)mode, rechandle); + return 0; +} + +uint32_t MsiDatabaseCommit(void *handle) +{ + warnx("FIXME: MsiDatabaseCommit(%p)", handle); + return 0; } diff --git a/fake-winterop.c b/fake-winterop.c index 828b8fa..ae4b8ef 100644 --- a/fake-winterop.c +++ b/fake-winterop.c @@ -86,15 +86,17 @@ uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir, uint32_t dwMaxThresh, int compression, void **out_ctx) { - fprintf(stderr, "CreateCabBegin(\"%s\", \"%s\", ...)!\n", + fprintf(stderr, "CreateCabBegin(\"%s\", \"%s\", ...)\n", ascii(wzCab, true), ascii(wzCabDir, true)); + *out_ctx = (void *)10; return 0; } uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken, void *pmfHash, void *ctx) { - fprintf(stderr, "CreateCabAddFile!\n"); + fprintf(stderr, "CreateCabAddFile(%p,%s,%s)\n", ctx, + ascii(wzFile, true), ascii(wzToken, false)); return 0; } -- cgit v1.2.3-55-g6feb