mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Initial megacommit.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
143
Source/Core/DiscIO/Src/AES/aes.h
Normal file
143
Source/Core/DiscIO/Src/AES/aes.h
Normal file
@ -0,0 +1,143 @@
|
||||
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_AES_H
|
||||
#define HEADER_AES_H
|
||||
|
||||
// #include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_NO_AES
|
||||
#error AES is disabled.
|
||||
#endif
|
||||
|
||||
#define AES_ENCRYPT 1
|
||||
#define AES_DECRYPT 0
|
||||
|
||||
/* Because array size can't be a const in C, the following two are macros.
|
||||
Both sizes are in bytes. */
|
||||
#define AES_MAXNR 14
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This should be a hidden type, but EVP requires that the size be known */
|
||||
struct aes_key_st
|
||||
{
|
||||
#ifdef AES_LONG
|
||||
unsigned long rd_key[4 * (AES_MAXNR + 1)];
|
||||
#else
|
||||
unsigned int rd_key[4 * (AES_MAXNR + 1)];
|
||||
#endif
|
||||
int rounds;
|
||||
};
|
||||
typedef struct aes_key_st AES_KEY;
|
||||
|
||||
const char* AES_options(void);
|
||||
|
||||
int AES_set_encrypt_key(const unsigned char* userKey, const int bits,
|
||||
AES_KEY* key);
|
||||
int AES_set_decrypt_key(const unsigned char* userKey, const int bits,
|
||||
AES_KEY* key);
|
||||
|
||||
void AES_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const AES_KEY* key);
|
||||
void AES_decrypt(const unsigned char* in, unsigned char* out,
|
||||
const AES_KEY* key);
|
||||
|
||||
void AES_ecb_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const AES_KEY* key, const int enc);
|
||||
void AES_cbc_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
unsigned char* ivec, const int enc);
|
||||
void AES_cfb128_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
unsigned char* ivec, int* num, const int enc);
|
||||
void AES_cfb1_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
unsigned char* ivec, int* num, const int enc);
|
||||
void AES_cfb8_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
unsigned char* ivec, int* num, const int enc);
|
||||
void AES_cfbr_encrypt_block(const unsigned char* in, unsigned char* out,
|
||||
const int nbits, const AES_KEY* key,
|
||||
unsigned char* ivec, const int enc);
|
||||
void AES_ofb128_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
unsigned char* ivec, int* num);
|
||||
|
||||
|
||||
void AES_ctr128_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY * key,
|
||||
unsigned char ivec[AES_BLOCK_SIZE],
|
||||
unsigned char ecount_buf[AES_BLOCK_SIZE],
|
||||
unsigned int* num);
|
||||
|
||||
/* For IGE, see also http://www.links.org/files/openssl-ige.pdf
|
||||
NB: the IV is _two_ blocks long */
|
||||
void AES_ige_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
unsigned char* ivec, const int enc);
|
||||
|
||||
|
||||
/* NB: the IV is _four_ blocks long */
|
||||
void AES_bi_ige_encrypt(const unsigned char* in, unsigned char* out,
|
||||
const unsigned long length, const AES_KEY* key,
|
||||
const AES_KEY* key2, const unsigned char* ivec,
|
||||
const int enc);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !HEADER_AES_H */
|
131
Source/Core/DiscIO/Src/AES/aes_cbc.c
Normal file
131
Source/Core/DiscIO/Src/AES/aes_cbc.c
Normal file
@ -0,0 +1,131 @@
|
||||
/* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#include "aes.h"
|
||||
#include "aes_locl.h"
|
||||
|
||||
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const unsigned long length, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc) {
|
||||
|
||||
unsigned long n;
|
||||
unsigned long len = length;
|
||||
unsigned char tmp[AES_BLOCK_SIZE];
|
||||
const unsigned char *iv = ivec;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
|
||||
|
||||
if (AES_ENCRYPT == enc) {
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
for(n=0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
AES_encrypt(out, out, key);
|
||||
iv = out;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (len) {
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
for(n=len; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = iv[n];
|
||||
AES_encrypt(out, out, key);
|
||||
iv = out;
|
||||
}
|
||||
memcpy(ivec,iv,AES_BLOCK_SIZE);
|
||||
} else if (in != out) {
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
AES_decrypt(in, out, key);
|
||||
for(n=0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv[n];
|
||||
iv = in;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (len) {
|
||||
AES_decrypt(in,tmp,key);
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] = tmp[n] ^ iv[n];
|
||||
iv = in;
|
||||
}
|
||||
memcpy(ivec,iv,AES_BLOCK_SIZE);
|
||||
} else {
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
AES_decrypt(in, out, key);
|
||||
for(n=0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= ivec[n];
|
||||
memcpy(ivec, tmp, AES_BLOCK_SIZE);
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (len) {
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
AES_decrypt(tmp, out, key);
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] ^= ivec[n];
|
||||
for(n=len; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = tmp[n];
|
||||
memcpy(ivec, tmp, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
1159
Source/Core/DiscIO/Src/AES/aes_core.c
Normal file
1159
Source/Core/DiscIO/Src/AES/aes_core.c
Normal file
File diff suppressed because it is too large
Load Diff
88
Source/Core/DiscIO/Src/AES/aes_locl.h
Normal file
88
Source/Core/DiscIO/Src/AES/aes_locl.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_AES_LOCL_H
|
||||
#define HEADER_AES_LOCL_H
|
||||
|
||||
|
||||
#ifdef OPENSSL_NO_AES
|
||||
#error AES is disabled.
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined (_MSC_VER) && (defined (_M_IX86) || defined (_M_AMD64) || defined (_M_X64))
|
||||
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
|
||||
# define GETU32(p) SWAP(*((u32*)(p)))
|
||||
# define PUTU32(ct, st) {*((u32*)(ct)) = SWAP((st));}
|
||||
#else
|
||||
# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
|
||||
# define PUTU32(ct, st) {(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st);}
|
||||
#endif
|
||||
|
||||
#ifdef AES_LONG
|
||||
typedef unsigned long u32;
|
||||
#else
|
||||
typedef unsigned int u32;
|
||||
#endif
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
||||
#define MAXKC (256 / 32)
|
||||
#define MAXKB (256 / 8)
|
||||
#define MAXNR 14
|
||||
|
||||
/* This controls loop-unrolling in aes_core.c */
|
||||
#undef FULL_UNROLL
|
||||
|
||||
#endif /* !HEADER_AES_LOCL_H */
|
102
Source/Core/DiscIO/Src/BannerLoader.cpp
Normal file
102
Source/Core/DiscIO/Src/BannerLoader.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "BannerLoader.h"
|
||||
#include "BannerLoaderWii.h"
|
||||
#include "BannerLoaderGC.h"
|
||||
|
||||
#include "VolumeCreator.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
bool IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src)
|
||||
{
|
||||
static bool bValidChars[256];
|
||||
static bool bInitialized = false;
|
||||
|
||||
if (!bInitialized)
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
bValidChars[i] = false;
|
||||
}
|
||||
|
||||
// generate valid chars
|
||||
for (unsigned char c = 0x20; c <= 0x80; c++)
|
||||
{
|
||||
bValidChars[c] = true;
|
||||
}
|
||||
|
||||
bValidChars[0x0a] = true;
|
||||
bValidChars[0xa9] = true;
|
||||
bValidChars[0xe9] = true;
|
||||
|
||||
bInitialized = true;
|
||||
}
|
||||
|
||||
bool bResult = true;
|
||||
char destBuffer[2048];
|
||||
char* dest = destBuffer;
|
||||
const char* src = _src;
|
||||
|
||||
// copy the string and check for "unknown" characters
|
||||
while (*src != 0x00)
|
||||
{
|
||||
u8 c = *src;
|
||||
|
||||
if (c == 0x0a){c = 0x20;}
|
||||
|
||||
if (bValidChars[c] == false)
|
||||
{
|
||||
bResult = false;
|
||||
break;
|
||||
}
|
||||
|
||||
*dest = c;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
// finalize the string
|
||||
if (bResult)
|
||||
{
|
||||
*dest = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[0] = ' ';
|
||||
dest[1] = 0x00;
|
||||
}
|
||||
|
||||
_rDestination = destBuffer;
|
||||
|
||||
return(bResult);
|
||||
}
|
||||
|
||||
|
||||
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem)
|
||||
{
|
||||
if (IsVolumeWiiDisc(_rFileSystem.GetVolume()))
|
||||
{
|
||||
return(new CBannerLoaderWii(_rFileSystem));
|
||||
}
|
||||
|
||||
return(new CBannerLoaderGC(_rFileSystem));
|
||||
}
|
||||
} // namespace
|
||||
|
57
Source/Core/DiscIO/Src/BannerLoader.h
Normal file
57
Source/Core/DiscIO/Src/BannerLoader.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _BANNER_LOADER_H_
|
||||
#define _BANNER_LOADER_H_
|
||||
|
||||
#include "Filesystem.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class IBannerLoader
|
||||
{
|
||||
public:
|
||||
|
||||
IBannerLoader()
|
||||
{}
|
||||
|
||||
|
||||
virtual ~IBannerLoader()
|
||||
{}
|
||||
|
||||
|
||||
virtual bool IsValid() = 0;
|
||||
|
||||
virtual bool GetBanner(u32* _pBannerImage) = 0;
|
||||
|
||||
virtual bool GetName(std::string& _rName) = 0;
|
||||
|
||||
virtual bool GetCompany(std::string& _rCompany) = 0;
|
||||
|
||||
virtual bool GetDescription(std::string& _rDescription) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool CopyToStringAndCheck(std::string& _rDestination, const char* _src);
|
||||
};
|
||||
|
||||
IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem);
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
192
Source/Core/DiscIO/Src/BannerLoaderGC.cpp
Normal file
192
Source/Core/DiscIO/Src/BannerLoaderGC.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "BannerLoaderGC.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem)
|
||||
: m_pBannerFile(NULL),
|
||||
m_IsValid(false)
|
||||
{
|
||||
// build LUT Table
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
lut3to8[i] = (i * 255) / 7;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
lut4to8[i] = (i * 255) / 15;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
lut5to8[i] = (i * 255) / 31;
|
||||
}
|
||||
|
||||
// load the opening.bnr
|
||||
size_t FileSize = _rFileSystem.GetFileSize("opening.bnr");
|
||||
|
||||
if (FileSize > 0)
|
||||
{
|
||||
m_pBannerFile = new u8[FileSize];
|
||||
_rFileSystem.ReadFile("opening.bnr", m_pBannerFile, FileSize);
|
||||
m_IsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CBannerLoaderGC::~CBannerLoaderGC()
|
||||
{
|
||||
delete[] m_pBannerFile;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderGC::IsValid()
|
||||
{
|
||||
return(m_IsValid);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderGC::GetBanner(u32* _pBannerImage)
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
|
||||
decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderGC::GetName(std::string& _rName)
|
||||
{
|
||||
_rName = "invalid image";
|
||||
|
||||
if (!IsValid())
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
|
||||
|
||||
if (!CopyToStringAndCheck(_rName, pBanner->comment[0].longTitle))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderGC::GetCompany(std::string& _rCompany)
|
||||
{
|
||||
_rCompany = "invalid images";
|
||||
|
||||
if (!IsValid())
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
|
||||
|
||||
if (!CopyToStringAndCheck(_rCompany, pBanner->comment[0].shortMaker))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderGC::GetDescription(std::string& _rDescription)
|
||||
{
|
||||
_rDescription = "invalid images";
|
||||
|
||||
if (!IsValid())
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile;
|
||||
|
||||
if (!CopyToStringAndCheck(_rDescription, pBanner->comment[0].comment))
|
||||
{
|
||||
_rDescription = "";
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
u32
|
||||
CBannerLoaderGC::decode5A3(u16 val)
|
||||
{
|
||||
u32 bannerBGColor = 0x00000000;
|
||||
|
||||
int r, g, b, a;
|
||||
|
||||
if ((val & 0x8000))
|
||||
{
|
||||
r = lut5to8[(val >> 10) & 0x1f];
|
||||
g = lut5to8[(val >> 5) & 0x1f];
|
||||
b = lut5to8[(val) & 0x1f];
|
||||
a = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = lut3to8[(val >> 12) & 0x7];
|
||||
r = (lut4to8[(val >> 8) & 0xf] * a + (bannerBGColor & 0xFF) * (255 - a)) / 255;
|
||||
g = (lut4to8[(val >> 4) & 0xf] * a + ((bannerBGColor >> 8) & 0xFF) * (255 - a)) / 255;
|
||||
b = (lut4to8[(val) & 0xf] * a + ((bannerBGColor >> 16) & 0xFF) * (255 - a)) / 255;
|
||||
a = 0xFF;
|
||||
}
|
||||
|
||||
return((a << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CBannerLoaderGC::decode5A3image(u32* dst, u16* src, int width, int height)
|
||||
{
|
||||
for (int y = 0; y < height; y += 4)
|
||||
{
|
||||
for (int x = 0; x < width; x += 4)
|
||||
{
|
||||
for (int iy = 0; iy < 4; iy++, src += 4)
|
||||
{
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
{
|
||||
u32 RGBA = decode5A3(Common::swap16(src[ix]));
|
||||
dst[(y + iy) * 96 + (x + ix)] = RGBA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
97
Source/Core/DiscIO/Src/BannerLoaderGC.h
Normal file
97
Source/Core/DiscIO/Src/BannerLoaderGC.h
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _BANNER_LOADER_GC_H_
|
||||
#define _BANNER_LOADER_GC_H_
|
||||
|
||||
#include "BannerLoader.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CBannerLoaderGC
|
||||
: public IBannerLoader
|
||||
{
|
||||
public:
|
||||
|
||||
CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem);
|
||||
|
||||
virtual ~CBannerLoaderGC();
|
||||
|
||||
virtual bool IsValid();
|
||||
|
||||
virtual bool GetBanner(u32* _pBannerImage);
|
||||
|
||||
virtual bool GetName(std::string& _rName);
|
||||
|
||||
virtual bool GetCompany(std::string& _rCompany);
|
||||
|
||||
virtual bool GetDescription(std::string& _rDescription);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
DVD_BANNER_WIDTH = 96,
|
||||
DVD_BANNER_HEIGHT = 32
|
||||
};
|
||||
|
||||
// Banner Comment
|
||||
struct DVDBannerComment
|
||||
{
|
||||
char shortTitle[32]; // Short game title shown in IPL menu
|
||||
char shortMaker[32]; // Short developer, publisher names shown in IPL menu
|
||||
char longTitle[64]; // Long game title shown in IPL game start screen
|
||||
char longMaker[64]; // Long developer, publisher names shown in IPL game start screen
|
||||
char comment[128]; // Game description shown in IPL game start screen in two lines.
|
||||
};
|
||||
|
||||
// "opening.bnr" file format for JP/US console
|
||||
struct DVDBanner
|
||||
{
|
||||
u32 id; // 'BNR1'
|
||||
u32 padding[7];
|
||||
u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image
|
||||
DVDBannerComment comment;
|
||||
};
|
||||
|
||||
// "opening.bnr" file format for EU console
|
||||
struct DVDBanner2
|
||||
{
|
||||
u32 id; // 'BNR2'
|
||||
u32 padding[7];
|
||||
u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image
|
||||
DVDBannerComment comment[6]; // Comments in six languages
|
||||
};
|
||||
|
||||
|
||||
// for banner decoding
|
||||
int lut3to8[8];
|
||||
int lut4to8[16];
|
||||
int lut5to8[32];
|
||||
|
||||
u8* m_pBannerFile;
|
||||
|
||||
bool m_IsValid;
|
||||
|
||||
u32 decode5A3(u16 val);
|
||||
void decode5A3image(u32* dst, u16* src, int width, int height);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
112
Source/Core/DiscIO/Src/BannerLoaderWii.cpp
Normal file
112
Source/Core/DiscIO/Src/BannerLoaderWii.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "BannerLoaderWii.h"
|
||||
#include "FileHandlerARC.h"
|
||||
// #include "FileHandlerLZ77.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CBannerLoaderWii::CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem)
|
||||
: m_pBuffer(NULL)
|
||||
{
|
||||
FILE* pFile = fopen("e:\\opening.bnr", "rb");
|
||||
|
||||
if (pFile)
|
||||
{
|
||||
fseek(pFile, 0, SEEK_END);
|
||||
int insize = ftell(pFile);
|
||||
fseek(pFile, 0, SEEK_SET);
|
||||
|
||||
m_pBuffer = new u8[insize];
|
||||
|
||||
fread(m_pBuffer, 1, insize, pFile);
|
||||
|
||||
fclose(pFile);
|
||||
|
||||
CARCFile ArcFile(m_pBuffer + 0x600, insize - 0x600);
|
||||
|
||||
size_t BannerSize = ArcFile.GetFileSize("meta\\banner.bin");
|
||||
|
||||
if (BannerSize > 0)
|
||||
{
|
||||
u8* TempBuffer = new u8[BannerSize];
|
||||
ArcFile.ReadFile("meta\\banner.bin", TempBuffer, BannerSize);
|
||||
|
||||
// CLZ77File File(TempBuffer + 0x20 + 4, BannerSize - 0x20 - 4);
|
||||
delete[] TempBuffer;
|
||||
|
||||
// CARCFile IconFile(File.GetBuffer(), File.GetSize());
|
||||
|
||||
// IconFile.ExportFile("arc\\anim\\banner_loop.brlan", "e:\\banner_loop.brlan");
|
||||
|
||||
//IconFile.ReadFile("meta\\icon.bin", TempBuffer, BannerSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Name = std::string("Wii: ") + _rFileSystem.GetVolume().GetName();
|
||||
}
|
||||
|
||||
|
||||
CBannerLoaderWii::~CBannerLoaderWii()
|
||||
{
|
||||
delete m_pBuffer;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::IsValid()
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::GetBanner(u32* _pBannerImage)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::GetName(std::string& _rName)
|
||||
{
|
||||
_rName = m_Name;
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::GetCompany(std::string& _rCompany)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CBannerLoaderWii::GetDescription(std::string& _rDescription)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
} // namespace
|
||||
|
54
Source/Core/DiscIO/Src/BannerLoaderWii.h
Normal file
54
Source/Core/DiscIO/Src/BannerLoaderWii.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _BANNER_LOADER_WII_H_
|
||||
#define _BANNER_LOADER_WII_H_
|
||||
|
||||
#include "BannerLoader.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CBannerLoaderWii
|
||||
: public IBannerLoader
|
||||
{
|
||||
public:
|
||||
|
||||
CBannerLoaderWii(DiscIO::IFileSystem& _rFileSystem);
|
||||
|
||||
virtual ~CBannerLoaderWii();
|
||||
|
||||
virtual bool IsValid();
|
||||
|
||||
virtual bool GetBanner(u32* _pBannerImage);
|
||||
|
||||
virtual bool GetName(std::string& _rName);
|
||||
|
||||
virtual bool GetCompany(std::string& _rCompany);
|
||||
|
||||
virtual bool GetDescription(std::string& _rDescription);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Name;
|
||||
|
||||
u8* m_pBuffer;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
567
Source/Core/DiscIO/Src/Blob.cpp
Normal file
567
Source/Core/DiscIO/Src/Blob.cpp
Normal file
@ -0,0 +1,567 @@
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "../../../../Externals/zlib/zlib.h"
|
||||
|
||||
#include "Blob.h"
|
||||
#include "MappedFile.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
const u32 kBlobCookie = 0xB10BC001;
|
||||
|
||||
// A blob file structure:
|
||||
// BlobHeader
|
||||
// u64 offsetsToBlocks[n], top bit specifies whether the block is compressed, or not.
|
||||
// compressed data
|
||||
|
||||
// Blocks that won't compress to less than 97% of the original size are stored as-is.
|
||||
|
||||
struct BlobHeader // 32 bytes
|
||||
{
|
||||
u32 magic_cookie; //0xB10BB10B
|
||||
u32 sub_type; // gc image, whatever
|
||||
u64 compressed_data_size;
|
||||
u64 data_size;
|
||||
u32 block_size;
|
||||
u32 num_blocks;
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
class PlainFileReader
|
||||
: public IBlobReader
|
||||
{
|
||||
HANDLE hFile;
|
||||
s64 size;
|
||||
public:
|
||||
|
||||
PlainFileReader(const char* filename)
|
||||
{
|
||||
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
DWORD size_low, size_high;
|
||||
size_low = GetFileSize(hFile, &size_high);
|
||||
size = ((u64)size_low) | ((u64)size_high << 32);
|
||||
}
|
||||
|
||||
|
||||
~PlainFileReader()
|
||||
{
|
||||
if (hFile)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IsValid() const {return(hFile != INVALID_HANDLE_VALUE);}
|
||||
|
||||
|
||||
u64 GetDataSize() const {return(size);}
|
||||
|
||||
|
||||
u64 GetRawSize() const {return(size);}
|
||||
|
||||
|
||||
bool Read(u64 offset, u64 size, u8* out_ptr)
|
||||
{
|
||||
LONG offset_high = (LONG)(offset >> 32);
|
||||
SetFilePointer(hFile, (DWORD)(offset & 0xFFFFFFFF), &offset_high, FILE_BEGIN);
|
||||
|
||||
if (size >= 0x100000000ULL)
|
||||
{
|
||||
return(false); // WTF, does windows really have this limitation?
|
||||
}
|
||||
|
||||
DWORD unused;
|
||||
|
||||
if (!ReadFile(hFile, out_ptr, DWORD(size & 0xFFFFFFFF), &unused, NULL))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#else // linux, 64-bit. We do not yet care about linux32
|
||||
// Not optimal - will keep recreating mappings.
|
||||
class PlainFileReader
|
||||
: public IBlobReader
|
||||
{
|
||||
FILE* file_;
|
||||
s64 size;
|
||||
public:
|
||||
|
||||
PlainFileReader(const char* filename)
|
||||
{
|
||||
file_ = fopen(filename, "rb");
|
||||
fseek64(file_, 0, SEEK_END);
|
||||
size = ftell(file_);
|
||||
fseek(file_, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
~PlainFileReader()
|
||||
{
|
||||
if (file_)
|
||||
{
|
||||
fclose(file_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return(file_ != 0);
|
||||
}
|
||||
|
||||
|
||||
u64 GetDataSize() const
|
||||
{
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
u64 GetRawSize() const
|
||||
{
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
bool Read(u64 offset, u64 size, u8* out_ptr)
|
||||
{
|
||||
fseek(file_, offset, SEEK_SET);
|
||||
fread(out_ptr, size, 1, file_);
|
||||
return(true);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class CompressedBlobReader
|
||||
: public IBlobReader
|
||||
{
|
||||
enum { CACHE_SIZE = 32 };
|
||||
|
||||
BlobHeader header;
|
||||
u64* block_pointers;
|
||||
int data_offset;
|
||||
u8* cache[CACHE_SIZE];
|
||||
u64 cache_tags[CACHE_SIZE];
|
||||
int cache_age[CACHE_SIZE];
|
||||
u64 counter;
|
||||
Common::IMappedFile* mapped_file;
|
||||
|
||||
public:
|
||||
|
||||
CompressedBlobReader(const char* filename)
|
||||
{
|
||||
counter = 0;
|
||||
mapped_file = Common::IMappedFile::CreateMappedFile();
|
||||
|
||||
if (mapped_file)
|
||||
{
|
||||
mapped_file->Open(filename);
|
||||
u8* start = mapped_file->Lock(0, sizeof(BlobHeader));
|
||||
memcpy(&header, start, sizeof(BlobHeader));
|
||||
mapped_file->Unlock(start);
|
||||
|
||||
block_pointers = (u64*)mapped_file->Lock(sizeof(BlobHeader), sizeof(u64) * header.num_blocks);
|
||||
data_offset = sizeof(BlobHeader) + sizeof(u64) * header.num_blocks;
|
||||
|
||||
for (int i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
cache[i] = new u8[header.block_size];
|
||||
cache_tags[i] = (u64)(s64) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const BlobHeader& GetHeader() const
|
||||
{
|
||||
return(header);
|
||||
}
|
||||
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return(mapped_file != 0);
|
||||
}
|
||||
|
||||
|
||||
~CompressedBlobReader()
|
||||
{
|
||||
for (int i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
delete[] cache[i];
|
||||
}
|
||||
|
||||
mapped_file->Unlock((u8*)block_pointers);
|
||||
|
||||
if (mapped_file)
|
||||
{
|
||||
mapped_file->Close();
|
||||
}
|
||||
|
||||
mapped_file = 0;
|
||||
}
|
||||
|
||||
|
||||
u64 GetDataSize() const
|
||||
{
|
||||
return(header.data_size);
|
||||
}
|
||||
|
||||
|
||||
u64 GetRawSize() const
|
||||
{
|
||||
return(mapped_file->GetSize());
|
||||
}
|
||||
|
||||
|
||||
u64 GetBlockCompressedSize(u64 block_num) const
|
||||
{
|
||||
u64 start = block_pointers[block_num];
|
||||
|
||||
if (block_num != header.num_blocks - 1)
|
||||
{
|
||||
return(block_pointers[block_num + 1] - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(header.compressed_data_size - start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// IMPORTANT: Calling this function invalidates all earlier pointers gotten from this function.
|
||||
u8* GetBlock(u64 block_num)
|
||||
{
|
||||
if (cache_tags[0] != block_num)
|
||||
{
|
||||
cache_tags[0] = block_num;
|
||||
//PanicAlert("here2");
|
||||
// let's begin with a super naive implementation.
|
||||
// let's just use the start of the cache for now.
|
||||
bool uncompressed = false;
|
||||
u32 comp_block_size = (u32)GetBlockCompressedSize(block_num);
|
||||
u64 offset = block_pointers[block_num] + data_offset;
|
||||
|
||||
if (offset & (1ULL << 63))
|
||||
{
|
||||
if (comp_block_size != header.block_size)
|
||||
{
|
||||
PanicAlert("Uncompressed block with wrong size");
|
||||
}
|
||||
|
||||
uncompressed = true;
|
||||
offset &= ~(1ULL << 63);
|
||||
}
|
||||
|
||||
u8* source = mapped_file->Lock(offset, comp_block_size);
|
||||
u8* dest = cache[0];
|
||||
|
||||
if (uncompressed)
|
||||
{
|
||||
memcpy(dest, source, comp_block_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
z_stream z;
|
||||
memset(&z, 0, sizeof(z));
|
||||
z.next_in = source;
|
||||
z.avail_in = comp_block_size;
|
||||
|
||||
if (z.avail_in > header.block_size)
|
||||
{
|
||||
PanicAlert("We have a problem");
|
||||
}
|
||||
|
||||
z.next_out = dest;
|
||||
z.avail_out = header.block_size;
|
||||
inflateInit(&z);
|
||||
int status = inflate(&z, Z_FULL_FLUSH);
|
||||
int uncomp_size = header.block_size - z.avail_out;
|
||||
|
||||
if (status != Z_STREAM_END)
|
||||
{
|
||||
// this seem to fire wrongly from time to time
|
||||
// to be sure, don't use compressed isos :P
|
||||
//PanicAlert("Failure reading block %i", block_num);
|
||||
}
|
||||
|
||||
if (uncomp_size != header.block_size)
|
||||
{
|
||||
PanicAlert("Wrong block size");
|
||||
}
|
||||
|
||||
inflateEnd(&z);
|
||||
}
|
||||
|
||||
mapped_file->Unlock(source);
|
||||
}
|
||||
|
||||
//PanicAlert("here3");
|
||||
return(cache[0]);
|
||||
}
|
||||
|
||||
|
||||
bool Read(u64 offset, u64 size, u8* out_ptr)
|
||||
{
|
||||
u64 startingBlock = offset / header.block_size;
|
||||
u64 remain = size;
|
||||
|
||||
int positionInBlock = (int)(offset % header.block_size);
|
||||
u64 block = startingBlock;
|
||||
|
||||
while (remain > 0)
|
||||
{
|
||||
u8* data = GetBlock(block);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
int toCopy = header.block_size - positionInBlock;
|
||||
|
||||
if (toCopy >= remain)
|
||||
{
|
||||
// yay, we are done!
|
||||
memcpy(out_ptr, data + positionInBlock, (size_t)remain);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(out_ptr, data + positionInBlock, toCopy);
|
||||
out_ptr += toCopy;
|
||||
remain -= toCopy;
|
||||
positionInBlock = 0;
|
||||
block++;
|
||||
}
|
||||
}
|
||||
|
||||
PanicAlert("here4");
|
||||
return(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type, int block_size,
|
||||
CompressCB callback, void* arg)
|
||||
{
|
||||
//Common::IMappedFile *in = Common::IMappedFile::CreateMappedFile();
|
||||
if (IsCompressedBlob(infile))
|
||||
{
|
||||
PanicAlert("%s is already compressed!", infile);
|
||||
return(false);
|
||||
}
|
||||
|
||||
FILE* inf = fopen(infile, "rb");
|
||||
|
||||
if (!inf)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
FILE* f = fopen(outfile, "wb");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
callback("Files opened, ready to compress.", 0, arg);
|
||||
|
||||
fseek(inf, 0, SEEK_END);
|
||||
int insize = ftell(inf);
|
||||
fseek(inf, 0, SEEK_SET);
|
||||
BlobHeader header;
|
||||
header.magic_cookie = kBlobCookie;
|
||||
header.sub_type = sub_type;
|
||||
header.block_size = block_size;
|
||||
header.data_size = insize;
|
||||
|
||||
// round upwards!
|
||||
header.num_blocks = (u32)((header.data_size + (block_size - 1)) / block_size);
|
||||
|
||||
u64* offsets = new u64[header.num_blocks];
|
||||
u8* out_buf = new u8[block_size];
|
||||
u8* in_buf = new u8[block_size];
|
||||
|
||||
// seek past the header (we will write it at the end)
|
||||
fseek(f, sizeof(BlobHeader), SEEK_CUR);
|
||||
// seek past the offset table (we will write it at the end)
|
||||
fseek(f, sizeof(u64) * header.num_blocks, SEEK_CUR);
|
||||
// Now we are ready to write compressed data!
|
||||
u64 position = 0;
|
||||
int num_compressed = 0;
|
||||
int num_stored = 0;
|
||||
|
||||
for (u32 i = 0; i < header.num_blocks; i++)
|
||||
{
|
||||
if (i % (header.num_blocks / 100) == 0)
|
||||
{
|
||||
u64 inpos = ftell(inf);
|
||||
int ratio = (int)(100 * position / inpos);
|
||||
char temp[512];
|
||||
sprintf(temp, "%i of %i blocks. compression ratio %i%%", i, header.num_blocks, ratio);
|
||||
callback(temp, (float)i / (float)header.num_blocks, arg);
|
||||
}
|
||||
|
||||
offsets[i] = position;
|
||||
// u64 start = i * header.block_size;
|
||||
// u64 size = header.block_size;
|
||||
memset(in_buf, 0, header.block_size);
|
||||
fread(in_buf, header.block_size, 1, inf);
|
||||
z_stream z;
|
||||
memset(&z, 0, sizeof(z));
|
||||
z.zalloc = Z_NULL;
|
||||
z.zfree = Z_NULL;
|
||||
z.opaque = Z_NULL;
|
||||
z.next_in = in_buf;
|
||||
z.avail_in = header.block_size;
|
||||
z.next_out = out_buf;
|
||||
z.avail_out = block_size;
|
||||
int retval = deflateInit(&z, 9);
|
||||
|
||||
if (retval != Z_OK)
|
||||
{
|
||||
PanicAlert("Deflate failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int status = deflate(&z, Z_FINISH);
|
||||
int comp_size = block_size - z.avail_out;
|
||||
|
||||
if ((status != Z_STREAM_END) || (z.avail_out < 10))
|
||||
{
|
||||
//PanicAlert("%i %i Store %i", i*block_size, position, comp_size);
|
||||
// let's store uncompressed
|
||||
offsets[i] |= 0x8000000000000000ULL;
|
||||
fwrite(in_buf, block_size, 1, f);
|
||||
position += block_size;
|
||||
num_stored++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// let's store compressed
|
||||
//PanicAlert("Comp %i to %i", block_size, comp_size);
|
||||
fwrite(out_buf, comp_size, 1, f);
|
||||
position += comp_size;
|
||||
num_compressed++;
|
||||
}
|
||||
|
||||
deflateEnd(&z);
|
||||
}
|
||||
|
||||
header.compressed_data_size = position;
|
||||
|
||||
// Okay, go back and fill in headers
|
||||
fseek(f, 0, SEEK_SET);
|
||||
fwrite(&header, sizeof(header), 1, f);
|
||||
fwrite(offsets, sizeof(u64), header.num_blocks, f);
|
||||
|
||||
cleanup:
|
||||
// Cleanup
|
||||
delete[] in_buf;
|
||||
delete[] out_buf;
|
||||
delete[] offsets;
|
||||
fclose(f);
|
||||
fclose(inf);
|
||||
callback("Done.", 1.0f, arg);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool DecompressBlobToFile(const char* infile, const char* outfile,
|
||||
CompressCB callback, void* arg)
|
||||
{
|
||||
if (!IsCompressedBlob(infile))
|
||||
{
|
||||
PanicAlert("File not compressed");
|
||||
return(false);
|
||||
}
|
||||
|
||||
CompressedBlobReader* reader = new CompressedBlobReader(infile);
|
||||
|
||||
FILE* f = fopen(outfile, "wb");
|
||||
const BlobHeader& header = reader->GetHeader();
|
||||
u8* buffer = new u8[header.block_size];
|
||||
|
||||
for (u64 i = 0; i < header.num_blocks; i++)
|
||||
{
|
||||
if (i % (header.num_blocks / 100) == 0)
|
||||
{
|
||||
callback("Unpacking", (float)i / (float)header.num_blocks, arg);
|
||||
}
|
||||
|
||||
reader->Read(i * header.block_size, header.block_size, buffer);
|
||||
fwrite(buffer, header.block_size, 1, f);
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
#ifdef _WIN32
|
||||
// TODO(ector): _chsize sucks, not 64-bit safe
|
||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||
_chsize_s(_fileno(f), (long)header.data_size);
|
||||
#else
|
||||
ftruncate(fileno(f), header.data_size);
|
||||
#endif
|
||||
fclose(f);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool IsCompressedBlob(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "rb");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
BlobHeader header;
|
||||
fread(&header, sizeof(header), 1, f);
|
||||
fclose(f);
|
||||
return(header.magic_cookie == kBlobCookie);
|
||||
}
|
||||
|
||||
|
||||
IBlobReader* CreateBlobReader(const char* filename)
|
||||
{
|
||||
IBlobReader* reader;
|
||||
|
||||
if (IsCompressedBlob(filename))
|
||||
{
|
||||
reader = new CompressedBlobReader(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader = new PlainFileReader(filename);
|
||||
}
|
||||
|
||||
if (reader->IsValid())
|
||||
{
|
||||
return(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete reader;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
} // namespace
|
63
Source/Core/DiscIO/Src/Blob.h
Normal file
63
Source/Core/DiscIO/Src/Blob.h
Normal file
@ -0,0 +1,63 @@
|
||||
#ifndef _BLOB_H
|
||||
#define _BLOB_H
|
||||
|
||||
/*
|
||||
Code not big-endian safe.
|
||||
|
||||
BLOB
|
||||
|
||||
Blobs are Binary Large OBjects. For example, a typical DVD image.
|
||||
Often, you may want to store these things in a highly compressed format, but still
|
||||
allow random access.
|
||||
|
||||
Always read your BLOBs using an interface returned by CreateBlobReader(). It will
|
||||
detect whether the file is a compressed blob, or just a big hunk of data, and
|
||||
automatically do the right thing.
|
||||
|
||||
To create new BLOBs, use CompressFileToBlob.
|
||||
|
||||
Right now caching of decompressed chunks doesn't work, so it's a bit slow.
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class IBlobReader
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~IBlobReader() {}
|
||||
|
||||
|
||||
virtual u64 GetRawSize() const = 0;
|
||||
virtual u64 GetDataSize() const = 0;
|
||||
virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0;
|
||||
virtual bool IsValid() const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
IBlobReader() {}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
IBlobReader(const IBlobReader& other) {}
|
||||
};
|
||||
|
||||
|
||||
IBlobReader* CreateBlobReader(const char* filename);
|
||||
bool IsCompressedBlob(const char* filename);
|
||||
|
||||
|
||||
typedef void (*CompressCB)(const char* text, float percent, void* arg);
|
||||
|
||||
bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type = 0, int sector_size = 16384,
|
||||
CompressCB callback = 0, void* arg = 0);
|
||||
bool DecompressBlobToFile(const char* infile, const char* outfile,
|
||||
CompressCB callback = 0, void* arg = 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
236
Source/Core/DiscIO/Src/FileHandlerARC.cpp
Normal file
236
Source/Core/DiscIO/Src/FileHandlerARC.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "FileHandlerARC.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
|
||||
#define ARC_ID 0x55aa382d
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CARCFile::CARCFile(const u8* _pBuffer, size_t _BufferSize)
|
||||
: m_pBuffer(NULL),
|
||||
m_Initialized(false)
|
||||
{
|
||||
m_pBuffer = new u8[_BufferSize];
|
||||
|
||||
if (m_pBuffer)
|
||||
{
|
||||
memcpy(m_pBuffer, _pBuffer, _BufferSize);
|
||||
m_Initialized = ParseBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CARCFile::~CARCFile()
|
||||
{
|
||||
delete m_pBuffer;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CARCFile::IsInitialized()
|
||||
{
|
||||
return(m_Initialized);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CARCFile::GetFileSize(const std::string& _rFullPath)
|
||||
{
|
||||
if (!m_Initialized)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (pFileInfo != NULL)
|
||||
{
|
||||
return(pFileInfo->m_FileSize);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CARCFile::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize)
|
||||
{
|
||||
if (!m_Initialized)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (pFileInfo == NULL)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (pFileInfo->m_FileSize > _MaxBufferSize)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
memcpy(_pBuffer, &m_pBuffer[pFileInfo->m_Offset], pFileInfo->m_FileSize);
|
||||
return(pFileInfo->m_FileSize);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CARCFile::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename)
|
||||
{
|
||||
if (!m_Initialized)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (pFileInfo == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
FILE* pFile = fopen(_rExportFilename.c_str(), "wb");
|
||||
|
||||
if (pFile == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
fwrite(&m_pBuffer[pFileInfo->m_Offset], pFileInfo->m_FileSize, 1, pFile);
|
||||
fclose(pFile);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CARCFile::ExportAllFiles(const std::string& _rFullPath)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CARCFile::ParseBuffer()
|
||||
{
|
||||
// check ID
|
||||
u32 ID = Common::swap32(*(u32*)(m_pBuffer));
|
||||
|
||||
if (ID != ARC_ID)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
// read header
|
||||
u32 FSTOffset = Common::swap32(*(u32*)(m_pBuffer + 0x4));
|
||||
u32 FSTSize = Common::swap32(*(u32*)(m_pBuffer + 0x8));
|
||||
u32 FileOffset = Common::swap32(*(u32*)(m_pBuffer + 0xC));
|
||||
|
||||
// read all file infos
|
||||
SFileInfo Root;
|
||||
Root.m_NameOffset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x0));
|
||||
Root.m_Offset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x4));
|
||||
Root.m_FileSize = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x8));
|
||||
|
||||
if (Root.IsDirectory())
|
||||
{
|
||||
m_FileInfoVector.resize(Root.m_FileSize);
|
||||
const char* szNameTable = (char*)(m_pBuffer + FSTOffset);
|
||||
|
||||
for (size_t i = 0; i < m_FileInfoVector.size(); i++)
|
||||
{
|
||||
u8* Offset = m_pBuffer + FSTOffset + (i * 0xC);
|
||||
m_FileInfoVector[i].m_NameOffset = Common::swap32(*(u32*)(Offset + 0x0));
|
||||
m_FileInfoVector[i].m_Offset = Common::swap32(*(u32*)(Offset + 0x4));
|
||||
m_FileInfoVector[i].m_FileSize = Common::swap32(*(u32*)(Offset + 0x8));
|
||||
|
||||
szNameTable += 0xC;
|
||||
}
|
||||
|
||||
BuildFilenames(1, m_FileInfoVector.size(), NULL, szNameTable);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CARCFile::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, const char* _szNameTable)
|
||||
{
|
||||
size_t CurrentIndex = _FirstIndex;
|
||||
|
||||
while (CurrentIndex < _LastIndex)
|
||||
{
|
||||
SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
|
||||
int uOffset = rFileInfo.m_NameOffset & 0xFFFFFF;
|
||||
|
||||
// check next index
|
||||
if (rFileInfo.IsDirectory())
|
||||
{
|
||||
// this is a directory, build up the new szDirectory
|
||||
if (_szDirectory != NULL)
|
||||
{
|
||||
rFileInfo.m_FullPath = StringFromFormat("%s%s\\", _szDirectory, &_szNameTable[uOffset]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rFileInfo.m_FullPath = StringFromFormat("%s\\", &_szNameTable[uOffset]);
|
||||
}
|
||||
|
||||
CurrentIndex = BuildFilenames(CurrentIndex + 1, rFileInfo.m_FileSize, rFileInfo.m_FullPath.c_str(), _szNameTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a filename
|
||||
if (_szDirectory != NULL)
|
||||
{
|
||||
rFileInfo.m_FullPath = StringFromFormat("%s%s", _szDirectory, &_szNameTable[uOffset]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rFileInfo.m_FullPath = StringFromFormat("%s", &_szNameTable[uOffset]);
|
||||
}
|
||||
|
||||
CurrentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return(CurrentIndex);
|
||||
}
|
||||
|
||||
|
||||
const CARCFile::SFileInfo*
|
||||
CARCFile::FindFileInfo(std::string _rFullPath) const
|
||||
{
|
||||
for (size_t i = 0; i < m_FileInfoVector.size(); i++)
|
||||
{
|
||||
if (!stricmp(m_FileInfoVector[i].m_FullPath.c_str(), _rFullPath.c_str()))
|
||||
{
|
||||
return(&m_FileInfoVector[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
} // namespace
|
77
Source/Core/DiscIO/Src/FileHandlerARC.h
Normal file
77
Source/Core/DiscIO/Src/FileHandlerARC.h
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _ARC_FILE_H
|
||||
#define _ARC_FILE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Filesystem.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CARCFile
|
||||
{
|
||||
public:
|
||||
|
||||
CARCFile(const u8* _pBuffer, size_t _BufferSize);
|
||||
|
||||
virtual ~CARCFile();
|
||||
|
||||
bool IsInitialized();
|
||||
|
||||
size_t GetFileSize(const std::string& _rFullPath);
|
||||
|
||||
size_t ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize);
|
||||
|
||||
bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename);
|
||||
|
||||
bool ExportAllFiles(const std::string& _rFullPath);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
u8* m_pBuffer;
|
||||
|
||||
bool m_Initialized;
|
||||
|
||||
struct SFileInfo
|
||||
{
|
||||
u32 m_NameOffset;
|
||||
u32 m_Offset;
|
||||
u32 m_FileSize;
|
||||
|
||||
std::string m_FullPath;
|
||||
|
||||
bool IsDirectory() {return((m_NameOffset& 0xFF000000) != 0 ? true : false);}
|
||||
};
|
||||
|
||||
typedef std::vector<SFileInfo>CFileInfoVector;
|
||||
CFileInfoVector m_FileInfoVector;
|
||||
|
||||
bool ParseBuffer();
|
||||
|
||||
size_t BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, const char* _szNameTable);
|
||||
|
||||
const SFileInfo* FindFileInfo(std::string _rFullPath) const;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
276
Source/Core/DiscIO/Src/FileSystemGCWii.cpp
Normal file
276
Source/Core/DiscIO/Src/FileSystemGCWii.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "FileSystemGCWii.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CFileSystemGCWii::CFileSystemGCWii(const IVolume& _rVolume)
|
||||
: IFileSystem(_rVolume),
|
||||
m_Initialized(false),
|
||||
m_OffsetShift(0)
|
||||
{
|
||||
m_Initialized = InitFileSystem();
|
||||
}
|
||||
|
||||
|
||||
CFileSystemGCWii::~CFileSystemGCWii()
|
||||
{}
|
||||
|
||||
|
||||
bool
|
||||
CFileSystemGCWii::IsInitialized()
|
||||
{
|
||||
return(m_Initialized);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CFileSystemGCWii::GetFileSize(const char* _rFullPath)
|
||||
{
|
||||
if (!m_Initialized)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (pFileInfo != NULL)
|
||||
{
|
||||
return(pFileInfo->m_FileSize);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
CFileSystemGCWii::GetFileName(u64 _Address)
|
||||
{
|
||||
for (size_t i = 0; i < m_FileInfoVector.size(); i++)
|
||||
{
|
||||
if ((m_FileInfoVector[i].m_Offset <= _Address) &&
|
||||
((m_FileInfoVector[i].m_Offset + m_FileInfoVector[i].m_FileSize) > _Address))
|
||||
{
|
||||
return(m_FileInfoVector[i].m_FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CFileSystemGCWii::ReadFile(const char* _rFullPath, u8* _pBuffer, size_t _MaxBufferSize)
|
||||
{
|
||||
if (!m_Initialized)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (pFileInfo == NULL)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (pFileInfo->m_FileSize > _MaxBufferSize)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
m_rVolume.Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer);
|
||||
return(pFileInfo->m_FileSize);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFilename)
|
||||
{
|
||||
size_t filesize = GetFileSize(_rFullPath);
|
||||
|
||||
if (filesize == 0)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
u8* buffer = new u8[filesize];
|
||||
|
||||
if (!ReadFile(_rFullPath, buffer, filesize))
|
||||
{
|
||||
delete[] buffer;
|
||||
return(false);
|
||||
}
|
||||
|
||||
FILE* f = fopen(_rExportFilename, "wb");
|
||||
|
||||
if (f)
|
||||
{
|
||||
fwrite(buffer, filesize, 1, f);
|
||||
fclose(f);
|
||||
delete[] buffer;
|
||||
return(true);
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CFileSystemGCWii::ExportAllFiles(const char* _rFullPath)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
u32
|
||||
CFileSystemGCWii::Read32(u64 _Offset) const
|
||||
{
|
||||
u32 Temp = 0;
|
||||
m_rVolume.Read(_Offset, 4, (u8*)&Temp);
|
||||
return(Common::swap32(Temp));
|
||||
}
|
||||
|
||||
|
||||
void CFileSystemGCWii::GetStringFromOffset(u64 _Offset, char* Filename) const
|
||||
{
|
||||
m_rVolume.Read(_Offset, 255, (u8*)Filename);
|
||||
}
|
||||
|
||||
|
||||
const CFileSystemGCWii::SFileInfo*
|
||||
CFileSystemGCWii::FindFileInfo(const char* _rFullPath) const
|
||||
{
|
||||
for (size_t i = 0; i < m_FileInfoVector.size(); i++)
|
||||
{
|
||||
if (!stricmp(m_FileInfoVector[i].m_FullPath, _rFullPath))
|
||||
{
|
||||
return(&m_FileInfoVector[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CFileSystemGCWii::InitFileSystem()
|
||||
{
|
||||
if (Read32(0x18) == 0x5D1C9EA3)
|
||||
{
|
||||
m_OffsetShift = 2;
|
||||
}
|
||||
else if (Read32(0x1c) == 0xC2339F3D)
|
||||
{
|
||||
m_OffsetShift = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
// read the whole FST
|
||||
u32 FSTOffset = Read32(0x424) << m_OffsetShift;
|
||||
// u32 FSTSize = Read32(0x428);
|
||||
// u32 FSTMaxSize = Read32(0x42C);
|
||||
|
||||
|
||||
// read all fileinfos
|
||||
SFileInfo Root;
|
||||
Root.m_NameOffset = Read32(FSTOffset + 0x0);
|
||||
Root.m_Offset = (u64)Read32(FSTOffset + 0x4) << m_OffsetShift;
|
||||
Root.m_FileSize = Read32(FSTOffset + 0x8);
|
||||
|
||||
if (Root.IsDirectory())
|
||||
{
|
||||
m_FileInfoVector.resize(Root.m_FileSize);
|
||||
u64 NameTableOffset = FSTOffset;
|
||||
|
||||
for (size_t i = 0; i < m_FileInfoVector.size(); i++)
|
||||
{
|
||||
u64 Offset = FSTOffset + (i * 0xC);
|
||||
m_FileInfoVector[i].m_NameOffset = Read32(Offset + 0x0);
|
||||
m_FileInfoVector[i].m_Offset = (u64)Read32(Offset + 0x4) << m_OffsetShift;
|
||||
m_FileInfoVector[i].m_FileSize = Read32(Offset + 0x8);
|
||||
NameTableOffset += 0xC;
|
||||
}
|
||||
|
||||
BuildFilenames(1, m_FileInfoVector.size(), NULL, NameTableOffset);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
//
|
||||
// Changed this stuff from C++ string to C strings for speed in debug mode. Doesn't matter in release, but
|
||||
// std::string is SLOW in debug mode.
|
||||
size_t
|
||||
CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, u64 _NameTableOffset)
|
||||
{
|
||||
size_t CurrentIndex = _FirstIndex;
|
||||
|
||||
while (CurrentIndex < _LastIndex)
|
||||
{
|
||||
SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
|
||||
u64 uOffset = _NameTableOffset + (rFileInfo.m_NameOffset & 0xFFFFFF);
|
||||
char filename[512];
|
||||
GetStringFromOffset(uOffset, filename);
|
||||
|
||||
// check next index
|
||||
if (rFileInfo.IsDirectory())
|
||||
{
|
||||
// this is a directory, build up the new szDirectory
|
||||
if (_szDirectory != NULL)
|
||||
{
|
||||
CharArrayFromFormat(rFileInfo.m_FullPath, "%s%s\\", _szDirectory, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharArrayFromFormat(rFileInfo.m_FullPath, "%s\\", filename);
|
||||
}
|
||||
|
||||
CurrentIndex = BuildFilenames(CurrentIndex + 1, rFileInfo.m_FileSize, rFileInfo.m_FullPath, _NameTableOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a filename
|
||||
if (_szDirectory != NULL)
|
||||
{
|
||||
CharArrayFromFormat(rFileInfo.m_FullPath, "%s%s", _szDirectory, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharArrayFromFormat(rFileInfo.m_FullPath, "%s", filename);
|
||||
}
|
||||
|
||||
CurrentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return(CurrentIndex);
|
||||
}
|
||||
} // namespace
|
||||
|
82
Source/Core/DiscIO/Src/FileSystemGCWii.h
Normal file
82
Source/Core/DiscIO/Src/FileSystemGCWii.h
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _FILESYSTEM_GC_WII_H
|
||||
#define _FILESYSTEM_GC_WII_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Filesystem.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CFileSystemGCWii
|
||||
: public IFileSystem
|
||||
{
|
||||
public:
|
||||
|
||||
CFileSystemGCWii(const IVolume& _rVolume);
|
||||
|
||||
virtual ~CFileSystemGCWii();
|
||||
|
||||
virtual bool IsInitialized();
|
||||
|
||||
virtual size_t GetFileSize(const char* _rFullPath);
|
||||
|
||||
virtual const char* GetFileName(u64 _Address);
|
||||
|
||||
virtual size_t ReadFile(const char* _rFullPath, u8* _pBuffer, size_t _MaxBufferSize);
|
||||
|
||||
virtual bool ExportFile(const char* _rFullPath, const char* _rExportFilename);
|
||||
|
||||
virtual bool ExportAllFiles(const char* _rFullPath);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// file info of an FST entry
|
||||
struct SFileInfo
|
||||
{
|
||||
u32 m_NameOffset;
|
||||
u64 m_Offset;
|
||||
u32 m_FileSize;
|
||||
char m_FullPath[512];
|
||||
|
||||
bool IsDirectory() {return((m_NameOffset& 0xFF000000) != 0 ? true : false);}
|
||||
};
|
||||
|
||||
typedef std::vector<SFileInfo>CFileInfoVector;
|
||||
CFileInfoVector m_FileInfoVector;
|
||||
|
||||
bool m_Initialized;
|
||||
|
||||
u32 m_OffsetShift; // WII offsets are all shifted
|
||||
|
||||
u32 Read32(u64 _Offset) const;
|
||||
|
||||
void GetStringFromOffset(u64 _Offset, char* Filename) const;
|
||||
|
||||
const SFileInfo* FindFileInfo(const char* _rFullPath) const;
|
||||
|
||||
bool InitFileSystem();
|
||||
|
||||
size_t BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, u64 _NameTableOffset);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
50
Source/Core/DiscIO/Src/Filesystem.cpp
Normal file
50
Source/Core/DiscIO/Src/Filesystem.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Filesystem.h"
|
||||
|
||||
#include "VolumeCreator.h"
|
||||
#include "FileSystemGCWii.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
IFileSystem::IFileSystem(const IVolume& _rVolume)
|
||||
: m_rVolume(_rVolume)
|
||||
{}
|
||||
|
||||
|
||||
IFileSystem::~IFileSystem()
|
||||
{}
|
||||
|
||||
|
||||
IFileSystem* CreateFileSystem(const IVolume& _rVolume)
|
||||
{
|
||||
IFileSystem* pFileSystem = new CFileSystemGCWii(_rVolume);
|
||||
|
||||
if (pFileSystem)
|
||||
{
|
||||
if (!pFileSystem->IsInitialized())
|
||||
{
|
||||
delete pFileSystem;
|
||||
pFileSystem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return(pFileSystem);
|
||||
}
|
||||
} // namespace
|
60
Source/Core/DiscIO/Src/Filesystem.h
Normal file
60
Source/Core/DiscIO/Src/Filesystem.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _FILESYSTEM_H
|
||||
#define _FILESYSTEM_H
|
||||
|
||||
#include "Volume.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class IFileSystem
|
||||
{
|
||||
public:
|
||||
|
||||
IFileSystem(const IVolume& _rVolume);
|
||||
|
||||
virtual ~IFileSystem();
|
||||
|
||||
virtual bool IsInitialized() = 0;
|
||||
|
||||
|
||||
// virtual size_t GetFileList(std::vector<std::string&> _rFilenames) = 0;
|
||||
|
||||
virtual size_t GetFileSize(const char* _rFullPath) = 0;
|
||||
|
||||
virtual size_t ReadFile(const char* _rFullPath, u8* _pBuffer, size_t _MaxBufferSize) = 0;
|
||||
|
||||
virtual bool ExportFile(const char* _rFullPath, const char* _rExportFilename) = 0;
|
||||
|
||||
virtual bool ExportAllFiles(const char* _rFullPath) = 0;
|
||||
|
||||
virtual const char* GetFileName(u64 _Address) = 0;
|
||||
|
||||
|
||||
virtual const IVolume& GetVolume() {return(m_rVolume);}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
const IVolume& m_rVolume;
|
||||
};
|
||||
|
||||
IFileSystem* CreateFileSystem(const IVolume& _rVolume);
|
||||
} // namespace
|
||||
|
||||
#endif
|
23
Source/Core/DiscIO/Src/SConscript
Normal file
23
Source/Core/DiscIO/Src/SConscript
Normal file
@ -0,0 +1,23 @@
|
||||
Import('env')
|
||||
|
||||
files = ["BannerLoader.cpp",
|
||||
"BannerLoaderGC.cpp",
|
||||
"BannerLoaderWii.cpp",
|
||||
"Blob.cpp",
|
||||
"FileHandlerARC.cpp",
|
||||
"FileHandlerLZ77.cpp",
|
||||
"Filesystem.cpp",
|
||||
"FileSystemGCWii.cpp",
|
||||
"VolumeCreator.cpp",
|
||||
"VolumeGC.cpp",
|
||||
"VolumeWiiCrypted.cpp",
|
||||
"AES/aes_cbc.c",
|
||||
"AES/aes_cfb.c",
|
||||
"AES/aes_core.c",
|
||||
"AES/aes_ctr.c",
|
||||
"AES/aes_ecb.c",
|
||||
"AES/aes_ige.c",
|
||||
"AES/aes_misc.c",
|
||||
"AES/aes_ofb.c",
|
||||
]
|
||||
env.StaticLibrary("discio", files, LIBS = ["common"])
|
59
Source/Core/DiscIO/Src/Volume.h
Normal file
59
Source/Core/DiscIO/Src/Volume.h
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
#ifndef _VOLUME_H
|
||||
#define _VOLUME_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class IVolume
|
||||
{
|
||||
public:
|
||||
|
||||
IVolume()
|
||||
{}
|
||||
|
||||
|
||||
virtual ~IVolume()
|
||||
{}
|
||||
|
||||
|
||||
virtual bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const = 0;
|
||||
virtual std::string GetName() const = 0;
|
||||
virtual std::string GetUniqueID() const = 0;
|
||||
|
||||
|
||||
enum ECountry
|
||||
{
|
||||
COUNTRY_EUROPE = 0,
|
||||
COUNTRY_FRANCE = 1,
|
||||
COUNTRY_USA = 2,
|
||||
COUNTRY_JAP,
|
||||
COUNTRY_UNKNOWN,
|
||||
NUMBER_OF_COUNTRIES
|
||||
};
|
||||
|
||||
virtual ECountry GetCountry() const = 0;
|
||||
virtual u64 GetSize() const = 0;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
232
Source/Core/DiscIO/Src/VolumeCreator.cpp
Normal file
232
Source/Core/DiscIO/Src/VolumeCreator.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "AES/aes.h"
|
||||
|
||||
#include "VolumeCreator.h"
|
||||
|
||||
#include "Volume.h"
|
||||
#include "VolumeGC.h"
|
||||
#include "VolumeWiiCrypted.h"
|
||||
|
||||
#include "Hash.h"
|
||||
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
enum EDiscType
|
||||
{
|
||||
DISC_TYPE_UNK,
|
||||
DISC_TYPE_WII,
|
||||
DISC_TYPE_WII_CONTAINER,
|
||||
DISC_TYPE_GC
|
||||
};
|
||||
|
||||
class CBlobBigEndianReader
|
||||
{
|
||||
public:
|
||||
|
||||
CBlobBigEndianReader(IBlobReader& _rReader)
|
||||
: m_rReader(_rReader)
|
||||
{}
|
||||
|
||||
|
||||
u32 Read32(u64 _Offset)
|
||||
{
|
||||
u32 Temp;
|
||||
m_rReader.Read(_Offset, 4, (u8*)&Temp);
|
||||
return(Common::swap32(Temp));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
IBlobReader& m_rReader;
|
||||
};
|
||||
|
||||
unsigned char g_MasterKey[16];
|
||||
bool g_MasterKeyInit = false;
|
||||
|
||||
IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, int _VolumeType);
|
||||
EDiscType GetDiscType(IBlobReader& _rReader);
|
||||
|
||||
|
||||
IVolume* CreateVolumeFromFilename(const std::string& _rFilename)
|
||||
{
|
||||
IBlobReader* pReader = CreateBlobReader(_rFilename.c_str());
|
||||
|
||||
if (pReader == NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
switch (GetDiscType(*pReader))
|
||||
{
|
||||
case DISC_TYPE_WII:
|
||||
case DISC_TYPE_GC:
|
||||
return(new CVolumeGC(pReader));
|
||||
|
||||
case DISC_TYPE_WII_CONTAINER:
|
||||
{
|
||||
IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, 0);
|
||||
|
||||
if (pVolume == NULL)
|
||||
{
|
||||
delete pReader;
|
||||
}
|
||||
|
||||
return(pVolume);
|
||||
}
|
||||
break;
|
||||
|
||||
case DISC_TYPE_UNK:
|
||||
default:
|
||||
delete pReader;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// unreachable code
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool IsVolumeWiiDisc(const IVolume& _rVolume)
|
||||
{
|
||||
u32 MagicWord = 0;
|
||||
_rVolume.Read(0x18, 4, (u8*)&MagicWord);
|
||||
|
||||
if (Common::swap32(MagicWord) == 0x5D1C9EA3)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, int _VolumeType)
|
||||
{
|
||||
if (!g_MasterKeyInit)
|
||||
{
|
||||
FILE* pT = fopen("WII/masterkey.bin", "rb");
|
||||
|
||||
if (pT == NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
fread(g_MasterKey, 16, 1, pT);
|
||||
fclose(pT);
|
||||
const u32 keyhash = 0x4bc30936;
|
||||
u32 hash = HashAdler32(g_MasterKey, 16);
|
||||
|
||||
if (hash != keyhash)
|
||||
{
|
||||
PanicAlert("Your Wii disc decryption key is bad.", keyhash, hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_MasterKeyInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
CBlobBigEndianReader Reader(_rReader);
|
||||
|
||||
u32 numPartitions = Reader.Read32(0x40000);
|
||||
u64 PartitionsOffset = (u64)Reader.Read32(0x40004) << 2;
|
||||
|
||||
struct SPartition
|
||||
{
|
||||
u64 Offset;
|
||||
u32 Type;
|
||||
};
|
||||
std::vector<SPartition>PartitionsVec;
|
||||
|
||||
// read all partitions
|
||||
for (u32 i = 0; i < numPartitions; i++)
|
||||
{
|
||||
SPartition Partition;
|
||||
Partition.Offset = ((u64)Reader.Read32(PartitionsOffset + (i * 8) + 0)) << 2;
|
||||
Partition.Type = Reader.Read32(PartitionsOffset + (i * 8) + 4);
|
||||
PartitionsVec.push_back(Partition);
|
||||
}
|
||||
|
||||
// find the partition with the game... type == 1 is prolly the firmware update partition
|
||||
for (size_t i = 0; i < PartitionsVec.size(); i++)
|
||||
{
|
||||
const SPartition& rPartition = PartitionsVec[i];
|
||||
|
||||
if (rPartition.Type == _VolumeType)
|
||||
{
|
||||
u8 SubKey[16];
|
||||
_rReader.Read(rPartition.Offset + 0x1bf, 16, SubKey);
|
||||
|
||||
u8 IV[16];
|
||||
memset(IV, 0, 16);
|
||||
_rReader.Read(rPartition.Offset + 0x44c, 8, IV);
|
||||
|
||||
AES_KEY AES_KEY;
|
||||
AES_set_decrypt_key(g_MasterKey, 128, &AES_KEY);
|
||||
|
||||
u8 VolumeKey[16];
|
||||
AES_cbc_encrypt(SubKey, VolumeKey, 16, &AES_KEY, IV, AES_DECRYPT);
|
||||
|
||||
return(new CVolumeWiiCrypted(&_rReader, rPartition.Offset + 0x20000, VolumeKey));
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
EDiscType GetDiscType(IBlobReader& _rReader)
|
||||
{
|
||||
CBlobBigEndianReader Reader(_rReader);
|
||||
|
||||
// check for wii
|
||||
{
|
||||
u32 MagicWord = Reader.Read32(0x18);
|
||||
|
||||
if (MagicWord == 0x5D1C9EA3)
|
||||
{
|
||||
if (Reader.Read32(0x60) != 0)
|
||||
{
|
||||
return(DISC_TYPE_WII);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(DISC_TYPE_WII_CONTAINER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for GC
|
||||
{
|
||||
u32 MagicWord = Reader.Read32(0x1C);
|
||||
|
||||
if (MagicWord == 0xC2339F3D)
|
||||
{
|
||||
return(DISC_TYPE_GC);
|
||||
}
|
||||
}
|
||||
|
||||
return(DISC_TYPE_UNK);
|
||||
}
|
||||
} // namespace
|
||||
|
30
Source/Core/DiscIO/Src/VolumeCreator.h
Normal file
30
Source/Core/DiscIO/Src/VolumeCreator.h
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _VOLUME_CREATOR_H
|
||||
#define _VOLUME_CREATOR_H
|
||||
|
||||
#include "Volume.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
IVolume* CreateVolumeFromFilename(const std::string& _rFilename);
|
||||
bool IsVolumeWiiDisc(const IVolume& _rVolume);
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
157
Source/Core/DiscIO/Src/VolumeGC.cpp
Normal file
157
Source/Core/DiscIO/Src/VolumeGC.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "VolumeGC.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CVolumeGC::CVolumeGC(IBlobReader* _pReader)
|
||||
: m_pReader(_pReader)
|
||||
{}
|
||||
|
||||
|
||||
CVolumeGC::~CVolumeGC()
|
||||
{
|
||||
delete m_pReader;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(m_pReader->Read(_Offset, _Length, _pBuffer));
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CVolumeGC::GetName() const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
char Name[128];
|
||||
|
||||
if (!Read(0x20, 0x60, (u8*)&Name))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(Name);
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CVolumeGC::GetUniqueID() const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
char ID[7];
|
||||
|
||||
if (!Read(0, 6, (u8*)ID))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
ID[6] = 0;
|
||||
|
||||
return(ID);
|
||||
}
|
||||
|
||||
|
||||
IVolume::ECountry
|
||||
CVolumeGC::GetCountry() const
|
||||
{
|
||||
if (!m_pReader)
|
||||
{
|
||||
return(COUNTRY_UNKNOWN);
|
||||
}
|
||||
|
||||
u8 CountryCode;
|
||||
m_pReader->Read(3, 1, &CountryCode);
|
||||
|
||||
ECountry country = COUNTRY_UNKNOWN;
|
||||
|
||||
switch (CountryCode)
|
||||
{
|
||||
case 'S':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // PAL // <- that is shitty :) zelda demo disc
|
||||
|
||||
case 'P':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // PAL
|
||||
|
||||
case 'D':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // PAL
|
||||
|
||||
case 'F':
|
||||
country = COUNTRY_FRANCE;
|
||||
break; // PAL
|
||||
|
||||
case 'X':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // XIII <- uses X but is PAL rip
|
||||
|
||||
case 'E':
|
||||
country = COUNTRY_USA;
|
||||
break; // USA
|
||||
|
||||
case 'J':
|
||||
country = COUNTRY_JAP;
|
||||
break; // JAP
|
||||
|
||||
case 'O':
|
||||
country = COUNTRY_UNKNOWN;
|
||||
break; // SDK
|
||||
|
||||
default:
|
||||
// PanicAlert(StringFromFormat("Unknown Country Code!").c_str());
|
||||
country = COUNTRY_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return(country);
|
||||
}
|
||||
|
||||
|
||||
u64
|
||||
CVolumeGC::GetSize() const
|
||||
{
|
||||
if (m_pReader)
|
||||
{
|
||||
return((size_t)m_pReader->GetDataSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
} // namespace
|
54
Source/Core/DiscIO/Src/VolumeGC.h
Normal file
54
Source/Core/DiscIO/Src/VolumeGC.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Volume.h"
|
||||
#include "Blob.h"
|
||||
|
||||
//
|
||||
// --- this volume type is used for GC and for decrypted Wii images ---
|
||||
//
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class CVolumeGC
|
||||
: public IVolume
|
||||
{
|
||||
public:
|
||||
|
||||
CVolumeGC(IBlobReader* _pReader);
|
||||
|
||||
~CVolumeGC();
|
||||
|
||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
std::string GetUniqueID() const;
|
||||
|
||||
ECountry GetCountry() const;
|
||||
|
||||
u64 GetSize() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
IBlobReader* m_pReader;
|
||||
};
|
||||
} // namespace
|
||||
|
196
Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
Normal file
196
Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "VolumeWiiCrypted.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey)
|
||||
: m_pReader(_pReader),
|
||||
m_pBuffer(0),
|
||||
m_VolumeOffset(_VolumeOffset),
|
||||
m_LastDecryptedBlockOffset(-1)
|
||||
{
|
||||
AES_set_decrypt_key(_pVolumeKey, 128, &m_AES_KEY);
|
||||
m_pBuffer = new u8[0x8000];
|
||||
}
|
||||
|
||||
|
||||
CVolumeWiiCrypted::~CVolumeWiiCrypted()
|
||||
{
|
||||
delete m_pReader; // is this really our responsibility?
|
||||
delete[] m_pBuffer;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
while (_Length > 0)
|
||||
{
|
||||
static unsigned char IV[16];
|
||||
|
||||
// math block offset
|
||||
u64 Block = _ReadOffset / 0x7C00;
|
||||
u64 Offset = _ReadOffset % 0x7C00;
|
||||
|
||||
// read current block
|
||||
if (!m_pReader->Read(m_VolumeOffset + Block * 0x8000, 0x8000, m_pBuffer))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (m_LastDecryptedBlockOffset != Block)
|
||||
{
|
||||
memcpy(IV, m_pBuffer + 0x3d0, 16);
|
||||
AES_cbc_encrypt(m_pBuffer + 0x400, m_LastDecryptedBlock, 0x7C00, &m_AES_KEY, IV, AES_DECRYPT);
|
||||
|
||||
m_LastDecryptedBlockOffset = Block;
|
||||
}
|
||||
|
||||
// copy the encrypted data
|
||||
u64 MaxSizeToCopy = 0x7C00 - Offset;
|
||||
u64 CopySize = (_Length > MaxSizeToCopy) ? MaxSizeToCopy : _Length;
|
||||
memcpy(_pBuffer, &m_LastDecryptedBlock[Offset], (size_t)CopySize);
|
||||
|
||||
// increase buffers
|
||||
_Length -= CopySize;
|
||||
_pBuffer += CopySize;
|
||||
_ReadOffset += CopySize;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CVolumeWiiCrypted::GetName() const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
char Name[0xFF];
|
||||
|
||||
if (!Read(0x20, 0x60, (u8*)&Name))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(Name);
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CVolumeWiiCrypted::GetUniqueID() const
|
||||
{
|
||||
if (m_pReader == NULL)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
char ID[7];
|
||||
|
||||
if (!Read(0, 6, (u8*)ID))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
ID[6] = 0;
|
||||
|
||||
return(ID);
|
||||
}
|
||||
|
||||
|
||||
IVolume::ECountry
|
||||
CVolumeWiiCrypted::GetCountry() const
|
||||
{
|
||||
if (!m_pReader)
|
||||
{
|
||||
return(COUNTRY_UNKNOWN);
|
||||
}
|
||||
|
||||
u8 CountryCode;
|
||||
m_pReader->Read(3, 1, &CountryCode);
|
||||
|
||||
ECountry country = COUNTRY_UNKNOWN;
|
||||
|
||||
switch (CountryCode)
|
||||
{
|
||||
case 'S':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // PAL // <- that is shitty :) zelda demo disc
|
||||
|
||||
case 'P':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // PAL
|
||||
|
||||
case 'D':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // PAL
|
||||
|
||||
case 'F':
|
||||
country = COUNTRY_FRANCE;
|
||||
break; // PAL
|
||||
|
||||
case 'X':
|
||||
country = COUNTRY_EUROPE;
|
||||
break; // XIII <- uses X but is PAL rip
|
||||
|
||||
case 'E':
|
||||
country = COUNTRY_USA;
|
||||
break; // USA
|
||||
|
||||
case 'J':
|
||||
country = COUNTRY_JAP;
|
||||
break; // JAP
|
||||
|
||||
case 'O':
|
||||
country = COUNTRY_UNKNOWN;
|
||||
break; // SDK
|
||||
|
||||
default:
|
||||
PanicAlert(StringFromFormat("Unknown Country Code!").c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
return(country);
|
||||
}
|
||||
|
||||
|
||||
u64
|
||||
CVolumeWiiCrypted::GetSize() const
|
||||
{
|
||||
if (m_pReader)
|
||||
{
|
||||
return(m_pReader->GetDataSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
} // namespace
|
65
Source/Core/DiscIO/Src/VolumeWiiCrypted.h
Normal file
65
Source/Core/DiscIO/Src/VolumeWiiCrypted.h
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _VOLUME_WII_CRYPTED
|
||||
#define _VOLUME_WII_CRYPTED
|
||||
|
||||
#include "Volume.h"
|
||||
#include "Blob.h"
|
||||
#include "AES/aes.h"
|
||||
|
||||
//
|
||||
// --- this volume type is used for encrypted Wii images ---
|
||||
//
|
||||
namespace DiscIO
|
||||
{
|
||||
class CVolumeWiiCrypted
|
||||
: public IVolume
|
||||
{
|
||||
public:
|
||||
|
||||
CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey);
|
||||
|
||||
~CVolumeWiiCrypted();
|
||||
|
||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
std::string GetUniqueID() const;
|
||||
|
||||
ECountry GetCountry() const;
|
||||
|
||||
u64 GetSize() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
IBlobReader* m_pReader;
|
||||
|
||||
u8* m_pBuffer;
|
||||
AES_KEY m_AES_KEY;
|
||||
|
||||
u64 m_VolumeOffset;
|
||||
|
||||
mutable u64 m_LastDecryptedBlockOffset;
|
||||
mutable unsigned char m_LastDecryptedBlock[0x8000];
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
21
Source/Core/DiscIO/Src/stdafx.cpp
Normal file
21
Source/Core/DiscIO/Src/stdafx.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
30
Source/Core/DiscIO/Src/stdafx.h
Normal file
30
Source/Core/DiscIO/Src/stdafx.h
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// 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, version 2.0.
|
||||
|
||||
// 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 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
|
||||
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _SCL_SECURE_NO_DEPRECATE
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
Reference in New Issue
Block a user