⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.c

📁 WiiFuse is a FUSE filesystem module for Linux and Mac OS X. It will let you mount a Wii disc ISO an
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2008 dhewg, #wiidev efnet *    based on code by: *  Copyright (C) 2006 Mike Melanson (mike at multimedia.cx) * *  some functions are taken from *  http://git.infradead.org/?p=users/segher/wii.git *  Copyright 2007,2008  Segher Boessenkool  <segher@kernel.crashing.org> *  21:14:49 <@segher> i'll happily grant you to license the whole as v3, btw * *  this file is part of wiifuse *  http://wiibrew.org/index.php?title=Wiifuse * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <sys/types.h>#include "global.h"#include "io.h"#include "tree.h"#include "metadata.h"#include "image.h"u8 image_parse_header (struct part_header *header, u8 *buffer) {        memset (header, 0, sizeof (struct part_header));        header->console = buffer[0];        header->is_gc = (header->console == 'G') ||                        (header->console == 'D') ||                        (header->console == 'P') ||                        (header->console == 'U');        header->is_wii = (header->console == 'R') ||                         (header->console == '_') ||                         (header->console == 'H') ||                         (header->console == '0') ||                         (header->console == '4');        header->gamecode[0] = buffer[1];        header->gamecode[1] = buffer[2];        header->region = buffer[3];        header->publisher[0] = buffer[4];        header->publisher[1] = buffer[5];        header->has_magic = get_be32 (&buffer[0x18]) == 0x5d1c9ea3;        strncpy (header->name, (char *) (&buffer[0x20]), 0x60);        header->dol_offset = get_be32 (&buffer[0x420]);        header->fst_offset = get_be32 (&buffer[0x424]);        header->fst_size = get_be32 (&buffer[0x428]);        if (header->is_wii) {                header->dol_offset *= 4llu;                header->fst_offset *= 4llu;                header->fst_size *= 4llu;        }        return header->is_gc || header->is_wii;}u32 parse_fst (u8 *fst, const char *names, u32 i, struct tree *tree,               struct image_file *image, u32 part) {        u64 offset;        u32 size;        const char *name;        u32 j;        struct tree *node;        name = names + (get_be32 (fst + 12 * i) & 0x00ffffff);        size = get_be32 (fst + 12 * i + 8);        if (i == 0) {                for (j = 1; j < size; )                        j = parse_fst (fst, names, j, tree, image, part);                return size;        }        if (fst[12 * i]) {                LOG (3, "  fst dir: %s", name);                node = tree_add_dir (part, tree, name);                for (j = i + 1; j < size; )                        j = parse_fst (fst, names, j, node, image, part);                return size;        } else {                offset = get_be32(fst + 12 * i + 4);                if (image->parts[part].header.is_wii)                        offset *= 4llu;                LOG (3, "    fst file: %s offset: 0x%016llx size: 0x%08x",                     name, offset, size);                tree_add_file (part, tree, name, offset, size);                image->nfiles++;                image->nbytes += size;                return i + 1;        }}u8 get_partitions (struct image_file *image) {        u8 buffer[16];        u64 part_tbl_offset;        u64 chan_tbl_offset;        u32 i;        u8 title_key[16];        u8 iv[16];        u8 partition_key[16];        u32 nchans;        io_read (buffer, 16, image, 0x40000);        image->nparts = 1 + get_be32 (buffer);        nchans = get_be32 (&buffer[8]);        LOG (1, "number of partitions: %u", image->nparts);        LOG (1, "number of channels: %u", nchans);        image->nparts += nchans;        if (image->nparts == 1)                return 0;        part_tbl_offset = get_be32 (&buffer[4]) * 4ull;        chan_tbl_offset = get_be32 (&buffer[12]) * 4ull;        LOG (1, "partition table offset: 0x%016llx", part_tbl_offset);        LOG (1, "channel table offset: 0x%016llx", chan_tbl_offset);        image->parts = (struct partition *)                        malloc (image->nparts * sizeof (struct partition));        memset (image->parts, 0, image->nparts * sizeof (struct partition));        for (i = 1; i < image->nparts; ++i) {                LOG (1, "found partition: %u", i);                if (i < image->nparts - nchans) {                        io_read (buffer, 8, image,                                 part_tbl_offset + (i - 1) * 8);                        switch (get_be32 (&buffer[4])) {                        case 0:                                image->parts[i].type = PART_DATA;                                break;                        case 1:                                image->parts[i].type = PART_UPDATE;                                break;                        case 2:                                image->parts[i].type = PART_INSTALLER;                                break;                        default:                                break;                        }                } else {                        io_read (buffer, 8, image,                                 chan_tbl_offset + (i - 3) * 8);                        image->parts[i].type = PART_VC;                        image->parts[i].chan_id[0] = buffer[4];                        image->parts[i].chan_id[1] = buffer[5];                        image->parts[i].chan_id[2] = buffer[6];                        image->parts[i].chan_id[3] = buffer[7];                }                image->parts[i].offset = get_be32 (buffer) * 4ull;                LOG (1, "partition offset: 0x%016llx", image->parts[i].offset);                tmd_load (image, i);                if (image->parts[i].tmd == NULL) {                        LOG_ERR ("partition %u has no valid tmd", i);                        continue;                }                sprintf (image->parts[i].title_id_str, "%016llx",                         image->parts[i].tmd->title_id);                image->parts[i].is_encrypted = 1;                image->parts[i].cached_block = 0xffffffff;                memset (title_key, 0, 16);                memset (iv, 0, 16);                io_read (title_key, 16, image, image->parts[i].offset + 0x1bf);                io_read (iv, 8, image, image->parts[i].offset + 0x1dc);                AES_cbc_encrypt (title_key, partition_key, 16,                                 &image->key, iv, 0);                AES_set_decrypt_key (partition_key, 128, &image->parts[i].key);                sprintf (image->parts[i].key_c, "0x"                         "%02x%02x%02x%02x%02x%02x%02x%02x"                         "%02x%02x%02x%02x%02x%02x%02x%02x",                          partition_key[0], partition_key[1],                          partition_key[2], partition_key[3],                          partition_key[4], partition_key[5],                          partition_key[6], partition_key[7],                          partition_key[8], partition_key[9],                          partition_key[10], partition_key[11],                          partition_key[12], partition_key[13],                          partition_key[14], partition_key[15]);                io_read (buffer, 8, image, image->parts[i].offset + 0x2b8);                image->parts[i].data_offset = get_be32 (buffer) * 4ull;                image->parts[i].data_size = get_be32 (&buffer[4]) * 4ull;                LOG (1, "partition data offset: 0x%016llx",                     image->parts[i].data_offset);                LOG (1, "partition data size: 0x%016llx",                     image->parts[i].data_size);        }        return image->nparts == 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -