static void AddItem(BOOL bIsStandard, const _bstr_t& name, const _bstr_t& descr, TOOL* tool) { LPWSTR lpszStandard; LVITEM item = {}; assert(tool); item.mask = LVIF_TEXT | LVIF_PARAM; item.lParam = (LPARAM)tool; item.pszText = (LPWSTR)name; item.iSubItem = 0; // item.iItem = ListView_GetItemCount(hToolsListCtrl); ListView_InsertItem(hToolsListCtrl, &item); if (bIsStandard) { lpszStandard = LoadResourceString(hInst, IDS_YES); ListView_SetItemText(hToolsListCtrl, item.iItem, 1, lpszStandard); MemFree(lpszStandard); } else { lpszStandard = LoadResourceString(hInst, IDS_NO); ListView_SetItemText(hToolsListCtrl, item.iItem, 1, lpszStandard); MemFree(lpszStandard); } ListView_SetItemText(hToolsListCtrl, item.iItem, 2, (LPWSTR)descr); }
BOOL Initialize(HINSTANCE hInstance) { BOOL Success = TRUE; LPWSTR lpszVistaAppName = NULL; HANDLE hSemaphore; INITCOMMONCONTROLSEX InitControls; /* Initialize our global version flags */ bIsWindows = TRUE; /* IsWindowsOS(); */ // TODO: Commented for testing purposes... bIsOSVersionLessThanVista = TRUE; /* IsOSVersionLessThanVista(); */ // TODO: Commented for testing purposes... /* Initialize global strings */ szAppName = LoadResourceString(hInstance, IDS_MSCONFIG); if (!bIsOSVersionLessThanVista) lpszVistaAppName = LoadResourceString(hInstance, IDS_MSCONFIG_2); /* We use a semaphore in order to have a single-instance application */ hSemaphore = CreateSemaphoreW(NULL, 0, 1, L"MSConfigRunning"); if (!hSemaphore || GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hSemaphore); /* * A semaphore with the same name already exist. It should have been * created by another instance of MSConfig. Try to find its window * and bring it to front. */ if ( (hSingleWnd && IsWindow(hSingleWnd)) || ( (hSingleWnd = FindWindowW(L"#32770", szAppName)) != NULL ) || (!bIsOSVersionLessThanVista ? ( (hSingleWnd = FindWindowW(L"#32770", lpszVistaAppName)) != NULL ) : FALSE) ) { /* Found it. Show the window. */ ShowWindow(hSingleWnd, SW_SHOWNORMAL); SetForegroundWindow(hSingleWnd); } /* Quit this instance of MSConfig */ Success = FALSE; } if (!bIsOSVersionLessThanVista) MemFree(lpszVistaAppName); /* Quit now if we failed */ if (!Success) { MemFree(szAppName); return FALSE; } /* Initialize the common controls */ InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX); InitControls.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS /* | ICC_PROGRESS_CLASS | ICC_HOTKEY_CLASS*/; InitCommonControlsEx(&InitControls); hInst = hInstance; return Success; }
//--------------------------------------------------------------------------- __fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner) { /* //バージョン情報取得 pAppInfoString->Comments; pAppInfoString->InternalName; pAppInfoString->ProductName; pAppInfoString->CompanyName; pAppInfoString->LegalCopyright; pAppInfoString->ProductVersion; pAppInfoString->FileDescription; pAppInfoString->LegalTrademarks; pAppInfoString->PrivateBuild; pAppInfoString->FileVersion; pAppInfoString->OriginalFilename; pAppInfoString->SpecialBuild; */ TGetAppInfoString *pAppInfoString = new TGetAppInfoString(); //アプリケーション名 lblAppName->Caption = pAppInfoString->ProductName; //バージョン情報 lblVersion->Caption = "ver."+ pAppInfoString->FileVersion; //著作権表示 lblCopyright->Caption = pAppInfoString->LegalCopyright; //サイト表示 lblWebSite->Caption = pAppInfoString->CompanyName; delete pAppInfoString; imgMainIcon->Picture->Icon = Application->Icon; //'バージョン情報' this->Caption = LoadResourceString(&Msgexeout::_FORM_ABOUT_CAPTION); //'このファイルは、フリーで、かつオープンソースで開発されている、'; //'ソフトウェアで暗号化されています。'; //'詳しい情報は以下のサイトをご覧ください。'; //'http://hibara.org/'; lblDescription01->Caption = LoadResourceString(&Msgexeout::_FORM_ABOUT_LABEL_CAPTION_DESCRIPTION_01); lblDescription02->Caption = LoadResourceString(&Msgexeout::_FORM_ABOUT_LABEL_CAPTION_DESCRIPTION_02); lblDescription03->Caption = LoadResourceString(&Msgexeout::_FORM_ABOUT_LABEL_CAPTION_DESCRIPTION_03); }
//--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { txtInputPassword->Text = ""; this->Caption = ExtractFileName(Application->ExeName); lblMsgInputPassword->Caption = LoadResourceString(&Msgexeout::_LABEL_CAPTION_INPUT_PASSWORD); lblAbout->Caption = LoadResourceString(&Msgexeout::_LABEL_CAPTION_ABOUT); chkSaveToOtherDirectory->Caption = LoadResourceString(&Msgexeout::_CHECK_BOX_SAVE_TO_OTHER_DIRECTORY); cmdOK->Caption = LoadResourceString(&Msgexeout::_BUTTON_CAPTION_DECRYOTION); cmdExit->Caption = LoadResourceString(&Msgexeout::_BUTTON_CAPTION_CANCEL); RetryNum = 0; }
//--------------------------------------------------------------------------- //メッセージダイアログの表示(スレッドオブジェクトから呼ばれる) //--------------------------------------------------------------------------- int __fastcall TForm1::ShowConfirmMassageForm (String MsgText, TMsgDlgType MsgType, TMsgDlgButtons MsgButtons, TMsgDlgBtn MsgDefaultButton) { TForm *dlg = CreateMessageDialog(MsgText, MsgType, MsgButtons, MsgDefaultButton); dlg->ParentWindow = Form1->Handle; if ( MsgType == mtError) { dlg->Caption = LoadResourceString(&Msgexeout::_MSG_CAPTION_ERROR); } else { dlg->Caption = LoadResourceString(&Msgexeout::_MSG_CAPTION_CONFIRMATION); } //メッセージダイアログの表示 int ret = dlg->ShowModal(); delete dlg; return(ret); }
//--------------------------------------------------------------------------- //上書き確認メッセージダイアログの表示(復号スレッドオブジェクトから呼ばれる) //--------------------------------------------------------------------------- int __fastcall TForm1::ShowConfirmOverwriteMassageForm(String MsgText, String &Path) { //ボタンをカスタマイズするので上記関数と分けて作成 TButton *btn; TMsgDlgButtons MsgButtons = (TMsgDlgButtons() << mbYesToAll << mbYes << mbNo << mbCancel); TForm *dlg = CreateMessageDialog(MsgText, mtConfirmation, MsgButtons, mbCancel); //ボタン名をそれぞれ書き換える btn = (TButton *)dlg->FindComponent("YesToAll"); //'全て上書き(&W)' btn->Caption = LoadResourceString(&Msgexeout::_DIALOG_BUTTON_NAME_OVERWITE_YES_TO_ALL); btn = (TButton *)dlg->FindComponent("Yes"); //'上書き(&O)' btn->Caption = LoadResourceString(&Msgexeout::_DIALOG_BUTTON_NAME_OVERWITE_YES); btn = (TButton *)dlg->FindComponent("No"); //'別名保存(&A)' btn->Caption = LoadResourceString(&Msgexeout::_DIALOG_BUTTON_NAME_OVERWITE_NO); btn = (TButton *)dlg->FindComponent("Cancel"); //'キャンセル(&C)' btn->Caption = LoadResourceString(&Msgexeout::_DIALOG_BUTTON_NAME_OVERWITE_CANCEL); dlg->Caption = LoadResourceString(&Msgexeout::_MSG_CAPTION_CONFIRMATION); dlg->ParentWindow = Form1->Handle; //メッセージダイアログの表示 int ret = dlg->ShowModal(); if (ret == mrNo) { //別名で保存する(いいえ) TSaveDialog *dlgsave = new TSaveDialog(dlg); //'復号ファイルの保存' dlgsave->Title = LoadResourceString(&Msgexeout::_DIALOG_SAVE_AS_FILE_CAPTION); dlgsave->InitialDir = ExtractFileDir(ExcludeTrailingPathDelimiter(Path)); dlgsave->FileName = ExtractFileName(ExcludeTrailingPathDelimiter(Path)); //'ファイルフォルダー|*' dlgsave->Filter = LoadResourceString(&Msgexeout::_DIALOG_SAVE_AS_FILTER); //別名保存ダイアログ if ( dlgsave->Execute() == true ){ Path = dlgsave->FileName; } else{ //キャンセル ret = mrCancel; } delete dlgsave; } delete dlg; return(ret); }
//--------------------------------------------------------------------------- //復号処理スレッドの終了 //--------------------------------------------------------------------------- void __fastcall TForm1::DecryptThreadTerminated(TObject *Sender) { ProgressBar1->Style = pbstNormal; ProgressBar1->Position = decrypt->ProgressPercentNum; lblProgressPercentNum->Caption = IntToStr(decrypt->ProgressPercentNum)+"%"; lblStatus->Caption = decrypt->ProgressStatusText; lblMsg->Caption = decrypt->ProgressMsgText; if(ptl){ ptl->SetProgressValue(Application->Handle, 100, 100); ptl->Release(); ptl = NULL; } TimerDecrypt->Enabled = false; //復号に成功 if ( decrypt->StatusNum > 0 ) { decrypt = NULL; //「キャンセル(C)」ラベルを「終了(X)」に変更 cmdExit->Caption = LoadResourceString(&Msgexeout::_BUTTON_CAPTION_EXIT); } //復号エラー else{ //パスワード入力エラーで抜けてきた if ( decrypt->StatusNum == -1 ) { //メインパネルへ戻る ChangeFormStatus(0); RetryNum++; //パスワード入力回数制限を超えた if ( RetryNum > decrypt->TypeLimits ) { //実行ファイルは自身を書き換えられないので終了するだけ decrypt = NULL; Application->Terminate(); } } //エラー else if ( decrypt->StatusNum == -2 ) { } //ユーザーキャンセル else{ } //エラーで終了してきた decrypt = NULL; //「キャンセル(C)」ラベルを「終了(X)」に変更 cmdExit->Caption = LoadResourceString(&Msgexeout::_BUTTON_CAPTION_EXIT); } }
BOOL DoDSoundCallback( LPDSENUMCALLBACKA lpDSEnumCallbackA, LPDSENUMCALLBACKW lpDSEnumCallbackW, LPGUID DeviceGuid, UINT ResourceId, LPWSTR ProductName, LPWSTR DriverName, LPVOID lpContext) { WCHAR Buffer[200] = {0}; char DriverNameA[200]; static LPWSTR SoundDriverW = L"Primary Sound Driver"; static LPWSTR SoundDriverA = L"Primary Sound Driver"; if (lpDSEnumCallbackW) { if (ResourceId) { /* load resource string */ Buffer[0] = 0; LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(WCHAR), (LPVOID)SoundDriverW, TRUE); Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = '\0'; } else { /* use passed string */ ASSERT(ProductName); wcscpy(Buffer, ProductName); } /* perform callback */ return lpDSEnumCallbackW(DeviceGuid, Buffer, DriverName, lpContext); } else { if (ResourceId) { /* load resource string */ Buffer[0] = 0; LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(char), (LPVOID)SoundDriverA, FALSE); Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0; } else { /* use passed string */ Buffer[0] = 0; WideCharToMultiByte(CP_ACP, 0, ProductName, -1, (LPSTR)Buffer, sizeof(Buffer) / sizeof(char), NULL, NULL); Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0; } DriverNameA[0] = 0; if (ProductName) { WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL); DriverNameA[(sizeof(DriverNameA) / sizeof(char))-1] = 0; } return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext); } }
//=========================================================================== //スレッド実行 //=========================================================================== 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; }
//=========================================================================== // バッファの出力 //=========================================================================== int __fastcall TAttacheCaseFileDecrypt1::OutputBuffer (char *output_buffer, int buff_size, TFileStream *&fsOut, bool &fOpen, TStringList *FileList, int &FileIndex, __int64 *FileSizeList, int *FileAttrList, int *FileAgeList) { //返値 0=<:成功, -1:エラー, -2:ユーザーキャンセル int res; int rest; String FileName, FilePath, DirPath; char read_buffer[LARGE_BUF_SIZE]; //コンペア用 char temp_buffer[LARGE_BUF_SIZE]; //データ詰める用 //---------------------------------------------------------------------- // 解凍されたバッファがすべて書き込まれるまでループ //---------------------------------------------------------------------- // ※0バイトファイルなどの場合もあるので // 一度はループに入れるようにした。 //while (buff_size > 0 && !Terminated) { do{ // ファイルが開かれていないならオープンする if ( fOpen == false ) { for (FileIndex; FileIndex < FileList->Count; FileIndex++) { FileName = FileList->Strings[FileIndex]; FilePath = OutDirPath + FileName; //---------------------------------------------------------------------- // ディレクトリ //---------------------------------------------------------------------- if (FileName.IsPathDelimiter(FileList->Strings[FileIndex].Length()) == true) { if ( fConfirmOverwirte == true && fOverwirteYesToAll == false ) { if (DirectoryExists(FilePath) == true) { //同名フォルダーの上書き確認メッセージダイアログ MsgText = LoadResourceString(&Msgdecrypt::_MSG_CONFIRM_OVER_WRITE_SAME_DIR)+"\n"+FilePath; Synchronize(&PostConfirmOverwriteMessageForm); if ( MsgReturnVal == mrYes ) { //上書きOKなのでFilePathはそのまま } else if ( MsgReturnVal == mrNo ) { //別名保存でFilePath文字列が書き換えられてきている FilePath = MsgReturnPath; } else if ( MsgReturnVal == mrYesToAll ) { //すべて上書き(YesToAll) fOverwirteYesToAll = true; } else if ( MsgReturnVal == mrCancel ) { //キャンセル goto LabelStop; } } } //----------------------------------- //暗号化ファイル自身への復号はNG //(ex: ..\hoge -> ..\hoge) //----------------------------------- if ( FilePath.CompareIC(AtcFilePath) == 0 ) { //'暗号化ファイル自身にファイルまたはフォルダーを復号することはできません。'+#13+ //'復号処理を中止します。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_NOT_OVERWRITE_MYSELF)+"\n"+FilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); //エラー goto LabelError; } //フォルダの生成 ForceDirectories(FilePath); //タイムスタンプのセット //FileSetDate(FilePath, FileAge[i]); //フォルダはタイムスタンプをセットしない //属性のセット FileSetAttr(FilePath, FileAttrList[FileIndex]); if ( fOpenFolder == true && fOpenFolderOnce == false ) { ShellExecuteW(NULL, L"open", L"EXPLORER.EXE", FilePath.c_str(), FilePath.c_str(), SW_NORMAL); //脆弱性対策(ver.2.70) //ShellExecuteW(NULL, L"explore", FilePath.c_str(), NULL, NULL, SW_NORMAL); //こちらでも正常動作したようだ fOpenFolderOnce = true; } continue; } //---------------------------------------------------------------------- // ファイル //---------------------------------------------------------------------- else { if (fConfirmOverwirte == true && fOverwirteYesToAll == false ) { DirPath = ExtractFileDir(FilePath); if (DirectoryExists(DirPath) == false) { ForceDirectories(DirPath); } if (FileExists(FilePath) == true) { //同名ファイルの上書き確認メッセージダイアログ MsgText = LoadResourceString(&Msgdecrypt::_MSG_CONFIRM_OVER_WRITE_SAME_FILE)+"\n"+FilePath; Synchronize(&PostConfirmOverwriteMessageForm); if ( MsgReturnVal == mrYes ) { //上書きOKなのでFilePathはそのまま } else if ( MsgReturnVal == mrNo ) { //別名保存でFilePath文字列が書き換えられてきている FilePath = MsgReturnPath; } else if ( MsgReturnVal == mrYesToAll ) { //すべて上書き(YesToAll) fOverwirteYesToAll = true; } else if ( MsgReturnVal == mrCancel ) { //キャンセル goto LabelStop; } } } //----------------------------------- //暗号化ファイル自身への復号はNG //(ex: ..\hoge -> ..\hoge) //----------------------------------- if ( FilePath.CompareIC(AtcFilePath) == 0) { //'暗号化ファイル自身にファイルまたはフォルダーを復号することはできません。'+#13+ //'復号処理を中止します。'; MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_NOT_OVERWRITE_MYSELF)+"\n"+FilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); //エラー goto LabelError; } try { // TODO: ver.2.75以前で「複数ファイルは一つの暗号化ファイルにまとめる」に // チェックして暗号化されていた場合の対処 DirPath = ExtractFileDir(FilePath); if (DirectoryExists(DirPath) == false) { ForceDirectories(DirPath); //親フォルダーがなければ強制的に生成する } //出力するファイルを開く fsOut = new TFileStream(FilePath, fmCreate); } catch(...) { //保存する先のファイルが開けません。他のアプリケーションが使用中の可能性があります。 MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_OUT_FILE_OPEN)+"\n"+FilePath; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); goto LabelError; } fOpen = true; if (FileSizeList[FileIndex] == 0) { // 0バイトファイル? delete fsOut; fOpen = false; FileSetAttr(FilePath, (int)FileAttrList[FileIndex]); //属性のセット FileSetDate(FilePath, (int)FileAgeList[FileIndex]); //タイムスタンプのセット //関連付けられたアプリケーションでファイルを開く if ( fTempOpenFile == true ) { ShellExecuteW(NULL, L"open", FilePath.c_str(), NULL, NULL, SW_NORMAL); } } else{ break; } } }//end for; }//end if (fOpen == false); //----------------------------------- // 開いたファイルに書き込む //----------------------------------- if ( fOpen == true ) { //----------------------------------- // 通常書き込み //----------------------------------- if (fsOut->Size + buff_size < FileSizeList[FileIndex]) { if (fsOut->Write(output_buffer, buff_size) != buff_size) { goto LabelReadWriteError; } else { buff_size = 0; } } else { //クローズするファイルパス(書き込んでいたファイルパス) FileName = FileList->Strings[FileIndex]; FilePath = OutDirPath + FileName; rest = FileSizeList[FileIndex] - fsOut->Size; if (fsOut->Write(output_buffer, rest) != rest) { goto LabelReadWriteError; } else { buff_size -= rest; //残ったバッファを前に詰める for (int i = 0; i < LARGE_BUF_SIZE; i++) { if (i < buff_size) { temp_buffer[i] = output_buffer[rest+i]; } else{ temp_buffer[i] = 0; } } memcpy(output_buffer, temp_buffer, LARGE_BUF_SIZE); delete fsOut; fOpen = false; FileSetAttr(FilePath, (int)FileAttrList[FileIndex]); //属性のセット FileSetDate(FilePath, (int)FileAgeList[FileIndex]); //タイムスタンプのセット //関連付けられたアプリケーションでファイルを開く if ( fTempOpenFile == true ) { ShellExecuteW(NULL, L"open", FilePath.c_str(), NULL, NULL, SW_NORMAL); } FileIndex++; } } } else { //もう開くファイルがない break; //----------------------------------- }//end if ( fOpen == true ); //----------------------------------- }while (buff_size > 0 && !Terminated);//end while ( buf_size > 0 ); //---------------------------------------------------------------------- //出力バッファはきれいにしておく for (int i = 0; i < LARGE_BUF_SIZE; i++) { output_buffer[i] = 0; } if ( Terminated == true ) { goto LabelStop; } //成功 return(0); //----------------------------------- //読み書きエラー LabelReadWriteError: //'保存する先のファイルに書き込めません。復号できません。' MsgText = LoadResourceString(&Msgdecrypt::_MSG_ERROR_OUT_FILE_WRITE)+"\n"+fsOut->FileName; MsgType = mtError; MsgButtons = TMsgDlgButtons() << mbOK; MsgDefaultButton = mbOK; Synchronize(&PostConfirmMessageForm); if ( fOpen == true ) { delete fsOut; fOpen = false; } return(-1); //----------------------------------- //エラー LabelError: //ここのエラーは直前でメッセージを提示してから来ている if ( fOpen == true ) { delete fsOut; fOpen = false; } return(-1); //----------------------------------- //ユーザーキャンセル LabelStop: if ( fOpen == true ) { delete fsOut; fOpen = false; } return(-2); }
//=========================================================================== // ヘッダ情報を生成する //=========================================================================== 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 __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; }
//=========================================================================== //スレッド実行 //=========================================================================== 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 __fastcall TForm1::DestroyAtcFile(void) { int i; int fh; String MsgText; char buffer[BUF_SIZE]; for ( i = 0; i < BUF_SIZE; i++ ){ buffer[i]=NULL; } TFileStream *fsIn; char token[16]; const char charTokenString[16] = "_AttacheCaseData"; //復号の正否に使う const char charDestroyTokenString[16] = "_Atc_Broken_Data"; //破壊されているとき String AtcFileTokenString; //暗号化ファイルのトークン(文字列) String AtcFileCreateDateString; //暗号化ファイルの生成日時(文字列) __int64 AllTotalSize; int PlaneHeaderSize; int HeaderBufSize; try { fsIn = new TFileStream(Application->ExeName, fmShareDenyNone); } catch(...) { //'ファイルを開けません。他のアプリケーションで使用中の可能性があります。' MsgText = LoadResourceString(&Msgexeout::_MSG_FILE_OPEN_ERROR); ShowConfirmMassageForm(MsgText, mtError, TMsgDlgButtons()<<mbOK, mbOK); return(false); } //総サイズ取得 AllTotalSize = fsIn->Seek((__int64)0, TSeekOrigin::soEnd); fsIn->Seek((__int64)0, TSeekOrigin::soBeginning); //----------------------------------- //ヘッダ情報のチェック //----------------------------------- // サイズを取得 fsIn->Seek(-(__int64)sizeof(__int64), TSeekOrigin::soEnd); fsIn->Read(&AllTotalSize, sizeof(__int64)); // 位置を戻す fsIn->Seek(-(AllTotalSize + sizeof(__int64)), TSeekOrigin::soEnd); // 平文ヘッダサイズを読み込む fsIn->Read(&PlaneHeaderSize, sizeof(int)); // トークンを取得 fsIn->Read(token, 16); // トークンを再チェック if (memcmp(token, charTokenString, 16) != 0 ) { //すでに壊れている? サイレントに処理終了 delete fsIn; return(true); } else{ fsIn->Seek((__int64)-16, TSeekOrigin::soCurrent); //"_Atc_Broken_Data"を書き込む fsIn->Write(charDestroyTokenString, 16); } //「データバージョン」「アルゴリズムの種類」分だけ進める fsIn->Seek((__int64)(sizeof(int)*2), TSeekOrigin::soCurrent); //暗号部ヘッダサイズを取得する fsIn->Read(&HeaderBufSize, sizeof(int)); //暗号部ヘッダのIVを書き換えて破壊する fsIn->Write(buffer, BUF_SIZE); //「暗号部ヘッダサイズ」分だけ進める fsIn->Seek((__int64)(HeaderBufSize-BUF_SIZE), TSeekOrigin::soCurrent); // IV部分を書き換えて破壊する fsIn->Write(buffer, BUF_SIZE); delete fsIn; return(true); }
//--------------------------------------------------------------------------- __fastcall TForm4::TForm4(TComponent* Owner, int Type) : TForm(Owner) { int i; InputType = Type; //日時のサンプル書式 String SampleText; String SampleDateTime[8] = { "dddddd(dddd)", "yymmdd", "yyyy_m_d", "h'時'n'分'n'秒'", "", "", "", "" }; PageControl1->Align = alClient; for (int i = 0; i < PageControl1->PageCount; i++) { PageControl1->Pages[i]->TabVisible = false; } switch(InputType){ case 0: //記憶する暗号化パスワードの入力 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INPUT_ENCRYPT_MEM_PASSWORD); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_OK); cmdOK->Enabled = false; txtInputMemPassword->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INPUT_MEM_NEW_PASSWORD); txtInputMemConfirmPassword->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INPUT_MEM_NEW_PASSWORD_CONFIRM); PageControl1->ActivePageIndex = 0; break; case 1: //記憶する復号パスワードの入力 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INSERT_DECRYPT_MEM_PASSWORD); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_OK); cmdOK->Enabled = false; txtInputMemPassword->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INPUT_MEM_NEW_PASSWORD); txtInputMemConfirmPassword->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INPUT_MEM_NEW_PASSWORD_CONFIRM); PageControl1->ActivePageIndex = 0; break; case 2: //日付書式の挿入 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INSERT_DATETIME_FORMAT); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_INSERT); lblExampleDateTime->Caption = LoadResourceString(&Msgunit4::_LABEL_INSERT_DATETIME); PageControl1->ActivePageIndex = 1; for ( i = 0; i < 8; i++ ){ if ( SampleDateTime[i] != "" ) { ComboDateTime->Items->Add(SampleDateTime[i]); } } ComboDateTime->ItemIndex = 0; //表示をサンプル反映 SampleText = Now().FormatString(SampleDateTime[ComboDateTime->ItemIndex]); lblExampleDateTime->Caption = "ex). "+SampleText; break; case 3: //連番書式の挿入 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INSERT_SERIAL_NUM_FORMAT); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_INSERT); txtNum->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INSERT_SERIAL_NUM); imgInsertNum->Picture = imgSerialNum->Picture; PageControl1->ActivePageIndex = 2; break; case 4: //ランダム文字列数の挿入 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INSERT_RANDOM_TEXT_NUM_FORMAT); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_INSERT); txtNum->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INSERT_RANDOM_TEXT); imgInsertNum->Picture = imgRandomText->Picture; PageControl1->ActivePageIndex = 2; break; case 5: //ファイル名の先頭文字数の挿入 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INSERT_FILE_NAME_HEAD_NUM_FORMAT); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_INSERT); txtNum->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INSERT_FILE_NAME_HEAD); imgInsertNum->Picture = imgFileNameHead->Picture; PageControl1->ActivePageIndex = 2; break; case 6: //ファイル名の末尾文字数の挿入 this->Caption = LoadResourceString(&Msgunit4::_FORM_CAPTION_INSERT_FILE_NAME_END_NUM_FORMAT); cmdOK->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_INSERT); txtNum->EditLabel->Caption = LoadResourceString(&Msgunit4::_LABEL_INSERT_FILE_NAME_END); imgInsertNum->Picture = imgFileNameEnd->Picture; PageControl1->ActivePageIndex = 2; break; default: //エラー PageControl1->Visible = false; break; } //キャンセルボタン cmdCancel->Caption = LoadResourceString(&Msgunit4::_BUTTON_CAPTION_CANCEL); }
INT_PTR CALLBACK ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam); switch (message) { case WM_INITDIALOG: { hServicesPage = hDlg; hServicesListCtrl = GetDlgItem(hServicesPage, IDC_SERVICES_LIST); // // Correctly display message strings. // LPCWSTR szOSVendor = (bIsWindows ? IDS_MICROSOFT : IDS_REACTOS); size_t itemLength = 0; LPWSTR szItem = NULL, szNewItem = NULL; itemLength = GetWindowTextLength(GetDlgItem(hServicesPage, IDC_STATIC_SERVICES_WARNING)) + 1; szItem = (LPWSTR)MemAlloc(0, itemLength * sizeof(WCHAR)); GetDlgItemText(hServicesPage, IDC_STATIC_SERVICES_WARNING, szItem, (int)itemLength); szNewItem = FormatString(szItem, szOSVendor); SetDlgItemText(hServicesPage, IDC_STATIC_SERVICES_WARNING, szNewItem); MemFree(szNewItem); MemFree(szItem); itemLength = GetWindowTextLength(GetDlgItem(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS)) + 1; szItem = (LPWSTR)MemAlloc(0, itemLength * sizeof(WCHAR)); GetDlgItemText(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS, szItem, (int)itemLength); szNewItem = FormatString(szItem, szOSVendor); SetDlgItemText(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS, szNewItem); MemFree(szNewItem); MemFree(szItem); // // Initialize the styles. // DWORD dwStyle = ListView_GetExtendedListViewStyle(hServicesListCtrl); ListView_SetExtendedListViewStyle(hServicesListCtrl, dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); SetWindowTheme(hServicesListCtrl, L"Explorer", NULL); // // Initialize the application page's controls. // LVCOLUMN column = {}; // First column : Service's name. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_SERVICE); column.cx = 150; ListView_InsertColumn(hServicesListCtrl, 0, &column); MemFree(column.pszText); // Second column : Whether the service is required or not. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_REQ); column.cx = 60; ListView_InsertColumn(hServicesListCtrl, 1, &column); MemFree(column.pszText); // Third column : Service's vendor. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_VENDOR); column.cx = 150; ListView_InsertColumn(hServicesListCtrl, 2, &column); MemFree(column.pszText); // Fourth column : Service's status. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_STATUS); column.cx = 60; ListView_InsertColumn(hServicesListCtrl, 3, &column); MemFree(column.pszText); // Fifth column : Service's disabled date. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_DATEDISABLED); column.cx = 120; ListView_InsertColumn(hServicesListCtrl, 4, &column); MemFree(column.pszText); // // Populate and sort the list. // GetServices(); ListView_Sort(hServicesListCtrl, 0); Update_Btn_States(hDlg); // Select the first item. ListView_SetItemState(hServicesListCtrl, 0, LVIS_SELECTED, LVIS_SELECTED); return TRUE; } case WM_DESTROY: { ClearServicesList(); userModificationsList.RemoveAll(); return 0; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BTN_SERVICES_ACTIVATE: { BOOL bAreThereModifs = FALSE; int index = -1; // From the beginning. while ((index = ListView_GetNextItem(hServicesListCtrl, index, LVNI_ALL)) != -1) { bAreThereModifs = ValidateItem(index, TRUE, FALSE) || bAreThereModifs; // The order is verrrrrry important !!!! } if (bAreThereModifs) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case IDC_BTN_SERVICES_DEACTIVATE: { BOOL bAreThereModifs = FALSE; int index = -1; // From the beginning. while ((index = ListView_GetNextItem(hServicesListCtrl, index, LVNI_ALL)) != -1) { bAreThereModifs = ValidateItem(index, FALSE, FALSE) || bAreThereModifs; // The order is verrrrrry important !!!! } if (bAreThereModifs) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS: { bMaskProprietarySvcs = !bMaskProprietarySvcs; GetServices(bMaskProprietarySvcs); Update_Btn_States(hDlg); return TRUE; } default: return FALSE; } return FALSE; } case UM_CHECKSTATECHANGE: { BOOL bNewCheckState = !!((ListView_GetCheckState(hServicesListCtrl, int(lParam)) + 1) % 2); if (ValidateItem(/*reinterpret_cast<int>*/ int(lParam), bNewCheckState, !HideEssentialServiceWarning())) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case WM_NOTIFY: { if (reinterpret_cast<LPNMHDR>(lParam)->hwndFrom == hServicesListCtrl) { switch (reinterpret_cast<LPNMHDR>(lParam)->code) { case NM_CLICK: case NM_RCLICK: { DWORD dwpos = GetMessagePos(); LVHITTESTINFO ht = {}; ht.pt.x = GET_X_LPARAM(dwpos); ht.pt.y = GET_Y_LPARAM(dwpos); MapWindowPoints(HWND_DESKTOP /*NULL*/, hServicesListCtrl, &ht.pt, 1); /* * We use ListView_SubItemHitTest(...) and not ListView_HitTest(...) * because ListView_HitTest(...) returns bad flags when one clicks * on a sub-item different from 0. The flags then contain LVHT_ONITEMSTATEICON * which must not be obviously present in this case. */ ListView_SubItemHitTest(hServicesListCtrl, &ht); if (LVHT_ONITEMSTATEICON & ht.flags) { PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)ht.iItem); // Disable default behaviour. Needed for the UM_CHECKSTATECHANGE // custom notification to work as expected. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); } return TRUE; } case NM_DBLCLK: case NM_RDBLCLK: { // We deactivate double-clicks. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); return TRUE; } case LVN_KEYDOWN: { if (reinterpret_cast<LPNMLVKEYDOWN>(lParam)->wVKey == VK_SPACE) { int iItem = ListView_GetSelectionMark(hServicesListCtrl); PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)iItem); // Disable default behaviour. Needed for the UM_CHECKSTATECHANGE // custom notification to work as expected. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); } return TRUE; } case LVN_COLUMNCLICK: { int iSortingColumn = reinterpret_cast<LPNMLISTVIEW>(lParam)->iSubItem; ListView_SortEx(hServicesListCtrl, iSortingColumn, iSortedColumn); iSortedColumn = iSortingColumn; return TRUE; } } } else { switch (reinterpret_cast<LPNMHDR>(lParam)->code) { case PSN_APPLY: { // Try to apply the modifications to the system. MessageBox(NULL, _T("In Services page: PSN_APPLY"), _T("Info"), MB_ICONINFORMATION); /* // // Move this away... // int iRetVal = MessageBox(NULL, _T("Would you really want to modify the configuration of your system ?"), _T("Warning"), MB_ICONWARNING | MB_YESNOCANCEL); if (iRetVal == IDYES /\* modifications are OK *\/) SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); else if (iRetVal == IDNO /\* modifications are not OK *\/) SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); else // if (iRetVal == IDCANCEL) // There was an error... SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_INVALID); */ // // We modify the services which are stored in the user modification list. // // 1- Open the Service Control Manager for modifications. SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCManager != NULL) { LPCWSTR svcName; for (POSITION it = userModificationsList.GetHeadPosition(); it; userModificationsList.GetNext(it)) { svcName = userModificationsList.GetAt(it); // 2- Retrieve a handle to the service. SC_HANDLE hService = OpenServiceW(hSCManager, svcName, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); if (hService == NULL) { // TODO : Show a message box. continue; } DWORD dwBytesNeeded = 0; QueryServiceConfigW(hService, NULL, 0, &dwBytesNeeded); // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) LPQUERY_SERVICE_CONFIG lpServiceConfig = (LPQUERY_SERVICE_CONFIG)MemAlloc(0, dwBytesNeeded); if (!lpServiceConfig) { CloseServiceHandle(hService); continue; // TODO ? Show a message box... } QueryServiceConfigW(hService, lpServiceConfig, dwBytesNeeded, &dwBytesNeeded); if (lpServiceConfig->dwStartType == SERVICE_DISABLED) // We have a disabled service which is becoming to be enabled. { // 3a- Retrive the properties of the disabled service from the registry. RegistryDisabledServiceItemParams params = {}; QUERY_REGISTRY_KEYS_TABLE KeysQueryTable[2] = {}; KeysQueryTable[0].QueryRoutine = GetRegistryKeyedDisabledServicesQueryRoutine; KeysQueryTable[0].EntryContext = ¶ms; RegQueryRegistryKeys(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", KeysQueryTable, (PVOID)svcName); if (bIsWindows && bIsPreVistaOSVersion && !params.bIsPresent) { QUERY_REGISTRY_VALUES_TABLE ValuesQueryTable[2] = {}; ValuesQueryTable[0].QueryRoutine = GetRegistryValuedDisabledServicesQueryRoutine; ValuesQueryTable[0].EntryContext = ¶ms; RegQueryRegistryValues(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", ValuesQueryTable, (PVOID)svcName); } if (params.bIsPresent) { // 4a- Modify the service. ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, params.dwStartType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // 5a- Remove the registry entry of the service. if (params.bIsKeyed) { CAtlStringW serviceRegKey(L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services\\"); serviceRegKey += svcName; RegDeleteKeyW(HKEY_LOCAL_MACHINE, serviceRegKey); /***** HACK for Windows < Vista (e.g. 2000, Xp, 2003...) *****/ // // Delete also the valued-entry of the service. // if (bIsWindows && bIsPreVistaOSVersion) { HKEY hSubKey = NULL; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", 0, KEY_SET_VALUE /*KEY_READ*/, &hSubKey) == ERROR_SUCCESS) { RegDeleteValue(hSubKey, svcName); RegCloseKey(hSubKey); } } /*************************************************************/ } else { HKEY hSubKey = NULL; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", 0, KEY_SET_VALUE /*KEY_READ*/, &hSubKey) == ERROR_SUCCESS) { RegDeleteValue(hSubKey, svcName); RegCloseKey(hSubKey); } } ////////// HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK /////////// // userModificationsList.RemoveAt(it); } else { // Ohoh !! We have a very big problem. MessageBox(NULL, _T("WTF ??"), _T("FATAL ERROR !!!!"), MB_ICONERROR); } } else // We have an enabled service which is becoming to be disabled. { // 3b- Retrieve the local time of disabling. SYSTEMTIME disableDate = {}; GetLocalTime(&disableDate); // 4b- Modify the service. ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // 5b- Register the service into the registry. CAtlStringW serviceRegKey(L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services\\"); serviceRegKey += svcName; HKEY hSubKey = NULL; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, serviceRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) { RegSetDWORDValue(hSubKey, NULL, svcName, FALSE, lpServiceConfig->dwStartType); #if 1 // DisableDate RegSetDWORDValue(hSubKey, NULL, L"DAY" , FALSE, disableDate.wDay ); RegSetDWORDValue(hSubKey, NULL, L"HOUR" , FALSE, disableDate.wHour ); RegSetDWORDValue(hSubKey, NULL, L"MINUTE", FALSE, disableDate.wMinute); RegSetDWORDValue(hSubKey, NULL, L"MONTH" , FALSE, disableDate.wMonth ); RegSetDWORDValue(hSubKey, NULL, L"SECOND", FALSE, disableDate.wSecond); RegSetDWORDValue(hSubKey, NULL, L"YEAR" , FALSE, disableDate.wYear ); #endif RegCloseKey(hSubKey); } /***** HACK for Windows < Vista (e.g. 2000, Xp, 2003...) *****/ // // Save also a valued-entry for the service. // if (bIsWindows && bIsPreVistaOSVersion) { RegSetDWORDValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", svcName, TRUE, lpServiceConfig->dwStartType); } /*************************************************************/ ////////// HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK /////////// // userModificationsList.RemoveAt(it); } MemFree(lpServiceConfig); CloseServiceHandle(hService); } //////////// HACK HACK !!!! //////////// userModificationsList.RemoveAll(); //////////////////////////////////////// CloseServiceHandle(hSCManager); //// PropSheet_UnChanged(GetParent(hServicesPage), hServicesPage); //// PropSheet_CancelToClose(GetParent(hDlg)); /* Modifications are OK */ SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); } else { MessageBox(hDlg, _T("Impossible to open the SC manager..."), _T("Error"), MB_ICONERROR); // There was an error... SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_INVALID); } GetServices(bMaskProprietarySvcs); Update_Btn_States(hDlg); return TRUE; } case PSN_HELP: { MessageBox(hServicesPage, _T("Help not implemented yet!"), _T("Help"), MB_ICONINFORMATION | MB_OK); return TRUE; } case PSN_KILLACTIVE: // Is going to lose activation. { // Changes are always valid of course. SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYCANCEL: { // RefreshStartupList(); // Allows cancellation. SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYINITIALFOCUS: { // Give the focus on and select the first item. ListView_SetItemState(hServicesListCtrl, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, (LONG_PTR)hServicesListCtrl); return TRUE; } // // DO NOT TOUCH THESE NEXT MESSAGES, THEY ARE OK LIKE THIS... // case PSN_RESET: // Perform final cleaning, called before WM_DESTROY. return TRUE; case PSN_SETACTIVE: // Is going to gain activation. { SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, 0); return TRUE; } default: break; } } } default: return FALSE; } return FALSE; }
INT_PTR CALLBACK ToolsPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { hToolsPage = hDlg; hToolsListCtrl = GetDlgItem(hToolsPage, IDC_TOOLS_LIST); // // Initialize the styles. // DWORD dwStyle = ListView_GetExtendedListViewStyle(hToolsListCtrl); ListView_SetExtendedListViewStyle(hToolsListCtrl, dwStyle | LVS_EX_FULLROWSELECT); SetWindowTheme(hToolsListCtrl, L"Explorer", NULL); // // Initialize the application page's controls. // LVCOLUMN column = {}; // First column : Tool's name. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_NAME); column.cx = 150; ListView_InsertColumn(hToolsListCtrl, 0, &column); MemFree(column.pszText); // Second column : Whether the tool is a standard one or not. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_STANDARD); column.cx = 60; ListView_InsertColumn(hToolsListCtrl, 1, &column); MemFree(column.pszText); // Third column : Description. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_TOOLS_COLUMN_DESCR); column.cx = 500; ListView_InsertColumn(hToolsListCtrl, 2, &column); MemFree(column.pszText); // // Populate and sort the list. // FillListView(); ListView_Sort(hToolsListCtrl, 0); // Force an update in case of an empty list (giving focus on it when empty won't emit a LVN_ITEMCHANGED message). Update_States(-1 /* Wrong index to initialize all the controls with their default state (i.e. disabled) */); PropSheet_UnChanged(GetParent(hToolsPage), hToolsPage); return TRUE; } case WM_DESTROY: { LVITEM lvitem = {}; lvitem.mask = LVIF_PARAM; lvitem.iItem = -1; // From the beginning. while ((lvitem.iItem = ListView_GetNextItem(hToolsListCtrl, lvitem.iItem, LVNI_ALL)) != -1) { // ListView_Update(); // Updates a list-view item. // ListView_FindItem(); // peut être intéressant pour faire de la recherche itérative à partir du nom (ou partie du...) de l'item. ListView_GetItem(hToolsListCtrl, &lvitem); delete reinterpret_cast<TOOL*>(lvitem.lParam); lvitem.lParam = NULL; } ListView_DeleteAllItems(hToolsListCtrl); return 0; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BTN_RUN: { RunSelectedTool(); return TRUE; } case IDC_CBX_TOOLS_ADVOPT: { Update_States(ListView_GetSelectionMark(hToolsListCtrl)); return TRUE; } default: return FALSE; } return FALSE; } case WM_NOTIFY: { if (((LPNMHDR)lParam)->hwndFrom == hToolsListCtrl) { switch (((LPNMHDR)lParam)->code) { case LVN_ITEMCHANGED: { if ( (((LPNMLISTVIEW)lParam)->uChanged & LVIF_STATE) && /* The state has changed */ (((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ ) { Update_States(((LPNMLISTVIEW)lParam)->iItem); } return TRUE; } case NM_DBLCLK: case NM_RDBLCLK: { RunSelectedTool(); return TRUE; } case LVN_COLUMNCLICK: { int iSortingColumn = ((LPNMLISTVIEW)lParam)->iSubItem; ListView_SortEx(hToolsListCtrl, iSortingColumn, iToolsPageSortedColumn); iToolsPageSortedColumn = iSortingColumn; return TRUE; } default: break; } } else { switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { // Since there are nothing to modify, applying modifications // cannot return any error. SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, PSNRET_NOERROR); PropSheet_UnChanged(GetParent(hToolsPage), hToolsPage); return TRUE; } case PSN_HELP: { MessageBoxW(hToolsPage, L"Help not implemented yet!", L"Help", MB_ICONINFORMATION | MB_OK); return TRUE; } case PSN_KILLACTIVE: // Is going to lose activation. { // Changes are always valid of course. SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYCANCEL: { // Allows cancellation since there are nothing to cancel... SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYINITIALFOCUS: { // Give the focus on and select the first item. ListView_SetItemState(hToolsListCtrl, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, (LONG_PTR)hToolsListCtrl); return TRUE; } // // DO NOT TOUCH THESE NEXT MESSAGES, THEY ARE OK LIKE THIS... // case PSN_RESET: // Perform final cleaning, called before WM_DESTROY. return TRUE; case PSN_SETACTIVE: // Is going to gain activation. { SetWindowLongPtr(hToolsPage, DWLP_MSGRESULT, 0); return TRUE; } default: break; } } return FALSE; } default: return FALSE; } // return FALSE; }
//--------------------------------------------------------------------------- // ファイルを復号する処理 //--------------------------------------------------------------------------- void __fastcall TForm1::FileDecrypt(void) { int i; String MsgText; char password[32]; for (i = 0; i < 32; i++) { password[i] = NULL; } AnsiString Password; AnsiString PasswordFileHash, PasswordFileHeader; String AtcFilePath; String OutDirPath; String RootDirPath = ExtractFileDir(Application->ExeName); TSelectDirExtOpts opt; //フォームを実行中状態にする ChangeFormStatus(1); //親フォルダを生成しない //if ( fNoParentFldr == true ) if ( chkSaveToOtherDirectory->Checked == true ) { opt = TSelectDirExtOpts() << sdShowShares << sdNewUI << sdNewFolder << sdShowEdit << sdValidateDir; // '復号する先のフォルダーを指定してください。' if (SelectDirectory(LoadResourceString(&Msgexeout::_DIALOG_MSG_SELECT_SAVE_TO_FOLDER), RootDirPath, OutDirPath, opt, this) == false){ return; } } else{ OutDirPath = ExtractFileDir(Application->ExeName); } if ( DirectoryExists(OutDirPath) == false ) { //'保存する先のフォルダーが見つかりません。保存設定を再確認してください。'+#13+ //'復号処理化を中止します。'; MsgText = LoadResourceString(&Msgexeout::_MSG_ERROR_SAVE_DEC_TO_FOLDER_NOT_EXISTS)+"\n"+ OutDirPath; MessageDlg(MsgText, mtError, TMsgDlgButtons() << mbOK, 0); //エラー終了表示 ProgressBar1->Position = 0; lblProgressPercentNum->Caption = " - %"; //'キャンセル' lblStatus->Caption = LoadResourceString(&Msgexeout::_LABEL_STATUS_TITLE_USER_CANCEL); //'復号が中止されました。' lblMsg->Caption = LoadResourceString(&Msgexeout::_LABEL_STATUS_DETAIL_STOPPED); return; } //----------------------------------- // 復号処理の開始 //----------------------------------- //復号処理インスタンスの作成 decrypt = new TAttacheCaseFileDecrypt2(true); decrypt->OnTerminate = DecryptThreadTerminated; decrypt->FreeOnTerminate = true; decrypt->AppExeFilePath = Application->ExeName; //アタッシェケース本体の場所(実行形式出力のときに参照する) decrypt->AtcFilePath = Application->ExeName; //入力する暗号化ファイルパス(自分自身) decrypt->OutDirPath = OutDirPath; //出力するディレクトリ decrypt->fConfirmOverwirte = true; //上書きの確認 //----------------------------------- //パスワードのセット //----------------------------------- //パスワードファイルを使用する if (PasswordFilePath != "") { //SHA-1ハッシュを求める if ( GetSHA1HashFromFile(PasswordFilePath, PasswordFileHash, PasswordFileHeader) == true ){ StrLCopy(password, PasswordFileHash.c_str(), 32); decrypt->SetPasswordBinary(password); FileDecrypt(); } else{ //'パスワードファイルを開けません。他のアプリケーションで使用中の可能性があります。'; MsgText = LoadResourceString(&Msgexeout::_MSG_ERROR_OPEN_PASSWORD_FILE)+"\n"+PasswordFilePath; MessageDlg(MsgText, mtError, TMsgDlgButtons() << mbOK, 0); } } else{ //文字列をセット Password = (AnsiString)txtInputPassword->Text; StrLCopy(password, Password.c_str(), 32); decrypt->SetPasswordBinary(password); } //復号の実行 decrypt->Start(); //タスクバー進捗表示(Win7) if(CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, (void**)&ptl) != S_OK) { //失敗 } if (ptl) ptl->SetProgressState(Application->Handle, TBPF_NORMAL); //進捗をTimerで監視 TimerDecrypt->Enabled = true; }
PRIVATE BOOL SpyInit( HANDLE hInstance, INT nCmdShow ) { WNDCLASS wc; HWND hwndT; CHAR szClassName[40]; BOOL bFoundPrevSpy = FALSE; INT i; INT j; ghInst = hInstance; /* * Loop through windows to find one of the spy class. */ for (hwndT = GetWindow(GetDesktopWindow(), GW_CHILD); hwndT; hwndT = GetWindow(hwndT, GW_HWNDNEXT)) { if (GetClassName(hwndT, szClassName, 40)) { if (!lstrcmpi(szClassName, gszSpyClassName)) { bFoundPrevSpy = TRUE; break; } } } if (bFoundPrevSpy) { if (hwndT) SendMessage(hwndT, WM_EXECINSTANCE, 0, 0); return FALSE; } if (!(ghaccelTbl = LoadAccelerators(ghInst, "spy"))) return FALSE; ReadRegistry(); gcxBorder = GetSystemMetrics(SM_CXBORDER); gcyBorder = GetSystemMetrics(SM_CYBORDER); // // Calculate the counts in the message groups. This is best // done at run time to be safe. // for (i = 0; i < gcMessages; i++) { // // If this message belongs to a message group, // increment the total for that group. // for (j = 0; j < gcMsgGroups; j++) { if (gaMsgGroup[j].flMask & gaMsgs[i].Flags) gaMsgGroup[j].cMsgs++; } } #ifdef JAPAN lstrcpy(gszWindowName,LoadResourceString(IDS_APPLICATION_NAME)); #endif wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(hInstance, gszAppName); wc.lpszMenuName = gszAppName; wc.lpszClassName = gszSpyClassName; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.hInstance = hInstance; wc.style = CS_BYTEALIGNCLIENT; wc.lpfnWndProc = SpyWndProc; wc.cbWndExtra = 0; wc.cbClsExtra = 0; if (!RegisterClass(&wc)) return FALSE; #ifdef JAPAN ghwndSpyApp = CreateWindow(gszSpyClassName, gszWindowName, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, hInstance, NULL); #else ghwndSpyApp = CreateWindow(gszSpyClassName, gszAppName, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, hInstance, NULL); #endif if (!ghwndSpyApp) return FALSE; if (nCmdShow != SW_SHOWNORMAL) gwndpl.showCmd = nCmdShow; SetWindowPlacement(ghwndSpyApp, &gwndpl); return TRUE; }
int CALLBACK PropSheetCallback(HWND hDlg, UINT message, LPARAM lParam) { switch (message) { case PSCB_PRECREATE: { LPDLGTEMPLATE dlgTemplate = (LPDLGTEMPLATE)lParam; LPDLGTEMPLATEEX dlgTemplateEx = (LPDLGTEMPLATEEX)lParam; // MFC : DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION; DWORD style = DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU; // DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; DWORD exStyle = WS_EX_CONTROLPARENT | WS_EX_APPWINDOW; /* Hide the dialog by default; we will center it on screen later, and then show it */ style &= ~WS_VISIBLE; /* Set the styles of the property sheet dialog */ if (dlgTemplateEx->signature == 0xFFFF) { dlgTemplateEx->style = style; dlgTemplateEx->exStyle = exStyle; } else { dlgTemplate->style = style; dlgTemplate->dwExtendedStyle = exStyle; } break; } case PSCB_INITIALIZED: { /* Customize the window's system menu, add items before the "Close" item */ LPWSTR szMenuString; HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); assert(hSysMenu); szMenuString = LoadResourceString(hInst, IDS_ABOUT); if (szMenuString) { /* "About" menu */ InsertMenuW(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED | MF_STRING, IDM_ABOUT, szMenuString); /* Separator */ InsertMenuW(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_SEPARATOR , 0 , NULL); MemFree(szMenuString); } DrawMenuBar(hDlg); /* Set the dialog icons */ hIcon = (HICON)LoadImageW(hInst, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE); hIconSm = (HICON)CopyImage(hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE); SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); /* Sub-class the property sheet window procedure */ wpOrigEditProc = (WNDPROC)SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LONG_PTR)MainWndProc); break; } default: break; } return FALSE; }
PRIVATE LRESULT SpyCommand( HWND hwnd, INT nCmd, INT nNotifyCode ) { HMENU hmenu; switch (nCmd) { case MENU_SPY_SELECTWINDOW: MyDialogBox(DID_SELECTWINDOW, SelectWindowDlgProc); break; case MENU_SPY_ABOUT: MyDialogBox(DID_ABOUT, AboutDlgProc); break; case MENU_SPY_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0); break; case MENU_EDIT_CUT: if (CopyToClipboard()) ClearPrintfWindow(ghwndPrintf); break; case MENU_EDIT_COPY: CopyToClipboard(); break; case MENU_EDIT_CLEAR: ClearPrintfWindow(ghwndPrintf); break; case MENU_OPTIONS_MESSAGES: MyDialogBox(DID_MESSAGES, MessagesDlgProc); break; case MENU_OPTIONS_FONT: SelectFont(); break; case MENU_OPTIONS_OUTPUT: MyDialogBox(DID_OUTPUT, OutputDlgProc); break; case MENU_START: if (SetSpyHook(TRUE)) { hmenu = GetMenu(hwnd); ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING, MENU_STOP, LoadResourceString(IDS_MENU_STOP)); DrawMenuBar(hwnd); SetSpyCaption(); } break; case MENU_STOP: if (SetSpyHook(FALSE)) { hmenu = GetMenu(hwnd); ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING, MENU_START, LoadResourceString(IDS_MENU_START)); DrawMenuBar(hwnd); SetSpyCaption(); } break; } return 0; }
//--------------------------------------------------------------------------- void __fastcall TForm4::cmdOKClick(TObject *Sender) { String InsFormatText = ""; String MsgErrorString; //----------------------------------- //記憶パスワードの入力タブシート //----------------------------------- if ( PageControl1->ActivePageIndex == 0 ) { if ( AnsiString(txtInputMemConfirmPassword->Text).Length() > 56 ){ //'パスワードに使用できる文字数は半角56文字(全角28文字)以内です。' MsgErrorString = LoadResourceString(&Msgunit4::_MSG_ERROR_PASSWORD_MAX_NUM); MessageDlg(MsgErrorString, mtError, TMsgDlgButtons() << mbOK, 0); txtInputMemConfirmPassword->SetFocus(); txtInputMemConfirmPassword->SelectAll(); return; } if ( (AnsiString)txtInputMemPassword->Text != (AnsiString)txtInputMemConfirmPassword->Text ){ //'入力されたパスワードとちがいます。'+#13+ //'再度パスワードを入力してください。' MsgErrorString = LoadResourceString(&Msgunit4::_MSG_ERROR_INPUT_PASSWORD_MISMATCH); MessageDlg(MsgErrorString, mtError, TMsgDlgButtons() << mbOK, 0); txtInputMemConfirmPassword->SetFocus(); txtInputMemConfirmPassword->SelectAll(); return; } if ( InputType == 0 ){ //暗号化パスワードの記録 //OKボタンが押されるまではまだ仮 Form3->TempMyEncodePassword = (AnsiString)txtInputMemConfirmPassword->Text; //文字数分だけ"*"を表示 Form3->btneditMyEncPassword->Text = String::StringOfChar('*', Form3->TempMyEncodePassword.Length()); Form3->chkMyEncPasswordKeep->Checked = true; } else if ( InputType == 1 ){ //復号パスワードの記録 //OKボタンが押されるまではまだ仮 Form3->TempMyDecodePassword = (AnsiString)txtInputMemConfirmPassword->Text; //文字数分だけ"*"を表示 Form3->btneditMyDecPassword->Text = String::StringOfChar('*', Form3->TempMyDecodePassword.Length()); Form3->chkMyDecPasswordKeep->Checked = true; }//end if; Close(); } //----------------------------------- // 書式入力タブシート //----------------------------------- else { switch(InputType){ case 2: //日付書式の挿入 InsFormatText = "<date:"+ComboDateTime->Items->Strings[ComboDateTime->ItemIndex]+">"; break; case 3: //連番書式の挿入 InsFormatText = "<number:" + IntToStr(UpDown1->Position) + ">"; break; case 4: //ランダム文字列数の挿入 InsFormatText = "<fend:" + IntToStr(UpDown1->Position) + ">"; break; case 5: //ファイル名の先頭文字数の挿入 InsFormatText = "<fhead:" + IntToStr(UpDown1->Position) + ">"; break; case 6: //ファイル名の末尾文字数の挿入 InsFormatText = "<fend:" + IntToStr(UpDown1->Position) + ">"; break; default: break; } Form3->btneditAutoNameFormatText->SelText = InsFormatText; Close(); } }
static void AddService(SC_HANDLE hSCManager, LPENUM_SERVICE_STATUS_PROCESS Service, BOOL bHideOSVendorServices) { // // Retrieve a handle to the service. // SC_HANDLE hService = OpenServiceW(hSCManager, Service->lpServiceName, SERVICE_QUERY_CONFIG); if (hService == NULL) return; DWORD dwBytesNeeded = 0; QueryServiceConfigW(hService, NULL, 0, &dwBytesNeeded); // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) LPQUERY_SERVICE_CONFIG lpServiceConfig = (LPQUERY_SERVICE_CONFIG)MemAlloc(0, dwBytesNeeded); if (!lpServiceConfig) { CloseServiceHandle(hService); return; } QueryServiceConfigW(hService, lpServiceConfig, dwBytesNeeded, &dwBytesNeeded); // // Get the service's vendor... // LPWSTR lpszVendor = NULL; { // Isolate only the executable path, without any arguments. // TODO: Correct at the level of CmdLineToArgv the potential bug when lpszFilename == NULL. #if 0 // Disabled until CmdLineToArgv is included unsigned int argc = 0; LPWSTR* argv = NULL; CmdLineToArgv(lpServiceConfig->lpBinaryPathName, &argc, &argv, L" \t"); if (argc >= 1 && argv[0]) lpszVendor = GetExecutableVendor(argv[0]); #else // Hackish solution taken from the original srvpage.c. // Will be removed after CmdLineToArgv is introduced. WCHAR FileName[MAX_PATH]; memset(&FileName, 0, sizeof(FileName)); if (wcscspn(lpServiceConfig->lpBinaryPathName, L"\"")) { wcsncpy(FileName, lpServiceConfig->lpBinaryPathName, wcscspn(lpServiceConfig->lpBinaryPathName, L" ") ); } else { wcscpy(FileName, lpServiceConfig->lpBinaryPathName); } lpszVendor = GetExecutableVendor(FileName); #endif if (!lpszVendor) lpszVendor = LoadResourceString(hInst, IDS_UNKNOWN); #if 0 MemFree(argv); #endif } // ...and display or not the Microsoft / ReactOS services. BOOL bContinue = TRUE; if (bHideOSVendorServices) { if (FindSubStrI(lpszVendor, bIsWindows ? IDS_MICROSOFT : IDS_REACTOS)) bContinue = FALSE; } if (bContinue) { BOOL bIsServiceEnabled = (lpServiceConfig->dwStartType != SERVICE_DISABLED); BOOL bAddServiceToList = FALSE; BOOL bIsModifiedService = FALSE; RegistryDisabledServiceItemParams params = {}; // // Try to look into the user modifications list... // POSITION it = userModificationsList.Find(Service->lpServiceName); if (it) { bAddServiceToList = TRUE; bIsModifiedService = TRUE; } // // ...if not found, try to find if the disabled service is in the registry. // if (!bAddServiceToList) { if (!bIsServiceEnabled) { QUERY_REGISTRY_KEYS_TABLE KeysQueryTable[2] = {}; KeysQueryTable[0].QueryRoutine = GetRegistryKeyedDisabledServicesQueryRoutine; KeysQueryTable[0].EntryContext = ¶ms; RegQueryRegistryKeys(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", KeysQueryTable, Service->lpServiceName); bAddServiceToList = params.bIsPresent; if (bIsWindows && bIsPreVistaOSVersion && !bAddServiceToList) { QUERY_REGISTRY_VALUES_TABLE ValuesQueryTable[2] = {}; ValuesQueryTable[0].QueryRoutine = GetRegistryValuedDisabledServicesQueryRoutine; ValuesQueryTable[0].EntryContext = ¶ms; RegQueryRegistryValues(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", ValuesQueryTable, Service->lpServiceName); bAddServiceToList = params.bIsPresent; } } else { bAddServiceToList = TRUE; } } if (bAddServiceToList) { // // Check if service is required by the system. // BOOL bIsRequired = FALSE; dwBytesNeeded = 0; QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, NULL, 0, &dwBytesNeeded); // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) LPSERVICE_FAILURE_ACTIONS lpServiceFailureActions = (LPSERVICE_FAILURE_ACTIONS)MemAlloc(0, dwBytesNeeded); if (!lpServiceFailureActions) { MemFree(lpszVendor); MemFree(lpServiceConfig); CloseServiceHandle(hService); return; } QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)lpServiceFailureActions, dwBytesNeeded, &dwBytesNeeded); // In Microsoft's MSConfig, things are done just like that!! (extracted string values from msconfig.exe) if ( ( wcsicmp(Service->lpServiceName, L"rpcss" ) == 0 || wcsicmp(Service->lpServiceName, L"rpclocator") == 0 || wcsicmp(Service->lpServiceName, L"dcomlaunch") == 0 ) || ( lpServiceFailureActions && (lpServiceFailureActions->cActions >= 1) && (lpServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT) ) ) // We add also this test, which corresponds to real life. { bIsRequired = TRUE; } MemFree(lpServiceFailureActions); // // Add the service into the list. // LVITEM item = {}; item.mask = LVIF_TEXT | LVIF_PARAM; item.pszText = Service->lpDisplayName; item.lParam = reinterpret_cast<LPARAM>(new ServiceItem(Service->lpServiceName, bIsServiceEnabled, bIsRequired)); item.iItem = ListView_InsertItem(hServicesListCtrl, &item); if (bIsRequired) { LPWSTR lpszYes = LoadResourceString(hInst, IDS_YES); ListView_SetItemText(hServicesListCtrl, item.iItem, 1, lpszYes); MemFree(lpszYes); } ListView_SetItemText(hServicesListCtrl, item.iItem, 2, lpszVendor); LPWSTR lpszStatus = LoadResourceString(hInst, ((Service->ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED) ? IDS_SERVICES_STATUS_STOPPED : IDS_SERVICES_STATUS_RUNNING)); ListView_SetItemText(hServicesListCtrl, item.iItem, 3, lpszStatus); MemFree(lpszStatus); if (!bIsServiceEnabled) { LPWSTR lpszUnknown = LoadResourceString(hInst, IDS_UNKNOWN); LPWSTR lpszDisableDate = FormatDateTime(¶ms.time); ListView_SetItemText(hServicesListCtrl, item.iItem, 4, (lpszDisableDate ? lpszDisableDate : lpszUnknown)); FreeDateTime(lpszDisableDate); MemFree(lpszUnknown); } ListView_SetCheckState(hServicesListCtrl, item.iItem, (!bIsModifiedService ? bIsServiceEnabled : !bIsServiceEnabled)); } } MemFree(lpszVendor); MemFree(lpServiceConfig); CloseServiceHandle(hService); return; }