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@45 385bec56-5757-e545-9c3a-d8741f4650f1
250 lines
8.0 KiB
C++
250 lines
8.0 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: FileTransfer.cpp
|
|
|
|
Copyright 2009 Nintendo. 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.
|
|
|
|
$Rev$
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include "FileTransfer.h"
|
|
#include <vector>
|
|
|
|
namespace common
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
u64 s_TotalFileSize;
|
|
u64 s_FinishedFileSize = 0;
|
|
u64 s_Progress = 0;
|
|
|
|
}
|
|
|
|
nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, u32& fileSize)
|
|
{
|
|
nn::fs::FileInputStream fis;
|
|
nn::fs::Directory dir;
|
|
nn::Result result;
|
|
std::vector<nn::fs::DirectoryEntry> entryList; //カレントディレクトリのエントリ一覧を格納
|
|
std::vector<nn::fs::DirectoryEntry>::iterator entryIndex;
|
|
|
|
result = dir.TryInitialize(currentDirectory.c_str());
|
|
|
|
if(result.IsSuccess())
|
|
{
|
|
nn::fs::DirectoryEntry entry;
|
|
s32 numEntry;
|
|
for(;;)
|
|
{
|
|
result = dir.TryRead(&numEntry, &entry, 1);
|
|
if(result.IsFailure())
|
|
{
|
|
dir.Finalize();
|
|
return result;
|
|
}
|
|
if(numEntry == 0)
|
|
{
|
|
// カレントディレクトリを閉じる
|
|
dir.Finalize();
|
|
|
|
// カレントディレクトリの子を開く
|
|
for(entryIndex = entryList.begin(); entryIndex != entryList.end(); entryIndex++)
|
|
{
|
|
if(entryIndex->attributes.isDirectory)
|
|
{
|
|
CalculateFileNum(currentDirectory + std::wstring(entryIndex->entryName) + std::wstring(L"/"), fileNum, fileSize);
|
|
}
|
|
}
|
|
|
|
return nn::ResultSuccess();
|
|
}
|
|
|
|
entryList.push_back(entry);
|
|
fileNum++;
|
|
fileSize+= entry.entrySize;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NN_LOG("failed initialize directory\n");
|
|
dir.Finalize();
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
// ディレクトリ間のコピー
|
|
// アーカイブ越しのコピーが可能
|
|
// アーカイブにマウントした状態で呼び出す必要あり
|
|
// 書き込み先のディレクトリはあらかじめ消去しておくこと。
|
|
// 引数はスラッシュ付き
|
|
bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf, const size_t bufSize)
|
|
{
|
|
nn::fs::Directory from_dir;
|
|
nn::fs::DirectoryEntry entry;
|
|
s32 numread = 0;
|
|
std::wostringstream target_from;
|
|
std::wostringstream target_to;
|
|
bool ret_value = true;
|
|
|
|
nn::Result result = from_dir.TryInitialize(from_path);
|
|
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
return false;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
result = from_dir.TryRead(&numread, &entry, 1);
|
|
if (result.IsFailure() || numread != 1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
target_from.str(L"");
|
|
target_from.clear(std::stringstream::goodbit);
|
|
target_from << from_path << entry.entryName;
|
|
|
|
target_to.str(L"");
|
|
target_to.clear(std::stringstream::goodbit);
|
|
target_to << to_path << entry.entryName;
|
|
|
|
// ディレクトリの場合
|
|
if (entry.attributes.isDirectory)
|
|
{
|
|
// ディレクトリ作成
|
|
NN_LOG("Create Directory %ls\n", target_to.str().c_str());
|
|
result = nn::fs::TryCreateDirectory(target_to.str().c_str());
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
}
|
|
else
|
|
{
|
|
target_from << L"/";
|
|
target_to << L"/";
|
|
// 再帰処理
|
|
if (!CopyDirectory(target_from.str().c_str(), target_to.str().c_str(), buf, bufSize))
|
|
{
|
|
ret_value = false;
|
|
}
|
|
}
|
|
}
|
|
// ファイルの場合
|
|
else
|
|
{
|
|
// ファイル作成
|
|
nn::fs::FileInputStream from_file;
|
|
nn::fs::FileOutputStream to_file;
|
|
s64 filesize;
|
|
s32 readsize;
|
|
s32 writesize;
|
|
|
|
NN_LOG("Copy File %ls\n", target_from.str().c_str());
|
|
|
|
// 読み込み対象ファイル開く
|
|
result = from_file.TryInitialize(target_from.str().c_str());
|
|
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
}
|
|
else
|
|
{
|
|
// 読み込み対象ファイルのサイズ取得
|
|
result = from_file.TryGetSize(&filesize);
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
}
|
|
else
|
|
{
|
|
// 書き込み対象ファイル作成
|
|
result = nn::fs::TryCreateFile(target_to.str().c_str(), filesize);
|
|
result = to_file.TryInitialize(target_to.str().c_str(), false);
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
}
|
|
else
|
|
{
|
|
while (1)
|
|
{
|
|
result = from_file.TryRead(&readsize, buf, bufSize);
|
|
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (readsize == 0)
|
|
{
|
|
result = to_file.TryFlush();
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
result = to_file.TryWrite(&writesize, buf, readsize, false);
|
|
s_FinishedFileSize += readsize;
|
|
s_Progress = s_FinishedFileSize * 100/ s_TotalFileSize;
|
|
NN_LOG("finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress);
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
ret_value = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
to_file.Finalize();
|
|
}
|
|
}
|
|
from_file.Finalize();
|
|
}
|
|
}
|
|
|
|
from_dir.Finalize();
|
|
return ret_value;
|
|
}
|
|
|
|
u32 GetProgress()
|
|
{
|
|
return s_Progress;
|
|
}
|
|
|
|
void InitializeTransferProgress(u64 totalSize)
|
|
{
|
|
s_TotalFileSize = totalSize;
|
|
s_FinishedFileSize = 0;
|
|
}
|
|
|
|
}
|