#include #include #include "memory.h" #include "dupstr.h" #include "subproc.h" #include "uchars.h" typedef struct CabCreateContext { char *outfile; /* aliases one of args[] */ 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); char *outdir = ascii(wzCabDir, true); char *cab = ascii(wzCab, true); ctx->outfile = dupcat(outdir, "/", cab, cNULL); sfree(cab); sfree(outdir); ctx->nargs = 0; ctx->argsize = 16; ctx->args = snewn(ctx->argsize, char *); ctx->args[ctx->nargs++] = dupcat(getenv("WIX"), "/", "makecab.py", cNULL); ctx->args[ctx->nargs++] = ctx->outfile; *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); warnx("CreateCabAddFile: %s :: %s <- %s", ctx->outfile, cabname, file_abs); 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++] = cabname; ctx->args[ctx->nargs++] = file_abs; sfree(file); 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; } void CreateCabCancel(CabCreateContext *ctx) { for (int i = 0; i < ctx->nargs; i++) sfree(ctx->args[i]); sfree(ctx->args); sfree(ctx); } uint32_t CreateCabFinish(CabCreateContext *ctx, void (*split_callback)(void)) { 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++] = NULL; system_argv_array(ctx->args); CreateCabCancel(ctx); /* free everything */ return 0; }