wix-on-linux/fake-winterop.c
Simon Tatham 0985b382d3 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.
2017-05-15 21:00:12 +01:00

134 lines
3.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <uchar.h>
#include <err.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "fake-lib.h"
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;
}
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,
uint32_t dwMaxFiles, uint32_t dwMaxSize,
uint32_t dwMaxThresh, int compression,
CabCreateContext **out_ctx)
{
CabCreateContext *ctx = snew(CabCreateContext);
ctx->outdir = ascii(wzCabDir, true);
ctx->outfile = dupcat(ctx->outdir, "/",
ascii(wzCab, true), (const char *)NULL);
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;
}
uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken,
void *pmfHash, CabCreateContext *ctx)
{
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 <- %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;
}
uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles,
const char16_t *const *pwzTokens,
void *pmfHash, uint32_t cFiles,
CabCreateContext *ctx)
{
for (uint32_t i = 0; i < cFiles; i++)
CreateCabAddFile(pwzFiles[i], pwzTokens[i], pmfHash, ctx);
return 0;
}
uint32_t CreateCabFinish(CabCreateContext *ctx, void (*split_callback)(void))
{
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;
}
void CreateCabCancel(void *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: pfnNotify looks like a fn ptr again */
fprintf(stderr, "EnumerateCab!\n");
return 0;
}
void EnumerateCabFinish(void)
{
}