Пример #1
0
void WriteToLog(String S) {
	HANDLE LogFile;
	String LogPath;
	String LogFileName;
	DWORD dwSize;
	AnsiString SS;
	TDateTime DateTime;
	LPDWORD NumberOfBytesWritten = new DWORD;

	try { // except
		DateTime = Now();

		LogPath = ExtractFilePath(Application->ExeName) + LoadStr(IDS_LOG_PATH);
		if (!DirectoryExists(LogPath))
			CreateDir(LogPath);

		LogFileName = IncludeTrailingPathDelimiter(LogPath) +
			ChangeFileExt(ExtractFileName(Application->ExeName),
			LoadStr(IDS_LOG_EXT));

		LogFile = CreateFile(LogFileName.w_str(), GENERIC_READ, FILE_SHARE_READ,
			NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

		dwSize = 0;
		if (LogFile != INVALID_HANDLE_VALUE) {
			dwSize = GetFileSize(LogFile, NULL);
			CloseHandle(LogFile);
		}

		if (dwSize > MaxLogSize) {
			String NewFileName = IncludeTrailingPathDelimiter(LogPath) +
				OnlyFileName(Application->ExeName) + SPACE + FormatDateTime
				(LoadStr(IDS_DATETIME_FORMAT_FILENAME), DateTime) +
				LoadStr(IDS_LOG_EXT);
			MoveFile(LogFileName.w_str(), NewFileName.w_str());
		}

		LogFile = CreateFile(LogFileName.w_str(), GENERIC_WRITE,
			FILE_SHARE_READ, NULL, OPEN_ALWAYS,
			FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_COMPRESSED, 0);

		if (LogFile != INVALID_HANDLE_VALUE) {
			SS = AnsiString(FormatDateTime(LoadStr(IDS_DATETIME_FORMAT_LOG),
				DateTime) + "; " + AnsiReplaceStr(S, sLineBreak, SPACE) +
				sLineBreak);

			if (SetFilePointer(LogFile, 0, NULL,
				FILE_END) != INVALID_SET_FILE_POINTER)
				WriteFile(LogFile, SS.c_str(), SS.Length(),
				NumberOfBytesWritten, NULL);

			CloseHandle(LogFile);
		}
	}
	catch (...) {
	}
}
Пример #2
0
TStringList GetFileList(wxString folder, const wxString& mask, bool includeFullFolderPath)
{
	TStringList result;
	wxString FName;
	if (wxDir::Exists(folder) == false)
	{
		return result;
	}
	wxDir dir(folder);
	if (dir.GetFirst(&FName,mask,wxDIR_FILES))
	{
		do
		{
			if (includeFullFolderPath)
			{
				wxString FullFileName = IncludeTrailingPathDelimiter(folder) + FName;
				result.Add(FullFileName);
			}
			else
			{
				result.Add(FName);
			}
		} while(dir.GetNext(&FName));
	}
	return result;
}
Пример #3
0
void __fastcall TFireDAC_SQLiteForm::FireTaskListBeforeConnect(TObject *Sender)
{
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR)
	FireTaskList->Params->Values["Database"] = IncludeTrailingPathDelimiter(
		System::Ioutils::TPath::GetDocumentsPath()) + "tasks.s3db";
#else
	FireTaskList->Params->Values["Database"] = "tasks.s3db";
#endif
}
Пример #4
0
String __fastcall GetAudioFileName(const String AFileName)
{
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR)
	return IncludeTrailingPathDelimiter(System::Ioutils::TPath::GetDocumentsPath()) +
		AFileName;
#else
	return  AFileName;
#endif
}
Пример #5
0
void TGuiToProfile::_destination()
{
	if (!f_Main->fr_Destination->ed_Directory->Text.IsEmpty())
		f_Main->fr_Destination->ed_Directory->Text
            = IncludeTrailingPathDelimiter(f_Main->fr_Destination->ed_Directory->Text);
	PProfile->config.Destination->pDir->value			   	= f_Main->fr_Destination->ed_Directory->Text.c_str();
	PProfile->config.Destination->bAutoCreateDir->value		= f_Main->fr_Destination->cb_AutoCreateDir->Checked;
	PProfile->config.Destination->tNameTemplate->value	   	= f_Main->fr_Destination->ed_NameTemplate->Text.c_str();
	PProfile->config.Destination->bAppendExtension->value 	= f_Main->fr_Destination->cb_AppendExtension->Checked;
}
Пример #6
0
void TGuiToProfile::_sourceRootDirList()
{
	PProfile->sourceRootDirList.clear();

	TTreeNode* node = f_Main->fr_Source->tv_Dirs->Items->GetFirstNode();
	while (node)
	{
		PProfile->sourceRootDirList.push_back(IncludeTrailingPathDelimiter(node->Text));
		node = node->getNextSibling();
	}
}
Пример #7
0
void __fastcall TFrameDestination::bt_BrowseDirClick(TObject *Sender)
{
	ecc::TBrowseForDirectory bd(PGlobals->UseNewUIOnBFD);
	bd.Handle 		= Handle;
	bd.Directory	= _formattedDestDir(ed_Directory->Text);
	bd.Title 		= _("Choose Destination Directory:");
	if (bd.Execute())
	{
		ed_Directory->Text = IncludeTrailingPathDelimiter(bd.Directory);
		GuiToProfile.setModified(true);
	}
}
Пример #8
0
//---------------------------------------------------------------------------
void __fastcall TVideoPlayBackForm::videoBtnClick(TObject *Sender)
{
  /*Under Project-Deployment, we added the media file and set the remote path.
  When the program starts, everything in the directory that is set under remote path is
  copied over to the Documents folder on the device. The MediaPlayer loads the file from
  the Documents folder*/
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || defined(__ANDROID__)
	MediaPlayer1->FileName =
		IncludeTrailingPathDelimiter(System::Ioutils::TPath::GetDocumentsPath()) + "Ocean.mp4";
#endif
	MediaPlayer1->Play();
}
//===========================================================================
//ディスクの空き容量を調べる
//===========================================================================
__int64 __fastcall TAttacheCaseFileDecrypt1::GetDiskFreeSpaceNum(String FilePath)
{

int i;
int flag;

__int64 FreeSpace;

String DriveName = ExtractFileDrive(FilePath)+":";
String DirPath = IncludeTrailingPathDelimiter(ExtractFileDir(FilePath));

OSVERSIONINFO ovi;   // バージョン情報を格納する構造体
ovi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

// バージョン情報取得
GetVersionEx( (LPOSVERSIONINFO)&ovi );

// Windows95 OSR2以前
if( ( ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
		&& ( int( ovi.dwBuildNumber & 0xffff ) <= 1000 ) ){

	DWORD SCluster,BSector,FCluster,TCluster;

	if ( GetDiskFreeSpaceW(String(DriveName).c_str(), &SCluster, &BSector, &FCluster, &TCluster) > 0){
		FreeSpace = SCluster*BSector*FCluster;
	}
	else{
		//ネットワークサーバ上は取得できずエラーとなる
		FreeSpace = -1;
	}

}
// OSR2以降~
else{

	ULARGE_INTEGER pqwFreeCaller;
	ULARGE_INTEGER pqwTot;
	ULARGE_INTEGER pqwFree;

	if(::GetDiskFreeSpaceExW(String(DirPath).c_str(), &pqwFreeCaller, &pqwTot, &pqwFree)){
		//64bit Integerで返す
		FreeSpace = pqwFreeCaller.QuadPart;
	}
	else{
		FreeSpace = -1;
	}

}

return(FreeSpace);

}//end GetDiskFreeSpaceNum;
Пример #10
0
TStringList GetFolderList(wxString baseFolder, bool includeFullFolderPath)
{
  TStringList result;
	wxString FName;
		wxDir dir(baseFolder);
	if (dir.GetFirst(&FName,wxEmptyString,wxDIR_DIRS))
	{
		do
		{
			if (includeFullFolderPath)
			{
				wxString FullDirName = IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(baseFolder) + FName);
				result.Add(FullDirName);
			}
			else
			{
				result.Add(FName);
      }
		} while(dir.GetNext(&FName));
	}
	return result;
}
Пример #11
0
void TGuiToProfile::sourceDirLists()
{
	_sourceRootDirList();
	PProfile->excludeDirList.clear();
	PProfile->includeDirList.clear();
	PProfile->excludeTreeList.clear();
	PProfile->includeTreeList.clear();
	String rootdir;

	TTreeNode* node = f_Main->fr_Source->tv_Dirs->Items->GetFirstNode();
	while (node)
	{
		_addSourceDirToList(node, rootdir, false);
		_sourceDirLists2(node->getFirstChild(),
            IncludeTrailingPathDelimiter(rootdir + node->Text));
		node = node->getNextSibling();
	}
}
Пример #12
0
bool GetDriveFreeSpace(String dir, String &freeBytesStr, __int64 &freeBytes)
{
	__int64 i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes;
	bool fResult;
    dir = IncludeTrailingPathDelimiter(ExtractFileDrive(dir));

	fResult = GetDiskFreeSpaceEx(
			dir.c_str(),
			(PULARGE_INTEGER)&i64FreeBytesToCaller,
			(PULARGE_INTEGER)&i64TotalBytes,
			(PULARGE_INTEGER)&i64FreeBytes
		);

	freeBytes = i64FreeBytes;	/* TODO : Use i64FreeBytesToCaller? */
	freeBytesStr.printf("%I64d", freeBytes);

	// fResult is zero on failure.
	return !fResult;
}
Пример #13
0
bool TAbaktFileList::buildAll()
{
	if (_building && !_fatalError) // If FError is true a previous Build...() has failed.
	{
		_fatalError = true;
		_errorString = __FUNC__ ": Building already in progress." ;
		return !_fatalError;
	}

	_reset();
	_building = true;

	// Clean-up old FileList files if they exist:
	_fatalError = !_deleteOldListFile(incFileName);
	if (!_fatalError)
		_fatalError = !_deleteOldListFile(excFileName);
	if (_fatalError)
		return !_fatalError;

	std::ofstream ofs_inc(incFileName.c_str()); // Can be 0 if IncFileName is empty.
	std::ofstream ofs_exc(excFileName.c_str()); // Can be 0 if ExcFileName is empty.

	for (unsigned int i = 0; i < PProfile->sourceRootDirList.size(); i++)
	{
		_currentSourceRootDir = IncludeTrailingPathDelimiter(PProfile->sourceRootDirList[i]);
		try
		{
			_doBuild(_currentSourceRootDir, ofs_inc, ofs_exc);
		}
		catch (Exception &ex)
		{
			_fatalError = true;
			_errorString = __FUNC__ ": Fatal Error: " + ex.Message;
		}
		if (_aborted) break;
		if (_fatalError) break;
	}

	_building = false;

	if (_fatalError || _aborted) return false;
	else return true;
}
Пример #14
0
XLog::XLog(const char *p_logfilenamepath,
           int p_logqueue_size,
           int p_flush_interval)
{
  if (!p_logfilenamepath)
    m_logfilepath.assign(ExtractFilePath(ParamStr(0),true));
  else
  {
    m_logfilepath.assign(p_logfilenamepath);
    if (m_logfilepath.empty() || !DirectoryExists(m_logfilepath.c_str()))
      m_logfilepath.assign(ExtractFilePath(ParamStr(0),true));
    else
      m_logfilepath.assign(IncludeTrailingPathDelimiter(m_logfilepath));
  }
  m_logqueue_size = p_logqueue_size;
  if (m_logqueue_size <= 0)
    m_logqueue_size = 1 * 1024 * 1024; //1M;
  m_flush_interval = p_flush_interval;

  m_swaplock = new pthread_mutex_t();
  pthread_mutex_init(m_swaplock,NULL);
  m_prequeuelock = new pthread_mutex_t();
  pthread_mutex_init(m_prequeuelock,NULL);
  m_prequeue_real = malloc(m_logqueue_size);
  m_savingqueue_real = malloc(m_logqueue_size);
  m_prequeue_logical = m_prequeue_real;
  m_savingqueue_logical = m_savingqueue_real;
  m_prequeue_size = 0;
  m_savingqueue_size = 0;
  m_file_handle = NULL;
  m_file_date = NULL;
  m_file_date_tmp = NULL;
  DWORD dwComputerNameSize = 255;
  m_computer_name = (char*)malloc(dwComputerNameSize*sizeof(char));
  memset(m_computer_name,0,dwComputerNameSize*sizeof(char));
  char s[255];
  memset(s,0,255);
  gethostname(s,255);
  memcpy(m_computer_name,s,strlen(s));
}
//===========================================================================
//スレッド実行
//===========================================================================
void __fastcall TAttacheCaseFileDecrypt2::Execute()
{

int i, c, len;
float ProgressPercentNumF;  //進捗パーセンテージ(浮動小数点)

// バッファ
char source_buffer[BUF_SIZE];
char temp_buffer[BUF_SIZE];
char chain_buffer[BUF_SIZE];
char output_buffer[LARGE_BUF_SIZE];
char *headerbuffer;

//パスワード
bool fPasswordOk;
//const int KeyArrayNum = sizeof(key)/sizeof(key[0]);

String FilePath, FileName;

// ファイルストリーム
TFileStream *fsIn;
TFileStream *fsOut;

bool fInputFileOpen = false;
bool fOutputFileOpen = false;

float free_space_required;
__int64 CurrentPos, TotalSize;
__int64 CurrentDriveFreeSpaceSize;

//処理する合計サイズ
AllTotalSize = 0;

int ret;	//バッファ出力の返値
int FileIndex = 0;

char token[17] = {0, };
const char charTokenString[17] = "_AttacheCaseData";         //復号の正否に使う
const char charBrokenToken[17] = "_Atc_Broken_Data";         //ファイルが破壊されていることを示すトークン
String AtcFileTokenString;                                   //暗号化ファイルのトークン(文字列)
String AtcFileCreateDateString;                              //暗号化ファイルの生成日時(文字列)

//「復号したファイルを関連付けされたソフトで開く」一時的な設定
fTempOpenFile = fOpenFile;
//フォルダーを一度開いたか(深いフォルダーすべてを開かないように)
fOpenFolderOnce = false;

// 出力するディレクトリ
OutDirPath = IncludeTrailingPathDelimiter(OutDirPath);

String TempRelativePath;


// 平文ヘッダサイズ(データサブバージョン、破壊設定など)
int PlainHeaderSize = 0;
// 暗号化部分のヘッダサイズ
int EncryptHeaderSize = 0;

int DataVersion;        // ver.2.00~は "5", ver.2.70~は "6"
int AlgorismType;

char reserved;          // 0
//int TypeLimits;       // ミスタイプ回数 0~10  (グローバル:public宣言とした)
//bool fDestroy;        // 破壊するか否か 0 or 1 (グローバル:public宣言とした)

String PrefixString;	  //ファイルリストの接頭辞(Fn_*, U_*)

int flush, status;      // zlib
z_stream z;             // zlibライブラリとやりとりするための構造体
bool fInputEnd = false; // 入力ストリームの終了

//ヘッダデータから必要情報を取り出すための
TMemoryStream *pms;     // メモリストリーム

int idx;
TStringList *DataList;
TStringList *tsv;

TStringList *FileList = new TStringList();  // 0: ファイル名
__int64 *FileSizeList = 0;               // 1: ファイルサイズ(フォルダは-1)
int *FileAttrList     = 0;               // 2: 属性
int *FileDtChangeList = 0;               // 3: 更新日
int *FileTmChangeList = 0;               // 4: 更新時
int *FileDtCreateList = 0;               // 5: 作成日
int *FileTmCreateList = 0;               // 6: 作成時

int rest;
int buf_size;

//----------------------------------------------------------------------
// 平文のヘッダ内容チェック

try {
	fsIn = new TFileStream(AtcFilePath, fmOpenRead | fmShareDenyNone);
}
catch(...) {
	//'復号するファイルを開けません。他のアプリケーションが使用中の可能性があります。'
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_OPEN);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	goto LabelError;
}

fInputFileOpen = true;

// 平文ヘッダサイズを取得
fsIn->Read(&PlainHeaderSize, sizeof(int));
// トークンを取得
fsIn->Read(token, 16);

if (StrComp(token, charTokenString) != 0 ) {
	//--------------------------------------------------------
	//実は自己実行形式ファイル?(拡張子偽装されている場合も)
	//--------------------------------------------------------
	// サイズを再取得
	fsIn->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd);
	fsIn->Read(&AllTotalSize, sizeof(__int64));
	// 位置を戻す
	fsIn->Seek(-(AllTotalSize + sizeof(__int64)), TSeekOrigin::soEnd);
	// もう一度、平文ヘッダサイズを読み込む
	fsIn->Read(&PlainHeaderSize, sizeof(int));
	// もう一度、トークンを取得
	fsIn->Read(token, 16);

	// トークンを再チェック
	if (StrComp(token, charTokenString) != 0 ) {

		if ( StrComp(token, charBrokenToken) == 0 ) {
			//'復号するファイルを開けません。この暗号化ファイルは破壊されています。'
			MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_BROKEN);
			MsgType = mtError;
			MsgButtons = TMsgDlgButtons() << mbOK;
			MsgDefaultButton = mbOK;
			Synchronize(&PostConfirmMessageForm);
		}
		else {
			// '暗号化ファイルではありません。アタッシェケースによって暗号化されたファイルでないか、'+#13+
			// 'ファイルが壊れている可能性があります。'
			MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_NOT_ATC);
			MsgType = mtError;
			MsgButtons = TMsgDlgButtons() << mbOK;
			MsgDefaultButton = mbOK;
			Synchronize(&PostConfirmMessageForm);
		}
		goto LabelError;
	}

}

//-----------------------------------
// データバージョンチェック
//-----------------------------------
DataVersion = -1;
fsIn->Read(&DataVersion, sizeof(int));

if (DataVersion > ATC_DATA_FILE_VERSION && DataVersion < 200) {
	//'データバージョンがちがいます。復号できません。'+#13+
	//'ファイルは上位バージョンのアタッシェケースで暗号化されています。'+#13+
	//'最新版を入手して復号を試みてください。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_HIGHER_VERSION);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	goto LabelError;
}
else if (DataVersion <= 103) {

	// Blowfishで暗号化されたファイル
	// 正式版では正常に復号されるが、ここではエラーとする

	//'データバージョンがちがいます。復号できません。'+#13+
	//'ファイルはver.1のアタッシェケースで暗号化されています。'+#13+
	//'古いバージョン(ver.2.75以前)か正式版を入手して復号を試みてください。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_LOWER_VERSION);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	goto LabelError;

}
else {

	// 104 ~
	// Rijndaelで暗号化されている

	// アルゴリズムタイプ
	fsIn->Read(&AlgorismType, sizeof(int));
	// ヘッダサイズを読み込む
	fsIn->Read(&EncryptHeaderSize, sizeof(int));
	// int型からポインタキャストでchar配列を取り出す
	headerbuffer = (char*) & PlainHeaderSize;
	// データサブバージョンチェック(ver.2.70~)
	if (headerbuffer[0] >= 6) {
		TypeLimits = (int)headerbuffer[2];
		fDestroy = (bool)headerbuffer[3];
		// 有効範囲(1~10)かチェック
		if (TypeLimits < 1 || 10 < TypeLimits) {
			TypeLimits = 3; // デフォルト
		}
	}
	else { // headerbuffer[0] == 5            //旧バージョン
		TypeLimits = 3;
		fDestroy = false;
	}
}


//-----------------------------------
// 復号の準備
//-----------------------------------

// テーブル生成
gentables();

// パスワードのセット
gkey(8, 8, key);

//-----------------------------------
// 暗号部ヘッダの復号
//-----------------------------------

pms = new TMemoryStream;

// IVの読み込み
fsIn->Read(chain_buffer, BUF_SIZE);

len = 0;

while (len < EncryptHeaderSize) {

	// 読み出しバッファ
	for (c = 0; c < BUF_SIZE; c++) {
		source_buffer[c] = 0;
	}
	// 暗号化されたデータブロックの読み出し
	len += fsIn->Read(source_buffer, BUF_SIZE);

	for (c = 0; c < BUF_SIZE; c++) {
		// あとのxorのためによけておく
		temp_buffer[c] = source_buffer[c];
	}

	// 復号処理
	rijndael_decrypt(source_buffer);

	// xor
	for (c = 0; c < BUF_SIZE; c++) {
		source_buffer[c] ^= chain_buffer[c];
		chain_buffer[c] = temp_buffer[c]; // CBC
	}

	pms->Write(source_buffer, BUF_SIZE);

}

pms->Seek((__int64)0, TSeekOrigin::soBeginning);  //ポインタを先頭へ戻す
DataList = new TStringList;
DataList->LoadFromStream(pms, TEncoding::GetEncoding(932));  // shift-jis

//-----------------------------------
// 復号正否(復号できたか)
//-----------------------------------

//MsgText = DataList->Strings[0];
//MsgType = mtError;
//MsgButtons = TMsgDlgButtons() << mbOK;
//MsgDefaultButton = mbOK;
//Synchronize(&PostConfirmMessageForm);

if (DataList->Count == 0 || DataList->Strings[0].Pos("AttacheCase") == 0) {
	fPasswordOk = false;
}
else{
	fPasswordOk = true;   //パスワード合致
}

if ( fPasswordOk == false ) {
	//'パスワードがちがいます。復号できません。'+#13+
	//'場合によってはファイルが壊れている可能性もあります。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_PASSWORD_WRONG);
	if ( fCompare == true ) {
		//メッセージに'コンペアに失敗しました。'を追加
		MsgText += "\n" + LoadResourceString(&Msgdecrypt::_MSG_ERROR_COMPARE_FILE);
	}
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	delete DataList;
	goto LabelTypeMiss;
}

//-----------------------------------
// 復号時のエンコーディング判定
//-----------------------------------
pms->Position = 0;
//DataList->LoadFromStream(pms, TEncoding::UTF8);
DataList->LoadFromStream(pms, TEncoding::GetEncoding(65001));

PrefixString = "Fn_";
for (i = 0; i < DataList->Count; i++) {
	if ( DataList->Strings[i].Pos("U_0") == 1){
		PrefixString = "U_";	//新バージョン(ver.2.8.0~)で暗号化されているようだ
		break;
	}
}

// Unicodeではないので従来のShift-JISで再度読み直し
if (PrefixString == "Fn_") {
	pms->Position = 0;
	DataList->LoadFromStream(pms, TEncoding::GetEncoding(932));
}

//===================================
// デバッグ
//ShowMessage(DataList->Text);
//===================================

#ifdef _DEBUG
DataList->SaveToFile(OutDirPath + ExtractFileName(AtcFilePath) + ".txt");
#endif

delete pms;


//-----------------------------------
// 暗号化ファイルの生成日時
//-----------------------------------
//※特に今は使用していないが、将来的に
//  期限付きでファイルを復号できなくなる
//  などの機能を追加しても良いかも。
//-----------------------------------
AtcFileCreateDateString = DataList->Strings[1];

//-----------------------------------
// ヘッダデータからファイルリストや
// ファイル情報などを各変数を動的確保
//-----------------------------------

FileSizeList = new __int64[DataList->Count];  // 1: ファイルサイズ(フォルダは-1)
FileAttrList = new int[DataList->Count];      // 2: 属性
FileDtChangeList = new int[DataList->Count];  // 3: 更新日
FileTmChangeList = new int[DataList->Count];  // 4: 更新時
FileDtCreateList = new int[DataList->Count];  // 5: 作成日
FileTmCreateList = new int[DataList->Count];  // 6: 作成時

DataList->NameValueSeparator = ':';

tsv = new TStringList;
tsv->Delimiter = '\t';
tsv->StrictDelimiter = true;

char lpPath[MAX_PATH];

for (i = 0; i < DataList->Count; i++) {
	idx = DataList->IndexOfName(PrefixString+IntToStr(i));
	if (idx > 0) {
		tsv->DelimitedText = DataList->ValueFromIndex[idx];

		// ディレクトリ・トラバーサル対策(ver.2.8.5.0~)
		bool fDirectoryTraversal = false;
		AnsiString CanonicalizePath = AnsiString(OutDirPath + tsv->Strings[0]);

		if (CanonicalizePath.Length() < MAX_PATH) {
			// ファイルパスを正規化
			if (PathCanonicalize(lpPath, CanonicalizePath.c_str()) == true) {
				// 正規化したパスが保存先と一致するか
				if (AnsiString(lpPath).Pos(OutDirPath) != 1 ){
					fDirectoryTraversal = true;
				}
			}
			else{
				fDirectoryTraversal = true;
			}
		}
		else{
			fDirectoryTraversal = true;
		}

		if (fDirectoryTraversal == true) {
			//'不正なファイルパスが含まれています。復号できません。';
			MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_INVALID_FILE_PATH) +
								"\n" + CanonicalizePath;
			MsgType = mtError;
			MsgButtons = TMsgDlgButtons() << mbOK;
			MsgDefaultButton = mbOK;
			Synchronize(&PostConfirmMessageForm);
			delete DataList;
			goto LabelTypeMiss;
		}

		FileList->Add(tsv->Strings[0]);                        // 0: ファイルパス
		FileSizeList[i] = StrToIntDef(tsv->Strings[1], -1);    // 1: ファイルサイズ(フォルダは-1)
		FileAttrList[i] = StrToIntDef(tsv->Strings[2], -1);    // 2: 属性
		FileDtChangeList[i] = StrToIntDef(tsv->Strings[3], -1);// 3: 更新日
		FileTmChangeList[i] = StrToIntDef(tsv->Strings[4], -1);// 4: 更新時
		FileDtCreateList[i] = StrToIntDef(tsv->Strings[5], -1);// 5: 作成日
		FileTmCreateList[i] = StrToIntDef(tsv->Strings[6], -1);// 6: 作成時
	}

}

delete tsv;
delete DataList;


//-----------------------------------
//ディスクの空き容量チェック
//-----------------------------------

CurrentDriveFreeSpaceSize = GetDiskFreeSpaceNum(OutDirPath);

if (CurrentDriveFreeSpaceSize > -1 && fCompare == false) {
	if ( AllTotalSize > CurrentDriveFreeSpaceSize ) {
		//'復号する先のドライブの空き容量が足りません。'+#13+
		//'復号するには、約%dMBの空き容量が必要です。復号処理を中止します。';
		MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_DRIVE_NO_FREE_SPACE);
		free_space_required = (float)AllTotalSize/1024/1024;  // MB
		MsgText = String().sprintf(MsgText.c_str(), free_space_required);
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
		goto LabelError;
	}
}
else{
	// OK!
	//
}

//-----------------------------------
//複数フォルダ/ファイルを開こうとしているので確認
//-----------------------------------

//復号したファイルを関連付けされたソフトで開くか
if ( fTempOpenFile == true && FileList->Count > 4 && fCompare == false) {

	//'5つ以上のファイルを復号後に開こうとしていますが、処理を続けますか?'+#13+
	//'「いいえ」を選択すると、開かず復号します。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_CONFIRM_OPEN_DECRYPTED_FILES);
	MsgType = mtConfirmation;
	MsgButtons = TMsgDlgButtons() << mbYes << mbNo << mbCancel;
	MsgDefaultButton = mbCancel;
	Synchronize(&PostConfirmMessageForm);

	if ( MsgReturnVal == mrCancel ) {
		goto LabelStop;
	}
	else if ( MsgReturnVal == mrNo ) {
		fTempOpenFile = true;
	}

}

//-----------------------------------
// 復号開始
//-----------------------------------

if (fCompare == false) {
	//'復号しています...'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_DECRYPTING);
	ProgressMsgText = ExtractFileName(AtcFilePath);
}
else{
	//'コンペアしています...'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_COMPARING);
	ProgressMsgText = ExtractFileName(AtcFilePath);
}

// ファイル(データ本体)サイズを取得する
AllTotalSize = fsIn->Size - fsIn->Position + 1;
// 初期化ベクトルの読み出し
TotalSize = fsIn->Read(chain_buffer, BUF_SIZE);

// zlib 前準備
// 圧縮においてすべてのメモリ管理をライブラリに任せる
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;

if (inflateInit(&z) != Z_OK) {
	// エラー
	// zlibエラーは最後でまとめてメッセージ処理
	goto LabelError;
}

// 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す
flush = Z_NO_FLUSH;

// 入出力バッファ
for (i = 0; i < LARGE_BUF_SIZE; i++) {
	output_buffer[i] = 0;
}

z.avail_in  = 0;               // 入力バッファ中のデータのバイト数
z.next_in   = Z_NULL;          // 入力バッファ中のデータのバイト数
z.next_out  = output_buffer;   // 出力バッファ残量
z.avail_out = LARGE_BUF_SIZE;  // 出力ポインタ(展開するので大きめに)
status      = Z_OK;

while (Terminated == false) {

	//-----------------------------------
	// 入力
	//-----------------------------------
	if (z.avail_in == 0) {

		TotalSize = InputBuffer(len, source_buffer, chain_buffer, fsIn, fInputFileOpen, TotalSize);
		z.avail_in = len;
		z.next_in = source_buffer;

		if ( len == 0 ) {  //入力ストリーム終了
			fInputEnd = true;
		}

	}

	//-----------------------------------
	// 展開
	//-----------------------------------
	status = inflate(&z, flush);


	//-----------------------------------
	// 処理ステータス
	//-----------------------------------
	if ( status == Z_OK ){

		if ( z.avail_out == 0 ) {

			ret = OutputBuffer(output_buffer, LARGE_BUF_SIZE,
												 fsOut, fOutputFileOpen,
												 FileList, FileIndex,
												 FileSizeList, FileAttrList,
												 FileDtChangeList, FileTmChangeList,
												 FileDtCreateList, FileTmCreateList);

			if ( ret == 0) {
				z.next_out = output_buffer;
				z.avail_out = LARGE_BUF_SIZE;
			}
			else if (ret == -1) {
				goto LabelError;
			}
			else{
				goto LabelStop;
			}

		}//end if (z.avail_out == 0);


	}
	//-----------------------------------
	// バッファエラー
	//-----------------------------------
	else if ( status == Z_BUF_ERROR ) { //出力バッファがいっぱいの可能性

		//出力バッファをクリアにして継続させる
		len = LARGE_BUF_SIZE - z.avail_out;
		ret = OutputBuffer(output_buffer, len,
											 fsOut, fOutputFileOpen,
											 FileList, FileIndex,
											 FileSizeList, FileAttrList,
											 FileDtChangeList, FileTmChangeList,
											 FileDtCreateList, FileTmCreateList);
		if (ret == 0) {
			z.next_out = output_buffer;
			z.avail_out = LARGE_BUF_SIZE;
		}
		else if ( ret == -1) {
			goto LabelError;
		}
		else{
			goto LabelStop;
		}

	}
	//-----------------------------------
	// 終了
	//-----------------------------------
	else if (status == Z_STREAM_END) {
		break;
	}
	//-----------------------------------
	// エラー
	//-----------------------------------
	else{
		// #define Z_OK              0
		// #define Z_STREAM_END      1
		// #define Z_NEED_DICT       2
		// #define Z_ERRNO         (-1)
		// #define Z_STREAM_ERROR  (-2)
		// #define Z_DATA_ERROR    (-3)
		// #define Z_MEM_ERROR     (-4)
		// #define Z_BUF_ERROR     (-5)
		// #define Z_VERSION_ERROR (-6)
		goto LabelError;
	}


	//-----------------------------------
	//進捗状況表示
	ProgressPercentNumF = (float)TotalSize/AllTotalSize;
	ProgressPercentNum = (int)(ProgressPercentNumF*100);
	if (AllTotalSize < 104857600) {	// 100MB未満
		ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%";
	}
	else{
		ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%";
	}

	if ( fInputEnd == true) {
		break;
	}

}//while (!Terminated);

if (Terminated == true) {
	//ユーザーキャンセルで抜けてきた
	goto LabelStop;
}

//----------------------------------------------------------------------
// 万が一、出力バッファに余りがある場合
//----------------------------------------------------------------------

len = LARGE_BUF_SIZE - z.avail_out;
ret = OutputBuffer(output_buffer, len,
									 fsOut, fOutputFileOpen,
									 FileList, FileIndex,
									 FileSizeList, FileAttrList,
									 FileDtChangeList, FileTmChangeList,
									 FileDtCreateList, FileTmCreateList);
if ( ret == 0 ) {
}
else if ( ret == -1 ){
	goto LabelError;
}
else{
	goto LabelStop;
}


if (inflateEnd(&z) != Z_OK) {
	goto LabelError;
}

ProgressPercentNum = 100;
//'完了'
ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_COMPLETE);
ProgressMsgText = ExtractFileName(AtcFilePath);

if ( fInputFileOpen == true ) {
	delete fsIn;
	fInputFileOpen = false;
}
if ( fOutputFileOpen == true ) {
	delete fsOut;
	fOutputFileOpen = false;
}

delete FileList;
delete [] FileSizeList;      // 1: ファイルサイズ(フォルダは-1)
delete [] FileAttrList;      // 2: 属性
delete [] FileDtChangeList;  // 3: 更新日
delete [] FileTmChangeList;  // 4: 更新時
delete [] FileDtCreateList;  // 5: 作成日
delete [] FileTmCreateList;  // 6: 作成時

//復号成功
StatusNum = 1;
return;


//-----------------------------------
//パスワード入力ミスの後始末
//-----------------------------------
LabelTypeMiss:

	ProgressPercentNum = 0;

	//'エラー'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_ERROR);
	//'復号に失敗しました。'
	ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_FAILED);

	if ( fInputFileOpen == true ) {
		delete fsIn;
		fInputFileOpen = false;
	}
	if ( fOutputFileOpen == true ) {
		delete fsOut;
		fOutputFileOpen = false;
	}

	delete FileList;
	delete [] FileSizeList;
	delete [] FileAttrList;
	delete [] FileDtChangeList;
	delete [] FileTmChangeList;
	delete [] FileDtCreateList;
	delete [] FileTmCreateList;

	StatusNum = -1;
	return;


//-----------------------------------
//エラーの後始末
//-----------------------------------
LabelError:

	ProgressPercentNum = 0;

	if ( status < 0 ){
		//'zlibライブラリからエラーを返されました。'
		//'エラー番号:'
		MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_ZLIB) + IntToStr(status) + "\n" + z.msg;
		if ( fCompare == true ) {
			//メッセージに'コンペアに失敗しました。'を追加
			MsgText += "\n" + LoadResourceString(&Msgdecrypt::_MSG_ERROR_COMPARE_FILE);
		}
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
	}

	//'エラー'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_ERROR);

	if (fCompare == true) {
		//'コンペアで問題を見つけたようです。';
		ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_COMPARE_FAILED);
	}
	else{
		//'復号に失敗しました。'
		ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_FAILED);
	}

	if ( fInputFileOpen == true ) {
		delete fsIn;
		fInputFileOpen = false;
	}
	if ( fOutputFileOpen == true ) {
		delete fsOut;
		fOutputFileOpen = false;
	}

	delete FileList;
	delete [] FileSizeList;
	delete [] FileAttrList;
	delete [] FileDtChangeList;
	delete [] FileTmChangeList;
	delete [] FileDtCreateList;
	delete [] FileTmCreateList;

	StatusNum = -2;
	return;


//-----------------------------------
//ユーザーキャンセルの後始末
//-----------------------------------
LabelStop:

	ProgressPercentNum = 0;
	//'キャンセル'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_USER_CANCEL);
	//'復号が中止されました。'
	ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_STOPPED);

	if ( fInputFileOpen == true ) {
		delete fsIn;
		fInputFileOpen = false;
	}
	if ( fOutputFileOpen == true ) {
		delete fsOut;
		fOutputFileOpen = false;
	}

	delete FileList;
	delete [] FileSizeList;
	delete [] FileAttrList;
	delete [] FileDtChangeList;
	delete [] FileTmChangeList;
	delete [] FileDtCreateList;
	delete [] FileTmCreateList;

	StatusNum = 0;
	return;

}
//===========================================================================
//スレッド実行
//===========================================================================
void __fastcall TAttacheCaseFileDecrypt1::Execute()
{

int i, c, len;
float ProgressPercentNumF;  //進捗パーセンテージ(浮動小数点)

// バッファ
char buffer[BUF_SIZE];
char source_buffer[BUF_SIZE];
char temp_buffer[BUF_SIZE];
char output_buffer[LARGE_BUF_SIZE];
char *headerbuffer;

//パスワード
bool fPasswordOk;

String FilePath, FileName;

// ファイルストリーム
TFileStream *fsIn;
TFileStream *fsOut;
bool fInputFileOpen = false;
bool fOutputFileOpen = false;

float free_space_required;
__int64 CurrentPos, TotalSize;
__int64 CurrentDriveFreeSpaceSize;

//処理する合計サイズ
AllTotalSize = 0;

int ret;	//バッファ出力の返値
int FileIndex = 0;

//Blowfish
CBlowFish *bf;

char token[17] = {0, };
const String PrefixString      = "Fn_";
const char charTokenString[17] = "_AttacheCaseData";         //復号の正否に使う
String AtcFileTokenString;                                   //暗号化ファイルのトークン(文字列)
String AtcFileCreateDateString;                              //暗号化ファイルの生成日時(文字列)

//同名ファイル/フォルダーはすべて上書きして復号する
//(ユーザーがダイアログで「すべてはい」を選択したとき = true )
fOverwirteYesToAll = false;
//「復号したファイルを関連付けされたソフトで開く」一時的な設定
fTempOpenFile = fOpenFile;
//フォルダーを一度開いたか(深いフォルダーすべてを開かないように)
fOpenFolderOnce = false;

// 出力するディレクトリ
OutDirPath = IncludeTrailingPathDelimiter(OutDirPath);

String TempRelativePath;


// 暗号化部分のヘッダサイズ
int EncryptHeaderSize = 0;

int DataVersion;        // ver.2.00~は "5", ver.2.70~は "6"

int flush, status;      // zlib
z_stream z;             // zlibライブラリとやりとりするための構造体
bool fInputEnd = false; // 入力ストリームの終了

//ヘッダデータから必要情報を取り出すための
TMemoryStream *pms;     // メモリストリーム

int idx;
TStringList *DataList;
TStringList *tsv;

TStringList *FileList = new TStringList();  // 0: ファイル名
__int64 *FileSizeList = 0;                  // 1: ファイルサイズ(フォルダは-1)
int *FileAttrList     = 0;                  // 2: 属性
int *FileAgeList      = 0;                  // 3: タイムスタンプ

int rest;
int buf_size;

//----------------------------------------------------------------------
// 平文のヘッダ内容チェック
try {
	fsIn = new TFileStream(AtcFilePath, fmOpenRead | fmShareDenyNone);
}
catch(...) {
	//'復号するファイルを開けません。他のアプリケーションが使用中の可能性があります。'
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_OPEN);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	goto LabelError;
}

fInputFileOpen = true;

// 暗号部ヘッダサイズを取得
fsIn->Read(&EncryptHeaderSize, sizeof(int));
// トークンを取得
fsIn->Read(token, 16);

if (StrComp(token, charTokenString) != 0 ) {
	//--------------------------------------------------------
	//実は自己実行形式ファイル?(拡張子偽装されている場合も)
	//--------------------------------------------------------
	// サイズを再取得
	fsIn->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd);
	fsIn->Read(&AllTotalSize, sizeof(__int64));
	// 位置を戻す
	fsIn->Seek(-(AllTotalSize + sizeof(__int64)), TSeekOrigin::soEnd);
	// もう一度、暗号部ヘッダサイズを取得
	fsIn->Read(&EncryptHeaderSize, sizeof(int));
	// もう一度、トークンを取得
	fsIn->Read(token, 16);

	// トークンを再チェック
	if (StrComp(token, charTokenString) != 0 ) {
		// '暗号化ファイルではありません。アタッシェケースによって暗号化されたファイルでないか、'+#13+
		// 'ファイルが壊れている可能性があります。'
		MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_FILE_NOT_ATC);
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
		goto LabelError;
	}

}
else{
	AllTotalSize = fsIn->Size;
}

//-----------------------------------
// データバージョンチェック
//-----------------------------------
DataVersion = -1;
fsIn->Read(&DataVersion, sizeof(int));

if (DataVersion <= 103) {

	// Blowfishで暗号化されたファイル

}
else{
	//'バージョンがちがいます。復号できません。'+#13+
	//'ファイルはver.1のアタッシェケースで暗号化されていません。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_NOT_BLOWFISH_ENCRYPTION);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	goto LabelError;
}

//-----------------------------------
// 復号の準備
//-----------------------------------

bf = new CBlowFish;
bf->Initialize( KeyString.c_str(), KeyString.Length() );   //初期化

//-----------------------------------
// 暗号部ヘッダの復号(ECBモード)
//-----------------------------------

pms = new TMemoryStream;

len = 0;
while (len < EncryptHeaderSize) {
	// 読み出しバッファ
	for (c = 0; c < BUF_SIZE; c++) {
		source_buffer[c] = 0;
	}
	// 暗号化されたデータブロックの読み出し
	len += fsIn->Read(source_buffer, BUF_SIZE);

	// 復号処理
	bf->Decode( source_buffer, buffer, BUF_SIZE);
	pms->Write(buffer, BUF_SIZE);
}

pms->Seek((__int64)0, TSeekOrigin::soBeginning);             //ポインタを先頭へ戻す
DataList = new TStringList;
DataList->LoadFromStream(pms, TEncoding::GetEncoding(932));  // shift-jis


//-----------------------------------
// 復号正否(復号できたか)
//-----------------------------------
if (DataList->Count == 0 || DataList->Strings[0].Pos("AttacheCase") == 0) {
	fPasswordOk = false;
}
else{
	fPasswordOk = true;   //パスワード合致
}

if ( fPasswordOk == false ) {
	//'パスワードがちがいます。復号できません。'+#13+
	//'場合によってはファイルが壊れている可能性もあります。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_PASSWORD_WRONG);
	MsgType = mtError;
	MsgButtons = TMsgDlgButtons() << mbOK;
	MsgDefaultButton = mbOK;
	Synchronize(&PostConfirmMessageForm);
	delete DataList;
	goto LabelTypeMiss;
}

//-----------------------------------
// 復号時のエンコーディング判定
//-----------------------------------
pms->Position = 0;
DataList->LoadFromStream(pms, TEncoding::GetEncoding(932));  // shift-jis


//===================================
// デバッグ
//ShowMessage(DataList->Text);
//===================================

delete pms;


//-----------------------------------
// 暗号化ファイルの生成日時
//-----------------------------------
//※特に今は使用していないが、将来的に
//  期限付きでファイルを復号できなくなる
//  などの機能を追加しても良いかも。
//-----------------------------------
AtcFileCreateDateString = DataList->Strings[1];

//-----------------------------------
// ヘッダデータからファイルリストや
// ファイル情報などを各変数を動的確保
//-----------------------------------

FileSizeList = new __int64[DataList->Count];  // 1: ファイルサイズ(フォルダは-1)
FileAttrList = new int[DataList->Count];      // 2: 属性
FileAgeList = new int[DataList->Count];       // 3: タイムスタンプ

DataList->NameValueSeparator = ':';

tsv = new TStringList;
tsv->Delimiter = '\t';
tsv->StrictDelimiter = true;

char lpPath[MAX_PATH];

for (i = 0; i < DataList->Count; i++) {
	idx = DataList->IndexOfName(PrefixString+IntToStr(i));
	if (idx > 0) {
		tsv->DelimitedText = DataList->ValueFromIndex[idx];

		// ディレクトリ・トラバーサル対策(ver.2.8.5.0~)
		bool fDirectoryTraversal = false;
		AnsiString CanonicalizePath = AnsiString(OutDirPath + tsv->Strings[0]);

		if (CanonicalizePath.Length() < MAX_PATH) {
			// ファイルパスを正規化
			if (PathCanonicalize(lpPath, CanonicalizePath.c_str()) == true) {
				// 正規化したパスが保存先と一致するか
				if (AnsiString(lpPath).Pos(OutDirPath) != 1 ){
					fDirectoryTraversal = true;
				}
			}
			else{
				fDirectoryTraversal = true;
			}
		}
		else{
			fDirectoryTraversal = true;
		}

		if (fDirectoryTraversal == true) {
			//'不正なファイルパスが含まれています。復号できません。';
			MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_INVALID_FILE_PATH) +
								"\n" + CanonicalizePath;
			MsgType = mtError;
			MsgButtons = TMsgDlgButtons() << mbOK;
			MsgDefaultButton = mbOK;
			Synchronize(&PostConfirmMessageForm);
			delete DataList;
			goto LabelTypeMiss;
		}

		FileList->Add(tsv->Strings[0]);                        // 0: ファイルパス
		FileSizeList[i] = StrToIntDef(tsv->Strings[1], -1);    // 1: ファイルサイズ(フォルダは-1)
		FileAttrList[i] = StrToIntDef(tsv->Strings[2], -1);    // 2: 属性
		FileAgeList[i] = StrToIntDef(tsv->Strings[3], -1);     // 3: タイムスタンプ
	}
}

delete tsv;
delete DataList;


//-----------------------------------
//ディスクの空き容量チェック
//-----------------------------------
CurrentDriveFreeSpaceSize = GetDiskFreeSpaceNum(OutDirPath);

if (CurrentDriveFreeSpaceSize > -1) {
	if ( AllTotalSize > CurrentDriveFreeSpaceSize ) {
		//'復号する先のドライブの空き容量が足りません。'+#13+
		//'復号するには、約%dMBの空き容量が必要です。復号処理を中止します。';
		MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_DRIVE_NO_FREE_SPACE);
		free_space_required = (float)AllTotalSize/1024/1024;  // MB
		MsgText = String().sprintf(MsgText.c_str(), free_space_required);
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
		goto LabelError;
	}
}
else{
	// OK!
	//
}

//-----------------------------------
//複数フォルダ/ファイルを開こうとしているので確認
//-----------------------------------

//復号したファイルを関連付けされたソフトで開くか
if ( fTempOpenFile == true && FileList->Count > 4) {

	//'5つ以上のファイルを復号後に開こうとしていますが、処理を続けますか?'+#13+
	//'「いいえ」を選択すると、開かず復号します。';
	MsgText = LoadResourceString(&Msgdecrypt::_MSG_CONFIRM_OPEN_DECRYPTED_FILES);
	MsgType = mtConfirmation;
	MsgButtons = TMsgDlgButtons() << mbYes << mbNo << mbCancel;
	MsgDefaultButton = mbCancel;
	Synchronize(&PostConfirmMessageForm);

	if ( MsgReturnVal == mrCancel ) {
		goto LabelStop;
	}
	else if ( MsgReturnVal == mrNo ) {
		fTempOpenFile = true;
	}

}

//-----------------------------------
// 復号開始
//-----------------------------------

//'復号しています...'
ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_DECRYPTING);
ProgressMsgText = ExtractFileName(AtcFilePath);

// ファイル(データ本体)サイズを取得する
AllTotalSize = fsIn->Size - fsIn->Position + 1;

// zlib 前準備
// 圧縮においてすべてのメモリ管理をライブラリに任せる
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;

if (inflateInit(&z) != Z_OK) {
	// エラー
	// zlibエラーは最後でまとめてメッセージ処理
	goto LabelError;
}

// 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す
flush = Z_NO_FLUSH;

// 入出力バッファ
for (i = 0; i < LARGE_BUF_SIZE; i++) {
	output_buffer[i] = 0;
}

z.avail_in  = 0;               // 入力バッファ中のデータのバイト数
z.next_in   = Z_NULL;          // 入力バッファ中のデータのバイト数
z.next_out  = output_buffer;   // 出力バッファ残量
z.avail_out = LARGE_BUF_SIZE;  // 出力ポインタ(展開するので大きめに)
status      = Z_OK;

while (Terminated == false) {

	//-----------------------------------
	// 入力
	//-----------------------------------
	if (z.avail_in == 0) {

		TotalSize = InputBuffer(bf, len, source_buffer, fsIn, fInputFileOpen, TotalSize);
		z.avail_in = len;
		z.next_in = source_buffer;

		if ( len == 0 ) {  //入力ストリーム終了
			fInputEnd = true;
		}

	}

	//-----------------------------------
	// 展開
	//-----------------------------------
	status = inflate(&z, flush);

	//-----------------------------------
	// 処理ステータス
	//-----------------------------------
	if ( status == Z_OK ){

		if ( z.avail_out == 0 ) {

			ret = OutputBuffer(output_buffer, LARGE_BUF_SIZE,
												 fsOut, fOutputFileOpen,
												 FileList, FileIndex,
												 FileSizeList, FileAttrList, FileAgeList);

			if ( ret == 0) {
				z.next_out = output_buffer;
				z.avail_out = LARGE_BUF_SIZE;
			}
			else if (ret == -1) {
				goto LabelError;
			}
			else{
				goto LabelStop;
			}

		}//end if (z.avail_out == 0);

	}
	//-----------------------------------
	// バッファエラー
	//-----------------------------------
	else if ( status == Z_BUF_ERROR ) { //出力バッファがいっぱいの可能性

		//出力バッファをクリアにして継続させる
		len = LARGE_BUF_SIZE - z.avail_out;
		ret = OutputBuffer(output_buffer, len,
											 fsOut, fOutputFileOpen,
											 FileList, FileIndex,
											 FileSizeList, FileAttrList, FileAgeList);
		if (ret == 0) {
			z.next_out = output_buffer;
			z.avail_out = LARGE_BUF_SIZE;
		}
		else if ( ret == -1) {
			goto LabelError;
		}
		else{
			goto LabelStop;
		}

	}
	//-----------------------------------
	// 終了
	//-----------------------------------
	else if (status == Z_STREAM_END) {
		break;
	}
	//-----------------------------------
	// エラー
	//-----------------------------------
	else{
		// #define Z_OK              0
		// #define Z_STREAM_END      1
		// #define Z_NEED_DICT       2
		// #define Z_ERRNO         (-1)
		// #define Z_STREAM_ERROR  (-2)
		// #define Z_DATA_ERROR    (-3)
		// #define Z_MEM_ERROR     (-4)
		// #define Z_BUF_ERROR     (-5)
		// #define Z_VERSION_ERROR (-6)
		goto LabelError;
	}


	//-----------------------------------
	//進捗状況表示
	ProgressPercentNumF = (float)TotalSize/AllTotalSize;
	ProgressPercentNum = (int)(ProgressPercentNumF*100);
	if (AllTotalSize < 104857600) {	// 100MB未満
		ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%";
	}
	else{
		ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%";
	}

	if ( fInputEnd == true) {
		break;
	}

}//while (!Terminated);

if (Terminated == true) {
	//ユーザーキャンセルで抜けてきた
	goto LabelStop;
}

//----------------------------------------------------------------------
// 万が一、出力バッファに余りがある場合
//----------------------------------------------------------------------

len = LARGE_BUF_SIZE - z.avail_out;
ret = OutputBuffer(output_buffer, len,
									 fsOut, fOutputFileOpen,
									 FileList, FileIndex,
									 FileSizeList, FileAttrList, FileAgeList);
if ( ret == 0 ) {
}
else if ( ret == -1 ){
	goto LabelError;
}
else{
	goto LabelStop;
}


if (inflateEnd(&z) != Z_OK) {
	goto LabelError;
}

ProgressPercentNum = 100;
//'完了'
ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_COMPLETE);
ProgressMsgText = ExtractFileName(AtcFilePath);

if ( fInputFileOpen == true ) {
	delete fsIn;
	fInputFileOpen = false;
}
if ( fOutputFileOpen == true ) {
	delete fsOut;
	fOutputFileOpen = false;
}

delete FileList;
delete [] FileSizeList;      // 1: ファイルサイズ(フォルダは-1)
delete [] FileAttrList;      // 2: 属性
delete [] FileAgeList;       // 3: 更新日

//復号成功
StatusNum = 1;
return;


//-----------------------------------
//パスワード入力ミスの後始末
//-----------------------------------
LabelTypeMiss:

	ProgressPercentNum = 0;

	//'エラー'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_ERROR);
	//'復号に失敗しました。'
	ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_FAILED);

	if ( fInputFileOpen == true ) {
		delete fsIn;
		fInputFileOpen = false;
	}
	if ( fOutputFileOpen == true ) {
		delete fsOut;
		fOutputFileOpen = false;
	}

	delete FileList;
	delete [] FileSizeList;
	delete [] FileAttrList;
	delete [] FileAgeList;

	StatusNum = -1;
	return;


//-----------------------------------
//エラーの後始末
//-----------------------------------
LabelError:

	ProgressPercentNum = 0;

	if ( status < 0 ){
		//'zlibライブラリからエラーを返されました。'
		//'エラー番号:'
		MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_ZLIB) + IntToStr(status) + "\n" + z.msg;
		MsgType = mtError;
		MsgButtons = TMsgDlgButtons() << mbOK;
		MsgDefaultButton = mbOK;
		Synchronize(&PostConfirmMessageForm);
	}
	//'エラー'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_ERROR);
	//'復号に失敗しました。'
	ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_FAILED);

	if ( fInputFileOpen == true ) {
		delete fsIn;
		fInputFileOpen = false;
	}
	if ( fOutputFileOpen == true ) {
		delete fsOut;
		fOutputFileOpen = false;
	}

	delete FileList;
	delete [] FileSizeList;
	delete [] FileAttrList;
	delete [] FileAgeList;

	StatusNum = -2;
	return;


//-----------------------------------
//ユーザーキャンセルの後始末
//-----------------------------------
LabelStop:

	ProgressPercentNum = 0;
	//'キャンセル'
	ProgressStatusText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_TITLE_USER_CANCEL);
	//'復号が中止されました。'
	ProgressMsgText = LoadResourceString(&Msgdecrypt::_LABEL_STATUS_DETAIL_STOPPED);

	if ( fInputFileOpen == true ) {
		delete fsIn;
		fInputFileOpen = false;
	}
	if ( fOutputFileOpen == true ) {
		delete fsOut;
		fOutputFileOpen = false;
	}

	delete FileList;
	delete [] FileSizeList;
	delete [] FileAttrList;
	delete [] FileAgeList;

	StatusNum = 0;
	return;

}
Пример #17
0
void TAbaktFileList::_doBuild(String dir, std::ofstream& ofs_inc, std::ofstream& ofs_exc)
{
	// Test if building should be aborted:
	if (_aborted) return;
	if (_fatalError) return;

   	_fileError = false;

	// Get the first item:
	dir = IncludeTrailingPathDelimiter(dir);

	HANDLE fhandle;
	WIN32_FIND_DATA filedata;
	String fitem;
	bool lastFile = false;

    int thisDirSubDirCount  = 0;  // Number of subdirs in [dir]. If 0 and (thisDirIncFileCount==0), directory is added to emptyDirList.
    int thisDirIncFileCount = 0;  // Number of Included files in [dir]. If 0, directory is added to emptyDirList.

	if (!_scanFullTree)
	{
		// Skip dir-trees that are excluded:
		if (PProfile->dirInExcludeTreeList(dir))
			return;
	}

	fhandle = ::FindFirstFile( String(dir + "*").c_str(), &filedata);
	if (fhandle == INVALID_HANDLE_VALUE)
	{
        DWORD lastError = GetLastError();
		_fileError = true;
        errorItemList->Append(dir);
        _errorString = ASPF(_("Error [%d] opening directory %s: %s"),
            lastError, ecc::QuoteStr(dir), abtGetLastErrorStr(lastError));
        // Call callback with empty filteritem to notify caller of error:
        if (OnCurrentFile) OnCurrentFile(NULL);
		return;
	}

	while (!lastFile)
	{
		if (_aborted)
		{
			FindClose(fhandle);
			return;
		}
		fitem = String(filedata.cFileName);

		// Test if the filedata-object is a directory or a file:
		if ((filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
		{
            // -- Object is a directory.
			Application->ProcessMessages(); // For lengthy operations.
			if ((fitem != ".") && (fitem != ".."))
			{
                ++thisDirSubDirCount;
				if (_recurse)
					_doBuild(dir + fitem, ofs_inc, ofs_exc);
			}
		}
		else
		{
            // -- Object is a file. Add it to Items.
			if (_filterItem.testFile(dir + fitem))
			{
                ++thisDirIncFileCount;
				++incFilesTotalCount;
				incFilesTotalSize += _filterItem.getFileProps().getSize();
				_appendFPathToFile(dir + fitem, ofs_inc);
			}
			else
			{
                // Only add files in _selected_ directories to list of excluded files:
                if (!PProfile->dirInExcludeDirList(dir))
                {
                    ++excFilesTotalCount;
                    excFilesTotalSize += _filterItem.getFileProps().getSize();
                    _appendFPathToFile(dir + fitem, ofs_exc);
                }
			}
			// Call callback if it exists:
			if (OnCurrentFile)
				OnCurrentFile(&_filterItem);
		}

		// Is this the last file in dir?
		if (!FindNextFile(fhandle, &filedata))
		{
            DWORD lastError = GetLastError();
			if (lastError == ERROR_NO_MORE_FILES)
				lastFile = true;
            else
            {
          		_fileError = true;
                String file = dir + String(filedata.cFileName);
        		_errorString = ASPF(_("Error [%d] in file %s: %s"),
                    lastError, ecc::QuoteStr(file), abtGetLastErrorStr(lastError));
                errorItemList->Append(file);
    			// Call callback with empty filteritem to notify caller of error:
	    		if (OnCurrentFile) OnCurrentFile(NULL);
            }
		}
	}

    // Remember empty directories (that passed the filter):
    // - f_Action will add these dirs to the backup if required.
    if (thisDirSubDirCount == 0)
    {
        if (thisDirIncFileCount == 0)
        {
            emptyDirList->Append(dir);
        }
    }

	FindClose(fhandle);
}
Пример #18
0
bool TActionSevenZip::execute()
{
	if (!_inited) return false;
	if (_error || _aborted) return false;

	f_Action->logB(_("Note:"), 1);
	f_Action->log(_("7-Zip requires the source files to be on one drive."));
	f_Action->log(" " + _("The 7-Zip executable will be called for every drive."), -1);

	String drive, prevDrive, file;

	// Call 7z.exe for every drive:

	std::ifstream ifs(f_Action->abtFileList->incFileName.c_str());
	if (!ifs)
	{
		f_Action->logError(ASPF(_("Could not open file: %s"),
                ecc::QuoteStr(f_Action->abtFileList->incFileName)) );
		_error = true;
		return false;
	}

	drive = prevDrive = "";

	_deleteFileListFile();
	int filesLeft = 0;
	char line[2048];

	while (ifs.getline(line, 2048))
	{
		// Test for reading more than 2048 chars or another error:
		if (ifs.fail())
		{
			f_Action->logError(__FUNC__ ": [Error while reading stream]");
			_error = true;
			break;
		}
		file = String(line);

        /* TODO 3 : drive should become (optionable) StorePath (like Zip) */
		drive = IncludeTrailingPathDelimiter(ExtractFileDrive(file));

        /* 093b1 (b.324): use OEM or UTF-8 to encode filenames in 7z listfile: */
        if (PGlobals->OEMlistfile7Zip)
            CharToOem(file.c_str(), file.c_str());
        else
            file = AnsiToUtf8(file);    // UTF-8 is default encoding in releases NEWER than 7-Zip 4.32.

		file = file.Delete(1, drive.Length());
		if (drive != prevDrive)
		{
			if (filesLeft)
				_call7ZipExe(prevDrive);    // Tests and sets _error and _aborted.
			filesLeft = 0;
			if (_error || _aborted)
				break;
			prevDrive = drive;
		}
		abtAppendStrToFile(ecc::QuoteStr(file), _fileListFile, false);
		++filesLeft;
	}
	// Do the remains:
	if (filesLeft)
		_call7ZipExe(prevDrive);    // Tests and sets _error and _aborted.
	_inited = false;    // Reset.

    // Display 7-Zip archive details:
    if ((!_aborted) && (!_error))
    {
        TFileProperties fp(_destFileName);
        if (!fp.failed())
        {
		    f_Action->logB(_("7-Zip Archive Details:"), 1);
            f_Action->log(ASPF(_("Compressed Size: %s (%s Bytes)"),
                    ecc::FloatToHumanFileSize(fp.getSize()), IntToStr(fp.getSize())) );
        }
    }

	if (_error || _aborted)
		_deleteFileListFile();

	return !(_error || _aborted);
}
//===========================================================================
// 暗号化するファイルリストとファイル情報のリストを同時生成する
//===========================================================================
__int64 __fastcall TAttacheCaseFileEncrypt::GetFileInfoList
	( int &Index,
		String DirPath,
		String FileName,
		String BasePath,
		TStringList *FileList,
		TStringList *DataList
	)
{

/* ------------------------------------------------
 ファイルリストのファイル番号の頭に「Fn_*:」と
 なぜ重複するような記号が挿入されているかと言いますと
 あまり意味はございません・・・お恥ずかしいかぎり・・・
 すみません、これもver.1からの仕様を引きずっているのと、
 習作時代にやっちゃった無意味なデータ仕様の一つです。
--------------------------------------------------- */

int ret;
__int64 TotalSize = 0;

bool fParent = false;
String OneLine;
String FilePath;
String FileNameString;

TSearchRec sr;
//_WIN32_FIND_DATAW fd;

DirPath = IncludeTrailingPathDelimiter(DirPath);

if (FileName == "") {  //ディレクトリ
	FileName = "*.*";
}
else{
	fParent = true;
}

ret = FindFirst(DirPath + FileName, faAnyFile, sr);

while (ret == 0) {

	if (sr.Name != "." && sr.Name != "..") {

		FilePath = DirPath + sr.Name;
		FileNameString = ExtractRelativePath(BasePath, FilePath);

		//-----------------------------------
		//ディレクトリ
		if (sr.Attr & faDirectory) {

			// Win95/98系(非対応だが一応)
			if ( Win32Platform == VER_PLATFORM_WIN32_WINDOWS ){
				OneLine =
					"Fn_" + IntToStr((int)Index) + ":" +                 //インデックス
					FileNameString + "\\\t" +                            //ディレクトリ名
					"*\t16\t0\t0\t0\t0";                                 //残りは0
			}
			else{
				// _WIN32_FIND_DATAW 構造体
				//fd = sr.FindData;
				OneLine =
					"Fn_" + IntToStr((int)Index) + ":" +                 //インデックス
					FileNameString + "\\\t" +                            //ディレクトリの相対パス
					"*\t" +                                              //ファイルサイズ(=0)
					IntToStr(sr.Attr) + "\t" +                           //属性
					TimeStampToString(sr.FindData.ftLastWriteTime)+"\t"+ //更新日時
					TimeStampToString(sr.FindData.ftCreationTime);       //作成日時

					//出力する暗号化ファイルのタイムスタンプを元ファイルに合わせるため保持
					if ( fKeepTimeStamp == true && first_fd.cFileName[0] == NULL ) {
						first_fd = sr.FindData;
					}

			}

			FileList->Add("");      //ディレクトリは空行
			DataList->Add(OneLine);
			Index++;

			if (fParent == false) {
				//再帰呼び出し
				TotalSize += GetFileInfoList(Index, FilePath, "", BasePath, FileList, DataList);
			}

		}
		//-----------------------------------
		//ファイル
		else{
			OneLine =
				"Fn_" + IntToStr((int)Index) + ":" +                   //インデックス
				FileNameString + "\t" +                                //ファイルの相対パス
				IntToStr(sr.Size) + "\t" +                             //ファイルサイズ
				IntToStr(sr.Attr) + "\t" +                             //属性
				TimeStampToString(sr.FindData.ftLastWriteTime)+"\t"+   //更新日時
				TimeStampToString(sr.FindData.ftCreationTime);         //作成日時

			//出力する暗号化ファイルのタイムスタンプを元ファイルに合わせるため保持
			if ( fKeepTimeStamp == true && first_fd.cFileName[0] == NULL ) {
				first_fd = sr.FindData;
			}

			if (sr.Size > 0) {
				FileList->Add(FilePath);
			}
			else{
				FileList->Add("");      //空ファイルは加えない
			}

			DataList->Add(OneLine);
			Index++;

			//ファイル総計
			TotalSize += sr.Size;

		}
		//-----------------------------------

	}//end if;

	ret = FindNext(sr);

}//while;

FindClose(sr);

return(TotalSize);


}//end GetFileInfoList;
Пример #20
0
void TProfileToGui::_listToTreeView(std::vector<String> &list, const TNodeStateIndex state,
		TTreeNode* rootnode, String rootdir)
{
	rootdir = IncludeTrailingPathDelimiter(rootdir);
	TTreeNode *node, *nod;

	_removeNonExistentDirsFromList(list);

	int pos;
	bool node_exists;
	String dir, subdir;
	for (unsigned int i = 0; i < list.size(); i++)
	{
		dir = list[i];

		// Ab.0075 Change charactercase for dir into 'real' case on disk:
        // Do not call ActualPathName() if dir is a drive (like 'C:\'):
        if (dir != IncludeTrailingPathDelimiter(ExtractFileDrive(dir)))
    		dir = IncludeTrailingPathDelimiter(ecc::ActualPathName(dir));

		// Skip directories that are not below current Root Source Dir:
		if (dir.LowerCase().Pos(rootdir.LowerCase()) != 1)
			continue;

		// Strip rootdir from dir:
		dir = dir.Delete(1, rootdir.Length());

		// Add unselected subdir:
		node = rootnode;
		while (dir.Length())
		{
			pos			= dir.Pos("\\");
			subdir		= dir.SubString(1, pos-1);
			node_exists	= false;
			nod			= node->getFirstChild();
			while (nod)
			{
				if (nod->Text.AnsiCompareIC(subdir) == 0)
				{
					node_exists = true;
					break;
				}
				nod = nod->getNextSibling();
			}

/* 092RC2: Incorrect code, replaced by code below this comment block (SE 27-mar-2006)
            if (!node_exists)
			{
				if (DirectoryExists(list[i]))
				{
					node = f_Main->fr_Source->tv_Dirs->Items->AddChild(node, subdir);
					node->StateIndex = state;
				}
			}
			dir = dir.Delete(1, pos);
			if (nod) node = nod;
		}
		node->StateIndex = state; */

            if (!node_exists)
            {
                if (DirectoryExists(list[i]))
                {
                    node = f_Main->fr_Source->tv_Dirs->Items->AddChild(node, subdir);
                    node->StateIndex = state;
                }
                else
                {
                    node = NULL;
                }
            }
            else
            {
                node = nod;
            }
            if (!node) break;
            dir = dir.Delete(1, pos);
        }
        if (node) node->StateIndex = state;
	}
}