diff --git a/trunk/CardSaveData/Mover/body/source/main.cpp b/trunk/CardSaveData/Mover/body/source/main.cpp index a35f541..6ccd878 100644 --- a/trunk/CardSaveData/Mover/body/source/main.cpp +++ b/trunk/CardSaveData/Mover/body/source/main.cpp @@ -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; diff --git a/trunk/CardSaveData/ToSD/body/source/main.cpp b/trunk/CardSaveData/ToSD/body/source/main.cpp index 70923f7..0f1e2fb 100644 --- a/trunk/CardSaveData/ToSD/body/source/main.cpp +++ b/trunk/CardSaveData/ToSD/body/source/main.cpp @@ -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; diff --git a/trunk/CardSaveData/ToSD/body/source/screen/screen.cpp b/trunk/CardSaveData/ToSD/body/source/screen/screen.cpp index bade6fa..90a5531 100644 --- a/trunk/CardSaveData/ToSD/body/source/screen/screen.cpp +++ b/trunk/CardSaveData/ToSD/body/source/screen/screen.cpp @@ -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(); +} + + //smF void scr_ConfirmDbg(char *str) diff --git a/trunk/CardSaveData/ToSD/body/source/screen/screen.h b/trunk/CardSaveData/ToSD/body/source/screen/screen.h index a44ebe4..1e8f7dc 100644 --- a/trunk/CardSaveData/ToSD/body/source/screen/screen.h +++ b/trunk/CardSaveData/ToSD/body/source/screen/screen.h @@ -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(); diff --git a/trunk/CardSaveData/common/common.cpp b/trunk/CardSaveData/common/common.cpp index 059e87f..f887565 100644 --- a/trunk/CardSaveData/common/common.cpp +++ b/trunk/CardSaveData/common/common.cpp @@ -3,14 +3,49 @@ #include "common.h" #include "sleep.h" #include "demo.h" +#include +#include +#include extern demo::RenderSystemDrawing s_RenderSystem; extern nn::fnd::ExpHeap appHeap; extern uptr heapForGx; -bool prohibitHome = false;// HOME {^֎~ +//G[\p񐶐 +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;//L[ .. 肦Ȃ + else if (desc < 180 ) code = ERC_READ;//t@C‚Ȃs + else if (desc < 200 ) code = ERC_WRITE_OW;//t@C .. 폜s? + 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;//ANZXG[ + else if (desc < 390 ) code = ERC_FORMAT;//tH[}bgG[ + else if (desc < 400 ) code = ERC_SDK_VERIFI;// + else if (desc < 580 ) code = ERC_ROM;//ROMG[ + else if (desc < 590 ) code = ERC_RETRY;//gCv + else if (desc < 600 ) code = ERC_UNKNOWN;//CCI,CXIs .. 肦Ȃ + else if (desc < 900 ) code = ERC_EXEC;//sG[A\tgoO + 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 {^֎~ // t@CVXeƑJڂX[vƂ̔rɗp //nn::os::CriticalSection g_SleepCS; // HOME {^Jڂƃt@CVXe̔rɗpi蓮Zbgj diff --git a/trunk/CardSaveData/common/common.h b/trunk/CardSaveData/common/common.h index 730fb6c..b2a8566 100644 --- a/trunk/CardSaveData/common/common.h +++ b/trunk/CardSaveData/common/common.h @@ -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 diff --git a/trunk/CardSaveData/common/my_defs.h b/trunk/CardSaveData/common/my_defs.h index b6a9ee7..0e2401e 100644 --- a/trunk/CardSaveData/common/my_defs.h +++ b/trunk/CardSaveData/common/my_defs.h @@ -85,6 +85,7 @@ typedef enum { RESULT_BAD_PARAM, RESULT_DIR_LEVEL_OVER, RESULT_PATH_LENGTH_OVER, + RESULT_DEVICE_FULL, RESULT_MAX }myResult; diff --git a/trunk/CardSaveData/common/savefile/membak.cpp b/trunk/CardSaveData/common/savefile/membak.cpp index cc54973..3d66da8 100644 --- a/trunk/CardSaveData/common/savefile/membak.cpp +++ b/trunk/CardSaveData/common/savefile/membak.cpp @@ -123,6 +123,7 @@ void MemBak::CloseSysW() { } + //VXet@CCg bool MemBak::WriteSys(tArcInfo *pinfo) { diff --git a/trunk/CardSaveData/common/savefile/savedata.cpp b/trunk/CardSaveData/common/savefile/savedata.cpp index 59cc4f3..2e4e010 100644 --- a/trunk/CardSaveData/common/savefile/savedata.cpp +++ b/trunk/CardSaveData/common/savefile/savedata.cpp @@ -7,153 +7,6 @@ #include #include -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;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) -{ -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;nFileEntry,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(); -} - diff --git a/trunk/CardSaveData/common/savefile/savedata.h b/trunk/CardSaveData/common/savefile/savedata.h index 4b15aaa..3a1c9dc 100644 --- a/trunk/CardSaveData/common/savefile/savedata.h +++ b/trunk/CardSaveData/common/savefile/savedata.h @@ -18,47 +18,23 @@ #include #include -//#include #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();}; }; diff --git a/trunk/CardSaveData/common/savefile/savefile.cpp b/trunk/CardSaveData/common/savefile/savefile.cpp index 1651f0a..3da0b7e 100644 --- a/trunk/CardSaveData/common/savefile/savefile.cpp +++ b/trunk/CardSaveData/common/savefile/savefile.cpp @@ -16,6 +16,15 @@ int GetPosDelmLast(wchar_t *s,int top) return 0; } +//pX +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); +} + //pX`FbN for SD //fs֐ňG[(INVALID_ARGUMENT)ɂȂȂ̂`FbN @@ -39,3 +48,245 @@ bool CheckPath(wchar_t *s) } + + +//-------------- Class SaveFileWrite +//fBNg쐬̃I[v +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(); + } + //fBNgȂ΃fBNg쐬 + pos = GetPosDelmLast(pathw_w,RootLength);//t@C݂fBNg + if (pos <= 0)return false;//rootpXs + wcscpy(pathw_w2,pathw_w);//[NɃRs[ + while (LastNnResult.IsFailure()){//fBNg쐬ł܂ők + if(nn::fs::ResultNotFound::Includes(LastNnResult)==false)return false; + pos2 = GetPosDelmLast(pathw_w2,RootLength);//EʒuT + if (pos2 == 0)return false;//rootB + pathw_w2[pos2] = 0;//E܂ō폜 () dir1/dir2/file -> dir1/dir2 -> dir1 + LastNnResult = nn::fs::TryCreateDirectory(pathw_w2); + } + //쐬fBNgƉʎ~܂̂ŁA쐬Ƃɔ + *mkdir = true; // AlFfalse mkdir=true ȂfBNg쐬̂ + return false; +} + +//fBNg쐬ȂI[vA݂ꍇ͒NjL +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);//NjL + }else LastNnResult = writer.TryInitialize(pathw_w,true);//VK + if (LastNnResult.IsFailure()) + { + writer.Finalize(); + return false; + } + return true; +} + + +//fBNg쐬ȂI[v +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(); +} + + + +//N[Y +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; +} + + +//fBNg쐬 +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(); +} + + +//t@C[h +s32 SaveFileRead::Read(char *buffer,size_t size) +{ + s32 ct; + LastNnResult = reader.TryRead(&ct,(void*)buffer,size); + if(LastNnResult.IsFailure())ct=0; + return ct; +} + +//݃`FbN +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;nMAX_PATH_LENGTH - 1)return RESULT_PATH_LENGTH_OVER; + wcscat(path,dcEntryl.entryName); + return RESULT_OK; + } + } + } + +} + + +//A[JCu̎擾 +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 #include #include +#include "../my_defs.h" +#include +#include -//APIgpăA[JCu擾 -#define INFO_API_USE 1 - -//J[h̕ςɃVXeZ[ugp(APIΉ܂ł̎b) -//#define USE_SYS_SAVE 1 - -//SDۑ -//#define BKUP_NOTMEM 1 - -int GetPosDelmLast(wchar_t *s,int top); - -//t@C̃o[W -#define INFO_VERSION 1 - -//tH[}bg -//SDobNAbv̏ꍇ͓ -//ύX̍ۂ͌݊Ƃ悤lĵ݂Ƃ -struct tArcInfo{ - u32 DirEntry,FileEntry; - u32 DirCount,FileCount; - bool Dup; - u8 Ver;//o[W - char Pcode[20];//product code save,exsaveNXPrdCodeTCYȂ - u8 padding[2];//pfBO - tArcInfo() - : Ver(INFO_VERSION){} -}; +//******************************** defines ********** //pX :SDK̓A[JCu253 -//A[JCuSDi[fBNg̗]TƂ +//A[JCuSDi[fBNg̗]T݂Ƃ #define MAX_PATH_LENGTH 512 //pXKw +//t@CɎgpA"/"+1ŒZȂ̂128ŏ\ #define MAX_LEVEL 128 +//******************************** functions ********** //pX`FbN //FATᔽ̔pXy[X邩`FbN //A\񖼁ApXAPIG[(INVALID_ARGUMENT)Ŕ bool CheckPath(wchar_t *s); +//f~^("/")ʒuԂ +int GetPosDelmLast(wchar_t *s,int top); + +//pX +void ChainPath(wchar_t *p1,wchar_t *p2); + + +//******************************** Types ********** +//Z[uɊւ +#define INFO_VERSION 0 +struct tArcInfo{ + u32 DirEntry,FileEntry;//tH[}bg + u32 DirCount,FileCount;//o^ + char Pcode[20];//product code SDK̃TCYȂ + bool Dup;//2d + u8 Ver; + u8 yobi;//pfBO +}; + +//******************************** Class *************** +class SaveFileBase +{ +public: + nn::Result LastNnResult; +protected: + wchar_t root_w[MAX_PATH_LENGTH];//pX(foCX) + wchar_t path_w[MAX_PATH_LENGTH];//pX + wchar_t pathw_w[MAX_PATH_LENGTH];//[N + wchar_t pathw_w2[MAX_PATH_LENGTH]; + s32 RootLength; + wchar_t *pPathTop; + char devName[16]; + bool IsMounted; + char dumy[3]; +public: + + //pXݒ + 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();}; +}; + +//Cg +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); +}; + +//[h +class SaveFileRead :public virtual SaveFileBase +{ +public: + s64 FileSize; +private: + int dc_readed[MAX_LEVEL];//[hς݃Gg + wchar_t pathu_w[MAX_LEVEL][MAX_PATH_LENGTH];//pX + 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 diff --git a/trunk/CardSaveData/common/savefile/sdmcwo.cpp b/trunk/CardSaveData/common/savefile/sdmcwo.cpp index 9016dd4..b32d1cf 100644 --- a/trunk/CardSaveData/common/savefile/sdmcwo.cpp +++ b/trunk/CardSaveData/common/savefile/sdmcwo.cpp @@ -15,17 +15,6 @@ #include #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(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(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(); } diff --git a/trunk/CardSaveData/common/savefile/sdmcwo.h b/trunk/CardSaveData/common/savefile/sdmcwo.h index a6fe321..03bb491 100644 --- a/trunk/CardSaveData/common/savefile/sdmcwo.h +++ b/trunk/CardSaveData/common/savefile/sdmcwo.h @@ -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違反パス格納データのヘッダ