wix-on-linux/fake-winterop.c
Simon Tatham abd0e801c0 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.
2017-02-16 20:33:01 +00:00

153 lines
3.7 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>
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)
{
}