Build cab files using lcab.
This commit is contained in:
parent
d6e5f7ae7b
commit
b19fd4ee77
5 changed files with 94 additions and 102 deletions
|
@ -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
|
||||
|
|
51
fake-lib.c
51
fake-lib.c
|
@ -11,7 +11,9 @@
|
|||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
9
fake-lib.h
Normal file
9
fake-lib.h
Normal file
|
@ -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)
|
27
fake-msi.c
27
fake-msi.c
|
@ -9,32 +9,7 @@
|
|||
|
||||
#include <fcntl.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 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,
|
||||
|
|
105
fake-winterop.c
105
fake-winterop.c
|
@ -11,63 +11,7 @@
|
|||
#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");
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue