mirror of
https://github.com/Maschell/saviine.git
synced 2024-11-21 22:19:16 +01:00
injection and dumper seems to work now!
- lot of cleanup - needs more testing - changed folder structure for dumps - added dialog for injection seem to crash for some games after dumping.
This commit is contained in:
parent
7356f4029c
commit
721c983122
@ -24,7 +24,7 @@ SFLAGS := -mgekko -mregnames
|
||||
# -memb: enable embedded application specific compilation
|
||||
# -ffunction-sections: split up functions so linker can garbage collect
|
||||
# -fdata-sections: split up data so linker can garbage collect
|
||||
CFLAGS := -O2 -Wall -x c -std=gnu99 \
|
||||
CFLAGS := -O0 -Wall -x c -std=gnu99 \
|
||||
-ffreestanding \
|
||||
-mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar \
|
||||
-msdata=none -memb -ffunction-sections -fdata-sections \
|
||||
|
@ -5,20 +5,8 @@
|
||||
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".magicptr"))); \
|
||||
res my_ ## name(__VA_ARGS__)
|
||||
#define DEBUG_LOG 0
|
||||
extern FSStatus FSOpenDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, int *dh, FSRetFlag errHandling);
|
||||
extern FSStatus FSReadDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSDirEntry *dir_entry, FSRetFlag errHandling);
|
||||
extern FSStatus FSChangeDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSRetFlag errHandling);
|
||||
extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFlag errHandling);
|
||||
extern FSStatus FSReadFile(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error);
|
||||
extern FSStatus FSSetPosFile(FSClient *pClient, FSCmdBlock *pCmd, int fd, int pos, int error);
|
||||
extern FSStatus FSCloseFile (FSClient *pClient, FSCmdBlock *pCmd, int fd, int error);
|
||||
extern FSStatus FSMakeDir(FSClient *pClient, FSCmdBlock *pCmd,const char *path, FSRetFlag errHandling);
|
||||
extern FSStatus FSRemove(FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSRetFlag errHandling);
|
||||
extern void OSDynLoad_Acquire (char* rpl, unsigned int *handle);
|
||||
extern void OSDynLoad_FindExport (unsigned int handle, int isdata, char *symbol, void *address);
|
||||
void GX2WaitForVsync(void);
|
||||
static void handle_saves(void *pClient, void *pCmd,int error, int client);
|
||||
static void hook(void * pClient,void * pCmd, int error, int client);
|
||||
#define BUFFER_SIZE (1024)*100*2
|
||||
#define BUFFER_SIZE_STEPS 0x200
|
||||
|
||||
DECL(int, FSAInit, void) {
|
||||
if ((int)bss_ptr == 0x0a000000) {
|
||||
@ -56,24 +44,6 @@ static int strlen(char* path) {
|
||||
return i;
|
||||
}
|
||||
|
||||
static int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while(*s1 && *s2)
|
||||
{
|
||||
if(*s1 != *s2) {
|
||||
return -1;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
if(*s1 != *s2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int client_num_alloc(void *pClient) {
|
||||
int i;
|
||||
|
||||
@ -153,7 +123,7 @@ DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
|
||||
// Init command block.
|
||||
FSInitCmdBlock(pCmd);
|
||||
|
||||
hook(pClient, pCmd,-1, client);
|
||||
hook(pClient, pCmd,-1);
|
||||
bss.saveFolderChecked = 2;
|
||||
|
||||
error: real_FSDelClient(pClient);
|
||||
@ -168,333 +138,259 @@ DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
|
||||
return res;
|
||||
}
|
||||
|
||||
static int remove_files_in_dir(void * pClient,void * pCmd, char * path, int handle){
|
||||
int ret = 0;
|
||||
if ((ret = FSOpenDir(pClient, pCmd, path, &handle, FS_RET_ALL_ERROR)) == FS_STATUS_OK){
|
||||
char buffer[strlen(path) + 25];
|
||||
|
||||
__os_snprintf(buffer, sizeof(buffer), "remove files in dir %s",path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
FSDirEntry dir_entry;
|
||||
while (FSReadDir(pClient, pCmd, handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
|
||||
{
|
||||
char full_path[255];
|
||||
int i=0;
|
||||
char *path_ptr = (char *)path;
|
||||
while(*path_ptr) {
|
||||
full_path[i++] = *path_ptr++;
|
||||
}
|
||||
full_path[i++] = '/';
|
||||
char *dir_name_ptr = (char *)dir_entry.name;
|
||||
while(*dir_name_ptr) {
|
||||
full_path[i++] = *dir_name_ptr++;
|
||||
}
|
||||
full_path[i++] = '\0';
|
||||
char buffer[strlen(full_path) + 50];
|
||||
__os_snprintf(buffer, sizeof(buffer), "deleting %s",full_path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
if((ret = FSRemove(pClient,pCmd,full_path,-1)) < 0){
|
||||
__os_snprintf(buffer, sizeof(buffer), "error: %d on %s",ret,full_path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if((FSCloseDir(pClient, pCmd, handle, FS_RET_NO_ERROR)) < 0 ){
|
||||
log_string(bss.logsock, "error while closing dir", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hook(void * pClient,void * pCmd, int error, int client){
|
||||
void hook(void * pClient,void * pCmd, int error){
|
||||
log_string(bss.logsock, "hook", BYTE_LOG_STR);
|
||||
handle_saves(pClient, pCmd,-1, client);
|
||||
handle_saves(pClient, pCmd,-1);
|
||||
}
|
||||
|
||||
static void init_Save(){
|
||||
int (*SAVEInit)();
|
||||
unsigned int save_handle;
|
||||
OSDynLoad_Acquire("nn_save.rpl", &save_handle);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInit", (void **)&SAVEInit);
|
||||
SAVEInit();
|
||||
}
|
||||
|
||||
static long getPesistentID(){
|
||||
unsigned int nn_act_handle;
|
||||
unsigned long (*GetPersistentIdEx)(unsigned char);
|
||||
int (*GetSlotNo)(void);
|
||||
void (*nn_Initialize)(void);
|
||||
void (*nn_Finalize)(void);
|
||||
OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "GetPersistentIdEx__Q2_2nn3actFUc", (void **)&GetPersistentIdEx);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "GetSlotNo__Q2_2nn3actFv", (void **)&GetSlotNo);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "Initialize__Q2_2nn3actFv", (void **)&nn_Initialize);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "Finalize__Q2_2nn3actFv", (void **)&nn_Finalize);
|
||||
|
||||
nn_Initialize(); // To be sure that it is really Initialized
|
||||
|
||||
unsigned char slotno = GetSlotNo();
|
||||
long idlong = GetPersistentIdEx(slotno);
|
||||
|
||||
|
||||
nn_Finalize(); //must be called an equal number of times to nn_Initialize
|
||||
return idlong;
|
||||
}
|
||||
|
||||
#define DUMP_BLOCK_SIZE (0x200 * 100)
|
||||
#define DUMP_BLOCK_SIZE_SLOW (0x20 * 100)
|
||||
static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error, int handle){
|
||||
int dir_handle = handle;
|
||||
int my_handle = handle +1;
|
||||
int ret = 0;
|
||||
if ((ret = FSOpenDir(pClient, pCmd, path, &dir_handle, FS_RET_ALL_ERROR)) == FS_STATUS_OK)
|
||||
{
|
||||
char buffer[strlen(path) + 25];
|
||||
|
||||
__os_snprintf(buffer, sizeof(buffer), "open dir %s",path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
FSDirEntry dir_entry;
|
||||
while (FSReadDir(pClient, pCmd, dir_handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
|
||||
{
|
||||
char full_path[255];
|
||||
int i=0;
|
||||
char *path_ptr = (char *)path;
|
||||
while(*path_ptr) {
|
||||
full_path[i++] = *path_ptr++;
|
||||
}
|
||||
full_path[i++] = '/';
|
||||
char *dir_name_ptr = (char *)dir_entry.name;
|
||||
while(*dir_name_ptr) {
|
||||
full_path[i++] = *dir_name_ptr++;
|
||||
}
|
||||
full_path[i++] = '\0';
|
||||
|
||||
|
||||
|
||||
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
|
||||
log_string(bss.logsock, "-> dir", BYTE_LOG_STR);
|
||||
dump_dir(pClient,client, pCmd,full_path,-1,my_handle);
|
||||
}else{
|
||||
//DUMP
|
||||
ret = FSOpenFile(pClient, pCmd, full_path, "r", &my_handle, FS_RET_ALL_ERROR);
|
||||
if (ret >= 0) {
|
||||
__os_snprintf(buffer, sizeof(buffer), "dumping %s",dir_entry.name);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
int my_ret = cafiine_send_handle(bss.socket_fsa[client], client, full_path, my_handle);
|
||||
|
||||
|
||||
|
||||
int size = (my_ret == 1 ? DUMP_BLOCK_SIZE : DUMP_BLOCK_SIZE_SLOW);
|
||||
void * buffer = memalign(sizeof(char) * size, 0x40);
|
||||
int ret2;
|
||||
while ((ret2 = FSReadFile(pClient, pCmd, buffer, 1, size, my_handle, 0, 0)) > 0)
|
||||
cafiine_send_file(bss.socket_fsa[client], buffer, ret2, my_handle);
|
||||
cafiine_fclose(bss.socket_fsa[client], &ret2, my_handle,1);
|
||||
FSSetPosFile(pClient, pCmd, my_handle, 0, FS_RET_ALL_ERROR);
|
||||
free(buffer);
|
||||
FSCloseFile(pClient, pCmd, my_handle, -1);
|
||||
}else{
|
||||
char type[2];
|
||||
type[0] = '9' + ret;
|
||||
type[1] = '\0';
|
||||
log_string(bss.logsock, type, BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
FSCloseDir(pClient, pCmd, dir_handle, FS_RET_NO_ERROR);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#define BUFFER_SIZE (1024)*100
|
||||
static void handle_saves(void *pClient, void *pCmd,int error, int client){
|
||||
log_string(bss.logsock, "handle_saves", BYTE_LOG_STR);
|
||||
init_Save();
|
||||
long id = getPesistentID();
|
||||
void handle_saves(void *pClient, void *pCmd,int error){
|
||||
log_string(bss.logsock, "init", BYTE_LOG_STR);
|
||||
int client = client_num(pClient);
|
||||
unsigned char slotNo;
|
||||
long id = getPesistentID(&slotNo);
|
||||
init_Save(slotNo);
|
||||
int mode;
|
||||
log_string(bss.logsock, "user savedata", BYTE_LOG_STR);
|
||||
|
||||
log_string(bss.logsock, "getting mode", BYTE_LOG_STR);
|
||||
if(getMode(bss.socket_fsa[client],&mode)){
|
||||
if(id >= 0x80000000 && id <= 0x90000000){
|
||||
char savepath[20];
|
||||
|
||||
char savepath[20];
|
||||
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",id);
|
||||
log_string(bss.logsock, "Getting mode!", BYTE_LOG_STR);
|
||||
{
|
||||
if(mode == BYTE_MODE_D){
|
||||
log_string(bss.logsock, "dump mode!", BYTE_LOG_STR);
|
||||
dump_dir(pClient,client,pCmd,savepath,-1,50);
|
||||
}else if(mode == BYTE_MODE_I){
|
||||
log_string(bss.logsock, "inject mode", BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "deleting current save", BYTE_LOG_STR);
|
||||
remove_files_in_dir(pClient,pCmd,savepath,0);
|
||||
int buf_size = BUFFER_SIZE;
|
||||
char * pBuffer;
|
||||
int failed = 0;
|
||||
do{
|
||||
buf_size -= 0x200;
|
||||
if(buf_size < 0){
|
||||
log_string(bss.logsock, "error on buffer allocation", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40);
|
||||
}while(!pBuffer);
|
||||
if(!failed){
|
||||
int result = injectFiles(pClient,pCmd,savepath,"/",pBuffer,buf_size,-1);
|
||||
if(result == -1){
|
||||
log_string(bss.logsock, "injection failed, trying to restore the data", BYTE_LOG_STR);
|
||||
//TODO FSRollbackQuota
|
||||
}else{
|
||||
char logbugger[50];
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "injected %d files, flushing the data now",result);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
if(FSFlushQuota(pClient,pCmd,savepath,-1) == 0){
|
||||
log_string(bss.logsock, "success", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(mode == BYTE_MODE_D){
|
||||
log_string(bss.logsock, "dump mode!", BYTE_LOG_STR);
|
||||
dumpSavaData(pClient, pCmd,id,error);
|
||||
}else if(mode == BYTE_MODE_I){
|
||||
log_string(bss.logsock, "inject mode", BYTE_LOG_STR);
|
||||
injectSaveData(pClient,pCmd,id,error);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dumpSavaData(void *pClient, void *pCmd,long persistentID,int error){
|
||||
int client = client_num(pClient);
|
||||
/*
|
||||
Allocate buffer for injection
|
||||
*/
|
||||
int buf_size = BUFFER_SIZE;
|
||||
char * pBuffer;
|
||||
int failed = 0;
|
||||
do{
|
||||
buf_size -= BUFFER_SIZE_STEPS;
|
||||
if(buf_size < 0){
|
||||
log_string(bss.logsock, "error on buffer allocation", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
if(mode == BYTE_MODE_D){
|
||||
log_string(bss.logsock, "dumping common savedata", BYTE_LOG_STR);
|
||||
dump_dir(pClient,client,pCmd,"/vol/save/common/",error,60);
|
||||
log_string(bss.logsock, "done!", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "common injection", BYTE_LOG_STR);
|
||||
int buf_size = BUFFER_SIZE;
|
||||
char * pBuffer;
|
||||
int failed = 0;
|
||||
do{
|
||||
buf_size -= 0x200;
|
||||
if(buf_size < 0){
|
||||
log_string(bss.logsock, "error on buffer allocation", BYTE_LOG_STR);
|
||||
pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40);
|
||||
}while(!pBuffer);
|
||||
|
||||
if(!failed){
|
||||
int mask = 0;
|
||||
char buffer[60];
|
||||
__os_snprintf(buffer, sizeof(buffer), "allocated %d bytes",buf_size);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
if(saviine_start_dump(bss.socket_fsa[client], persistentID,&mask)){
|
||||
if((mask & MASK_USER) == MASK_USER){
|
||||
char savepath[20];
|
||||
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",persistentID);
|
||||
log_string(bss.logsock, "user savedata", BYTE_LOG_STR);
|
||||
if(dump_dir(pClient,pCmd,savepath,pBuffer,buf_size,-1,50) == -1){
|
||||
log_string(bss.logsock, "error dumping user dir", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40);
|
||||
}while(!pBuffer);
|
||||
if(!failed){
|
||||
int result = injectFiles(pClient,pCmd,"/vol/save/common/","/",pBuffer,buf_size,-1);
|
||||
if(result == -1){
|
||||
log_string(bss.logsock, "injection failed, trying to restore the data", BYTE_LOG_STR);
|
||||
//TODO FSRollbackQuota
|
||||
}else{
|
||||
char logbugger[50];
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "injected %d files, flushing the data now",result);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
if(FSFlushQuota(pClient,pCmd,"/vol/save/common/",-1) == 0){
|
||||
log_string(bss.logsock, "success", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
if((mask & MASK_COMMON) == MASK_COMMON && !failed){
|
||||
char * commonDir = "/vol/save/common";
|
||||
log_string(bss.logsock, "dumping common savedata", BYTE_LOG_STR);
|
||||
if(dump_dir(pClient,pCmd,commonDir,pBuffer,buf_size,error,60) == -1){
|
||||
log_string(bss.logsock, "error dumping common dir (maybe the game has no common folder?)", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
log_string(bss.logsock, "done!", BYTE_LOG_STR);
|
||||
|
||||
if(!saviine_end_dump(bss.socket_fsa[client])) if(DEBUG_LOG) log_string(bss.logsock, "saviine_end_injection() failed", BYTE_LOG_STR);
|
||||
free(pBuffer);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "end of dump", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "saviine_start_dump() failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dump_dir(void *pClient, void *pCmd, char *path, void * pBuffer, int size,int error, int handle){
|
||||
int client = client_num(pClient);
|
||||
int dir_handle = handle;
|
||||
int my_handle = handle +1;
|
||||
int ret = 0;
|
||||
int final_result = 0;
|
||||
if ((ret = FSOpenDir(pClient, pCmd, path, &dir_handle, FS_RET_ALL_ERROR)) == FS_STATUS_OK){
|
||||
char buffer[strlen(path) + 25];
|
||||
__os_snprintf(buffer, sizeof(buffer), "open dir %s",path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
FSDirEntry dir_entry;
|
||||
while (FSReadDir(pClient, pCmd, dir_handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK && final_result == 0)
|
||||
{
|
||||
char full_path[strlen(path) + 1 + strlen(dir_entry.name) +1];
|
||||
__os_snprintf(full_path, sizeof(full_path), "%s/%s",path,dir_entry.name);
|
||||
|
||||
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
|
||||
log_string(bss.logsock, "-> dir", BYTE_LOG_STR);
|
||||
if(dump_dir(pClient, pCmd,full_path,pBuffer,size,-1,my_handle) == -1){
|
||||
log_string(bss.logsock, "error", BYTE_LOG_STR);
|
||||
final_result = -1;
|
||||
}
|
||||
}else{
|
||||
//DUMP
|
||||
ret = FSOpenFile(pClient, pCmd, full_path, "r", &my_handle, FS_RET_ALL_ERROR);
|
||||
if (ret >= 0) {
|
||||
__os_snprintf(buffer, sizeof(buffer), "dumping %s",dir_entry.name);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
|
||||
int buf_size = BUFFER_SIZE;
|
||||
int ret2;
|
||||
|
||||
int my_ret = cafiine_send_handle(bss.socket_fsa[client], client, full_path, my_handle);
|
||||
if(my_ret != -1){
|
||||
while ((ret2 = FSReadFile(pClient, pCmd, pBuffer, 1, buf_size, my_handle, 0, 0)) > 0)
|
||||
cafiine_send_file(bss.socket_fsa[client], pBuffer, ret2, my_handle);
|
||||
cafiine_fclose(bss.socket_fsa[client], &ret2, my_handle,1);
|
||||
}else{
|
||||
log_string(bss.logsock, "error on opening file on pc" , BYTE_LOG_STR);
|
||||
final_result = -1;
|
||||
}
|
||||
|
||||
FSSetPosFile(pClient, pCmd, my_handle, 0, FS_RET_ALL_ERROR);
|
||||
FSCloseFile(pClient, pCmd, my_handle, -1);
|
||||
}else{
|
||||
char buffer[100];
|
||||
__os_snprintf(buffer, sizeof(buffer), "error on FSOpenFile: %d",ret);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
final_result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
FSCloseDir(pClient, pCmd, dir_handle, FS_RET_NO_ERROR);
|
||||
}else{
|
||||
log_string(bss.logsock, "error on FSOpenDir()", BYTE_LOG_STR);
|
||||
final_result = -1;
|
||||
}
|
||||
return final_result;
|
||||
}
|
||||
|
||||
/**************************
|
||||
Injection functions
|
||||
**************************/
|
||||
void injectSaveData(void *pClient, void *pCmd,long persistentID,int error){
|
||||
int client = client_num(pClient);
|
||||
char logbuffer[255];
|
||||
/*
|
||||
Allocate buffer for injection
|
||||
*/
|
||||
int buf_size = BUFFER_SIZE;
|
||||
char * pBuffer;
|
||||
int failed = 0;
|
||||
do{
|
||||
buf_size -= BUFFER_SIZE_STEPS;
|
||||
if(buf_size < 0){
|
||||
log_string(bss.logsock, "error on buffer allocation", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40);
|
||||
}while(!pBuffer);
|
||||
|
||||
if(!failed){
|
||||
int result = 0;
|
||||
int mask = 0;
|
||||
if((result = saviine_start_injection(bss.socket_fsa[client], persistentID,&mask))){
|
||||
if((mask & MASK_USER) == MASK_USER){
|
||||
char savepath[20];
|
||||
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",persistentID);
|
||||
__os_snprintf(logbuffer, sizeof(logbuffer), "injecting new userdata in %08x",persistentID);
|
||||
log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "deleting userdata save", BYTE_LOG_STR);
|
||||
if(remove_files_in_dir(pClient,pCmd,savepath,0) == -1){
|
||||
failed = 1;
|
||||
}else{
|
||||
/*
|
||||
Inject Save
|
||||
*/
|
||||
result = injectFiles(pClient,pCmd,savepath,"/",pBuffer,buf_size,-1);
|
||||
doFlushOrRollback(pClient,pCmd,result,savepath);
|
||||
}
|
||||
}
|
||||
if((mask & MASK_COMMON) == MASK_COMMON && !failed){
|
||||
char * commonDir = "/vol/save/common";
|
||||
|
||||
if((mask & MASK_COMMON_CLEAN) == MASK_COMMON_CLEAN){
|
||||
log_string(bss.logsock, "deleting common save", BYTE_LOG_STR);
|
||||
if(remove_files_in_dir(pClient,pCmd,commonDir,0) == -1){
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if(!failed){
|
||||
/*
|
||||
Inject common
|
||||
*/
|
||||
result = injectFiles(pClient,pCmd,commonDir,"/",pBuffer,buf_size,-1);
|
||||
doFlushOrRollback(pClient,pCmd,result,commonDir);
|
||||
}
|
||||
}
|
||||
if(!saviine_end_injection(bss.socket_fsa[client])) if(DEBUG_LOG) log_string(bss.logsock, "saviine_end_injection() failed", BYTE_LOG_STR);
|
||||
free(pBuffer);
|
||||
if(DEBUG_LOG)log_string(bss.logsock, "end of injection", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "saviine_start_injection() failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char * pBuffer, int buffer_size, int error){
|
||||
|
||||
//FSStatus (*FSWriteFileWithPos) (FSClient *pClient, FSCmdBlock *pCmd, const void *source,int size,int count,int fpos,int fileHandle,int flag,FSRetFlag errHandling);
|
||||
int client = client_num(pClient);
|
||||
int failed = 0;
|
||||
int filesinjected = 0;
|
||||
int type = 0;
|
||||
log_string(bss.logsock, "injecting files", BYTE_LOG_STR);
|
||||
char namebuffer[255];
|
||||
char logbugger[255];
|
||||
char logbuffer[255];
|
||||
int filesize = 0;
|
||||
|
||||
|
||||
|
||||
if(!failed){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "buffer size: %d bytes",buffer_size);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
__os_snprintf(logbuffer, sizeof(logbuffer), "buffer size: %d bytes",buffer_size);
|
||||
log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
|
||||
while(getFiles(bss.socket_fsa[client],path,namebuffer, &type,&filesize) && !failed){
|
||||
|
||||
while(saviine_readdir(bss.socket_fsa[client],path,namebuffer, &type,&filesize) && !failed){
|
||||
if(DEBUG_LOG)log_string(bss.logsock, "got a file", BYTE_LOG_STR);
|
||||
char newpath[strlen(path) + 1 + strlen(namebuffer)];
|
||||
__os_snprintf(newpath, sizeof(newpath), "%s/%s",path,namebuffer);
|
||||
if(type == BYTE_FILE){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "file: %s%s size: %d",relativepath,namebuffer,filesize);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
__os_snprintf(logbuffer, sizeof(logbuffer), "file: %s%s size: %d",relativepath,namebuffer,filesize);
|
||||
log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "downloading it", BYTE_LOG_STR);
|
||||
|
||||
int handle = 10;
|
||||
if(FSOpenFile(pClient, pCmd, newpath,"w+",&handle,-1) >= 0){
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "file opened and created", BYTE_LOG_STR);
|
||||
if(filesize > 0){
|
||||
int myhandle;
|
||||
int ret = 0;
|
||||
if((cafiine_fopen(bss.socket_fsa[client], &ret, newpath, "r", &myhandle)) == 0 && ret == 0){
|
||||
if(DEBUG_LOG)__os_snprintf(logbugger, sizeof(logbugger), "cafiine_fopen with handle %d",myhandle);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
int size = sizeof(char);
|
||||
int count = buffer_size;
|
||||
int retsize = 0;
|
||||
int pos = 0;
|
||||
while(pos < filesize){
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "reading", BYTE_LOG_STR);
|
||||
if(DEBUG_LOG)__os_snprintf(logbugger, sizeof(logbugger), "count %d",count);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
if(cafiine_fread(bss.socket_fsa[client], &retsize, pBuffer, count, myhandle) == 0){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "got %d",retsize);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
int fwrite = 0;
|
||||
if((fwrite = my_FSWriteFile(pClient, pCmd, pBuffer,size,retsize,handle,0,0x0200)) >= 0){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "wrote %d",retsize);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
}else{
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "my_FSWriteFile failed with error: %d",fwrite);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "error while FSWriteFile", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "old p %d new p %d",pos,pos+retsize);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
pos += retsize;
|
||||
}else{
|
||||
log_string(bss.logsock, "error while recieving file", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if((cafiine_fclose(bss.socket_fsa[client], &result, myhandle,0)) == 0 && result == 0){
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "cafiine_fclose success", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "cafiine_fclose failed", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
log_string(bss.logsock, "cafiine_fopen failed", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
if(filesize > 0){
|
||||
failed = doInjectForFile(pClient,pCmd,handle,newpath,filesize,pBuffer,buffer_size);
|
||||
}else{
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "filesize is 0", BYTE_LOG_STR);
|
||||
}
|
||||
|
||||
if((FSCloseFile (pClient, pCmd, handle, -1)) < 0){
|
||||
log_string(bss.logsock, "FSCloseFile failed", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}else{
|
||||
log_string(bss.logsock, "opening the file failed", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
if(!failed) filesinjected++;
|
||||
}else if( type == BYTE_FOLDER){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "dir: %s",namebuffer);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
__os_snprintf(logbuffer, sizeof(logbuffer), "dir: %s",namebuffer);
|
||||
log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, newpath, BYTE_LOG_STR);
|
||||
if(FSMakeDir(pClient, pCmd, newpath, -1) == 0){
|
||||
char op_offset[strlen(relativepath) + strlen(namebuffer)+ 1 + 1];
|
||||
@ -510,14 +406,163 @@ int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(pBuffer);
|
||||
}
|
||||
if(failed) return -1;
|
||||
else return filesinjected;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int doInjectForFile(void * pClient, void * pCmd,int handle,char * filepath,int filesize,void * pBuffer,int buf_size){
|
||||
int client = client_num(pClient);
|
||||
int failed = 0;
|
||||
int myhandle;
|
||||
int ret = 0;
|
||||
char logbuffer[255];
|
||||
if((cafiine_fopen(bss.socket_fsa[client], &ret, filepath, "r", &myhandle)) == 0 && ret == 0){
|
||||
if(DEBUG_LOG)__os_snprintf(logbuffer, sizeof(logbuffer), "cafiine_fopen with handle %d",myhandle);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
int retsize = 0;
|
||||
int pos = 0;
|
||||
while(pos < filesize){
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "reading", BYTE_LOG_STR);
|
||||
if(cafiine_fread(bss.socket_fsa[client], &retsize, pBuffer, buf_size , myhandle) == 0){
|
||||
if(DEBUG_LOG)__os_snprintf(logbuffer, sizeof(logbuffer), "got %d",retsize);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
int fwrite = 0;
|
||||
if((fwrite = my_FSWriteFile(pClient, pCmd, pBuffer,sizeof(char),retsize,handle,0,0x0200)) >= 0){
|
||||
if(DEBUG_LOG)__os_snprintf(logbuffer, sizeof(logbuffer), "wrote %d",retsize);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
}else{
|
||||
if(DEBUG_LOG)__os_snprintf(logbuffer, sizeof(logbuffer), "my_FSWriteFile failed with error: %d",fwrite);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "error while FSWriteFile", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
if(DEBUG_LOG)__os_snprintf(logbuffer, sizeof(logbuffer), "old p %d new p %d",pos,pos+retsize);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
pos += retsize;
|
||||
}else{
|
||||
log_string(bss.logsock, "error while recieving file", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if((cafiine_fclose(bss.socket_fsa[client], &result, myhandle,0)) == 0 && result == 0){
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "cafiine_fclose success", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "cafiine_fclose failed", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
log_string(bss.logsock, "cafiine_fopen failed", BYTE_LOG_STR);
|
||||
failed = 1;
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
/*************************
|
||||
Util functions
|
||||
**************************/
|
||||
|
||||
/*flush if result != -1*/
|
||||
void doFlushOrRollback(void *pClient, void *pCmd,int result,char *savepath){
|
||||
char logbuffer[50 + strlen(savepath)];
|
||||
if(result != -1){
|
||||
__os_snprintf(logbuffer, sizeof(logbuffer), "injected %d files",result);
|
||||
log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "Flushing data now", BYTE_LOG_STR);
|
||||
if(FSFlushQuota(pClient,pCmd,savepath,-1) == 0){
|
||||
log_string(bss.logsock, "success", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "failed", BYTE_LOG_STR);
|
||||
}
|
||||
}else{
|
||||
log_string(bss.logsock, "injection failed, trying to restore the data", BYTE_LOG_STR);
|
||||
if(FSRollbackQuota(pClient,pCmd,savepath,-1) == 0){
|
||||
log_string(bss.logsock, "rollback done", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "rollback failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_Save(unsigned char slotNo){
|
||||
int (*SAVEInit)();
|
||||
int (*SAVEInitSaveDir)(unsigned char accountSlotNo);
|
||||
unsigned int save_handle;
|
||||
OSDynLoad_Acquire("nn_save.rpl", &save_handle);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInit", (void **)&SAVEInit);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInitSaveDir", (void **)&SAVEInitSaveDir);
|
||||
|
||||
SAVEInit();
|
||||
SAVEInitSaveDir(slotNo);
|
||||
SAVEInitSaveDir(255U);
|
||||
}
|
||||
|
||||
long getPesistentID(unsigned char * slotno){
|
||||
unsigned int nn_act_handle;
|
||||
unsigned long (*GetPersistentIdEx)(unsigned char);
|
||||
int (*GetSlotNo)(void);
|
||||
void (*nn_Initialize)(void);
|
||||
void (*nn_Finalize)(void);
|
||||
OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "GetPersistentIdEx__Q2_2nn3actFUc", (void **)&GetPersistentIdEx);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "GetSlotNo__Q2_2nn3actFv", (void **)&GetSlotNo);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "Initialize__Q2_2nn3actFv", (void **)&nn_Initialize);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "Finalize__Q2_2nn3actFv", (void **)&nn_Finalize);
|
||||
|
||||
nn_Initialize(); // To be sure that it is really Initialized
|
||||
|
||||
*slotno = GetSlotNo();
|
||||
|
||||
long idlong = GetPersistentIdEx(*slotno);
|
||||
|
||||
nn_Finalize(); //must be called an equal number of times to nn_Initialize
|
||||
return idlong;
|
||||
}
|
||||
|
||||
int remove_files_in_dir(void * pClient,void * pCmd, char * path, int handle){
|
||||
int ret = 0;
|
||||
int my_handle = handle +1;
|
||||
char buffer[strlen(path) + 50];
|
||||
if ((ret = FSOpenDir(pClient, pCmd, path, &handle, FS_RET_ALL_ERROR)) == FS_STATUS_OK){
|
||||
__os_snprintf(buffer, sizeof(buffer), "remove files in dir %s",path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
FSDirEntry dir_entry;
|
||||
while (FSReadDir(pClient, pCmd, handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
|
||||
{
|
||||
char full_path[strlen(path) + 1 + strlen(dir_entry.name) +1];
|
||||
__os_snprintf(full_path, sizeof(full_path), "%s/%s",path,dir_entry.name);
|
||||
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
|
||||
log_string(bss.logsock, "recursive deletion", BYTE_LOG_STR);
|
||||
if(remove_files_in_dir(pClient,pCmd,full_path,my_handle) == -1) return -1;
|
||||
}else{
|
||||
char buffer[strlen(full_path) + 50];
|
||||
__os_snprintf(buffer, sizeof(buffer), "deleting %s",full_path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
if((ret = FSRemove(pClient,pCmd,full_path,-1)) < 0){
|
||||
__os_snprintf(buffer, sizeof(buffer), "error: %d on removing %s",ret,full_path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if((FSCloseDir(pClient, pCmd, handle, FS_RET_NO_ERROR)) < 0 ){
|
||||
log_string(bss.logsock, "error while closing dir", BYTE_LOG_STR);
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
__os_snprintf(buffer, sizeof(buffer), "error: %d on opening %s",ret,path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAKE_MAGIC(x) { x, my_ ## x, &real_ ## x }
|
||||
@ -537,6 +582,4 @@ struct magic_t {
|
||||
MAKE_MAGIC(FSDelClient),
|
||||
MAKE_MAGIC(FSWriteFile),
|
||||
MAKE_MAGIC(FSFlushQuota),
|
||||
|
||||
|
||||
};
|
||||
|
@ -24,9 +24,18 @@
|
||||
#define BYTE_LOG_STR 0xfb
|
||||
#define BYTE_FILE 0xC0
|
||||
#define BYTE_FOLDER 0xC1
|
||||
#define BYTE_GET_FILES 0xCC
|
||||
#define BYTE_READ_DIR 0xCC
|
||||
#define BYTE_INJECTSTART 0x40
|
||||
#define BYTE_INJECTEND 0x41
|
||||
#define BYTE_DUMPSTART 0x42
|
||||
#define BYTE_DUMPEND 0x43
|
||||
#define BYTE_END 0xfd
|
||||
|
||||
#define MASK_NORMAL 0x8000
|
||||
#define MASK_USER 0x0100
|
||||
#define MASK_COMMON 0x0200
|
||||
#define MASK_COMMON_CLEAN 0x0400
|
||||
|
||||
void *memcpy(void *dst, const void *src, int bytes);
|
||||
void *memset(void *dst, int val, int bytes);
|
||||
|
||||
@ -47,16 +56,40 @@ extern FSStatus FSAddClient(FSClient *pClient, FSRetFlag errHandling);
|
||||
extern void FSInitCmdBlock(FSCmdBlock *pCmd);
|
||||
extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFlag errHandling);
|
||||
extern FSStatus FSOpenFile(FSClient *pClient, FSCmdBlock *pCmd, char *path,char *mode,int *dh,FSRetFlag errHandling);
|
||||
|
||||
extern FSStatus FSOpenDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, int *dh, FSRetFlag errHandling);
|
||||
extern FSStatus FSReadDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSDirEntry *dir_entry, FSRetFlag errHandling);
|
||||
extern FSStatus FSChangeDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSRetFlag errHandling);
|
||||
extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFlag errHandling);
|
||||
extern FSStatus FSReadFile(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error);
|
||||
extern FSStatus FSSetPosFile(FSClient *pClient, FSCmdBlock *pCmd, int fd, int pos, int error);
|
||||
extern FSStatus FSCloseFile (FSClient *pClient, FSCmdBlock *pCmd, int fd, int error);
|
||||
extern FSStatus FSMakeDir(FSClient *pClient, FSCmdBlock *pCmd,const char *path, FSRetFlag errHandling);
|
||||
extern FSStatus FSRemove(FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSRetFlag errHandling);
|
||||
extern FSStatus FSRollbackQuota(FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSRetFlag errHandling);
|
||||
extern void OSDynLoad_Acquire (char* rpl, unsigned int *handle);
|
||||
extern void OSDynLoad_FindExport (unsigned int handle, int isdata, char *symbol, void *address);
|
||||
|
||||
extern void socket_lib_init();
|
||||
extern int socket(int domain, int type, int protocol);
|
||||
extern int socketclose(int socket);
|
||||
extern int connect(int socket, void *addr, int addrlen);
|
||||
extern int send(int socket, const void *buffer, int size, int flags);
|
||||
extern int recv(int socket, void *buffer, int size, int flags);
|
||||
|
||||
extern int __os_snprintf(char* s, int n, const char * format, ...);
|
||||
int getFiles(int sock, char * path,char * resultname, int * resulttype,int *filesize);
|
||||
|
||||
int saviine_readdir(int sock, char * path,char * resultname, int * resulttype,int *filesize);
|
||||
int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char * pBuffer, int buffer_size, int error);
|
||||
void doFlushOrRollback(void *pClient,void *pCmd,int result,char *savepath);
|
||||
void injectSaveData(void *pClient, void *pCmd,long persistentID,int error);
|
||||
void dumpSavaData(void *pClient, void *pCmd,long persistentID,int error);
|
||||
long getPesistentID(unsigned char * slotno);
|
||||
void init_Save(unsigned char slotNo);
|
||||
int doInjectForFile(void * pClient, void * pCmd,int handle,char * filepath,int filesize,void * pBuffer,int buf_size);
|
||||
void handle_saves(void *pClient, void *pCmd,int error);
|
||||
void hook(void * pClient,void * pCmd, int error);
|
||||
int dump_dir(void *pClient, void *pCmd, char *path, void * pBuffer, int size,int error, int handle);
|
||||
int remove_files_in_dir(void * pClient,void * pCmd, char * path, int handle);
|
||||
|
||||
struct in_addr {
|
||||
unsigned int s_addr;
|
||||
@ -101,4 +134,9 @@ int cafiine_fgetpos(int socket, int *result, int fd, int *pos);
|
||||
int cafiine_fstat(int sock, int *result, int fd, void *ptr);
|
||||
int cafiine_feof(int sock, int *result, int fd);
|
||||
void cafiine_send_ping(int sock, int val1, int val2);
|
||||
void log_string(int sock, const char* str, char flag_byte);
|
||||
void log_string(int sock, const char* str, char flag_byte);
|
||||
|
||||
int saviine_end_injection(int sock);
|
||||
int saviine_start_injection(int sock, long persistentID,int * mask);
|
||||
int saviine_start_dump(int sock, long persistentID,int * mask);
|
||||
int saviine_end_dump(int sock);
|
@ -72,9 +72,8 @@ int getMode(int sock,int * result)
|
||||
{
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
// create and send buffer with : [cmd id][fd][size][buffer data ...]
|
||||
{
|
||||
@ -145,6 +144,8 @@ int cafiine_send_handle(int sock, int client, const char *path, int handle)
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_SPECIAL);
|
||||
if(ret == BYTE_REQUEST){
|
||||
ret = 1;
|
||||
}else{
|
||||
@ -152,6 +153,7 @@ int cafiine_send_handle(int sock, int client, const char *path, int handle)
|
||||
}
|
||||
// wait reply
|
||||
int special_ret = recvbyte(sock);
|
||||
CHECK_ERROR(special_ret < 0);
|
||||
CHECK_ERROR(special_ret != BYTE_SPECIAL);
|
||||
bss.lock = 0;
|
||||
return ret;
|
||||
@ -164,10 +166,9 @@ error:
|
||||
int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int *handle) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
int final_result = -1;
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int final_ret = 0;
|
||||
int ret;
|
||||
int len_path = 0;
|
||||
while (path[len_path++]);
|
||||
@ -186,23 +187,23 @@ int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int
|
||||
buffer[9 + len_path + ret] = mode[ret];
|
||||
|
||||
ret = sendwait(sock, buffer, 1 + 8 + len_path + len_mode);
|
||||
}
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwait(sock, handle, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwait(sock, handle, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
}
|
||||
final_result = 0;
|
||||
|
||||
|
||||
quit:
|
||||
bss.lock = 0;
|
||||
return final_ret;
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return -1;
|
||||
return final_result;
|
||||
}
|
||||
|
||||
void cafiine_send_file(int sock, char *file, int size, int fd) {
|
||||
@ -225,7 +226,7 @@ void cafiine_send_file(int sock, char *file, int size, int fd) {
|
||||
|
||||
// send buffer, wait for reply
|
||||
ret = sendwait(sock, buffer, 1 + 4 + 4 + size);
|
||||
|
||||
CHECK_ERROR(ret < 0);
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
@ -246,16 +247,18 @@ int cafiine_fread(int sock, int *result, void *ptr, int size, int fd) {
|
||||
buffer[0] = BYTE_READ;
|
||||
*(int *)(buffer + 1) = size;
|
||||
*(int *)(buffer + 5) = fd;
|
||||
ret = sendwait(sock, buffer, 1 + 8);
|
||||
ret = sendwait(sock, buffer, 1 + 8);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
int sz;
|
||||
ret = recvwait(sock, &sz, 4);
|
||||
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwaitlen(sock, ptr, sz);
|
||||
*result = sz - ret;
|
||||
ret = sendbyte(sock, BYTE_OK);
|
||||
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
bss.lock = 0;
|
||||
return 0;
|
||||
error:
|
||||
@ -289,11 +292,115 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getFiles(int sock, char * path,char * resultname, int * resulttype, int * filesize){
|
||||
int saviine_start_injection(int sock, long persistentID,int * mask){
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
char buffer[1+4];
|
||||
|
||||
buffer[0] = BYTE_INJECTSTART;
|
||||
*(long *)(buffer + 1) = persistentID;
|
||||
ret = sendwait(sock, buffer, 1 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
|
||||
ret = recvwait(sock, mask, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR((*mask & MASK_NORMAL) != MASK_NORMAL);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_end_injection(int sock){
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
ret = sendbyte(sock, BYTE_INJECTEND);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_OK);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_start_dump(int sock, long persistentID,int * mask){
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
char buffer[1+4];
|
||||
|
||||
buffer[0] = BYTE_DUMPSTART;
|
||||
*(long *)(buffer + 1) = persistentID;
|
||||
ret = sendwait(sock, buffer, 1 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
|
||||
ret = recvwait(sock, mask, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR((*mask & MASK_NORMAL) != MASK_NORMAL);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_end_dump(int sock){
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
ret = sendbyte(sock, BYTE_DUMPEND);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_OK);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_readdir(int sock, char * path,char * resultname, int * resulttype, int * filesize){
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
// create and send buffer with : [cmd id][len_path][path][filesize]
|
||||
{
|
||||
@ -301,13 +408,14 @@ int getFiles(int sock, char * path,char * resultname, int * resulttype, int * fi
|
||||
while (path[size++]);
|
||||
char buffer[1+4+size];
|
||||
|
||||
buffer[0] = BYTE_GET_FILES;
|
||||
buffer[0] = BYTE_READ_DIR;
|
||||
*(int *)(buffer + 1) = size;
|
||||
for (ret = 0; ret < size; ret++)
|
||||
buffer[5 + ret] = path[ret];
|
||||
|
||||
// send buffer, wait for reply
|
||||
ret = sendwait(sock, buffer, 1+4+size);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
|
@ -26,6 +26,7 @@ PROVIDE(FSAAddClient = 0x106546c);
|
||||
PROVIDE(FSADelClient = 0x1060aa4);
|
||||
PROVIDE(FSAOpenFile = 0x10621f8);
|
||||
|
||||
/*FE3C00*/
|
||||
/* FS methods */
|
||||
PROVIDE(FSInit = 0x10683c8);
|
||||
PROVIDE(FSShutdown = 0x1068538);
|
||||
@ -45,7 +46,7 @@ PROVIDE(FSGetStatFile = 0x106f5a0);
|
||||
PROVIDE(FSIsEof = 0x106f610);
|
||||
PROVIDE(FSWriteFile = 0x106F228);
|
||||
PROVIDE(FSFlushQuota = 0x106FAC8);
|
||||
|
||||
PROVIDE(FSRollbackQuota = 0x106FC48);
|
||||
|
||||
/* */
|
||||
PROVIDE(FSGetStat = 0x0106fdc8);
|
||||
|
@ -34,9 +34,24 @@ namespace saviine_server
|
||||
public const byte BYTE_LOG_STR = 0xFB;
|
||||
public const byte BYTE_FILE = 0xC0;
|
||||
public const byte BYTE_FOLDER = 0xC1;
|
||||
public const byte BYTE_GET_FILES = 0xCC;
|
||||
public const byte BYTE_READ_DIR = 0xCC;
|
||||
public const byte BYTE_INJECTSTART = 0x40;
|
||||
public const byte BYTE_INJECTEND = 0x41;
|
||||
public const byte BYTE_DUMPSTART = 0x42;
|
||||
public const byte BYTE_DUMPEND = 0x43;
|
||||
public const byte BYTE_END = 0xfd;
|
||||
|
||||
|
||||
public const int MASK_NORMAL = 0x8000;
|
||||
public const int MASK_USER = 0x0100;
|
||||
public const int MASK_COMMON = 0x0200;
|
||||
public const int MASK_COMMON_CLEAN = 0x0400;
|
||||
|
||||
|
||||
private static long currentPersistentID = 0x0;
|
||||
private static long COMMON_PERSISTENTID = 0x1;
|
||||
|
||||
|
||||
[Flags]
|
||||
public enum FSStatFlag : uint
|
||||
{
|
||||
@ -80,13 +95,16 @@ namespace saviine_server
|
||||
|
||||
public static string root = "saviine_root";
|
||||
public static string logs_root = "logs";
|
||||
public static string injectfolder = "inject";
|
||||
public static string dumpfolder = "dump";
|
||||
public static string common = "common";
|
||||
|
||||
const uint BUFFER_SIZE = 64 * 1024;
|
||||
static Boolean fastmode = false;
|
||||
static byte op_mode = BYTE_MODE_D;
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
{
|
||||
if (args.Length > 1)
|
||||
{
|
||||
Console.Error.WriteLine("Usage: saviine_server [fastmode|fast]");
|
||||
@ -118,6 +136,7 @@ namespace saviine_server
|
||||
|
||||
if (op_mode == BYTE_MODE_D)
|
||||
{
|
||||
currentPersistentID = 0x01;
|
||||
Console.WriteLine("Dump mode");
|
||||
if(fastmode)Console.WriteLine("Now using fastmode");
|
||||
}
|
||||
@ -199,30 +218,7 @@ namespace saviine_server
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
static string getRealPath(string path,string title_id){
|
||||
SaveSelectorDialog ofd = new SaveSelectorDialog(path, title_id);
|
||||
try
|
||||
{
|
||||
DialogResult result = ofd.ShowDialog();
|
||||
if (result == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
Console.WriteLine("selected: " + ofd.NewPath);
|
||||
return ofd.NewPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("nothing selected");
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine("No saves found to inject");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void Handle(object client_obj)
|
||||
{
|
||||
@ -295,11 +291,18 @@ namespace saviine_server
|
||||
string mode = reader.ReadString(Encoding.ASCII, len_mode - 1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
|
||||
path = getRealPathCurrent(path, title_id);
|
||||
|
||||
//Log(log, "old path" + path);
|
||||
//Log(log, "currentID: " + currentPersistentID);
|
||||
if (op_mode == BYTE_MODE_I)
|
||||
path = getRealPathCurrentInject(path, title_id);
|
||||
|
||||
//Log(log, "new path" + path);
|
||||
if (path.Length == 0) failed = true;
|
||||
|
||||
if (File.Exists(path) && !failed)
|
||||
{
|
||||
//Log(log, "path exits");
|
||||
int handle = -1;
|
||||
for (int i = 1; i < files.Length; i++)
|
||||
{
|
||||
@ -326,6 +329,7 @@ namespace saviine_server
|
||||
writer.Write(handle);
|
||||
break;
|
||||
}
|
||||
//Log(log, "error fopen");
|
||||
//else on error:
|
||||
writer.Write(BYTE_NORMAL);
|
||||
|
||||
@ -357,18 +361,158 @@ namespace saviine_server
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BYTE_GET_FILES:
|
||||
case BYTE_INJECTSTART:
|
||||
{
|
||||
long wiiUpersistentID = (long)reader.ReadUInt32();
|
||||
int dumpCommon = 0;
|
||||
Boolean injectioncanceled = false;
|
||||
SaveSelectorDialog ofd = new SaveSelectorDialog(title_id, wiiUpersistentID);
|
||||
try
|
||||
{
|
||||
DialogResult result = ofd.ShowDialog();
|
||||
if (result == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
currentPersistentID = ofd.NewPersistentID;
|
||||
dumpCommon = ofd.DumpCommon;
|
||||
//Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id);
|
||||
if (dumpCommon == 1) Console.WriteLine("clean and inject common folder");
|
||||
if (dumpCommon == 2) Console.WriteLine("inject common folder");
|
||||
if (dumpCommon > 0 && currentPersistentID == 0) currentPersistentID = COMMON_PERSISTENTID;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Injection canceled");
|
||||
injectioncanceled = true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Injection canceled");
|
||||
injectioncanceled = true;
|
||||
}
|
||||
if (injectioncanceled)
|
||||
{
|
||||
writer.Write(BYTE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
}
|
||||
int dumpmask = MASK_NORMAL;
|
||||
if (currentPersistentID != 0 && currentPersistentID != COMMON_PERSISTENTID)
|
||||
dumpmask |= MASK_USER;
|
||||
|
||||
if (dumpCommon >= 1) {
|
||||
dumpmask |= MASK_COMMON;
|
||||
if(dumpCommon == 2)
|
||||
dumpmask |= MASK_COMMON_CLEAN;
|
||||
}
|
||||
writer.Write(dumpmask);
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_INJECTEND:
|
||||
{
|
||||
currentPersistentID = 0;
|
||||
//close all opened files
|
||||
for (int i = 1; i < files.Length; i++)
|
||||
{
|
||||
if (files[i] != null)
|
||||
{
|
||||
files[i].Close();
|
||||
files[i] = null;
|
||||
}
|
||||
}
|
||||
writer.Write(BYTE_OK);
|
||||
Console.WriteLine("InjectionEND");
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_DUMPSTART:
|
||||
{
|
||||
long wiiUpersistentID = (long)reader.ReadUInt32();
|
||||
int dumpCommon = 0;
|
||||
currentPersistentID = wiiUpersistentID;
|
||||
dumpCommon = 1;
|
||||
/*
|
||||
Boolean injectioncanceled = false;
|
||||
SaveSelectorDialog ofd = new SaveSelectorDialog(title_id, wiiUpersistentID);
|
||||
try
|
||||
{
|
||||
DialogResult result = ofd.ShowDialog();
|
||||
if (result == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
currentPersistentID = ofd.NewPersistentID;
|
||||
dumpCommon = ofd.DumpCommon;
|
||||
//Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id);
|
||||
if (dumpCommon == 1) Console.WriteLine("clean and inject common folder");
|
||||
if (dumpCommon == 2) Console.WriteLine("inject common folder");
|
||||
if (dumpCommon > 0 && currentPersistentID == 0) currentPersistentID = COMMON_PERSISTENTID;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("dump canceled");
|
||||
injectioncanceled = true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("dump canceled");
|
||||
injectioncanceled = true;
|
||||
}
|
||||
if (injectioncanceled)
|
||||
{
|
||||
writer.Write(BYTE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
}*/
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
int dumpmask = MASK_NORMAL;
|
||||
if (currentPersistentID != 0 && currentPersistentID != COMMON_PERSISTENTID)
|
||||
dumpmask |= MASK_USER;
|
||||
|
||||
if (dumpCommon == 1)
|
||||
{
|
||||
dumpmask |= MASK_COMMON;
|
||||
}
|
||||
writer.Write(dumpmask);
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_DUMPEND:
|
||||
{
|
||||
currentPersistentID = 0;
|
||||
//close all opened files
|
||||
for (int i = 1; i < files.Length; i++)
|
||||
{
|
||||
if (files[i] != null)
|
||||
{
|
||||
files[i].Close();
|
||||
files[i] = null;
|
||||
}
|
||||
}
|
||||
writer.Write(BYTE_OK);
|
||||
Console.WriteLine("dumpEND");
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_READ_DIR:
|
||||
{
|
||||
Boolean failed = false;
|
||||
int len_path = reader.ReadInt32();
|
||||
string path = reader.ReadString(Encoding.ASCII, len_path-1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
int x = 0;
|
||||
|
||||
currentPersistentID = getPersistentIDFromPath(path);
|
||||
path = getRealPath(path, title_id);
|
||||
//Console.WriteLine("old" + path);
|
||||
if(op_mode == BYTE_MODE_I)
|
||||
path = getRealPathCurrentInject(path, title_id);
|
||||
//Console.WriteLine("new" + path);
|
||||
if(path.Length == 0)failed = true;
|
||||
|
||||
|
||||
if (Directory.Exists(path) && !failed)
|
||||
{
|
||||
x = countDirectory(path);
|
||||
@ -433,7 +577,7 @@ namespace saviine_server
|
||||
}
|
||||
writer.Write(BYTE_END); //
|
||||
//Console.Write("list was empty return BYTE_END \n");
|
||||
|
||||
|
||||
//Console.Write("in break \n");
|
||||
break;
|
||||
}
|
||||
@ -464,9 +608,13 @@ namespace saviine_server
|
||||
string strSize = (sz / 1024).ToString();
|
||||
string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' ');
|
||||
Console.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize);
|
||||
log.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize);
|
||||
|
||||
//Console.Write("send " + rd );
|
||||
if(offset == sz) Console.Write("\n");
|
||||
if (offset == sz)
|
||||
{
|
||||
Console.Write("\n");
|
||||
log.Write("\r\t--> {0}% ({1} kB / {2} kB)\n", strProgress, strCurrent, strSize);
|
||||
}
|
||||
int ret = -5;
|
||||
if ((ret =reader.ReadByte()) != BYTE_OK)
|
||||
{
|
||||
@ -486,13 +634,24 @@ namespace saviine_server
|
||||
int len_path = reader.ReadInt32();
|
||||
string path = reader.ReadString(Encoding.ASCII, len_path - 1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
if (!Directory.Exists(LocalRootDump + path))
|
||||
//Console.WriteLine("old " + path);
|
||||
if (op_mode == BYTE_MODE_D)
|
||||
path = getRealPathCurrentDump(path, title_id);
|
||||
//Console.WriteLine("new " + path);
|
||||
|
||||
if (path.Length == 0)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(LocalRootDump + path));
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
}
|
||||
|
||||
// Add new file for incoming data
|
||||
files_request.Add(fd, new FileStream(LocalRootDump + path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write));
|
||||
files_request.Add(fd, new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write));
|
||||
// Send response
|
||||
if (fastmode) {
|
||||
writer.Write(BYTE_REQUEST);
|
||||
@ -652,40 +811,43 @@ namespace saviine_server
|
||||
Console.WriteLine(name + " Exit");
|
||||
}
|
||||
|
||||
private static string getPersistentIDFromPath(string path)
|
||||
private static string getRealPathCurrentInject(string path, string title_id)
|
||||
{
|
||||
return getRealPathCurrent(injectfolder, path, title_id);
|
||||
}
|
||||
private static string getRealPathCurrentDump(string path, string title_id)
|
||||
{
|
||||
return getRealPathCurrent(dumpfolder, path, title_id);
|
||||
}
|
||||
|
||||
private static string getRealPathCurrent(string prefix, string path, string title_id)
|
||||
{
|
||||
string savePath = Program.root + "/" + prefix + "/" + title_id;
|
||||
if (currentPersistentID == 0) return "";
|
||||
string[] stringSeparators = new string[] { "vol/save/", "vol\\save\\" };
|
||||
string[] result;
|
||||
string resultstr = "";
|
||||
|
||||
string resultstr = "";
|
||||
result = path.Split(stringSeparators, StringSplitOptions.None);
|
||||
if (result.Length < 2) return "";
|
||||
resultstr = result[result.Length-1];
|
||||
if (result.Length < 2) return "";
|
||||
resultstr = result[result.Length-1];
|
||||
stringSeparators = new string[] { "/", "\\" };
|
||||
result = resultstr.Split(stringSeparators, StringSplitOptions.None);
|
||||
if (result.Length < 1) return "";
|
||||
return result[0];
|
||||
}
|
||||
private static string currentPersistentID = "80000009";
|
||||
private static string getRealPathCurrent(string path, string title_id)
|
||||
{
|
||||
if (currentPersistentID.Length == 0) return "";
|
||||
string[] stringSeparators = new string[] { "vol/save/", "vol\\save\\" };
|
||||
string[] result;
|
||||
string resultstr = "";
|
||||
|
||||
result = path.Split(stringSeparators, StringSplitOptions.None);
|
||||
if (result.Length < 2) return "";
|
||||
resultstr = result[result.Length-1];
|
||||
stringSeparators = new string[] { "/", "\\" };
|
||||
result = resultstr.Split(stringSeparators, StringSplitOptions.None);
|
||||
if (result.Length < 2) return "";
|
||||
if (result.Length < 2)
|
||||
{
|
||||
if (result[0] != "common") return savePath + "/" + String.Format("{0:X}", currentPersistentID);
|
||||
return savePath + "/" + "common";
|
||||
}
|
||||
resultstr = "";
|
||||
if (result[0] != "common")
|
||||
savePath += "/" + String.Format("{0:X}", currentPersistentID);
|
||||
else
|
||||
savePath += "/" + "common";
|
||||
for (int i = 1; i < result.Length; i++)
|
||||
{
|
||||
resultstr += "/" + result[i];
|
||||
}
|
||||
string savePath = Program.root + "/" + "inject" + "/" + title_id + "/" + currentPersistentID + resultstr;
|
||||
|
||||
savePath += resultstr;
|
||||
|
||||
return savePath;
|
||||
}
|
||||
|
89
saviine/server/src/SaveSelectorDialog.Designer.cs
generated
89
saviine/server/src/SaveSelectorDialog.Designer.cs
generated
@ -30,15 +30,19 @@
|
||||
{
|
||||
this.btn_ok = new System.Windows.Forms.Button();
|
||||
this.btn_cancel = new System.Windows.Forms.Button();
|
||||
this.listBox_saves = new System.Windows.Forms.ListBox();
|
||||
this.lbl_message = new System.Windows.Forms.Label();
|
||||
this.comBoxIDList = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.Inj = new System.Windows.Forms.Label();
|
||||
this.comBoxCommon = new System.Windows.Forms.ComboBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btn_ok
|
||||
//
|
||||
this.btn_ok.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.btn_ok.Location = new System.Drawing.Point(167, 266);
|
||||
this.btn_ok.Location = new System.Drawing.Point(62, 133);
|
||||
this.btn_ok.Name = "btn_ok";
|
||||
this.btn_ok.Size = new System.Drawing.Size(105, 33);
|
||||
this.btn_ok.Size = new System.Drawing.Size(81, 21);
|
||||
this.btn_ok.TabIndex = 0;
|
||||
this.btn_ok.Text = "OK";
|
||||
this.btn_ok.UseVisualStyleBackColor = true;
|
||||
@ -47,33 +51,80 @@
|
||||
// btn_cancel
|
||||
//
|
||||
this.btn_cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btn_cancel.Location = new System.Drawing.Point(332, 269);
|
||||
this.btn_cancel.Location = new System.Drawing.Point(198, 133);
|
||||
this.btn_cancel.Name = "btn_cancel";
|
||||
this.btn_cancel.Size = new System.Drawing.Size(130, 29);
|
||||
this.btn_cancel.Size = new System.Drawing.Size(81, 21);
|
||||
this.btn_cancel.TabIndex = 1;
|
||||
this.btn_cancel.Text = "Cancel";
|
||||
this.btn_cancel.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// listBox_saves
|
||||
// lbl_message
|
||||
//
|
||||
this.listBox_saves.FormattingEnabled = true;
|
||||
this.listBox_saves.Location = new System.Drawing.Point(54, 48);
|
||||
this.listBox_saves.Name = "listBox_saves";
|
||||
this.listBox_saves.Size = new System.Drawing.Size(408, 160);
|
||||
this.listBox_saves.TabIndex = 2;
|
||||
this.lbl_message.AutoSize = true;
|
||||
this.lbl_message.Location = new System.Drawing.Point(12, 10);
|
||||
this.lbl_message.Name = "lbl_message";
|
||||
this.lbl_message.Size = new System.Drawing.Size(236, 13);
|
||||
this.lbl_message.TabIndex = 3;
|
||||
this.lbl_message.Text = "Got an injection request for 00050000-10157F00";
|
||||
//
|
||||
// Form1
|
||||
// comBoxIDList
|
||||
//
|
||||
this.comBoxIDList.FormattingEnabled = true;
|
||||
this.comBoxIDList.Location = new System.Drawing.Point(186, 48);
|
||||
this.comBoxIDList.Name = "comBoxIDList";
|
||||
this.comBoxIDList.Size = new System.Drawing.Size(93, 21);
|
||||
this.comBoxIDList.TabIndex = 4;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 51);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(81, 13);
|
||||
this.label1.TabIndex = 5;
|
||||
this.label1.Text = "Select userdata";
|
||||
this.label1.Click += new System.EventHandler(this.label1_Click);
|
||||
//
|
||||
// Inj
|
||||
//
|
||||
this.Inj.AutoSize = true;
|
||||
this.Inj.Location = new System.Drawing.Point(12, 86);
|
||||
this.Inj.Name = "Inj";
|
||||
this.Inj.Size = new System.Drawing.Size(108, 13);
|
||||
this.Inj.TabIndex = 7;
|
||||
this.Inj.Text = "Inject common save?";
|
||||
this.Inj.Click += new System.EventHandler(this.Inj_Click);
|
||||
//
|
||||
// comBoxCommon
|
||||
//
|
||||
this.comBoxCommon.FormattingEnabled = true;
|
||||
this.comBoxCommon.Items.AddRange(new object[] {
|
||||
"no",
|
||||
"inject",
|
||||
"clean and inject (deleting existing common)"});
|
||||
this.comBoxCommon.Location = new System.Drawing.Point(126, 83);
|
||||
this.comBoxCommon.Name = "comBoxCommon";
|
||||
this.comBoxCommon.Size = new System.Drawing.Size(153, 21);
|
||||
this.comBoxCommon.TabIndex = 8;
|
||||
//
|
||||
// SaveSelectorDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(499, 314);
|
||||
this.Controls.Add(this.listBox_saves);
|
||||
this.ClientSize = new System.Drawing.Size(310, 166);
|
||||
this.Controls.Add(this.comBoxCommon);
|
||||
this.Controls.Add(this.Inj);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.comBoxIDList);
|
||||
this.Controls.Add(this.lbl_message);
|
||||
this.Controls.Add(this.btn_cancel);
|
||||
this.Controls.Add(this.btn_ok);
|
||||
this.Name = "Form1";
|
||||
this.Text = "Form1";
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Name = "SaveSelectorDialog";
|
||||
this.Text = "Injection request";
|
||||
this.Load += new System.EventHandler(this.Form1_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@ -81,6 +132,10 @@
|
||||
|
||||
private System.Windows.Forms.Button btn_ok;
|
||||
private System.Windows.Forms.Button btn_cancel;
|
||||
private System.Windows.Forms.ListBox listBox_saves;
|
||||
private System.Windows.Forms.Label lbl_message;
|
||||
private System.Windows.Forms.ComboBox comBoxIDList;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label Inj;
|
||||
private System.Windows.Forms.ComboBox comBoxCommon;
|
||||
}
|
||||
}
|
@ -12,40 +12,61 @@ namespace saviine_server
|
||||
{
|
||||
public partial class SaveSelectorDialog : Form
|
||||
{
|
||||
private string newPath = "";
|
||||
private long newPersistentID = 0;
|
||||
private int dumpCommon = 0;
|
||||
|
||||
public string NewPath
|
||||
public long NewPersistentID
|
||||
{
|
||||
get { return newPath; }
|
||||
get { return newPersistentID; }
|
||||
}
|
||||
private static string savePath = Program.root + "/" + "inject";
|
||||
public SaveSelectorDialog(string path,string title_id)
|
||||
public int DumpCommon
|
||||
{
|
||||
get { return dumpCommon; }
|
||||
}
|
||||
private static string savePath;
|
||||
public SaveSelectorDialog(string title_id,long persistentID)
|
||||
{
|
||||
InitializeComponent();
|
||||
string[] stringSeparators = new string[] { "vol/save/", "vol\\save\\" };
|
||||
string[] result;
|
||||
|
||||
result = path.Split(stringSeparators, StringSplitOptions.None);
|
||||
if (result.Length < 2) this.Close();
|
||||
string resultPath = result[result.Length-2];
|
||||
|
||||
Console.WriteLine(title_id);
|
||||
comBoxCommon.SelectedIndex = 0;
|
||||
savePath = Program.root + "/" + Program.injectfolder;;
|
||||
this.lbl_message.Text = "Got an injection request for " + title_id;
|
||||
savePath += "/" + title_id;
|
||||
string[] subdirectoryEntries;
|
||||
if (Directory.Exists(savePath))
|
||||
{
|
||||
// Recurse into subdirectories of this directory.
|
||||
string[] subdirectoryEntries = Directory.GetDirectories(savePath);
|
||||
subdirectoryEntries = Directory.GetDirectories(savePath);
|
||||
this.comBoxIDList.Items.Add("---none---");
|
||||
comBoxIDList.SelectedIndex = 0;
|
||||
foreach (string subdirectory in subdirectoryEntries)
|
||||
{
|
||||
this.listBox_saves.Items.Add(Path.GetFileName(subdirectory));
|
||||
string filename = Path.GetFileName(subdirectory);
|
||||
long id;
|
||||
try{
|
||||
id = Convert.ToUInt32(filename, 16);
|
||||
}catch (Exception){
|
||||
id = 0;
|
||||
}
|
||||
|
||||
|
||||
if (id >= 0x80000000 && id <= 0x81000000)
|
||||
{
|
||||
|
||||
this.comBoxIDList.Items.Add(filename);
|
||||
}
|
||||
}
|
||||
if (comBoxIDList.Items.Count == 1)
|
||||
{
|
||||
this.comBoxIDList.Enabled = false;
|
||||
|
||||
}
|
||||
if (!Directory.Exists(savePath + "/" + Program.common))
|
||||
{
|
||||
comBoxCommon.Enabled = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("dir not found! " + savePath);
|
||||
this.Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
@ -55,12 +76,34 @@ namespace saviine_server
|
||||
|
||||
private void btn_ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
newPath = savePath + "/" + this.listBox_saves.SelectedItem.ToString();
|
||||
long id;
|
||||
try
|
||||
{
|
||||
id = Convert.ToUInt32(this.comBoxIDList.SelectedItem.ToString(), 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
newPersistentID = id;
|
||||
dumpCommon = comBoxCommon.SelectedIndex;
|
||||
Console.WriteLine(dumpCommon);
|
||||
|
||||
}
|
||||
private void btn_cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Inj_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void label1_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,8 +1,8 @@
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.exe.config
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.exe
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.pdb
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.csprojResolveAssemblyReference.cache
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.exe
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.pdb
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.Form1.resources
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.csproj.GenerateResource.Cache
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.SaveSelectorDialog.resources
|
||||
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.csprojResolveAssemblyReference.cache
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user