Convert UTF-8 to UTF-16 before passing to FS functions.

This commit is contained in:
Steven Smith 2016-04-18 19:27:08 -07:00
parent 574424e6af
commit 6702f4f267
10 changed files with 114 additions and 24 deletions

View File

@ -54,15 +54,18 @@ static void action_delete_contents_update(ui_view* view, void* data, float* prog
} else { } else {
FS_Archive* archive = deleteData->base->archive; FS_Archive* archive = deleteData->base->archive;
char* path = deleteData->contents[deleteData->processed]; char* path = deleteData->contents[deleteData->processed];
FS_Path fsPath = fsMakePath(PATH_ASCII, path);
FS_Path* fsPath = util_make_path_utf8(path);
Result res = 0; Result res = 0;
if(util_is_dir(archive, path)) { if(util_is_dir(archive, path)) {
res = FSUSER_DeleteDirectory(*archive, fsPath); res = FSUSER_DeleteDirectory(*archive, *fsPath);
} else { } else {
res = FSUSER_DeleteFile(*archive, fsPath); res = FSUSER_DeleteFile(*archive, *fsPath);
} }
util_free_path_utf8(fsPath);
if(R_SUCCEEDED(res) && archive->id == ARCHIVE_USER_SAVEDATA) { if(R_SUCCEEDED(res) && archive->id == ARCHIVE_USER_SAVEDATA) {
res = FSUSER_ControlArchive(*archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); res = FSUSER_ControlArchive(*archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
} }

View File

@ -36,12 +36,16 @@ static void action_export_secure_value_update(ui_view* view, void* data, float*
char pathBuf[64]; char pathBuf[64];
snprintf(pathBuf, 64, "/fbi/securevalue/%016llX.dat", info->titleId); snprintf(pathBuf, 64, "/fbi/securevalue/%016llX.dat", info->titleId);
FS_Path* fsPath = util_make_path_utf8(pathBuf);
Handle fileHandle = 0; Handle fileHandle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenFile(&fileHandle, sdmcArchive, fsMakePath(PATH_ASCII, pathBuf), FS_OPEN_WRITE | FS_OPEN_CREATE, 0))) { if(R_SUCCEEDED(res = FSUSER_OpenFile(&fileHandle, sdmcArchive, *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0))) {
u32 bytesWritten = 0; u32 bytesWritten = 0;
res = FSFILE_Write(fileHandle, &bytesWritten, 0, &value, sizeof(u64), FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); res = FSFILE_Write(fileHandle, &bytesWritten, 0, &value, sizeof(u64), FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
FSFILE_Close(fileHandle); FSFILE_Close(fileHandle);
} }
util_free_path_utf8(fsPath);
} }
FSUSER_CloseArchive(&sdmcArchive); FSUSER_CloseArchive(&sdmcArchive);

View File

@ -7,6 +7,7 @@
#include "../../progressbar.h" #include "../../progressbar.h"
#include "../../prompt.h" #include "../../prompt.h"
#include "../../../screen.h" #include "../../../screen.h"
#include "../../../util.h"
static void action_import_secure_value_end_onresponse(ui_view* view, void* data, bool response) { static void action_import_secure_value_end_onresponse(ui_view* view, void* data, bool response) {
prompt_destroy(view); prompt_destroy(view);
@ -20,9 +21,11 @@ static void action_import_secure_value_update(ui_view* view, void* data, float*
Result res = 0; Result res = 0;
FS_Path* fsPath = util_make_path_utf8(pathBuf);
FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (void*) ""}}; FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (void*) ""}};
Handle fileHandle = 0; Handle fileHandle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenFileDirectly(&fileHandle, sdmcArchive, fsMakePath(PATH_ASCII, pathBuf), FS_OPEN_READ, 0))) { if(R_SUCCEEDED(res = FSUSER_OpenFileDirectly(&fileHandle, sdmcArchive, *fsPath, FS_OPEN_READ, 0))) {
u32 bytesRead = 0; u32 bytesRead = 0;
u64 value = 0; u64 value = 0;
if(R_SUCCEEDED(res = FSFILE_Read(fileHandle, &bytesRead, 0, &value, sizeof(u64)))) { if(R_SUCCEEDED(res = FSFILE_Read(fileHandle, &bytesRead, 0, &value, sizeof(u64)))) {
@ -32,6 +35,8 @@ static void action_import_secure_value_update(ui_view* view, void* data, float*
FSFILE_Close(fileHandle); FSFILE_Close(fileHandle);
} }
util_free_path_utf8(fsPath);
if(R_FAILED(res)) { if(R_FAILED(res)) {
progressbar_destroy(view); progressbar_destroy(view);
ui_pop(); ui_pop();

View File

@ -36,7 +36,13 @@ Result action_install_cias_make_dst_directory(void* data, u32 index) {
Result action_install_cias_open_src(void* data, u32 index, u32* handle) { Result action_install_cias_open_src(void* data, u32 index, u32* handle) {
install_cias_data* installData = (install_cias_data*) data; install_cias_data* installData = (install_cias_data*) data;
return FSUSER_OpenFile(handle, *installData->base->archive, fsMakePath(PATH_ASCII, installData->contents[index]), FS_OPEN_READ, 0); FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
Result res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0);
util_free_path_utf8(fsPath);
return res;
} }
Result action_install_cias_close_src(void* data, u32 index, bool succeeded, u32 handle) { Result action_install_cias_close_src(void* data, u32 index, bool succeeded, u32 handle) {
@ -44,7 +50,11 @@ Result action_install_cias_close_src(void* data, u32 index, bool succeeded, u32
Result res = 0; Result res = 0;
if(R_SUCCEEDED(res = FSFILE_Close(handle)) && installData->delete && succeeded) { if(R_SUCCEEDED(res = FSFILE_Close(handle)) && installData->delete && succeeded) {
FSUSER_DeleteFile(*installData->base->archive, fsMakePath(PATH_ASCII, installData->contents[index])); FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
FSUSER_DeleteFile(*installData->base->archive, *fsPath);
util_free_path_utf8(fsPath);
} }
return res; return res;

View File

@ -32,7 +32,13 @@ Result action_install_tickets_make_dst_directory(void* data, u32 index) {
Result action_install_tickets_open_src(void* data, u32 index, u32* handle) { Result action_install_tickets_open_src(void* data, u32 index, u32* handle) {
install_tickets_data* installData = (install_tickets_data*) data; install_tickets_data* installData = (install_tickets_data*) data;
return FSUSER_OpenFile(handle, *installData->base->archive, fsMakePath(PATH_ASCII, installData->contents[index]), FS_OPEN_READ, 0); FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
Result res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0);
util_free_path_utf8(fsPath);
return res;
} }
Result action_install_tickets_close_src(void* data, u32 index, bool succeeded, u32 handle) { Result action_install_tickets_close_src(void* data, u32 index, bool succeeded, u32 handle) {

View File

@ -47,13 +47,25 @@ Result action_paste_files_make_dst_directory(void* data, u32 index) {
char dstPath[PATH_MAX]; char dstPath[PATH_MAX];
action_paste_files_get_dst_path(pasteData, index, dstPath); action_paste_files_get_dst_path(pasteData, index, dstPath);
return FSUSER_CreateDirectory(*pasteData->base->archive, fsMakePath(PATH_ASCII, dstPath), 0); FS_Path* fsPath = util_make_path_utf8(dstPath);
Result res = FSUSER_CreateDirectory(*pasteData->base->archive, *fsPath, 0);
util_free_path_utf8(fsPath);
return res;
} }
Result action_paste_files_open_src(void* data, u32 index, u32* handle) { Result action_paste_files_open_src(void* data, u32 index, u32* handle) {
paste_files_data* pasteData = (paste_files_data*) data; paste_files_data* pasteData = (paste_files_data*) data;
return FSUSER_OpenFile(handle, *pasteData->base->archive, fsMakePath(PATH_ASCII, pasteData->contents[index]), FS_OPEN_READ, 0); FS_Path* fsPath = util_make_path_utf8(pasteData->contents[index]);
Result res = FSUSER_OpenFile(handle, *pasteData->base->archive, *fsPath, FS_OPEN_READ, 0);
util_free_path_utf8(fsPath);
return res;
} }
Result action_paste_files_close_src(void* data, u32 index, bool succeeded, u32 handle) { Result action_paste_files_close_src(void* data, u32 index, bool succeeded, u32 handle) {
@ -74,7 +86,13 @@ Result action_paste_files_open_dst(void* data, u32 index, void* initialReadBlock
char dstPath[PATH_MAX]; char dstPath[PATH_MAX];
action_paste_files_get_dst_path(pasteData, index, dstPath); action_paste_files_get_dst_path(pasteData, index, dstPath);
return FSUSER_OpenFile(handle, *pasteData->base->archive, fsMakePath(PATH_ASCII, dstPath), FS_OPEN_WRITE | FS_OPEN_CREATE, 0); FS_Path* fsPath = util_make_path_utf8(dstPath);
Result res = FSUSER_OpenFile(handle, *pasteData->base->archive, *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0);
util_free_path_utf8(fsPath);
return res;
} }
Result action_paste_files_close_dst(void* data, u32 index, bool succeeded, u32 handle) { Result action_paste_files_close_dst(void* data, u32 index, bool succeeded, u32 handle) {

View File

@ -42,7 +42,7 @@ Result dumpnand_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u
Result dumpnand_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) { Result dumpnand_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (u8*) ""}}; FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (u8*) ""}};
return FSUSER_OpenFileDirectly(handle, sdmcArchive, fsMakePath(PATH_ASCII, "/NAND.bin"), FS_OPEN_WRITE | FS_OPEN_CREATE, 0); return FSUSER_OpenFileDirectly(handle, sdmcArchive, fsMakePath(PATH_UTF16, u"/NAND.bin"), FS_OPEN_WRITE | FS_OPEN_CREATE, 0);
} }
Result dumpnand_close_dst(void* data, u32 index, bool succeeded, u32 handle) { Result dumpnand_close_dst(void* data, u32 index, bool succeeded, u32 handle) {

View File

@ -30,8 +30,10 @@ static void task_populate_files_thread(void* arg) {
Result res = 0; Result res = 0;
if(data->max > *data->count) { if(data->max > *data->count) {
FS_Path* fsPath = util_make_path_utf8(data->dir->path);
Handle dirHandle = 0; Handle dirHandle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *data->dir->archive, fsMakePath(PATH_ASCII, data->dir->path)))) { if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *data->dir->archive, *fsPath))) {
u32 entryCount = 0; u32 entryCount = 0;
FS_DirectoryEntry* entries = (FS_DirectoryEntry*) calloc(data->max, sizeof(FS_DirectoryEntry)); FS_DirectoryEntry* entries = (FS_DirectoryEntry*) calloc(data->max, sizeof(FS_DirectoryEntry));
if(entries != NULL) { if(entries != NULL) {
@ -75,8 +77,10 @@ static void task_populate_files_thread(void* arg) {
fileInfo->size = 0; fileInfo->size = 0;
fileInfo->isCia = false; fileInfo->isCia = false;
FS_Path* fileFsPath = util_make_path_utf8(fileInfo->path);
Handle fileHandle; Handle fileHandle;
if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, *data->dir->archive, fsMakePath(PATH_ASCII, fileInfo->path), FS_OPEN_READ, 0))) { if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, *data->dir->archive, *fileFsPath, FS_OPEN_READ, 0))) {
FSFILE_GetSize(fileHandle, &fileInfo->size); FSFILE_GetSize(fileHandle, &fileInfo->size);
size_t len = strlen(fileInfo->path); size_t len = strlen(fileInfo->path);
@ -128,6 +132,8 @@ static void task_populate_files_thread(void* arg) {
FSFILE_Close(fileHandle); FSFILE_Close(fileHandle);
} }
util_free_path_utf8(fileFsPath);
} }
strncpy(item->name, entryName, NAME_MAX); strncpy(item->name, entryName, NAME_MAX);
@ -145,6 +151,8 @@ static void task_populate_files_thread(void* arg) {
FSDIR_Close(dirHandle); FSDIR_Close(dirHandle);
} }
util_free_path_utf8(fsPath);
} }
if(R_FAILED(res)) { if(R_FAILED(res)) {

View File

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <3ds.h> #include <3ds.h>
#include <3ds/services/fs.h>
#include "util.h" #include "util.h"
#include "ui/section/task/task.h" #include "ui/section/task/task.h"
@ -125,22 +126,27 @@ void util_panic(const char* s, ...) {
} }
bool util_is_dir(FS_Archive* archive, const char* path) { bool util_is_dir(FS_Archive* archive, const char* path) {
Handle dirHandle = 0; FS_Path* fsPath = util_make_path_utf8(path);
if(R_SUCCEEDED(FSUSER_OpenDirectory(&dirHandle, *archive, fsMakePath(PATH_ASCII, path)))) {
FSDIR_Close(dirHandle);
return true; Result res = 0;
Handle dirHandle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *archive, *fsPath))) {
FSDIR_Close(dirHandle);
} }
return false; util_free_path_utf8(fsPath);
return R_SUCCEEDED(res);
} }
static Result util_traverse_dir_internal(FS_Archive* archive, const char* path, bool recursive, bool dirsFirst, void* data, bool (*filter)(void* data, FS_Archive* archive, const char* path, u32 attributes), static Result util_traverse_dir_internal(FS_Archive* archive, const char* path, bool recursive, bool dirsFirst, void* data, bool (*filter)(void* data, FS_Archive* archive, const char* path, u32 attributes),
void (*process)(void* data, FS_Archive* archive, const char* path, u32 attributes)) { void (*process)(void* data, FS_Archive* archive, const char* path, u32 attributes)) {
Result res = 0; Result res = 0;
FS_Path* fsPath = util_make_path_utf8(path);
Handle handle = 0; Handle handle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&handle, *archive, fsMakePath(PATH_ASCII, path)))) { if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&handle, *archive, *fsPath))) {
size_t pathLen = strlen(path); size_t pathLen = strlen(path);
char* pathBuf = (char*) calloc(1, PATH_MAX); char* pathBuf = (char*) calloc(1, PATH_MAX);
strncpy(pathBuf, path, PATH_MAX); strncpy(pathBuf, path, PATH_MAX);
@ -186,6 +192,8 @@ static Result util_traverse_dir_internal(FS_Archive* archive, const char* path,
FSDIR_Close(handle); FSDIR_Close(handle);
} }
util_free_path_utf8(fsPath);
return res; return res;
} }
@ -212,8 +220,10 @@ static Result util_traverse_file(FS_Archive* archive, const char* path, bool rec
void (*process)(void* data, FS_Archive* archive, const char* path, u32 attributes)) { void (*process)(void* data, FS_Archive* archive, const char* path, u32 attributes)) {
Result res = 0; Result res = 0;
FS_Path* fsPath = util_make_path_utf8(path);
Handle handle = 0; Handle handle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenFile(&handle, *archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, 0))) { if(R_SUCCEEDED(res = FSUSER_OpenFile(&handle, *archive, *fsPath, FS_OPEN_READ, 0))) {
if(process != NULL && (filter == NULL || filter(data, archive, path, 0))) { if(process != NULL && (filter == NULL || filter(data, archive, path, 0))) {
process(data, archive, path, 0); process(data, archive, path, 0);
} }
@ -221,6 +231,8 @@ static Result util_traverse_file(FS_Archive* archive, const char* path, bool rec
FSFILE_Close(handle); FSFILE_Close(handle);
} }
util_free_path_utf8(fsPath);
return res; return res;
} }
@ -395,15 +407,36 @@ Result util_ensure_dir(FS_Archive* archive, const char* path) {
Result res = 0; Result res = 0;
if(!util_is_dir(archive, path)) { if(!util_is_dir(archive, path)) {
FS_Path fsPath = fsMakePath(PATH_ASCII, path); FS_Path* fsPath = util_make_path_utf8(path);
FSUSER_DeleteFile(*archive, fsPath); FSUSER_DeleteFile(*archive, *fsPath);
res = FSUSER_CreateDirectory(*archive, fsPath, 0); res = FSUSER_CreateDirectory(*archive, *fsPath, 0);
util_free_path_utf8(fsPath);
} }
return res; return res;
} }
FS_Path* util_make_path_utf8(const char* path) {
size_t len = strlen(path);
u16* utf16 = (u16*) calloc(len + 1, sizeof(u16));
ssize_t utf16Len = utf8_to_utf16(utf16, (const uint8_t*) path, len);
FS_Path* fsPath = (FS_Path*) calloc(1, sizeof(FS_Path));
fsPath->type = PATH_UTF16;
fsPath->size = (utf16Len + 1) * sizeof(u16);
fsPath->data = utf16;
return fsPath;
}
void util_free_path_utf8(FS_Path* path) {
free((void*) path->data);
free(path);
}
int util_compare_u32(const void* e1, const void* e2) { int util_compare_u32(const void* e1, const void* e2) {
u32 id1 = *(u32*) e1; u32 id1 = *(u32*) e1;
u32 id2 = *(u32*) e2; u32 id2 = *(u32*) e2;

View File

@ -57,6 +57,9 @@ void util_get_path_file(char* out, const char* path, u32 size);
void util_get_parent_path(char* out, const char* path, u32 size); void util_get_parent_path(char* out, const char* path, u32 size);
Result util_ensure_dir(FS_Archive* archive, const char* path); Result util_ensure_dir(FS_Archive* archive, const char* path);
FS_Path* util_make_path_utf8(const char* path);
void util_free_path_utf8(FS_Path* path);
int util_compare_u32(const void* e1, const void* e2); int util_compare_u32(const void* e1, const void* e2);
int util_compare_u64(const void* e1, const void* e2); int util_compare_u64(const void* e1, const void* e2);
int util_compare_directory_entries(const void* e1, const void* e2); int util_compare_directory_entries(const void* e1, const void* e2);