[CPU] Move LZX code to its own files.
This commit is contained in:
parent
dd3a049b23
commit
5f764fc752
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/lzx.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/memory.h"
|
||||
#include "xenia/kernel/util/xex2_info.h"
|
||||
|
||||
#include "third_party/mspack/lzx.h"
|
||||
#include "third_party/mspack/mspack.h"
|
||||
|
||||
typedef struct mspack_memory_file_t {
|
||||
struct mspack_system sys;
|
||||
void* buffer;
|
||||
off_t buffer_size;
|
||||
off_t offset;
|
||||
} mspack_memory_file;
|
||||
mspack_memory_file* mspack_memory_open(struct mspack_system* sys, void* buffer,
|
||||
const size_t buffer_size) {
|
||||
assert_true(buffer_size < INT_MAX);
|
||||
if (buffer_size >= INT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
mspack_memory_file* memfile =
|
||||
(mspack_memory_file*)calloc(1, sizeof(mspack_memory_file));
|
||||
if (!memfile) {
|
||||
return NULL;
|
||||
}
|
||||
memfile->buffer = buffer;
|
||||
memfile->buffer_size = (off_t)buffer_size;
|
||||
memfile->offset = 0;
|
||||
return memfile;
|
||||
}
|
||||
void mspack_memory_close(mspack_memory_file* file) {
|
||||
mspack_memory_file* memfile = (mspack_memory_file*)file;
|
||||
free(memfile);
|
||||
}
|
||||
int mspack_memory_read(struct mspack_file* file, void* buffer, int chars) {
|
||||
mspack_memory_file* memfile = (mspack_memory_file*)file;
|
||||
const off_t remaining = memfile->buffer_size - memfile->offset;
|
||||
const off_t total = std::min(static_cast<off_t>(chars), remaining);
|
||||
memcpy(buffer, (uint8_t*)memfile->buffer + memfile->offset, total);
|
||||
memfile->offset += total;
|
||||
return (int)total;
|
||||
}
|
||||
int mspack_memory_write(struct mspack_file* file, void* buffer, int chars) {
|
||||
mspack_memory_file* memfile = (mspack_memory_file*)file;
|
||||
const off_t remaining = memfile->buffer_size - memfile->offset;
|
||||
const off_t total = std::min(static_cast<off_t>(chars), remaining);
|
||||
memcpy((uint8_t*)memfile->buffer + memfile->offset, buffer, total);
|
||||
memfile->offset += total;
|
||||
return (int)total;
|
||||
}
|
||||
void* mspack_memory_alloc(struct mspack_system* sys, size_t chars) {
|
||||
return calloc(chars, 1);
|
||||
}
|
||||
void mspack_memory_free(void* ptr) { free(ptr); }
|
||||
void mspack_memory_copy(void* src, void* dest, size_t chars) {
|
||||
memcpy(dest, src, chars);
|
||||
}
|
||||
struct mspack_system* mspack_memory_sys_create() {
|
||||
struct mspack_system* sys =
|
||||
(struct mspack_system*)calloc(1, sizeof(struct mspack_system));
|
||||
if (!sys) {
|
||||
return NULL;
|
||||
}
|
||||
sys->read = mspack_memory_read;
|
||||
sys->write = mspack_memory_write;
|
||||
sys->alloc = mspack_memory_alloc;
|
||||
sys->free = mspack_memory_free;
|
||||
sys->copy = mspack_memory_copy;
|
||||
return sys;
|
||||
}
|
||||
void mspack_memory_sys_destroy(struct mspack_system* sys) { free(sys); }
|
||||
|
||||
int lzx_decompress(const void* lzx_data, size_t lzx_len, void* dest,
|
||||
size_t dest_len, uint32_t window_size, void* window_data,
|
||||
size_t window_data_len) {
|
||||
uint32_t window_bits = 0;
|
||||
uint32_t temp_sz = window_size;
|
||||
for (size_t m = 0; m < 32; m++, window_bits++) {
|
||||
temp_sz >>= 1;
|
||||
if (temp_sz == 0x00000000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int result_code = 1;
|
||||
|
||||
mspack_system* sys = mspack_memory_sys_create();
|
||||
mspack_memory_file* lzxsrc =
|
||||
mspack_memory_open(sys, (void*)lzx_data, lzx_len);
|
||||
mspack_memory_file* lzxdst = mspack_memory_open(sys, dest, dest_len);
|
||||
lzxd_stream* lzxd =
|
||||
lzxd_init(sys, (struct mspack_file*)lzxsrc, (struct mspack_file*)lzxdst,
|
||||
window_bits, 0, 0x8000, (off_t)dest_len, 0);
|
||||
|
||||
if (lzxd) {
|
||||
if (window_data) {
|
||||
// zero the window and then copy window_data to the end of it
|
||||
memset(lzxd->window, 0, window_data_len);
|
||||
memcpy(lzxd->window + (window_size - window_data_len), window_data,
|
||||
window_data_len);
|
||||
}
|
||||
|
||||
result_code = lzxd_decompress(lzxd, (off_t)dest_len);
|
||||
|
||||
lzxd_free(lzxd);
|
||||
lzxd = NULL;
|
||||
}
|
||||
if (lzxsrc) {
|
||||
mspack_memory_close(lzxsrc);
|
||||
lzxsrc = NULL;
|
||||
}
|
||||
if (lzxdst) {
|
||||
mspack_memory_close(lzxdst);
|
||||
lzxdst = NULL;
|
||||
}
|
||||
if (sys) {
|
||||
mspack_memory_sys_destroy(sys);
|
||||
sys = NULL;
|
||||
}
|
||||
|
||||
return result_code;
|
||||
}
|
||||
|
||||
int lzxdelta_apply_patch(xe::xex2_delta_patch* patch, size_t patch_len,
|
||||
uint32_t window_size, void* dest) {
|
||||
void* patch_end = (char*)patch + patch_len;
|
||||
auto* cur_patch = patch;
|
||||
|
||||
while (patch_end > cur_patch) {
|
||||
int patch_sz = -4; // 0 byte patches need us to remove 4 byte from next
|
||||
// patch addr because of patch_data field
|
||||
if (cur_patch->compressed_len == 0 && cur_patch->uncompressed_len == 0 &&
|
||||
cur_patch->new_addr == 0 && cur_patch->old_addr == 0)
|
||||
break;
|
||||
switch (cur_patch->compressed_len) {
|
||||
case 0: // fill with 0
|
||||
memset((char*)dest + cur_patch->new_addr, 0,
|
||||
cur_patch->uncompressed_len);
|
||||
break;
|
||||
case 1: // copy from old -> new
|
||||
memcpy((char*)dest + cur_patch->new_addr,
|
||||
(char*)dest + cur_patch->old_addr, cur_patch->uncompressed_len);
|
||||
break;
|
||||
default: // delta patch
|
||||
patch_sz =
|
||||
cur_patch->compressed_len - 4; // -4 because of patch_data field
|
||||
|
||||
int result = lzx_decompress(
|
||||
cur_patch->patch_data, cur_patch->compressed_len,
|
||||
(char*)dest + cur_patch->new_addr, cur_patch->uncompressed_len,
|
||||
window_size, (char*)dest + cur_patch->old_addr,
|
||||
cur_patch->uncompressed_len);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cur_patch++;
|
||||
cur_patch = (xe::xex2_delta_patch*)((char*)cur_patch +
|
||||
patch_sz); // TODO: make this less ugly
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_LZX_H_
|
||||
#define XENIA_CPU_LZX_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/cpu/module.h"
|
||||
|
||||
namespace xe {
|
||||
struct xex2_delta_patch;
|
||||
} // namespace xe
|
||||
|
||||
int lzx_decompress(const void* lzx_data, size_t lzx_len, void* dest,
|
||||
size_t dest_len, uint32_t window_size, void* window_data,
|
||||
size_t window_data_len);
|
||||
|
||||
int lzxdelta_apply_patch(xe::xex2_delta_patch* patch, size_t patch_len,
|
||||
uint32_t window_size, void* dest);
|
||||
|
||||
#endif // XENIA_CPU_XEX_MODULE_H_
|
|
@ -17,6 +17,7 @@
|
|||
#include "xenia/base/memory.h"
|
||||
#include "xenia/cpu/cpu_flags.h"
|
||||
#include "xenia/cpu/export_resolver.h"
|
||||
#include "xenia/cpu/lzx.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/xmodule.h"
|
||||
|
@ -24,8 +25,6 @@
|
|||
#include "third_party/crypto/TinySHA1.hpp"
|
||||
#include "third_party/crypto/rijndael-alg-fst.c"
|
||||
#include "third_party/crypto/rijndael-alg-fst.h"
|
||||
#include "third_party/mspack/lzx.h"
|
||||
#include "third_party/mspack/mspack.h"
|
||||
#include "third_party/pe/pe_image.h"
|
||||
|
||||
static const uint8_t xe_xex2_retail_key[16] = {
|
||||
|
@ -35,165 +34,6 @@ static const uint8_t xe_xex2_devkit_key[16] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
typedef struct mspack_memory_file_t {
|
||||
struct mspack_system sys;
|
||||
void* buffer;
|
||||
off_t buffer_size;
|
||||
off_t offset;
|
||||
} mspack_memory_file;
|
||||
mspack_memory_file* mspack_memory_open(struct mspack_system* sys, void* buffer,
|
||||
const size_t buffer_size) {
|
||||
assert_true(buffer_size < INT_MAX);
|
||||
if (buffer_size >= INT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
mspack_memory_file* memfile =
|
||||
(mspack_memory_file*)calloc(1, sizeof(mspack_memory_file));
|
||||
if (!memfile) {
|
||||
return NULL;
|
||||
}
|
||||
memfile->buffer = buffer;
|
||||
memfile->buffer_size = (off_t)buffer_size;
|
||||
memfile->offset = 0;
|
||||
return memfile;
|
||||
}
|
||||
void mspack_memory_close(mspack_memory_file* file) {
|
||||
mspack_memory_file* memfile = (mspack_memory_file*)file;
|
||||
free(memfile);
|
||||
}
|
||||
int mspack_memory_read(struct mspack_file* file, void* buffer, int chars) {
|
||||
mspack_memory_file* memfile = (mspack_memory_file*)file;
|
||||
const off_t remaining = memfile->buffer_size - memfile->offset;
|
||||
const off_t total = std::min(static_cast<off_t>(chars), remaining);
|
||||
memcpy(buffer, (uint8_t*)memfile->buffer + memfile->offset, total);
|
||||
memfile->offset += total;
|
||||
return (int)total;
|
||||
}
|
||||
int mspack_memory_write(struct mspack_file* file, void* buffer, int chars) {
|
||||
mspack_memory_file* memfile = (mspack_memory_file*)file;
|
||||
const off_t remaining = memfile->buffer_size - memfile->offset;
|
||||
const off_t total = std::min(static_cast<off_t>(chars), remaining);
|
||||
memcpy((uint8_t*)memfile->buffer + memfile->offset, buffer, total);
|
||||
memfile->offset += total;
|
||||
return (int)total;
|
||||
}
|
||||
void* mspack_memory_alloc(struct mspack_system* sys, size_t chars) {
|
||||
return calloc(chars, 1);
|
||||
}
|
||||
void mspack_memory_free(void* ptr) { free(ptr); }
|
||||
void mspack_memory_copy(void* src, void* dest, size_t chars) {
|
||||
memcpy(dest, src, chars);
|
||||
}
|
||||
struct mspack_system* mspack_memory_sys_create() {
|
||||
struct mspack_system* sys =
|
||||
(struct mspack_system*)calloc(1, sizeof(struct mspack_system));
|
||||
if (!sys) {
|
||||
return NULL;
|
||||
}
|
||||
sys->read = mspack_memory_read;
|
||||
sys->write = mspack_memory_write;
|
||||
sys->alloc = mspack_memory_alloc;
|
||||
sys->free = mspack_memory_free;
|
||||
sys->copy = mspack_memory_copy;
|
||||
return sys;
|
||||
}
|
||||
void mspack_memory_sys_destroy(struct mspack_system* sys) { free(sys); }
|
||||
|
||||
int lzx_decompress(const void* lzx_data, size_t lzx_len, void* dest,
|
||||
size_t dest_len, uint32_t window_size, void* window_data,
|
||||
size_t window_data_len) {
|
||||
uint32_t window_bits = 0;
|
||||
uint32_t temp_sz = window_size;
|
||||
for (size_t m = 0; m < 32; m++, window_bits++) {
|
||||
temp_sz >>= 1;
|
||||
if (temp_sz == 0x00000000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int result_code = 1;
|
||||
|
||||
mspack_system* sys = mspack_memory_sys_create();
|
||||
mspack_memory_file* lzxsrc =
|
||||
mspack_memory_open(sys, (void*)lzx_data, lzx_len);
|
||||
mspack_memory_file* lzxdst = mspack_memory_open(sys, dest, dest_len);
|
||||
lzxd_stream* lzxd =
|
||||
lzxd_init(sys, (struct mspack_file*)lzxsrc, (struct mspack_file*)lzxdst,
|
||||
window_bits, 0, 0x8000, (off_t)dest_len, 0);
|
||||
|
||||
if (lzxd) {
|
||||
if (window_data) {
|
||||
// zero the window and then copy window_data to the end of it
|
||||
memset(lzxd->window, 0, window_data_len);
|
||||
memcpy(lzxd->window + (window_size - window_data_len), window_data,
|
||||
window_data_len);
|
||||
}
|
||||
|
||||
result_code = lzxd_decompress(lzxd, (off_t)dest_len);
|
||||
|
||||
lzxd_free(lzxd);
|
||||
lzxd = NULL;
|
||||
}
|
||||
if (lzxsrc) {
|
||||
mspack_memory_close(lzxsrc);
|
||||
lzxsrc = NULL;
|
||||
}
|
||||
if (lzxdst) {
|
||||
mspack_memory_close(lzxdst);
|
||||
lzxdst = NULL;
|
||||
}
|
||||
if (sys) {
|
||||
mspack_memory_sys_destroy(sys);
|
||||
sys = NULL;
|
||||
}
|
||||
|
||||
return result_code;
|
||||
}
|
||||
|
||||
int lzxdelta_apply_patch(xe::xex2_delta_patch* patch, size_t patch_len,
|
||||
uint32_t window_size, void* dest) {
|
||||
void* patch_end = (char*)patch + patch_len;
|
||||
auto* cur_patch = patch;
|
||||
|
||||
while (patch_end > cur_patch) {
|
||||
int patch_sz = -4; // 0 byte patches need us to remove 4 byte from next
|
||||
// patch addr because of patch_data field
|
||||
if (cur_patch->compressed_len == 0 && cur_patch->uncompressed_len == 0 &&
|
||||
cur_patch->new_addr == 0 && cur_patch->old_addr == 0)
|
||||
break;
|
||||
switch (cur_patch->compressed_len) {
|
||||
case 0: // fill with 0
|
||||
memset((char*)dest + cur_patch->new_addr, 0,
|
||||
cur_patch->uncompressed_len);
|
||||
break;
|
||||
case 1: // copy from old -> new
|
||||
memcpy((char*)dest + cur_patch->new_addr,
|
||||
(char*)dest + cur_patch->old_addr, cur_patch->uncompressed_len);
|
||||
break;
|
||||
default: // delta patch
|
||||
patch_sz =
|
||||
cur_patch->compressed_len - 4; // -4 because of patch_data field
|
||||
|
||||
int result = lzx_decompress(
|
||||
cur_patch->patch_data, cur_patch->compressed_len,
|
||||
(char*)dest + cur_patch->new_addr, cur_patch->uncompressed_len,
|
||||
window_size, (char*)dest + cur_patch->old_addr,
|
||||
cur_patch->uncompressed_len);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cur_patch++;
|
||||
cur_patch = (xe::xex2_delta_patch*)((char*)cur_patch +
|
||||
patch_sz); // TODO: make this less ugly
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aes_decrypt_buffer(const uint8_t* session_key, const uint8_t* input_buffer,
|
||||
const size_t input_size, uint8_t* output_buffer,
|
||||
const size_t output_size) {
|
||||
|
|
Loading…
Reference in New Issue