git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@124 385bec56-5757-e545-9c3a-d8741f4650f1

This commit is contained in:
mizu 2011-03-13 23:59:19 +00:00
parent d51310a5a9
commit 728d726405

View File

@ -1,445 +0,0 @@
#include <wchar.h>
#include <string.h>
#include <nn/fs.h>
#include "savedata.h"
#include <nn/fs/fs_ResultPrivate.h>
//#include <../fs/fs_ApiSysSaveData.h>
#include <../fs/ctr/mpcore/fs_FileSystemBasePrivate.h>
#include <nn/fs/CTR/MPCore/fs_ApiForHwCheck.h>
#include <nn/am/am_ApiSystemMenu.h>
#include <nn/am/am_ApiLocalImporter.h>
#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;n<MAX_LEVEL;n++)dc_readed[n] = 0;
//wcscpy(pathu_w,path_w);
}
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なら終了
s_lv--;//上の層に戻る
wcscpy(path_w,pathu_w[s_lv]);//パス戻す
}else{
if(dcEntryl.attributes.isDirectory){//ディレクトリ
//m_info.DirCount++;
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{//ファイル
//m_info.FileCount++;
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)
{
//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<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;}// ---- 終了
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;
#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;
}
//プロダクトコード
//結果は PrdCord に格納
bool SaveData::GetPrdCode()
{
PrdCode[0] = 0;//clear
s32 numPrograms;
nn::ProgramId programId;
LastNnResult = nn::am::InitializeForLocalImporter();
//LastNnResult = nn::am::InitializeForSystemMenu();
if (LastNnResult.IsFailure()){
//NN_LOG("%d",LastNnResult.GetDescription());
//nn::am::FinalizeForSystemMenu();
nn::am::FinalizeForLocalImporter();
return false;
}
LastNnResult = nn::am::GetProgramList(&numPrograms, &programId, 1, nn::fs::MEDIA_TYPE_CTRCARD);
if (LastNnResult.IsFailure()){
//NN_LOG("%d",LastNnResult.GetDescription());
//nn::am::FinalizeForSystemMenu();
nn::am::FinalizeForLocalImporter();
return false;
}
LastNnResult = nn::am::GetProductCode( (nn::ProductCode*)&PrdCode,nn::fs::MEDIA_TYPE_CTRCARD,programId);
//nn::am::FinalizeForSystemMenu();
nn::am::FinalizeForLocalImporter();
PrdCode[sizeof(nn::ProductCode)] = 0;//表示時のオーバラン対策
return LastNnResult.IsSuccess();
}
//マウント&アーカイブ情報の取得
myResult SaveData::Mount()
{
if (IsMounted)return RESULT_ALREADY_MOUNT;
#ifdef USE_SYS_SAVE
LastNnResult=nn::fs::MountSystemSaveData(sdataName,SysSaveId);
#else
//LastNnResult=nn::fs::MountSaveDataOnCard(sdataName);//FileSystemBasePrivate
LastNnResult = nn::fs::MountCtrCardSaveDataForCheck(sdataName);//ApiForHwCheck
#endif
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;
return RESULT_FAIL;
}
//システムセーブのデリート
//API実装までのテスト用データを消す用
#ifdef USE_SYS_SAVE
void SaveData::Delete()
{
LastNnResult=nn::fs::DeleteSystemSaveData(SysSaveId);
}
#endif
//ファイルリード
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;
//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();
}