mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
*Removed easter egg (no one ever found it anyway)
*Added some useful file/directory operations from WiiXplorer and removed the old ones *Fixed crash with playcount on game start
This commit is contained in:
parent
0ddf6e9d72
commit
73ade7d0b4
@ -2,8 +2,8 @@
|
||||
<app version="1">
|
||||
<name> USB Loader GX</name>
|
||||
<coder>USB Loader GX Team</coder>
|
||||
<version>1.0 r972</version>
|
||||
<release_date>201009242132</release_date>
|
||||
<version>1.0 r973</version>
|
||||
<release_date>201009250551</release_date>
|
||||
<short_description>Loads games from USB-devices</short_description>
|
||||
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
|
||||
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.
|
||||
|
2
Makefile
2
Makefile
@ -41,6 +41,8 @@ SOURCES := source \
|
||||
source/libfat \
|
||||
source/memory \
|
||||
source/libntfs \
|
||||
source/FileOperations \
|
||||
source/utils \
|
||||
source/utils/minizip \
|
||||
source/usbloader/wbfs
|
||||
DATA := data
|
||||
|
File diff suppressed because one or more lines are too long
2
gui.pnps
2
gui.pnps
@ -1 +1 @@
|
||||
<pd><ViewState><e p="gui\source\mload" x="false"></e><e p="gui\source\settings" x="false"></e><e p="gui\source\utils" x="false"></e><e p="gui\source\images" x="false"></e><e p="gui\source\libfat" x="false"></e><e p="gui\source\prompts" x="false"></e><e p="gui\source\banner" x="false"></e><e p="gui\source\cheats" x="false"></e><e p="gui\source\libntfs" x="false"></e><e p="gui\source\network" x="true"></e><e p="gui\source\fonts" x="false"></e><e p="gui\source\menu" x="false"></e><e p="gui\source\ramdisk" x="false"></e><e p="gui\source\sounds" x="false"></e><e p="gui\source\system" x="false"></e><e p="gui\source\wad" x="false"></e><e p="gui" x="true"></e><e p="gui\source\homebrewboot" x="false"></e><e p="gui\source\language" x="false"></e><e p="gui\source" x="true"></e><e p="gui\source\libwbfs" x="false"></e><e p="gui\source\libwiigui" x="false"></e><e p="gui\source\patches" x="false"></e><e p="gui\source\themes" x="false"></e><e p="gui\source\memory" x="false"></e><e p="gui\source\usbloader" x="false"></e><e p="gui\source\xml" x="false"></e></ViewState></pd>
|
||||
<pd><ViewState><e p="gui\source\mload" x="false"></e><e p="gui\source\settings" x="false"></e><e p="gui\source\utils" x="false"></e><e p="gui\source\images" x="false"></e><e p="gui\source\libfat" x="false"></e><e p="gui\source\prompts" x="false"></e><e p="gui\source\banner" x="false"></e><e p="gui\source\cheats" x="false"></e><e p="gui\source\libntfs" x="false"></e><e p="gui\source\network" x="true"></e><e p="gui\source\fonts" x="false"></e><e p="gui\source\menu" x="false"></e><e p="gui\source\ramdisk" x="false"></e><e p="gui\source\sounds" x="false"></e><e p="gui\source\system" x="false"></e><e p="gui\source\wad" x="false"></e><e p="gui" x="true"></e><e p="gui\source\FileOperations" x="false"></e><e p="gui\source\homebrewboot" x="false"></e><e p="gui\source\language" x="false"></e><e p="gui\source" x="true"></e><e p="gui\source\libwbfs" x="false"></e><e p="gui\source\libwiigui" x="false"></e><e p="gui\source\patches" x="false"></e><e p="gui\source\themes" x="false"></e><e p="gui\source\memory" x="false"></e><e p="gui\source\usbloader" x="false"></e><e p="gui\source\xml" x="false"></e></ViewState></pd>
|
230
source/FileOperations/DirList.cpp
Normal file
230
source/FileOperations/DirList.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2010
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* DirList Class
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
#include "utils/StringTools.h"
|
||||
#include "DirList.h"
|
||||
|
||||
DirList::DirList(const char * path, const char *filter)
|
||||
{
|
||||
filecount = 0;
|
||||
FileInfo = NULL;
|
||||
|
||||
this->LoadPath(path, filter);
|
||||
this->SortList();
|
||||
}
|
||||
|
||||
DirList::~DirList()
|
||||
{
|
||||
ClearList();
|
||||
}
|
||||
|
||||
bool DirList::LoadPath(const char * folder, const char *filter)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = NULL;
|
||||
char filename[1024];
|
||||
|
||||
char folderpath[strlen(folder)+2];
|
||||
sprintf(folderpath, "%s", folder);
|
||||
|
||||
if(folderpath[strlen(folderpath)-1] == '/')
|
||||
folderpath[strlen(folderpath)-1] = '\0';
|
||||
|
||||
char * notRoot = strrchr(folderpath, '/');
|
||||
if(!notRoot)
|
||||
{
|
||||
strcat(folderpath, "/");
|
||||
}
|
||||
|
||||
dir = diropen(folderpath);
|
||||
if (dir == NULL)
|
||||
return false;
|
||||
|
||||
while (dirnext(dir,filename,&st) == 0)
|
||||
{
|
||||
if (strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
|
||||
{
|
||||
if(filter)
|
||||
{
|
||||
char * fileext = strrchr(filename, '.');
|
||||
if(fileext)
|
||||
{
|
||||
if(strtokcmp(fileext, filter, ",") == 0)
|
||||
{
|
||||
bool result = AddEntrie(folderpath, filename, st.st_size, (st.st_mode & S_IFDIR) ? true : false);
|
||||
if(!result)
|
||||
{
|
||||
dirclose(dir);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool result = AddEntrie(folderpath, filename, st.st_size, (st.st_mode & S_IFDIR) ? true : false);
|
||||
if(!result)
|
||||
{
|
||||
dirclose(dir);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DirList::AddEntrie(const char * folderpath, const char * filename, u64 filesize, bool isDir)
|
||||
{
|
||||
if(!FileInfo)
|
||||
{
|
||||
FileInfo = (FileInfos *) malloc(sizeof(FileInfos));
|
||||
if (!FileInfo)
|
||||
return false;
|
||||
}
|
||||
|
||||
FileInfos *TempFileInfo = (FileInfos *) realloc(FileInfo, (filecount+1)*sizeof(FileInfos));
|
||||
|
||||
if (!TempFileInfo)
|
||||
{
|
||||
ClearList();
|
||||
filecount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
FileInfo = TempFileInfo;
|
||||
|
||||
memset(&(FileInfo[filecount]), 0, sizeof(FileInfo));
|
||||
|
||||
FileInfo[filecount].FilePath = strdup(folderpath);
|
||||
FileInfo[filecount].FileName = strdup(filename);
|
||||
FileInfo[filecount].FileSize = filesize;
|
||||
FileInfo[filecount].isDir = isDir;
|
||||
|
||||
if (!FileInfo[filecount].FilePath || !FileInfo[filecount].FileName)
|
||||
{
|
||||
ClearList();
|
||||
filecount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
filecount++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DirList::ClearList()
|
||||
{
|
||||
for(int i = 0; i < filecount; i++)
|
||||
{
|
||||
if(FileInfo[i].FilePath)
|
||||
{
|
||||
free(FileInfo[i].FilePath);
|
||||
FileInfo[i].FilePath = NULL;
|
||||
}
|
||||
if(FileInfo[i].FileName)
|
||||
{
|
||||
free(FileInfo[i].FileName);
|
||||
FileInfo[i].FileName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (FileInfo)
|
||||
{
|
||||
free(FileInfo);
|
||||
FileInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *DirList::GetFilename(int ind)
|
||||
{
|
||||
if (ind >= filecount || ind < 0)
|
||||
return NULL;
|
||||
else
|
||||
return FileInfo[ind].FileName;
|
||||
}
|
||||
|
||||
char *DirList::GetFilepath(int ind)
|
||||
{
|
||||
if (ind >= filecount || ind < 0)
|
||||
return NULL;
|
||||
else
|
||||
return FileInfo[ind].FilePath;
|
||||
}
|
||||
|
||||
unsigned int DirList::GetFilesize(int ind)
|
||||
{
|
||||
if (ind >= filecount || !filecount || !FileInfo)
|
||||
return NULL;
|
||||
else
|
||||
return FileInfo[ind].FileSize;
|
||||
}
|
||||
|
||||
bool DirList::IsDir(int ind)
|
||||
{
|
||||
if (ind >= filecount || !filecount || !FileInfo)
|
||||
return false;
|
||||
else
|
||||
return FileInfo[ind].isDir;
|
||||
}
|
||||
|
||||
static int ListCompare(const void *a, const void *b)
|
||||
{
|
||||
FileInfos *ab = (FileInfos*) a;
|
||||
FileInfos *bb = (FileInfos*) b;
|
||||
|
||||
return stricmp((char *) ab->FileName, (char *) bb->FileName);
|
||||
}
|
||||
|
||||
void DirList::SortList()
|
||||
{
|
||||
if(!FileInfo)
|
||||
return;
|
||||
|
||||
qsort(FileInfo, filecount, sizeof(FileInfos), ListCompare);
|
||||
}
|
||||
|
||||
int DirList::GetFileIndex(const char *filename)
|
||||
{
|
||||
if(!filename || !FileInfo)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < filecount; i++)
|
||||
{
|
||||
if (strcasecmp(FileInfo[i].FileName, filename) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
58
source/FileOperations/DirList.h
Normal file
58
source/FileOperations/DirList.h
Normal file
@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
* DirList Class
|
||||
* for WiiXplorer
|
||||
***************************************************************************/
|
||||
#ifndef ___DIRLIST_H_
|
||||
#define ___DIRLIST_H_
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *FileName;
|
||||
char *FilePath;
|
||||
u64 FileSize;
|
||||
bool isDir;
|
||||
} FileInfos;
|
||||
|
||||
class DirList
|
||||
{
|
||||
public:
|
||||
//!Constructor
|
||||
//!\param path Path from where to load the filelist of all files
|
||||
//!\param filter A fileext that needs to be filtered
|
||||
DirList(const char * path, const char *filter = NULL);
|
||||
//!Destructor
|
||||
~DirList();
|
||||
//! Load all the files from a directory
|
||||
//!\param path Path where to check for homebrew files
|
||||
bool LoadPath(const char * path, const char *filter = NULL);
|
||||
//! Get a filename of the list
|
||||
//!\param list index
|
||||
char * GetFilename(int index);
|
||||
//! Get the a filepath of the list
|
||||
//!\param list index
|
||||
char * GetFilepath(int index);
|
||||
//! Get the a filesize of the list
|
||||
//!\param list index
|
||||
unsigned int GetFilesize(int index);
|
||||
//! Is index a dir or a file
|
||||
//!\param list index
|
||||
bool IsDir(int index);
|
||||
//! Get the filecount of the whole list
|
||||
int GetFilecount() { return filecount; };
|
||||
//! Sort list by filepath
|
||||
void SortList();
|
||||
//! Get the index of the specified filename
|
||||
int GetFileIndex(const char *filename);
|
||||
protected:
|
||||
//!Add a list entrie
|
||||
bool AddEntrie(const char * folderpath, const char * filename, u64 filesize, bool isDir);
|
||||
//! Clear the list
|
||||
void ClearList();
|
||||
|
||||
int filecount;
|
||||
FileInfos *FileInfo;
|
||||
};
|
||||
|
||||
#endif
|
913
source/FileOperations/fileops.cpp
Normal file
913
source/FileOperations/fileops.cpp
Normal file
@ -0,0 +1,913 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* fileops.cpp
|
||||
* File operations for the WiiXplorer
|
||||
* Handling all the needed file operations
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gccore.h>
|
||||
#include <sys/dir.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include "fileops.h"
|
||||
|
||||
#define BLOCKSIZE 70*1024 //70KB
|
||||
#define VectorResize(List) if(List.capacity()-List.size() == 0) List.reserve(List.size()+100)
|
||||
|
||||
|
||||
static bool actioncanceled = false;
|
||||
|
||||
/****************************************************************************
|
||||
* FindFile
|
||||
*
|
||||
* Check if file is available in the given directory
|
||||
***************************************************************************/
|
||||
extern "C" bool FindFile(const char * filename, const char * path)
|
||||
{
|
||||
if(!filename || ! path)
|
||||
return false;
|
||||
|
||||
DIR_ITER *dir = NULL;
|
||||
struct stat st;
|
||||
char currfilename[MAXPATHLEN];
|
||||
|
||||
dir = diropen(path);
|
||||
if(!dir)
|
||||
{
|
||||
dirclose(dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (dirnext(dir,currfilename,&st) == 0)
|
||||
{
|
||||
if (strcasecmp(currfilename, filename) == 0)
|
||||
{
|
||||
dirclose(dir);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* SearchFile
|
||||
*
|
||||
* Search for a file recursive through all subdirectories
|
||||
***************************************************************************/
|
||||
extern "C" bool SearchFile(const char * searchpath, const char * searched_filename, char * outfilepath)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = NULL;
|
||||
bool result = false;
|
||||
|
||||
char filename[MAXPATHLEN];
|
||||
char pathptr[strlen(searchpath)+2];
|
||||
snprintf(pathptr, sizeof(pathptr), "%s", searchpath);
|
||||
|
||||
if(pathptr[strlen(pathptr)-1] == '/')
|
||||
{
|
||||
pathptr[strlen(pathptr)-1] = '\0';
|
||||
}
|
||||
|
||||
char * notRoot = strrchr(pathptr, '/');
|
||||
if(!notRoot)
|
||||
{
|
||||
strcat(pathptr, "/");
|
||||
}
|
||||
|
||||
dir = diropen(pathptr);
|
||||
if(!dir)
|
||||
return false;
|
||||
|
||||
while (dirnext(dir,filename,&st) == 0 && result == false)
|
||||
{
|
||||
if(strcasecmp(filename, searched_filename) == 0)
|
||||
{
|
||||
if(outfilepath)
|
||||
{
|
||||
sprintf(outfilepath, "%s/%s", pathptr, filename);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else if((st.st_mode & S_IFDIR) != 0)
|
||||
{
|
||||
if(strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0)
|
||||
{
|
||||
char newpath[1024];
|
||||
snprintf(newpath, sizeof(newpath), "%s/%s", pathptr, filename);
|
||||
result = SearchFile(newpath, searched_filename, outfilepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* CheckFile
|
||||
*
|
||||
* Check if file is existing
|
||||
***************************************************************************/
|
||||
extern "C" bool CheckFile(const char * filepath)
|
||||
{
|
||||
if(!filepath)
|
||||
return false;
|
||||
|
||||
struct stat filestat;
|
||||
|
||||
char dirnoslash[strlen(filepath)+2];
|
||||
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
|
||||
|
||||
if(dirnoslash[strlen(dirnoslash)-1] == '/')
|
||||
dirnoslash[strlen(dirnoslash)-1] = '\0';
|
||||
|
||||
char * notRoot = strrchr(dirnoslash, '/');
|
||||
if(!notRoot)
|
||||
{
|
||||
strcat(dirnoslash, "/");
|
||||
}
|
||||
|
||||
if (stat(dirnoslash, &filestat) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* FileSize
|
||||
*
|
||||
* Get filesize in bytes. u64 for files bigger than 4GB
|
||||
***************************************************************************/
|
||||
extern "C" u64 FileSize(const char * filepath)
|
||||
{
|
||||
struct stat filestat;
|
||||
|
||||
if (stat(filepath, &filestat) != 0)
|
||||
return 0;
|
||||
|
||||
return filestat.st_size;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* LoadFileToMem
|
||||
*
|
||||
* Load up the file into a block of memory
|
||||
***************************************************************************/
|
||||
extern "C" int LoadFileToMem(const char *filepath, u8 **inbuffer, u64 *size)
|
||||
{
|
||||
int ret = -1;
|
||||
u64 filesize = FileSize(filepath);
|
||||
char * filename = strrchr(filepath, '/');
|
||||
if(filename)
|
||||
filename++;
|
||||
|
||||
*inbuffer = NULL;
|
||||
*size = 0;
|
||||
|
||||
FILE *file = fopen(filepath, "rb");
|
||||
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
|
||||
u8 *buffer = (u8 *) malloc(filesize);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return -2;
|
||||
}
|
||||
|
||||
u64 done = 0;
|
||||
u32 blocksize = BLOCKSIZE;
|
||||
|
||||
do
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
free(buffer);
|
||||
fclose(file);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(blocksize > filesize-done)
|
||||
blocksize = filesize-done;
|
||||
|
||||
ret = fread(buffer+done, 1, blocksize, file);
|
||||
if(ret < 0)
|
||||
{
|
||||
free(buffer);
|
||||
fclose(file);
|
||||
return -3;
|
||||
}
|
||||
else if(ret == 0)
|
||||
{
|
||||
//we are done
|
||||
break;
|
||||
}
|
||||
|
||||
done += ret;
|
||||
|
||||
}
|
||||
while(done < filesize);
|
||||
|
||||
fclose(file);
|
||||
|
||||
if (done != filesize)
|
||||
{
|
||||
free(buffer);
|
||||
return -3;
|
||||
}
|
||||
|
||||
*inbuffer = buffer;
|
||||
*size = filesize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* LoadFileToMemWithProgress
|
||||
*
|
||||
* Load up the file into a block of memory, while showing a progress dialog
|
||||
***************************************************************************/
|
||||
extern "C" int LoadFileToMemWithProgress(const char *progressText, const char *filepath, u8 **inbuffer, u64 *size)
|
||||
{
|
||||
|
||||
int ret = LoadFileToMem(filepath, inbuffer, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* CreateSubfolder
|
||||
*
|
||||
* Create recursive all subfolders to the given path
|
||||
***************************************************************************/
|
||||
extern "C" bool CreateSubfolder(const char * fullpath)
|
||||
{
|
||||
if(!fullpath)
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
|
||||
char dirnoslash[strlen(fullpath)+1];
|
||||
strcpy(dirnoslash, fullpath);
|
||||
|
||||
int pos = strlen(dirnoslash)-1;
|
||||
while(dirnoslash[pos] == '/')
|
||||
{
|
||||
dirnoslash[pos] = '\0';
|
||||
pos--;
|
||||
}
|
||||
|
||||
if(CheckFile(dirnoslash))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
char parentpath[strlen(dirnoslash)+2];
|
||||
strcpy(parentpath, dirnoslash);
|
||||
char * ptr = strrchr(parentpath, '/');
|
||||
|
||||
if(!ptr)
|
||||
{
|
||||
//!Device root directory (must be with '/')
|
||||
strcat(parentpath, "/");
|
||||
struct stat filestat;
|
||||
if (stat(parentpath, &filestat) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
ptr[0] = '\0';
|
||||
|
||||
result = CreateSubfolder(parentpath);
|
||||
}
|
||||
|
||||
if(!result)
|
||||
return false;
|
||||
|
||||
if (mkdir(dirnoslash, 0777) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* CompareDevices
|
||||
*
|
||||
* Compare if its the devices are equal
|
||||
***************************************************************************/
|
||||
static bool CompareDevices(const char *src, const char *dest)
|
||||
{
|
||||
if(!src || !dest)
|
||||
return false;
|
||||
|
||||
char *device1 = strchr(src, ':');
|
||||
char *device2 = strchr(dest, ':');
|
||||
|
||||
if(!device1 || !device2)
|
||||
return false;
|
||||
|
||||
int position1 = device1-src+1;
|
||||
int position2 = device2-dest+1;
|
||||
|
||||
char temp1[50];
|
||||
char temp2[50];
|
||||
|
||||
snprintf(temp1, position1, "%s", src);
|
||||
snprintf(temp2, position2, "%s", dest);
|
||||
|
||||
if(strcasecmp(temp1, temp2) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* CopyFile
|
||||
*
|
||||
* Copy the file from source filepath to destination filepath
|
||||
***************************************************************************/
|
||||
extern "C" int CopyFile(const char * src, const char * dest)
|
||||
{
|
||||
u32 read = 1;
|
||||
u32 wrote = 1;
|
||||
|
||||
char * filename = strrchr(src, '/');
|
||||
if(filename)
|
||||
filename++;
|
||||
else
|
||||
return -1;
|
||||
|
||||
u64 sizesrc = FileSize(src);
|
||||
|
||||
FILE * source = fopen(src, "rb");
|
||||
|
||||
if(!source)
|
||||
return -2;
|
||||
|
||||
u32 blksize = BLOCKSIZE;
|
||||
|
||||
u8 * buffer = (u8 *) malloc(blksize);
|
||||
|
||||
if(buffer == NULL){
|
||||
//no memory
|
||||
fclose(source);
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE * destination = fopen(dest, "wb");
|
||||
|
||||
if(destination == NULL)
|
||||
{
|
||||
free(buffer);
|
||||
fclose(source);
|
||||
return -3;
|
||||
}
|
||||
|
||||
u64 done = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
free(buffer);
|
||||
RemoveFile((char *) dest);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(blksize > sizesrc - done)
|
||||
blksize = sizesrc - done;
|
||||
|
||||
//Display progress
|
||||
read = fread(buffer, 1, blksize, source);
|
||||
if(read < 0)
|
||||
{
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
free(buffer);
|
||||
RemoveFile((char *) dest);
|
||||
return -3;
|
||||
}
|
||||
|
||||
wrote = fwrite(buffer, 1, read, destination);
|
||||
if(wrote < 0)
|
||||
{
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
free(buffer);
|
||||
RemoveFile((char *) dest);
|
||||
return -3;
|
||||
}
|
||||
|
||||
done += wrote;
|
||||
}
|
||||
while (read > 0);
|
||||
|
||||
free(buffer);
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
|
||||
if(sizesrc != done)
|
||||
return -4;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* ClearList
|
||||
*
|
||||
* Clearing a vector list
|
||||
****************************************************************************/
|
||||
static inline void ClearList(std::vector<char *> &List)
|
||||
{
|
||||
for(u32 i = 0; i < List.size(); ++i)
|
||||
{
|
||||
if(List[i])
|
||||
free(List[i]);
|
||||
List[i] = NULL;
|
||||
}
|
||||
List.clear();
|
||||
std::vector<char *>().swap(List);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* CopyDirectory
|
||||
*
|
||||
* Copy recursive a complete source path to destination path
|
||||
***************************************************************************/
|
||||
extern "C" int CopyDirectory(const char * src, const char * dest)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = NULL;
|
||||
|
||||
dir = diropen(src);
|
||||
if(dir == NULL)
|
||||
return -1;
|
||||
|
||||
char *filename = (char *) malloc(MAXPATHLEN);
|
||||
if(!filename)
|
||||
{
|
||||
dirclose(dir);
|
||||
return -2;
|
||||
}
|
||||
|
||||
std::vector<char *> DirList;
|
||||
std::vector<char *> FileList;
|
||||
|
||||
while (dirnext(dir,filename,&st) == 0)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
free(filename);
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
dirclose(dir);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(st.st_mode & S_IFDIR)
|
||||
{
|
||||
if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
|
||||
{
|
||||
VectorResize(DirList);
|
||||
DirList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorResize(FileList);
|
||||
FileList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
free(filename);
|
||||
filename = NULL;
|
||||
|
||||
//! Ensure that empty directories are created
|
||||
CreateSubfolder(dest);
|
||||
|
||||
for(u32 i = 0; i < FileList.size(); ++i)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(FileList[i])
|
||||
{
|
||||
u32 strsize = strlen(src)+strlen(FileList[i])+1;
|
||||
char currentname[strsize];
|
||||
char destname[strsize];
|
||||
sprintf(currentname, "%s%s", src, FileList[i]);
|
||||
sprintf(destname, "%s%s", dest, FileList[i]);
|
||||
free(FileList[i]);
|
||||
FileList[i] = NULL;
|
||||
CopyFile(currentname, destname);
|
||||
}
|
||||
}
|
||||
|
||||
FileList.clear();
|
||||
ClearList(FileList);
|
||||
|
||||
for(u32 i = 0; i < DirList.size(); ++i)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(DirList[i])
|
||||
{
|
||||
u32 strsize = strlen(src)+strlen(DirList[i])+2;
|
||||
char currentname[strsize];
|
||||
char destname[strsize];
|
||||
sprintf(currentname, "%s%s/", src, DirList[i]);
|
||||
sprintf(destname, "%s%s/", dest, DirList[i]);
|
||||
free(DirList[i]);
|
||||
DirList[i] = NULL;
|
||||
CopyDirectory(currentname, destname);
|
||||
}
|
||||
}
|
||||
|
||||
DirList.clear();
|
||||
ClearList(DirList);
|
||||
|
||||
if(actioncanceled)
|
||||
return -10;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MoveDirectory
|
||||
*
|
||||
* Move recursive a complete source path to destination path
|
||||
***************************************************************************/
|
||||
extern "C" int MoveDirectory(char * src, const char * dest)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = NULL;
|
||||
|
||||
dir = diropen(src);
|
||||
if(dir == NULL)
|
||||
return -1;
|
||||
|
||||
char *filename = (char *) malloc(MAXPATHLEN);
|
||||
|
||||
if(!filename)
|
||||
{
|
||||
dirclose(dir);
|
||||
return -2;
|
||||
}
|
||||
|
||||
std::vector<char *> DirList;
|
||||
std::vector<char *> FileList;
|
||||
|
||||
while (dirnext(dir,filename,&st) == 0)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
free(filename);
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
dirclose(dir);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(st.st_mode & S_IFDIR)
|
||||
{
|
||||
if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
|
||||
{
|
||||
VectorResize(DirList);
|
||||
DirList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorResize(FileList);
|
||||
FileList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
free(filename);
|
||||
filename = NULL;
|
||||
|
||||
//! Ensure that empty directories are created
|
||||
CreateSubfolder(dest);
|
||||
|
||||
for(u32 i = 0; i < FileList.size(); ++i)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(FileList[i])
|
||||
{
|
||||
u32 strsize = strlen(src)+strlen(FileList[i])+2;
|
||||
char currentname[strsize];
|
||||
char destname[strsize];
|
||||
sprintf(currentname, "%s%s", src, FileList[i]);
|
||||
sprintf(destname, "%s%s", dest, FileList[i]);
|
||||
|
||||
MoveFile(currentname, destname);
|
||||
|
||||
free(FileList[i]);
|
||||
FileList[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FileList.clear();
|
||||
ClearList(FileList);
|
||||
|
||||
for(u32 i = 0; i < DirList.size(); ++i)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(DirList[i])
|
||||
{
|
||||
u32 strsize = strlen(src)+strlen(DirList[i])+2;
|
||||
char currentname[strsize];
|
||||
char destname[strsize];
|
||||
sprintf(currentname, "%s%s/", src, DirList[i]);
|
||||
sprintf(destname, "%s%s/", dest, DirList[i]);
|
||||
free(DirList[i]);
|
||||
DirList[i] = NULL;
|
||||
|
||||
MoveDirectory(currentname, destname);
|
||||
}
|
||||
}
|
||||
|
||||
DirList.clear();
|
||||
ClearList(DirList);
|
||||
|
||||
src[strlen(src)-1] = '\0';
|
||||
|
||||
if(actioncanceled)
|
||||
return -10;
|
||||
|
||||
if(remove(src) != 0)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MoveFile
|
||||
*
|
||||
* Move a file from srcpath to destdir
|
||||
***************************************************************************/
|
||||
extern "C" int MoveFile(const char *srcpath, char *destdir)
|
||||
{
|
||||
if(CompareDevices(srcpath, destdir))
|
||||
{
|
||||
if(RenameFile(srcpath, destdir))
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res = CopyFile(srcpath, destdir);
|
||||
if(res < 0)
|
||||
return -1;
|
||||
|
||||
if(RemoveFile(srcpath))
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* RemoveDirectory
|
||||
*
|
||||
* Remove a directory and its content recursively
|
||||
***************************************************************************/
|
||||
extern "C" int RemoveDirectory(char * dirpath)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = NULL;
|
||||
|
||||
dir = diropen(dirpath);
|
||||
if(dir == NULL)
|
||||
return -1;
|
||||
|
||||
char * filename = (char *) malloc(MAXPATHLEN);
|
||||
|
||||
if(!filename)
|
||||
{
|
||||
dirclose(dir);
|
||||
return -2;
|
||||
}
|
||||
|
||||
std::vector<char *> DirList;
|
||||
std::vector<char *> FileList;
|
||||
|
||||
while (dirnext(dir,filename,&st) == 0)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
free(filename);
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
dirclose(dir);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(st.st_mode & S_IFDIR)
|
||||
{
|
||||
if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
|
||||
{
|
||||
VectorResize(DirList);
|
||||
DirList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorResize(FileList);
|
||||
FileList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
free(filename);
|
||||
filename = NULL;
|
||||
|
||||
for(u32 i = 0; i < FileList.size(); ++i)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
return -10;
|
||||
}
|
||||
|
||||
if(FileList[i])
|
||||
{
|
||||
u32 strsize = strlen(dirpath)+strlen(FileList[i])+2;
|
||||
char fullpath[strsize];
|
||||
sprintf(fullpath, "%s%s", dirpath, FileList[i]);
|
||||
RemoveFile(fullpath);
|
||||
|
||||
//!Display Throbber rotating
|
||||
free(FileList[i]);
|
||||
FileList[i] = NULL;
|
||||
}
|
||||
}
|
||||
FileList.clear();
|
||||
ClearList(FileList);
|
||||
|
||||
for(u32 i = 0; i < DirList.size(); ++i)
|
||||
{
|
||||
if(actioncanceled)
|
||||
{
|
||||
ClearList(DirList);
|
||||
ClearList(FileList);
|
||||
return -10;
|
||||
}
|
||||
if(DirList[i])
|
||||
{
|
||||
char fullpath[strlen(dirpath)+strlen(DirList[i])+2];
|
||||
sprintf(fullpath, "%s%s/", dirpath, DirList[i]);
|
||||
free(DirList[i]);
|
||||
DirList[i] = NULL;
|
||||
|
||||
RemoveDirectory(fullpath);
|
||||
}
|
||||
}
|
||||
DirList.clear();
|
||||
ClearList(DirList);
|
||||
|
||||
dirpath[strlen(dirpath)-1] = '\0';
|
||||
|
||||
if(actioncanceled)
|
||||
return -10;
|
||||
|
||||
if(remove(dirpath) != 0)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* RemoveFile
|
||||
*
|
||||
* Delete the file from a given filepath
|
||||
***************************************************************************/
|
||||
extern "C" bool RemoveFile(const char * filepath)
|
||||
{
|
||||
return (remove(filepath) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* RenameFile
|
||||
*
|
||||
* Rename the file from a given srcpath to a given destpath
|
||||
***************************************************************************/
|
||||
extern "C" bool RenameFile(const char * srcpath, const char * destpath)
|
||||
{
|
||||
return (rename(srcpath, destpath) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* GetFolderSize
|
||||
*
|
||||
* Get recursivly complete foldersize
|
||||
***************************************************************************/
|
||||
extern "C" void GetFolderSize(const char * folderpath, u64 * foldersize, u32 * filecount)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = diropen(folderpath);
|
||||
|
||||
if(dir == NULL)
|
||||
return;
|
||||
|
||||
char *filename = (char *) malloc(MAXPATHLEN);
|
||||
|
||||
if(!filename)
|
||||
{
|
||||
dirclose(dir);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<char *> DirList;
|
||||
|
||||
while (dirnext(dir,filename,&st) == 0)
|
||||
{
|
||||
if(st.st_mode & S_IFDIR)
|
||||
{
|
||||
if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
|
||||
{
|
||||
VectorResize(DirList);
|
||||
DirList.push_back(strdup(filename));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(filecount) *filecount++;
|
||||
if(foldersize) *foldersize += st.st_size;
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
free(filename);
|
||||
filename = NULL;
|
||||
|
||||
for(u32 i = 0; i < DirList.size(); ++i)
|
||||
{
|
||||
if(DirList[i])
|
||||
{
|
||||
char currentname[strlen(folderpath)+strlen(DirList[i])+2];
|
||||
sprintf(currentname, "%s%s/", folderpath, DirList[i]);
|
||||
free(DirList[i]);
|
||||
DirList[i] = NULL;
|
||||
|
||||
GetFolderSize(currentname, foldersize, filecount);
|
||||
}
|
||||
}
|
||||
DirList.clear();
|
||||
ClearList(DirList);
|
||||
}
|
57
source/FileOperations/fileops.h
Normal file
57
source/FileOperations/fileops.h
Normal file
@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* fileops.h
|
||||
* File operations for the WiiXplorer
|
||||
* Handling all the needed file operations
|
||||
***************************************************************************/
|
||||
#ifndef _FILEOPS_H_
|
||||
#define _FILEOPS_H_
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool CreateSubfolder(const char * fullpath);
|
||||
bool FindFile(const char * filename, const char * path);
|
||||
bool SearchFile(const char * searchpath, const char * searched_filename, char * outfilepath);
|
||||
bool CheckFile(const char * filepath);
|
||||
u64 FileSize(const char * filepath);
|
||||
int LoadFileToMem(const char * filepath, u8 **buffer, u64 *size);
|
||||
int LoadFileToMemWithProgress(const char *progressText, const char *filePath, u8 **buffer, u64 *size);
|
||||
int CopyFile(const char * src, const char * dest);
|
||||
int CopyDirectory(const char * src, const char * dest);
|
||||
int MoveDirectory(char * src, const char * dest);
|
||||
int MoveFile(const char *srcpath, char *destdir);
|
||||
int RemoveDirectory(char * dirpath);
|
||||
bool RenameFile(const char * srcpath, const char * destpath);
|
||||
bool RemoveFile(const char * filepath);
|
||||
void GetFolderSize(const char * folderpath, u64 * foldersize, u32 * filenumber);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -36,7 +36,7 @@
|
||||
#include <unzip/unzip.h>
|
||||
|
||||
#include "prompts/ProgressWindow.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "ZipFile.h"
|
||||
#include "language/gettext.h"
|
||||
|
||||
@ -96,7 +96,7 @@ bool ZipFile::ExtractAll(const char *dest)
|
||||
char temppath[strlen(writepath)];
|
||||
snprintf(temppath, position, "%s", writepath);
|
||||
|
||||
subfoldercreate(temppath);
|
||||
CreateSubfolder(temppath);
|
||||
|
||||
if (ret == UNZ_OK)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "banner.h"
|
||||
#include "openingbnr.h"
|
||||
#include "../ramdisk/ramdisk.h"
|
||||
#include "../listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
|
||||
u16 be16(const u8 *p)
|
||||
{
|
||||
@ -453,7 +453,7 @@ int extractbnrfile(const char * filepath, const char * destpath)
|
||||
FILE *fp = fopen(filepath, "rb");
|
||||
if (fp)
|
||||
{
|
||||
subfoldercreate(destpath);
|
||||
CreateSubfolder(destpath);
|
||||
chdir(destpath);
|
||||
|
||||
do_imet_header(fp);
|
||||
@ -470,7 +470,7 @@ int unpackBin(const char * filename, const char * outdir)
|
||||
;
|
||||
if (fp)
|
||||
{
|
||||
subfoldercreate(outdir);
|
||||
CreateSubfolder(outdir);
|
||||
chdir(outdir);
|
||||
|
||||
do_U8_archivebanner(fp);
|
||||
@ -489,7 +489,7 @@ int unpackBanner(const u8 *gameid, int what, const char *outdir)
|
||||
char path[256];
|
||||
if (!ramdiskMount("BANNER", NULL)) return -1;
|
||||
|
||||
subfoldercreate(TMP_PATH( "/" ));
|
||||
CreateSubfolder(TMP_PATH( "/" ));
|
||||
s32 ret = dump_banner(gameid, TMP_PATH( "/opening.bnr" ));
|
||||
if (ret != 1)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "language/gettext.h"
|
||||
#include "themes/CTheme.h"
|
||||
#include "fatmounter.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "menu.h"
|
||||
#include "filelist.h"
|
||||
#include "sys.h"
|
||||
@ -153,7 +153,7 @@ int CheatMenu(const char * gameID)
|
||||
}
|
||||
else
|
||||
{
|
||||
subfoldercreate(Settings.Cheatcodespath);
|
||||
CreateSubfolder(Settings.Cheatcodespath);
|
||||
string chtpath = Settings.Cheatcodespath;
|
||||
string gctfname = chtpath + c.getGameID() + ".gct";
|
||||
c.createGCT(selectednrs, x, gctfname.c_str());
|
||||
|
BIN
source/data1
BIN
source/data1
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
@ -8,7 +8,8 @@
|
||||
#include <sys/dir.h>
|
||||
|
||||
#include "UpdateLanguage.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "FileOperations/DirList.h"
|
||||
#include "menu.h"
|
||||
#include "network/networkops.h"
|
||||
#include "network/http.h"
|
||||
@ -17,24 +18,23 @@ int updateLanguageFiles()
|
||||
{
|
||||
char languageFiles[50][MAXLANGUAGEFILES];
|
||||
|
||||
//get all the files in the language path
|
||||
int countfiles = GetAllDirFiles(Settings.languagefiles_path);
|
||||
DirList Dir(Settings.languagefiles_path);
|
||||
|
||||
//give up now if we didn't find any
|
||||
if (!countfiles) return -2;
|
||||
if (Dir.GetFilecount() == 0) return -2;
|
||||
|
||||
//now from the files we got, get only the .lang files
|
||||
for (int cnt = 0; cnt < countfiles; cnt++)
|
||||
for (int cnt = 0; cnt < Dir.GetFilecount(); cnt++)
|
||||
{
|
||||
char filename[64];
|
||||
strlcpy(filename, GetFileName(cnt), sizeof(filename));
|
||||
strlcpy(filename, Dir.GetFilename(cnt), sizeof(filename));
|
||||
if (strcasestr(filename, ".lang"))
|
||||
{
|
||||
strcpy(languageFiles[cnt], filename);
|
||||
}
|
||||
}
|
||||
|
||||
subfoldercreate(Settings.languagefiles_path);
|
||||
CreateSubfolder(Settings.languagefiles_path);
|
||||
|
||||
//we assume that the network will already be init by another function
|
||||
// ( that has gui eletents in it because this one doesn't)
|
||||
@ -42,7 +42,7 @@ int updateLanguageFiles()
|
||||
if (IsNetworkInit())
|
||||
{
|
||||
//build the URL, save path, and download each file and save it
|
||||
while (j < countfiles)
|
||||
while (j < Dir.GetFilecount())
|
||||
{
|
||||
char savepath[150];
|
||||
char codeurl[200];
|
||||
|
@ -1,191 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gccore.h>
|
||||
#include <sys/dir.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "listfiles.h"
|
||||
#include "libfat/fat.h"
|
||||
|
||||
static char alldirfiles[300][70];
|
||||
char filenames[80];
|
||||
|
||||
bool findfile(const char * filename, const char * path)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *file;
|
||||
|
||||
dir = opendir(path);
|
||||
|
||||
char temp[11];
|
||||
while ((file = readdir(dir)))
|
||||
{
|
||||
snprintf(temp, sizeof(temp), "%s", file->d_name);
|
||||
if (!strncmpi(temp, filename, 11))
|
||||
{
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool subfoldercreate(const char * fullpath)
|
||||
{
|
||||
//check forsubfolders
|
||||
char dir[300];
|
||||
char * pch = NULL;
|
||||
u32 len;
|
||||
struct stat st;
|
||||
|
||||
strlcpy(dir, fullpath, sizeof(dir));
|
||||
len = strlen(dir);
|
||||
if (len && len < sizeof(dir) - 2 && dir[len - 1] != '/')
|
||||
{
|
||||
dir[len++] = '/';
|
||||
dir[len] = '\0';
|
||||
}
|
||||
if (stat(dir, &st) != 0) // fullpath not exist?
|
||||
{
|
||||
while (len && dir[len - 1] == '/')
|
||||
dir[--len] = '\0'; // remove all trailing /
|
||||
pch = strrchr(dir, '/');
|
||||
if (pch == NULL) return false;
|
||||
*pch = '\0';
|
||||
if (subfoldercreate(dir))
|
||||
{
|
||||
*pch = '/';
|
||||
if (mkdir(dir, 0777) == -1) return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool subfolderremove(const char * fullpath, const char*fp)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(fullpath, &st) != 0) // fullpath not exist?
|
||||
return false;
|
||||
if (S_ISDIR( st.st_mode ))
|
||||
{
|
||||
DIR_ITER *dir = NULL;
|
||||
char filename[256];
|
||||
bool cont = true;
|
||||
while (cont)
|
||||
{
|
||||
cont = false;
|
||||
dir = diropen(fullpath);
|
||||
if (dir)
|
||||
{
|
||||
char* bind = fullpath[strlen(fullpath) - 1] == '/' ? "" : "/";
|
||||
while (dirnext(dir, filename, &st) == 0)
|
||||
{
|
||||
if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0)
|
||||
{
|
||||
char currentname[256];
|
||||
if (S_ISDIR( st.st_mode ))
|
||||
snprintf(currentname, sizeof(currentname), "%s%s%s/", fullpath, bind, filename);
|
||||
else snprintf(currentname, sizeof(currentname), "%s%s%s", fullpath, bind, filename);
|
||||
subfolderremove(currentname, fp);
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return unlink(fullpath) == 0;
|
||||
}
|
||||
char * GetFileName(int i)
|
||||
{
|
||||
return alldirfiles[i];
|
||||
}
|
||||
|
||||
s32 filenamescmp(const void *a, const void *b)
|
||||
{
|
||||
/* Compare strings */
|
||||
return stricmp((char *) a, (char *) b);
|
||||
}
|
||||
|
||||
int GetAllDirFiles(char * filespath)
|
||||
{
|
||||
int countfiles = 0;
|
||||
|
||||
struct stat st;
|
||||
DIR_ITER* dir;
|
||||
dir = diropen(filespath);
|
||||
|
||||
if (dir == NULL) //If empty
|
||||
return 0;
|
||||
while (dirnext(dir, filenames, &st) == 0)
|
||||
{
|
||||
if ((st.st_mode & S_IFDIR) == 0)
|
||||
{
|
||||
// st.st_mode & S_IFDIR indicates a directory
|
||||
snprintf(alldirfiles[countfiles], 70, "%s", filenames);
|
||||
countfiles++;
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
qsort(alldirfiles, countfiles, sizeof(char[70]), filenamescmp);
|
||||
return countfiles;
|
||||
}
|
||||
|
||||
bool checkfile(char * path)
|
||||
{
|
||||
FILE * f;
|
||||
f = fopen(path, "r");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SearchFile(const char * searchpath, const char * searched_filename, char * outfilepath)
|
||||
{
|
||||
struct stat st;
|
||||
DIR_ITER *dir = NULL;
|
||||
bool result = false;
|
||||
|
||||
char filename[1024];
|
||||
char pathptr[strlen(searchpath) + 1];
|
||||
snprintf(pathptr, sizeof(pathptr), "%s", searchpath);
|
||||
|
||||
if (pathptr[strlen(pathptr) - 1] == '/')
|
||||
{
|
||||
pathptr[strlen(pathptr) - 1] = '\0';
|
||||
}
|
||||
|
||||
dir = diropen(pathptr);
|
||||
if (!dir) return false;
|
||||
|
||||
while (dirnext(dir, filename, &st) == 0 && result == false)
|
||||
{
|
||||
if (strcasecmp(filename, searched_filename) == 0)
|
||||
{
|
||||
if (outfilepath)
|
||||
{
|
||||
sprintf(outfilepath, "%s/%s", pathptr, filename);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else if ((st.st_mode & S_IFDIR) != 0)
|
||||
{
|
||||
if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0)
|
||||
{
|
||||
char newpath[1024];
|
||||
snprintf(newpath, sizeof(newpath), "%s/%s", pathptr, filename);
|
||||
result = SearchFile(newpath, searched_filename, outfilepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
|
||||
return result;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#ifndef _LISTFILES_H_
|
||||
#define _LISTFILES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
bool findfile(const char * filename, const char * path);
|
||||
char * GetFileName(int i);
|
||||
int GetAllDirFiles(char * filespath);
|
||||
bool subfoldercreate(const char * fullpath);
|
||||
bool checkfile(char * path);
|
||||
bool SearchFile(const char * searchpath, const char * searched_filename, char * outfilepath);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -38,7 +38,7 @@ extern "C"
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "filelist.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "main.h"
|
||||
#include "fatmounter.h"
|
||||
#include "sys.h"
|
||||
@ -93,9 +93,9 @@ int main(int argc, char *argv[])
|
||||
printf("\tSearch for configuration file\n");
|
||||
//try USB
|
||||
//left in all the dol and elf files in this check in case this is the first time running the app and they dont have the config
|
||||
if (checkfile((char*) "USB:/config/GXglobal.cfg") || (checkfile((char*) "USB:/apps/usbloader_gx/boot.elf"))
|
||||
|| checkfile((char*) "USB:/apps/usbloadergx/boot.dol") || (checkfile(
|
||||
(char*) "USB:/apps/usbloadergx/boot.elf")) || checkfile((char*) "USB:/apps/usbloader_gx/boot.dol")) strcpy(
|
||||
if (CheckFile((char*) "USB:/config/GXglobal.cfg") || (CheckFile((char*) "USB:/apps/usbloader_gx/boot.elf"))
|
||||
|| CheckFile((char*) "USB:/apps/usbloadergx/boot.dol") || (CheckFile(
|
||||
(char*) "USB:/apps/usbloadergx/boot.elf")) || CheckFile((char*) "USB:/apps/usbloader_gx/boot.dol")) strcpy(
|
||||
bootDevice, "USB:");
|
||||
|
||||
printf("\tConfiguration file is on %s\n", bootDevice);
|
||||
|
@ -56,10 +56,8 @@ int MenuDiscList()
|
||||
gameList.FilterList();
|
||||
int offset = MIN( ( int )startat, gameList.size() - 1 );
|
||||
startat = offset;
|
||||
int datag = 0;
|
||||
int datagB = 0;
|
||||
int dataed = -1;
|
||||
int cosa = 0, sina = 0;
|
||||
int selectImg1 = 0;
|
||||
char ID[4];
|
||||
char IDfull[7];
|
||||
@ -77,7 +75,7 @@ int MenuDiscList()
|
||||
int check = 0; //to skip the first cycle when wiimote isn't completely connected
|
||||
|
||||
datagB = 0;
|
||||
int menu = MENU_NONE, dataef = 0;
|
||||
int menu = MENU_NONE;
|
||||
|
||||
u32 nolist;
|
||||
char text[MAX_CHARACTERS + 4];
|
||||
@ -113,7 +111,6 @@ int MenuDiscList()
|
||||
GuiImageData btnSettings(imgPath, settings_button_png);
|
||||
snprintf(imgPath, sizeof(imgPath), "%ssettings_button_over.png", Settings.theme_path);
|
||||
GuiImageData btnSettingsOver(imgPath, settings_button_over_png);
|
||||
GuiImageData dataID(&data1);
|
||||
|
||||
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", Settings.theme_path);
|
||||
GuiImageData btnpwroff(imgPath, wiimote_poweroff_png);
|
||||
@ -286,10 +283,6 @@ int MenuDiscList()
|
||||
gameInfo.SetTrigger(&trig2);
|
||||
gameInfo.SetSoundClick(btnClick2);
|
||||
|
||||
GuiImage wiiBtnImg(&dataID);
|
||||
wiiBtnImg.SetWidescreen(Settings.widescreen);
|
||||
GuiButton wiiBtn(&wiiBtnImg, &wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, btnClick2, 0);
|
||||
|
||||
GuiTooltip favoriteBtnTT(tr( "Display favorites" ));
|
||||
if (Settings.wsprompt == yes) favoriteBtnTT.SetWidescreen(Settings.widescreen);
|
||||
favoriteBtnTT.SetAlpha(Theme.tooltipAlpha);
|
||||
@ -764,125 +757,6 @@ int MenuDiscList()
|
||||
|
||||
}
|
||||
|
||||
if ((datagB < 1) && (Settings.cios == 1) && (Settings.videomode == ntsc) && (Settings.hddinfo == hr12)
|
||||
&& (Settings.quickboot == 1) && (Settings.wsprompt == 0) && (Settings.language == ger)
|
||||
&& (Settings.tooltips == 0))
|
||||
{
|
||||
dataed = 1;
|
||||
dataef = 1;
|
||||
}
|
||||
if (dataef == 1)
|
||||
{
|
||||
if (cosa > 7)
|
||||
{
|
||||
cosa = 1;
|
||||
}
|
||||
datag++;
|
||||
if (sina == 3)
|
||||
{
|
||||
wiiBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
|
||||
wiiBtnImg.SetAngle(0);
|
||||
if (datag > 163)
|
||||
{
|
||||
datag = 1;
|
||||
}
|
||||
else if (datag < 62)
|
||||
{
|
||||
wiiBtn.SetPosition(((cosa) * 70), (-2 * (datag) + 120));
|
||||
}
|
||||
else if (62 <= datag)
|
||||
{
|
||||
wiiBtn.SetPosition(((cosa) * 70), ((datag * 2) - 130));
|
||||
}
|
||||
if (datag > 162)
|
||||
{
|
||||
wiiBtn.SetPosition(700, 700);
|
||||
w.Remove(&wiiBtn);
|
||||
datagB = 2;
|
||||
cosa++;
|
||||
sina = lastrawtime % 4;
|
||||
}
|
||||
w.Append(&wiiBtn);
|
||||
}
|
||||
if (sina == 2)
|
||||
{
|
||||
wiiBtn.SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
|
||||
wiiBtnImg.SetAngle(270);
|
||||
if (datag > 163)
|
||||
{
|
||||
datag = 1;
|
||||
}
|
||||
else if (datag < 62)
|
||||
{
|
||||
wiiBtn.SetPosition(((-2 * (datag) + 130)), ((cosa) * 50));
|
||||
}
|
||||
else if (62 <= datag)
|
||||
{
|
||||
wiiBtn.SetPosition((2 * (datag) - 120), ((cosa) * 50));
|
||||
}
|
||||
if (datag > 162)
|
||||
{
|
||||
wiiBtn.SetPosition(700, 700);
|
||||
w.Remove(&wiiBtn);
|
||||
datagB = 2;
|
||||
cosa++;
|
||||
sina = lastrawtime % 4;
|
||||
}
|
||||
w.Append(&wiiBtn);
|
||||
}
|
||||
if (sina == 1)
|
||||
{
|
||||
wiiBtn.SetAlignment(ALIGN_TOP, ALIGN_LEFT);
|
||||
wiiBtnImg.SetAngle(180);
|
||||
if (datag > 163)
|
||||
{
|
||||
datag = 1;
|
||||
}
|
||||
else if (datag < 62)
|
||||
{
|
||||
wiiBtn.SetPosition(((cosa) * 70), (2 * (datag) - 120));
|
||||
}
|
||||
else if (62 <= datag)
|
||||
{
|
||||
wiiBtn.SetPosition(((cosa) * 70), (-2 * (datag) + 130));
|
||||
}
|
||||
if (datag > 162)
|
||||
{
|
||||
wiiBtn.SetPosition(700, 700);
|
||||
w.Remove(&wiiBtn);
|
||||
datagB = 2;
|
||||
cosa++;
|
||||
sina = lastrawtime % 4;
|
||||
}
|
||||
w.Append(&wiiBtn);
|
||||
}
|
||||
if (sina == 0)
|
||||
{
|
||||
wiiBtn.SetAlignment(ALIGN_TOP, ALIGN_LEFT);
|
||||
wiiBtnImg.SetAngle(90);
|
||||
if (datag > 163)
|
||||
{
|
||||
datag = 1;
|
||||
}
|
||||
else if (datag < 62)
|
||||
{
|
||||
wiiBtn.SetPosition(((2 * (datag) - 130)), ((cosa) * 50));
|
||||
}
|
||||
else if (62 <= datag)
|
||||
{
|
||||
wiiBtn.SetPosition((-2 * (datag) + 120), ((cosa) * 50));
|
||||
}
|
||||
if (datag > 162)
|
||||
{
|
||||
wiiBtn.SetPosition(700, 700);
|
||||
w.Remove(&wiiBtn);
|
||||
datagB = 2;
|
||||
cosa++;
|
||||
sina = lastrawtime % 4;
|
||||
}
|
||||
w.Append(&wiiBtn);
|
||||
}
|
||||
}
|
||||
// respond to button presses
|
||||
if (shutdown == 1)
|
||||
{
|
||||
@ -994,25 +868,6 @@ int MenuDiscList()
|
||||
}
|
||||
|
||||
}
|
||||
else if (wiiBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
gprintf("\twiiBtn clicked\n");
|
||||
|
||||
dataed++;
|
||||
wiiBtn.ResetState();
|
||||
if (Settings.gameDisplay == list)
|
||||
{
|
||||
gameBrowser->SetFocus(1);
|
||||
}
|
||||
else if (Settings.gameDisplay == grid)
|
||||
{
|
||||
gameGrid->SetFocus(1);
|
||||
}
|
||||
else if (Settings.gameDisplay == carousel)
|
||||
{
|
||||
gameCarousel->SetFocus(1);
|
||||
}
|
||||
}
|
||||
else if (installBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
choice = WindowPrompt(tr( "Install a game" ), 0, tr( "Yes" ), tr( "No" ));
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "usbloader/apploader.h"
|
||||
#include "patchcode.h"
|
||||
#include "settings/cfg.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "fst.h"
|
||||
|
||||
//#include "sd.h"
|
||||
@ -146,7 +146,7 @@ bool dogamehooks(void *addr, u32 len)
|
||||
GameId[6] = 0;
|
||||
sprintf(filepath, "%s%s.gct", CheatFilepath, GameId);
|
||||
|
||||
if (!checkfile(filepath)) return false;
|
||||
if (!CheckFile(filepath)) return false;
|
||||
|
||||
//TODO for oggzee: when using Ocarina check if a hook as patched
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "themes/CTheme.h"
|
||||
#include "mload/mload.h"
|
||||
#include "fatmounter.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "menu.h"
|
||||
#include "menu.h"
|
||||
#include "filelist.h"
|
||||
@ -2083,15 +2083,15 @@ bool SearchMissingImages(int choice2)
|
||||
char *covers_path = choice2 == 1 ? Settings.covers2d_path : Settings.covers_path;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%c%c%c.png", header->id[0], header->id[1], header->id[2]);
|
||||
found2 = findfile(filename, covers_path);
|
||||
found2 = FindFile(filename, covers_path);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%c%c%c%c.png", header->id[0], header->id[1], header->id[2],
|
||||
header->id[3]);
|
||||
found3 = findfile(filename, covers_path);
|
||||
found3 = FindFile(filename, covers_path);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%c%c%c%c%c%c.png", header->id[0], header->id[1], header->id[2],
|
||||
header->id[3], header->id[4], header->id[5]); //full id
|
||||
found1 = findfile(filename, covers_path);
|
||||
found1 = FindFile(filename, covers_path);
|
||||
if (!found1 && !found2 && !found3) //if could not find any image
|
||||
{
|
||||
snprintf(missingFiles[cntMissFiles], 11, "%s", filename);
|
||||
@ -2101,10 +2101,10 @@ bool SearchMissingImages(int choice2)
|
||||
else if (choice2 == 3)
|
||||
{
|
||||
snprintf(filename, sizeof(filename), "%c%c%c.png", header->id[0], header->id[1], header->id[2]);
|
||||
found2 = findfile(filename, Settings.disc_path);
|
||||
found2 = FindFile(filename, Settings.disc_path);
|
||||
snprintf(filename, sizeof(filename), "%c%c%c%c%c%c.png", header->id[0], header->id[1], header->id[2],
|
||||
header->id[3], header->id[4], header->id[5]); //full id
|
||||
found1 = findfile(filename, Settings.disc_path);
|
||||
found1 = FindFile(filename, Settings.disc_path);
|
||||
if (!found1 && !found2)
|
||||
{
|
||||
snprintf(missingFiles[cntMissFiles], 11, "%s", filename);
|
||||
@ -2378,7 +2378,7 @@ int ProgressDownloadWindow(int choice2)
|
||||
struct stat st;
|
||||
if (stat(Settings.covers_path, &st) != 0)
|
||||
{
|
||||
if (subfoldercreate(Settings.covers_path) != 1)
|
||||
if (!CreateSubfolder(Settings.covers_path))
|
||||
{
|
||||
WindowPrompt(tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ));
|
||||
cntMissFiles = 0;
|
||||
@ -2386,7 +2386,7 @@ int ProgressDownloadWindow(int choice2)
|
||||
}
|
||||
if (stat(Settings.covers2d_path, &st) != 0)
|
||||
{
|
||||
if (subfoldercreate(Settings.covers2d_path) != 1)
|
||||
if (!CreateSubfolder(Settings.covers2d_path))
|
||||
{
|
||||
WindowPrompt(tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ));
|
||||
cntMissFiles = 0;
|
||||
@ -2394,7 +2394,7 @@ int ProgressDownloadWindow(int choice2)
|
||||
}
|
||||
if (stat(Settings.disc_path, &st) != 0)
|
||||
{
|
||||
if (subfoldercreate(Settings.disc_path) != 1)
|
||||
if (!CreateSubfolder(Settings.disc_path))
|
||||
{
|
||||
WindowPrompt(tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ));
|
||||
cntMissFiles = 0;
|
||||
@ -3340,7 +3340,7 @@ int ProgressUpdateWindow()
|
||||
struct stat st;
|
||||
if (stat(Settings.update_path, &st) != 0)
|
||||
{
|
||||
if (subfoldercreate(Settings.update_path) != 1)
|
||||
if (!CreateSubfolder(Settings.update_path))
|
||||
{
|
||||
WindowPrompt(tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ));
|
||||
ret = -1;
|
||||
@ -3474,7 +3474,7 @@ int ProgressUpdateWindow()
|
||||
if (!failed)
|
||||
{
|
||||
//remove old
|
||||
if (checkfile(dolpathsuccess))
|
||||
if (CheckFile(dolpathsuccess))
|
||||
{
|
||||
remove(dolpathsuccess);
|
||||
}
|
||||
@ -3509,7 +3509,7 @@ int ProgressUpdateWindow()
|
||||
file = downloadfile(XMLurl);
|
||||
if (file.data != NULL)
|
||||
{
|
||||
subfoldercreate(Settings.titlestxt_path);
|
||||
CreateSubfolder(Settings.titlestxt_path);
|
||||
snprintf(wiitdbpath, sizeof(wiitdbpath), "%swiitdb_%s.zip",
|
||||
Settings.titlestxt_path, game_partition);
|
||||
snprintf(wiitdbpathtmp, sizeof(wiitdbpathtmp), "%swiitmp_%s.zip",
|
||||
@ -3564,7 +3564,7 @@ int ProgressUpdateWindow()
|
||||
struct block file = downloadfile(XMLurl);
|
||||
if (file.data != NULL)
|
||||
{
|
||||
subfoldercreate(Settings.titlestxt_path);
|
||||
CreateSubfolder(Settings.titlestxt_path);
|
||||
snprintf(wiitdbpath, sizeof(wiitdbpath), "%swiitdb_%s.zip", Settings.titlestxt_path, game_partition);
|
||||
snprintf(wiitdbpathtmp, sizeof(wiitdbpathtmp), "%swiitmp_%s.zip", Settings.titlestxt_path,
|
||||
game_partition);
|
||||
@ -3703,7 +3703,7 @@ int CodeDownload(const char *id)
|
||||
struct stat st;
|
||||
if (stat(Settings.TxtCheatcodespath, &st) != 0)
|
||||
{
|
||||
if (subfoldercreate(Settings.TxtCheatcodespath) != 1)
|
||||
if (!CreateSubfolder(Settings.TxtCheatcodespath))
|
||||
{
|
||||
WindowPrompt(tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ));
|
||||
ret = -1;
|
||||
@ -3880,7 +3880,7 @@ int HBCWindowPrompt(const char *name, const char *coder, const char *version, co
|
||||
GuiImage *iconImg = NULL;
|
||||
snprintf(imgPath, sizeof(imgPath), "%s", iconPath);
|
||||
|
||||
bool iconExist = checkfile(imgPath);
|
||||
bool iconExist = CheckFile(imgPath);
|
||||
if (iconExist)
|
||||
{
|
||||
iconData = new GuiImageData(iconPath, dialogue_box_png);
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "network/networkops.h"
|
||||
#include "network/http.h"
|
||||
#include "filelist.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "settings/cfg.h"
|
||||
#include "themes/CTheme.h"
|
||||
#include "sys.h"
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "menu.h"
|
||||
|
||||
#include "themes/CTheme.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "language/gettext.h"
|
||||
#include "PromptWindows.h"
|
||||
#include "libwiigui/gui.h"
|
||||
@ -515,7 +515,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=
|
||||
{
|
||||
if (WindowPrompt(tr( "Directory does not exist!" ),
|
||||
tr( "The entered directory does not exist. Would you like to create it?" ),
|
||||
tr( "OK" ), tr( "Cancel" )) == 1) if (subfoldercreate(newfolder) == false) WindowPrompt(
|
||||
tr( "OK" ), tr( "Cancel" )) == 1) if (CreateSubfolder(newfolder) == false) WindowPrompt(
|
||||
tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ));
|
||||
}
|
||||
if (ParseDirectory(newfolder, Flags, Filter) == 0)
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "sys.h"
|
||||
#include "wpad.h"
|
||||
#include "fatmounter.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "prompts/PromptWindows.h"
|
||||
#include "gameinfo.h"
|
||||
#include "usbloader/GameList.h"
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "CGameSettings.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
|
||||
CGameSettings GameSettings;
|
||||
|
||||
@ -131,7 +131,7 @@ bool CGameSettings::Load(const char * path)
|
||||
{
|
||||
char line[1024];
|
||||
char filepath[300];
|
||||
snprintf(filepath, sizeof(filepath), "%s/config/GXCGameSettings.cfg", path);
|
||||
snprintf(filepath, sizeof(filepath), "%sGXGameSettings.cfg", path);
|
||||
|
||||
ConfigPath = filepath;
|
||||
|
||||
@ -159,7 +159,7 @@ bool CGameSettings::Save()
|
||||
if(ptr)
|
||||
ptr[0] = 0;
|
||||
|
||||
subfoldercreate(filepath);
|
||||
CreateSubfolder(filepath);
|
||||
|
||||
FILE * f = fopen(ConfigPath.c_str(), "w");
|
||||
if (!f) return false;
|
||||
|
@ -27,13 +27,10 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "CSettings.h"
|
||||
#include "CGameSettings.h"
|
||||
#include "language/gettext.h"
|
||||
#include "themes/CTheme.h"
|
||||
#include "listfiles.h"
|
||||
|
||||
#define DEFAULT_APP_PATH "apps/usbloader_gx/"
|
||||
#define CONFIGPATH "config/"
|
||||
#define CONFIGNAME "GXGlobal.cfg"
|
||||
#include "FileOperations/fileops.h"
|
||||
|
||||
CSettings Settings;
|
||||
|
||||
@ -149,8 +146,13 @@ bool CSettings::Load()
|
||||
//!The following needs to be moved later
|
||||
CFG_LoadGameNum();
|
||||
|
||||
snprintf(filepath, sizeof(filepath), "%sGXtheme.cfg", theme_path);
|
||||
Theme.Load(filepath);
|
||||
char GameSetPath[200];
|
||||
snprintf(GameSetPath, sizeof(GameSetPath), ConfigPath);
|
||||
char * ptr = strrchr(GameSetPath, '/');
|
||||
if(ptr) ptr[1] = 0;
|
||||
|
||||
GameSettings.Load(GameSetPath);
|
||||
Theme.Load(theme_path);
|
||||
|
||||
return true;
|
||||
|
||||
@ -179,7 +181,7 @@ bool CSettings::Save()
|
||||
tmppath[0] = '\0';
|
||||
}
|
||||
|
||||
subfoldercreate(filedest);
|
||||
if(!CreateSubfolder(filedest)) return false;
|
||||
|
||||
file = fopen(ConfigPath, "w");
|
||||
if (!file) return false;
|
||||
@ -566,10 +568,10 @@ bool CSettings::FindConfig()
|
||||
if (i == 1) strcpy(BootDevice, "USB:");
|
||||
|
||||
snprintf(ConfigPath, sizeof(ConfigPath), "%s/config/GXGlobal.cfg", BootDevice);
|
||||
if ((found = checkfile(ConfigPath))) break;
|
||||
if ((found = CheckFile(ConfigPath))) break;
|
||||
|
||||
snprintf(ConfigPath, sizeof(ConfigPath), "%s/apps/usbloader_gx/GXGlobal.cfg", BootDevice);
|
||||
if ((found = checkfile(ConfigPath))) break;
|
||||
if ((found = CheckFile(ConfigPath))) break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "menu.h"
|
||||
#include "menu/menus.h"
|
||||
#include "filelist.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "sys.h"
|
||||
#include "cfg.h"
|
||||
#include "usbloader/partition_usbloader.h"
|
||||
@ -2962,7 +2962,7 @@ int MenuGameSettings(struct discHdr * header)
|
||||
int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" ));
|
||||
if (choice1 == 1)
|
||||
{
|
||||
if (checkfile(tmp)) remove(tmp);
|
||||
if (CheckFile(tmp)) remove(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2979,7 +2979,7 @@ int MenuGameSettings(struct discHdr * header)
|
||||
int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" ));
|
||||
if (choice1 == 1)
|
||||
{
|
||||
if (checkfile(tmp)) remove(tmp);
|
||||
if (CheckFile(tmp)) remove(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2997,7 +2997,7 @@ int MenuGameSettings(struct discHdr * header)
|
||||
int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" ));
|
||||
if (choice1 == 1)
|
||||
{
|
||||
if (checkfile(tmp)) remove(tmp);
|
||||
if (CheckFile(tmp)) remove(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3015,7 +3015,7 @@ int MenuGameSettings(struct discHdr * header)
|
||||
int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" ));
|
||||
if (choice1 == 1)
|
||||
{
|
||||
if (checkfile(tmp)) remove(tmp);
|
||||
if (CheckFile(tmp)) remove(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,8 @@
|
||||
#include "settings/CSettings.h"
|
||||
#include "themes/CTheme.h"
|
||||
#include "network/URL_List.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "FileOperations/DirList.h"
|
||||
#include "main.h"
|
||||
#include "fatmounter.h"
|
||||
#include "filelist.h"
|
||||
@ -112,7 +113,7 @@ int MenuLanguageSelect()
|
||||
trigB.SetButtonOnlyTrigger( -1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B );
|
||||
|
||||
char fullpath[100];
|
||||
int countfiles = GetAllDirFiles( Settings.languagefiles_path );
|
||||
DirList Dir( Settings.languagefiles_path );
|
||||
|
||||
if ( !strcmp( "", Settings.languagefiles_path ) )
|
||||
{
|
||||
@ -194,12 +195,12 @@ int MenuLanguageSelect()
|
||||
updateBtn.SetTrigger( &trigA );
|
||||
updateBtn.SetEffectGrow();
|
||||
|
||||
customOptionList options2( countfiles );
|
||||
customOptionList options2( Dir.GetFilecount() );
|
||||
|
||||
for ( cnt = 0; cnt < countfiles; cnt++ )
|
||||
for ( cnt = 0; cnt < Dir.GetFilecount(); cnt++ )
|
||||
{
|
||||
char filename[64];
|
||||
strlcpy( filename, GetFileName( cnt ), sizeof( filename ) );
|
||||
strlcpy( filename, Dir.GetFilename( cnt ), sizeof( filename ) );
|
||||
char *dot = strchr( filename, '.' );
|
||||
if ( dot ) *dot = '\0';
|
||||
options2.SetName( cnt, "%s", filename );
|
||||
@ -288,7 +289,7 @@ int MenuLanguageSelect()
|
||||
URL_List LinkList( URL );
|
||||
int listsize = LinkList.GetURLCount();
|
||||
|
||||
subfoldercreate( Settings.languagefiles_path );
|
||||
CreateSubfolder( Settings.languagefiles_path );
|
||||
|
||||
for ( int i = 0; i < listsize; i++ )
|
||||
{
|
||||
@ -356,7 +357,7 @@ int MenuLanguageSelect()
|
||||
WindowPrompt( tr( "No SD-Card inserted!" ), tr( "Insert an SD-Card to save." ), tr( "OK" ) );
|
||||
}
|
||||
}
|
||||
if ( countfiles > 0 )
|
||||
if ( Dir.GetFilecount() > 0 )
|
||||
{
|
||||
optionBrowser4.SetFocus( 1 );
|
||||
}
|
||||
@ -372,9 +373,9 @@ int MenuLanguageSelect()
|
||||
{
|
||||
if ( isInserted( bootDevice ) )
|
||||
{
|
||||
snprintf( Settings.language_path, sizeof( Settings.language_path ), "%s%s", Settings.languagefiles_path, GetFileName( ret ) );
|
||||
snprintf( Settings.language_path, sizeof( Settings.language_path ), "%s%s", Settings.languagefiles_path, Dir.GetFilename( ret ) );
|
||||
Settings.Save();
|
||||
if ( !checkfile( Settings.language_path ) )
|
||||
if ( !CheckFile( Settings.language_path ) )
|
||||
{
|
||||
sprintf( Settings.language_path, tr( "not set" ) );
|
||||
WindowPrompt( tr( "File not found." ), tr( "Loading standard language." ), tr( "OK" ) );
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "language/gettext.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "cfg.h"
|
||||
#define isspace2(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
|
||||
|
||||
@ -365,7 +365,7 @@ void game_set_num(char *name, char *val)
|
||||
|
||||
bool cfg_load_game_num()
|
||||
{
|
||||
char GXGameFavorites_cfg[32];
|
||||
char GXGameFavorites_cfg[100];
|
||||
sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice);
|
||||
return cfg_parsefile(GXGameFavorites_cfg, &game_set_num);
|
||||
}
|
||||
@ -374,25 +374,18 @@ bool cfg_save_game_num()
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
char GXGameFavorites_cfg[32];
|
||||
char GXGameFavorites_cfg[100];
|
||||
sprintf(GXGameFavorites_cfg, "%s/config", bootDevice);
|
||||
mkdir(GXGameFavorites_cfg, 0777);
|
||||
CreateSubfolder(GXGameFavorites_cfg);
|
||||
|
||||
sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice);
|
||||
f = fopen(GXGameFavorites_cfg, "w");
|
||||
if (!f)
|
||||
{
|
||||
printf("Error saving %s\n", "GXGameFavorites.cfg");
|
||||
sleep(1);
|
||||
return false;
|
||||
}
|
||||
fprintf(f, "# USB Loader settings file\n");
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fclose(f);
|
||||
/* Closing and reopening because of a write issue we are having right now */
|
||||
f = fopen(GXGameFavorites_cfg, "w");
|
||||
fprintf(f, "# USB Loader settings file\n");
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fprintf(f, "# Num Games: %d\n", num_saved_game_num);
|
||||
for (i = 0; i < num_saved_game_num; i++)
|
||||
{
|
||||
@ -409,25 +402,15 @@ bool CFG_reset_all_playcounters()
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
char GXGameFavorites_cfg[32];
|
||||
sprintf(GXGameFavorites_cfg, "%s/config", bootDevice);
|
||||
mkdir(GXGameFavorites_cfg, 0777);
|
||||
|
||||
char GXGameFavorites_cfg[100];
|
||||
sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice);
|
||||
f = fopen(GXGameFavorites_cfg, "w");
|
||||
if (!f)
|
||||
{
|
||||
printf("Error saving %s\n", "GXGameFavorites.cfg");
|
||||
sleep(1);
|
||||
return false;
|
||||
}
|
||||
fprintf(f, "# USB Loader settings file\n");
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fclose(f);
|
||||
/* Closing and reopening because of a write issue we are having right now */
|
||||
f = fopen(GXGameFavorites_cfg, "w");
|
||||
fprintf(f, "# USB Loader settings file\n");
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fprintf(f, "# Num Games: %d\n", num_saved_game_num);
|
||||
for (i = 0; i < num_saved_game_num; i++)
|
||||
{
|
||||
|
@ -1,6 +0,0 @@
|
||||
.rodata
|
||||
|
||||
.globl data1
|
||||
.balign 32
|
||||
data1:
|
||||
.incbin "../source/data1"
|
@ -19,7 +19,7 @@
|
||||
#include "themes/CTheme.h"
|
||||
#include "menu.h"
|
||||
#include "filelist.h"
|
||||
#include "listfiles.h"
|
||||
#include "FileOperations/fileops.h"
|
||||
#include "sys.h"
|
||||
#include "network/http.h"
|
||||
#include "ZipFile.h"
|
||||
@ -56,7 +56,7 @@ int DownloadTheme(const char *url, const char *title)
|
||||
|
||||
snprintf(path, sizeof(path), "%s%s", Settings.theme_downloadpath, title);
|
||||
|
||||
subfoldercreate(path);
|
||||
CreateSubfolder(path);
|
||||
|
||||
snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
|
||||
|
||||
@ -526,7 +526,7 @@ int Theme_Downloader()
|
||||
struct block file = downloadfile(url);
|
||||
char storepath[300];
|
||||
snprintf(storepath, sizeof(storepath), "%s/tmp/", Settings.theme_downloadpath);
|
||||
subfoldercreate(storepath);
|
||||
CreateSubfolder(storepath);
|
||||
if (file.data)
|
||||
{
|
||||
storefile = fopen(filepath, "wb");
|
||||
|
128
source/utils/StringTools.c
Normal file
128
source/utils/StringTools.c
Normal file
@ -0,0 +1,128 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <gctypes.h>
|
||||
|
||||
const char * fmt(const char * format, ...)
|
||||
{
|
||||
static char strChar[512];
|
||||
memset(strChar, 0, sizeof(strChar));
|
||||
char * tmp = NULL;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
||||
{
|
||||
snprintf(strChar, sizeof(strChar), tmp);
|
||||
free(tmp);
|
||||
va_end(va);
|
||||
return (const char *) strChar;
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
if(tmp)
|
||||
free(tmp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const wchar_t * wfmt(const char * format, ...)
|
||||
{
|
||||
static wchar_t strWChar[512];
|
||||
strWChar[0] = 0;
|
||||
|
||||
if(!format)
|
||||
return (const wchar_t *) &strWChar;
|
||||
|
||||
if(strcmp(format, "") == 0)
|
||||
return (const wchar_t *) &strWChar;
|
||||
|
||||
char * tmp = NULL;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
||||
{
|
||||
int bt;
|
||||
int strlength = strlen(tmp);
|
||||
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512 );
|
||||
free(tmp);
|
||||
tmp = 0;
|
||||
|
||||
if(bt > 0)
|
||||
{
|
||||
strWChar[bt] = 0;
|
||||
return (const wchar_t *) &strWChar;
|
||||
}
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
if(tmp)
|
||||
free(tmp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool char2wchar_t(const char * strChar, wchar_t * dest)
|
||||
{
|
||||
if(!strChar || !dest)
|
||||
return false;
|
||||
|
||||
int bt;
|
||||
bt = mbstowcs(dest, strChar, strlen(strChar));
|
||||
if (bt > 0) {
|
||||
dest[bt] = (wchar_t) '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int strtokcmp(const char * string, const char * compare, const char * separator)
|
||||
{
|
||||
if(!string || !compare)
|
||||
return -1;
|
||||
|
||||
char TokCopy[512];
|
||||
strcpy(TokCopy, compare);
|
||||
|
||||
char * strTok = strtok(TokCopy, separator);
|
||||
|
||||
while (strTok != NULL)
|
||||
{
|
||||
if (strcasecmp(string, strTok) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
strTok = strtok(NULL,separator);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
43
source/utils/StringTools.h
Normal file
43
source/utils/StringTools.h
Normal file
@ -0,0 +1,43 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#ifndef __STRING_TOOLS_H
|
||||
#define __STRING_TOOLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char * fmt(const char * format, ...);
|
||||
const wchar_t * wfmt(const char * format, ...);
|
||||
bool char2wchar_t(const char * src, wchar_t * dest);
|
||||
int strtokcmp(const char * string, const char * compare, const char * separator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif /* __STRING_TOOLS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user