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:
mizu 2011-05-24 08:13:28 +00:00
parent 8f878dc3ee
commit 9cbc2e2846
14 changed files with 584 additions and 589 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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();

View File

@ -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 ボタン遷移とファイルシステム処理の排他制御に利用(手動リセット)

View File

@ -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

View File

@ -85,6 +85,7 @@ typedef enum {
RESULT_BAD_PARAM,
RESULT_DIR_LEVEL_OVER,
RESULT_PATH_LENGTH_OVER,
RESULT_DEVICE_FULL,
RESULT_MAX
}myResult;

View File

@ -123,6 +123,7 @@ void MemBak::CloseSysW()
{
}
//システムファイルライト
bool MemBak::WriteSys(tArcInfo *pinfo)
{

View File

@ -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.13のみエラー)
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();
}

View File

@ -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();};
};

View File

@ -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.13のみエラー)
GetFormatInfoCore(&m_info);
Mount();
*pinfo = m_info;
return true;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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違反パス格納データのヘッダ