mirror of
https://github.com/Maschell/saviine.git
synced 2024-11-13 02:25:05 +01:00
added injection feature
code still needs a lot of clean up. injection needs testing. todo: update readme
This commit is contained in:
parent
3939be8263
commit
6cdc9276aa
11
.gitignore
vendored
11
.gitignore
vendored
@ -41,3 +41,14 @@ $RECYCLE.BIN/
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
saviine/installer/bin/*
|
||||
saviine/client/build/*
|
||||
saviine/server/src/bin/logs/*
|
||||
saviine/server/src/bin/saviine_root/*
|
||||
saviine/server/src/bin/saviine_server.pdb
|
||||
saviine/server/src/bin/saviine_server.vshost.exe.manifest
|
||||
saviine/server/src/obj/x86/Debug/saviine_server.exe
|
||||
saviine/server/src/obj/x86/Debug/saviine_server.pdb
|
||||
saviine/server/src/bin/saviine_server.vshost.exe
|
||||
saviine/server/src/bin/saviine_server.exe.config
|
||||
saviine/server/src/bin/saviine_server.vshost.exe.config
|
||||
|
@ -4,10 +4,7 @@
|
||||
extern res name(__VA_ARGS__); \
|
||||
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".magicptr"))); \
|
||||
res my_ ## name(__VA_ARGS__)
|
||||
|
||||
#define BYTE_LOG_STR 0xfb
|
||||
|
||||
|
||||
#define DEBUG_LOG 0
|
||||
extern FSStatus FSOpenDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, int *dh, FSRetFlag errHandling);
|
||||
extern FSStatus FSReadDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSDirEntry *dir_entry, FSRetFlag errHandling);
|
||||
extern FSStatus FSChangeDir(FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSRetFlag errHandling);
|
||||
@ -15,17 +12,13 @@ extern FSStatus FSCloseDir(FSClient *pClient, FSCmdBlock *pCmd, int dh, FSRetFla
|
||||
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 dump_saves(void *pClient, void *pCmd,int error, int client);
|
||||
|
||||
static int strlen(char* path) {
|
||||
int i = 0;
|
||||
while (path[i++])
|
||||
;
|
||||
return i;
|
||||
}
|
||||
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) {
|
||||
if ((int)bss_ptr == 0x0a000000) {
|
||||
@ -56,6 +49,31 @@ DECL(int, FSADelClient, int client) {
|
||||
return real_FSADelClient(client);
|
||||
}
|
||||
|
||||
static int strlen(char* path) {
|
||||
int i = 0;
|
||||
while (path[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) {
|
||||
int i;
|
||||
|
||||
@ -100,8 +118,17 @@ DECL(int, FSDelClient, void *pClient) {
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
DECL(int, FSFlushQuota,FSClient *pClient,FSCmdBlock *pCmd,const char *path,FSRetFlag error) {
|
||||
return real_FSFlushQuota(pClient,pCmd,path,error);
|
||||
}
|
||||
|
||||
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);
|
||||
@ -118,35 +145,77 @@ DECL(int, FSAddClientEx, void *r3, void *r4, void *r5) {
|
||||
FSAddClient(pClient, FS_RET_NO_ERROR);
|
||||
int client = client_num_alloc(pClient);
|
||||
if(client < MAX_CLIENT && client >= 0) {
|
||||
cafiine_connect(&bss.socket_fs[client]);
|
||||
cafiine_connect(&bss.socket_fs[client]);
|
||||
bss.logsock = bss.socket_fs[client];
|
||||
}else{
|
||||
goto error;
|
||||
}
|
||||
// Init command block.
|
||||
FSInitCmdBlock(pCmd);
|
||||
|
||||
dump_saves(pClient, pCmd,-1, client);
|
||||
hook(pClient, pCmd,-1, client);
|
||||
bss.saveFolderChecked = 2;
|
||||
|
||||
|
||||
error:
|
||||
real_FSDelClient(pClient);
|
||||
|
||||
error: real_FSDelClient(pClient);
|
||||
free(pClient);
|
||||
free(pCmd);
|
||||
}
|
||||
}
|
||||
//cafiine_connect(&bss.socket_fs[client]);
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int remove_files_in_dir(void * pClient,void * pCmd, char * path, int handle){
|
||||
int ret = 0;
|
||||
if ((ret = FSOpenDir(pClient, pCmd, path, &handle, FS_RET_ALL_ERROR)) == FS_STATUS_OK){
|
||||
char buffer[strlen(path) + 25];
|
||||
|
||||
__os_snprintf(buffer, sizeof(buffer), "remove files in dir %s",path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
FSDirEntry dir_entry;
|
||||
while (FSReadDir(pClient, pCmd, handle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK)
|
||||
{
|
||||
char full_path[255];
|
||||
int i=0;
|
||||
char *path_ptr = (char *)path;
|
||||
while(*path_ptr) {
|
||||
full_path[i++] = *path_ptr++;
|
||||
}
|
||||
full_path[i++] = '/';
|
||||
char *dir_name_ptr = (char *)dir_entry.name;
|
||||
while(*dir_name_ptr) {
|
||||
full_path[i++] = *dir_name_ptr++;
|
||||
}
|
||||
full_path[i++] = '\0';
|
||||
char buffer[strlen(full_path) + 50];
|
||||
__os_snprintf(buffer, sizeof(buffer), "deleting %s",full_path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
if((ret = FSRemove(pClient,pCmd,full_path,-1)) < 0){
|
||||
__os_snprintf(buffer, sizeof(buffer), "error: %d on %s",ret,full_path);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if((FSCloseDir(pClient, pCmd, handle, FS_RET_NO_ERROR)) <=0 ){
|
||||
log_string(bss.logsock, "error while closing dir", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hook(void * pClient,void * pCmd, int error, int client){
|
||||
log_string(bss.logsock, "hook", BYTE_LOG_STR);
|
||||
handle_saves(pClient, pCmd,-1, client);
|
||||
}
|
||||
|
||||
static void init_Save(){
|
||||
int (*SAVEInit)();
|
||||
unsigned int save_handle;
|
||||
OSDynLoad_Acquire("nn_save.rpl", &save_handle);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInit", &SAVEInit);
|
||||
OSDynLoad_FindExport(save_handle, 0, "SAVEInit", (void **)&SAVEInit);
|
||||
SAVEInit();
|
||||
}
|
||||
|
||||
@ -157,10 +226,10 @@ static long getPesistentID(){
|
||||
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", &GetPersistentIdEx);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &GetSlotNo);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_Initialize);
|
||||
OSDynLoad_FindExport(nn_act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_Finalize);
|
||||
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
|
||||
|
||||
@ -183,7 +252,7 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
|
||||
char buffer[strlen(path) + 25];
|
||||
|
||||
__os_snprintf(buffer, sizeof(buffer), "open dir %s",path);
|
||||
log_string(bss.socket_fsa[client], buffer, BYTE_LOG_STR);
|
||||
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)
|
||||
{
|
||||
@ -203,14 +272,14 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
|
||||
|
||||
|
||||
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) == FS_STAT_FLAG_IS_DIRECTORY){
|
||||
log_string(bss.socket_fsa[client], "-> dir", BYTE_LOG_STR);
|
||||
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.socket_fsa[client], buffer, BYTE_LOG_STR);
|
||||
log_string(bss.logsock, buffer, BYTE_LOG_STR);
|
||||
int my_ret = cafiine_send_handle(bss.socket_fsa[client], client, full_path, my_handle);
|
||||
|
||||
|
||||
@ -220,7 +289,7 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
|
||||
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);
|
||||
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);
|
||||
@ -228,7 +297,7 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
|
||||
char type[2];
|
||||
type[0] = '9' + ret;
|
||||
type[1] = '\0';
|
||||
log_string(bss.socket_fsa[client], type, BYTE_LOG_STR);
|
||||
log_string(bss.logsock, type, BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,22 +307,145 @@ static int dump_dir(void *pClient,int client, void *pCmd, char *path, int error,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_saves(void *pClient, void *pCmd,int error, int client){
|
||||
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();
|
||||
|
||||
log_string(bss.socket_fsa[client], "dumping user savedata", BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "user savedata", BYTE_LOG_STR);
|
||||
|
||||
if(id >= 0x80000000 && id <= 0x90000000){
|
||||
char savepath[20];
|
||||
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",id);
|
||||
dump_dir(pClient,client,pCmd,savepath,-1,50);
|
||||
int mode;
|
||||
__os_snprintf(savepath, sizeof(savepath), "/vol/save/%08x",id);
|
||||
log_string(bss.logsock, "Getting mode!", BYTE_LOG_STR);
|
||||
if(getMode(bss.socket_fsa[client],&mode)){
|
||||
if(mode == BYTE_MODE_D){
|
||||
log_string(bss.logsock, "dump mode!", BYTE_LOG_STR);
|
||||
dump_dir(pClient,client,pCmd,savepath,-1,50);
|
||||
}else if(mode == BYTE_MODE_I){
|
||||
log_string(bss.logsock, "inject mode", BYTE_LOG_STR);
|
||||
log_string(bss.logsock, "deleting current save", BYTE_LOG_STR);
|
||||
remove_files_in_dir(pClient,pCmd,savepath,0);
|
||||
injectFiles(pClient,pCmd,savepath,"/",-1);
|
||||
log_string(bss.logsock, "flushing quota", BYTE_LOG_STR);
|
||||
FSFlushQuota(pClient,pCmd,savepath,-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
log_string(bss.logsock, "dumping common savedata", BYTE_LOG_STR);
|
||||
dump_dir(pClient,client,pCmd,"/vol/save/common/",error,60);
|
||||
log_string(bss.logsock, "done!", BYTE_LOG_STR);*/
|
||||
}
|
||||
|
||||
|
||||
#define BUFFER_SIZE (1024)*100
|
||||
void injectFiles(void *pClient, void *pCmd, char * path,char * relativepath, 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 type = 0;
|
||||
log_string(bss.logsock, "injecting files", BYTE_LOG_STR);
|
||||
char namebuffer[255];
|
||||
char logbugger[255];
|
||||
int filesize = 0;
|
||||
|
||||
int buf_size = BUFFER_SIZE;
|
||||
char * pBuffer;
|
||||
do{
|
||||
buf_size -= 0x200;
|
||||
if(buf_size < 0){
|
||||
log_string(bss.logsock, "error on buffer allocation", BYTE_LOG_STR);
|
||||
return;
|
||||
}
|
||||
pBuffer = (char *)MEMAllocFromDefaultHeapEx(buf_size, 0x40);
|
||||
}while(!pBuffer);
|
||||
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "buffer size: %d bytes",buf_size);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
|
||||
while(getFiles(bss.socket_fsa[client],path,namebuffer, &type,&filesize)){
|
||||
if(DEBUG_LOG)log_string(bss.logsock, "got a file", BYTE_LOG_STR);
|
||||
char newpath[strlen(path) + 1 + strlen(namebuffer)];
|
||||
__os_snprintf(newpath, sizeof(newpath), "%s/%s",path,namebuffer);
|
||||
if(type == BYTE_FILE){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "file: %s%s size: %d",relativepath,namebuffer,filesize);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "downloading it", BYTE_LOG_STR);
|
||||
|
||||
int handle = 10;
|
||||
if(FSOpenFile(pClient, pCmd, newpath,"w+",&handle,-1) >= 0){
|
||||
if(DEBUG_LOG) log_string(bss.logsock, "file opened and created", BYTE_LOG_STR);
|
||||
if(filesize > 0){
|
||||
int myhandle;
|
||||
int ret = 0;
|
||||
if((cafiine_fopen(bss.socket_fsa[client], &ret, newpath, "r", &myhandle)) == 0 && ret == 0){
|
||||
if(DEBUG_LOG)__os_snprintf(logbugger, sizeof(logbugger), "cafiine_fopen with handle %d",myhandle);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
int size = sizeof(char);
|
||||
int count = buf_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);
|
||||
}
|
||||
__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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
log_string(bss.socket_fsa[client], "dumping common savedata", BYTE_LOG_STR);
|
||||
dump_dir(pClient,client,pCmd,"/vol/save/common/",error,60);
|
||||
|
||||
log_string(bss.socket_fsa[client], "done!", BYTE_LOG_STR);
|
||||
}else{
|
||||
log_string(bss.logsock, "cafiine_fopen failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
|
||||
if((FSCloseFile (pClient, pCmd, handle, -1)) <= 0)
|
||||
log_string(bss.logsock, "FSCloseFile failed", BYTE_LOG_STR);
|
||||
}
|
||||
|
||||
}else if( type == BYTE_FOLDER){
|
||||
__os_snprintf(logbugger, sizeof(logbugger), "dir: %s",namebuffer);
|
||||
log_string(bss.logsock, logbugger, BYTE_LOG_STR);
|
||||
if(DEBUG_LOG) log_string(bss.logsock, newpath, BYTE_LOG_STR);
|
||||
if(FSMakeDir(pClient, pCmd, newpath, -1) == 0){
|
||||
char op_offset[strlen(relativepath) + strlen(namebuffer)+ 1 + 1];
|
||||
__os_snprintf(op_offset, sizeof(op_offset), "%s%s/",relativepath,namebuffer);
|
||||
injectFiles(pClient, pCmd, newpath,op_offset,error);
|
||||
}else{
|
||||
log_string(bss.logsock, "folder creation failed", BYTE_LOG_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(pBuffer);
|
||||
log_string(bss.logsock, "getting files done", BYTE_LOG_STR);
|
||||
}
|
||||
|
||||
#define MAKE_MAGIC(x) { x, my_ ## x, &real_ ## x }
|
||||
@ -270,5 +462,9 @@ struct magic_t {
|
||||
MAKE_MAGIC(FSInit),
|
||||
MAKE_MAGIC(FSShutdown),
|
||||
MAKE_MAGIC(FSAddClientEx),
|
||||
MAKE_MAGIC(FSDelClient),
|
||||
MAKE_MAGIC(FSDelClient),
|
||||
MAKE_MAGIC(FSWriteFile),
|
||||
MAKE_MAGIC(FSFlushQuota),
|
||||
|
||||
|
||||
};
|
||||
|
@ -2,6 +2,31 @@
|
||||
#include "../common/fs_defs.h"
|
||||
#define NULL ((void *)0)
|
||||
|
||||
#define BYTE_NORMAL 0xff
|
||||
#define BYTE_SPECIAL 0xfe
|
||||
#define BYTE_OPEN 0x00
|
||||
#define BYTE_READ 0x01
|
||||
#define BYTE_CLOSE 0x02
|
||||
#define BYTE_OK 0x03
|
||||
#define BYTE_SETPOS 0x04
|
||||
#define BYTE_STATFILE 0x05
|
||||
#define BYTE_EOF 0x06
|
||||
#define BYTE_GETPOS 0x07
|
||||
#define BYTE_REQUEST 0x08
|
||||
#define BYTE_REQUEST_SLOW 0x09
|
||||
#define BYTE_HANDLE 0x0A
|
||||
#define BYTE_DUMP 0x0B
|
||||
#define BYTE_PING 0x0C
|
||||
#define BYTE_G_MODE 0x0D
|
||||
#define BYTE_MODE_D 0x0E
|
||||
#define BYTE_MODE_I 0x0F
|
||||
#define BYTE_CLOSE_DUMP 0x10
|
||||
#define BYTE_LOG_STR 0xfb
|
||||
#define BYTE_FILE 0xC0
|
||||
#define BYTE_FOLDER 0xC1
|
||||
#define BYTE_GET_FILES 0xCC
|
||||
#define BYTE_END 0xfd
|
||||
|
||||
void *memcpy(void *dst, const void *src, int bytes);
|
||||
void *memset(void *dst, int val, int bytes);
|
||||
|
||||
@ -30,6 +55,8 @@ extern int connect(int socket, void *addr, int addrlen);
|
||||
extern int send(int socket, const void *buffer, int size, int flags);
|
||||
extern int recv(int socket, void *buffer, int size, int flags);
|
||||
extern int __os_snprintf(char* s, int n, const char * format, ...);
|
||||
int getFiles(int sock, char * path,char * resultname, int * resulttype,int *filesize);
|
||||
void injectFiles(void *pClient, void *pCmd, char * path,char * relativepath, int error);
|
||||
|
||||
struct in_addr {
|
||||
unsigned int s_addr;
|
||||
@ -55,6 +82,7 @@ struct bss_t {
|
||||
char save_path[255];
|
||||
volatile int saveFolderChecked;
|
||||
volatile int lock;
|
||||
int logsock;
|
||||
};
|
||||
|
||||
#define bss_ptr (*(struct bss_t **)0x100000e4)
|
||||
@ -62,11 +90,12 @@ struct bss_t {
|
||||
|
||||
void cafiine_connect(int *socket);
|
||||
void cafiine_disconnect(int socket);
|
||||
int getMode(int sock, int * result);
|
||||
int cafiine_fopen(int socket, int *result, const char *path, const char *mode, int *handle);
|
||||
int cafiine_send_handle(int sock, int client, const char *path, int handle);
|
||||
void cafiine_send_file(int sock, char *file, int size, int fd);
|
||||
int cafiine_fread(int socket, int *result, void *buffer, int size, int count, int fd);
|
||||
int cafiine_fclose(int socket, int *result, int fd);
|
||||
int cafiine_fread(int socket, int *result, void *buffer, int size, int fd);
|
||||
int cafiine_fclose(int socket, int *result, int fd, int dumpclose);
|
||||
int cafiine_fsetpos(int socket, int *result, int fd, int set);
|
||||
int cafiine_fgetpos(int socket, int *result, int fd, int *pos);
|
||||
int cafiine_fstat(int sock, int *result, int fd, void *ptr);
|
||||
|
@ -1,33 +1,22 @@
|
||||
#include "main.h"
|
||||
|
||||
static int recvwait(int sock, void *buffer, int len);
|
||||
static int recvwaitlen(int sock, void *buffer, int len);
|
||||
|
||||
static int recvbyte(int sock);
|
||||
static int sendwait(int sock, const void *buffer, int len);
|
||||
|
||||
static int sendbyte(int sock, unsigned char value);
|
||||
static int cafiine_handshake(int sock);
|
||||
|
||||
#define CHECK_ERROR(cond) if (cond) { goto error; }
|
||||
|
||||
#define BYTE_NORMAL 0xff
|
||||
#define BYTE_SPECIAL 0xfe
|
||||
//#define BYTE_OPEN 0x00
|
||||
//#define BYTE_READ 0x01
|
||||
#define BYTE_CLOSE 0x02
|
||||
//#define BYTE_OK 0x03
|
||||
//#define BYTE_SETPOS 0x04
|
||||
//#define BYTE_STATFILE 0x05
|
||||
//#define BYTE_EOF 0x06
|
||||
//#define BYTE_GETPOS 0x07
|
||||
#define BYTE_REQUEST 0x08
|
||||
#define BYTE_REQUEST_SLOW 0x09
|
||||
#define BYTE_HANDLE 0x0A
|
||||
#define BYTE_DUMP 0x0B
|
||||
#define BYTE_PING 0x0C
|
||||
|
||||
#define BYTE_LOG_STR 0xfb
|
||||
|
||||
void GX2WaitForVsync(void);
|
||||
|
||||
|
||||
|
||||
|
||||
void cafiine_connect(int *psock) {
|
||||
extern unsigned int server_ip;
|
||||
struct sockaddr_in addr;
|
||||
@ -79,6 +68,56 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getMode(int sock,int * result)
|
||||
{
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret = 0;
|
||||
|
||||
// create and send buffer with : [cmd id][fd][size][buffer data ...]
|
||||
{
|
||||
ret = sendbyte(sock, BYTE_G_MODE);
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
if(ret == BYTE_MODE_D) *result = BYTE_MODE_D;
|
||||
if(ret == BYTE_MODE_I) *result = BYTE_MODE_I;
|
||||
ret = 1;
|
||||
}
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int cafiine_fsetpos(int sock, int *result, int fd, int set) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
char buffer[1 + 8];
|
||||
buffer[0] = BYTE_SETPOS;
|
||||
*(int *)(buffer + 1) = fd;
|
||||
*(int *)(buffer + 5) = set;
|
||||
ret = sendwait(sock, buffer, 1 + 8);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
bss.lock = 0;
|
||||
return 0;
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cafiine_send_handle(int sock, int client, const char *path, int handle)
|
||||
{
|
||||
@ -122,6 +161,49 @@ error:
|
||||
bss.lock = 0;
|
||||
return -1;
|
||||
}
|
||||
int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int *handle) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int final_ret = 0;
|
||||
int ret;
|
||||
int len_path = 0;
|
||||
while (path[len_path++]);
|
||||
int len_mode = 0;
|
||||
while (mode[len_mode++]);
|
||||
|
||||
//
|
||||
{
|
||||
char buffer[1 + 8 + len_path + len_mode];
|
||||
buffer[0] = BYTE_OPEN;
|
||||
*(int *)(buffer + 1) = len_path;
|
||||
*(int *)(buffer + 5) = len_mode;
|
||||
for (ret = 0; ret < len_path; ret++)
|
||||
buffer[9 + ret] = path[ret];
|
||||
for (ret = 0; ret < len_mode; ret++)
|
||||
buffer[9 + len_path + ret] = mode[ret];
|
||||
|
||||
ret = sendwait(sock, buffer, 1 + 8 + len_path + len_mode);
|
||||
}
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwait(sock, handle, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
quit:
|
||||
bss.lock = 0;
|
||||
return final_ret;
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void cafiine_send_file(int sock, char *file, int size, int fd) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
@ -153,10 +235,36 @@ error:
|
||||
bss.lock = 0;
|
||||
return;
|
||||
}
|
||||
int cafiine_fread(int sock, int *result, void *ptr, int size, int fd) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
char buffer[1 + 8];
|
||||
buffer[0] = BYTE_READ;
|
||||
*(int *)(buffer + 1) = size;
|
||||
*(int *)(buffer + 5) = fd;
|
||||
ret = sendwait(sock, buffer, 1 + 8);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
int sz;
|
||||
ret = recvwait(sock, &sz, 4);
|
||||
|
||||
ret = recvwaitlen(sock, ptr, sz);
|
||||
*result = sz - ret;
|
||||
ret = sendbyte(sock, BYTE_OK);
|
||||
|
||||
bss.lock = 0;
|
||||
return 0;
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int cafiine_fclose(int sock, int *result, int fd) {
|
||||
int cafiine_fclose(int sock, int *result, int fd,int dumpclose) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
|
||||
@ -165,11 +273,11 @@ int cafiine_fclose(int sock, int *result, int fd) {
|
||||
int ret;
|
||||
char buffer[1 + 4];
|
||||
buffer[0] = BYTE_CLOSE;
|
||||
if(dumpclose)buffer[0] = BYTE_CLOSE_DUMP;
|
||||
*(int *)(buffer + 1) = fd;
|
||||
ret = sendwait(sock, buffer, 1 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
@ -181,6 +289,55 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getFiles(int sock, char * path,char * resultname, int * resulttype, int * filesize){
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int result = 0;
|
||||
int ret;
|
||||
// create and send buffer with : [cmd id][len_path][path][filesize]
|
||||
{
|
||||
int size = 0;
|
||||
while (path[size++]);
|
||||
char buffer[1+4+size];
|
||||
|
||||
buffer[0] = BYTE_GET_FILES;
|
||||
*(int *)(buffer + 1) = size;
|
||||
for (ret = 0; ret < size; ret++)
|
||||
buffer[5 + ret] = path[ret];
|
||||
|
||||
// send buffer, wait for reply
|
||||
ret = sendwait(sock, buffer, 1+4+size);
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret != BYTE_OK);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret != BYTE_FILE && ret != BYTE_FOLDER);
|
||||
*resulttype = ret;
|
||||
size = 0;
|
||||
ret = recvwait(sock, &size, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvwait(sock, resultname, size+1);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
size = 0;
|
||||
ret = recvwait(sock, &size, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
*filesize = size;
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
result = 1;
|
||||
|
||||
}
|
||||
error:
|
||||
bss.lock = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void cafiine_send_ping(int sock, int val1, int val2) {
|
||||
while (bss.lock) GX2WaitForVsync();
|
||||
bss.lock = 1;
|
||||
@ -211,6 +368,19 @@ static int recvwait(int sock, void *buffer, int len) {
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
static int recvwaitlen(int sock, void *buffer, int len) {
|
||||
int ret;
|
||||
while (len > 0) {
|
||||
ret = recv(sock, buffer, len, 0);
|
||||
CHECK_ERROR(ret < 0);
|
||||
len -= ret;
|
||||
buffer += ret;
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static int recvbyte(int sock) {
|
||||
unsigned char buffer[1];
|
||||
@ -260,3 +430,9 @@ void log_string(int sock, const char* str, char flag_byte) {
|
||||
|
||||
bss.lock = 0;
|
||||
}
|
||||
static int sendbyte(int sock, unsigned char byte) {
|
||||
unsigned char buffer[1];
|
||||
|
||||
buffer[0] = byte;
|
||||
return sendwait(sock, buffer, 1);
|
||||
}
|
@ -35,7 +35,7 @@ PROVIDE(FSDelClient = 0x1068a08);
|
||||
PROVIDE(FSOpenFile = 0x106ef7c);
|
||||
PROVIDE(FSOpenFileAsync = 0x0106a434);
|
||||
PROVIDE(FSInitCmdBlock = 0x01068c54);
|
||||
|
||||
PROVIDE(FSMakeDir = 0x0106f8e0);
|
||||
PROVIDE(FSCloseFile = 0x106f088);
|
||||
PROVIDE(FSReadFile = 0x106f108);
|
||||
PROVIDE(FSReadFileWithPos = 0x106f194);
|
||||
@ -43,6 +43,9 @@ PROVIDE(FSGetPosFile = 0x106f4c0);
|
||||
PROVIDE(FSSetPosFile = 0x106f530);
|
||||
PROVIDE(FSGetStatFile = 0x106f5a0);
|
||||
PROVIDE(FSIsEof = 0x106f610);
|
||||
PROVIDE(FSWriteFile = 0x106F228);
|
||||
PROVIDE(FSFlushQuota = 0x106FAC8);
|
||||
|
||||
|
||||
/* */
|
||||
PROVIDE(FSGetStat = 0x0106fdc8);
|
||||
@ -54,7 +57,7 @@ PROVIDE(FSReadDir = 0x0106f780);
|
||||
PROVIDE(FSCloseDir = 0x0106f700);
|
||||
PROVIDE(FSChangeDir = 0x0106eefc);
|
||||
PROVIDE(FSCloseDir = 0x0106f700);
|
||||
|
||||
PROVIDE(FSRemove = 0x0106F960);
|
||||
|
||||
/* GX2 methods */
|
||||
PROVIDE(GX2WaitForVsync = 0x1151964);
|
||||
@ -65,7 +68,7 @@ PROVIDE(socket = 0x10c21c8);
|
||||
PROVIDE(socketclose = 0x10c2314);
|
||||
PROVIDE(connect = 0x10c0828);
|
||||
PROVIDE(send = 0x10c16ac);
|
||||
PROVIDE(recv = 0x10c0aec);
|
||||
PROVIDE(recv = 0x10c0aec);
|
||||
|
||||
/* Standard library methods */
|
||||
PROVIDE(memcpy = 0x1035a68);
|
||||
|
Binary file not shown.
Binary file not shown.
@ -13,11 +13,11 @@ namespace saviine_server
|
||||
{
|
||||
public const byte BYTE_NORMAL = 0xff;
|
||||
public const byte BYTE_SPECIAL = 0xfe;
|
||||
//public const byte BYTE_OPEN = 0x00;
|
||||
// public const byte BYTE_READ = 0x01;
|
||||
public const byte BYTE_OPEN = 0x00;
|
||||
public const byte BYTE_READ = 0x01;
|
||||
public const byte BYTE_CLOSE = 0x02;
|
||||
//public const byte BYTE_OK = 0x03;
|
||||
//public const byte BYTE_SETPOS = 0x04;
|
||||
public const byte BYTE_OK = 0x03;
|
||||
public const byte BYTE_SETPOS = 0x04;
|
||||
//public const byte BYTE_STATFILE = 0x05;
|
||||
//public const byte BYTE_EOF = 0x06;
|
||||
//public const byte BYTE_GETPOS = 0x07;
|
||||
@ -26,8 +26,15 @@ namespace saviine_server
|
||||
public const byte BYTE_HANDLE = 0x0A;
|
||||
public const byte BYTE_DUMP = 0x0B;
|
||||
public const byte BYTE_PING = 0x0C;
|
||||
|
||||
public const byte BYTE_G_MODE = 0x0D;
|
||||
public const byte BYTE_MODE_D = 0x0E;
|
||||
public const byte BYTE_MODE_I = 0x0F;
|
||||
public const byte BYTE_CLOSE_DUMP = 0x10;
|
||||
public const byte BYTE_LOG_STR = 0xFB;
|
||||
public const byte BYTE_FILE = 0xC0;
|
||||
public const byte BYTE_FOLDER = 0xC1;
|
||||
public const byte BYTE_GET_FILES = 0xCC;
|
||||
public const byte BYTE_END = 0xfd;
|
||||
|
||||
[Flags]
|
||||
public enum FSStatFlag : uint
|
||||
@ -75,6 +82,7 @@ namespace saviine_server
|
||||
|
||||
const uint BUFFER_SIZE = 64 * 1024;
|
||||
static Boolean fastmode = false;
|
||||
static byte op_mode = BYTE_MODE_D;
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length > 1)
|
||||
@ -86,11 +94,36 @@ namespace saviine_server
|
||||
{
|
||||
if (args[0].Equals("fastmode") || args[0].Equals("fast") || args[0].Equals("-fast"))
|
||||
{
|
||||
fastmode = true;
|
||||
Console.WriteLine("Now using fastmode");
|
||||
op_mode = BYTE_MODE_D;
|
||||
fastmode = true;
|
||||
}else if(args[0].Equals("inject")) {
|
||||
op_mode = BYTE_MODE_I;
|
||||
}
|
||||
|
||||
}
|
||||
if (args.Length == 2)
|
||||
{
|
||||
if (args[0].Equals("dump")) {
|
||||
op_mode = BYTE_MODE_D;
|
||||
if (args[1].Equals("fastmode") || args[1].Equals("fast") || args[1].Equals("-fast"))
|
||||
{
|
||||
fastmode = true;
|
||||
}
|
||||
}else if(args[0].Equals("inject")) {
|
||||
op_mode = BYTE_MODE_I;
|
||||
}
|
||||
}
|
||||
|
||||
if (op_mode == BYTE_MODE_D)
|
||||
{
|
||||
Console.WriteLine("Dump mode");
|
||||
if(fastmode)Console.WriteLine("Now using fastmode");
|
||||
}
|
||||
else if(op_mode == BYTE_MODE_I)
|
||||
{
|
||||
Console.WriteLine("Injection mode!");
|
||||
}
|
||||
|
||||
// Check for cafiine_root and logs folder
|
||||
if (!Directory.Exists(root))
|
||||
{
|
||||
@ -149,6 +182,21 @@ namespace saviine_server
|
||||
log.Flush();
|
||||
Console.Write(str);
|
||||
}
|
||||
public static int countDirectory(string targetDirectory)
|
||||
{
|
||||
int x = 0;
|
||||
// Process the list of files found in the directory.
|
||||
string [] fileEntries = Directory.GetFiles(targetDirectory);
|
||||
foreach(string fileName in fileEntries)
|
||||
x++;
|
||||
|
||||
// Recurse into subdirectories of this directory.
|
||||
string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
|
||||
foreach(string subdirectory in subdirectoryEntries)
|
||||
x++;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static void Handle(object client_obj)
|
||||
{
|
||||
@ -156,6 +204,8 @@ namespace saviine_server
|
||||
FileStream[] files = new FileStream[256];
|
||||
Dictionary<int, FileStream> files_request = new Dictionary<int, FileStream>();
|
||||
StreamWriter log = null;
|
||||
Dictionary<string, Dictionary<string, byte>> dir_files = new Dictionary<string, Dictionary<string, byte>>();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
@ -196,23 +246,231 @@ namespace saviine_server
|
||||
|
||||
while (true)
|
||||
{
|
||||
byte cmd_byte = reader.ReadByte();
|
||||
//Log(log, "cmd_byte");
|
||||
byte cmd_byte = reader.ReadByte();
|
||||
switch (cmd_byte)
|
||||
{
|
||||
case BYTE_HANDLE:
|
||||
{
|
||||
case BYTE_OPEN:
|
||||
{
|
||||
//Log(log, "BYTE_OPEN");
|
||||
bool request_slow = false;
|
||||
|
||||
int len_path = reader.ReadInt32();
|
||||
int len_mode = reader.ReadInt32();
|
||||
string path = reader.ReadString(Encoding.ASCII, len_path - 1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
string mode = reader.ReadString(Encoding.ASCII, len_mode - 1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
|
||||
|
||||
if (File.Exists(LocalRoot + path))
|
||||
{
|
||||
int handle = -1;
|
||||
for (int i = 1; i < files.Length; i++)
|
||||
{
|
||||
if (files[i] == null)
|
||||
{
|
||||
handle = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (handle == -1)
|
||||
{
|
||||
Log(log, name + " Out of file handles!");
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(-19);
|
||||
writer.Write(0);
|
||||
break;
|
||||
}
|
||||
//Log(log, name + " -> fopen(\"" + path + "\", \"" + mode + "\") = " + handle.ToString());
|
||||
|
||||
files[handle] = new FileStream(LocalRoot + path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(0);
|
||||
writer.Write(handle);
|
||||
|
||||
}
|
||||
else { writer.Write(BYTE_NORMAL); }
|
||||
|
||||
// Log(log, "No request found: " + LocalRoot + path);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_SETPOS:
|
||||
{
|
||||
//Log(log, "BYTE_SETPOS");
|
||||
int fd = reader.ReadInt32();
|
||||
int pos = reader.ReadInt32();
|
||||
if ((fd & 0x0fff00ff) == 0x0fff00ff)
|
||||
{
|
||||
int handle = (fd >> 8) & 0xff;
|
||||
if (files[handle] == null)
|
||||
{
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(-38);
|
||||
break;
|
||||
}
|
||||
FileStream f = files[handle];
|
||||
Log(log, "Postion was set to " + pos + "for handle " + handle);
|
||||
f.Position = pos;
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(BYTE_NORMAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BYTE_GET_FILES:
|
||||
{
|
||||
int len_path = reader.ReadInt32();
|
||||
string path = reader.ReadString(Encoding.ASCII, len_path-1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
int x = 0;
|
||||
if (path[0] == '/' && path[1] == '/')
|
||||
{
|
||||
path = path.Substring(2);
|
||||
}
|
||||
else if (path[0] == '/')
|
||||
{
|
||||
path = path.Substring(1);
|
||||
}
|
||||
path = LocalRoot + path;
|
||||
|
||||
if(Directory.Exists(path)) {
|
||||
x = countDirectory(path);
|
||||
if (x > 0)
|
||||
{
|
||||
Dictionary<string, byte> value;
|
||||
if (!dir_files.TryGetValue(path, out value))
|
||||
{
|
||||
//Console.Write("found no \"" + path + "\" in dic \n");
|
||||
value = new Dictionary<string, byte>();
|
||||
string[] fileEntries = Directory.GetFiles(path);
|
||||
foreach (string fn in fileEntries)
|
||||
{
|
||||
string fileName = Path.GetFileName(fn);
|
||||
value.Add(fileName, BYTE_FILE);
|
||||
}
|
||||
string[] subdirectoryEntries = Directory.GetDirectories(path);
|
||||
foreach (string sd in subdirectoryEntries)
|
||||
{
|
||||
string subdirectory = Path.GetFileName(sd);
|
||||
value.Add(subdirectory, BYTE_FOLDER);
|
||||
}
|
||||
dir_files.Add(path, value);
|
||||
//Console.Write("added \"" + path + "\" to dic \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.Write("dic for \"" + path + "\" ready \n");
|
||||
}
|
||||
|
||||
if (value.Count > 0)
|
||||
{
|
||||
writer.Write(BYTE_OK);
|
||||
//Console.Write("sent ok byte \n");
|
||||
foreach (var item in value)
|
||||
{ //Write
|
||||
writer.Write(item.Value);
|
||||
//Console.Write("type : " + item.Value);
|
||||
writer.Write(item.Key.Length);
|
||||
//Console.Write("length : " + item.Key.Length);
|
||||
writer.Write(item.Key, Encoding.ASCII, true);
|
||||
//Console.Write("filename : " + item.Key);
|
||||
int length = 0;
|
||||
if (item.Value == BYTE_FILE) length = (int)new System.IO.FileInfo(path + "/" + item.Key).Length;
|
||||
writer.Write(length);
|
||||
//Console.Write("filesize : " + length + " \n");
|
||||
value.Remove(item.Key);
|
||||
//Console.Write("removed from list! " + value.Count + " remaining\n");
|
||||
break;
|
||||
}
|
||||
writer.Write(BYTE_SPECIAL); //
|
||||
//Console.Write("file sent, wrote special byte \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(BYTE_END); //
|
||||
//Console.Write("list was empty return BYTE_END \n");
|
||||
dir_files.Remove(path);
|
||||
//Console.Write("removed \"" + path + "\" from dic \n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.Write(path + "empty \n");
|
||||
writer.Write(BYTE_END); //
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.Write(path + " is not found\n");
|
||||
writer.Write(BYTE_END); //
|
||||
}
|
||||
//Console.Write("in break \n");
|
||||
break;
|
||||
}
|
||||
case BYTE_READ:
|
||||
{
|
||||
//Log(log,"BYTE_READ");
|
||||
int size = reader.ReadInt32();
|
||||
int fd = reader.ReadInt32();
|
||||
|
||||
|
||||
FileStream f = files[fd];
|
||||
|
||||
byte[] buffer = new byte[size];
|
||||
int sz = (int)f.Length;
|
||||
int rd = 0;
|
||||
|
||||
//Log(log, "want size:" + size + " for handle: " + fd);
|
||||
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
|
||||
rd = f.Read(buffer, 0, buffer.Length);
|
||||
//Log(log,"rd:" + rd);
|
||||
writer.Write(rd);
|
||||
writer.Write(buffer, 0, rd);
|
||||
|
||||
int offset = (int)f.Position;
|
||||
int progress = (int)(((float)offset / (float)sz) * 100);
|
||||
string strProgress = progress.ToString().PadLeft(3, ' ');
|
||||
string strSize = (sz / 1024).ToString();
|
||||
string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' ');
|
||||
Console.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize);
|
||||
log.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize);
|
||||
//Console.Write("send " + rd );
|
||||
if(offset == sz) Console.Write("\n");
|
||||
int ret = -5;
|
||||
if ((ret =reader.ReadByte()) != BYTE_OK)
|
||||
{
|
||||
Console.Write("error, got " + ret + " instead of " + BYTE_OK);
|
||||
//throw new InvalidDataException();
|
||||
}
|
||||
|
||||
//Log(log, "break READ");
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_HANDLE:
|
||||
{
|
||||
//Log(log,"BYTE_HANDLE");
|
||||
// Read buffer params : fd, path length, path string
|
||||
int fd = reader.ReadInt32();
|
||||
int len_path = reader.ReadInt32();
|
||||
string path = reader.ReadString(Encoding.ASCII, len_path - 1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
if (!Directory.Exists(LocalRoot + path))
|
||||
if (!Directory.Exists(LocalRoot + "dump" + path))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(LocalRoot + path));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(LocalRoot + "dump" + path));
|
||||
}
|
||||
|
||||
// Add new file for incoming data
|
||||
files_request.Add(fd, new FileStream(LocalRoot + path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write));
|
||||
files_request.Add(fd, new FileStream(LocalRoot + "dump" + path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write));
|
||||
// Send response
|
||||
if (fastmode) {
|
||||
writer.Write(BYTE_REQUEST);
|
||||
@ -227,7 +485,8 @@ namespace saviine_server
|
||||
break;
|
||||
}
|
||||
case BYTE_DUMP:
|
||||
{
|
||||
{
|
||||
//Log(log,"BYTE_DUMP");
|
||||
// Read buffer params : fd, size, file data
|
||||
int fd = reader.ReadInt32();
|
||||
int sz = reader.ReadInt32();
|
||||
@ -257,25 +516,31 @@ namespace saviine_server
|
||||
}
|
||||
case BYTE_CLOSE:
|
||||
{
|
||||
//Log(log, "BYTE_CLOSE");
|
||||
int fd = reader.ReadInt32();
|
||||
if ((fd & 0x0fff00ff) == 0x0fff00ff)
|
||||
|
||||
|
||||
if (files[fd] == null)
|
||||
{
|
||||
int handle = (fd >> 8) & 0xff;
|
||||
if (files[handle] == null)
|
||||
{
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(-38);
|
||||
break;
|
||||
}
|
||||
Log(log, name + " close(" + handle.ToString() + ")");
|
||||
FileStream f = files[handle];
|
||||
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(0);
|
||||
f.Close();
|
||||
files[handle] = null;
|
||||
writer.Write(-38);
|
||||
break;
|
||||
}
|
||||
else
|
||||
//Log(log, name + " close(" + fd.ToString() + ")");
|
||||
FileStream f = files[fd];
|
||||
|
||||
writer.Write(BYTE_SPECIAL);
|
||||
writer.Write(0);
|
||||
f.Close();
|
||||
files[fd] = null;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE_CLOSE_DUMP:
|
||||
{
|
||||
int fd = reader.ReadInt32();
|
||||
if ((fd & 0x0fff00ff) != 0x0fff00ff)
|
||||
{
|
||||
// Check if it is a file to dump
|
||||
foreach (var item in files_request)
|
||||
@ -291,7 +556,6 @@ namespace saviine_server
|
||||
// Close file and remove from request list
|
||||
dump_file.Close();
|
||||
files_request.Remove(fd);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -300,18 +564,32 @@ namespace saviine_server
|
||||
writer.Write(BYTE_NORMAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
case BYTE_PING:
|
||||
{
|
||||
//Log(log, "BYTE_PING");
|
||||
int val1 = reader.ReadInt32();
|
||||
int val2 = reader.ReadInt32();
|
||||
|
||||
Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString());
|
||||
break;
|
||||
}
|
||||
case BYTE_G_MODE:
|
||||
{
|
||||
if (op_mode == BYTE_MODE_D)
|
||||
{
|
||||
writer.Write(BYTE_MODE_D);
|
||||
}
|
||||
else if (op_mode == BYTE_MODE_I)
|
||||
{
|
||||
writer.Write(BYTE_MODE_I);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BYTE_LOG_STR:
|
||||
{
|
||||
//Log(log, "BYTE_LOG_STR");
|
||||
int len_str = reader.ReadInt32();
|
||||
string str = reader.ReadString(Encoding.ASCII, len_str - 1);
|
||||
if (reader.ReadByte() != 0) throw new InvalidDataException();
|
||||
@ -320,6 +598,7 @@ namespace saviine_server
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Log(log, "xx" + cmd_byte);
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
1
saviine/server/src/bin/dump.bat
Normal file
1
saviine/server/src/bin/dump.bat
Normal file
@ -0,0 +1 @@
|
||||
saviine_server.exe dump
|
1
saviine/server/src/bin/inject.bat
Normal file
1
saviine/server/src/bin/inject.bat
Normal file
@ -0,0 +1 @@
|
||||
saviine_server.exe inject
|
BIN
saviine/server/src/bin/saviine_server.exe
Normal file
BIN
saviine/server/src/bin/saviine_server.exe
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user