mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@270 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
parent
8f878dc3ee
commit
9cbc2e2846
@ -242,40 +242,16 @@ void LogAdd_InfoParam(tArcInfo *p)
|
||||
#endif
|
||||
|
||||
char sts[64];
|
||||
//エラー表示
|
||||
void PutError(ErcDev dev,int cd)
|
||||
{
|
||||
int desc,code;
|
||||
nn::Result res;
|
||||
switch (dev)
|
||||
{
|
||||
case ERC_DEV_CARD: res = savedata.LastNnResult;break;
|
||||
case ERC_DEV_OUT: res = exsave.LastNnResult;break;
|
||||
}
|
||||
if(dev != ERC_DEV_OTHER)LogAdd_Res(res);
|
||||
if(isDebugMode==false)
|
||||
{
|
||||
if ((cd ==0 ) && (dev != ERC_DEV_OTHER))
|
||||
{
|
||||
desc = res.GetDescription();
|
||||
if (desc < 100 ) code = ERC_UNKNOWN;//キー検索完了 .. ありえない
|
||||
else if (desc < 180 ) code = ERC_READ;//ファイルが見つからないか不正
|
||||
else if (desc < 200 ) code = ERC_WRITE_OW;//ファイルが存在 .. 削除失敗?
|
||||
else if (desc < 220 ) code = ERC_WRITE_NS;//空きが無い
|
||||
else if (desc < 260 ) code = ERC_ACCESS;//操作拒否
|
||||
else if (desc < 280 ) code = ERC_WRITE_PROTECT;//書き込み禁止
|
||||
else if (desc < 340 ) code = ERC_ACCESS;//アクセスエラー
|
||||
else if (desc < 390 ) code = ERC_FORMAT;//フォーマットエラー
|
||||
else if (desc < 400 ) code = ERC_SDK_VERIFI;//改竄
|
||||
else if (desc < 580 ) code = ERC_ROM;//ROM情報エラー
|
||||
else if (desc < 590 ) code = ERC_RETRY;//リトライ要求
|
||||
else if (desc < 600 ) code = ERC_UNKNOWN;//CCI,CXI不正 .. ありえない
|
||||
else if (desc < 900 ) code = ERC_EXEC;//実行時エラー、ソフトバグ
|
||||
else code = ERC_FATAL;//本体に問題の可能性
|
||||
}else code = cd;
|
||||
sprintf(sts,"ERROR %d",dev+code);
|
||||
scr_Status(sts,COLOR_RED);
|
||||
}
|
||||
GetErrorStr(dev,res,cd,sts);
|
||||
scr_Status(sts,COLOR_RED);
|
||||
}
|
||||
|
||||
|
||||
@ -822,7 +798,7 @@ RetCode Sd2Card()
|
||||
#endif
|
||||
int rev = 0;
|
||||
while(1){
|
||||
if (savedata.OpenW(file_pathw,fsize,&mkdir)==false)
|
||||
if (savedata.OpenC(file_pathw,fsize,&mkdir)==false)
|
||||
{
|
||||
if(mkdir)//ディレクトリのみ作成
|
||||
{//深い場合に作成が多いと画面が止まるので
|
||||
@ -1409,7 +1385,7 @@ void nnMain()
|
||||
sprintf(file_path,"dir%d/file%d",i,i);
|
||||
LogAdd(file_path);
|
||||
mbstowcs(file_pathw,file_path,510);
|
||||
if (savedata.OpenW(file_pathw,FILEBUFF_SIZE,&flg)==false)
|
||||
if (savedata.OpenC(file_pathw,FILEBUFF_SIZE,&flg)==false)
|
||||
{
|
||||
LogAdd("> Open Error");
|
||||
break;
|
||||
@ -1427,7 +1403,7 @@ void nnMain()
|
||||
sprintf(file_path,"dir%d/dir%d/file%d",i,i,i);
|
||||
LogAdd(file_path);
|
||||
mbstowcs(file_pathw,file_path,510);
|
||||
if (savedata.OpenW(file_pathw,FILEBUFF_SIZE,&flg)==false)
|
||||
if (savedata.OpenC(file_pathw,FILEBUFF_SIZE,&flg)==false)
|
||||
{
|
||||
LogAdd("> Open Error");
|
||||
break;
|
||||
@ -1442,7 +1418,7 @@ void nnMain()
|
||||
sprintf(file_path,"dir%d/dir%d/file%d",i,i,i+2);
|
||||
LogAdd(file_path);
|
||||
mbstowcs(file_pathw,file_path,510);
|
||||
if (savedata.OpenW(file_pathw,FILEBUFF_SIZE,&flg)==false)
|
||||
if (savedata.OpenC(file_pathw,FILEBUFF_SIZE,&flg)==false)
|
||||
{
|
||||
LogAdd("> Open Error");
|
||||
break;
|
||||
|
||||
@ -103,42 +103,6 @@ void failstop()
|
||||
}
|
||||
|
||||
|
||||
char sts[128];
|
||||
//エラー表示
|
||||
void PutError(ErcDev dev,int cd)
|
||||
{
|
||||
int desc,code;
|
||||
nn::Result res;
|
||||
switch (dev)
|
||||
{
|
||||
case ERC_DEV_CARD: res = savedata.LastNnResult;break;
|
||||
case ERC_DEV_OUT: res = exsave.LastNnResult;break;
|
||||
}
|
||||
if ((cd ==0 ) && (dev != ERC_DEV_OTHER))
|
||||
{
|
||||
desc = res.GetDescription();
|
||||
if (desc < 100 ) code = ERC_UNKNOWN;//キー検索完了 .. ありえない
|
||||
else if (desc < 180 ) code = ERC_READ;//ファイルが見つからないか不正
|
||||
else if (desc < 200 ) code = ERC_WRITE_OW;//ファイルが存在 .. 削除失敗?
|
||||
else if (desc < 220 ) code = ERC_WRITE_NS;//空きが無い
|
||||
else if (desc < 260 ) code = ERC_ACCESS;//操作拒否
|
||||
else if (desc < 280 ) code = ERC_WRITE_PROTECT;//書き込み禁止
|
||||
else if (desc < 340 ) code = ERC_ACCESS;//アクセスエラー
|
||||
else if (desc < 390 ) code = ERC_FORMAT;//フォーマットエラー
|
||||
else if (desc < 400 ) code = ERC_SDK_VERIFI;//改竄
|
||||
else if (desc < 580 ) code = ERC_ROM;//ROM情報エラー
|
||||
else if (desc < 590 ) code = ERC_RETRY;//リトライ要求
|
||||
else if (desc < 600 ) code = ERC_UNKNOWN;//CCI,CXI不正 .. ありえない
|
||||
else if (desc < 900 ) code = ERC_EXEC;//実行時エラー、ソフトバグ
|
||||
else code = ERC_FATAL;//本体に問題の可能性
|
||||
}else code = cd;
|
||||
if (desc>=600){
|
||||
sprintf(sts,"desc %d",desc);
|
||||
}else{
|
||||
sprintf(sts,"ERROR %d",dev+code);
|
||||
}
|
||||
scr_Status(sts,COLOR_RED);
|
||||
}
|
||||
|
||||
wchar_t file_pathw[MAX_PATH_LENGTH];
|
||||
wchar_t file_pathw2[MAX_PATH_LENGTH];
|
||||
@ -148,6 +112,20 @@ char fileBuffer[512] NN_ATTRIBUTE_ALIGN(4);//検証 512単位
|
||||
char fileBuffer_ex[512] NN_ATTRIBUTE_ALIGN(4);
|
||||
#define FILEBUFF_SIZE sizeof(fileBuffer)
|
||||
|
||||
//エラー表示
|
||||
char sts[64];
|
||||
void PutError(ErcDev dev,int cd)
|
||||
{
|
||||
nn::Result res;
|
||||
switch (dev)
|
||||
{
|
||||
case ERC_DEV_CARD: res = savedata.LastNnResult;break;
|
||||
case ERC_DEV_OUT: res = exsave.LastNnResult;break;
|
||||
}
|
||||
GetErrorStr(dev,res,cd,sts);
|
||||
scr_Status(sts,COLOR_RED);
|
||||
}
|
||||
|
||||
//デバグ用ウエイト
|
||||
void waitSec(int sec)
|
||||
{
|
||||
@ -161,21 +139,18 @@ void waitSec(int sec)
|
||||
}
|
||||
|
||||
|
||||
char mes[128];
|
||||
//保存先のディレクトリ削除
|
||||
bool TryDeleteDir()
|
||||
{
|
||||
nn::Result resbk = exsave.LastNnResult;
|
||||
if(exsave.Delete()==false)
|
||||
{
|
||||
//フォルダ削除に失敗したら手削除
|
||||
strcpy(sts,"Please delete folder[ ");
|
||||
strcat(sts,exsave.DirName);//フォルダ名
|
||||
strcat(sts," ]");
|
||||
scr_Status(sts,COLOR_RED);
|
||||
return false;
|
||||
}
|
||||
exsave.LastNnResult = resbk;
|
||||
return true;
|
||||
if(exsave.Delete())return true;
|
||||
//フォルダ削除に失敗したら手削除
|
||||
strcpy(mes,"broken folder [ ");
|
||||
strcat(mes,exsave.DirName);//フォルダ名
|
||||
strcat(mes," ]");
|
||||
//scr_Status(sts,COLOR_RED);
|
||||
scr_MessOnCount(mes);
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------- CARD to SD
|
||||
@ -183,7 +158,7 @@ RetCode Card2Sd()
|
||||
{
|
||||
myResult res;
|
||||
int ct=0,msize,rsize;
|
||||
s64 total=0;
|
||||
s64 total=0,free_size;
|
||||
|
||||
scr_BackupYesNo();//実行確認
|
||||
WaitUI();//入力待ち
|
||||
@ -218,7 +193,7 @@ RetCode Card2Sd()
|
||||
if (exsave.Create() == false)
|
||||
{
|
||||
savedata.Unmount();
|
||||
if(TryDeleteDir())PutError(ERC_DEV_OUT);
|
||||
PutError(ERC_DEV_OUT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
@ -263,7 +238,7 @@ RetCode Card2Sd()
|
||||
if(CheckInsExit())break;//挿抜による中断
|
||||
//SDで支障あるパス名の場合は別ファイルに格納する
|
||||
exsave.GetRootPath(file_pathw2);//格納先ルート取得
|
||||
wcscat(file_pathw2,file_pathw);//実パス名に変換
|
||||
ChainPath(file_pathw2,file_pathw);//実パス名に変換
|
||||
if (CheckPath(file_pathw2)==false)//パス名チェック
|
||||
{
|
||||
if (exsave.OpenVnfW(file_pathw,fsize)==false)//退避ファイル
|
||||
@ -275,7 +250,7 @@ RetCode Card2Sd()
|
||||
bool mkdir;
|
||||
int rev;
|
||||
while(1){
|
||||
if (exsave.OpenW(file_pathw,fsize,&mkdir)==false)
|
||||
if (exsave.OpenC(file_pathw,fsize,&mkdir)==false)
|
||||
{
|
||||
if(mkdir)//ディレクトリ作成のみ
|
||||
{//深いと作成に時間かかるので画面に変化つける
|
||||
@ -337,6 +312,11 @@ RetCode Card2Sd()
|
||||
if(exsave.Write(fileBuffer,rsize) != rsize )//ライト
|
||||
{
|
||||
res = RESULT_FAIL_WRITE;
|
||||
if(exsave.LastNnResult.IsSuccess()){//容量不足でオープンすると書けるとこまで書いてエラーとならない
|
||||
if (exsave.GetFreeSize(&free_size)){
|
||||
if (free_size == 0 ) res = RESULT_DEVICE_FULL;//空き無し
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -352,6 +332,8 @@ RetCode Card2Sd()
|
||||
exsave.Unmount();
|
||||
|
||||
//結果
|
||||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||||
scr_CountPerMax2(0,0,-1);
|
||||
if(isInsEject != InEx_None )
|
||||
{//挿抜による中断
|
||||
if(TryDeleteDir())return INSEXIT;
|
||||
@ -373,20 +355,24 @@ RetCode Card2Sd()
|
||||
scr_CountPerMax2(0,0,total);//総サイズ
|
||||
return SUCCESS;
|
||||
}
|
||||
res = RESULT_FAIL_WRITE;
|
||||
if(exsave.LastNnResult.IsSuccess()){//容量不足でオープンすると書けるとこまで書いてエラーとならない
|
||||
if (exsave.GetFreeSize(&free_size)){
|
||||
if (free_size == 0 ) res = RESULT_DEVICE_FULL;//空き無し
|
||||
}
|
||||
}
|
||||
}else{
|
||||
NN_LOG("file count error\n");
|
||||
res = RESULT_FAIL;
|
||||
}
|
||||
}
|
||||
//失敗
|
||||
if (TryDeleteDir())//ディレクトリごと削除
|
||||
{
|
||||
if ((res == RESULT_FAIL_WRITE) || (res== RESULT_FAIL_OPENW)) PutError(ERC_DEV_OUT);
|
||||
else if ((res == RESULT_FAIL_READ) || (res== RESULT_FAIL_OPEN)) PutError(ERC_DEV_CARD);
|
||||
else if (res == RESULT_FAIL_VERIFI) PutError(ERC_DEV_OUT,ERC_VERIFI);
|
||||
else PutError(ERC_DEV_OTHER);
|
||||
}
|
||||
|
||||
if (res == RESULT_DEVICE_FULL)PutError(ERC_DEV_OUT,ERC_WRITE_NS);
|
||||
else if ((res == RESULT_FAIL_WRITE) || (res== RESULT_FAIL_OPENW)) PutError(ERC_DEV_OUT);
|
||||
else if ((res == RESULT_FAIL_READ) || (res== RESULT_FAIL_OPEN)) PutError(ERC_DEV_CARD);
|
||||
else if (res == RESULT_FAIL_VERIFI) PutError(ERC_DEV_OUT,ERC_VERIFI);
|
||||
else PutError(ERC_DEV_OTHER);
|
||||
TryDeleteDir();//ディレクトリごと削除
|
||||
}
|
||||
return ERROR;
|
||||
|
||||
@ -432,9 +418,10 @@ void CheckSaveDataState()
|
||||
scr_PrdCode(savedata.PrdCode);
|
||||
}
|
||||
|
||||
//エクスポート先の状態確認
|
||||
void CheckExSaveState()
|
||||
{
|
||||
exActive = nn::fs::IsSdmcInserted();
|
||||
exActive = nn::fs::IsSdmcInserted() && nn::fs::IsSdmcWritable();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------ 挿抜チェック
|
||||
@ -568,6 +555,7 @@ void nnMain()
|
||||
else PutError(ERC_DEV_OTHER);
|
||||
scr_ResultQuit("Break",COLOR_RED);//エラーとQuitボタン
|
||||
break;
|
||||
case CANCEL:break;
|
||||
default://errors
|
||||
scr_ResultQuit("Failed",COLOR_RED);//エラーとQuitボタン
|
||||
break;
|
||||
|
||||
@ -550,7 +550,7 @@ void scr_TopMenu(bool formatted,bool inserted,bool sdins,int err)
|
||||
}else
|
||||
if (sdins == false)
|
||||
{
|
||||
strcpy(scr_err,"Please Insert SD");
|
||||
strcpy(scr_err,"SD protected or not Insert");
|
||||
gui.MessEffective(MESSAGE_MENU_CAUTION);
|
||||
|
||||
}else{
|
||||
@ -701,6 +701,15 @@ void scr_MessOnCount2(char *str)
|
||||
gui.Draw();
|
||||
}
|
||||
|
||||
void scr_MessOnCount(char *str)
|
||||
{
|
||||
// gui.MessCol(MESSAGE_COUNT2,COLOR_YELLO);
|
||||
gui.MessStr(MESSAGE_COUNT,str);
|
||||
gui.MessEffective(MESSAGE_COUNT);
|
||||
gui.Draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//ŽÀ<C5BD>sŠm”F
|
||||
void scr_ConfirmDbg(char *str)
|
||||
|
||||
@ -108,6 +108,7 @@ void scr_PrdCode(char *s);
|
||||
void scr_PrdCodeEx(char *s);
|
||||
void scr_DelConf();
|
||||
void scr_MessOnCount2(char *str);
|
||||
void scr_MessOnCount(char *str);
|
||||
void scr_Draw();
|
||||
void scr_GetEvnt();
|
||||
|
||||
|
||||
@ -3,14 +3,49 @@
|
||||
#include "common.h"
|
||||
#include "sleep.h"
|
||||
#include "demo.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern demo::RenderSystemDrawing s_RenderSystem;
|
||||
extern nn::fnd::ExpHeap appHeap;
|
||||
extern uptr heapForGx;
|
||||
|
||||
bool prohibitHome = false;// HOME ボタン禁止
|
||||
|
||||
//エラー表示用文字列生成
|
||||
void GetErrorStr(ErcDev dev,nn::Result res,int cd,char* s)
|
||||
{
|
||||
int desc=0,code;
|
||||
desc = res.GetDescription();
|
||||
|
||||
if ((cd ==0 ) && (dev != ERC_DEV_OTHER))
|
||||
{
|
||||
if (desc < 100 ) code = ERC_UNKNOWN;//キー検索完了 .. ありえない
|
||||
else if (desc < 180 ) code = ERC_READ;//ファイルが見つからないか不正
|
||||
else if (desc < 200 ) code = ERC_WRITE_OW;//ファイルが存在 .. 削除失敗?
|
||||
else if (desc < 220 ) code = ERC_WRITE_NS;//空きが無い
|
||||
else if (desc < 260 ) code = ERC_ACCESS;//操作拒否
|
||||
else if (desc < 280 ) code = ERC_WRITE_PROTECT;//書き込み禁止
|
||||
else if (desc < 340 ) code = ERC_ACCESS;//アクセスエラー
|
||||
else if (desc < 390 ) code = ERC_FORMAT;//フォーマットエラー
|
||||
else if (desc < 400 ) code = ERC_SDK_VERIFI;//改竄
|
||||
else if (desc < 580 ) code = ERC_ROM;//ROM情報エラー
|
||||
else if (desc < 590 ) code = ERC_RETRY;//リトライ要求
|
||||
else if (desc < 600 ) code = ERC_UNKNOWN;//CCI,CXI不正 .. ありえない
|
||||
else if (desc < 900 ) code = ERC_EXEC;//実行時エラー、ソフトバグ
|
||||
else code = ERC_FATAL;//本体に問題の可能性
|
||||
}else code = cd;
|
||||
if (desc>=600){
|
||||
sprintf(s,"ERROR %d, desc %d",dev+code,desc);
|
||||
}else{
|
||||
sprintf(s,"ERROR %d",dev+code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool prohibitHome = false;// HOME ボタン禁止
|
||||
// ファイルシステム処理と遷移やスリープ処理との排他制御に利用
|
||||
//nn::os::CriticalSection g_SleepCS;
|
||||
// HOME ボタン遷移とファイルシステム処理の排他制御に利用(手動リセット)
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#include "my_defs.h"
|
||||
|
||||
typedef void (*FUNCP)();
|
||||
|
||||
void finish();
|
||||
void CheckSysBreak();
|
||||
void InitSysBreak(uptr adrs);
|
||||
void GetErrorStr(ErcDev dev,nn::Result res,int cd,char* s);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -85,6 +85,7 @@ typedef enum {
|
||||
RESULT_BAD_PARAM,
|
||||
RESULT_DIR_LEVEL_OVER,
|
||||
RESULT_PATH_LENGTH_OVER,
|
||||
RESULT_DEVICE_FULL,
|
||||
RESULT_MAX
|
||||
}myResult;
|
||||
|
||||
|
||||
@ -123,6 +123,7 @@ void MemBak::CloseSysW()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//システムファイルライト
|
||||
bool MemBak::WriteSys(tArcInfo *pinfo)
|
||||
{
|
||||
|
||||
@ -7,153 +7,6 @@
|
||||
#include <nn/am/am_ApiSystemMenu.h>
|
||||
#include <nn/am/am_ApiLocalImporter.h>
|
||||
|
||||
int dc_readed[MAX_LEVEL];//リード済みエントリ数
|
||||
|
||||
const wchar_t *sdataRoot_w = L"data:/";
|
||||
#define ROOTLENGTH 6
|
||||
const char *sdataName = "data:";
|
||||
static bool IsMounted;
|
||||
wchar_t path_w[MAX_PATH_LENGTH];//パス名
|
||||
wchar_t pathu_w[MAX_LEVEL][MAX_PATH_LENGTH];//パス名履歴
|
||||
wchar_t pathw_w[MAX_PATH_LENGTH];//パス名ワーク
|
||||
|
||||
//セーブ作成、成功時はマウント状態
|
||||
myResult SaveData::Format(tArcInfo *pinfo)
|
||||
{
|
||||
if ( IsMounted )return RESULT_ALREADY_MOUNT;
|
||||
LastNnResult = nn::fs::FormatCtrCardSaveData(pinfo->FileEntry,pinfo->DirEntry,pinfo->Dup);
|
||||
if (LastNnResult.IsFailure())return RESULT_FAIL_FORMAT;
|
||||
if ( Mount() != RESULT_OK )return RESULT_FAIL_MOUNT;
|
||||
IsMounted = true;
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
void SaveData::ResetPath()
|
||||
{
|
||||
s_lv=0;
|
||||
s_serch = false;
|
||||
wcscpy(path_w,sdataRoot_w);
|
||||
for (int n = 0;n<MAX_LEVEL;n++)dc_readed[n] = 0;
|
||||
}
|
||||
|
||||
myResult SaveData::GetPath(wchar_t *path)
|
||||
{
|
||||
static nn::fs::DirectoryEntry dcEntryl;
|
||||
static nn::fs::Directory dcl;
|
||||
|
||||
int n,ct;
|
||||
while(1){
|
||||
LastNnResult = dcl.TryInitialize(path_w);//Open
|
||||
if (LastNnResult.IsFailure()){
|
||||
return RESULT_FAIL;
|
||||
}
|
||||
if (dc_readed[s_lv] != 0)for(n=0;n<dc_readed[s_lv];n++)dcl.Read(&dcEntryl,1);
|
||||
n = (dcl.Read(&dcEntryl,1));
|
||||
dc_readed[s_lv]++;
|
||||
dcl.Finalize();
|
||||
if ( n==0 )//終端
|
||||
{
|
||||
if (s_lv == 0){path[0]=0;return RESULT_OK;}// ---- rootなら終了
|
||||
dc_readed[s_lv]=0;
|
||||
s_lv--;//上の層に戻る
|
||||
wcscpy(path_w,pathu_w[s_lv]);//パス戻す
|
||||
}else{
|
||||
if(dcEntryl.attributes.isDirectory){//ディレクトリ
|
||||
wcscpy(pathu_w[s_lv],path_w);//パス保存
|
||||
wcscat(path_w,dcEntryl.entryName);//次のディレクトリパス
|
||||
wcscat(path_w,L"/");
|
||||
if (++s_lv == MAX_LEVEL)return RESULT_DIR_LEVEL_OVER;
|
||||
}else{//ファイル
|
||||
wcscpy(path,pPathTop);
|
||||
ct =wcslen(path) + wcslen(dcEntryl.entryName);
|
||||
if (ct>MAX_PATH_LENGTH - 1)return RESULT_PATH_LENGTH_OVER;
|
||||
wcscat(path,dcEntryl.entryName);
|
||||
return RESULT_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//アンマウント
|
||||
void SaveData::Unmount()
|
||||
{
|
||||
if(IsMounted){
|
||||
IsMounted = false;
|
||||
nn::fs::Unmount(sdataName);
|
||||
}
|
||||
}
|
||||
|
||||
//バックアップの存在チェック
|
||||
myResult SaveData::IsExist(){
|
||||
myResult res;
|
||||
res = Mount();
|
||||
Unmount();
|
||||
return res;
|
||||
}
|
||||
|
||||
//アーカイブ情報の取得
|
||||
bool SaveData::GetInfo(tArcInfo *pinfo)
|
||||
{
|
||||
static nn::fs::DirectoryEntry dcEntryl;
|
||||
static nn::fs::Directory dcl;
|
||||
|
||||
if(IsMounted==false){NN_LOG("GetInfo: Not Mounted\n");return false;};
|
||||
|
||||
s_lv=0;
|
||||
m_info.DirCount = 0;
|
||||
m_info.FileCount = 0;
|
||||
m_info.DirEntry = 0;
|
||||
m_info.FileEntry = 0;
|
||||
m_info.Dup = false;
|
||||
wcscpy(path_w,sdataRoot_w);
|
||||
|
||||
int n;
|
||||
int lv = 0;
|
||||
for (n = 0;n<MAX_LEVEL;n++)dc_readed[n] = 0;
|
||||
bool cont = true;
|
||||
while(cont){
|
||||
LastNnResult = dcl.TryInitialize(path_w);//Open
|
||||
if (LastNnResult.IsFailure())return false;
|
||||
if (dc_readed[lv] != 0)for(n=0;n<dc_readed[lv];n++)dcl.Read(&dcEntryl,1);
|
||||
while(1){
|
||||
n = (dcl.Read(&dcEntryl,1));
|
||||
dc_readed[lv]++;
|
||||
if ( n==0 )//終端
|
||||
{
|
||||
if (lv == 0){cont=false;break;}// ---- 終了
|
||||
dc_readed[lv]=0;
|
||||
lv--;//上の層に戻る
|
||||
wcscpy(path_w,pathu_w[lv]);//パス戻す
|
||||
break;
|
||||
}else{
|
||||
if(dcEntryl.attributes.isDirectory){//ディレクトリ
|
||||
m_info.DirCount++;
|
||||
wcscpy(pathu_w[lv],path_w);//パス保存
|
||||
wcscat(path_w,dcEntryl.entryName);//次のディレクトリパス
|
||||
wcscat(path_w,L"/");
|
||||
if (++lv == MAX_LEVEL)return false;
|
||||
break;
|
||||
}else{//ファイル
|
||||
m_info.FileCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dcl.Finalize();
|
||||
}
|
||||
for (n = 0;n<MAX_LEVEL;n++)dc_readed[n] = 0;
|
||||
|
||||
Unmount();//GetCtrCardSaveDataFormatInfo内でマウントするので一旦アンマウント(SDK2.1~3のみエラー?)
|
||||
LastNnResult = nn::fs::GetCtrCardSaveDataFormatInfo(&m_info.FileEntry,&m_info.DirEntry,&m_info.Dup);
|
||||
Mount();
|
||||
|
||||
*pinfo = m_info;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//プロダクトコード
|
||||
//結果は PrdCord に格納
|
||||
bool SaveData::GetPrdCode()
|
||||
@ -178,134 +31,49 @@ bool SaveData::GetPrdCode()
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
|
||||
//マウント&アーカイブ情報の取得
|
||||
myResult SaveData::Mount()
|
||||
//セーブ作成、成功時はマウント状態
|
||||
myResult SaveData::Format(tArcInfo *pinfo)
|
||||
{
|
||||
if (IsMounted)return RESULT_ALREADY_MOUNT;
|
||||
LastNnResult = nn::fs::MountCtrCardSaveDataForCheck(sdataName);//ApiForHwCheck
|
||||
IsMounted = LastNnResult.IsSuccess();
|
||||
if (IsMounted)return RESULT_OK;
|
||||
if (nn::fs::ResultMediaNotFound().Includes(LastNnResult))return RESULT_NO_MEDIA;
|
||||
if (nn::fs::ResultFatNotFound().Includes(LastNnResult))return RESULT_NOT_FAUND;//書けるのか?
|
||||
if (nn::fs::ResultNotFormatted().Includes(LastNnResult))return RESULT_NOT_FORMAT;
|
||||
if (nn::fs::ResultBadFormat().Includes(LastNnResult))return RESULT_BAD_FORMAT;
|
||||
if (nn::fs::ResultVerificationFailed().Includes(LastNnResult))return RESULT_SDK_VERIFI;//SDK2.3以前
|
||||
|
||||
return RESULT_FAIL;
|
||||
if ( IsMounted )return RESULT_ALREADY_MOUNT;
|
||||
LastNnResult = nn::fs::FormatCtrCardSaveData(pinfo->FileEntry,pinfo->DirEntry,pinfo->Dup);
|
||||
if (LastNnResult.IsFailure())return RESULT_FAIL_FORMAT;
|
||||
if ( Mount() != RESULT_OK )return RESULT_FAIL_MOUNT;
|
||||
IsMounted = true;
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//ファイルリード
|
||||
s32 SaveData::Read(char *buffer,size_t size)
|
||||
{
|
||||
//if (IsMounted==false)return 0;
|
||||
s32 ct;
|
||||
LastNnResult = reader.TryRead(&ct,(void*)buffer,size);
|
||||
if(LastNnResult.IsFailure())ct=0;
|
||||
return ct;
|
||||
}
|
||||
|
||||
|
||||
void SaveData::Close()
|
||||
{
|
||||
reader.Finalize();
|
||||
}
|
||||
|
||||
void SaveData::CloseW()
|
||||
{
|
||||
writer.Finalize();
|
||||
}
|
||||
|
||||
//ファイルを開く
|
||||
//パス指定はルート以降
|
||||
//(ex)data:/dir/file -> dir/file
|
||||
bool SaveData::Open(wchar_t *path)
|
||||
{
|
||||
wcscpy(pathw_w,sdataRoot_w);
|
||||
wcscat(pathw_w,path);
|
||||
LastNnResult = reader.TryInitialize(pathw_w);
|
||||
if (LastNnResult.IsSuccess())
|
||||
{
|
||||
LastNnResult = reader.TryGetSize(&FileSize);
|
||||
if (LastNnResult.IsSuccess())return true;
|
||||
else Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SaveData::OpenW(wchar_t *path,s64 size,bool *mkdir)
|
||||
{
|
||||
int pos,pos2;
|
||||
|
||||
wcscpy(path_w,sdataRoot_w);
|
||||
wcscat(path_w,path);
|
||||
*mkdir = false;
|
||||
LastNnResult = nn::fs::TryCreateFile(path_w,size);
|
||||
if(LastNnResult.IsSuccess())
|
||||
{
|
||||
LastNnResult = writer.TryInitialize(path_w,false);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
//ディレクトリがなければディレクトリを作成
|
||||
pos = GetPosDelmLast(path_w,ROOTLENGTH);//ファイルが存在するディレクトリ
|
||||
if (pos <= 0)return false;//rootかパスが不正
|
||||
wcscpy(pathw_w,path_w);//ワークにコピー
|
||||
while (LastNnResult.IsFailure()){//ディレクトリ作成できるまで遡る
|
||||
if(LastNnResult.GetDescription()!=nn::fs::DESCRIPTION_DBM_DIRECTORY_NOT_FOUND)return false;
|
||||
pos2 = GetPosDelmLast(pathw_w,ROOTLENGTH);//境界位置を探す
|
||||
if (pos2 == 0)return false;//root到達
|
||||
pathw_w[pos2] = 0;//境界まで削除 (例) dir1/dir2/file -> dir1/dir2 -> dir1
|
||||
LastNnResult = nn::fs::TryCreateDirectory(pathw_w);
|
||||
}
|
||||
//作成ディレクトリ多いと画面止まるので、作成ごとに抜ける
|
||||
*mkdir = true; // 帰値:false で mkdir=true ならディレクトリ作成のみ
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//ファイルライト
|
||||
s32 SaveData::Write(char *buffer,size_t size)
|
||||
{
|
||||
s32 ct;
|
||||
LastNnResult = writer.TryWrite(&ct,(void*)buffer,size);
|
||||
if(LastNnResult.IsFailure())ct=0;
|
||||
return ct;
|
||||
}
|
||||
|
||||
//コミット
|
||||
bool SaveData::Commit()
|
||||
{
|
||||
LastNnResult=nn::fs::CommitSaveData(sdataName);
|
||||
LastNnResult=nn::fs::CommitSaveData(devName);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
|
||||
|
||||
//マウント
|
||||
bool SaveData::MountCore()
|
||||
{
|
||||
//リストア先の場合、コール元でチェック(エラーによってはフォーマットすれば使える)
|
||||
LastNnResult = nn::fs::MountCtrCardSaveDataForCheck(devName);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
|
||||
//フォーマット情報
|
||||
void SaveData::GetFormatInfoCore(tArcInfo *ifo)
|
||||
{
|
||||
LastNnResult = nn::fs::GetCtrCardSaveDataFormatInfo(&ifo->FileEntry,&ifo->DirEntry,&ifo->Dup);
|
||||
}
|
||||
|
||||
|
||||
//コンストラクタ
|
||||
SaveData::SaveData()
|
||||
{
|
||||
IsMounted = false;
|
||||
s_lv=0;
|
||||
PrdCode[0] = 0;
|
||||
m_info.DirCount = 0;
|
||||
m_info.FileCount = 0;
|
||||
m_info.DirEntry = 0;
|
||||
m_info.FileEntry = 0;
|
||||
wcscpy(path_w,sdataRoot_w);
|
||||
pPathTop = (wchar_t*)((u32)&path_w+strlen(sdataName)*2+2);
|
||||
strcpy(devName,"data:");
|
||||
SetRootPath(L"data:");
|
||||
|
||||
}
|
||||
|
||||
void SaveData::Finalize()
|
||||
{
|
||||
Close();
|
||||
Unmount();
|
||||
}
|
||||
//デストラクタ
|
||||
SaveData::~SaveData()
|
||||
{
|
||||
Finalize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -18,47 +18,23 @@
|
||||
|
||||
#include <nn/types.h>
|
||||
#include <nn/Result.h>
|
||||
//#include <nn/am/am_ApiSystemMenu.h>
|
||||
#include "../my_defs.h"
|
||||
#include "savefile.h"
|
||||
|
||||
|
||||
class SaveData
|
||||
class SaveData: public SaveFileRead,public SaveFileWrite
|
||||
{
|
||||
public:
|
||||
s64 FileSize;
|
||||
nn::Result LastNnResult;
|
||||
char PrdCode[20];
|
||||
private:
|
||||
nn::fs::FileReader reader;
|
||||
nn::fs::FileWriter writer;
|
||||
int s_lv;
|
||||
wchar_t *pPathTop;
|
||||
tArcInfo m_info;
|
||||
bool s_serch;
|
||||
u8 pad[3];//padding
|
||||
public:
|
||||
SaveData();
|
||||
~SaveData();
|
||||
myResult Mount();
|
||||
void Unmount();
|
||||
myResult GetPath(wchar_t *path);
|
||||
void ResetPath();
|
||||
bool Open(wchar_t *path);
|
||||
void Finalize();
|
||||
void Close();
|
||||
void CloseW();
|
||||
s32 Read(char *buffer,size_t size);
|
||||
myResult IsExist();
|
||||
bool GetInfo(tArcInfo *pinfo);
|
||||
myResult Format(tArcInfo *pinfo);
|
||||
bool OpenW(wchar_t *path,s64 size,bool *mkdir);
|
||||
s32 Write(char *buffer,size_t size);
|
||||
bool Commit();
|
||||
void GetFormatInfoCore(tArcInfo *ifo);
|
||||
bool MountCore();
|
||||
void Finalize(){Close();};
|
||||
bool GetPrdCode();
|
||||
#ifdef USE_SYS_SAVE
|
||||
void Delete();
|
||||
#endif
|
||||
bool Commit();
|
||||
SaveData();
|
||||
~SaveData(){Finalize();};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -16,6 +16,15 @@ int GetPosDelmLast(wchar_t *s,int top)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//パス結合
|
||||
void ChainPath(wchar_t *p1,wchar_t *p2)
|
||||
{
|
||||
int n=wcslen(p1);
|
||||
if ((p1[n-1] == L'/') && (p2[0] == L'/')) p1[n-1] = 0;
|
||||
if ((p1[wcslen(p1)-1] != L'/') && (p2[0] != L'/')) wcscat(p1,L"/");
|
||||
wcscat(p1,p2);
|
||||
}
|
||||
|
||||
|
||||
//パス名チェック for SD
|
||||
//fs関数で引数エラー(INVALID_ARGUMENT)にならないものをチェック
|
||||
@ -39,3 +48,245 @@ bool CheckPath(wchar_t *s)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------- Class SaveFileWrite
|
||||
//ディレクトリ作成ありのオープン
|
||||
bool SaveFileWrite::OpenC(wchar_t *path,s64 size,bool *mkdir)
|
||||
{
|
||||
int pos,pos2;
|
||||
|
||||
wcscpy(pathw_w,root_w);
|
||||
ChainPath(pathw_w,path);
|
||||
|
||||
*mkdir = false;
|
||||
LastNnResult = nn::fs::TryCreateFile(pathw_w,size);
|
||||
if(LastNnResult.IsSuccess())
|
||||
{
|
||||
LastNnResult = writer.TryInitialize(pathw_w,false);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
//ディレクトリがなければディレクトリを作成
|
||||
pos = GetPosDelmLast(pathw_w,RootLength);//ファイルが存在するディレクトリ
|
||||
if (pos <= 0)return false;//rootかパスが不正
|
||||
wcscpy(pathw_w2,pathw_w);//ワークにコピー
|
||||
while (LastNnResult.IsFailure()){//ディレクトリ作成できるまで遡る
|
||||
if(nn::fs::ResultNotFound::Includes(LastNnResult)==false)return false;
|
||||
pos2 = GetPosDelmLast(pathw_w2,RootLength);//境界位置を探す
|
||||
if (pos2 == 0)return false;//root到達
|
||||
pathw_w2[pos2] = 0;//境界まで削除 (例) dir1/dir2/file -> dir1/dir2 -> dir1
|
||||
LastNnResult = nn::fs::TryCreateDirectory(pathw_w2);
|
||||
}
|
||||
//作成ディレクトリ多いと画面止まるので、作成ごとに抜ける
|
||||
*mkdir = true; // 帰値:false で mkdir=true ならディレクトリ作成のみ
|
||||
return false;
|
||||
}
|
||||
|
||||
//ディレクトリ作成なしオープン、存在する場合は追記
|
||||
bool SaveFileWrite::OpenAdd(wchar_t *path)
|
||||
{
|
||||
wcscpy(pathw_w,root_w);
|
||||
ChainPath(pathw_w,path);
|
||||
LastNnResult = writer.TryInitialize(pathw_w,false);
|
||||
if (LastNnResult.IsSuccess()){
|
||||
LastNnResult = writer.TrySeek(0,nn::fs::POSITION_BASE_END);//追記
|
||||
}else LastNnResult = writer.TryInitialize(pathw_w,true);//新規
|
||||
if (LastNnResult.IsFailure())
|
||||
{
|
||||
writer.Finalize();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//ディレクトリ作成なしオープン
|
||||
bool SaveFileWrite::OpenW(const wchar_t *path)
|
||||
{
|
||||
wcscpy(pathw_w,root_w);
|
||||
ChainPath(pathw_w,(wchar_t*)path);
|
||||
LastNnResult = writer.TryInitialize(pathw_w,true);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//クローズ
|
||||
void SaveFileWrite::CloseW()
|
||||
{
|
||||
writer.Finalize();
|
||||
}
|
||||
|
||||
s32 SaveFileWrite::Write(char *buffer,size_t size)
|
||||
{
|
||||
s32 ct;
|
||||
LastNnResult = writer.TryWrite(&ct,(void*)buffer,size);
|
||||
if(LastNnResult.IsFailure()){NN_LOG("write fail\n");ct=0;}
|
||||
return ct;
|
||||
}
|
||||
|
||||
|
||||
//ディレクトリ作成
|
||||
bool SaveFileWrite::CreateDir(const wchar_t *dir)
|
||||
{
|
||||
LastNnResult = nn::fs::TryCreateDirectory(dir);
|
||||
if(LastNnResult.IsSuccess())return true;
|
||||
return nn::fs::ResultAlreadyExists::Includes(LastNnResult);
|
||||
}
|
||||
|
||||
//削除
|
||||
bool SaveFileWrite::DeleteDir(const wchar_t *dir)
|
||||
{
|
||||
LastNnResult = nn::fs::TryDeleteDirectoryRecursively(dir);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------ Class SaveFileRead
|
||||
bool SaveFileRead::Open(const wchar_t *path)
|
||||
{
|
||||
wcscpy(pathw_w,root_w);
|
||||
ChainPath(pathw_w,(wchar_t*)path);
|
||||
LastNnResult = reader.TryInitialize(pathw_w);
|
||||
if (LastNnResult.IsSuccess())
|
||||
{
|
||||
LastNnResult = reader.TryGetSize(&FileSize);
|
||||
if (LastNnResult.IsSuccess())return true;
|
||||
else Close();
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void SaveFileRead::Close()
|
||||
{
|
||||
reader.Finalize();
|
||||
}
|
||||
|
||||
|
||||
//ファイルリード
|
||||
s32 SaveFileRead::Read(char *buffer,size_t size)
|
||||
{
|
||||
s32 ct;
|
||||
LastNnResult = reader.TryRead(&ct,(void*)buffer,size);
|
||||
if(LastNnResult.IsFailure())ct=0;
|
||||
return ct;
|
||||
}
|
||||
|
||||
//存在チェック
|
||||
myResult SaveFileRead::IsExist(){
|
||||
myResult res;
|
||||
res = Mount();
|
||||
Unmount();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void SaveFileRead::ResetPath()
|
||||
{
|
||||
s_lv=0;
|
||||
s_serch = false;
|
||||
wcscpy(path_w,root_w);
|
||||
wcscat(path_w,L"/");
|
||||
for (int n = 0;n<MAX_LEVEL;n++)dc_readed[n] = 0;
|
||||
}
|
||||
|
||||
myResult SaveFileRead::GetPath(wchar_t *path)
|
||||
{
|
||||
static nn::fs::DirectoryEntry dcEntryl;
|
||||
static nn::fs::Directory dcl;
|
||||
|
||||
int n,ct;
|
||||
while(1){
|
||||
LastNnResult = dcl.TryInitialize(path_w);//Open
|
||||
if (LastNnResult.IsFailure())return RESULT_FAIL;
|
||||
if (dc_readed[s_lv] != 0)for(n=0;n<dc_readed[s_lv];n++)dcl.Read(&dcEntryl,1);
|
||||
n = (dcl.Read(&dcEntryl,1));
|
||||
dc_readed[s_lv]++;
|
||||
dcl.Finalize();
|
||||
if ( n==0 )//終端
|
||||
{
|
||||
if (s_lv == 0){path[0]=0;return RESULT_OK;}// ---- rootなら終了
|
||||
dc_readed[s_lv]=0;
|
||||
s_lv--;//上の層に戻る
|
||||
wcscpy(path_w,pathu_w[s_lv]);//パス戻す
|
||||
}else{
|
||||
if(dcEntryl.attributes.isDirectory){//ディレクトリ
|
||||
wcscpy(pathu_w[s_lv],path_w);//パス保存
|
||||
wcscat(path_w,dcEntryl.entryName);//次のディレクトリパス
|
||||
wcscat(path_w,L"/");
|
||||
if (++s_lv == MAX_LEVEL)return RESULT_DIR_LEVEL_OVER;
|
||||
}else{//ファイル
|
||||
wcscpy(path,pPathTop);
|
||||
ct =wcslen(path) + wcslen(dcEntryl.entryName);
|
||||
if (ct>MAX_PATH_LENGTH - 1)return RESULT_PATH_LENGTH_OVER;
|
||||
wcscat(path,dcEntryl.entryName);
|
||||
return RESULT_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//アーカイブ情報の取得
|
||||
bool SaveFileRead::GetInfo(tArcInfo *pinfo)
|
||||
{
|
||||
static nn::fs::DirectoryEntry dcEntryl;
|
||||
static nn::fs::Directory dcl;
|
||||
|
||||
if(IsMounted==false){NN_LOG("GetInfo: Not Mounted\n");return false;};
|
||||
|
||||
s_lv=0;
|
||||
m_info.DirCount = 0;
|
||||
m_info.FileCount = 0;
|
||||
m_info.DirEntry = 0;
|
||||
m_info.FileEntry = 0;
|
||||
m_info.Dup = false;
|
||||
wcscpy(pathw_w,root_w);
|
||||
wcscat(pathw_w,L"/");
|
||||
|
||||
int n;
|
||||
int lv = 0;
|
||||
for (n = 0;n<MAX_LEVEL;n++)dc_readed[n] = 0;
|
||||
bool cont = true;
|
||||
while(cont){
|
||||
LastNnResult = dcl.TryInitialize(pathw_w);//Open
|
||||
if (LastNnResult.IsFailure())return false;
|
||||
if (dc_readed[lv] != 0)for(n=0;n<dc_readed[lv];n++)dcl.Read(&dcEntryl,1);
|
||||
while(1){
|
||||
n = (dcl.Read(&dcEntryl,1));
|
||||
dc_readed[lv]++;
|
||||
if ( n==0 )//終端
|
||||
{
|
||||
if (lv == 0){cont=false;break;}// ---- 終了
|
||||
dc_readed[lv]=0;
|
||||
lv--;//上の層に戻る
|
||||
wcscpy(pathw_w,pathu_w[lv]);//パス戻す
|
||||
break;
|
||||
}else{
|
||||
if(dcEntryl.attributes.isDirectory){//ディレクトリ
|
||||
m_info.DirCount++;
|
||||
wcscpy(pathu_w[lv],pathw_w);//パス保存
|
||||
wcscat(pathw_w,dcEntryl.entryName);//次のディレクトリパス
|
||||
wcscat(pathw_w,L"/");
|
||||
if (++lv == MAX_LEVEL)return false;
|
||||
break;
|
||||
}else{//ファイル
|
||||
m_info.FileCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dcl.Finalize();
|
||||
}
|
||||
for (n = 0;n<MAX_LEVEL;n++)dc_readed[n] = 0;
|
||||
|
||||
Unmount();//GetCtrCardSaveDataFormatInfo内でマウントするので一旦アンマウント(SDK2.1~3のみエラー?)
|
||||
GetFormatInfoCore(&m_info);
|
||||
Mount();
|
||||
|
||||
*pinfo = m_info;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -4,45 +4,142 @@
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <nn/types.h>
|
||||
#include "../my_defs.h"
|
||||
#include <nn/Result.h>
|
||||
#include <nn/fs.h>
|
||||
|
||||
//API使用してアーカイブ情報を取得
|
||||
#define INFO_API_USE 1
|
||||
|
||||
//カードの変わりにシステムセーブを使用(API対応までの暫定)
|
||||
//#define USE_SYS_SAVE 1
|
||||
|
||||
//SD保存
|
||||
//#define BKUP_NOTMEM 1
|
||||
|
||||
int GetPosDelmLast(wchar_t *s,int top);
|
||||
|
||||
//情報ファイルのバージョン
|
||||
#define INFO_VERSION 1
|
||||
|
||||
//フォーマット情報
|
||||
//SDバックアップの場合は同梱する
|
||||
//変更の際は後方互換とれるよう追加のみとする
|
||||
struct tArcInfo{
|
||||
u32 DirEntry,FileEntry;
|
||||
u32 DirCount,FileCount;
|
||||
bool Dup;
|
||||
u8 Ver;//バージョン
|
||||
char Pcode[20];//product code save,exsaveクラスのPrdCodeサイズを下回らないこと
|
||||
u8 padding[2];//パディング
|
||||
tArcInfo()
|
||||
: Ver(INFO_VERSION){}
|
||||
};
|
||||
|
||||
//******************************** defines **********
|
||||
//パス名長 :SDK制限はアーカイブ名抜いて253文字
|
||||
//アーカイブ名およびSD格納ディレクトリの余裕いれとく
|
||||
//アーカイブ名およびSD格納ディレクトリの余裕分をみとく
|
||||
#define MAX_PATH_LENGTH 512
|
||||
//パス階層上限
|
||||
//ファイル検索時に使用、"/"+1文字が最短なので128で十分
|
||||
#define MAX_LEVEL 128
|
||||
|
||||
//******************************** functions **********
|
||||
//パス名チェック
|
||||
//FAT違反の半角スペースあるかチェック
|
||||
//文字、予約名、パス長はAPIエラー(INVALID_ARGUMENT)で判定
|
||||
bool CheckPath(wchar_t *s);
|
||||
|
||||
//デリミタ("/")位置を返す
|
||||
int GetPosDelmLast(wchar_t *s,int top);
|
||||
|
||||
//パス結合
|
||||
void ChainPath(wchar_t *p1,wchar_t *p2);
|
||||
|
||||
|
||||
//******************************** Types **********
|
||||
//セーブに関する情報
|
||||
#define INFO_VERSION 0
|
||||
struct tArcInfo{
|
||||
u32 DirEntry,FileEntry;//フォーマット
|
||||
u32 DirCount,FileCount;//登録数
|
||||
char Pcode[20];//product code SDKのサイズを下回らないこと
|
||||
bool Dup;//2重化
|
||||
u8 Ver;
|
||||
u8 yobi;//パディング
|
||||
};
|
||||
|
||||
//******************************** Class ***************
|
||||
class SaveFileBase
|
||||
{
|
||||
public:
|
||||
nn::Result LastNnResult;
|
||||
protected:
|
||||
wchar_t root_w[MAX_PATH_LENGTH];//基底パス(デバイス名含)
|
||||
wchar_t path_w[MAX_PATH_LENGTH];//パス名
|
||||
wchar_t pathw_w[MAX_PATH_LENGTH];//ワーク
|
||||
wchar_t pathw_w2[MAX_PATH_LENGTH];
|
||||
s32 RootLength;
|
||||
wchar_t *pPathTop;
|
||||
char devName[16];
|
||||
bool IsMounted;
|
||||
char dumy[3];
|
||||
public:
|
||||
|
||||
//基底パス設定
|
||||
void SetRootPath(wchar_t *path)
|
||||
{// 最後に"/"はつけない 例) "data:"
|
||||
wcscpy(root_w,path);
|
||||
RootLength = wcslen(path);
|
||||
pPathTop = (wchar_t*)((u32)&path_w+RootLength*2);
|
||||
}
|
||||
void GetRootPath(wchar_t *path)
|
||||
{
|
||||
wcscpy(path,root_w);
|
||||
|
||||
}
|
||||
virtual bool MountCore() = 0;
|
||||
myResult Mount(){
|
||||
if ( IsMounted )return RESULT_ALREADY_MOUNT;
|
||||
if (MountCore()){
|
||||
IsMounted = true;
|
||||
return RESULT_OK;
|
||||
}
|
||||
return RESULT_FAIL_MOUNT;
|
||||
};
|
||||
void Unmount(){
|
||||
if(IsMounted){
|
||||
IsMounted = false;
|
||||
nn::fs::Unmount(devName);
|
||||
}
|
||||
};
|
||||
SaveFileBase(){IsMounted = false;root_w[0]=0;RootLength=0;};
|
||||
~SaveFileBase(){Unmount();};
|
||||
};
|
||||
|
||||
//ライト
|
||||
class SaveFileWrite :public virtual SaveFileBase
|
||||
{
|
||||
private:
|
||||
nn::fs::FileWriter writer;
|
||||
public:
|
||||
SaveFileWrite(){RootLength=0;};
|
||||
~SaveFileWrite(){};
|
||||
bool DeleteDir(const wchar_t *dir);
|
||||
bool OpenW(const wchar_t *path);
|
||||
bool OpenC(wchar_t *path,s64 size,bool *mkdir);
|
||||
bool OpenAdd(wchar_t *path);
|
||||
void CloseW();
|
||||
s32 Write(char *buffer,size_t size);
|
||||
bool CreateDir(const wchar_t *dir);
|
||||
};
|
||||
|
||||
//リード
|
||||
class SaveFileRead :public virtual SaveFileBase
|
||||
{
|
||||
public:
|
||||
s64 FileSize;
|
||||
private:
|
||||
int dc_readed[MAX_LEVEL];//リード済みエントリ数
|
||||
wchar_t pathu_w[MAX_LEVEL][MAX_PATH_LENGTH];//パス名履歴
|
||||
nn::fs::FileReader reader;
|
||||
int s_lv;
|
||||
tArcInfo m_info;
|
||||
bool s_serch;
|
||||
u8 pad[3];//padding
|
||||
public:
|
||||
virtual void GetFormatInfoCore(tArcInfo *ifo) = 0;
|
||||
myResult IsExist();
|
||||
bool Open(const wchar_t *path);
|
||||
void Close();
|
||||
myResult GetPath(wchar_t *path);
|
||||
void ResetPath();
|
||||
bool GetInfo(tArcInfo *pinfo);
|
||||
s32 Read(char *buffer,size_t size);
|
||||
SaveFileRead(){
|
||||
s_lv=0;
|
||||
m_info.DirCount = 0;
|
||||
m_info.FileCount = 0;
|
||||
m_info.DirEntry = 0;
|
||||
m_info.FileEntry = 0;
|
||||
};
|
||||
~SaveFileRead(){};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -15,17 +15,6 @@
|
||||
#include <nn/fs.h>
|
||||
#include "sdmcwo.h"
|
||||
|
||||
const char *devName = "sdmcwo:";
|
||||
const wchar_t *devName_w = L"sdmcwo:";
|
||||
#define PATHLENGTH_MAX_SD 512
|
||||
|
||||
wchar_t sdmcRoot_w[MAX_PATH_LENGTH];//filer/UserSaveData/YearMtDtHrMtSc/00000000
|
||||
#define ROOTLENGTH_SD 51
|
||||
wchar_t expath_w[MAX_PATH_LENGTH];//パス名
|
||||
wchar_t expathw_w[MAX_PATH_LENGTH];//パス名ワーク
|
||||
wchar_t latestPath_w[MAX_PATH_LENGTH];//filer/UserSaveData/YearMtDtHrMtSc
|
||||
bool created;
|
||||
bool IsMounted;
|
||||
|
||||
//SDKツールのSaveFiler用の情報ファイル
|
||||
//-------ources\tools\NandFiler\nandf_Dialog.h 参照
|
||||
@ -83,38 +72,29 @@ bit64 ChangeId(bit64 id, bit64 key)
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
//ディレクトリ作成
|
||||
//ディレクトリオープンも出来ないので、ライト試行
|
||||
bool CreateDir(const wchar_t *dirName)
|
||||
|
||||
bool Sdmcwo::DelDir(const wchar_t *dir)
|
||||
{
|
||||
nn::Result result = nn::fs::TryCreateDirectory(dirName);
|
||||
if(result.IsSuccess())return true;
|
||||
return nn::fs::ResultAlreadyExists::Includes(result);
|
||||
//if (created==false)return true;//未作成ならなにもしない
|
||||
if (Mount() == RESULT_FAIL_MOUNT)return false;
|
||||
bool res = DeleteDir(dir);
|
||||
Unmount();
|
||||
//if (res)created==false;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//SDMCにライト専用アーカイブ
|
||||
//ディレクトリもファイルも読めない
|
||||
|
||||
//直前のCreateで作成したDateTimeフォルダ削除
|
||||
//直前に作成したDateTimeフォルダ削除
|
||||
bool Sdmcwo::Delete()
|
||||
{
|
||||
if (created==false)return true;
|
||||
if (Mount() == RESULT_FAIL_MOUNT)return false;
|
||||
LastNnResult = nn::fs::TryDeleteDirectoryRecursively(latestPath_w);
|
||||
Unmount();
|
||||
return LastNnResult.IsSuccess();
|
||||
return DelDir(latestPath_w);
|
||||
}
|
||||
|
||||
//全削除
|
||||
bool Sdmcwo::DeleteAll()
|
||||
{
|
||||
if (Mount() == RESULT_FAIL_MOUNT)return false;
|
||||
std::wostringstream woss;
|
||||
woss << devName << SDMC_ROOT_DIR_NAME;//sdmc:/filer
|
||||
LastNnResult = nn::fs::TryDeleteDirectoryRecursively(woss.str().c_str());
|
||||
Unmount();
|
||||
return LastNnResult.IsSuccess();
|
||||
return DelDir(woss.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
@ -142,8 +122,9 @@ bool Sdmcwo::Create()
|
||||
woss << L"/" << "00000000";//sdmc:/filer/UserSaveData/YearMtDtHrMtSc/00000000
|
||||
if ( CreateDir(woss.str().c_str()) )
|
||||
{
|
||||
woss << L"/";//sdmc:/filer/UserSaveData/YearMtDtHrMtSc/00000000/
|
||||
wcscpy(sdmcRoot_w,woss.str().c_str());//格納先パス保存
|
||||
//woss << L"/";//sdmc:/filer/UserSaveData/YearMtDtHrMtSc/00000000/
|
||||
wcscpy(rootPath_w,woss.str().c_str());//格納先パス保存
|
||||
SetRootPath(rootPath_w);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -153,157 +134,63 @@ bool Sdmcwo::Create()
|
||||
return false;
|
||||
}
|
||||
|
||||
//格納先パスの取得
|
||||
//先にCreateしとくこと
|
||||
void Sdmcwo::GetRootPath(wchar_t *path)
|
||||
{
|
||||
wcscpy(path,sdmcRoot_w);
|
||||
}
|
||||
|
||||
|
||||
//マウント
|
||||
myResult Sdmcwo::Mount()
|
||||
{
|
||||
if ( IsMounted )return RESULT_ALREADY_MOUNT;
|
||||
LastNnResult = nn::fs::MountSdmcWriteOnly(devName);
|
||||
if (LastNnResult.IsFailure()){
|
||||
return RESULT_FAIL_MOUNT;
|
||||
}
|
||||
IsMounted = true;
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
void Sdmcwo::Unmount()
|
||||
{
|
||||
IsMounted = false;
|
||||
nn::fs::Unmount(devName);
|
||||
}
|
||||
|
||||
//ライト属性ファイルを閉じる
|
||||
void Sdmcwo::CloseW()
|
||||
{
|
||||
writer.Finalize();
|
||||
}
|
||||
|
||||
//ファイルライト
|
||||
s32 Sdmcwo::Write(char *buffer,size_t size)
|
||||
{
|
||||
s32 ct;
|
||||
LastNnResult = writer.TryWrite(&ct,(void*)buffer,size);
|
||||
if(LastNnResult.IsFailure())ct=0;
|
||||
return ct;
|
||||
}
|
||||
|
||||
//ライトでオープン
|
||||
bool Sdmcwo::OpenW(wchar_t *path,s64 size,bool *mkdir)
|
||||
{
|
||||
int pos,pos2;
|
||||
|
||||
wcscpy(expath_w,sdmcRoot_w);
|
||||
wcscat(expath_w,path);
|
||||
*mkdir = false;
|
||||
LastNnResult = nn::fs::TryCreateFile(expath_w,size);
|
||||
if(LastNnResult.IsSuccess())
|
||||
{
|
||||
LastNnResult = writer.TryInitialize(expath_w,false);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
//ディレクトリがなければディレクトリを作成
|
||||
pos = GetPosDelmLast(expath_w,ROOTLENGTH_SD);//ファイルが存在するディレクトリ
|
||||
if (pos <= 0)return false;//rootかパスが不正
|
||||
wcscpy(expathw_w,expath_w);//ワークにコピー
|
||||
while (LastNnResult.IsFailure()){//ディレクトリ作成できるまで遡る
|
||||
if(nn::fs::ResultNotFound::Includes(LastNnResult)==false)return false;
|
||||
pos2 = GetPosDelmLast(expathw_w,ROOTLENGTH_SD);//境界位置を探す
|
||||
if (pos2 == 0)return false;//root到達
|
||||
expathw_w[pos2] = 0;//境界まで削除 (例) dir1/dir2/file -> dir1/dir2 -> dir1
|
||||
LastNnResult = nn::fs::TryCreateDirectory(expathw_w);
|
||||
}
|
||||
//作成ディレクトリ多いと画面止まるので、作成ごとに抜ける
|
||||
*mkdir = true; // 帰値:false で mkdir=true ならディレクトリ作成のみ
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//パス名エラーで作成できない場合の格納先
|
||||
bool Sdmcwo::OpenVnfW(wchar_t *path,s64 size)
|
||||
{
|
||||
s32 sz;
|
||||
tVnf vnf;
|
||||
bool res=false;
|
||||
//パス名&オフセット用ファイル
|
||||
wcscpy(expath_w,latestPath_w);
|
||||
wcscat(expath_w,L"/00000000.vnf");// 00000000.vnf
|
||||
LastNnResult = writer.TryInitialize(expath_w,false);
|
||||
if (LastNnResult.IsSuccess()){
|
||||
LastNnResult = writer.TrySeek(0,nn::fs::POSITION_BASE_END);//追記
|
||||
}else LastNnResult = writer.TryInitialize(expath_w,true);//新規
|
||||
if (LastNnResult.IsSuccess())
|
||||
SetRootPath(latestPath_w);//基底パスを変更
|
||||
if (OpenAdd(L"/00000000.vnf"))//追記で開く
|
||||
{
|
||||
wcscpy(vnf.path,path);
|
||||
wcscpy(vnf.path,path);//ヘッダ格納
|
||||
vnf.size = size;
|
||||
LastNnResult = writer.TryWrite(&sz,&vnf,sizeof(tVnf));//ヘッダ格納
|
||||
res = (Write((char*)&vnf,sizeof(tVnf)) == sizeof(tVnf));
|
||||
}
|
||||
if (LastNnResult.IsFailure())
|
||||
{
|
||||
writer.Finalize();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
SetRootPath(rootPath_w);//基底パスを戻す
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char buff[32768*2];
|
||||
//情報ファイル
|
||||
//
|
||||
bool Sdmcwo::WriteSys(tArcInfo *ifo)
|
||||
{//SaveFilerで読むためのファイル
|
||||
std::wostringstream woss;
|
||||
if (Mount() == RESULT_FAIL_MOUNT)return false;
|
||||
woss << latestPath_w << L"/00000000";
|
||||
bool res = false;
|
||||
SetRootPath(latestPath_w);//基底パスを変更
|
||||
// FormatParameter を保存
|
||||
LastNnResult = writer.TryInitialize( (woss.str() + L".dat").c_str(), true);
|
||||
if (LastNnResult.IsFailure()){Unmount();return false;}
|
||||
s32 size;
|
||||
FormatParameters Fparam;
|
||||
Fparam.m_MaxDir = ifo->DirEntry;
|
||||
Fparam.m_MaxFile = ifo->FileEntry;
|
||||
Fparam.m_Duplicate = ifo->Dup;
|
||||
LastNnResult = writer.TryWrite(&size, &Fparam, sizeof(FormatParameters));
|
||||
if (LastNnResult.IsFailure()){Unmount();return false;}
|
||||
LastNnResult = writer.TryFlush();
|
||||
if (LastNnResult.IsFailure()){Unmount();return false;}
|
||||
writer.Finalize();
|
||||
//AdditionalInfoを保存
|
||||
AdditionalInfo Ainfo;
|
||||
LastNnResult = writer.TryInitialize((woss.str() + L"_.dat").c_str(), true);
|
||||
if (LastNnResult.IsFailure()){ Unmount();return false;}
|
||||
Ainfo.m_Version = 0;
|
||||
Ainfo.m_Id = ChangeId(Ainfo.m_Id, static_cast<bit64>(std::wcstoll(DateDirName.c_str(), NULL, 10)));
|
||||
LastNnResult = writer.TryWrite(&size, &Ainfo, sizeof(AdditionalInfo));
|
||||
if (LastNnResult.IsFailure()){ Unmount();return false;}
|
||||
LastNnResult = writer.TryFlush();
|
||||
if (LastNnResult.IsFailure()){ Unmount();return false;}
|
||||
writer.Finalize();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//コンストラクタ
|
||||
Sdmcwo::Sdmcwo()
|
||||
{
|
||||
IsMounted = false;
|
||||
}
|
||||
|
||||
void Sdmcwo::Finalize()
|
||||
{
|
||||
if(OpenW( L"/00000000.dat" ))
|
||||
{
|
||||
FormatParameters Fparam;
|
||||
Fparam.m_MaxDir = ifo->DirEntry;
|
||||
Fparam.m_MaxFile = ifo->FileEntry;
|
||||
Fparam.m_Duplicate = ifo->Dup;
|
||||
if ( Write((char*)&Fparam, sizeof(FormatParameters)) == sizeof(FormatParameters))
|
||||
{ //AdditionalInfoを保存
|
||||
CloseW();
|
||||
if(OpenW( L"/00000000_.dat"))
|
||||
{
|
||||
AdditionalInfo Ainfo;
|
||||
Ainfo.m_Version = 0;
|
||||
Ainfo.m_Id = ChangeId(Ainfo.m_Id, static_cast<bit64>(std::wcstoll(DateDirName.c_str(), NULL, 10)));
|
||||
res = Write((char*)&Ainfo, sizeof(AdditionalInfo)) == sizeof(AdditionalInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseW();
|
||||
Unmount();
|
||||
}
|
||||
//デストラクタ
|
||||
Sdmcwo::~Sdmcwo()
|
||||
{
|
||||
Finalize();
|
||||
SetRootPath(rootPath_w);//基底パスを戻す
|
||||
return res;
|
||||
}
|
||||
|
||||
//空き容量
|
||||
bool Sdmcwo::GetFreeSize(s64 *size)
|
||||
{
|
||||
s64 sz;
|
||||
LastNnResult = nn::fs::GetSdmcSize(&sz,size);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,8 @@
|
||||
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
//ライトのみアーカイブ使用
|
||||
//SDKツールのSaveFilerで読める形式でsdmcダイレクトで書き出す
|
||||
//リードはしない
|
||||
|
||||
#ifndef sdmcwo_H_
|
||||
#define sdmcwo_H_
|
||||
@ -22,32 +23,33 @@
|
||||
#include "../my_defs.h"
|
||||
#include "savefile.h"
|
||||
|
||||
class Sdmcwo
|
||||
class Sdmcwo: public SaveFileWrite
|
||||
{
|
||||
public:
|
||||
s64 FileSize;
|
||||
nn::Result LastNnResult;
|
||||
char DirName[16];
|
||||
private:
|
||||
tArcInfo m_info;
|
||||
bool DelDir(const wchar_t *dir);
|
||||
std::wstring GetDateName();
|
||||
std::wstring DateDirName;
|
||||
nn::fs::FileWriter writer;
|
||||
wchar_t latestPath_w[MAX_PATH_LENGTH];//dev:filer/UserSaveData/YearMtDtHrMtSc
|
||||
wchar_t rootPath_w[MAX_PATH_LENGTH];//dev:/filer/UserSaveData/YearMtDtHrMtSc/00000000/
|
||||
bool created;
|
||||
char dummy[3];
|
||||
public:
|
||||
Sdmcwo();
|
||||
~Sdmcwo();
|
||||
void Finalize();
|
||||
bool MountCore()
|
||||
{
|
||||
LastNnResult = nn::fs::MountSdmcWriteOnly(devName);
|
||||
return LastNnResult.IsSuccess();
|
||||
}
|
||||
bool GetFreeSize(s64 *size);
|
||||
void Finalize(){CloseW();};
|
||||
bool Create();
|
||||
myResult Mount();
|
||||
void Unmount();
|
||||
bool Delete();
|
||||
bool DeleteAll();
|
||||
void CloseW();
|
||||
bool OpenW(wchar_t *path,s64 size,bool *mkdir);
|
||||
bool OpenVnfW(wchar_t *path,s64 size);
|
||||
void GetRootPath(wchar_t *path);
|
||||
s32 Write(char *buffer,size_t size);
|
||||
bool WriteSys(tArcInfo *ifo);
|
||||
Sdmcwo(){strcpy(devName,"sdmcwo:");};
|
||||
~Sdmcwo(){Finalize();};
|
||||
};
|
||||
|
||||
//Fat違反パス格納データのヘッダ
|
||||
|
||||
Loading…
Reference in New Issue
Block a user