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:
Maschell 2015-10-25 18:26:25 +01:00
parent 7356f4029c
commit 721c983122
13 changed files with 897 additions and 447 deletions

View File

@ -24,7 +24,7 @@ SFLAGS := -mgekko -mregnames
# -memb: enable embedded application specific compilation # -memb: enable embedded application specific compilation
# -ffunction-sections: split up functions so linker can garbage collect # -ffunction-sections: split up functions so linker can garbage collect
# -fdata-sections: split up data 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 \ -ffreestanding \
-mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar \ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar \
-msdata=none -memb -ffunction-sections -fdata-sections \ -msdata=none -memb -ffunction-sections -fdata-sections \

View File

@ -5,20 +5,8 @@
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".magicptr"))); \ res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".magicptr"))); \
res my_ ## name(__VA_ARGS__) res my_ ## name(__VA_ARGS__)
#define DEBUG_LOG 0 #define DEBUG_LOG 0
extern FSStatus FSOpenDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, int *dh, FSRetFlag errHandling); #define BUFFER_SIZE (1024)*100*2
extern FSStatus FSReadDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSDirEntry *dir_entry, FSRetFlag errHandling); #define BUFFER_SIZE_STEPS 0x200
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);
DECL(int, FSAInit, void) { DECL(int, FSAInit, void) {
if ((int)bss_ptr == 0x0a000000) { if ((int)bss_ptr == 0x0a000000) {
@ -56,24 +44,6 @@ static int strlen(char* path) {
return i; 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) { static int client_num_alloc(void *pClient) {
int i; int i;
@ -153,7 +123,7 @@ DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
// Init command block. // Init command block.
FSInitCmdBlock(pCmd); FSInitCmdBlock(pCmd);
hook(pClient, pCmd,-1, client); hook(pClient, pCmd,-1);
bss.saveFolderChecked = 2; bss.saveFolderChecked = 2;
error: real_FSDelClient(pClient); error: real_FSDelClient(pClient);
@ -168,333 +138,259 @@ DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
return res; return res;
} }
static int remove_files_in_dir(void * pClient,void * pCmd, char * path, int handle){ void hook(void * pClient,void * pCmd, int error){
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){
log_string(bss.logsock, "hook", BYTE_LOG_STR); log_string(bss.logsock, "hook", BYTE_LOG_STR);
handle_saves(pClient, pCmd,-1, client); handle_saves(pClient, pCmd,-1);
} }
static void init_Save(){ void handle_saves(void *pClient, void *pCmd,int error){
int (*SAVEInit)(); log_string(bss.logsock, "init", BYTE_LOG_STR);
unsigned int save_handle; int client = client_num(pClient);
OSDynLoad_Acquire("nn_save.rpl", &save_handle); unsigned char slotNo;
OSDynLoad_FindExport(save_handle, 0, "SAVEInit", (void **)&SAVEInit); long id = getPesistentID(&slotNo);
SAVEInit(); init_Save(slotNo);
}
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();
int mode; 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(getMode(bss.socket_fsa[client],&mode)){
if(id >= 0x80000000 && id <= 0x90000000){ if(id >= 0x80000000 && id <= 0x90000000){
char savepath[20]; char savepath[20];
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",id); __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);
if(mode == BYTE_MODE_D){ dumpSavaData(pClient, pCmd,id,error);
log_string(bss.logsock, "dump mode!", BYTE_LOG_STR); }else if(mode == BYTE_MODE_I){
dump_dir(pClient,client,pCmd,savepath,-1,50); log_string(bss.logsock, "inject mode", BYTE_LOG_STR);
}else if(mode == BYTE_MODE_I){ injectSaveData(pClient,pCmd,id,error);
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);
}
}
}
}
} }
}
}
}
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){ pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40);
log_string(bss.logsock, "dumping common savedata", BYTE_LOG_STR); }while(!pBuffer);
dump_dir(pClient,client,pCmd,"/vol/save/common/",error,60);
log_string(bss.logsock, "done!", BYTE_LOG_STR); if(!failed){
}else{ int mask = 0;
log_string(bss.logsock, "common injection", BYTE_LOG_STR); char buffer[60];
int buf_size = BUFFER_SIZE; __os_snprintf(buffer, sizeof(buffer), "allocated %d bytes",buf_size);
char * pBuffer; log_string(bss.logsock, buffer, BYTE_LOG_STR);
int failed = 0; if(saviine_start_dump(bss.socket_fsa[client], persistentID,&mask)){
do{ if((mask & MASK_USER) == MASK_USER){
buf_size -= 0x200; char savepath[20];
if(buf_size < 0){ __os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",persistentID);
log_string(bss.logsock, "error on buffer allocation", BYTE_LOG_STR); 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; 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){ 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 client = client_num(pClient);
int failed = 0; int failed = 0;
int filesinjected = 0; int filesinjected = 0;
int type = 0; int type = 0;
log_string(bss.logsock, "injecting files", BYTE_LOG_STR); log_string(bss.logsock, "injecting files", BYTE_LOG_STR);
char namebuffer[255]; char namebuffer[255];
char logbugger[255]; char logbuffer[255];
int filesize = 0; int filesize = 0;
if(!failed){ if(!failed){
__os_snprintf(logbugger, sizeof(logbugger), "buffer size: %d bytes",buffer_size); __os_snprintf(logbuffer, sizeof(logbuffer), "buffer size: %d bytes",buffer_size);
log_string(bss.logsock, logbugger, BYTE_LOG_STR); 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); if(DEBUG_LOG)log_string(bss.logsock, "got a file", BYTE_LOG_STR);
char newpath[strlen(path) + 1 + strlen(namebuffer)]; char newpath[strlen(path) + 1 + strlen(namebuffer)];
__os_snprintf(newpath, sizeof(newpath), "%s/%s",path,namebuffer); __os_snprintf(newpath, sizeof(newpath), "%s/%s",path,namebuffer);
if(type == BYTE_FILE){ if(type == BYTE_FILE){
__os_snprintf(logbugger, sizeof(logbugger), "file: %s%s size: %d",relativepath,namebuffer,filesize); __os_snprintf(logbuffer, sizeof(logbuffer), "file: %s%s size: %d",relativepath,namebuffer,filesize);
log_string(bss.logsock, logbugger, BYTE_LOG_STR); log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
if(DEBUG_LOG) log_string(bss.logsock, "downloading it", BYTE_LOG_STR); if(DEBUG_LOG) log_string(bss.logsock, "downloading it", BYTE_LOG_STR);
int handle = 10; int handle = 10;
if(FSOpenFile(pClient, pCmd, newpath,"w+",&handle,-1) >= 0){ if(FSOpenFile(pClient, pCmd, newpath,"w+",&handle,-1) >= 0){
if(DEBUG_LOG) log_string(bss.logsock, "file opened and created", BYTE_LOG_STR); 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{ if(filesize > 0){
log_string(bss.logsock, "cafiine_fopen failed", BYTE_LOG_STR); failed = doInjectForFile(pClient,pCmd,handle,newpath,filesize,pBuffer,buffer_size);
failed = 1; }else{
} if(DEBUG_LOG) log_string(bss.logsock, "filesize is 0", BYTE_LOG_STR);
} }
if((FSCloseFile (pClient, pCmd, handle, -1)) < 0){ if((FSCloseFile (pClient, pCmd, handle, -1)) < 0){
log_string(bss.logsock, "FSCloseFile failed", BYTE_LOG_STR); log_string(bss.logsock, "FSCloseFile failed", BYTE_LOG_STR);
failed = 1; failed = 1;
} }
}else{ }else{
log_string(bss.logsock, "opening the file failed", BYTE_LOG_STR); log_string(bss.logsock, "opening the file failed", BYTE_LOG_STR);
failed = 1; failed = 1;
} }
if(!failed) filesinjected++; if(!failed) filesinjected++;
}else if( type == BYTE_FOLDER){ }else if( type == BYTE_FOLDER){
__os_snprintf(logbugger, sizeof(logbugger), "dir: %s",namebuffer); __os_snprintf(logbuffer, sizeof(logbuffer), "dir: %s",namebuffer);
log_string(bss.logsock, logbugger, BYTE_LOG_STR); log_string(bss.logsock, logbuffer, BYTE_LOG_STR);
if(DEBUG_LOG) log_string(bss.logsock, newpath, BYTE_LOG_STR); if(DEBUG_LOG) log_string(bss.logsock, newpath, BYTE_LOG_STR);
if(FSMakeDir(pClient, pCmd, newpath, -1) == 0){ if(FSMakeDir(pClient, pCmd, newpath, -1) == 0){
char op_offset[strlen(relativepath) + strlen(namebuffer)+ 1 + 1]; 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; failed = 1;
} }
} }
} }
free(pBuffer);
if(failed) return -1; if(failed) return -1;
else return filesinjected; else return filesinjected;
}else{ }else{
return -1; 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 } #define MAKE_MAGIC(x) { x, my_ ## x, &real_ ## x }
@ -537,6 +582,4 @@ struct magic_t {
MAKE_MAGIC(FSDelClient), MAKE_MAGIC(FSDelClient),
MAKE_MAGIC(FSWriteFile), MAKE_MAGIC(FSWriteFile),
MAKE_MAGIC(FSFlushQuota), MAKE_MAGIC(FSFlushQuota),
}; };

View File

@ -24,9 +24,18 @@
#define BYTE_LOG_STR 0xfb #define BYTE_LOG_STR 0xfb
#define BYTE_FILE 0xC0 #define BYTE_FILE 0xC0
#define BYTE_FOLDER 0xC1 #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 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 *memcpy(void *dst, const void *src, int bytes);
void *memset(void *dst, int val, 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 void FSInitCmdBlock(FSCmdBlock *pCmd);
extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFlag errHandling); 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 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 void socket_lib_init();
extern int socket(int domain, int type, int protocol); extern int socket(int domain, int type, int protocol);
extern int socketclose(int socket); extern int socketclose(int socket);
extern int connect(int socket, void *addr, int addrlen); extern int connect(int socket, void *addr, int addrlen);
extern int send(int socket, const void *buffer, int size, int flags); 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 recv(int socket, void *buffer, int size, int flags);
extern int __os_snprintf(char* s, int n, const char * format, ...); 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); 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 { struct in_addr {
unsigned int s_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_fstat(int sock, int *result, int fd, void *ptr);
int cafiine_feof(int sock, int *result, int fd); int cafiine_feof(int sock, int *result, int fd);
void cafiine_send_ping(int sock, int val1, int val2); 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);

View File

@ -72,9 +72,8 @@ int getMode(int sock,int * result)
{ {
while (bss.lock) GX2WaitForVsync(); while (bss.lock) GX2WaitForVsync();
bss.lock = 1; bss.lock = 1;
CHECK_ERROR(sock == -1);
int ret = 0; int ret = 0;
CHECK_ERROR(sock == -1);
// create and send buffer with : [cmd id][fd][size][buffer data ...] // 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 // wait reply
ret = recvbyte(sock); ret = recvbyte(sock);
CHECK_ERROR(ret < 0);
CHECK_ERROR(ret == BYTE_SPECIAL);
if(ret == BYTE_REQUEST){ if(ret == BYTE_REQUEST){
ret = 1; ret = 1;
}else{ }else{
@ -152,6 +153,7 @@ int cafiine_send_handle(int sock, int client, const char *path, int handle)
} }
// wait reply // wait reply
int special_ret = recvbyte(sock); int special_ret = recvbyte(sock);
CHECK_ERROR(special_ret < 0);
CHECK_ERROR(special_ret != BYTE_SPECIAL); CHECK_ERROR(special_ret != BYTE_SPECIAL);
bss.lock = 0; bss.lock = 0;
return ret; return ret;
@ -164,10 +166,9 @@ error:
int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int *handle) { int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int *handle) {
while (bss.lock) GX2WaitForVsync(); while (bss.lock) GX2WaitForVsync();
bss.lock = 1; bss.lock = 1;
int final_result = -1;
CHECK_ERROR(sock == -1); CHECK_ERROR(sock == -1);
int final_ret = 0;
int ret; int ret;
int len_path = 0; int len_path = 0;
while (path[len_path++]); 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]; buffer[9 + len_path + ret] = mode[ret];
ret = sendwait(sock, buffer, 1 + 8 + len_path + len_mode); ret = sendwait(sock, buffer, 1 + 8 + len_path + len_mode);
} CHECK_ERROR(ret < 0);
CHECK_ERROR(ret < 0);
ret = recvbyte(sock); ret = recvbyte(sock);
CHECK_ERROR(ret < 0); CHECK_ERROR(ret < 0);
CHECK_ERROR(ret == BYTE_NORMAL); CHECK_ERROR(ret == BYTE_NORMAL);
ret = recvwait(sock, result, 4); ret = recvwait(sock, result, 4);
CHECK_ERROR(ret < 0); CHECK_ERROR(ret < 0);
ret = recvwait(sock, handle, 4); ret = recvwait(sock, handle, 4);
CHECK_ERROR(ret < 0); CHECK_ERROR(ret < 0);
}
final_result = 0;
quit:
bss.lock = 0;
return final_ret;
error: error:
bss.lock = 0; bss.lock = 0;
return -1; return final_result;
} }
void cafiine_send_file(int sock, char *file, int size, int fd) { 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 // send buffer, wait for reply
ret = sendwait(sock, buffer, 1 + 4 + 4 + size); ret = sendwait(sock, buffer, 1 + 4 + 4 + size);
CHECK_ERROR(ret < 0);
// wait reply // wait reply
ret = recvbyte(sock); ret = recvbyte(sock);
CHECK_ERROR(ret != BYTE_SPECIAL); 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; buffer[0] = BYTE_READ;
*(int *)(buffer + 1) = size; *(int *)(buffer + 1) = size;
*(int *)(buffer + 5) = fd; *(int *)(buffer + 5) = fd;
ret = sendwait(sock, buffer, 1 + 8); ret = sendwait(sock, buffer, 1 + 8);
CHECK_ERROR(ret < 0);
ret = recvbyte(sock); ret = recvbyte(sock);
CHECK_ERROR(ret == BYTE_NORMAL); CHECK_ERROR(ret == BYTE_NORMAL);
int sz; int sz;
ret = recvwait(sock, &sz, 4); ret = recvwait(sock, &sz, 4);
CHECK_ERROR(ret < 0);
ret = recvwaitlen(sock, ptr, sz); ret = recvwaitlen(sock, ptr, sz);
*result = sz - ret; *result = sz - ret;
ret = sendbyte(sock, BYTE_OK); ret = sendbyte(sock, BYTE_OK);
CHECK_ERROR(ret < 0);
bss.lock = 0; bss.lock = 0;
return 0; return 0;
error: error:
@ -289,11 +292,115 @@ error:
return -1; 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(); while (bss.lock) GX2WaitForVsync();
bss.lock = 1; bss.lock = 1;
CHECK_ERROR(sock == -1);
int result = 0; 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; int ret;
// create and send buffer with : [cmd id][len_path][path][filesize] // 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++]); while (path[size++]);
char buffer[1+4+size]; char buffer[1+4+size];
buffer[0] = BYTE_GET_FILES; buffer[0] = BYTE_READ_DIR;
*(int *)(buffer + 1) = size; *(int *)(buffer + 1) = size;
for (ret = 0; ret < size; ret++) for (ret = 0; ret < size; ret++)
buffer[5 + ret] = path[ret]; buffer[5 + ret] = path[ret];
// send buffer, wait for reply // send buffer, wait for reply
ret = sendwait(sock, buffer, 1+4+size); ret = sendwait(sock, buffer, 1+4+size);
CHECK_ERROR(ret < 0);
// wait reply // wait reply
ret = recvbyte(sock); ret = recvbyte(sock);

View File

@ -26,6 +26,7 @@ PROVIDE(FSAAddClient = 0x106546c);
PROVIDE(FSADelClient = 0x1060aa4); PROVIDE(FSADelClient = 0x1060aa4);
PROVIDE(FSAOpenFile = 0x10621f8); PROVIDE(FSAOpenFile = 0x10621f8);
/*FE3C00*/
/* FS methods */ /* FS methods */
PROVIDE(FSInit = 0x10683c8); PROVIDE(FSInit = 0x10683c8);
PROVIDE(FSShutdown = 0x1068538); PROVIDE(FSShutdown = 0x1068538);
@ -45,7 +46,7 @@ PROVIDE(FSGetStatFile = 0x106f5a0);
PROVIDE(FSIsEof = 0x106f610); PROVIDE(FSIsEof = 0x106f610);
PROVIDE(FSWriteFile = 0x106F228); PROVIDE(FSWriteFile = 0x106F228);
PROVIDE(FSFlushQuota = 0x106FAC8); PROVIDE(FSFlushQuota = 0x106FAC8);
PROVIDE(FSRollbackQuota = 0x106FC48);
/* */ /* */
PROVIDE(FSGetStat = 0x0106fdc8); PROVIDE(FSGetStat = 0x0106fdc8);

View File

@ -34,9 +34,24 @@ namespace saviine_server
public const byte BYTE_LOG_STR = 0xFB; public const byte BYTE_LOG_STR = 0xFB;
public const byte BYTE_FILE = 0xC0; public const byte BYTE_FILE = 0xC0;
public const byte BYTE_FOLDER = 0xC1; 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 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] [Flags]
public enum FSStatFlag : uint public enum FSStatFlag : uint
{ {
@ -80,13 +95,16 @@ namespace saviine_server
public static string root = "saviine_root"; public static string root = "saviine_root";
public static string logs_root = "logs"; 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; const uint BUFFER_SIZE = 64 * 1024;
static Boolean fastmode = false; static Boolean fastmode = false;
static byte op_mode = BYTE_MODE_D; static byte op_mode = BYTE_MODE_D;
[STAThread] [STAThread]
static void Main(string[] args) static void Main(string[] args)
{ {
if (args.Length > 1) if (args.Length > 1)
{ {
Console.Error.WriteLine("Usage: saviine_server [fastmode|fast]"); Console.Error.WriteLine("Usage: saviine_server [fastmode|fast]");
@ -118,6 +136,7 @@ namespace saviine_server
if (op_mode == BYTE_MODE_D) if (op_mode == BYTE_MODE_D)
{ {
currentPersistentID = 0x01;
Console.WriteLine("Dump mode"); Console.WriteLine("Dump mode");
if(fastmode)Console.WriteLine("Now using fastmode"); if(fastmode)Console.WriteLine("Now using fastmode");
} }
@ -199,30 +218,7 @@ namespace saviine_server
return x; 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) static void Handle(object client_obj)
{ {
@ -295,11 +291,18 @@ namespace saviine_server
string mode = reader.ReadString(Encoding.ASCII, len_mode - 1); string mode = reader.ReadString(Encoding.ASCII, len_mode - 1);
if (reader.ReadByte() != 0) throw new InvalidDataException(); 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 (path.Length == 0) failed = true;
if (File.Exists(path) && !failed) if (File.Exists(path) && !failed)
{ {
//Log(log, "path exits");
int handle = -1; int handle = -1;
for (int i = 1; i < files.Length; i++) for (int i = 1; i < files.Length; i++)
{ {
@ -326,6 +329,7 @@ namespace saviine_server
writer.Write(handle); writer.Write(handle);
break; break;
} }
//Log(log, "error fopen");
//else on error: //else on error:
writer.Write(BYTE_NORMAL); writer.Write(BYTE_NORMAL);
@ -357,18 +361,158 @@ namespace saviine_server
} }
break; 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; Boolean failed = false;
int len_path = reader.ReadInt32(); int len_path = reader.ReadInt32();
string path = reader.ReadString(Encoding.ASCII, len_path-1); string path = reader.ReadString(Encoding.ASCII, len_path-1);
if (reader.ReadByte() != 0) throw new InvalidDataException(); if (reader.ReadByte() != 0) throw new InvalidDataException();
int x = 0; int x = 0;
//Console.WriteLine("old" + path);
currentPersistentID = getPersistentIDFromPath(path); if(op_mode == BYTE_MODE_I)
path = getRealPath(path, title_id); path = getRealPathCurrentInject(path, title_id);
//Console.WriteLine("new" + path);
if(path.Length == 0)failed = true; if(path.Length == 0)failed = true;
if (Directory.Exists(path) && !failed) if (Directory.Exists(path) && !failed)
{ {
x = countDirectory(path); x = countDirectory(path);
@ -433,7 +577,7 @@ namespace saviine_server
} }
writer.Write(BYTE_END); // writer.Write(BYTE_END); //
//Console.Write("list was empty return BYTE_END \n"); //Console.Write("list was empty return BYTE_END \n");
//Console.Write("in break \n"); //Console.Write("in break \n");
break; break;
} }
@ -464,9 +608,13 @@ namespace saviine_server
string strSize = (sz / 1024).ToString(); string strSize = (sz / 1024).ToString();
string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' '); string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' ');
Console.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize); 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 ); //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; int ret = -5;
if ((ret =reader.ReadByte()) != BYTE_OK) if ((ret =reader.ReadByte()) != BYTE_OK)
{ {
@ -486,13 +634,24 @@ namespace saviine_server
int len_path = reader.ReadInt32(); int len_path = reader.ReadInt32();
string path = reader.ReadString(Encoding.ASCII, len_path - 1); string path = reader.ReadString(Encoding.ASCII, len_path - 1);
if (reader.ReadByte() != 0) throw new InvalidDataException(); 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 // 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 // Send response
if (fastmode) { if (fastmode) {
writer.Write(BYTE_REQUEST); writer.Write(BYTE_REQUEST);
@ -652,40 +811,43 @@ namespace saviine_server
Console.WriteLine(name + " Exit"); 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[] stringSeparators = new string[] { "vol/save/", "vol\\save\\" };
string[] result; string[] result;
string resultstr = ""; string resultstr = "";
result = path.Split(stringSeparators, StringSplitOptions.None); result = path.Split(stringSeparators, StringSplitOptions.None);
if (result.Length < 2) return ""; if (result.Length < 2) return "";
resultstr = result[result.Length-1]; resultstr = result[result.Length-1];
stringSeparators = new string[] { "/", "\\" }; stringSeparators = new string[] { "/", "\\" };
result = resultstr.Split(stringSeparators, StringSplitOptions.None); result = resultstr.Split(stringSeparators, StringSplitOptions.None);
if (result.Length < 1) return ""; if (result.Length < 2)
return result[0]; {
} if (result[0] != "common") return savePath + "/" + String.Format("{0:X}", currentPersistentID);
private static string currentPersistentID = "80000009"; return savePath + "/" + "common";
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 "";
resultstr = ""; resultstr = "";
if (result[0] != "common")
savePath += "/" + String.Format("{0:X}", currentPersistentID);
else
savePath += "/" + "common";
for (int i = 1; i < result.Length; i++) for (int i = 1; i < result.Length; i++)
{ {
resultstr += "/" + result[i]; resultstr += "/" + result[i];
} }
string savePath = Program.root + "/" + "inject" + "/" + title_id + "/" + currentPersistentID + resultstr;
savePath += resultstr;
return savePath; return savePath;
} }

View File

@ -30,15 +30,19 @@
{ {
this.btn_ok = new System.Windows.Forms.Button(); this.btn_ok = new System.Windows.Forms.Button();
this.btn_cancel = 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(); this.SuspendLayout();
// //
// btn_ok // btn_ok
// //
this.btn_ok.DialogResult = System.Windows.Forms.DialogResult.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.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.TabIndex = 0;
this.btn_ok.Text = "OK"; this.btn_ok.Text = "OK";
this.btn_ok.UseVisualStyleBackColor = true; this.btn_ok.UseVisualStyleBackColor = true;
@ -47,33 +51,80 @@
// btn_cancel // btn_cancel
// //
this.btn_cancel.DialogResult = System.Windows.Forms.DialogResult.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.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.TabIndex = 1;
this.btn_cancel.Text = "Cancel"; this.btn_cancel.Text = "Cancel";
this.btn_cancel.UseVisualStyleBackColor = true; this.btn_cancel.UseVisualStyleBackColor = true;
// //
// listBox_saves // lbl_message
// //
this.listBox_saves.FormattingEnabled = true; this.lbl_message.AutoSize = true;
this.listBox_saves.Location = new System.Drawing.Point(54, 48); this.lbl_message.Location = new System.Drawing.Point(12, 10);
this.listBox_saves.Name = "listBox_saves"; this.lbl_message.Name = "lbl_message";
this.listBox_saves.Size = new System.Drawing.Size(408, 160); this.lbl_message.Size = new System.Drawing.Size(236, 13);
this.listBox_saves.TabIndex = 2; 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.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(499, 314); this.ClientSize = new System.Drawing.Size(310, 166);
this.Controls.Add(this.listBox_saves); 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_cancel);
this.Controls.Add(this.btn_ok); this.Controls.Add(this.btn_ok);
this.Name = "Form1"; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Text = "Form1"; this.Name = "SaveSelectorDialog";
this.Text = "Injection request";
this.Load += new System.EventHandler(this.Form1_Load); this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout();
} }
@ -81,6 +132,10 @@
private System.Windows.Forms.Button btn_ok; private System.Windows.Forms.Button btn_ok;
private System.Windows.Forms.Button btn_cancel; 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;
} }
} }

View File

@ -12,40 +12,61 @@ namespace saviine_server
{ {
public partial class SaveSelectorDialog : Form 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 int DumpCommon
public SaveSelectorDialog(string path,string title_id) {
get { return dumpCommon; }
}
private static string savePath;
public SaveSelectorDialog(string title_id,long persistentID)
{ {
InitializeComponent(); InitializeComponent();
string[] stringSeparators = new string[] { "vol/save/", "vol\\save\\" }; comBoxCommon.SelectedIndex = 0;
string[] result; savePath = Program.root + "/" + Program.injectfolder;;
this.lbl_message.Text = "Got an injection request for " + title_id;
result = path.Split(stringSeparators, StringSplitOptions.None);
if (result.Length < 2) this.Close();
string resultPath = result[result.Length-2];
Console.WriteLine(title_id);
savePath += "/" + title_id; savePath += "/" + title_id;
string[] subdirectoryEntries;
if (Directory.Exists(savePath)) if (Directory.Exists(savePath))
{ {
// Recurse into subdirectories of this directory. // 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) 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) private void Form1_Load(object sender, EventArgs e)
@ -55,12 +76,34 @@ namespace saviine_server
private void btn_ok_Click(object sender, EventArgs e) 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 btn_cancel_Click(object sender, EventArgs e)
{ {
} }
private void Inj_Click(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
} }

View File

@ -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.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.exe
G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\bin\saviine_server.pdb 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.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.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.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