From 0985b382d387f6868240928db1531b22c0915d24 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 15 May 2017 21:00:12 +0100 Subject: [PATCH] Create the cab with the files in the right order. In my test MSI, the files are supposed to be in alphabetical order, not in 'whatever order lcab enumerated the Unix directory I pointed it at' order. The test MSI didn't install, but with this change, it does, so my guess is that either the real Windows installer system depends on the alphabetical order for a search algorithm, or else files in the cab are referred to by a numeric index of some kind. --- fake-winterop.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/fake-winterop.c b/fake-winterop.c index c302f12..eb891c4 100644 --- a/fake-winterop.c +++ b/fake-winterop.c @@ -29,6 +29,9 @@ typedef struct CabCreateContext { char *tempdir; char *outdir; char *outfile; + + char **args; + int nargs, argsize; } CabCreateContext; uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir, @@ -43,6 +46,11 @@ uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir, ctx->tempdir = dupcat(ctx->outdir, "/cabXXXXXX", (const char *)NULL); if (!mkdtemp(ctx->tempdir)) err(1, "mkdtemp"); + ctx->nargs = 0; + ctx->argsize = 16; + ctx->args = snewn(ctx->argsize, char *); + ctx->args[ctx->nargs++] = dupcat("lcab", (const char *)NULL); + ctx->args[ctx->nargs++] = dupcat("-n", (const char *)NULL); *out_ctx = ctx; return 0; } @@ -54,9 +62,15 @@ uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken, 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); + printf("CreateCabAddFile: %s :: %s <- %s\n", ctx->outfile, + cabname, file_abs); if (symlink(file_abs, cab_abs) < 0) err(1, "symlink"); + if (ctx->nargs + 1 >= ctx->argsize) { + ctx->argsize = ctx->nargs * 5 / 4 + 16; + ctx->args = sresize(ctx->args, ctx->argsize, char *); + } + ctx->args[ctx->nargs++] = cab_abs; return 0; } @@ -72,8 +86,13 @@ uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles, uint32_t CreateCabFinish(CabCreateContext *ctx, void (*split_callback)(void)) { - system_argv("lcab", "-r", "-n", ctx->tempdir, ctx->outfile, - (const char *)NULL); + if (ctx->nargs + 2 >= ctx->argsize) { + ctx->argsize = ctx->nargs * 5 / 4 + 16; + ctx->args = sresize(ctx->args, ctx->argsize, char *); + } + ctx->args[ctx->nargs++] = ctx->outfile; + ctx->args[ctx->nargs++] = NULL; + system_argv_array(ctx->args); return 0; }