#include #include #include #include "savedata.h" #include //#include <../fs/fs_ApiSysSaveData.h> //#include <../fs/ctr/mpcore/fs_FileSystemBasePrivate.h> #include #include #include #define MAX_LEVEL 256 //static nn::fs::DirectoryEntry dcEntry[MAX_LEVEL]; //static nn::fs::Directory dc[MAX_LEVEL]; int dc_readed[MAX_LEVEL];//リード済みエントリ数 //生成時のデバイス名を超えるとパス長上限をこえる //可能性があるので1文字にする(無用な心配かも) const wchar_t *sdataRoot_w = L"s:/"; #define ROOTLENGTH 3 const char *sdataName = "s:"; const wchar_t *Dummy_w = L"ncltool"; //char path[512];//パス名 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];//パス名ワーク //#define SysSaveId 0x20300 //セーブ作成、成功時はマウント状態 myResult SaveData::Format(tArcInfo *pinfo) { if ( IsMounted )return RESULT_ALREADY_MOUNT; #ifdef USE_SYS_SAVE LastNnResult = nn::fs::CreateSystemSaveData( SysSaveId,pinfo->FileEntry,pinfo->DirEntry,0x100000,pinfo->Dup); if (LastNnResult.IsFailure())return RESULT_FAIL_FORMAT; #else LastNnResult = nn::fs::FormatCtrCardSaveData(pinfo->FileEntry,pinfo->DirEntry,pinfo->Dup); if (LastNnResult.IsFailure())return RESULT_FAIL_FORMAT; #endif 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;nMAX_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) { //strcpy(path,readerRoot); 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); //wcscpy(pathu_w,path_w); int n; int lv = 0; bool cont = true; while(cont){ LastNnResult = dc[lv].TryInitialize(path_w);//Open if (LastNnResult.IsFailure())return false; while(1){ n = (dc[lv].Read(&dcEntry[lv],1)); if ( n==0 )//終端 { dc[lv].Finalize(); if (lv == 0){cont=false;break;}// ---- 終了 lv--;//上の層に戻る wcscpy(path_w,pathu_w[lv]);//パス戻す }else{ if(dcEntry[lv].attributes.isDirectory){//ディレクトリ m_info.DirCount++; wcscpy(pathu_w[lv],path_w);//パス保存 wcscat(path_w,dcEntry[lv].entryName);//次のディレクトリパス wcscat(path_w,L"/"); if (++lv == MAX_LEVEL)return false; break; }else{//ファイル m_info.FileCount++; } } } } #ifndef INFO_API_USE //アーカイブのエントリ数 // .. APIまでの暫定 m_info.DirEntry = m_info.DirCount; m_info.FileEntry = m_info.FileCount; #else //API使用 #ifdef USE_SYS_SAVE size_t sz; LastNnResult = nn::fs::GetSystemSaveDataFormatInfo(SysSaveId, &m_info.FileEntry, &m_info.DirEntry, &sz, &m_info.Dup); #else //LastNnResult = nn::fs::GetSaveDataFormatInfo(&m_info.FileEntry,&m_info.DirEntry,&m_info.Dup); LastNnResult = nn::fs::GetCtrCardSaveDataFormatInfo(&m_info.FileEntry,&m_info.DirEntry,&m_info.Dup); #endif if (LastNnResult.IsFailure())return false; #endif *pinfo = m_info;//構造体コピー return true; } */ //アーカイブ情報の取得 bool SaveData::GetInfo(tArcInfo *pinfo) { static nn::fs::DirectoryEntry dcEntryl; static nn::fs::Directory dcl; //strcpy(path,readerRoot); 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); //wcscpy(pathu_w,path_w); int n; int lv = 0; for (n = 0;n 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; //while(1){ 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かパスが不正 //while (1){ 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; //if (pos2 == pos)break;//配置ディレクトリなら抜ける //todo:ディレクトリが深いとき時間がかかるなら、無駄なTryCreateを省く //案)直上から最初の成功までのデリミタ位置を記録 //先に全ディレクトリ作っておくのがよさげ //} //} //LastNnResult = writer.TryInitialize(path_w,false); //return LastNnResult.IsSuccess(); } //ファイルライト 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() { #ifdef USE_SYS_SAVE LastNnResult=nn::fs::CommitSystemSaveData(sdataName); #else LastNnResult=nn::fs::CommitSaveData(sdataName); #endif return LastNnResult.IsSuccess(); } //コンストラクタ 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); //wcscpy(pathu_w,path_w); pPathTop = (wchar_t*)((u32)&path_w+strlen(sdataName)*2+2); } void SaveData::Finalize() { Close(); Unmount(); } //デストラクタ SaveData::~SaveData() { Finalize(); }