From b19fd4ee7798a4948f5f47fafd89d67576a4642a Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 15 May 2017 19:19:10 +0100 Subject: Build cab files using lcab. --- Makefile.wixfakelibs | 4 +- fake-lib.c | 51 ++++++++++++++++++++++++- fake-lib.h | 9 +++++ fake-msi.c | 27 +------------ fake-winterop.c | 105 ++++++++++++++++----------------------------------- 5 files changed, 94 insertions(+), 102 deletions(-) create mode 100644 fake-lib.h diff --git a/Makefile.wixfakelibs b/Makefile.wixfakelibs index 7a3b8ef..f53c539 100644 --- a/Makefile.wixfakelibs +++ b/Makefile.wixfakelibs @@ -10,9 +10,9 @@ all: libwinterop.so.la libmsi.so.la %.lo: %.c libtool --mode=compile gcc -c $^ -libwinterop.so.la: fake-winterop.lo +libwinterop.so.la: fake-winterop.lo fake-lib.lo -libmsi.so.la: fake-msi.lo +libmsi.so.la: fake-msi.lo fake-lib.lo clean: rm -rf .libs diff --git a/fake-lib.c b/fake-lib.c index f8dbea4..9255005 100644 --- a/fake-lib.c +++ b/fake-lib.c @@ -11,7 +11,9 @@ #include #include -static char *ascii(const char16_t *wstr, bool translate_slashes) +#include "fake-lib.h" + +char *ascii(const char16_t *wstr, bool translate_slashes) { size_t len = 0; for (const char16_t *wp = wstr; *wp; wp++) @@ -26,7 +28,7 @@ static char *ascii(const char16_t *wstr, bool translate_slashes) return ret; } -static void system_argv(const char *cmd, ...) +void system_argv(const char *cmd, ...) { int nargs, nchars; const char *word; @@ -68,3 +70,48 @@ static void system_argv(const char *cmd, ...) if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) errx(1, "subcommand failed"); } + +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; +} + +void *smalloc(size_t size) +{ + void *toret = malloc(size); + if (!toret) + errx(1, "out of memory"); + return toret; +} + +char *dupcat(const char *str, ...) +{ + va_list ap; + const char *p; + char *out, *outp; + size_t len; + + len = 1; + va_start(ap, str); + for (p = str; p; p = va_arg(ap, const char *)) + len += strlen(p); + va_end(ap); + + out = snewn(len, char); + outp = out; + va_start(ap, str); + for (p = str; p; p = va_arg(ap, const char *)) { + strcpy(outp, p); + outp += strlen(p); + } + va_end(ap); + + return out; +} diff --git a/fake-lib.h b/fake-lib.h new file mode 100644 index 0000000..65fed63 --- /dev/null +++ b/fake-lib.h @@ -0,0 +1,9 @@ +char *ascii(const char16_t *wstr, bool translate_slashes); +void system_argv(const char *cmd, ...); +void c16cpy(char16_t *out, uint32_t *outsize, char *s); +void *smalloc(size_t size); +char *dupcat(const char *str, ...); + +#define snew(type) ((type *)smalloc(sizeof(type))) +#define snewn(n,type) ((type *)smalloc((n)*sizeof(type))) +#define sfree(ptr) free(ptr) diff --git a/fake-msi.c b/fake-msi.c index 3bf1475..59e0a4b 100644 --- a/fake-msi.c +++ b/fake-msi.c @@ -9,32 +9,7 @@ #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; -} +#include "fake-lib.h" uint32_t MsiGetFileVersionW(const char16_t *filename, char16_t *version, uint32_t *version_size, diff --git a/fake-winterop.c b/fake-winterop.c index ae4b8ef..d792553 100644 --- a/fake-winterop.c +++ b/fake-winterop.c @@ -11,63 +11,7 @@ #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"); -} +#include "fake-lib.h" uint32_t HashPublicKeyInfo(void *pCertContext, void *rgbSubjectKeyIdentifier, @@ -81,44 +25,61 @@ uint32_t ResetAcls(const char16_t **pwzFiles, uint32_t cFiles) return 0; } +typedef struct CabCreateContext { + char *tempdir; + char *outdir; + char *outfile; +} CabCreateContext; + 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) + CabCreateContext **out_ctx) { - fprintf(stderr, "CreateCabBegin(\"%s\", \"%s\", ...)\n", - ascii(wzCab, true), ascii(wzCabDir, true)); - *out_ctx = (void *)10; + CabCreateContext *ctx = snew(CabCreateContext); + ctx->outdir = ascii(wzCabDir, true); + ctx->outfile = dupcat(ctx->outdir, "/", + ascii(wzCab, true), (const char *)NULL); + ctx->tempdir = snewn(20 + strlen(ctx->outdir), char); + sprintf(ctx->tempdir, "%s/cabXXXXXX", ctx->outdir); + if (!mkdtemp(ctx->tempdir)) + err(1, "mkdtemp"); + *out_ctx = ctx; return 0; } uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken, - void *pmfHash, void *ctx) + void *pmfHash, CabCreateContext *ctx) { - fprintf(stderr, "CreateCabAddFile(%p,%s,%s)\n", ctx, - ascii(wzFile, true), ascii(wzToken, false)); + char *file = ascii(wzFile, true); + char *file_abs = realpath(file, NULL); + char *cabname = ascii(wzToken, true); + char *cab_abs = dupcat(ctx->tempdir, "/", cabname, (const char *)NULL); + printf("CreateCabAddFile: %s <- %s\n", ctx->outfile, file_abs); + if (symlink(file_abs, cab_abs) < 0) + err(1, "symlink"); return 0; } uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles, const char16_t *const *pwzTokens, - void *pmfHash, uint32_t cFiles, void *hContext) + void *pmfHash, uint32_t cFiles, + CabCreateContext *ctx) { - fprintf(stderr, "CreateCabAddFiles!\n"); + for (uint32_t i = 0; i < cFiles; i++) + CreateCabAddFile(pwzFiles[i], pwzTokens[i], pmfHash, ctx); return 0; } -uint32_t CreateCabFinish(void *hContext, void *newCabNamesCallBackAddress) +uint32_t CreateCabFinish(CabCreateContext *ctx, void (*split_callback)(void)) { - /* FIXME: newCabNamesCallBackAddress is actually a fn ptr of some kind */ - fprintf(stderr, "CabCFinish(%p,%p)!\n", - hContext, newCabNamesCallBackAddress); + system_argv("lcab", "-r", "-n", ctx->tempdir, ctx->outfile, + (const char *)NULL); return 0; } void CreateCabCancel(void *hContext) { - fprintf(stderr, "CabCCancel(%p)!\n", hContext); } uint32_t ExtractCabBegin(void) @@ -145,7 +106,7 @@ uint32_t EnumerateCabBegin(void) uint32_t EnumerateCab(const char16_t *wzCabinet, void *pfnNotify) { - /* FIXME: fpnNotify looks like a fn ptr again */ + /* FIXME: pfnNotify looks like a fn ptr again */ fprintf(stderr, "EnumerateCab!\n"); return 0; } -- cgit v1.2.3-55-g6feb