Subversion Repositories Kolibri OS

Rev

Rev 7867 | Rev 7869 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7867 Rev 7868
Line 1... Line 1...
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include 
4
#include 
5
#include 
5
#include 
6
#include 
-
 
Line 7... Line 6...
7
 
6
 
8
typedef struct {
7
typedef struct {
9
    size_t length;
8
    size_t length;
10
    size_t capacity;
9
    size_t capacity;
Line 52... Line 51...
52
static void mkdir(const char *name) {
51
static void mkdir(const char *name) {
53
    struct {
52
    struct {
54
        int fn;
53
        int fn;
55
        int unused[4];
54
        int unused[4];
56
        char b;
55
        char b;
57
        const char *path __attribute__((packed));
56
        const char *path;
58
    } info;
57
    } __attribute__((packed)) info;
59
    memset(&info, 0, sizeof(info));
58
    memset(&info, 0, sizeof(info));
60
    info.fn = 9;
59
    info.fn = 9;
61
    info.b = 0;
60
    info.b = 0;
62
    info.path = name;
61
    info.path = name;
63
    asm volatile ("int $0x40"::"a"(70), "b"(&info));
62
    asm volatile ("int $0x40"::"a"(70), "b"(&info));
Line 327... Line 326...
327
    this->sectorsPerFat = *(uint16_t *)((uintptr_t)this->image + 0x16);
326
    this->sectorsPerFat = *(uint16_t *)((uintptr_t)this->image + 0x16);
328
    this->firstFat = (0 + this->reservedSectorCount) * this->bytesPerSector;
327
    this->firstFat = (0 + this->reservedSectorCount) * this->bytesPerSector;
329
    this->rootDirectory = this->firstFat + this->numberOfFats 
328
    this->rootDirectory = this->firstFat + this->numberOfFats 
330
        * this->sectorsPerFat * this->bytesPerSector;
329
        * this->sectorsPerFat * this->bytesPerSector;
331
    this->dataRegion = this->rootDirectory + this->maxRootEntries * 32;
330
    this->dataRegion = this->rootDirectory + this->maxRootEntries * 32;
332
    con_printf("\nBytes per sector: %d\n",      this->bytesPerSector);
331
    printf("\nBytes per sector: %d\n",    this->bytesPerSector);
333
    con_printf("Sectors per claster: %d\n",   this->sectorsPerClaster);
332
    printf("Sectors per claster: %d\n",   this->sectorsPerClaster);
334
    con_printf("Reserver sector count: %d\n", this->reservedSectorCount);
333
    printf("Reserver sector count: %d\n", this->reservedSectorCount);
335
    con_printf("Number of FATs: %d\n",        this->numberOfFats);
334
    printf("Number of FATs: %d\n",        this->numberOfFats);
336
    con_printf("Max root entries: %d\n",      this->maxRootEntries);
335
    printf("Max root entries: %d\n",      this->maxRootEntries);
337
    con_printf("Total sectors: %d\n",         this->totalSectors);
336
    printf("Total sectors: %d\n",         this->totalSectors);
338
    con_printf("Sectors per FAT: %d\n",       this->sectorsPerFat);
337
    printf("Sectors per FAT: %d\n",       this->sectorsPerFat);
339
    con_printf("First FAT: %d\n",             this->firstFat);
338
    printf("First FAT: %d\n",             this->firstFat);
340
    con_printf("Root directory: %d\n",        this->rootDirectory);
339
    printf("Root directory: %d\n",        this->rootDirectory);
341
    con_printf("Data region: %d\n\n",           this->dataRegion);
340
    printf("Data region: %d\n\n",         this->dataRegion);
342
    return 1;
341
    return 1;
343
}
342
}
Line 344... Line 343...
344
 
343
 
345
static int fat12__error(Fat12 *this, const char *errorMessage) {
344
static int fat12__error(Fat12 *this, const char *errorMessage) {
346
    this->errorMessage = errorMessage;
345
    this->errorMessage = errorMessage;
347
    return 0;
346
    return 0;
Line 348... Line 347...
348
}
347
}
349
 
348
 
350
static int handleError(const Fat12 *fat12) {
-
 
351
    con_printf("Error in Fat12: %s\n", fat12->errorMessage);
349
static int handleError(const Fat12 *fat12) {
352
    con_exit(0);
350
    printf("Error in Fat12: %s\n", fat12->errorMessage);
Line -... Line 351...
-
 
351
    return -1;
-
 
352
}
-
 
353
 
-
 
354
void writeFile(const char *fileName, int size, const uint8_t *data) {
-
 
355
//    FILE *fp = NULL;
-
 
356
//    if (!(fp = fopen(fileName, "wb"))) { perror(NULL); }
-
 
357
//    fwrite(data, 1, size, fp);
-
 
358
//    fclose(fp);
-
 
359
    struct Info {
-
 
360
        int number;
-
 
361
        int reserved0;
-
 
362
        int reserved1;
-
 
363
        int dataSize;
-
 
364
        const void *data;
-
 
365
        char zero;
-
 
366
        const char *name;
-
 
367
    } __attribute__((packed)) *info = calloc(sizeof(struct Info), 1);
-
 
368
    
-
 
369
    info->number = 2; // create/overwrite file
-
 
370
    info->dataSize = size;
-
 
371
    info->data = data;
-
 
372
    info->zero = 0;
-
 
373
    info->name = fileName;
353
    return -1;
374
    asm volatile ("int $0x40" :: "a"(70), "b"(info));
354
}
-
 
355
 
375
}
Line 356... Line 376...
356
static int callback(const char *name, size_t size, const uint8_t *data, void *param) {
376
 
357
    FILE *fp = NULL;
377
static int callback(const char *name, size_t size, const uint8_t *data, void *param) {
358
    String *outputPath = param;
378
    String *outputPath = param;
Line 371... Line 391...
371
            *fileNameDelim = '\0';
391
            *fileNameDelim = '\0';
372
            mkdir_p(outputPath->data);
392
            mkdir_p(outputPath->data);
373
            *fileNameDelim = '/';
393
            *fileNameDelim = '/';
374
        }
394
        }
375
    }
395
    }
376
    con_printf("Extracting %s\n", outputPath->data);
396
    printf("Extracting %s\n", outputPath->data);
377
    if (!(fp = fopen(outputPath->data, "wb"))) { perror(NULL); }
-
 
378
    fwrite(data, 1, size, fp);
397
    writeFile(outputPath->data, size, data);
379
    fclose(fp);
-
 
380
    outputPath->data[outputPath->length] = '\0';
398
    outputPath->data[outputPath->length] = '\0';
381
    return 0;
399
    return 0;
382
}
400
}
Line 383... Line 401...
383
 
401
 
384
 
402
 
385
 
403
 
386
int main(int argc, char **argv) {
404
int main(int argc, char **argv) {
387
    Fat12 fat12 = { 0 };
-
 
388
    char *imageFile = NULL;
-
 
389
    String outputFolder = { 0 };
-
 
390
    int exit = 0;
-
 
Line 391... Line 405...
391
 
405
    Fat12 fat12 = { 0 };
392
	char app_title[] = "UnImg - kolibri.img file unpacker";
406
    char *imageFile = NULL;
393
	if (con_init_console_dll_param(-1, -1, -1, 350, app_title)) return -1;
407
    String outputFolder = { 0 };
394
 
-
 
395
    if (argc < 2) { 
-
 
396
        con_write_asciiz(" Usage:\n");
408
 
397
        con_write_asciiz(" unimg \"/path/to/kolibri.img\" \"/optional/extract/path\" [-e]\n");
409
    if (argc < 2) { 
398
        con_write_asciiz("        where optional key [-e] is exit on success");
410
        puts(" Usage:\n");
399
        con_exit(0);
411
        puts(" unimg \"/path/to/kolibri.img\" \"/optional/extract/path\"\n");
400
        return -1;
412
        return -1;
Line 401... Line 413...
401
    } else {
413
    } else {
402
    	imageFile = argv[1];
414
    	imageFile = argv[1];
Line 414... Line 426...
414
    	strcat(outputFolder.data, strrchr(imageFile, '/'));
426
    	strcat(outputFolder.data, strrchr(imageFile, '/'));
415
    }
427
    }
Line 416... Line 428...
416
 
428
 
Line 417... Line -...
417
    outputFolder.length = strlen(outputFolder.data);
-
 
418
 
-
 
419
    // handle -e parameter - exit on success
-
 
420
    if (argc >= 3 && !strcmp(argv[argc - 1], "-e")) { exit = 1; }
429
    outputFolder.length = strlen(outputFolder.data);
421
 
430
 
422
    if (!fat12__open(&fat12, imageFile)) { 
431
    if (!fat12__open(&fat12, imageFile)) { 
Line 423... Line 432...
423
        return handleError(&fat12); 
432
        return handleError(&fat12); 
424
    }
433
    }
425
 
434
 
Line 426... Line 435...
426
    if (!fat12__forEachFile(&fat12, callback, &outputFolder)) {
435
    if (!fat12__forEachFile(&fat12, callback, &outputFolder)) {
427
        return handleError(&fat12);
-
 
428
    }
436
        return handleError(&fat12);