From f215d3b13ea7107683ba39f66799cca452adc277 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 25 Oct 2015 23:07:28 +0100 Subject: [PATCH] fixed all known bugs -fixed the make dir issue -fixed injection in existing folders need to find a work arround for too much data. --- .gitignore | 1 + README | 58 +++- saviine/client/Makefile | 2 +- saviine/client/main.c | 260 +++++++++++------- saviine/client/main.h | 9 +- saviine/client/saviine.c | 5 - saviine/client/saviine532.ld | 1 + saviine/common/fs_defs.h | 6 + saviine/installer/bin/code532.bin | Bin 7187 -> 7187 bytes saviine/installer/bin/saviine.o | Bin 9248 -> 9248 bytes saviine/installer/saviine.c | 2 +- saviine/server/{src/bin => }/dump.bat | 0 saviine/server/fastmode.bat | 1 - saviine/server/{src/bin => }/inject.bat | 0 saviine/server/saviine_server.exe | Bin 27136 -> 39424 bytes saviine/server/src/DumpDialog.Designer.cs | 140 ++++++++++ saviine/server/src/DumpDialog.cs | 42 +++ saviine/server/src/DumpDialog.resx | 120 ++++++++ saviine/server/src/Program.cs | 37 ++- .../Debug/saviine_server.DumpDialog.resources | Bin 0 -> 180 bytes ...saviine_server.csproj.FileListAbsolute.txt | 1 + saviine/server/src/saviine_server.csproj | 9 + saviine/server/src/saviine_server.v12.suo | Bin 53248 -> 53248 bytes www/saviine/payload532.html | 2 +- www/saviine/saviine532.elf | Bin 70856 -> 81276 bytes 25 files changed, 551 insertions(+), 145 deletions(-) rename saviine/server/{src/bin => }/dump.bat (100%) delete mode 100644 saviine/server/fastmode.bat rename saviine/server/{src/bin => }/inject.bat (100%) create mode 100644 saviine/server/src/DumpDialog.Designer.cs create mode 100644 saviine/server/src/DumpDialog.cs create mode 100644 saviine/server/src/DumpDialog.resx create mode 100644 saviine/server/src/obj/x86/Debug/saviine_server.DumpDialog.resources diff --git a/.gitignore b/.gitignore index cf15d48..643f697 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ saviine/server/src/obj/x86/Debug/saviine_server.csprojResolveAssemblyReference.c saviine/server/src/obj/x86/Debug/saviine_server.csproj.FileListAbsolute.txt saviine/server/src/obj/x86/Debug/saviine_server.csproj.GenerateResource.Cache saviine/server/src/obj/x86/Debug/saviine_server.Form1.resources +saviine/server/src/bin/saviine_server.exe diff --git a/README b/README index 3e1fbbc..83d0951 100644 --- a/README +++ b/README @@ -1,8 +1,8 @@ -Saviine 0.3 +Saviine 1.0 (25.10.2015) Compatible with 5.3.2 fw -dumps WiiU Saves and is a mod of cafiine. Thanks to everyone who worked on cafiine! +dumps and injects (experimental) WiiU Saves(Thanks to everyone who worked on cafiine! code is based on cafiine) Compilation : - in order to compile saviine you need to put the saviine folder in your libwiiu project @@ -13,22 +13,52 @@ Pre-made version : - in www/saviine, it is already compiled, just put the folder in your server Note : +- make sure you already have a save of the game on you console before trying to dump/inject them - you can change the server ip directly in the application. - start the saviine in folder with a short path, some savedata files have some really long names (170+ chracters) - backup your savedata before dumping it!!! I'm not responsible for any lost data. -- fastmode doesn't work for all games. +- make sure that your game version and the game version from injecting save are the same +- e.g. injecting PAL saves into NTSC one is untested! + +NOTE FOR SUPER SMASH BROS FOR WIIU the common data is too big to inject at one time. injecting the common folder will fail. try to split the files up and use the inject without clean to inject the data without the texture folder. MAKE SURE TO MAKE A BACKUP! This may also applies to other games + +The WiiU has mutiple save folder. One folder for infos that are shared with all accounts (common) and a folder for each account (e.g 8000000a) +At the moment it is only possible to dump the common folder your own folder. Not all games use the common folder. + +Folder structur: +logs/ <-- logs +saviine_root/dump <-- the save files will be dumped here. A sub folder for each game will be created (name is the game title id) +saviine_root/inject <-- place the saves here if you want to inject them How to use : -Usage: -Normal mode: saviine_server.exe -Fast mode: saviine_server.exe fastmode -- launch the kernel exploit in the brower -- open saviine server in your computer, check your ip -(you can start the server in fastmode (faster dumper), this doesn't work for all games. Only use it when the savegame is really big (e.g. Super Smash Bros for WiiU) ) -- relaunch browser and launch saviine app, set saviine server ip in the application with up/down/left/right, and press A to install saviine +temporary installing saviine: +- launch the "normal" kernel exploit in the brower +- relaunch browser and launch saviine app, set saviine server ip in the application with up/down/left/right, and press A to install saviine. if you see crap on the screen, press up/down to fix it -> browser should exit -- launch a game or application -- the savedata should be dumped to a folder in /saviine/[title_id] -- profit -- you can close the game and dump an other \ No newline at end of file + +dumping: +--- MAKE SURE THAT THE SAVIINE SERVER IN A FOLDER WITH A SHORT PATH! some gamefiles have some really really long names. e.g. D:/saviine/ --- +- open the dump.bat or start the saviine_server.exe with the argument "dump" +- launch a game +- a dialog should appear, select if you want to dump the user and/or the common data +- the data will be dumped to saviine_root/dump/[game_title_id]/80000000x (user data) and/or saviine_root/dump/[game_title_id]/common (common) +- close the game and dump an other + +injecting: +--- INJECTING FILES IS STILL IN TESTING! MAKE SURE TO SAVE YOUR SAVES BEFORE TRYING TO INJECT SOMETHING --- +--- EXISTING SAVE DATA ON THAT WILL BE GONE AFTER THE INJECTION --- + +- open the inject.bat or start the saviine_server.exe with the argument "inject" +- place the save data you want to inject into the "saviine_root/inject" folder. You need to have a folder for each game, named after the games title id (e.g saviine_root\inject\00050000-1010ED00). +this folder will be scanned for 8000000x or common folders. +- launch a game +- a dialog should appear, select if the profile you want to inject and choose if you want to inject the common files too. +For the commmon folder you have two options: + 1. inject. + this adds the data into the existing common folder, existing files will be overwritten. (I think this way you can add replays to your Mario Kart 8) + 2. clean and inject + deletes all existing files in the existing common and injects the new one. + +- on errors during the injection, the wii tries to restore the old data. but it can't guarantee that it works, make sure to make backups! + diff --git a/saviine/client/Makefile b/saviine/client/Makefile index cf19cfb..c8478fe 100644 --- a/saviine/client/Makefile +++ b/saviine/client/Makefile @@ -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 := -O0 -Wall -x c -std=gnu99 \ +CFLAGS := -O2 -Wall -x c -std=gnu99 \ -ffreestanding \ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar \ -msdata=none -memb -ffunction-sections -fdata-sections \ diff --git a/saviine/client/main.c b/saviine/client/main.c index 1ac22da..bf88b3c 100644 --- a/saviine/client/main.c +++ b/saviine/client/main.c @@ -5,7 +5,7 @@ res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".magicptr"))); \ res my_ ## name(__VA_ARGS__) #define DEBUG_LOG 0 -#define BUFFER_SIZE (1024)*100*2 +#define BUFFER_SIZE 0x400 * 101 #define BUFFER_SIZE_STEPS 0x200 DECL(int, FSAInit, void) { @@ -24,8 +24,7 @@ DECL(int, FSAAddClient, void *r3) { if ((int)bss_ptr != 0x0a000000 && res < MAX_CLIENT && res >= 0) { cafiine_connect(&bss.socket_fsa[res]); } - - + return res; } DECL(int, FSADelClient, int client) { @@ -55,7 +54,7 @@ static int client_num_alloc(void *pClient) { return -1; } -static void clietn_num_free(int client) { +static void client_num_free(int client) { bss.pClient_fs[client] = 0; } @@ -72,6 +71,7 @@ DECL(int, FSInit, void) { if ((int)bss_ptr == 0x0a000000) { bss_ptr = memalign(sizeof(struct bss_t), 0x40); memset(bss_ptr, 0, sizeof(struct bss_t)); + } return real_FSInit(); } @@ -83,75 +83,103 @@ DECL(int, FSDelClient, void *pClient) { int client = client_num(pClient); if (client < MAX_CLIENT && client >= 0) { cafiine_disconnect(bss.socket_fs[client]); - clietn_num_free(client); + client_num_free(client); } } return real_FSDelClient(pClient); } DECL(int, FSWriteFile,FSClient *pClient, FSCmdBlock *pCmd, const void *source,int size, int count, int fileHandle, int flag,FSRetFlag error) { -return real_FSWriteFile(pClient,pCmd,source,size,count,fileHandle,flag,error); + return real_FSWriteFile(pClient,pCmd,source,size,count,fileHandle,flag,error); } DECL(int, FSFlushQuota,FSClient *pClient,FSCmdBlock *pCmd,const char *path,FSRetFlag error) { -return real_FSFlushQuota(pClient,pCmd,path,error); + return real_FSFlushQuota(pClient,pCmd,path,error); +} +DECL(void, _Exit,void) { + return real__Exit(); } + DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) { - int res = real_FSAddClientEx(r3, r4, r5); - - if(bss.saveFolderChecked == 1) return res; - if ((int)bss_ptr != 0x0a000000 && res >= 0) { - //int client = client_num_alloc(r3); - //if (client < MAX_CLIENT && client >= 0) { - // create game save path - if(bss.saveFolderChecked < 2){ - bss.saveFolderChecked = 1; - // Create client and cmd block - FSClient* pClient = (FSClient*)malloc(sizeof(FSClient)); - FSCmdBlock* pCmd = (FSCmdBlock*)malloc(sizeof(FSCmdBlock)); - if (pClient && pCmd) - { - // Add client to FS. - FSAddClient(pClient, FS_RET_NO_ERROR); - int client = client_num_alloc(pClient); - if(client < MAX_CLIENT && client >= 0) { - cafiine_connect(&bss.socket_fs[client]); - bss.logsock = bss.socket_fs[client]; - }else{ - goto error; + if(!bss.saveinitfs){ //bypass the check for save_init + if(bss.saveFolderChecked != 2){ + + if(bss.saveFolderChecked == 1){ + if(r3 != bss.on_start_hook_client){ // block every other client until the on_start method is done + while(bss.saveFolderChecked != 2 || bss.saveFolderChecked != 3){ + GX2WaitForVsync(); + } + } + } + + if ((int)bss_ptr != 0x0a000000) { + int error = 0; + if(bss.saveFolderChecked == 0){ + bss.saveFolderChecked = 1; + // Create client and cmd block + FSClient* pClient_ = (FSClient*)malloc(sizeof(FSClient)); + FSCmdBlock* pCmd = (FSCmdBlock*)malloc(sizeof(FSCmdBlock)); + if (pClient_ && pCmd){ + // need to save the pointer of our client to find it again where adding our client to the FS + bss.on_start_hook_client = pClient_; + // Add client to FS. + if(FSAddClient(pClient_, FS_RET_ALL_ERROR) >= 0){ + int client = client_num_alloc(pClient_); + if(client < MAX_CLIENT && client >= 0) { + cafiine_connect(&bss.socket_fs[client]); + bss.logsock = bss.socket_fs[client]; + }else{ + error = 3; + bss.saveFolderChecked = 3; + } + // Init command block. + FSInitCmdBlock(pCmd); + if(DEBUG_LOG) log_string(bss.logsock, "FSInitCmdBlock() done", BYTE_LOG_STR); + hook(pClient_, pCmd,FS_RET_ALL_ERROR); + // Init command block. + if(DEBUG_LOG) log_string(bss.logsock, "hook done", BYTE_LOG_STR); + + + real_FSDelClient(pClient_); + }else{ + error = 2; + bss.saveFolderChecked = 3; + } + free(pClient_); + free(pCmd); + if(DEBUG_LOG) log_string(bss.logsock, "freed the client and buffer", BYTE_LOG_STR); + if(bss.saveFolderChecked != 3) + bss.saveFolderChecked = 2; + if(DEBUG_LOG) log_string(bss.logsock, "set status to done;", BYTE_LOG_STR); + }else{ + error = 1; + bss.saveFolderChecked = 3; } - // Init command block. - FSInitCmdBlock(pCmd); - - hook(pClient, pCmd,-1); - bss.saveFolderChecked = 2; - - error: real_FSDelClient(pClient); - free(pClient); - free(pCmd); } } - //cafiine_connect(&bss.socket_fs[client]); - //} - } + } + }else{ + bss.saveinitfs = 0; + } + int res = real_FSAddClientEx(r3, r4, r5); return res; } void hook(void * pClient,void * pCmd, int error){ - log_string(bss.logsock, "hook", BYTE_LOG_STR); - handle_saves(pClient, pCmd,-1); + if(DEBUG_LOG) log_string(bss.logsock, "hook", BYTE_LOG_STR); + handle_saves(pClient, pCmd,error); } void handle_saves(void *pClient, void *pCmd,int error){ - log_string(bss.logsock, "init", BYTE_LOG_STR); + if(DEBUG_LOG) 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, "getting mode", BYTE_LOG_STR); + if(DEBUG_LOG)log_string(bss.logsock, "getting mode", BYTE_LOG_STR); if(getMode(bss.socket_fsa[client],&mode)){ if(id >= 0x80000000 && id <= 0x90000000){ char savepath[20]; @@ -183,9 +211,10 @@ void dumpSavaData(void *pClient, void *pCmd,long persistentID,int error){ break; } pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40); + if(pBuffer) memset(pBuffer, 0x00, buf_size); }while(!pBuffer); - - if(!failed){ + + if(!failed){ int mask = 0; char buffer[60]; __os_snprintf(buffer, sizeof(buffer), "allocated %d bytes",buf_size); @@ -194,8 +223,8 @@ void dumpSavaData(void *pClient, void *pCmd,long persistentID,int error){ 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, "dumping user savedata", BYTE_LOG_STR); + if(dump_dir(pClient,pCmd,savepath,pBuffer,buf_size,error,50) == -1){ log_string(bss.logsock, "error dumping user dir", BYTE_LOG_STR); failed = 1; } @@ -207,14 +236,18 @@ void dumpSavaData(void *pClient, void *pCmd,long persistentID,int error){ 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); + + 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); } + + if(DEBUG_LOG) log_string(bss.logsock, "free(pBuffer) coming next", BYTE_LOG_STR); + free(pBuffer); + if(DEBUG_LOG) log_string(bss.logsock, "free(pBuffer)", BYTE_LOG_STR); } } @@ -225,7 +258,7 @@ int dump_dir(void *pClient, void *pCmd, char *path, void * pBuffer, int size,int 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]; + char buffer[strlen(path) + 30]; __os_snprintf(buffer, sizeof(buffer), "open dir %s",path); log_string(bss.logsock, buffer, BYTE_LOG_STR); FSDirEntry dir_entry; @@ -236,41 +269,43 @@ int dump_dir(void *pClient, void *pCmd, char *path, void * pBuffer, int size,int 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){ + + if(dump_dir(pClient, pCmd,full_path,pBuffer,size,error,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); + ret = FSOpenFile(pClient, pCmd, full_path, "r", &my_handle, 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) + while ((ret2 = FSReadFile(pClient, pCmd, pBuffer, 1, 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]; + if((ret2 = FSCloseFile(pClient, pCmd, my_handle, error)) < FS_STATUS_OK){ + __os_snprintf(buffer, sizeof(buffer), "error on FSOpenFile: %d",ret2); + log_string(bss.logsock, buffer, BYTE_LOG_STR); + } + }else{ __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); + if(FSCloseDir(pClient, pCmd, dir_handle, error) < FS_STATUS_OK){ + if(DEBUG_LOG) log_string(bss.logsock, "error on FSCloseDir()", BYTE_LOG_STR); + } }else{ log_string(bss.logsock, "error on FSOpenDir()", BYTE_LOG_STR); final_result = -1; @@ -298,9 +333,13 @@ void injectSaveData(void *pClient, void *pCmd,long persistentID,int error){ break; } pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40); + if(pBuffer) memset(pBuffer, 0x00, buf_size); }while(!pBuffer); - + if(!failed){ + char buffer[60]; + __os_snprintf(buffer, sizeof(buffer), "allocated %d bytes",buf_size); + log_string(bss.logsock, buffer, BYTE_LOG_STR); int result = 0; int mask = 0; if((result = saviine_start_injection(bss.socket_fsa[client], persistentID,&mask))){ @@ -309,14 +348,14 @@ void injectSaveData(void *pClient, void *pCmd,long persistentID,int error){ __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); + log_string(bss.logsock, "deleting user 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); + result = injectFiles(pClient,pCmd,savepath,"/",savepath,pBuffer,buf_size,error); doFlushOrRollback(pClient,pCmd,result,savepath); } } @@ -333,20 +372,20 @@ void injectSaveData(void *pClient, void *pCmd,long persistentID,int error){ /* Inject common */ - result = injectFiles(pClient,pCmd,commonDir,"/",pBuffer,buf_size,-1); + result = injectFiles(pClient,pCmd,commonDir,"/",commonDir,pBuffer,buf_size,error); 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); } + free(pBuffer); } } -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 * basepath, char * pBuffer, int buffer_size, int error){ int client = client_num(pClient); int failed = 0; int filesinjected = 0; @@ -357,9 +396,6 @@ int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char int filesize = 0; if(!failed){ - __os_snprintf(logbuffer, sizeof(logbuffer), "buffer size: %d bytes",buffer_size); - log_string(bss.logsock, logbuffer, BYTE_LOG_STR); - 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)]; @@ -370,16 +406,18 @@ int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char 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(FSOpenFile(pClient, pCmd, newpath,"w+",&handle,error) >= FS_STATUS_OK){ if(DEBUG_LOG) log_string(bss.logsock, "file opened and created", BYTE_LOG_STR); if(filesize > 0){ - failed = doInjectForFile(pClient,pCmd,handle,newpath,filesize,pBuffer,buffer_size); + failed = doInjectForFile(pClient,pCmd,handle,newpath,filesize,basepath,pBuffer,buffer_size); + if(failed == 2) // trying it again if the journal was full + failed = doInjectForFile(pClient,pCmd,handle,newpath,filesize,basepath,pBuffer,buffer_size); }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, error)) < FS_STATUS_OK){ log_string(bss.logsock, "FSCloseFile failed", BYTE_LOG_STR); failed = 1; } @@ -392,10 +430,11 @@ int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char __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){ + int ret = 0; + if((ret = FSMakeDir(pClient, pCmd, newpath, -1)) == FS_STATUS_OK || ret == FS_STATUS_EXISTS ){ char op_offset[strlen(relativepath) + strlen(namebuffer)+ 1 + 1]; __os_snprintf(op_offset, sizeof(op_offset), "%s%s/",relativepath,namebuffer); - int injectedsub = injectFiles(pClient, pCmd, newpath,op_offset,pBuffer,buffer_size,error); + int injectedsub = injectFiles(pClient, pCmd, newpath,op_offset,basepath,pBuffer,buffer_size,error); if(injectedsub == -1){ failed = 1; }else{ @@ -414,31 +453,45 @@ int injectFiles(void *pClient, void *pCmd, char * path,char * relativepath,char } } -int doInjectForFile(void * pClient, void * pCmd,int handle,char * filepath,int filesize,void * pBuffer,int buf_size){ +int doInjectForFile(void * pClient, void * pCmd,int handle,char * filepath,int filesize, char * basepath,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((cafiine_fopen(bss.socket_fsa[client], &ret, filepath, "r", &myhandle)) == 0 && ret == FS_STATUS_OK){ 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(cafiine_fread(bss.socket_fsa[client], &retsize, pBuffer, buf_size , myhandle) == FS_STATUS_OK){ 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((fwrite = my_FSWriteFile(pClient, pCmd, pBuffer,sizeof(char),retsize,handle,0,0x0200)) >= FS_STATUS_OK){ 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); + if(fwrite == FS_STATUS_JOURNAL_FULL){ + log_string(bss.logsock, "journal is full, flushing it now.", BYTE_LOG_STR); + if(FSFlushQuota(pClient,pCmd,basepath,FS_RET_ALL_ERROR) == FS_STATUS_OK){ + log_string(bss.logsock, "success", BYTE_LOG_STR); + failed = 2; + break; + }else{ + log_string(bss.logsock, "failed", BYTE_LOG_STR); + failed = 1; + break; + } + + } + __os_snprintf(logbuffer, sizeof(logbuffer), "my_FSWriteFile failed with error: %d",fwrite); + log_string(bss.logsock, logbuffer, BYTE_LOG_STR); + //log_string(bss.logsock, "error while FSWriteFile", BYTE_LOG_STR); failed = 1; + break; } 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); @@ -451,7 +504,7 @@ int doInjectForFile(void * pClient, void * pCmd,int handle,char * filepath,int f } int result = 0; - if((cafiine_fclose(bss.socket_fsa[client], &result, myhandle,0)) == 0 && result == 0){ + if((cafiine_fclose(bss.socket_fsa[client], &result, myhandle,0)) == 0 && result == FS_STATUS_OK){ if(DEBUG_LOG) log_string(bss.logsock, "cafiine_fclose success", BYTE_LOG_STR); }else{ log_string(bss.logsock, "cafiine_fclose failed", BYTE_LOG_STR); @@ -477,14 +530,14 @@ void doFlushOrRollback(void *pClient, void *pCmd,int result,char *savepath){ __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){ + if(FSFlushQuota(pClient,pCmd,savepath,FS_RET_ALL_ERROR) == FS_STATUS_OK){ log_string(bss.logsock, "success", BYTE_LOG_STR); }else{ - log_string(bss.logsock, "failed", BYTE_LOG_STR); + 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){ + if(FSRollbackQuota(pClient,pCmd,savepath,FS_RET_ALL_ERROR) == FS_STATUS_OK){ log_string(bss.logsock, "rollback done", BYTE_LOG_STR); }else{ log_string(bss.logsock, "rollback failed", BYTE_LOG_STR); @@ -499,10 +552,13 @@ void init_Save(unsigned char slotNo){ OSDynLoad_Acquire("nn_save.rpl", &save_handle); OSDynLoad_FindExport(save_handle, 0, "SAVEInit", (void **)&SAVEInit); OSDynLoad_FindExport(save_handle, 0, "SAVEInitSaveDir", (void **)&SAVEInitSaveDir); - - SAVEInit(); + bss.saveinitfs = 1; + SAVEInit(); + if(DEBUG_LOG) log_string(bss.logsock, "saveinit done", BYTE_LOG_STR); SAVEInitSaveDir(slotNo); + if(DEBUG_LOG) log_string(bss.logsock, "SAVEInitSaveDir done", BYTE_LOG_STR); SAVEInitSaveDir(255U); + if(DEBUG_LOG) log_string(bss.logsock, "SAVEInitSaveDir 2 done", BYTE_LOG_STR); } long getPesistentID(unsigned char * slotno){ @@ -540,20 +596,21 @@ int remove_files_in_dir(void * pClient,void * pCmd, char * path, int handle){ 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(DEBUG_LOG) 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; - } + } + 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,FS_RET_ALL_ERROR)) < FS_STATUS_OK){ + __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 ){ + if((FSCloseDir(pClient, pCmd, handle, FS_RET_NO_ERROR)) < FS_STATUS_OK ){ log_string(bss.logsock, "error while closing dir", BYTE_LOG_STR); return -1; } @@ -582,4 +639,5 @@ struct magic_t { MAKE_MAGIC(FSDelClient), MAKE_MAGIC(FSWriteFile), MAKE_MAGIC(FSFlushQuota), + MAKE_MAGIC(_Exit), }; diff --git a/saviine/client/main.h b/saviine/client/main.h index 3332d63..958dd20 100644 --- a/saviine/client/main.h +++ b/saviine/client/main.h @@ -36,6 +36,8 @@ #define MASK_COMMON 0x0200 #define MASK_COMMON_CLEAN 0x0400 +void GX2WaitForVsync(void); + void *memcpy(void *dst, const void *src, int bytes); void *memset(void *dst, int val, int bytes); @@ -68,6 +70,7 @@ extern FSStatus FSRemove(FSClient *pClient, FSCmdBlock *pCmd, const char *path, 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 _Exit(); extern void socket_lib_init(); extern int socket(int domain, int type, int protocol); @@ -79,13 +82,13 @@ extern int recv(int socket, void *buffer, int size, int flags); extern int __os_snprintf(char* s, int n, const char * format, ...); 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 * basepath, 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); +int doInjectForFile(void * pClient, void * pCmd,int handle,char * filepath,int filesize, char * basepath,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); @@ -114,7 +117,9 @@ struct bss_t { int socket_fs[MAX_CLIENT]; char save_path[255]; volatile int saveFolderChecked; + volatile void * on_start_hook_client; volatile int lock; + volatile int saveinitfs; int logsock; }; diff --git a/saviine/client/saviine.c b/saviine/client/saviine.c index 1413ff9..2760049 100644 --- a/saviine/client/saviine.c +++ b/saviine/client/saviine.c @@ -12,11 +12,6 @@ static int cafiine_handshake(int sock); -void GX2WaitForVsync(void); - - - - void cafiine_connect(int *psock) { extern unsigned int server_ip; struct sockaddr_in addr; diff --git a/saviine/client/saviine532.ld b/saviine/client/saviine532.ld index 51df7c0..e0e33a4 100644 --- a/saviine/client/saviine532.ld +++ b/saviine/client/saviine532.ld @@ -47,6 +47,7 @@ PROVIDE(FSIsEof = 0x106f610); PROVIDE(FSWriteFile = 0x106F228); PROVIDE(FSFlushQuota = 0x106FAC8); PROVIDE(FSRollbackQuota = 0x106FC48); +PROVIDE(_Exit = 0x101CD70); /* */ PROVIDE(FSGetStat = 0x0106fdc8); diff --git a/saviine/common/fs_defs.h b/saviine/common/fs_defs.h index 95b3180..f78a3c3 100644 --- a/saviine/common/fs_defs.h +++ b/saviine/common/fs_defs.h @@ -10,10 +10,16 @@ #define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE #define FS_STATUS_OK 0 +#define FS_STATUS_EXISTS -5 +#define FS_STATUS_STORAGE_FULL -12 +#define FS_STATUS_JOURNAL_FULL -13 + + #define FS_RET_UNSUPPORTED_CMD 0x0400 #define FS_RET_NO_ERROR 0x0000 #define FS_RET_ALL_ERROR (uint)(-1) + /* directory entry stat flag */ #define FS_STAT_ATTRIBUTES_SIZE (48) /* size of FS-specific attributes field */ #define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 /* entry is directory */ diff --git a/saviine/installer/bin/code532.bin b/saviine/installer/bin/code532.bin index 33366d58d8fdc8b03211d811ee4b49dd88cd64bc..e4a58b2dc08afad2ec44b5dd21aec6e8340d0699 100644 GIT binary patch delta 16 XcmbPiG1+3nb}42$*0q#_vsGy(;U diff --git a/saviine/installer/bin/saviine.o b/saviine/installer/bin/saviine.o index 94ff1dff04b1ea903a396c0bbc654cc07e03e39e..a39d9072eea8b3874e13db4e81ee5919fa61e311 100644 GIT binary patch delta 16 XcmZ4BvA|=)YbjMNLIs^s| delta 16 XcmZ4BvA|=)Ybj;}J>$*qq>MNLIt~U9 diff --git a/saviine/installer/saviine.c b/saviine/installer/saviine.c index ca4f4dd..934f0ab 100644 --- a/saviine/installer/saviine.c +++ b/saviine/installer/saviine.c @@ -308,7 +308,7 @@ static int show_ip_selection_screen(unsigned int coreinit_handle, unsigned int * while (1) { // Print message - PRINT_TEXT1(14, 1, "-- SAVIINE 0.3 (a cafiine mod) --"); + PRINT_TEXT1(14, 1, "-- SAVIINE 1.0 (a cafiine mod) --"); PRINT_TEXT2(0, 5, "%s : %3d.%3d.%3d.%3d", "1. Server IP", ip.digit[0], ip.digit[1], ip.digit[2], ip.digit[3]); PRINT_TEXT1(0, 6, "2. Press A to install saviine"); PRINT_TEXT1(42, 17, "home button to exit ..."); diff --git a/saviine/server/src/bin/dump.bat b/saviine/server/dump.bat similarity index 100% rename from saviine/server/src/bin/dump.bat rename to saviine/server/dump.bat diff --git a/saviine/server/fastmode.bat b/saviine/server/fastmode.bat deleted file mode 100644 index 449152e..0000000 --- a/saviine/server/fastmode.bat +++ /dev/null @@ -1 +0,0 @@ -saviine_server.exe fastmode \ No newline at end of file diff --git a/saviine/server/src/bin/inject.bat b/saviine/server/inject.bat similarity index 100% rename from saviine/server/src/bin/inject.bat rename to saviine/server/inject.bat diff --git a/saviine/server/saviine_server.exe b/saviine/server/saviine_server.exe index 2c9f79b94ba2041e6c4938446598f61515a1f224..abf68e58fbac1ed78d32f9a5dc9db93c0a1a5cf9 100644 GIT binary patch literal 39424 zcmeHw3w&I4mH)YS?%a7KndHvo*(S~OL76s9`le}13u%(JfwWDVw9rxv(`4FCo8*R> zqz@{XDk3g#MC9f25LZzY5L6Id+f@-%Ug86G6$|USBJ5vTbyrp`|L-}!d+*F71-h*J z`TQR{Fz5cx`JLZ6=XZYR_q@MJ*KNC&d_-j6`{tWO597(7GX=gq7(;fX{wooBDD>pi zhqcZpr}pelXXC>edsiko81G9C4cQ~{9jSO`bSR!4innd(jt|=Xsiu;W@C-+ES36Os z=A-YdZrtK(J4U)zq!kfe3rbK?SKfzb9N#1OvUPDhbY(YEVn08LG@*0KM`wPJs7(IP zJsp%8@Oka?L>oA91a|Y09JqY%sE|bPQjXbrZgMpEHS8<)M;{ zvtRLH+jR0%d^gbzXcLYJ3)=4ANi+XF2nEAQLO+s~Obz6ch)b6ml4KP# zu!(wBl5CuwsAdiNAr@C<*W{4;()b6VFFOe&dvcDRf$_sOBF!yTzp=g|TgO~ea>Poz zK8IvVxkx-msIsT#5dFA`s+rkoAlcIuooiI>TEj^E2G}yuAkNCb9iBlARA^rl)t1l^V1Ji3p!hPZ1+f zw6H)C6EmO4QzTqHSxT=kH9^0CO}t9_Egj~k&xLg|hHPL{FGd^HMKwokwTrs zS#@sAv`ou?b^5p=j5p@-*{FTE>bT}qps~~uQfV(khEo^ir{$=L)Lm*Ul9*dLRdHjE zA`Q+adX6G5QE&yOA#U5rn3Fm|m9}-wguJkQI)Gczuv1Yy!D^}&RSIlK3ahr22uQ4C z>t-um8r4nlbb-nm3Gp<39^{xPoCldQejbd?Gw5RoDugoPP0fR-k~dY1Lv|Ci2xIq0S_1y(6z{JcyvTmmZm=M32o2qc}$Mh*qBVbN^yNU6%x0x7OOyTs! zl`W*O^9v~)0fiKfw?Ybsc_D>+qC@c}#y_K~?!-9V=QTLIje%ErJF!aqHGZy~j4>*P z2@w-8#;B{)RmXK6z=Kw>v62#PD3e*k0^7NC^J{1mVUkgvnf8!gc}wOa%(5CRjZ+!@ zq=!Zsz0XA_GSPqRxH20MN$ULGN>vRZ1`j> z0G%HIrxmczL8e-Shz4FM1T!CEDGNA9i0&F>tN!7a^(njt*+IHbbq3u&m&N-WPRZEH z6fa{NV^~1&`e8SsHNbtWGOQ=gLk9d7Gb>|(hBBBMxTP42tFRS-sR1isnVtt<))R}s zT|yznZ3%bGcnkKIumo%%%RhVaJd<9>;1OheGdr53z1R%Iu4u=el?72NliQ&2R~$jniQ zm*FRNhIK|`4OziB&hW@agPD|h4!PMr7EzzQ0Q zO_}UATkS-LA-m4ao^rxgtq*1TR87RFssuU$f)G)dO(RtjdOO#sjy6%PsGO)ydULE8 zBH4LXu^J9!=0Zar_ZqVKTUdh-hJXY|a*0(EYq47DTNm%KTH4WN2u(vv&~cU*5v>91 z=g?*NIsSV+_PUp1i0v;X`Z~UD{v9X>foE=Q$Ks!`e4$q`!!7}`66*jU>StXM^kv6;|ngB*i0_+lM|(I>yntYH1W z*oaRiSE@wwpW)|#1!HTfs#hfDF;ik#&)Xfir!m%LUu5c5TRt0+g zo29)1Jv*1(#kI96ru50U&>O?h7|XA4-2|)u-qGBpjJ+jR6`CYV+t?~=Rb}R8=^U%7 ztja4f`)YSttEw|c6|KgKxwOO(YL`%60qY*y20mVuQ(I~%EvzCn{{TVCb;JZ_4#lb~ zV>OkrNmj8{okawjvB_jjwud1xR%_KdJ9uuQVWwl!GG#%7H2Q=YtAV>chcse2!>zVP z?5T0qXA(`Bsz5HIa(?6zc-W}iBSqclX$)U-8mJ7(&4Ii6E*0d9~b6ZGk=tgfE8t|?CZ{sL9X#ub^V;Dp{r#^9)4!a*?-pqVgYe0Xy_K=)?`~LK zh)^gPR$oFR5yo5W8qL^rYkH;Hm+^@EEy*%0D>}o@aIa;{BYdFL4%_~q~Ras4y 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 y5i<7#*0`q6EwKIcxtdl@V^0L#(H@G literal 27136 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 HjTRL diff --git a/saviine/server/src/DumpDialog.Designer.cs b/saviine/server/src/DumpDialog.Designer.cs new file mode 100644 index 0000000..870e6a4 --- /dev/null +++ b/saviine/server/src/DumpDialog.Designer.cs @@ -0,0 +1,140 @@ +namespace saviine_server +{ + partial class DumpDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btn_ok = new System.Windows.Forms.Button(); + this.btn_cancel = new System.Windows.Forms.Button(); + this.lbl_message = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.Inj = new System.Windows.Forms.Label(); + this.checkBoxUser = new System.Windows.Forms.CheckBox(); + this.checkBoxCommon = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // btn_ok + // + this.btn_ok.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btn_ok.Location = new System.Drawing.Point(15, 133); + this.btn_ok.Name = "btn_ok"; + 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; + this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); + // + // btn_cancel + // + this.btn_cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btn_cancel.Location = new System.Drawing.Point(148, 133); + this.btn_cancel.Name = "btn_cancel"; + 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; + // + // lbl_message + // + this.lbl_message.AutoSize = true; + this.lbl_message.Location = new System.Drawing.Point(12, 9); + this.lbl_message.Name = "lbl_message"; + this.lbl_message.Size = new System.Drawing.Size(217, 13); + this.lbl_message.TabIndex = 3; + this.lbl_message.Text = "Got a dump request for 00050000-10157F00"; + // + // 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(84, 13); + this.label1.TabIndex = 5; + this.label1.Text = "Dump user save"; + // + // 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(104, 13); + this.Inj.TabIndex = 7; + this.Inj.Text = "Dump common save"; + // + // checkBoxUser + // + this.checkBoxUser.AutoSize = true; + this.checkBoxUser.Checked = true; + this.checkBoxUser.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxUser.Location = new System.Drawing.Point(202, 50); + this.checkBoxUser.Name = "checkBoxUser"; + this.checkBoxUser.Size = new System.Drawing.Size(15, 14); + this.checkBoxUser.TabIndex = 9; + this.checkBoxUser.UseVisualStyleBackColor = true; + // + // checkBoxCommon + // + this.checkBoxCommon.AutoSize = true; + this.checkBoxCommon.Checked = true; + this.checkBoxCommon.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxCommon.Location = new System.Drawing.Point(202, 85); + this.checkBoxCommon.Name = "checkBoxCommon"; + this.checkBoxCommon.Size = new System.Drawing.Size(15, 14); + this.checkBoxCommon.TabIndex = 10; + this.checkBoxCommon.UseVisualStyleBackColor = true; + // + // DumpDialog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(257, 166); + this.Controls.Add(this.checkBoxCommon); + this.Controls.Add(this.checkBoxUser); + this.Controls.Add(this.Inj); + this.Controls.Add(this.label1); + this.Controls.Add(this.lbl_message); + this.Controls.Add(this.btn_cancel); + this.Controls.Add(this.btn_ok); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "DumpDialog"; + this.Text = "Dump request"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btn_ok; + private System.Windows.Forms.Button btn_cancel; + private System.Windows.Forms.Label lbl_message; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label Inj; + private System.Windows.Forms.CheckBox checkBoxUser; + private System.Windows.Forms.CheckBox checkBoxCommon; + } +} \ No newline at end of file diff --git a/saviine/server/src/DumpDialog.cs b/saviine/server/src/DumpDialog.cs new file mode 100644 index 0000000..4e01fe6 --- /dev/null +++ b/saviine/server/src/DumpDialog.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace saviine_server +{ + public partial class DumpDialog : Form + { + private Boolean dumpUser = false; + private Boolean dumpCommon = false; + + public Boolean DumpCommon + { + get { return dumpCommon; } + } + public Boolean DumpUser + { + get { return dumpUser; } + } + private static string savePath; + public DumpDialog(string title_id, long persistentID) + { + InitializeComponent(); + + } + + + private void btn_ok_Click(object sender, EventArgs e) + { + dumpUser = checkBoxUser.Checked; + dumpCommon = checkBoxCommon.Checked; + + } + + } +} diff --git a/saviine/server/src/DumpDialog.resx b/saviine/server/src/DumpDialog.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/saviine/server/src/DumpDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/saviine/server/src/Program.cs b/saviine/server/src/Program.cs index b8bdbe8..388c98d 100644 --- a/saviine/server/src/Program.cs +++ b/saviine/server/src/Program.cs @@ -425,56 +425,55 @@ namespace saviine_server } } writer.Write(BYTE_OK); - Console.WriteLine("InjectionEND"); + //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); + Boolean dumpCommon = false; + Boolean dumpUser = false; + currentPersistentID = wiiUpersistentID; + + Boolean dumpcanceled = false; + DumpDialog ofd = new DumpDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { - currentPersistentID = ofd.NewPersistentID; + dumpUser = ofd.DumpUser; 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; + if (dumpCommon) Console.WriteLine("dumping common data"); + if (dumpUser) Console.WriteLine("dumping user data"); } else { Console.WriteLine("dump canceled"); - injectioncanceled = true; + dumpcanceled = true; } } catch (Exception e) { Console.WriteLine("dump canceled"); - injectioncanceled = true; + dumpcanceled = true; } - if (injectioncanceled) + if (dumpcanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); - }*/ - writer.Write(BYTE_SPECIAL); + } + int dumpmask = MASK_NORMAL; - if (currentPersistentID != 0 && currentPersistentID != COMMON_PERSISTENTID) + if (dumpUser) dumpmask |= MASK_USER; - if (dumpCommon == 1) + if (dumpCommon) { dumpmask |= MASK_COMMON; } @@ -496,7 +495,7 @@ namespace saviine_server } } writer.Write(BYTE_OK); - Console.WriteLine("dumpEND"); + //Console.WriteLine("dumpEND"); break; } diff --git a/saviine/server/src/obj/x86/Debug/saviine_server.DumpDialog.resources b/saviine/server/src/obj/x86/Debug/saviine_server.DumpDialog.resources new file mode 100644 index 0000000000000000000000000000000000000000..6c05a9776bd7cbae976fdcec7e3a254e93018279 GIT binary patch literal 180 zcmX?i>is@O1_p+SK%5g?SzMBus~417oL^d$oLUTL1*ImYq!#HYR*8GxXUf^%t3Noi54ZC+|=Nl{{sjzU0bQch;FcWPxwes*e}ZIZcpqG__J onW3ezNveT`r81^vrFkWpxv4PQgHubGfR2KJ07n-P+5+SQ04Y>DD*ylh literal 0 HcmV?d00001 diff --git a/saviine/server/src/obj/x86/Debug/saviine_server.csproj.FileListAbsolute.txt b/saviine/server/src/obj/x86/Debug/saviine_server.csproj.FileListAbsolute.txt index 4e3310e..f376321 100644 --- a/saviine/server/src/obj/x86/Debug/saviine_server.csproj.FileListAbsolute.txt +++ b/saviine/server/src/obj/x86/Debug/saviine_server.csproj.FileListAbsolute.txt @@ -6,3 +6,4 @@ G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debu 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 +G:\Programmieren\libwiiu-master\saviinet\saviine\saviine\server\src\obj\x86\Debug\saviine_server.DumpDialog.resources diff --git a/saviine/server/src/saviine_server.csproj b/saviine/server/src/saviine_server.csproj index b8f286a..d61b573 100644 --- a/saviine/server/src/saviine_server.csproj +++ b/saviine/server/src/saviine_server.csproj @@ -57,6 +57,12 @@ + + Form + + + DumpDialog.cs + Form @@ -94,6 +100,9 @@ + + DumpDialog.cs + SaveSelectorDialog.cs diff --git a/saviine/server/src/saviine_server.v12.suo b/saviine/server/src/saviine_server.v12.suo index 4ceec0a239d77d21e44841b0437c412155276d9a..94173cb919b4a3ea3094e6463c88283186c36dcf 100644 GIT binary patch delta 3909 zcmdT{4@{fK760xt24jB)n_%-F90J5RzzjGEYL|q7lMo<=Y;KnVN%<2(SVI!9od(i? zvym;VEDe59)wE~>lhH)UI>MK9WNI_Bz(lfjgH4*cN$c1qP181Mp$bwKEoJZ7{#sL{ zR8^))JM{Ctd+*)5``+FC?r;yu+(WW+Uu0p|HbwJH39I=uwWf2YzCC)5WpEr<44wQ5 z)&q;YP0cM~$wVd9Fkr}FFMvx{C8$uP4pH}f6&nJA$|}So>JTiE*p_4^%GCKIRFFRf zQ3TsMtWyyYh$sa0(PEv1&;;93oJ4HbBkTb^kF(RNl62d!nT1%3$PSp6@}OO@imk`r zq=XHqdn%}xLOqS`60+{LqSTC_$!*7a2citI6H$(+KvW_U5Y&5juqOE{A@VaQKa1E8 z&*{=)DH@dq)HEVu5zsI91yf&Nv+ape-xiwsz(`9=p-VvNk3*16NB$WDi1o_ru9fPoAp5k()FZ%SNJW=+A(CkC3&XB3c0iP(vPETxaMmk1WgP^TV zJ6YNu^br!^Qmk3A5sgI%n2(K*mn>URQGzH%&;&uFi}kOlziFu8$SYxN5exk{i5f-a4ZL)C#RABUheF`1-S6Divm{$TOKsjR*TE9c_cxTCOo z?JDg*&%QAG@O;LN3s+TwY~i(a99en8; z95Ye)hfe$HLMOjr@4sRAhh|T&35I$tFmO5DGZhb-VWT3L7!Hbui@-f)SD4pZHf*$< zd=KVMXMp?V?`WH<^X~rk`@e9E#DL-7Y4sehtwaMqInWa z)$DQGJn4kWi2k(8u)tEb^)t5!ESm6PMc0w^j-X=!&UO9&W0K!RC;CaRt2X?O!-ylG zR;9uFx@7+errc2(FTU+RwIO^)R5gtqX7H<*Q&lKsmHC)joGkk?V`HEze>XCBI(Bm- zK2V>Bl=2(mxr!Q@irzHR30T;b4dz-iR9EeZ-ceGylgLG~;n9XmRYl%19{yB4DpuFk zFz>Sp`0&u{Vwe2@gMw$QD13u~xuqXw4=Tm_#-T{?)?W=a%4N{eW`uobZQ`+`-;#^- zZ3bSv+cM9*UBbxxi#*JYB!l}*n)vjYX$G_P-Q)_|oHA0v-Wx`!&HbLIV-LFsY30ip z2RVx#WHY3PYG)2kKL!krQTFySPdwh}Nf)8yX@xJjF2Z@|E&i{Zr>`9P-x?G@=z4{L zweN=_PCI8>fY75h&1@_06U z-F->>1FV9Nl~!~<#2w*UxIE+=2e%ob+!q2~5kW5~J9Q8gz3K3mQ;Cd&$**r2|C)*a zoXnEzR;J?XlJ3h04rWiA;q2Sbf$f$OUcGE&?;!nrfiz+JU2R99!JE$}gQ{K7kYf@} zL%)$}>Kx4-$C^9p934${k{{d~lC$aM-N(eI;M>=J3Z|i4@2C>Y!xv!e`kz+}8Ub71 zy#seIi~2VtTEy91L7Co<)|Ely^;VpnwYA~Uk(NAbv!k`;aC1jqlcNSEe{79=j4h08 z@b{?{c;}`{Pyd_*N{o;Gx1raob!7&k)gcj^9J^_dsFkWf>`OP(^mJ26Wi1NCa#ksg zpJbLYmJmAICWoPR+hOO6u8sqHYiX4DWutsz^iN^AQ5p|xF=65@2Ev4(OvY9k4Sq*j z7f~}>$i!>D_nC&?3G~>bl>hPE;NM{GM`qD>OJpL;>S5#W*%;)Hr{g3w;GSuOh0#>c zomXM5zyu2~#X|IGj>k|u;`1^nHrSwjqJW;19BjE659T*D@PjkqiF8{Bio&We?Wv}=- zO)9G+gdT!4;6QT`Mu;M&hz%FeVO=h9;4bU8hZq(|qr)F_x#zFEVUWdx z5HJ%=1F>K!U=^My2514VQVR@}Vwkh9$+*Fa4l6x@Is=$NRzQ}GItS!}JYWHZfc3fX z2A)K}c#5n9?fKw4pcIsW8G!YjWY@%D(S&6X@R?ayhq@ko7c2*B{YuHyuf7m4r~6m& zw~P;A&TUi8$!l_v&B|>)h-_IM_Mir`JQQuVF88OSX6tGITbI9+t;^%G4-FXOJ{MS< z9GV&bS6j~t?B{E2-L82NN_~JdhU8hh(bxlC27AFPpdb7Ykj-G)b^whxz(H^b41mL6 z5DWn}%@Nc`!LdM}Wz3HP{gbFqfggj@;0)k#DNvt9{Z63G^7Cl_)Zf?oCh|>4lZGU5 zZ(q${9{m$|A}b<9Bu>be5C`_f2xaaZ+xAUOj0>~_akuTf%{2YiCg_+@&2((<$QYsF_! zvhmGt`MGWs^Nk7oU_aiJ1!RjXCim<+>NyZBq0MEzVm3|Ax#^o;4n4fCI6;%C)$CJo zoVwDM>N#pB0C~6ix6t9>$>kCBiF7wfr5q`;2|Y*Ia3G(II^%|=RVXmduTo^u{YWqA%!C{1SQ1f{&+K-HsKiW)J| zr`N~nncYV`F}DA4!A*F5oIv>|2Pgaqb(xmxImfbyi_cAO(Ik3e z6I0|-!{}7|uY3u_KEvOhww+l-}8DMjqR?s z^)CB{Oh?C-EkPf%7uZtY+zT9i{+k#0UGswMv{1hnq%YI13BNHpcFCi3XRceUhPUBA z`73!$H2U1l|El=b2E{Ac-Fzi=RS*Xpe82ZTr&m228XEc{?WTtJD^EdpX5ReIz3953 zG7eBAZ;eoTstme*#HU5&brmZSQYK#BMXkM|bgC*<_tf7%+xmIrgh1e&Dwq0~tW>EG zDJaMF7+Jdv(nl-*q#UeOQf^z1^!loGf}+H!i#m+n`oKcAQiv#o}lrjmZG`yJmHW3UV*=` z)2Tf3Z_|c;@bo{1pI+SX!EZH})B1if?jKo^g`nh*Y?RzLELHW?i$PZiX?B&K>; zTRmB7QA?5T{o)-O+q!FRE0SNQVxyu>;X=CWK-&e0U9kaeyP_MZuvq~eGVO1a-hQ!4 z<=OQy&F+t(oZabC`oQm0wEukLHw-nNt9`VWii<|-PgK6~;l)FWq7T%eH@1F{ZzA7W zF8q-HjL7Zp{rf{6JgU{bif7J$Cc+d~0x_&1r`6fHvCZ{-N2kka-_T+2Zfujz%E*lP4Xyx;C(uH`c`nRhKdK?n>o9{ zl55S&&bJg4T3!fK*yMdRta!+|;;Q|2s`J^YE@-D`IA<8YZqRVQLHh7wJpJLiUdx%5 zi|swOh4jg}ZV?MF1q=Vj;Jg|a26NI31mBE?cv`rEPsCfA8BiQr&d* zzx0gU3$7h(1XJGksr22?sNz@&l^(7NX7bVFdTJQ0mR5`&NATJm!t>JEpH&6hwP#cK zuxbv}8tJdsrweL7oIqn268RC+wVis>=j*8{VeJ(1eE*)eTMSg2Zi)>gX}m0#!l7sk zY>oCEP50#2Q}nS!sy!P^JF_;CJOALfdiw4gZ88N%w$3fihJ@0c6AMutl(m`J?<$z$K8S^M{99u&!Jn}g)L%o3>pNsC{R%(Z@<6$ z-kVGUVr{!;&z^JXp}e{8zWe9%`*VN4-+M-HU$RiR1SS8tC=1s@!A_C>_59{zu%$>Q}Lqi2u@`al87X2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`e zihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhl zpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H; z0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2Or zBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs> zC<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%I zfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhl@c)y* zJg>-&7tZxY3e%pxBbM&9f9EHEufqMca|CK>*=j|=9zhcY1BJR znUzBx>JpSyYtl%(k|?^lhN^Z@KFgy#DKQS zwbgFVLmPEPiL{-rt)b(0ZTqxw{($vpf5dvGq^#$PQ8vE0_`QjTwP|9`;S) zLKA0mn@N_#p;lv!?)xGg{x8y8V}bVm&Zc9>^;l@vg`cX^@5{|yssS`);Y zyq6p{7)P>+Ec&oGWu4X0m(M0SB(N6d%Ijslw$?hP%?p6%IMApV2o%?;R8aMuhh$UNMf% z(Ypsl%&45McMpqB-(oU)gxJ)RC${udiLRbOv9o7b?CKR_Pj8-ht~V_9^1l78yzlf? z8>eC4+XL3V7m^9je$VawAoXn%ckp zl-{16(6!xjNBzU(o)5ijf9uEkydjahdyvbTKu3f&Bw3hquJzrt+-Z|qti?iZ_$X89C_L-0B%NNtFS|^FfVmie8iHJL! zG?N<3^T-{YaZtDRaq>s-J?@gtL{)v_K;-R*b!V;7nFn>v6zkjfJgbLB-(6>{zF|XE z%$3P{g?%)}o|*ePGh!}Zf7s)<$E%lIifKf0xr6-?U5wr5>Izb6cO1WCZ(_{4Cw1e# z!^J!Y^!J&PglSgo5T_zXTJamc4~obAjE2L|@BD4?o5XsSee@@1b!`B;@U>q`POR^| z-q7gDyP~h0)tRYLe}mo?6^&Kf&3(KU@L$h1sC`#7vTgJ8*0^7;;(P5+Kbzb$_Sr4R zSZ$BdCmxUIS#wA^Vh!CI#<1lW6)$7%_m=ZBRXfJCR9W-5q0uw{%FoAF3cY(4Y`bcy z?u&{8vFVhaIB9;|{_+o{|A-$nUx=SH_jOD+2Rde(uXKdW108G4pLINH9_o13e7)nK zdAQ@Gc{DNI97@bKM-m}(G_lq^m3Y)VlX%uVmpEu%h=jkXvwy2x#ePlX);>%lu}9_} zikI6mfKCRfePio+ zU2^U{*4);-qbII1@3oj$<2B;nyZx*9-;2+2|B9H%mHN@CEs^>m?btM}_1^pj`q$Y0 zT<8Am6S;qH9yP+JZ!wO{(R-_Cz2ke0e}o?lQ=9aYang++!%qrYV;Jy@{bayqjov|u z;T-5>e+Rz^e9hQX z)S05YI9B3zj+JmP!10o^Zp`81-_}|Sz6x&BqiHY0CkG8DHi|(`36=q$)sR~P@=8EP z3CJe_ncz%};SBG@nYf8nY=BRaQyMi?P&Zxt&pQji zI(@-$ZnFjMNqJe!wSD9FW*x`9Ep}}1{Jd4rd+1qsE%bg+1Q8!B!L_s`Hc=&9?bxuhibmZ3Q`uv?9+IFkREFU1c=SMU$A9_`_pUQ$H8hveZ zy|H1D8DEQ-p~14VqBQ7!Osv3InbBj5v!Z=xD6m}w;$J0df8~cd`e#LVpVW>fQ;W;!Cq?@kcb+9e*eLi=hLFe3ZNqer^VRpsmBz67;hkrTjK1hYqkMf?`-#GpS z0r3Uff~oEHb+NDFbz1iD)-}v1)mH_n;CATeND8|;haK(}@>(VLDKCRN z<{UlsA@^lYy!XHk%8@z``+`5>=VsbMIlyuJLxi#%n6c?5gOAy8=DKt|h&Bu4TP( z*Q(xrS6z49mCyE4{?}|TX@_OL@T8S5#MZjxe#&=(U#DN5D5=@q%mk7MBZtME4_a*MwJKk1u$&i7mY z3V*9V%fHoM0C^q=^rQuid9c;LHBI;i8G~Ojp54sxtoSqTb6GswiFmdOz9pYN&v6RJ z=^U$YoQ}BE&2f5p9I-5XqNOK8C*qYZw)X+7;d%T!h%+kyUpQfJ-Sas2vi2_b-4ENu zUU|1zUk9#<#FHNL28J;!VDN6o$R{6O3mN4yq^#l3&3m@R&jE0g0z-WS_I zd;OET7A3d6uWRIb5mRg5B{#>=QrBfnJ#!wPrO>@;(c0hW+rH*ZbY7hn7{qN z4-tbN`xo95;`>7}?34S&Ub6a?d($!}9@X13kn8+AIGGnew9nbL_7ASlV*TnyJR2Eo z#l1^gqu&PmAf742Gt&}iyRaWzT}IOlI`+OrvbPyo+>hO8ai=9Ef5&mwSmzx%%-~W` zlX2>$Sb2c`=Er5@e9SElL+ufNV4UHMo54=zJ?zKAocDD4iyWVB`TZFg=<~R<4yhBY zGncP>3a=S{+KGRMd=7w4*M*`#reH)@*v*D`Gme# z$Yp(t=r+z*SwVmF*g=P8mURB>}9tc>?fxv!$~{6}a*v(}hX`P$!k<|=C+#r!ir%lzYO_a8<)apJQ) zi+bG2Q9j8zcRdpY*NIuF?EEaSM- zUT3yeTkgd=E3nQ&tS8%EXO_L5qR>eH#*}tv{WWM`m(uR6e+}A~r?j*Gz%mo?g~?Z(?5naV%!3$hr?8ceQDOd#)7;rK0^_6?<~LF zG!bL(WjjPX-4$K@OW3K{<$sj~>UDc$KH4vy<9rlx{61s*435P+5r=O=488^N_g2L6 zk0XxnL#+RN*PDWCGM{S0(OoBXX~XExHY{_MdgM1lrdeJ{b8x=Q;~G*l|DawzNbW#~ zE5@uVaTZ58587Sc$92kDAB|Z4_{eo!2a<7#od?YyLVpsu{txD!3sNrEZ*(~i=5}f_ znCB9SarS4$@Aj2K8(Kp`X zd$2K%BM3FD7gGJ=A6lzQU8_6`%}Zb9vlV&wAzm-9k=JIOgXR|27v=$78EF6KXZ3L& zzdr5w3}!O%yvw)p;ctalT~x#1UhPUd&)FT?U| zEk8P`&-c-1nUyPy$-eMmcD+cTUL@>#kysD$S?@7qy-2iit^oVA>qWw@7YVywBv3CB zR=vnA^WuFI>P0s$;JJREdQk!UBdcCid4FoX2<<7gB4Nj#zuG42IdQ~+ww_saqU(Rc z?Z!;RXaVG-w~G~=Z&@{%zo@eGNQ@vKMIA!ci?X;LfqGHR{j<`!el$`!Aacu(X{Rdi zFV}`-ZTD4woz#h+q9*A^OmYHw+^mC$LEhiUeYmzO>y^;skomznM^-EYdv1Oga)tVj zK>Y_yW&KB>{v%NT5vczN)PDr(KLYh1f%=b_T>qIAOKFqpKiBO?Zv2_Xw(CF3SpUFW z)_$b_3k$pc^Ln1tP52hvM?PGU$@#FQpRZ4`1;WK%=bR$aMuP!HIElE&!1qwPkUdyb`NQ>ykParXti9OHo@a zLv4}YcUIuM4)A$B&)Y@OzF+|FC*=DkmTgiGzU}0)|8ZkHk8+U1{yE~(YW(|otaE1y z?@i;pzu=Sg4z?lWeXL8!QR47J>n&X~3sRmlQl1l+KX>9fJg0%XUHdZ+gJ-_|uDXcp zuZZij`CT8^T){TS*gsp3BR)e8;5G1mli#nQHlB$b!P6V2EYw;I+>fE%g}oHm*8;iu z9)AC7ziai_?Z|&V~T8>~^Y zeOW0p;M`Ewpkt;f_ut^^42?GYLiXtsTFgYff>7teysU%1FOxB@b0U*<&Uu&Tn+1J? zPV>85j(MW@E-FTj8(6;5{VwJMJ&2*bGx|t2 z1zsc%e%FM4cVQ9l-R|!SyomSpmVDEoqa)~3ByBZ7X*@Qsm&fPz+G7?W7E9~?GLLVT z@>rNJjr;L^?uYgu;`LEGUe7XKn!N$KmMPyY50b~&F@tl=oGP?|?~=fF3i5f)=NiA; zlD_Wrxf5J>h`x29CVK4pEUxJXV&-A!QV#4=epdl~@jzd)pfA~Mn|x1OMf6Gc|M)eH z%38>ua!ppOVGh9lG`2tXi|hkKr-yFAUR>}k0yaN2bb9PO`&IUdu(3V!ydsz7%(6kg zmi;ePl#PBKUm#~!cOK>7_w}LE$K`u!__y^HF%OU9(K>HE#6Bx@eD3Y+KkT|J>&Bgy z9pK%B)n0)9Tu1u3-CndAb~$@9;a#s}UEMndJ?Ardl8@x)L#NGd$fMflwc@rb_2d2g zCB{PEI-A4g{;D573OSCnSKCKHUpKLz!aA};zdOId)@Rwq=RwI1S$AR|v5EBo{g!b) z1-<>;cDyg=eX(DPj$obUrMsMKYrmJ?u-+Mv7yIRUeA0(wECGM$<{BjSChdf61agoZ zSQgN|q#u*>OJ62=$#c%BUosDVR>}|Ke$sO`mqXBrBHNFbNk1M27u0SfmpFX)KIz9d z!OrrHH|AJ=d=Tdubjsp%?#`=mLZ4mWlg=z`oyd3s`^R~afiXXa`W4P~c~%;BpDc^l z$KSWx>%c3^){hmEDZhu@N$GfYv)v~EZe@<&n!pYFVOilk@Pb7?bgBThU1T#Xwe9;V z&zk1do=tMZ*j%rHot1IDrk6SXW{%GF80^){aRciY?6H9B`0_l&I#_=!j%PEtucL!f z-}=V&4QEc7FIWDyzFnCW(q)}<7V<@_&UwZ+jjoFgqju(|TT!Rn5OLEXuD2V*RZTc9 zrWvo{`=0O7G?v2?0{WIuQ#k+at%Lr>@eXG!_=8CL;w=7t_$C zF8`5w4LQIAi}EkEfyht&S4SC#TJtQY)UMXGJ^e4P97I6TjlzL~%t;HS(0 z`U=j&;Im{+i)%)RWpenOhP*5IoJL&Z<@cFH|=-f_qqagmgFKNUg#rPjAl zRK~T@arwWO!Ou>R|Mm&;@AUcco2+_8WX(6NZFTVMfer$2-;xXBNPTND% zSTBt4&B}_b{^kbXO!~axn=ap-uuky16JvN$6YB!&#^bCT(24G9ngYG>8vhmifiYt1 z#ZN80;5mJ6%3v;$^xLxdS)8|{k-rW8fc0m45cw#X=j3-d=7qns<^G&Jhm-nq;WfK` ztE~@w25fS^LxGOL#xLx)`&i$nByInKqmwIG=4|8LfD_F-h<7ujT}|!@d@CbmewDhd zH73p&drauTb9TL9*SJ2IS=tc38#*C%<7mhx7mcD%~^UX61ODNEG0_&pe8GCjH(HouQD zq|N8S?^fg82xQgU3E6I^?8uF<`D#nHPfW9I9{Bg2 zdV27(^JtqpI+8t7PB??s~R z)s!vg*~z}>{1jUzH8I3MS3K{)jcp+TW;nMdowNby@>S!CqmV7jlj92Hic+4ioAJ2fF5bm^%t^i^g(vF_`qf~)fmDt%R+B8>cVaD> zd&8gDEYCVR>9FJ&pn}K4ey<$MV$Givmr5B}@9tnz?>{4Du+Q8ZuOPaARt&X5bI(Ls zzQ57#)5WsHyuykrOwJ=?wmuHQzvS5Zm@oayAh;ohO=V(nIuTE8n;iF}kNkESoT@nH zmurDeSuy{6^|sF3E%$*uz|yz(hPhob?xSjO$!FU|9m&lx562}O^Q@_*G+zMcbgirp zWy6o;EUP`zZriPVUuAQZ&&zm;``gbWww2GM_P6){N9fJy{a525_hjkKZMIz4uTB}) zn=_8BP12h)Ket)^FX+vg`{meI)tfU`OtR1X6Y0%6PW|JG`C^LREVx{6e(U&}NqX~J zssI0ndUNGCm(OLyMKaDsZPkut3R2GHiE%FKGWgatdpxdr`^Ha+bzhOWj@OQL7cJEv zL!68EVWQ+w8PlHWUP*3W23^a!4#%<_-*Udg@u>C;O|^0!^JlPA8Pm#q2eD5icS5`~ zMdmoD4Ta3pmapkUZINq5-^IIQ*mcPK@0m$Gt)xu&mNdxn?)YboIq{9QjDtSqJMD>c zpMJ)!8Mrq^QKMd924+7(0yW~!=orpiBKn718ONk|eGBmz*3B^n_TuRO-LaS8qqv>p z=H0xX)5~q!2sr(*&-C7#_>4O3v+w1@=H+t^hi>>^+`rDgpN@E)Ss;HKyI`{rf+;(z#{l$Cf{S>%GbT#}|OVMII{sTpW7fm9nzx3OK89_92!#iSH9X z`}relVe*?ka|kh^M}D6TKg_y|cs?IGpNVre3v*;+eMdRx=ei^3{QM3*HHWv?e@kkc z%+s)b)^A=v>nCDFcLX{v^Lf^BC!dFYC-eD*ODE*>QpaCIE!o!ZCvlb_Uqc>G>#wBa z+>e<(F$*<6^WFWL=#^x6K41dH__j4kb zmWkZCWnyYZ8?MuF?G;m(HHut;-*YR()M>kLeH7OLF*R`jeMWGtiK!bkTxa1rAJ-p? z+?)8>pqToITjaU|xULpc-!DL)d|VfZsUPvPWwAF;0M z>o9=#o(*mFn7ib`=EjoN@PqXwGfOpnd|eN;;$d#D3%7-n<2tLBcjbPZmfGfZ>#*YF z6XWArcgEK?=?Ugkur9peo_cTFntJcO;dS-iHQ`ooQ?u6|b9HlLU42VsA=NcE)kEC~ zlQc9m)vs)A3%9hblvPA&Dd4fPK?LL#aS zua;|BUEA2)>WqPBlI>C%?8TwIq3OQ*+BWC;R$@_Op4OSI-qwb1S+ad-HqpYR3wXek zg%LUG!JPOxXU{;$LqOM{ZJ5IX=B;h1mx6b?*>hXs=jT~37dm)Y&J1XLjS#1`?jmnn z%LZO@TQm0G+Sc4+$;ws@YH4n4yeC|{*2@CI^U2@#wwsz(vR)LotZ$^HRbRh-QBy-3 zx+Sld;wBWB&@WuuCcDws>f37STUr}h+v=Oz7S-LZuUvWOS5|(dsc8j8&!f-M z#^$y=nkU?Qka+xta3gR|x`AgFHb6VBaHpkyUGsw$)>dyr(tN3|zOi143w)DG!L}(M zU?{kOKk}Z}(h*h#zQYDG;TcDOcw}4;n(80&vOP%wU}oD6oq3an2-|epQjCq~o@fvD z$jwdTMu9$TCEj(-b!yB$|$g2x>oa?pAxk-m3uaMz+ccEsVvTGn7V0;Hq6B2#MK z#`k#d?VStQHUUodQVaA<)wsl2m-xq;RSPLLn)!!aXX4UrV!UoxTkB#Lr=stk?{UY# zn9OM2=Y8(^@p(SakJp8J>F0ivK3v31Fj7*a%bf$ro%>zW8O>;H3fj_+ZVRPbToyDd zHe>Tx6FQl(W$YrF#wPH)>jsksRv`p1ECUEJHt75EXJ@%X2*E^7+9Z;^dWfBp-YFKNGwk=$;R-Q&m3<`DXN$wgW~DO~;>cAdNoT9XQDhiBu4!o&fLwPdsOG0wo>-IH)K82@EWO{Fr3jC!(OSJ_m5HU%mcx8UYL;FCf5~ z8rb)Kf}sREa{R{YoE}aMr-jqwn9B)yA^Q^7hpwC3eU#|edn`b$=<`D64*ukANVH^{0wnyuZB(kg(m+~ROab9`i#BAN zu=y(Zn0CrU(Z6;qj_E^Tg#iWk&EJ|)tN&fdd<8h%T|^g{#(E*?N51gIS>y90v>8tK(FZK!tFYd5lGNZUZKtogkFP$x`;-Z9dzNj>^5X}>{4@z9_ETVs?nJ;Kwf`JJzqzv4XAkf)rlds(u z!xWS+Y?uOvDR7tqhbeHFK!gccn34-tXx$b9i_2}u7W}Ir{EC^MSR{oTv zd{OXcg*Yht1hr4vn=g9KXyXY0XS88Ce2otjQUAskWi73f8!R<3dX|9{Y)m^!!8b5-xWH2HHqebQI6Gg0xIEanK?s7orPJVi@k4`Cp_P$()|kAImLYe3 zK{FR|)%t1wg-+uwK>@ule(>L+4$$+%BFsPm9h8LxkoX7N6)O~^28*1?Cs$8CW#ltM zK4l3X0xcZLHIZ+LFaE*WNAv>eEu_y_sh4w`c`{%8#5XH{$PJL5K%Ka>JUPjh6cCb2 zS~_)g%ii^pn7_0EyyDsrflaLSxeY=jH$v-};c5+m%VGd|zt`=SCt;k^#tk`bWOST6 zrkuR+#HHG4G|Pu+y1Ty+g->&5>3Y@jHu-H%CfnS2g$J++SU{?m}=ar+cdN}e4) z@0GZ&Sw5c}4(drtrpbScQ<}JB)DmigiKv}eyyyS;j5{s?B9;iyCZG17zxXswQ1gn= zlXf#lQQL~JIr#?9@V8ftcg_obU=$9iKArF8s<+k4MYxGAe5mFW;~KW@Z)#aF?nt}2 z+NKT`qb=>`ss+_ligs6oHn5C;8u`4@wmr>1mwa)2cb-JPU9>on)GXR3G%Y#&5jvEW zYN!<3(V)(i;+m}s-z0Y}#>)`iBls~uD!C`AHx1FDubBp{7y><|;4*u})}=PAM>|H; z{`L4WMt=P)efA%Ity;)qwJKvEBs<4eZ-R=yAa19Ja}s;|H* z3f}yE%u`QQ;#%KCu}GgEptDmTovz?#gcD+s2J#bxEE17Hw0o0Dn_9Kfjs*qOQ=nT^ zK)1+3x2S|>E<*RHjNhY#MV{c-w8vSfCo9p~PA6%pxJfEBRa~;$i^b{BK3W{_FmFpD zodS9)E{6bSzGDSF5tT^YY?kz~Y-N9Tq|beJ`bM^sy?aSyw5 zSG`b;`Q$xcjjb~3^vBT*C1^Ibpf0nYI=Y6JTGi%?Ct3%8?~?ogQZDJ%WJ#4cUibuS4V#b{c7K{GhpZM z_H~tlsQyX7@@zYgytB8PKCo)E7Te2>0n()Yq$h>%(G%%k8UYLdCT#p_feZ7uY$DYK dQe7YmQ_7E?+?Bf|+?Mpn|3eR!rT4|(;lHLg