bool z3ResEx::z3Decrypt ( TMemoryStream &src, TMemoryStream &dst, unsigned char *key, unsigned int keylen ) { StringSource keyStr( key, keylen, true ); AutoSeededRandomPool rng; ECIES<ECP>::Decryptor ellipticalEnc( keyStr ); unsigned char *tmpBuffer( new unsigned char[ src.Size() ] ); DecodingResult dr = ellipticalEnc.Decrypt( rng, src.Data(), src.Size(), tmpBuffer ); if( !( dr.isValidCoding ) || ( dr.messageLength == 0 ) ) { delete tmpBuffer; return false; } dst.Write( tmpBuffer, dr.messageLength ); delete tmpBuffer; return true; }
void z3ResEx::parseMsf( TMemoryStream &msf ) { switch( m_fileindexVer ) { case 0 : { unsigned char method( 0 ); FILEINDEX_ENTRY info; unsigned char *strMRFN( nullptr ); unsigned char *strName( nullptr ); unsigned int items( 0 ), errors( 0 ); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackStringEx( msf, strMRFN, info.lenMRFN ); unpackStringEx( msf, strName, info.lenName ); if( m_listContents ) { printf( "%s (%u bytes)\n", strName, info.size ); } else { if( !( extractItem( info, method, (char *)strMRFN, (char *)strName ) ) ) ++errors; } ++items; delete strMRFN; delete strName; } printf( "Processed %u items (%u issues)\n\n", items, errors ); break; } case 1 : { parseMsfMethod2( msf ); break; } } }
//--------------------------------------------------------------------------- void __fastcall THttpTestForm::SendButtonClick(TObject *Sender) { TMemoryStream *DataIn; TMemoryStream *DataOut; AnsiString Buf; BOOL bSuccess; DisplayMemo->Clear(); DataIn = new TMemoryStream; DataOut = new TMemoryStream; bSuccess = TRUE; try { Buf = "ID=" + UserIDEdit->Text + "&REMITE=" + EMailEdit->Text + "&MENSAJE=" + Encode(MessageEdit->Text); DataOut->Write(&Buf[1], Buf.Length()); DataOut->Seek(0, soFromBeginning); HttpCli1->SendStream = DataOut; HttpCli1->RcvdStream = DataIn; HttpCli1->Proxy = ProxyEdit->Text; HttpCli1->ProxyPort = "80"; HttpCli1->URL = "http://www.unired.net.pe/cgi-bin/a.out"; SendButton->Enabled = FALSE; AbortButton->Enabled = TRUE; try { HttpCli1->Post(); } __except (TRUE) { bSuccess = FALSE; } if (bSuccess) { DataIn->Seek(0, 0); DisplayMemo->Lines->LoadFromStream(DataIn); } SendButton->Enabled = TRUE; AbortButton->Enabled = FALSE; } __except (TRUE) { bSuccess = FALSE; } if (!bSuccess) DisplayMemo->Lines->Add("Failed : " + HttpCli1->ReasonPhrase); delete DataOut; delete DataIn; }
void z3ResEx::unpackStringEx( TMemoryStream &msf, vector<unsigned char>& buf, const unsigned int len ) const { msf.Read( &buf[0], len ); buf[len] = 0; /* Simple xor added to strings in later clients buf[0] is the xor character buf[1] to buf[size-1] contains the xored string */ if( m_fileindexVer == 1 ) { const unsigned char encKey( buf[0] ); // First byte is the key unsigned int i = 1; // Second byte starts the data while( i < len ) { // This unscrambles the string into the same buffer buf[i-1] = buf[i] ^ encKey; ++i; } buf[len-1] = 0; // Buffer now has 2 null characters at the end } }
//---------- //接口实现 //---------- TMemoryStream* TFComm::Read() { UINT8 buf[RECV_BUFF_MAX_LEN]; int rv; TMemoryStream *p; if (m_Recv->Count() > 0) { p = (TMemoryStream*)m_Recv->Pop(); p->Seek(0, soFromBeginning); rv = p->Read(buf, RECV_BUFF_MAX_LEN); LogMsg("Read" + IntToStr(rv) + ": " + StreamToText(buf, rv)); return p; } else return NULL; }
void z3ResEx::parseMsf( TMemoryStream &msf ) { switch( m_fileindexVer ) { case 0 : { unsigned char method( 0 ); FILEINDEX_ENTRY info; vector<unsigned char> strMRFN(MAX_STRING_SIZE); vector<unsigned char> strName(MAX_STRING_SIZE); unsigned int items( 0 ), errors( 0 ); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackStringEx(msf, strMRFN, info.lenMRFN); unpackStringEx(msf, strName, info.lenName); if( m_listContents ) { printf( "%s (%u bytes)\n", &strName[0], info.size ); } else { if( !( extractItem( info, method, reinterpret_cast<const char*>(&strMRFN[0]), reinterpret_cast<const char*>(&strName[0]) ) ) ) ++errors; } ++items; } printf( "Processed %u items (%u issues)\n\n", items, errors ); break; } case 1 : { parseMsfMethod2( msf ); break; } } }
//--------------------------------------------------------------------------- void __fastcall THttpTestForm::PostButtonClick(TObject *Sender) { TMemoryStream *DataOut; TFileStream *DataIn; AnsiString Buf; int I; DisplayMemo->Clear(); DocumentMemo->Clear(); SetButtonState(FALSE); DataOut = new TMemoryStream; Buf = DataEdit->Text; DataOut->Write(&Buf[1], Buf.Length()); DataOut->Seek(0, soFromBeginning); HttpCli1->SendStream = DataOut; HttpCli1->Proxy = ProxyHostEdit->Text; HttpCli1->ProxyPort = ProxyPortEdit->Text; HttpCli1->RcvdStream = NULL; HttpCli1->URL = URLEdit->Text; try { HttpCli1->Post(); } __except (TRUE) { SetButtonState(TRUE); delete DataOut; DisplayMemo->Lines->Add("POST Failed !"); DisplayMemo->Lines->Add("StatusCode = " + IntToStr(HttpCli1->StatusCode)); DisplayMemo->Lines->Add("ReasonPhrase = " + HttpCli1->ReasonPhrase); return; } delete DataOut; DisplayMemo->Lines->Add("StatusCode = " + IntToStr(HttpCli1->StatusCode)); for (I = 0; I < HttpCli1->RcvdHeader->Count; I++) DisplayMemo->Lines->Add("hdr>" + HttpCli1->RcvdHeader->Strings[I]); DataIn = new TFileStream(HttpCli1->DocName, fmOpenRead); DocumentMemo->Lines->LoadFromStream(DataIn); delete DataIn; SetButtonState(TRUE); }
void __fastcall TAboutbox::setGermanText() { String t = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang2055{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Arial;} " "{\\f1\\fswiss\\fcharset0 Arial;}} " "\\viewkind4\\uc1\\pard\\b\\f0\\fs28 DB-BEAD\\b0\\f1\\fs20\\par " "\\par " "Dies ist DB-BEAD, ein Programm, das Ihnen beim Entwurf von geh\\'e4kelten " "Perlenketten helfen soll. Die Erstellung solcher Ketten wird beispielsweise " "im Buch 'Geh\\'e4kelte Glasperlenketten' von Lotti Gygax beschrieben. Die Arbeit ist aufw\\'e4ndig und " "langwierig. Das Resultat entsch\\'e4digt aber f\\'fcr die erlittene M\\'fchsal.\\par " "\\par " "Mit DB-BEAD k\\'f6nnen Sie schon vor Beginn der Arbeit simulieren, wie Ihr " "Entwurf als Kette dann aussehen wird. Direkt am Bildschirm k\\'f6nnen Sie " "\\'c4nderungen vornehmen.\\par " "\\par " "Wenn Sie zufrieden mit dem Entwurf sind, k\\'f6nnen Sie alle notwendigen " "Daten ausdrucken lassen, inklusive einer 'F\\'e4delliste', die hilfreich " "f\\'fcr das Auff\\'e4deln der Perlen auf das H\\'e4kelgarn ist.\\par " "\\par " "DB-BEAD wurde von Damian Brunold geschrieben. Es steht unter der Lizenz " "GPL v3, was bedeutet, dass Sie es kostenlos verwenden, kopieren und \\'e4ndern " "d\\'fcrfen. Daf\\'fcr \\'fcbernimmt Damian Brunold absolut keine " "Haftung f\\'fcr Fehler und Sch\\'e4den durch Benutzung des Programmes. " "Sie m\\'fcssen selber entscheiden, ob das Programm f\\'fcr Sie n\\'fctzlich " "ist oder nicht.\\par " "\\par " "Weitere Informationen erhalten Sie unter http://www.brunoldsoftware.ch " "oder per E-Mail an [email protected]. An diese Adresse k\\'f6nnen " "Sie auch Fehler oder Verbesserungsvorschl\\'e4ge melden.\\par " "\\par " "Viel Spass mit dem Programm\\par " "Damian Brunold\\par " "}"; try { TMemoryStream* ms = new TMemoryStream(); ms->Write (t.c_str(), t.Length()); ms->Position = 0; text->Lines->LoadFromStream (ms); delete ms; } catch(...) { } }
void __fastcall TAboutbox::setEnglishText() { String t = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang2055{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Arial;} " "{\\f1\\fswiss\\fcharset0 Arial;}} " "\\viewkind4\\uc1\\pard\\b\\f0\\fs28 DB-BEAD\\b0\\f1\\fs20\\par " "\\par " "This is DB-BEAD, a program designed to help you design crochet bead ropes. " "The creation of such ropes is describes in e.g. the book " "'Geh\\'e4kelte Glasperlenketten' written by Lotti Gygax. It is hard work to " "create such a rope, but the result is very beautiful.\\par " "\\par " "With DB-BEAD you simulate before you start working how your design will " "look like as a finished rope. You can make changes directly on the screen.\\par " "\\par " "After finishing the design, you can print out all relevant data " "including a 'list of beads', which is very useful for correctly arranging " "the beads onto the thread.\\par " "\\par " "DB-BEAD was written by Damian Brunold. It is freely available and licensed " "under the GPL v3. This means, you can use and copy it freely and you can " "create derivative works (if you are a programmer). Damian Brunold cannot " "assume any liability for bugs and damage caused by using the program. " "You have to decide for yourself whether the program is useful for you or not.\\par " "\\par " "More information is available at http://www.brunoldsoftware.ch or by sending " "e-mail to [email protected]. This also is the address to direct bug " "reports or feature requests to.\\par " "\\par " "Have fun using DB-WEAVE\\par " "Damian Brunold\\par " "}"; try { TMemoryStream* ms = new TMemoryStream(); ms->Write (t.c_str(), t.Length()); ms->Position = 0; text->Lines->LoadFromStream (ms); delete ms; } catch(...) { } }
bool z3ResEx::z3Decrypt ( TMemoryStream &src, TMemoryStream &dst, unsigned char *key, unsigned int keylen ) { StringSource keyStr( key, keylen, true ); AutoSeededRandomPool rng; ECIES<ECP>::Decryptor ellipticalEnc( keyStr ); vector<unsigned char> tmpBuffer(src.Size()); DecodingResult dr = ellipticalEnc.Decrypt( rng, src.Data(), src.Size(), &tmpBuffer[0] ); if( dr.isValidCoding && dr.messageLength > 0 ) { dst.Write(&tmpBuffer[0], dr.messageLength); return true; } return false; }
bool z3ResEx::fsRle( TMemoryStream &src, TMemoryStream &dst, bool isMSF ) { unsigned int msfSizeFlag; unsigned int expectedSize, len; unsigned char *pData( src.Data() ), *pDataEnd( pData + src.Size() ); if( isMSF ) { // Read the expected size from data msfSizeFlag = src.ReadUInt(); pData += 4; } if( !( z3Rle::decodeSize( pData, expectedSize, len ) ) ) { dst.Close(); //printf("ERROR: Problems decoding RLE buffer size\n"); return false; } if( isMSF && !( msfSizeFlag == expectedSize ) ) { dst.Close(); //printf("ERROR: Unexpected MSF buffer size\n"); return false; } // Skip the length of the expected size pData += len; unsigned char *tmpBuffer( new unsigned char[ expectedSize ] ); unsigned int tmpOffset( 0 ); while( tmpOffset < expectedSize ) { if( !( z3Rle::decodeInstruction( pData, len, pDataEnd, tmpBuffer, tmpOffset ) ) ) { delete tmpBuffer; //printf("ERROR: Problems decoding RLE buffer\n"); return false; } pData += len; } dst.Write( tmpBuffer, expectedSize ); delete tmpBuffer; return true; }
bool z3ResEx::extractItem( FILEINDEX_ENTRY &info, unsigned char method, const char *strMrf, const char *strName ) { TFileStream mrf( strMrf ); if( !( mrf.isOpen() ) ) { setMessage( "ERROR: Unable to open file (%s)", strMrf ); return false; } // Format the output filename std::string fname( fsRename( strMrf, strName ) ); // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } vector<unsigned char> buf( info.zsize ); // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( &buf[0], info.zsize ); mrf.Close(); // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( &buf[0], info.zsize ); buf.clear(); printf ( ( m_doExtraction ? "Saving %s.. " : "Checking %s.. " ), fname.substr( fname.rfind('/') +1 ).c_str() ); // Create path only when extraction is flagged if( m_doExtraction ) fsCreatePath( fname ); switch( method ) { // Compressed, most files case FILEINDEX_ENTRY_COMPRESSED : { fsXor( fdata, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); puts(" ..done!"); } // fsRle will display any errors fdata_raw.Close(); break; } // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( fdata, fdata_dec, m_fileindexKey, m_fileindexKeyLength ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( fdata_dec, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); printf(" ..done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } // Large files, some FSB (GunZ 2) case FILEINDEX_ENTRY_UNCOMPRESSED : { if( m_doExtraction ) fdata.SaveToFile( fname.c_str() ); puts(" ..done!"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", method); return false; } } fdata.Close(); return true; }
void z3ResEx::parseMsfMethod2( TMemoryStream &msf ) { unsigned short strLen( 0 ); unsigned short mrfIndexLen( 0 ); // Folders are now in a table at the top of the file msf.Read( &mrfIndexLen, sizeof( unsigned short ) ); if (mrfIndexLen == 0) { // There are no folders in the filesystem return; } // List of filenames vector<string> vecMsf(mrfIndexLen); vector<unsigned char> strBuffer(MAX_STRING_SIZE); // MRF filenames are now packed in a list for( unsigned short i( 0 ); i != mrfIndexLen; ++i ) { strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); // Required to rename files //vecMsf[i].first.assign( (char *)strBuffer ); // Cached file opening (and a pointer so we can call the constructor) //vecMsf[i].second = new TFileStream( strBuffer ); vecMsf[i] = string(strBuffer.begin(), strBuffer.end()); } // Files are now listed (similar to before) FILEINDEX_ENTRY2 fiItem; unsigned int items( 0 ), errors( 0 ); //msf.SaveToFile("debugFilesys.dat"); bool bMatchesCriteria = true; string tmpFilename; while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { msf.Read( &fiItem, sizeof( FILEINDEX_ENTRY2 ) ); strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); if( !m_folderCriteria.empty() ) { tmpFilename = string(strBuffer.begin(), strBuffer.end()); std::transform(tmpFilename.begin(), tmpFilename.end(), tmpFilename.begin(), ::toupper); bMatchesCriteria = !( tmpFilename.find( m_folderCriteria ) == string::npos ); } if( bMatchesCriteria ) { if( m_listContents ) { printf( "%s (%u bytes)\n", &strBuffer[0], fiItem.size ); } else { if( !( extractItem2( fiItem, vecMsf[ fiItem.mrfIndex ], reinterpret_cast<const char*>(&strBuffer[0]) ) ) ) ++errors; } } ++items; } vecMsf.clear(); printf( "Processed %u items (%u issues)\n\n", items, errors ); }
void z3ResEx::fsXor( TMemoryStream &src, unsigned int key ) const { z3Xor::rs3Unscramble( src.Data(), src.Size(), key ); }
//添加数据到接收缓冲 void TFComm::SendToRecvBuf(UINT8 *pstream, UINT32 szLen) { TMemoryStream *pms = new TMemoryStream(); pms->Write(pstream, szLen); m_Recv->Push(pms); }
//--------------------------------------------------------------------------- int __fastcall TTrdCot_Rm::Request(TRequest Request,TAnswer **Answer,int &AnsCount) { TAnswer answer; int retVal = 0; Request.Head.Version = 2010; try { TMemoryStream* dest = new TMemoryStream(); int orgsize = sizeof(Request) ; dest->Write(&orgsize,sizeof(int)); TCompressionStream * cs = new TCompressionStream(Zlib::clDefault,dest); TMemoryStream *source = new TMemoryStream(); TDecompressionStream *ds = new TDecompressionStream(source); FCS->Enter(); try { memset(&answer,0,sizeof(TAnswer)); if( Request.Head.FuncType == ftInit) { this->Connect(); if( FTcpClt->Connected() == false ) return ERR_TRDSVR_SEND_FAILED; FTcpClt->Socket->UseNagle = false; } cs->Write(&Request,sizeof(Request)); delete cs; cs = NULL; if( FTcpClt == NULL ) return -1000; // 发送请求 try { FTcpClt->IOHandler->LargeStream = false; FTcpClt->IOHandler->Write(dest,0x000000000,true); } catch(...) { retVal = ERR_TRDSVR_SEND_FAILED; FTcpClt->Disconnect(); return retVal; } delete dest; dest = NULL; // 接收响应 try { int size = FTcpClt->IOHandler->ReadInteger(false); if( size >0 ) { orgsize = FTcpClt->IOHandler->ReadInteger(false); FTcpClt->IOHandler->ReadStream(source,size-sizeof(int),false); if( sizeof(TAnswer) != ds->Read(&answer,sizeof(TAnswer)) ) { throw ""; } } else { throw ""; } } catch(...) { retVal = ERR_TRDSVR_RECV_FAILED; FTcpClt->Disconnect(); return retVal; } retVal = answer.Head.RetVal; if(retVal==0) { AnsCount = answer.Head.AnsCount; if(AnsCount>0) { *Answer = new TAnswer[AnsCount]; try { memcpy(&(*Answer)[0],&answer,sizeof(TAnswer)); int len = sizeof(TAnswer)*(AnsCount-1); if( len!= ds->Read(&(*Answer)[1],len)) { throw ""; } } catch(...) { delete [] (*Answer); retVal= ERR_TRDSVR_RECV_FAILED; FTcpClt->Disconnect(); return retVal; } } } delete source; source = NULL; delete ds; ds = NULL; } __finally { FCS->Leave(); if( dest ) delete dest; if( source) delete source; if( ds ) delete ds; if (cs) delete cs; } } catch(...) { retVal= ERR_REMOTE_OTHER_FAILED; } return retVal; }
//=========================================================================== // スレッド実行 //=========================================================================== void __fastcall TAttacheCaseFileEncrypt::Execute() { int i, c; int res; float ProgressPercentNumF; //進捗パーセンテージ(浮動小数点) z_stream z; // zlibライブラリとやりとりするための構造体 int flush, status; // zlib //出力する暗号化ファイルのタイムスタンプを元ファイルに合わせる HANDLE hFile; //_WIN32_FIND_DATAW first_fd; ZeroMemory(&first_fd, sizeof(_WIN32_FIND_DATAW)); int len, pos; int FileIndex; String FilePath; int HeaderSize; //ヘッダデータサイズ __int64 CurrentDriveFreeSpaceSize = -1; //保存するドライブの空き容量 //実行可能形式出力ファイルのデータサイズ __int64 ExeAllSize = 0; __int64 ExeSize = 0; //全体のファイルサイズ AllTotalSize = 0; __int64 TotalSize = 0; //バッファ char source_buffer[BUF_SIZE]; char read_buffer[BUF_SIZE]; char out_buffer[BUF_SIZE]; char chain_buffer[BUF_SIZE]; // IVなどを格納するチェインバッファ char margin_buffer[BUF_SIZE]; //ファイルストリーム TFileStream *fsIn; TFileStream *fsOut; TFileStream *fsExe; //オープン中か bool fOpenIn; bool fOpenOut; //メモリストリーム TMemoryStream *pms = new TMemoryStream; // マージンバッファサイズ int MarginBufSize = MARGIN_BUF_SIZE; // PKCS #7 Pading num. unsigned char paddingNum = 0; //--------------------------------------- // 同名ファイルがあるのでダイアログ表示 //--------------------------------------- if ( fConfirmOverwirte == true && fOverwirteYesToAll == false ) { if (FileExists(OutFilePath) == true) { //同名ファイルの上書き確認メッセージダイアログ MsgText = LoadResourceString(&Msgencrypt::_MSG_CONFIRM_OVER_WRITE_SAME_FILE)+"\n"+OutFilePath; Synchronize(&PostConfirmOverwriteMessageForm); if ( MsgReturnVal == mrYes ) { //上書きOKなのでFilePathはそのまま } else if ( MsgReturnVal == mrNo ) { //別名保存でFilePath文字列が書き換えられてきている OutFilePath = MsgReturnPath; } else if ( MsgReturnVal == mrYesToAll ) { //すべて上書き(YesToAll) fOverwirteYesToAll = true; } else if ( MsgReturnVal == mrCancel ) { //キャンセル delete pms; goto LabelStop; } } } //--------------------------------------- // ヘッダ情報の生成&ファイル総サイズ取得 //--------------------------------------- //'暗号化するファイルリストの生成中...' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_LISTING); if ( CreateHeaderData( pms, InputFileList, FilePathList, AllTotalSize) == false ){ if (Terminated == true) { //ユーザーキャンセルで抜けてきた delete pms; goto LabelStop; } else{ //'暗号化するファイルを開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_FILE_OPEN); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } } //----------------------------------- // ディスクの空き容量チェック //----------------------------------- CurrentDriveFreeSpaceSize = GetDiskFreeSpaceNum(OutFilePath); if (CurrentDriveFreeSpaceSize > -1 ) { if ( AllTotalSize > CurrentDriveFreeSpaceSize ) { //"ディスクの空き容量が足りません! 暗号化ファイルを保存できません。\n //暗号化を中止します。;" MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_NO_DISK_FREE_SPACE); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } } else{ // -1はネットワークドライブの可能性があるので無視 //(万が一、別のエラーの場合、実際書き込みに移行したときエラーが発生する) } //----------------------------------- // 実行可能形式でかつ // 合計バイト数が4GBを越えたときのエラー //----------------------------------- if ( fExeOutputOption == true && fOver4gbOk == false && AllTotalSize > SIZE_4GB ){ //実行形式ファイルのサイズが4GBを超えてしまう可能性があります!\n //Win32アプリケーションとして実行できなくなるかもしれませんがよろしいですか?'; MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OVER_4GB_EXE); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbYes << mbNo; MsgDefaultButton = mbNo; Synchronize(&PostConfirmMessageForm); if ( MsgReturnVal == mbNo) { //キャンセル delete pms; goto LabelStop; } } //----------------------------------- // 暗号化ファイルの生成開始 //----------------------------------- //'暗号化しています...' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ENCRYPTING); ProgressMsgText = ExtractFileName(OutFilePath); TotalSize = 0; try{ fsOut = new TFileStream(OutFilePath, fmCreate); fOpenOut = true; } catch(...){ //'保存する先のファイルが開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_OPEN) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } //----------------------------------- // 実行可能形式の出力 //----------------------------------- if ( fExeOutputOption == true ){ //----------------------------------- // 自分のお尻から実行データを抽出 //----------------------------------- //自分自身の実行ファイルを開く try{ fsExe = new TFileStream(Application->ExeName, fmOpenRead | fmShareDenyWrite); } catch(...){ //'実行可能形式出力に失敗しました。暗号化処理を中止します。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_EXEOUT_FAILED); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); delete pms; goto LabelError; } //切り出すサイズを取得 fsExe->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd); fsExe->Read(&ExeAllSize, sizeof(__int64)); //処理する合計サイズに実行形式分を加える AllTotalSize += ExeAllSize; //自己実行可能形式データの境界へ fsExe->Seek(-(__int64)ExeAllSize-sizeof(__int64), TSeekOrigin::soEnd); while(fsExe->Read(read_buffer, BUF_SIZE) != 0 ){ ExeSize+=BUF_SIZE; //書き込む if ( ExeSize < ExeAllSize ){ fsOut->Write(read_buffer, BUF_SIZE); TotalSize += BUF_SIZE; } else{ fsOut->Write(read_buffer, ExeSize-ExeAllSize); TotalSize += (ExeSize-ExeAllSize); } //進捗表示 ProgressPercentNumF = (float)TotalSize/AllTotalSize; ProgressPercentNum = (int)(ProgressPercentNumF*100); if (AllTotalSize < 104857600) { // 100MB未満 ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%"; } else{ ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%"; } } //自分自身を閉じる delete fsExe; } //----------------------------------- // ヘッダ情報の描き込み //----------------------------------- pms->SaveToStream(fsOut); //fsOutに追記 delete pms; //----------------------------------- // Rijndaelの初期化 //----------------------------------- gentables(); gkey( 8, 8, key); // 初期化ベクトルを生成して先頭に書き込む fillrand(chain_buffer, BUF_SIZE); if ( fsOut->Write(chain_buffer, BUF_SIZE) < BUF_SIZE ){ //''保存先に指定された暗号化ファイルに書き込めません。 MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } //----------------------------------- // zlib 初期化(圧縮においてすべてのメモリ管理をライブラリに任せる) z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; //z.next_in = Z_NULL; // 第2引数は圧縮の度合。0~9 の範囲の整数で,0 は無圧縮 // Z_DEFAULT_COMPRESSION (= 6) が標準 if (deflateInit(&z, CompressRateNum) != Z_OK){ //zlibエラー表示はラベル先で goto LabelError; } //出力バッファの初期化 for(i = 0; i < BUF_SIZE; i++){ out_buffer[i] = 0; } // zlibに入出力バッファをセットする z.avail_in = 0; // 入力バッファ中のデータのバイト数 z.next_out = out_buffer; // 出力バッファ残量 z.avail_out = BUF_SIZE; // 出力ポインタ // 通常は deflate() の第2引数は Z_NO_FLUSH にして呼び出す flush = Z_NO_FLUSH; FileIndex = 0; while(!Terminated) { //----------------------------------- //入力 //----------------------------------- if ( z.avail_in == 0 && flush != Z_FINISH){ pos = 0; for(i = 0; i < BUF_SIZE; i++){ source_buffer[i] = 0; read_buffer[i] = 0; } while ( pos < BUF_SIZE ){ //オープン中のファイルがあればそこから読む if ( fOpenIn == true ) { if (pos < BUF_SIZE) { len = fsIn->Read(read_buffer, BUF_SIZE - pos); TotalSize+=len; for (i = 0; i < len; i++) { source_buffer[pos+i] = read_buffer[i]; } if (len < BUF_SIZE - pos) { fOpenIn = false; //ファイルを閉じる delete fsIn; } } pos += len; } //ファイルを開く else{ if (FileIndex < FilePathList->Count) { while(FileIndex < FilePathList->Count){ if (FilePathList->Strings[FileIndex] != "") { try{ fsIn = new TFileStream(FilePathList->Strings[FileIndex], fmOpenRead | fmShareDenyWrite); fOpenIn = true; FileIndex++; break; } catch(...){ //'暗号化するファイルを開けません。他のアプリケーションが使用中の可能性があります。' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_FILE_OPEN); MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); fOpenIn = false; goto LabelError; } } FileIndex++; } } else{ //読み込むファイルがなくなったので、 //お尻にダミーのマージンデータを挿入する // //【補足】 // 本来はここにあるマージンデータ挿入処理は不要ですが、 // 昔に作った際に復号の際に圧縮データ境界のチェックを // 怠っていたため、このように余分なデータを // 入れておくという力業を使っています(すみません...) fillrand(margin_buffer, BUF_SIZE); for (i = pos; i < BUF_SIZE; i++) { source_buffer[i] = margin_buffer[i]; } pos = BUF_SIZE; MarginBufSize -= BUF_SIZE; }//end if (FileIndex < FilePathList->Count); }//end if ( fOpenIn == true ); }//while ( pos < BUF_SIZE && 0 < MarginBufSize ); if (MarginBufSize < 1) { flush = Z_FINISH; //入力バッファはこれが最後 } z.next_in = source_buffer; z.avail_in = pos; }//end if ( z.avail_in == 0 ); //----------------------------------- //圧縮 //----------------------------------- if ( z.avail_out > 0 ){ status = deflate(&z, flush); } if (status == Z_STREAM_END){ break; } if (status != Z_OK ){ //#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; } //----------------------------------- //出力 //----------------------------------- if ( z.avail_out == 0 ){ // CBC - xor the file bytes with the IV bytes for(i = 0; i < BUF_SIZE; i++){ out_buffer[i] ^= chain_buffer[i]; } //encrypt! rijndael_encrypt(out_buffer); len = fsOut->Write(out_buffer, BUF_SIZE); if (len < BUF_SIZE) { //'保存先に指定された暗号化ファイルに書き込めません。 MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } for(i = 0; i < BUF_SIZE; i++){ chain_buffer[i] = out_buffer[i]; out_buffer[i] = 0; } z.next_out = out_buffer; // 出力バッファ残量を元に戻す z.avail_out = BUF_SIZE; // 出力ポインタを元に戻す } //----------------------------------- //進捗状況表示 if (AllTotalSize == 0) { ProgressPercentNum = 100; ProgressPercentNumText = "100%"; } else if (TotalSize == 0) { ProgressPercentNum = 0; ProgressPercentNumText = "0%"; } else{ ProgressPercentNumF = (float)TotalSize/AllTotalSize; ProgressPercentNum = (int)(ProgressPercentNumF*100); if (AllTotalSize < 104857600) { // 100MB未満 ProgressPercentNumText = IntToStr(ProgressPercentNum)+"%"; } else{ ProgressPercentNumText = FloatToStrF(ProgressPercentNumF*100, ffNumber, 4, 1)+"%"; } } //----------------------------------- if ( fOpenIn == true ){ ProgressMsgText = ExtractFileName(fsIn->FileName); } else{ ProgressMsgText = ExtractFileName(OutFilePath); } }//while(!Terminated); if (Terminated == true) { //ユーザーキャンセルで抜けてきた goto LabelStop; } //残りのバッファ if (z.avail_out > 0) { // PKCS #7 パディング len = BUF_SIZE - z.avail_out; paddingNum = (char)z.avail_out; for(i = len; i < BUF_SIZE; i++){ out_buffer[i] = paddingNum; } // CBC - xor the file bytes with the IV bytes for(i = 0; i < BUF_SIZE; i++){ out_buffer[i] ^= chain_buffer[i]; } //encrypt! rijndael_encrypt(out_buffer); if ((len = fsOut->Write(out_buffer, BUF_SIZE)) != BUF_SIZE){ //'保存先に指定された暗号化ファイルに書き込めません。 MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_OUT_FILE_WRITE) + "\n" + OutFilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } } if (deflateEnd(&z) != Z_OK){ //zlibエラー goto LabelError; } //----------------------------------- // 実行可能形式ファイルは // 末尾へ暗号化データサイズを書き込む //----------------------------------- if ( fExeOutputOption == true ){ ExeSize = fsOut->Seek((__int64)0, TSeekOrigin::soEnd); ExeSize = ExeSize-ExeAllSize; fsOut->Write(&ExeSize, sizeof(__int64)); } //----------------------------------- // 完了 //----------------------------------- ProgressPercentNum = 100; //'完了' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_COMPLETE); ProgressMsgText = ExtractFileName(OutFilePath); if (fOpenIn == true) { delete fsIn; } if (fOpenOut == true) { delete fsOut; } //出力する暗号化ファイルのタイムスタンプを元ファイルに合わせる if ( fKeepTimeStamp == true && first_fd.cFileName[0] != NULL ) { hFile = CreateFileW(FilePath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { SetFileTime( hFile, &first_fd.ftCreationTime, &first_fd.ftLastAccessTime, &first_fd.ftLastWriteTime); CloseHandle(hFile); } } StatusNum = 1; return; //----------------------------------- // エラーの後始末 //----------------------------------- LabelError: ProgressPercentNum = 0; if ( status < 0 ){ //'zlibライブラリからエラーを返されました。' //'エラー番号:' MsgText = LoadResourceString(&Msgencrypt::_MSG_ERROR_ZLIB) + IntToStr(status) + "\n" + z.msg; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); } //'エラー' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ERROR); //'暗号化に失敗しました。' ProgressMsgText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_DETAIL_FAILED); if (fOpenIn == true) { delete fsIn; } if (fOpenOut == true) { delete fsOut; } StatusNum = -1; return; //----------------------------------- // ユーザーキャンセルの後始末 //----------------------------------- LabelStop: ProgressPercentNum = 0; //'キャンセル' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_USER_CANCEL); //'暗号化が中止されました。' ProgressMsgText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_DETAIL_STOPPED); if (fOpenIn == true) { delete fsIn; } if (fOpenOut == true) { delete fsOut; } StatusNum = -2; return; }
bool extractItem( FILEINDEX_ENTRY &info, unsigned char method, char *strMrf, char *strName ) { TFileStream mrf( strMrf ); if( !( mrf.isOpen() ) ) { printf("ERROR: Could not open file (%s)\n", strMrf ); return false; } // Format the output filename std::string fname( fsRename( strMrf, strName ) ); #ifdef VERBOSE printf("Using filename: %s\n", fname.c_str()); #endif // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } unsigned char *buf( new unsigned char[ info.zsize ] ); #ifdef VERBOSE printf("Allocated %u bytes\n", info.zsize); #endif // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( buf, info.zsize ); mrf.Close(); #ifdef VERBOSE printf("Read %u bytes at %u\n", info.zsize, info.offset ); #endif // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( buf, info.zsize ); delete buf; printf ( ( user_opt_allow_extraction ? "Saving %s.. " : "Checking %s.. " ), fname.substr( fname.rfind('/') +1 ).c_str() ); // Create path only when extraction is flagged if( user_opt_allow_extraction ) fsCreatePath( fname ); switch( method ) { // Compressed, most files case FILEINDEX_ENTRY_COMPRESSED : { fsXor( info, fdata ); #ifdef VERBOSE printf("Complete XOR routine\n"); #endif TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { #ifdef VERBOSE printf("Completed RLE routine\n"); #endif if( user_opt_allow_extraction ) fdata_raw.SaveToFile( fname.c_str() ); printf("done!\n"); } // fsRle will display any errors fdata_raw.Close(); break; } // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( z3CurrentKey, fdata, fdata_dec ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( info, fdata_dec ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( user_opt_allow_extraction ) fdata_raw.SaveToFile( fname.c_str() ); printf("done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } // Large files, some FSB (GunZ 2) case FILEINDEX_ENTRY_UNCOMPRESSED : { if( user_opt_allow_extraction ) fdata.SaveToFile( fname.c_str() ); printf("done!\n"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", method); return false; } } fdata.Close(); return true; }
int main( int argc, char **argv ) { printf ( "z3ResEx" \ "\nResearched and coded by x1nixmzeng\n\n" ); // Check arguments if( argc > 1 ) { if( SetCurrentDirectory( argv[1] ) == 0 ) { printf("ERROR: Failed to set the client path (%s)\n", argv[1] ); return 0; } if( argc > 2 ) { // For all other arguments, check against known flags if( argv[2][0] == '-' ) { // -v Verbose // todo // -l List all files if( argv[2][1] == 'l' ) { user_opt_list_files = true; } else // -x No extraction if( argv[2][1] == 'x' ) { user_opt_allow_extraction = false; } // -f Extract only (filter) // todo } } } // Check the fileindex exists if( TFileSize( msfName ) == 0 ) { printf("ERROR: Unable to open file (%s)\n", msfName); } else { unsigned int keyIndex( 0 ); TMemoryStream msf; // Brute-force the key while( ( keyIndex < Z3_KEY_LIST_LENGTH ) && ( msf.Size() == 0 ) ) { if( fsReadMSF( msf, Z3_KEY_LIST[ keyIndex ] ) ) { z3CurrentKey = Z3_KEY_LIST[ keyIndex ]; // todo: verbose? - show key } ++keyIndex; } if( !( z3CurrentKey == nullptr ) ) { // Run main extraction loop if( !( user_opt_allow_extraction ) ) printf("NOTE: Opted NOT to save data\n"); extractionMain( msf ); } else { // No key found or incompatiable file (not checked) printf("ERROR: This file is using an updated key or unsupported method\n"); } msf.Close(); } return 0; }
void extractionMain( TMemoryStream &msf ) { const unsigned int MAX_ERRORS( 50 ); unsigned int items( 0 ); FILEINDEX_ENTRY info; unsigned char method; char *strMRFN( nullptr ), *strName( nullptr ); #define unpackString(buf,len) \ { \ buf = new char[ len +1 ]; \ msf.Read( buf, len ); \ buf[ len ] = 0; \ } #ifdef SAVE_MSF_FILEINDEX msf.SaveToFile("z3debug_fileindex.msf"); #endif // Are we just listing files? if( user_opt_list_files ) { std::string fname; printf("Listing filesystem contents\n\n"); while( msf.Position() < msf.Size() ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackString( strMRFN, info.lenMRFN ); unpackString( strName, info.lenName ); fname = fsRename( strMRFN, strName ); printf("%s\n", fname.c_str()); ++items; delete strMRFN; delete strName; } fname.clear(); printf("\nLocated %u files\n", items); } else // Run the main extraction loop { unsigned int errors( 0 ); printf("Extracting filesystem contents\n\n"); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackString( strMRFN, info.lenMRFN ); unpackString( strName, info.lenName ); if( !( extractItem( info, method, strMRFN, strName ) ) ) ++errors; ++items; delete strMRFN; delete strName; } if( errors >= MAX_ERRORS ) printf("ERROR: Extraction stopped as there were too many errors\n"); else printf("\nExtracted %u files (%u problems)\n", items, errors); } }
void z3ResEx::parseMsfMethod2( TMemoryStream &msf ) { unsigned short strLen( 0 ); unsigned char *strBuffer( nullptr ); unsigned short mrfIndexLen( 0 ); // Folders are now in a table at the top of the file msf.Read( &mrfIndexLen, sizeof( unsigned short ) ); // List of filenames //typedef std::pair<string, TFileStream* > mrfItem; typedef vector<string > mrfItemList; mrfItemList vecMsf; vecMsf.resize( mrfIndexLen ); // MRF filenames are now packed in a list for( unsigned short i( 0 ); i != mrfIndexLen; ++i ) { strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); // Required to rename files //vecMsf[i].first.assign( (char *)strBuffer ); // Cached file opening (and a pointer so we can call the constructor) //vecMsf[i].second = new TFileStream( strBuffer ); vecMsf[i].assign( (char *)strBuffer ); delete strBuffer; } // Files are now listed (similar to before) FILEINDEX_ENTRY2 fiItem; unsigned int items( 0 ), errors( 0 ); //msf.SaveToFile("debugFilesys.dat"); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { msf.Read( &fiItem, sizeof( FILEINDEX_ENTRY2 ) ); strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); if( m_listContents ) { printf( "%s (%u bytes)\n", strBuffer, fiItem.size ); } else { if( !( extractItem2( fiItem, vecMsf[ fiItem.mrfIndex ], (char *)strBuffer ) ) ) ++errors; } delete strBuffer; ++items; } vecMsf.clear(); printf( "Processed %u items (%u issues)\n\n", items, errors ); }
void __fastcall TForm1::SpeedButton1Click(TObject *Sender) { TMemoryStream *d = new TMemoryStream(); FormelIntr *fi = new FormelIntr(); long double res; long double max = 0; #define VARCOUNT 3 FormIntrVar vars[VARCOUNT] = { { "rand" , 0 } , { "t" , 0 } , { "pi" , 3.141592654 } }; FormIntrError error; int SampRate = StrToInt ( ComboBox1->Text.SubString ( 1, 5 ) ); randomize(); for ( long double i = 0; i < CSpinEdit1->Value * SampRate; i++ ) { vars[0].Val = (long double)(rand()*rand()) / ((long double)rand()+1); vars[1].Val = (long double)i / (long double)SampRate; fi->Calc ( res, Edit1->Text.c_str(), VARCOUNT, vars, error ); if ( error.ErrNum != 0 ) res = 0.0; d->Write ( &res, sizeof ( res ) ); if ( res > max ) max = res; else if ( res < (-max) ) max = -res; } if ( max == 0 ) { delete d; delete fi; OUTPUT ( "Error" ); return; } long double scal = (long double)30000 / max; delete SoundBuffer; SoundBuffer = new TMemoryStream(); Chart1->Series[0]->Clear(); Chart2->Series[0]->Clear(); WaveHeader ( SoundBuffer, SampRate, d->Size / sizeof(res) ); d->Position = 0; short signed end = -1; short unsigned x1, x2; x2 = CSpinEdit2->Value; x1 = 0; while ( d->Read ( &res, sizeof(res) ) == sizeof( res ) ) { end = ( res * scal ); SoundBuffer->Write ( &end, 2 ); if ( x1 <= 0 ) { Chart1->Series[0]->AddY ( end, "", clTeeColor ); Chart2->Series[0]->AddY ( end, "", clTeeColor ); x1 = x2; } x1--; } delete d; delete fi; OUTPUT ( "Created" ); }
//=========================================================================== //スレッド実行 //=========================================================================== 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; }
bool z3ResEx::extractItem2( FILEINDEX_ENTRY2 &info, const string &strMrf, char *strName ) { TFileStream mrf( strMrf.c_str() ); if( !( mrf.isOpen() ) ) { setMessage( "ERROR: Unable to open file (%s)", strMrf.c_str() ); return false; } // Format the output filename std::string fname( fsRename( strMrf.c_str(), strName ) ); // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } unsigned char *buf( new unsigned char[ info.zsize ] ); // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( buf, info.zsize ); mrf.Close(); // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( buf, info.zsize ); delete buf; printf( "Saving %s.. ", fname.substr( fname.rfind('/') +1 ).c_str() ); fsCreatePath( fname ); switch( info.type ) { case FILEINDEXITEM_COMPRESSED : { fsXor( fdata, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); puts(" ..done!"); } // fsRle will display any errors fdata_raw.Close(); break; } /* // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( fdata, fdata_dec, m_fileindexKey, m_fileindexKeyLength ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( info, fdata_dec ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); printf(" ..done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } */ case FILEINDEXITEM_UNCOMPRESSED : { fdata.SaveToFile( fname.c_str() ); puts(" ..done!"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", info.type); return false; } } fdata.Close(); return true; }
//=========================================================================== // ヘッダ情報を生成する //=========================================================================== bool __fastcall TAttacheCaseFileEncrypt::CreateHeaderData (TMemoryStream *pms, TStringList *FileList, TStringList *FilePathList, __int64 &AllTotalFileSize) { int i, c; int ret; int Index = 0; int HeaderSizeAddress = 0; TSearchRec sr; String OneLine; String DirPath, FileName; String MsgText; //暗号部トークン const AnsiString Passcode_AttacheCase = "Passcode:AttacheCase\n"; //暗号化ファイルの作成日 AnsiString LastDateTimeString = "LastDateTime:" + DateTimeToStr(Now()) + "\n"; //旧ヘッダーテキストすべて AnsiString Fn_HeaderText; //Unicode用ヘッダーテキストすべて String U_HeaderText; int EncryptHeaderSize = 0; //暗号部ヘッダサイズ char buffer[BUF_SIZE]; char chain_buffer[BUF_SIZE]; TStringList *HeaderDataList; TMemoryStream* tpms; //テンポラリメモリストリーム //----------------------------------- // ヘッダ情報(平文) //----------------------------------- const char charReservedValue[4] = { 0, 0, 0, 0 }; const char charDataSubVersion = ATC_DATA_SUB_VERSION; const char charOptMissTypeLimitsNumOption = intOptMissTypeLimitsNumOption; const char charOptBrokenFileOption = (fOptBrokenFileOption > 0 ? 1 : 0); const char charTokenString[17] = "_AttacheCaseData"; const int DataFileVersion = ATC_DATA_FILE_VERSION; const int AlgorismType = TYPE_ALGORISM_RIJNDAEL; //データサブバージョン : 1byte pms->Write(&charDataSubVersion, sizeof(char)); //予約データ(reserved) : 1byte pms->Write(&charReservedValue, sizeof(char)); //ミスタイプ回数 : 1byte pms->Write(&charOptMissTypeLimitsNumOption, sizeof(char)); //破壊するか否か : 1byte pms->Write(&charOptBrokenFileOption, sizeof(char)); //トークン : 16byte pms->Write(&charTokenString, 16); //データファイルバージョン : 4byte pms->Write(&DataFileVersion, sizeof(int)); //アルゴリズムタイプ : 4byte pms->Write(&AlgorismType, sizeof(int)); //暗号化部分のヘッダデータサイズ(先に確保しておく):4byte HeaderSizeAddress = pms->Position; pms->Write(&EncryptHeaderSize, sizeof(int)); //----------------------------------- // ヘッダ情報(暗号化部分) //----------------------------------- //進捗状況表示 ProgressPercentNum = -1; //'暗号化するファイルリストの生成中...' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_LISTING); //ヘッダデータリスト(文字列) HeaderDataList = new TStringList; //パスワード HeaderDataList->Add(Passcode_AttacheCase); //作成日 HeaderDataList->Add(LastDateTimeString); for ( i = 0; i < FileList->Count; i++ ){ //ファイル if (FileExists(FileList->Strings[i]) == true) { DirPath = ExtractFileDir(FileList->Strings[i]); FileName = ExtractFileName(FileList->Strings[i]); ProgressMsgText = FileName; //処理中のファイル名 AllTotalFileSize += GetFileInfoList(Index, DirPath, FileName, FileList->Strings[i], FilePathList, HeaderDataList); } //ディレクトリ else{ DirPath = ExtractFileDir(FileList->Strings[i]); FileName = ExtractFileName(FileList->Strings[i]); ProgressMsgText = FileName; //処理中のファイル名 //トップディレクトリ GetFileInfoList(Index, DirPath, FileName, FileList->Strings[i], FilePathList, HeaderDataList); //その配下 AllTotalFileSize += GetFileInfoList(Index, FileList->Strings[i], "", FileList->Strings[i], FilePathList, HeaderDataList); } //ユーザーキャンセル if (Terminated == true) { delete HeaderDataList; return(false); } }// end for; //進捗状況表示 ProgressPercentNum = -1; //'ヘッダデータを書き込んでいます...' ProgressStatusText = LoadResourceString(&Msgencrypt::_LABEL_STATUS_TITLE_ENCRYPTING_LIST); ProgressMsgText = ""; //メモリストリームへ書き込み tpms = new TMemoryStream; //------------------------------------------------ // 暗号化時にヘッダデータの互換性維持 //--------------------------------------------------- HeaderDataList->SaveToStream(tpms, TEncoding::GetEncoding(932)); //新バージョン(ver.2.8.0~)用(UTF-8)に保存 for (i = 0; i < HeaderDataList->Count; i++) { HeaderDataList->Strings[i] = StringReplace(HeaderDataList->Strings[i],"Fn_","U_",TReplaceFlags()<<rfIgnoreCase ); } HeaderDataList->SaveToStream(tpms, TEncoding::UTF8); delete HeaderDataList; //----------------------------------- //ヘッダ情報の暗号化 //----------------------------------- //暗号化の準備 gentables(); //キー入力 gkey( 8, 8, key); for (i = 0; i < BUF_SIZE; i++) { buffer[i] = 0; } //初期化ベクトル(IV)を生成 fillrand(chain_buffer, BUF_SIZE); pms->Write(chain_buffer, BUF_SIZE); //先頭にポインタを戻す tpms->Seek((__int64)0, TSeekOrigin::soBeginning); EncryptHeaderSize = 0; //CBCモードで書き込む while (tpms->Read( buffer, BUF_SIZE ) != NULL){ EncryptHeaderSize += BUF_SIZE; // xor for ( i = 0; i < BUF_SIZE; i++ ){ buffer[i] ^= chain_buffer[i]; } // rijndael rijndael_encrypt(buffer); pms->Write(buffer, BUF_SIZE); //CBC&バッファの初期化 for ( i = 0; i < BUF_SIZE; i++ ){ chain_buffer[i] = buffer[i]; buffer[i] = 0; } //ユーザーキャンセル if (Terminated == true) { delete tpms; return(false); } }//loop; delete tpms; //暗号化部分のヘッダデータサイズ(確保しておいた場所へ改めて書き込む) pms->Position = HeaderSizeAddress; pms->Write(&EncryptHeaderSize, sizeof(int)); //先頭にポインタを戻す pms->Seek((__int64)0, TSeekOrigin::soBeginning); return(true); }//end CreateHeaderData;
void z3ResEx::Run( ) { // Check the fileindex exists if( TFileSize( msfName ) == 0 ) { setMessage( "ERROR: Unable to open file (%s)", msfName ); } else { TMemoryStream msf; m_fileindexKey = nullptr; m_fileindexKeyLength = 0; // // Brute-force the key (version 1) // unsigned int keyIndex( 0 ); // For all known keys while( ( keyIndex < keyList1Count ) && ( msf.Size() == 0 ) ) { // Try to read the fileindex if( fsReadMSF( msf, keyList1[ keyIndex ].Data, KeyLength1, 0 ) ) { m_fileindexKey = keyList1[ keyIndex ].Data; m_fileindexKeyLength = KeyLength1; m_fileindexVer = 0; if( m_verboseMessages ) printf("Found key for %s!\n", keyList1[ keyIndex ].Desc ); } ++keyIndex; } // If key has not been found if( m_fileindexKey == nullptr ) { // // Continue to brute-force the key (version 2) // keyIndex = 0; // For all known keys while( ( keyIndex < keyList2Count ) && ( msf.Size() == 0 ) ) { // Try to read the fileindex if( fsReadMSF( msf, keyList2[ keyIndex ].Data, KeyLength2, 1 ) ) { m_fileindexKey = keyList2[ keyIndex ].Data; m_fileindexKeyLength = KeyLength2; m_fileindexVer = 1; if( m_verboseMessages ) printf("Found key for %s!\n", keyList2[ keyIndex ].Desc ); } ++keyIndex; } } // If a valid key has been found and fileindex loaded if( !( ( m_fileindexKey == nullptr ) && ( msf.Size() == 0 ) ) ) { // Attempt to parse it (to extract or list files) msf.Seek( 0, bufo_start ); parseMsf( msf ); } else { // No key found or incompatiable file (not checked) setMessage( "ERROR: This file is using an updated key or unsupported method" ); } msf.Close(); } }
//=========================================================================== //スレッド実行 //=========================================================================== 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; }
void TClientSockThread::AcceptClient() { int iResult; int iSendResult; char recvbuf[DEFAULT_BUFLEN]; char sandbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; bool IsData; int CommandID, CurCommandID; int DataType, CurDataType; TMemoryStream *ms = new TMemoryStream; if (Authentication(ClientSocket, ms)) { CurCommandID = -1; // Receive until the peer shuts down the connection do { iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { Form1->m->Lines->Append("Bytes received: " + IntToStr(iResult)); CommandID = GetCommand(recvbuf, iResult); if (CommandID == CM_EXEC) { RunCommand( ClientSocket, CurCommandID, ms); StrCopy(sandbuf, "ok\0"); iSendResult = send( ClientSocket, sandbuf, strlen(sandbuf), 0 ); } else if (CommandID) { CurCommandID = CommandID; ms->Clear(); StrCopy(sandbuf, "ok\0"); iSendResult = send( ClientSocket, sandbuf, strlen(sandbuf), 0 ); } else { ms->Write(recvbuf, iResult); StrCopy(sandbuf, "ok\0"); iSendResult = send( ClientSocket, sandbuf, strlen(sandbuf), 0 ); } // // Echo the buffer back to the sender // iSendResult = send( ClientSocket, recvbuf, iResult, 0 ); // if (iSendResult == SOCKET_ERROR) { // Form1->m->Lines->Append("send failed with error: " + IntToStr(WSAGetLastError())); // closesocket(ClientSocket); // WSACleanup(); // return; // } // Form1->m->Lines->Append("Bytes sent: " + IntToStr(iSendResult)); } else if (iResult == 0) Form1->m->Lines->Append("Connection closing...\n"); else { Form1->m->Lines->Append("recv failed with error: " + IntToStr(WSAGetLastError())); closesocket(ClientSocket); WSACleanup(); delete ms; return; } } while (iResult > 0); } // shutdown the connection since we're done iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { Form1->m->Lines->Append("shutdown failed with error: " + IntToStr(WSAGetLastError())); closesocket(ClientSocket); WSACleanup(); delete ms; return; } // cleanup closesocket(ClientSocket); delete ms; }