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@254 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
parent
5adc064478
commit
da83077290
@ -29,7 +29,7 @@ SOURCES[] =
|
|||||||
./source/main.cpp
|
./source/main.cpp
|
||||||
./source/screen/screen.cpp
|
./source/screen/screen.cpp
|
||||||
../../common/savefile/savedata.cpp
|
../../common/savefile/savedata.cpp
|
||||||
../../common/savefile/sdmc.cpp
|
../../common/savefile/sdmcwo.cpp
|
||||||
../../common/savefile/savefile.cpp
|
../../common/savefile/savefile.cpp
|
||||||
../../common/gui/gui.cpp
|
../../common/gui/gui.cpp
|
||||||
../../common/shfnt.cpp
|
../../common/shfnt.cpp
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
#include <nn/fs/fs_Parameters.h>
|
#include <nn/fs/fs_Parameters.h>
|
||||||
#include "../../../common/savefile/savefile.h"
|
#include "../../../common/savefile/savefile.h"
|
||||||
#include "../../../common/savefile/savedata.h"
|
#include "../../../common/savefile/savedata.h"
|
||||||
#include "../../../common/savefile/sdmc.h"
|
#include "../../../common/savefile/sdmcwo.h"
|
||||||
#include "../../../common/common.h"
|
#include "../../../common/common.h"
|
||||||
#include "./screen/screen.h"
|
#include "./screen/screen.h"
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ myResult errRes;
|
|||||||
SaveData savedata;
|
SaveData savedata;
|
||||||
nn::os::LightEvent ejectEvnt(false);
|
nn::os::LightEvent ejectEvnt(false);
|
||||||
nn::os::LightEvent insEvnt(false);
|
nn::os::LightEvent insEvnt(false);
|
||||||
Sdmc exsave;
|
Sdmcwo exsave;
|
||||||
nn::os::LightEvent ejectEvntSd(false);
|
nn::os::LightEvent ejectEvntSd(false);
|
||||||
nn::os::LightEvent insEvntSd(false);
|
nn::os::LightEvent insEvntSd(false);
|
||||||
|
|
||||||
@ -178,113 +178,6 @@ bool TryDeleteDir()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------- Verifi
|
|
||||||
bool Verifi()
|
|
||||||
{
|
|
||||||
myResult res;
|
|
||||||
int ct=0,msize,rsize,i;
|
|
||||||
s64 total=0;
|
|
||||||
|
|
||||||
|
|
||||||
if (arcInfo.FileCount == 0)return true;//ファイル無し
|
|
||||||
|
|
||||||
//セーブデータのマウント
|
|
||||||
scr_Status("Mount SaveData",COLOR_YELLO);
|
|
||||||
res = savedata.Mount();
|
|
||||||
if(res != RESULT_OK)return false;
|
|
||||||
scr_Status("Mount SD",COLOR_YELLO);
|
|
||||||
res = exsave.Mount();
|
|
||||||
if(res != RESULT_OK)return false;
|
|
||||||
|
|
||||||
scr_Status("file compairing",COLOR_YELLO);
|
|
||||||
savedata.ResetPath();
|
|
||||||
s64 fsize;
|
|
||||||
res = RESULT_OK;
|
|
||||||
while(res==RESULT_OK){
|
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
|
||||||
res = savedata.GetPath(file_pathw);//パス取得
|
|
||||||
if (res != RESULT_OK)break;
|
|
||||||
if (file_pathw[0] == 0)break;//root then end
|
|
||||||
if (ct>=arcInfo.FileCount)
|
|
||||||
{
|
|
||||||
res = RESULT_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
|
||||||
scr_CountPerMax(ct,arcInfo.FileCount);//カウンタ表示
|
|
||||||
if (savedata.Open(file_pathw)==false)//カード上のファイル
|
|
||||||
{
|
|
||||||
res = RESULT_FAIL_OPEN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fsize = savedata.FileSize;
|
|
||||||
total += fsize;
|
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
|
||||||
if (exsave.Open(file_pathw)==false)//SDのファイル
|
|
||||||
{
|
|
||||||
if (exsave.OpenVnf(file_pathw)==false)//退避ファイルを探す
|
|
||||||
{
|
|
||||||
res = RESULT_FAIL_OPEN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msize=fsize;
|
|
||||||
while(fsize)
|
|
||||||
{
|
|
||||||
if(msize > FILEBUFF_SIZE * 2){//サイズが大きい場合にゲージ表示
|
|
||||||
scr_CountPerMax2(msize-fsize,msize,0);
|
|
||||||
}
|
|
||||||
if (fsize>FILEBUFF_SIZE)
|
|
||||||
{
|
|
||||||
rsize = FILEBUFF_SIZE;
|
|
||||||
fsize -= FILEBUFF_SIZE;
|
|
||||||
}else{
|
|
||||||
rsize = fsize;
|
|
||||||
fsize = 0;
|
|
||||||
}
|
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
|
||||||
if(savedata.Read(fileBuffer,rsize) != rsize )//カード
|
|
||||||
{ //中身のデータが作成サイズに満たない場合
|
|
||||||
//不明部分の処置は書出し時と合わせる
|
|
||||||
if(nn::fs::ResultVerificationFailed::Includes(savedata.LastNnResult))
|
|
||||||
{
|
|
||||||
for ( i = 0; i < rsize; i++)
|
|
||||||
{
|
|
||||||
fileBuffer[i] = 0;//0埋め
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
res = RESULT_FAIL_READ;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
|
||||||
if(exsave.Read(fileBuffer_ex,rsize) != rsize )//SD
|
|
||||||
{
|
|
||||||
res = RESULT_FAIL_READ;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
savedata.Close();
|
|
||||||
exsave.Close();
|
|
||||||
if (res != RESULT_OK)break;
|
|
||||||
if(isInsEject != InEx_None )break;//挿抜による中断
|
|
||||||
//比較
|
|
||||||
for (i=0;i<rsize;i++)if (fileBuffer[i]!=fileBuffer_ex[i]){
|
|
||||||
res = RESULT_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ct++;
|
|
||||||
}
|
|
||||||
savedata.Close();
|
|
||||||
exsave.Close();
|
|
||||||
savedata.Unmount();
|
|
||||||
exsave.Unmount();
|
|
||||||
|
|
||||||
return res == RESULT_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------- CARD to SD
|
//---------------------------------------------------------------------- CARD to SD
|
||||||
RetCode Card2Sd()
|
RetCode Card2Sd()
|
||||||
{
|
{
|
||||||
@ -336,7 +229,7 @@ RetCode Card2Sd()
|
|||||||
res = RESULT_OK;
|
res = RESULT_OK;
|
||||||
while(res==RESULT_OK){
|
while(res==RESULT_OK){
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
if(CheckInsExit())break;//挿抜による中断
|
||||||
res = savedata.GetPath(file_pathw);
|
res = savedata.GetPath(file_pathw);//パス取得
|
||||||
if (res != RESULT_OK)
|
if (res != RESULT_OK)
|
||||||
{
|
{
|
||||||
if (res == RESULT_DIR_LEVEL_OVER){
|
if (res == RESULT_DIR_LEVEL_OVER){
|
||||||
@ -350,7 +243,7 @@ RetCode Card2Sd()
|
|||||||
res = RESULT_FAIL_OPEN;
|
res = RESULT_FAIL_OPEN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (file_pathw[0] == 0)break;//root then end
|
if (file_pathw[0] == 0)break;//ルートなら終了
|
||||||
if (ct>=arcInfo.FileCount)
|
if (ct>=arcInfo.FileCount)
|
||||||
{
|
{
|
||||||
res = RESULT_FAIL;
|
res = RESULT_FAIL;
|
||||||
@ -384,8 +277,8 @@ RetCode Card2Sd()
|
|||||||
while(1){
|
while(1){
|
||||||
if (exsave.OpenW(file_pathw,fsize,&mkdir)==false)
|
if (exsave.OpenW(file_pathw,fsize,&mkdir)==false)
|
||||||
{
|
{
|
||||||
if(mkdir)//ディレクトリのみ作成
|
if(mkdir)//ディレクトリ作成のみ
|
||||||
{//深い場合に作成が多いと画面が止まるので
|
{//深いと作成に時間かかるので画面に変化つける
|
||||||
rev++;
|
rev++;
|
||||||
if (rev & 1)scr_MessOnCount2("Create Directry -");
|
if (rev & 1)scr_MessOnCount2("Create Directry -");
|
||||||
else scr_MessOnCount2("Create Directry |");
|
else scr_MessOnCount2("Create Directry |");
|
||||||
@ -396,8 +289,8 @@ RetCode Card2Sd()
|
|||||||
if (exsave.OpenVnfW(file_pathw,fsize)==false)//退避ファイル
|
if (exsave.OpenVnfW(file_pathw,fsize)==false)//退避ファイル
|
||||||
{
|
{
|
||||||
res = RESULT_FAIL_OPENW;
|
res = RESULT_FAIL_OPENW;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}else{
|
}else{
|
||||||
res = RESULT_FAIL_OPENW;
|
res = RESULT_FAIL_OPENW;
|
||||||
break;
|
break;
|
||||||
@ -423,7 +316,7 @@ RetCode Card2Sd()
|
|||||||
fsize = 0;
|
fsize = 0;
|
||||||
}
|
}
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
if(CheckInsExit())break;//挿抜による中断
|
||||||
if(savedata.Read(fileBuffer,rsize) != rsize )
|
if(savedata.Read(fileBuffer,rsize) != rsize )//リード
|
||||||
{
|
{
|
||||||
//中身のデータが作成サイズに満たない場合に検証エラーとなる対策
|
//中身のデータが作成サイズに満たない場合に検証エラーとなる対策
|
||||||
//読めないブロックは置き換える
|
//読めないブロックは置き換える
|
||||||
@ -441,7 +334,7 @@ RetCode Card2Sd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(CheckInsExit())break;//挿抜による中断
|
if(CheckInsExit())break;//挿抜による中断
|
||||||
if(exsave.Write(fileBuffer,rsize) != rsize )
|
if(exsave.Write(fileBuffer,rsize) != rsize )//ライト
|
||||||
{
|
{
|
||||||
res = RESULT_FAIL_WRITE;
|
res = RESULT_FAIL_WRITE;
|
||||||
break;
|
break;
|
||||||
@ -455,7 +348,6 @@ RetCode Card2Sd()
|
|||||||
savedata.Close();
|
savedata.Close();
|
||||||
exsave.CloseW();
|
exsave.CloseW();
|
||||||
}
|
}
|
||||||
|
|
||||||
savedata.Unmount();
|
savedata.Unmount();
|
||||||
exsave.Unmount();
|
exsave.Unmount();
|
||||||
|
|
||||||
@ -467,57 +359,39 @@ RetCode Card2Sd()
|
|||||||
}else{
|
}else{
|
||||||
if (res == RESULT_OK)
|
if (res == RESULT_OK)
|
||||||
{
|
{
|
||||||
if (ct != arcInfo.FileCount)//ファイル数に満たないパス検索終了
|
if (ct == arcInfo.FileCount)//ファイル数一致?
|
||||||
{//ディレクトリ情報かパス取得で失敗してると思われる
|
|
||||||
PutError(ERC_DEV_OTHER,ERC_EXEC);
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Verifi())//ベリファイ
|
|
||||||
{
|
{
|
||||||
if (exsave.WriteSys(&arcInfo))
|
if(exsave.WriteSys(&arcInfo))//フォーマット情報
|
||||||
{//最後に書き戻しに必要なパラメータファイルを記録
|
{
|
||||||
if(CheckInsExit()==false)
|
//成功
|
||||||
{
|
strcpy(sts,"output folder [ ");
|
||||||
if (exsave.GetInfo(&arcInfo_ex))
|
strcat(sts,exsave.DirName);//保存先
|
||||||
{ //リードチェック
|
strcat(sts," ]");
|
||||||
if ((arcInfo.DirEntry != arcInfo_ex.DirEntry) ||
|
scr_Status(sts,COLOR_WHITE);
|
||||||
(arcInfo.FileEntry != arcInfo_ex.FileEntry) ||
|
|
||||||
(arcInfo.DirCount != arcInfo_ex.DirCount) ||
|
scr_CountPerMax(ct,arcInfo.FileCount);//ファイル数
|
||||||
(arcInfo.FileCount != arcInfo_ex.FileCount) ||
|
scr_CountPerMax2(0,0,total);//総サイズ
|
||||||
(arcInfo.Dup != arcInfo_ex.Dup))res = RESULT_FAIL_WRITE;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
}else res = RESULT_FAIL;
|
}else{
|
||||||
}else res = RESULT_FAIL_WRITE;
|
NN_LOG("file count error\n");
|
||||||
}else res = RESULT_FAIL_VERIFI;
|
res = RESULT_FAIL;
|
||||||
}
|
|
||||||
if (res != RESULT_OK)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}else
|
|
||||||
{
|
|
||||||
strcpy(sts,"output folder [ ");
|
|
||||||
strcat(sts,exsave.DirName);//保存先
|
|
||||||
strcat(sts," ]");
|
|
||||||
scr_Status(sts,COLOR_WHITE);
|
|
||||||
|
|
||||||
scr_CountPerMax(ct,arcInfo.FileCount);//ファイル数
|
|
||||||
scr_CountPerMax2(0,0,total);//総サイズ
|
|
||||||
return SUCCESS;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//失敗
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return ERROR;
|
return ERROR;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mkdir;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------- セーブデータの情報取得
|
//--------------------------------------------------------------- セーブデータの情報取得
|
||||||
//呼ぶ前に tmerr のクリアを忘れない事
|
//呼ぶ前に tmerr のクリアを忘れない事
|
||||||
|
|||||||
@ -19,7 +19,8 @@ int GetPosDelmLast(wchar_t *s,int top);
|
|||||||
//情報ファイルのバージョン
|
//情報ファイルのバージョン
|
||||||
#define INFO_VERSION 1
|
#define INFO_VERSION 1
|
||||||
|
|
||||||
//SDバックアップに同梱する情報
|
//フォーマット情報
|
||||||
|
//SDバックアップの場合は同梱する
|
||||||
//変更の際は後方互換とれるよう追加のみとする
|
//変更の際は後方互換とれるよう追加のみとする
|
||||||
struct tArcInfo{
|
struct tArcInfo{
|
||||||
u32 DirEntry,FileEntry;
|
u32 DirEntry,FileEntry;
|
||||||
|
|||||||
307
trunk/CardSaveData/common/savefile/sdmcwo.cpp
Normal file
307
trunk/CardSaveData/common/savefile/sdmcwo.cpp
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Horizon/tools/SaveDataFiler で読めるファイルを作成
|
||||||
|
|
||||||
|
ライトのみアーカイブ使用
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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のフォーマットに合わせる
|
||||||
|
//------------ sources\tools\NandFiler\nandf_Dialog.h 参照
|
||||||
|
const wchar_t *SDMC_ROOT_DIR_NAME = L"/filer";
|
||||||
|
|
||||||
|
struct FormatParameters
|
||||||
|
{
|
||||||
|
size_t m_LimitSize;
|
||||||
|
size_t m_MaxDir;
|
||||||
|
size_t m_MaxFile;
|
||||||
|
s32 m_IconSize;
|
||||||
|
bit8 *m_pIconData;
|
||||||
|
bool m_Duplicate;
|
||||||
|
|
||||||
|
FormatParameters()
|
||||||
|
: m_LimitSize(0),m_IconSize(0), m_pIconData(0) {}
|
||||||
|
//オリジナルはLinitSize不定
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AdditionalInfo
|
||||||
|
{
|
||||||
|
bit64 m_Version;
|
||||||
|
bit64 m_Id;
|
||||||
|
bit64 m_Reserved[128];//オリジナルは乱数埋
|
||||||
|
AdditionalInfo()
|
||||||
|
: m_Version(0), m_Id(0) {}
|
||||||
|
};
|
||||||
|
//--------------------------- nandf_util.cpp 参照
|
||||||
|
std::wstring Sdmcwo::GetDateName()
|
||||||
|
{
|
||||||
|
nn::fnd::DateTime tm = nn::fnd::DateTime::GetNow();
|
||||||
|
|
||||||
|
std::wostringstream name;
|
||||||
|
name << std::setw(4) << std::setfill(L'0') << tm.GetYear()
|
||||||
|
<< std::setw(2) << std::setfill(L'0') << tm.GetMonth()
|
||||||
|
<< std::setw(2) << std::setfill(L'0') << tm.GetDay()
|
||||||
|
<< std::setw(2) << std::setfill(L'0') << tm.GetHour()
|
||||||
|
<< std::setw(2) << std::setfill(L'0') << tm.GetMinute()
|
||||||
|
<< std::setw(2) << std::setfill(L'0') << tm.GetSecond();
|
||||||
|
|
||||||
|
|
||||||
|
//char型 :表示で使う
|
||||||
|
wcstombs(DirName, name.str().c_str(), 14);
|
||||||
|
DirName[14] = 0;
|
||||||
|
return name.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bit64 ChangeId(bit64 id, bit64 key)
|
||||||
|
{
|
||||||
|
return id ^ key ^ 0xce8a4d52f7105339;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------
|
||||||
|
|
||||||
|
//ディレクトリ作成
|
||||||
|
//ディレクトリオープンも出来ないので、ライト試行
|
||||||
|
bool CreateDir(const wchar_t *dirName)
|
||||||
|
{
|
||||||
|
nn::Result result = nn::fs::TryCreateDirectory(dirName);
|
||||||
|
if(result.IsSuccess())return true;
|
||||||
|
return nn::fs::ResultAlreadyExists::Includes(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//SDMCにライト専用アーカイブ
|
||||||
|
//ディレクトリもファイルも読めない
|
||||||
|
|
||||||
|
//直前のCreateで作成した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();
|
||||||
|
}
|
||||||
|
|
||||||
|
//全削除
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//保存先のディレクトリ作成
|
||||||
|
//成功時はマウント状態
|
||||||
|
bool Sdmcwo::Create()
|
||||||
|
{
|
||||||
|
std::wostringstream woss;
|
||||||
|
created = false;
|
||||||
|
if (Mount() == RESULT_FAIL_MOUNT)return false;
|
||||||
|
|
||||||
|
woss << devName << SDMC_ROOT_DIR_NAME;//sdmc:/filer
|
||||||
|
if (CreateDir(woss.str().c_str()))
|
||||||
|
{
|
||||||
|
woss << L"/" << L"UserSaveData";//sdmc:/filer/UserSaveData
|
||||||
|
if ( CreateDir(woss.str().c_str()) )
|
||||||
|
{
|
||||||
|
DateDirName = GetDateName();
|
||||||
|
woss << L"/" << DateDirName;//sdmc:/filer/UserSaveData/YearMtDtHrMtSc
|
||||||
|
if ( CreateDir(woss.str().c_str()) )
|
||||||
|
{
|
||||||
|
wcscpy(latestPath_w,woss.str().c_str());
|
||||||
|
created = true;//日時ディレクトリ作成フラグ
|
||||||
|
//コピー先ルート
|
||||||
|
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());//格納先パス保存
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Unmount();
|
||||||
|
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(LastNnResult.GetDescription()!=nn::fs::DESCRIPTION_DBM_DIRECTORY_NOT_FOUND)return false;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//パス名エラーで作成できない場合の退避先
|
||||||
|
//例:FAT規約違反、"/ test"->"/test"、SD格納先ディレクトリでパス長オーバー
|
||||||
|
bool Sdmcwo::OpenVnfW(wchar_t *path,s64 size)
|
||||||
|
{
|
||||||
|
s32 sz;
|
||||||
|
tVnf vnf;
|
||||||
|
//パス名&オフセット用ファイル
|
||||||
|
wcscpy(expath_w,latestPath_w);
|
||||||
|
wcscat(expath_w,L"/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())
|
||||||
|
{
|
||||||
|
wcscpy(vnf.path,path);
|
||||||
|
vnf.size = size;
|
||||||
|
LastNnResult = writer.TryWrite(&sz,&vnf,sizeof(tVnf));//ヘッダ格納
|
||||||
|
}
|
||||||
|
if (LastNnResult.IsFailure())
|
||||||
|
{
|
||||||
|
writer.Finalize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//情報ファイル
|
||||||
|
//
|
||||||
|
bool Sdmcwo::WriteSys(tArcInfo *ifo)
|
||||||
|
{//SaveFilerで読むためのファイル
|
||||||
|
std::wostringstream woss;
|
||||||
|
if (Mount() == RESULT_FAIL_MOUNT)return false;
|
||||||
|
woss << latestPath_w << L"/00000000";
|
||||||
|
// 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()
|
||||||
|
{
|
||||||
|
CloseW();
|
||||||
|
Unmount();
|
||||||
|
}
|
||||||
|
//デストラクタ
|
||||||
|
Sdmcwo::~Sdmcwo()
|
||||||
|
{
|
||||||
|
Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
61
trunk/CardSaveData/common/savefile/sdmcwo.h
Normal file
61
trunk/CardSaveData/common/savefile/sdmcwo.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Horizon
|
||||||
|
|
||||||
|
Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//ライトのみアーカイブ使用
|
||||||
|
|
||||||
|
#ifndef sdmcwo_H_
|
||||||
|
#define sdmcwo_H_
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <nn/types.h>
|
||||||
|
#include <nn/Result.h>
|
||||||
|
#include "../my_defs.h"
|
||||||
|
#include "savefile.h"
|
||||||
|
|
||||||
|
class Sdmcwo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
s64 FileSize;
|
||||||
|
nn::Result LastNnResult;
|
||||||
|
char DirName[16];
|
||||||
|
private:
|
||||||
|
tArcInfo m_info;
|
||||||
|
std::wstring GetDateName();
|
||||||
|
std::wstring DateDirName;
|
||||||
|
nn::fs::FileWriter writer;
|
||||||
|
public:
|
||||||
|
Sdmcwo();
|
||||||
|
~Sdmcwo();
|
||||||
|
void Finalize();
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
//Fat違反パス格納データのヘッダ
|
||||||
|
//直後にデータ配置
|
||||||
|
//Header+Data,、Header+Data ... と連続して追記してゆく
|
||||||
|
typedef struct{
|
||||||
|
wchar_t path[MAX_PATH_LENGTH];
|
||||||
|
s64 size;
|
||||||
|
}tVnf;
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -971,7 +971,7 @@ bool Test6_V()
|
|||||||
strcat(fname,"_.bin");//data:/base_/base_.bin
|
strcat(fname,"_.bin");//data:/base_/base_.bin
|
||||||
|
|
||||||
i =0;
|
i =0;
|
||||||
while(kinsi[i] != '/')//末尾スラッシュは名無しでエラー
|
while(kinsi[i] != 0)//末尾スラッシュは名無しでエラー
|
||||||
{
|
{
|
||||||
c = kinsi[i];
|
c = kinsi[i];
|
||||||
fname[pos] = c;
|
fname[pos] = c;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user