Initial Commit
[Projects.git] / pkgbuilds / wiifuse / src / wiifuse-0.2.0 / io.c
blob29e99c4ac009b5e8480abf597153029615b5a7c9
1 /*
2 * Copyright (C) 2008 dhewg, #wiidev efnet
4 * this file is part of wiifuse
5 * http://wiibrew.org/index.php?title=Wiifuse
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdio.h>
24 #include "io.h"
26 int io_read (void *ptr, size_t size, struct image_file *image, u64 offset) {
27 size_t bytes;
29 if (fseeko (image->fp, offset, SEEK_SET)) {
30 perror ("io_seek");
31 return -1;
34 bytes = fread (ptr, 1, size, image->fp);
36 if (bytes != size)
37 perror ("io_read");
39 return bytes;
42 int decrypt_block (struct image_file *image, u32 part, u32 block) {
43 if (block == image->parts[part].cached_block)
44 return 0;
46 LOG (3, "decrypting part/block %u/%08x", part, block);
48 if (io_read (image->parts[part].dec_buffer, 0x8000, image,
49 image->parts[part].offset +
50 image->parts[part].data_offset + 0x8000ull * block)
51 != 0x8000) {
52 perror ("decrypt read");
53 return -1;
56 AES_cbc_encrypt (&image->parts[part].dec_buffer[0x400],
57 image->parts[part].cache, 0x7c00,
58 &image->parts[part].key,
59 &image->parts[part].dec_buffer[0x3d0], 0);
61 image->parts[part].cached_block = block;
63 return 0;
66 size_t io_read_part (void *ptr, size_t size, struct image_file *image,
67 u32 part, u64 offset) {
68 u32 block = offset / 0x7c00;
69 u32 cache_offset = offset % 0x7c00;
70 u32 cache_size;
71 void *dst = ptr;
73 if (!image->parts[part].is_encrypted)
74 return io_read (ptr, size, image,
75 image->parts[part].offset + offset);
77 while (size) {
78 if (decrypt_block (image, part, block))
79 return dst - ptr;
81 cache_size = size;
82 if (cache_size + cache_offset > 0x7c00)
83 cache_size = 0x7c00 - cache_offset;
85 memcpy (dst, image->parts[part].cache + cache_offset,
86 cache_size);
87 dst += cache_size;
88 size -= cache_size;
89 cache_offset = 0;
91 block++;
94 return dst - ptr;