Implement pausing/resuming directly on the server

This commit is contained in:
BullyWiiPlaza 2017-04-16 19:33:35 +02:00
parent c630849186
commit 05492f5f48
16 changed files with 163 additions and 171 deletions

View File

@ -28,7 +28,7 @@
extern "C" {
#endif
#include "common/fs_defs.h"
#include "../common/fs_defs.h"
void InitFSFunctionPointers(void);

View File

@ -16,7 +16,7 @@ int __entry_menu(int argc, char **argv) {
InitSocketFunctionPointers();
InitGX2FunctionPointers();
start_pygecko();
startTCPGecko();
return EXIT_RELAUNCH_ON_LOAD;
}

View File

@ -4,7 +4,7 @@
#include <unistd.h>
#include <fcntl.h>
#include "common/fs_defs.h"
#include "dynamic_libs/fs_functions.h"
#include "../dynamic_libs/fs_functions.h"
int MountFS(void *pClient, void *pCmd, char **mount_path)

View File

@ -29,8 +29,8 @@
#include <malloc.h>
#include <fcntl.h>
#include <stdio.h>
#include "dynamic_libs/fs_functions.h"
#include "dynamic_libs/os_functions.h"
#include "../dynamic_libs/fs_functions.h"
#include "../dynamic_libs/os_functions.h"
#include "fs_utils.h"
#define FS_ALIGNMENT 0x40

View File

@ -1,8 +1,8 @@
#include "common/os_defs.h"
#include "common/kernel_defs.h"
#include "common/common.h"
#include "dynamic_libs/os_functions.h"
#include "utils/utils.h"
#include "../common/os_defs.h"
#include "../common/kernel_defs.h"
#include "../common/common.h"
#include "../dynamic_libs/os_functions.h"
#include "../utils/utils.h"
#include "syscalls.h"
extern void my_PrepareTitle_hook(void);

View File

@ -15,12 +15,11 @@
#include "fs/sd_fat_devoptab.h"
#include "kernel/kernel_functions.h"
#include "system/memory.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "common/common.h"
#include "main.h"
int CCHandler;
int codeHandlerInstalled;
void startMiiMaker() {
char buf_vol_odd[20];
@ -45,12 +44,6 @@ int Menu_Main(void) {
InitVPadFunctionPointers();
InitSysFunctionPointers();
const char ip_address[100] = "192.168.178.49";
log_init(ip_address);
log_deinit();
log_init(ip_address);
log_printf("Started %s\n", cosAppXmlInfoStruct.rpx_name);
if (strcasecmp("men.rpx", cosAppXmlInfoStruct.rpx_name) == 0) {
return EXIT_RELAUNCH_ON_LOAD;
} else if (strlen(cosAppXmlInfoStruct.rpx_name) > 0 &&
@ -194,7 +187,7 @@ int Menu_Main(void) {
m_DCInvalidateRange((u32) physicalCodeHandlerAddress, codeHandlerSize);
unmount_sd_fat("sd");
CCHandler = 1;
codeHandlerInstalled = 1;
launchMethod = 2;
break;
@ -212,8 +205,6 @@ int Menu_Main(void) {
MEM1_free(screenBuffer);
screenBuffer = NULL;
log_deinit();
memoryRelease();
if (launchMethod == 0) {

View File

@ -12,7 +12,7 @@ extern "C" {
//! C wrapper for our C++ functions
int Menu_Main(void);
extern int CCHandler;
extern int codeHandlerInstalled;
#ifdef __cplusplus
}

View File

@ -1,7 +1,7 @@
#include <malloc.h>
#include "common/common.h"
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "../dynamic_libs/os_functions.h"
#include "../dynamic_libs/socket_functions.h"
#include "function_hooks.h"
#include "fs_logger.h"
#include "utils/utils.h"

View File

@ -14,6 +14,7 @@
#include "dynamic_libs/fs_functions.h"
#include "common/fs_defs.h"
#include "system/exception_handler.h"
#include "utils/logger.h"
void *client;
void *commandBlock;
@ -53,6 +54,9 @@ struct pygecko_bss_t {
#define COMMAND_MEMORY_SEARCH 0x73
// #define COMMAND_SYSTEM_CALL 0x80
#define COMMAND_EXECUTE_ASSEMBLY 0x81
#define COMMAND_PAUSE_CONSOLE 0x82
#define COMMAND_RESUME_CONSOLE 0x83
#define COMMAND_IS_CONSOLE_PAUSED 0x84
#define COMMAND_SERVER_VERSION 0x99
#define COMMAND_OS_VERSION 0x9A
#define COMMAND_RUN_KERNEL_COPY_SERVICE 0xCD
@ -152,7 +156,8 @@ unsigned char *memcpy_buffer[DATA_BUFFER_SIZE];
void pygecko_memcpy(unsigned char *destinationBuffer, unsigned char *sourceBuffer, unsigned int length) {
memcpy(memcpy_buffer, sourceBuffer, length);
SC0x25_KernelCopyData((unsigned int) OSEffectiveToPhysical(destinationBuffer), (unsigned int) &memcpy_buffer, length);
SC0x25_KernelCopyData((unsigned int) OSEffectiveToPhysical(destinationBuffer), (unsigned int) &memcpy_buffer,
length);
DCFlushRange(destinationBuffer, (u32) length);
}
@ -199,6 +204,48 @@ void startKernelCopyService() {
OSResumeThread(thread);
}
int (*AVMGetDRCScanMode)(int);
unsigned long getConsoleStatePatchAddress() {
if (AVMGetDRCScanMode) {
log_print("Already acquired!\n");
} else {
// Acquire the RPL and function
log_print("Acquiring...\n");
unsigned int avm_handle;
OSDynLoad_Acquire("avm.rpl", (u32 * ) & avm_handle);
ASSERT_ALLOCATED(avm_handle, "avm.rpl")
OSDynLoad_FindExport((u32) avm_handle, 0, "AVMGetDRCScanMode", &AVMGetDRCScanMode);
ASSERT_ALLOCATED(AVMGetDRCScanMode, "AVMGetDRCScanMode")
log_print("Acquired!\n");
}
return (unsigned long) (AVMGetDRCScanMode + 0x44);
}
typedef enum {
PAUSED = 0x38000001, RUNNING = 0x38000000
} ConsoleState;
void writeConsoleState(ConsoleState state) {
// Get the value to write
int patchValue = state;
log_printf("Patch value: %x\n", patchValue);
// Write the value
unsigned int patchAddress = getConsoleStatePatchAddress();
log_printf("Patch address: %x\n", patchAddress);
pygecko_memcpy((unsigned char *) patchAddress, (unsigned char *) &patchValue, 4);
}
bool isConsolePaused() {
unsigned int patchAddress = getConsoleStatePatchAddress();
log_printf("Patch address: %x\n", patchAddress);
int value = *(unsigned int *) patchAddress;
return value == PAUSED;
}
/*Validates the address range (last address inclusive) but is SLOW on bigger ranges */
static int validateAddressRange(int starting_address, int ending_address) {
return __OSValidateAddressSpaceRange(1, (void *) starting_address, ending_address - starting_address + 1);
@ -252,7 +299,7 @@ static int sendwait(struct pygecko_bss_t *bss, int sock, const void *buffer, int
return ret;
}
static int sendbyte(struct pygecko_bss_t *bss, int sock, unsigned char byte) {
static int sendByte(struct pygecko_bss_t *bss, int sock, unsigned char byte) {
unsigned char buffer[1];
buffer[0] = byte;
@ -405,7 +452,7 @@ int kernelMemoryCompare(const void *sourceBuffer,
return kern_read(sourceBuffer) - kern_read(destinationBuffer);
}
static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
static int listenForCommands(struct pygecko_bss_t *bss, int clientfd) {
int ret;
// Hold the command and the data
@ -480,7 +527,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
if (rangeIterationIndex == length) {
// No need to send all zero bytes for performance
ret = sendbyte(bss, clientfd, ONLY_ZEROS_READ);
ret = sendByte(bss, clientfd, ONLY_ZEROS_READ);
CHECK_ERROR(ret < 0)
} else {
// TODO Compression of ptr, sending of status, compressed size and data, length: 1 + 4 + len(data)
@ -527,7 +574,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
if (rangeIterationIndex == length) {
// No need to send all zero bytes for performance
ret = sendbyte(bss, clientfd, ONLY_ZEROS_READ);
ret = sendByte(bss, clientfd, ONLY_ZEROS_READ);
CHECK_ERROR(ret < 0)
} else {
// TODO Compression of ptr, sending of status, compressed size and data, length: 1 + 4 + len(data)
@ -564,7 +611,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
int isAddressRangeValid = validateAddressRange(startingAddress, endingAddress);
sendbyte(bss, clientfd, (unsigned char) isAddressRangeValid);
sendByte(bss, clientfd, (unsigned char) isAddressRangeValid);
break;
}
/*case COMMAND_DISASSEMBLE_RANGE: {
@ -1126,7 +1173,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
break;
}
case COMMAND_SERVER_STATUS: {
ret = sendbyte(bss, clientfd, 1);
ret = sendByte(bss, clientfd, 1);
CHECK_ERROR(ret < 0)
break;
}
@ -1259,6 +1306,24 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
break;
}
case COMMAND_PAUSE_CONSOLE: {
writeConsoleState(PAUSED);
break;
}
case COMMAND_RESUME_CONSOLE: {
writeConsoleState(RUNNING);
break;
}
case COMMAND_IS_CONSOLE_PAUSED: {
bool paused = isConsolePaused();
log_printf("Paused: %d\n", paused);
ret = sendByte(bss, clientfd, (unsigned char) paused);
ASSERT_FUNCTION_SUCCEEDED(ret, "sendByte (sending paused console status)")
break;
}
case COMMAND_SERVER_VERSION: {
char versionBuffer[50];
strcpy(versionBuffer, SERVER_VERSION);
@ -1299,7 +1364,7 @@ static int rungecko(struct pygecko_bss_t *bss, int clientfd) {
return 0;
}
static int start(int argc, void *argv) {
static int runTCPGeckoServer(int argc, void *argv) {
int sockfd = -1, clientfd = -1, ret = 0, len;
struct sockaddr_in addr;
struct pygecko_bss_t *bss = argv;
@ -1307,7 +1372,10 @@ static int start(int argc, void *argv) {
setup_os_exceptions();
socket_lib_init();
while (1) {
log_init("192.168.2.103");
log_print("TCP Gecko Installer\n");
while (true) {
addr.sin_family = AF_INET;
addr.sin_port = 7331;
addr.sin_addr.s_addr = 0;
@ -1321,11 +1389,11 @@ static int start(int argc, void *argv) {
ret = listen(sockfd, 20);
CHECK_ERROR(ret < 0)
while (1) {
while (true) {
len = 16;
clientfd = accept(sockfd, (void *) &addr, &len);
CHECK_ERROR(clientfd == -1)
ret = rungecko(bss, clientfd);
ret = listenForCommands(bss, clientfd);
CHECK_ERROR(ret < 0)
socketclose(clientfd);
clientfd = -1;
@ -1345,7 +1413,8 @@ static int start(int argc, void *argv) {
return 0;
}
static int CCThread(int argc, void *argv) {
static int startTCPGeckoThread(int argc, void *argv) {
// Run the TCP Gecko Installer server
struct pygecko_bss_t *bss;
bss = memalign(0x40, sizeof(struct pygecko_bss_t));
@ -1353,25 +1422,28 @@ static int CCThread(int argc, void *argv) {
return 0;
memset(bss, 0, sizeof(struct pygecko_bss_t));
if (OSCreateThread(&bss->thread, start, 1, bss, (u32) bss->stack + sizeof(bss->stack), sizeof(bss->stack), 0,
if (OSCreateThread(&bss->thread, runTCPGeckoServer, 1, bss, (u32) bss->stack + sizeof(bss->stack),
sizeof(bss->stack), 0,
0xc) == 1) {
OSResumeThread(&bss->thread);
} else {
free(bss);
}
if (CCHandler == 1) {
void (*entrypoint)() = (void *) CODE_HANDLER_INSTALL_ADDRESS;
// Execute the code handler if it is installed
if (codeHandlerInstalled) {
void (*codeHandlerFunction)() = (void (*)()) CODE_HANDLER_INSTALL_ADDRESS;
while (1) {
while (true) {
usleep(9000);
entrypoint();
codeHandlerFunction();
}
}
return 0;
}
void start_pygecko() {
void startTCPGecko() {
// Force the debugger to be initialized by default
// writeInt((unsigned int) (OSIsDebuggerInitialized + 0x1C), 0x38000001); // li r3, 1
@ -1381,7 +1453,7 @@ void start_pygecko() {
void *thread = memalign(0x40, 0x1000);
ASSERT_ALLOCATED(thread, "TCP Gecko thread")
int status = OSCreateThread(thread, CCThread, 1,
int status = OSCreateThread(thread, startTCPGeckoThread, 1,
NULL, (u32) stack + sizeof(stack),
sizeof(stack), 0,
OS_THREAD_ATTR_AFFINITY_CORE1 | OS_THREAD_ATTR_PINNED_AFFINITY | OS_THREAD_ATTR_DETACH);

View File

@ -10,7 +10,7 @@ extern "C" {
#endif
//! C wrapper for our C++ functions
void start_pygecko(void);
void startTCPGecko(void);
#ifdef __cplusplus
}

View File

@ -1,6 +1,6 @@
#include <stdio.h>
#include "dynamic_libs/os_functions.h"
#include "utils/logger.h"
#include "../dynamic_libs/os_functions.h"
#include "../utils/logger.h"
#include "exception_handler.h"
#define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4

View File

@ -16,8 +16,8 @@
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "dynamic_libs/os_functions.h"
#include "common/common.h"
#include "../dynamic_libs/os_functions.h"
#include "../common/common.h"
#include "memory.h"
#define MEMORY_ARENA_1 0

View File

@ -2,18 +2,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "common/common.h"
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "../dynamic_libs/os_functions.h"
#include "../dynamic_libs/socket_functions.h"
#include "logger.h"
static int log_socket = 0;
#ifdef DEBUG_LOGGER
static int log_socket = -1;
static volatile int log_lock = 0;
void log_init(const char * ipString)
{
void log_init(const char *ipString) {
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0)
return;
@ -24,30 +21,26 @@ void log_init(const char * ipString)
connect_addr.sin_port = 4405;
inet_aton(ipString, &connect_addr.sin_addr);
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
if (connect(log_socket, (struct sockaddr *) &connect_addr, sizeof(connect_addr)) < 0) {
socketclose(log_socket);
log_socket = -1;
}
}
void log_deinit(void)
{
if(log_socket > 0)
{
void log_deinit(void) {
if (log_socket >= 0) {
socketclose(log_socket);
log_socket = -1;
}
}
void log_print(const char *str)
{
void log_print(const char *str) {
// socket is always 0 initially as it is in the BSS
if(log_socket <= 0) {
if (log_socket < 0) {
return;
}
while(log_lock)
while (log_lock)
usleep(1000);
log_lock = 1;
@ -56,7 +49,7 @@ void log_print(const char *str)
while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
ret = send(log_socket, str, block, 0);
if(ret < 0)
if (ret < 0)
break;
len -= ret;
@ -66,23 +59,22 @@ void log_print(const char *str)
log_lock = 0;
}
void log_printf(const char *format, ...)
{
if(log_socket <= 0) {
void log_printf(const char *format, ...) {
if (log_socket < 0) {
return;
}
char * tmp = NULL;
char *tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
if ((vasprintf(&tmp, format, va) >= 0) && tmp) {
log_print(tmp);
}
va_end(va);
if(tmp)
if (tmp)
free(tmp);
}
#endif

View File

@ -5,85 +5,22 @@
extern "C" {
#endif
/* Communication bytes with the server */
// Com
#define BYTE_NORMAL 0xff
#define BYTE_SPECIAL 0xfe
#define BYTE_OK 0xfd
#define BYTE_PING 0xfc
#define BYTE_LOG_STR 0xfb
#define BYTE_DISCONNECT 0xfa
// SD
#define BYTE_MOUNT_SD 0xe0
#define BYTE_MOUNT_SD_OK 0xe1
#define BYTE_MOUNT_SD_BAD 0xe2
// Replacement
#define BYTE_STAT 0x00
#define BYTE_STAT_ASYNC 0x01
#define BYTE_OPEN_FILE 0x02
#define BYTE_OPEN_FILE_ASYNC 0x03
#define BYTE_OPEN_DIR 0x04
#define BYTE_OPEN_DIR_ASYNC 0x05
#define BYTE_CHANGE_DIR 0x06
#define BYTE_CHANGE_DIR_ASYNC 0x07
#define BYTE_MAKE_DIR 0x08
#define BYTE_MAKE_DIR_ASYNC 0x09
#define BYTE_RENAME 0x0A
#define BYTE_RENAME_ASYNC 0x0B
#define BYTE_REMOVE 0x0C
#define BYTE_REMOVE_ASYNC 0x0D
// Log
#define BYTE_CLOSE_FILE 0x40
#define BYTE_CLOSE_FILE_ASYNC 0x41
#define BYTE_CLOSE_DIR 0x42
#define BYTE_CLOSE_DIR_ASYNC 0x43
#define BYTE_FLUSH_FILE 0x44
#define BYTE_GET_ERROR_CODE_FOR_VIEWER 0x45
#define BYTE_GET_LAST_ERROR 0x46
#define BYTE_GET_MOUNT_SOURCE 0x47
#define BYTE_GET_MOUNT_SOURCE_NEXT 0x48
#define BYTE_GET_POS_FILE 0x49
#define BYTE_SET_POS_FILE 0x4A
#define BYTE_GET_STAT_FILE 0x4B
#define BYTE_EOF 0x4C
#define BYTE_READ_FILE 0x4D
#define BYTE_READ_FILE_ASYNC 0x4E
#define BYTE_READ_FILE_WITH_POS 0x4F
#define BYTE_READ_DIR 0x50
#define BYTE_READ_DIR_ASYNC 0x51
#define BYTE_GET_CWD 0x52
#define BYTE_SET_STATE_CHG_NOTIF 0x53
#define BYTE_TRUNCATE_FILE 0x54
#define BYTE_WRITE_FILE 0x55
#define BYTE_WRITE_FILE_WITH_POS 0x56
#define BYTE_SAVE_INIT 0x57
#define BYTE_SAVE_SHUTDOWN 0x58
#define BYTE_SAVE_INIT_SAVE_DIR 0x59
#define BYTE_SAVE_FLUSH_QUOTA 0x5A
#define BYTE_SAVE_OPEN_DIR 0x5B
#define BYTE_SAVE_REMOVE 0x5C
#define BYTE_CREATE_THREAD 0x60
#define LOADIINE_LOGGER_IP "192.168.178.3"
int logger_connect(int *socket);
void logger_disconnect(int socket);
void log_string(int sock, const char* str, char byte);
void log_byte(int sock, char byte);
#define DEBUG_LOGGER 1
#ifdef DEBUG_LOGGER
void log_init(const char * ip);
void log_deinit(void);
void log_print(const char *str);
void log_printf(const char *format, ...);
#else
#define log_init(x)
#define log_deinit()
#define log_print(x)
#define log_printf(x, ...)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,8 +1,8 @@
#include <string.h>
#include <malloc.h>
#include "common/common.h"
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "../common/common.h"
#include "../dynamic_libs/os_functions.h"
#include "../dynamic_libs/socket_functions.h"
#include "net.h"
static volatile int iLock = 0;

Binary file not shown.