#include "devil1pld.h" #include #include #include #include bool writedata(const char *basename, unsigned int id, const char *data, unsigned int dsize) { bool status = false; char *fn = (char*)malloc(sizeof(char) * strlen(basename) + 4); sprintf(fn, "%s_%d", basename, id); FILE *out = fopen(fn, "w"); if (out != NULL) { fwrite(data, sizeof(char), dsize, out); fclose(out); status = true; } free(fn); return status; } void unpackpld(const char *buffer, const struct PldHeader *ph, const char *name, unsigned int s) { char *wbuffer = NULL; // write buffer that will change. unsigned int wsize = 0; // size of wbuffer. unsigned int i; unsigned int start = 0; // ending offset for data unsigned int end = 0; // ending offset for data for (i = 0; (i + 1) < (ph -> numOffset) + 1; i++) { printf("start: %x - end: %x\n", ph -> offsets[i], ph -> offsets[i + 1]); start = ph -> offsets[i]; // the last offset still has some data until the end of file end = (i == (ph -> numOffset) - 1) ? s : ph -> offsets[i + 1]; // copy sector to write buffer wsize = end - start; printf("end is %x - i is %d - wsize is %x\n", end, i, wsize); wbuffer = (char*)malloc(sizeof(char) * wsize); memcpy(wbuffer, buffer + start, wsize); // create a file. writedata(name, i, wbuffer, wsize); } free(wbuffer); } void show_pldheader(struct PldHeader *x) { printf("number of offsets = %i\n", x -> numOffset); unsigned int i; for (i = 0; i < x -> numOffset; i++) { printf("offset %i = %x\n", i, x -> offsets[i]); } } struct PldHeader *read_pldheader(const char *buffer) { if (buffer == NULL) { return NULL; } int32_t *n = (int32_t*)buffer; struct PldHeader *ph = (struct PldHeader*)malloc( sizeof(struct PldHeader) ); uint32_t size_offsets = sizeof(uint32_t) * n[0]; ph -> offsets = (uint32_t*)malloc(size_offsets); if (ph -> offsets == NULL) { perror("Error 4: "); free(ph); free(ph -> offsets); return NULL; } // set data of struct. ph -> numOffset = n[0]; memcpy(ph -> offsets, buffer + sizeof(int32_t), size_offsets); return ph; } char *readpld(const char *fname, unsigned int *s) { FILE *f = fopen(fname, "rb"); unsigned int size = 0; // number of elements to buffer; unsigned int rcnt = 0; // number of char's read by fread(...) if (f == NULL) { perror("Error 1: "); return NULL; } // this method of determining file size doesn't work until 2 GB. fseek(f, 0, SEEK_END); size = ftell(f); rewind(f); char *buf = (char*)malloc(sizeof(char) * size); if (buf == NULL) { perror("Error 2: "); free(buf); return NULL; } rcnt = fread(buf, sizeof(char), size, f); if (rcnt < size) { perror("Error 3: "); free(buf); return NULL; } fclose(f); *s = rcnt; return buf; } int main(int argc, char ** argv) { char *filename = argv[1]; unsigned int fsize = 0; char *filedata = readpld(filename, &fsize); printf("fsize is %i\n", fsize); if (filedata != NULL && fsize != 0) { struct PldHeader *pldh = read_pldheader(filedata); unpackpld(filedata, pldh, filename, fsize); free(pldh -> offsets); free(pldh); } free(filedata); return 0; }