From abd0e801c055418418120a81de893345c20b5d54 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 16 Feb 2017 20:33:01 +0000 Subject: Fake implementation of winterop.dll. If I compile this to Linux native code, and then run WiX under Mono, it loads this library and gets past the first CabExtract call, so I can find out what the next problem turns out to be. --- fake-winterop.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libwinterop.so.la | 42 +++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 fake-winterop.c create mode 100644 libwinterop.so.la diff --git a/fake-winterop.c b/fake-winterop.c new file mode 100644 index 0000000..828b8fa --- /dev/null +++ b/fake-winterop.c @@ -0,0 +1,153 @@ +#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"); +} + +uint32_t HashPublicKeyInfo(void *pCertContext, + void *rgbSubjectKeyIdentifier, + uint32_t *pcbSubjectKeyIndentifier) +{ + errx(1, "HashPublicKeyInfo NYI"); +} + +uint32_t ResetAcls(const char16_t **pwzFiles, uint32_t cFiles) +{ + return 0; +} + +uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir, + uint32_t dwMaxFiles, uint32_t dwMaxSize, + uint32_t dwMaxThresh, int compression, + void **out_ctx) +{ + fprintf(stderr, "CreateCabBegin(\"%s\", \"%s\", ...)!\n", + ascii(wzCab, true), ascii(wzCabDir, true)); + return 0; +} + +uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken, + void *pmfHash, void *ctx) +{ + fprintf(stderr, "CreateCabAddFile!\n"); + return 0; +} + +uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles, + const char16_t *const *pwzTokens, + void *pmfHash, uint32_t cFiles, void *hContext) +{ + fprintf(stderr, "CreateCabAddFiles!\n"); + return 0; +} + +uint32_t CreateCabFinish(void *hContext, void *newCabNamesCallBackAddress) +{ + /* FIXME: newCabNamesCallBackAddress is actually a fn ptr of some kind */ + fprintf(stderr, "CabCFinish(%p,%p)!\n", + hContext, newCabNamesCallBackAddress); + return 0; +} + +void CreateCabCancel(void *hContext) +{ + fprintf(stderr, "CabCCancel(%p)!\n", hContext); +} + +uint32_t ExtractCabBegin(void) +{ + return 0; +} + +uint32_t ExtractCab(const char16_t *wzCabinet, const char16_t *wzExtractDir) +{ + char *cab = ascii(wzCabinet, true), *dir = ascii(wzExtractDir, true); + fprintf(stderr, "ExtractCab(\"%s\", \"%s\"\n", cab, dir); + system_argv("cabextract", "-d", dir, cab, (const char *)NULL); + return 0; +} + +void ExtractCabFinish(void) +{ +} + +uint32_t EnumerateCabBegin(void) +{ + return 0; +} + +uint32_t EnumerateCab(const char16_t *wzCabinet, void *pfnNotify) +{ + /* FIXME: fpnNotify looks like a fn ptr again */ + fprintf(stderr, "EnumerateCab!\n"); + return 0; +} + +void EnumerateCabFinish(void) +{ +} diff --git a/libwinterop.so.la b/libwinterop.so.la new file mode 100644 index 0000000..74b9ccc --- /dev/null +++ b/libwinterop.so.la @@ -0,0 +1,42 @@ +# libsane-u12.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.2 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libwinterop.so' + +# Names of this library. +library_names='libwinterop.so' + +# The name of the static archive. +old_library='libwinterop.a' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs='' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libwinterop. +current=1 +age=0 +revision=0 + +# Is this an already installed library? +installed=no + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/lib/x86_64-linux-gnu' + -- cgit v1.2.3-55-g6feb