OSDN Git Service

Fix bugs of automatic detection for Kanji code of filenames.
[ffftp/ffftp.git] / main.c
diff --git a/main.c b/main.c
index 4cae7c0..79d3709 100644 (file)
--- a/main.c
+++ b/main.c
@@ -42,6 +42,8 @@
 #include "common.h"\r
 #include "resource.h"\r
 #include "aes.h"\r
+// 暗号化通信対応\r
+#include "sha.h"\r
 \r
 #include <htmlhelp.h>\r
 #include "helpid.h"\r
@@ -133,12 +135,20 @@ HWND hHelpWin = NULL;
 /* 設定値 */\r
 int WinPosX = CW_USEDEFAULT;\r
 int WinPosY = 0;\r
-int WinWidth = 630;\r
-int WinHeight = 393;\r
-int LocalWidth = 309;\r
-int TaskHeight = 50;\r
-int LocalTabWidth[4] = { 120, 90, 60, 37 };\r
-int RemoteTabWidth[6] = { 120, 90, 60, 37, 60, 60 };\r
+// 機能が増えたためサイズ変更\r
+// VGAサイズに収まるようになっていたのをSVGAサイズに引き上げ\r
+//int WinWidth = 630;\r
+//int WinHeight = 393;\r
+//int LocalWidth = 309;\r
+//int TaskHeight = 50;\r
+//int LocalTabWidth[4] = { 120, 90, 60, 37 };\r
+//int RemoteTabWidth[6] = { 120, 90, 60, 37, 60, 60 };\r
+int WinWidth = 790;\r
+int WinHeight = 513;\r
+int LocalWidth = 389;\r
+int TaskHeight = 100;\r
+int LocalTabWidth[4] = { 160, 110, 60, 37 };\r
+int RemoteTabWidth[6] = { 160, 110, 60, 37, 60, 60 };\r
 char UserMailAdrs[USER_MAIL_LEN+1] = { "who@example.com" };\r
 char ViewerName[VIEWERS][FMAX_PATH+1] = { { "notepad" }, { "" }, { "" } };\r
 HFONT ListFont = NULL;\r
@@ -208,6 +218,8 @@ int MirUpDelNotify = YES;
 int MirDownDelNotify = YES; \r
 int FolderAttr = NO;\r
 int FolderAttrNum = 777;\r
+// 暗号化通信対応\r
+BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];\r
 \r
 \r
 \r
@@ -230,6 +242,70 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
        int Ret;\r
        BOOL Sts;\r
 \r
+       // プロセス保護\r
+#ifdef ENABLE_PROCESS_PROTECTION\r
+       DWORD ProtectLevel;\r
+       char* pCommand;\r
+       char Option[FMAX_PATH+1];\r
+       ProtectLevel = PROCESS_PROTECTION_NONE;\r
+       pCommand = lpszCmdLine;\r
+       while(pCommand = GetToken(pCommand, Option))\r
+       {\r
+               if(strcmp(Option, "--protect") == 0)\r
+               {\r
+                       ProtectLevel = PROCESS_PROTECTION_DEFAULT;\r
+                       break;\r
+               }\r
+               else if(strcmp(Option, "--protect-high") == 0)\r
+               {\r
+                       ProtectLevel = PROCESS_PROTECTION_HIGH;\r
+                       break;\r
+               }\r
+               else if(strcmp(Option, "--protect-medium") == 0)\r
+               {\r
+                       ProtectLevel = PROCESS_PROTECTION_MEDIUM;\r
+                       break;\r
+               }\r
+               else if(strcmp(Option, "--protect-low") == 0)\r
+               {\r
+                       ProtectLevel = PROCESS_PROTECTION_LOW;\r
+                       break;\r
+               }\r
+       }\r
+       if(ProtectLevel != PROCESS_PROTECTION_NONE)\r
+       {\r
+               SetProcessProtectionLevel(ProtectLevel);\r
+               if(!InitializeLoadLibraryHook())\r
+               {\r
+                       MessageBox(NULL, MSGJPN321, "FFFTP", MB_OK | MB_ICONERROR);\r
+                       return 0;\r
+               }\r
+#ifndef _DEBUG\r
+               if(IsDebuggerPresent())\r
+               {\r
+                       MessageBox(NULL, MSGJPN322, "FFFTP", MB_OK | MB_ICONERROR);\r
+                       return 0;\r
+               }\r
+#endif\r
+               if(!UnloadUntrustedModule())\r
+               {\r
+                       MessageBox(NULL, MSGJPN323, "FFFTP", MB_OK | MB_ICONERROR);\r
+                       return 0;\r
+               }\r
+#ifndef _DEBUG\r
+               if(RestartProtectedProcess(" --restart"))\r
+                       return 0;\r
+#endif\r
+               if(!EnableLoadLibraryHook(TRUE))\r
+               {\r
+                       MessageBox(NULL, MSGJPN324, "FFFTP", MB_OK | MB_ICONERROR);\r
+                       return 0;\r
+               }\r
+       }\r
+       else\r
+               InitializeLoadLibraryHook();\r
+#endif\r
+\r
 #ifdef DISABLE_MULTI_CPUS\r
        SetProcessAffinityMask(GetCurrentProcess(), 1);\r
 #endif\r
@@ -242,6 +318,7 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
 \r
        InitCommonControls();\r
 \r
+       // FTPS対応\r
 #ifdef USE_OPENSSL\r
        LoadOpenSSL();\r
 #endif\r
@@ -275,6 +352,7 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
                Ret = Msg.wParam;\r
        }\r
     UnregisterClass(FtpClassStr, hInstFtp);\r
+       // FTPS対応\r
 #ifdef USE_OPENSSL\r
        FreeOpenSSL();\r
 #endif\r
@@ -390,6 +468,7 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow)
 \r
                        // 暗号化通信対応\r
                        SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback);\r
+                       SetSSLConfirmCallback(SSLConfirmCallback);\r
 \r
                        LoadJre();\r
                        if(NoRasControl == NO)\r
@@ -431,7 +510,7 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow)
                                        DispWindowTitle();\r
                                        // SourceForge.JPによるフォーク\r
 //                                     SetTaskMsg("FFFTP Ver." VER_STR " Copyright(C) 1997-2010 Sota & cooperators.");\r
-                                       SetTaskMsg("FFFTP Ver." VER_STR " Copyright(C) 1997-2010 Sota & cooperators.\r\nCopyright (C) 2011 Hiromichi Matsushima, Suguru Kawamoto.");\r
+                                       SetTaskMsg("FFFTP Ver." VER_STR " Copyright(C) 1997-2010 Sota & cooperators.\r\nCopyright (C) 2011 FFFTP Project (Hiromichi Matsushima, Suguru Kawamoto, IWAMOTO Kouichi, vitamin0x, unarist, Asami, fortran90, tomo1192).");\r
 \r
                                        if(ForceIni)\r
                                                SetTaskMsg("%s%s", MSGJPN283, IniPath);\r
@@ -759,6 +838,10 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
        switch (message)\r
        {\r
                case WM_COMMAND :\r
+                       // 同時接続対応\r
+                       // 中断後に受信バッファに応答が残っていると次のコマンドの応答が正しく処理できない\r
+                       if(CancelFlg == YES)\r
+                               RemoveReceivedData(AskCmdCtrlSkt());\r
                        switch(LOWORD(wParam))\r
                        {\r
                                case MENU_CONNECT :\r
@@ -1008,12 +1091,16 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                        break;\r
 \r
                                case MENU_FILTER :\r
+                                       // 同時接続対応\r
+                                       CancelFlg = NO;\r
                                        SetFilter(&CancelFlg);\r
                                        break;\r
 \r
                                case MENU_SORT :\r
                                        if(SortSetting() == YES)\r
                                        {\r
+                                               // 同時接続対応\r
+                                               CancelFlg = NO;\r
                                                LocalFileSort = AskSortType(ITEM_LFILE);\r
                                                LocalDirSort = AskSortType(ITEM_LDIR);\r
                                                RemoteFileSort = AskSortType(ITEM_RFILE);\r
@@ -1067,6 +1154,7 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                case MENU_KNJ_EUC :\r
                                case MENU_KNJ_JIS :\r
                                case MENU_KNJ_UTF8N :\r
+                               case MENU_KNJ_UTF8BOM :\r
                                case MENU_KNJ_NONE :\r
                                        SetHostKanjiCode(LOWORD(wParam));\r
                                        break;\r
@@ -1075,6 +1163,7 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                case MENU_L_KNJ_EUC :\r
                                case MENU_L_KNJ_JIS :\r
                                case MENU_L_KNJ_UTF8N :\r
+                               case MENU_L_KNJ_UTF8BOM :\r
                                        SetLocalKanjiCode(LOWORD(wParam));\r
                                        break;\r
 \r
@@ -1083,6 +1172,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                        break;\r
 \r
                                case MENU_REFRESH :\r
+                                       // 同時接続対応\r
+                                       CancelFlg = NO;\r
                                        SuppressRefresh = 1;\r
                                        GetLocalDirForWnd();\r
                                        if(CheckClosedAndReconnect() == FFFTP_SUCCESS)\r
@@ -1107,6 +1198,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                        break;\r
 \r
                                case REFRESH_REMOTE :\r
+                                       // 同時接続対応\r
+                                       CancelFlg = NO;\r
                                        SuppressRefresh = 1;\r
                                        if(CheckClosedAndReconnect() == FFFTP_SUCCESS)\r
                                                GetRemoteDirForWnd(CACHE_REFRESH, &CancelFlg);\r
@@ -1135,7 +1228,9 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                        break;\r
 \r
                                case MENU_HELP_TROUBLE :\r
-                                       ShellExecute(NULL, "open", MYWEB_URL, NULL, ".", SW_SHOW);\r
+                                       // 任意のコードが実行されるバグ修正\r
+//                                     ShellExecute(NULL, "open", MYWEB_URL, NULL, ".", SW_SHOW);\r
+                                       ShellExecute(NULL, "open", MYWEB_URL, NULL, NULL, SW_SHOW);\r
                                        break;\r
 \r
                                case MENU_BMARK_ADD :\r
@@ -1171,6 +1266,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                        break;\r
 \r
                                case MENU_DOTFILE :\r
+                                       // 同時接続対応\r
+                                       CancelFlg = NO;\r
                                        DotFile ^= 1;\r
                                        DispDotFileMode();\r
                                        GetLocalDirForWnd();\r
@@ -1359,6 +1456,10 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                                        lpttt->lpszText = MSGJPN308;\r
                                                        break;\r
 \r
+                                               case MENU_KNJ_UTF8BOM :\r
+                                                       lpttt->lpszText = MSGJPN330;\r
+                                                       break;\r
+\r
                                                case MENU_KNJ_NONE :\r
                                                        lpttt->lpszText = MSGJPN173;\r
                                                        break;\r
@@ -1379,6 +1480,10 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                                        lpttt->lpszText = MSGJPN312;\r
                                                        break;\r
 \r
+                                               case MENU_L_KNJ_UTF8BOM :\r
+                                                       lpttt->lpszText = MSGJPN331;\r
+                                                       break;\r
+\r
                                                case MENU_KANACNV :\r
                                                        lpttt->lpszText = MSGJPN174;\r
                                                        break;\r
@@ -1407,6 +1512,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                case LVN_COLUMNCLICK :\r
                                        if(((NMHDR *)lParam)->hwndFrom == GetLocalHwnd())\r
                                        {\r
+                                               // 同時接続対応\r
+                                               CancelFlg = NO;\r
                                                SetSortTypeByColumn(WIN_LOCAL, ((NM_LISTVIEW *)lParam)->iSubItem);\r
                                                ReSortDispList(WIN_LOCAL, &CancelFlg);\r
                                        }\r
@@ -1414,6 +1521,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
                                        {\r
                                                if(((NM_LISTVIEW *)lParam)->iSubItem != 4)\r
                                                {\r
+                                                       // 同時接続対応\r
+                                                       CancelFlg = NO;\r
                                                        SetSortTypeByColumn(WIN_REMOTE, ((NM_LISTVIEW *)lParam)->iSubItem);\r
                                                        ReSortDispList(WIN_REMOTE, &CancelFlg);\r
                                                }\r
@@ -1695,6 +1804,24 @@ static int AnalyzeComLine(char *Str, int *AutoConnect, int *CmdOption, char *unc
                        {\r
                                hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000024);\r
                        }\r
+                       // プロセス保護\r
+#ifdef ENABLE_PROCESS_PROTECTION\r
+                       else if(strcmp(Tmp, "--restart") == 0)\r
+                       {\r
+                       }\r
+                       else if(strcmp(Tmp, "--protect") == 0)\r
+                       {\r
+                       }\r
+                       else if(strcmp(Tmp, "--protect-high") == 0)\r
+                       {\r
+                       }\r
+                       else if(strcmp(Tmp, "--protect-medium") == 0)\r
+                       {\r
+                       }\r
+                       else if(strcmp(Tmp, "--protect-low") == 0)\r
+                       {\r
+                       }\r
+#endif\r
                        else\r
                        {\r
                                SetTaskMsg(MSGJPN180, Tmp);\r
@@ -1988,6 +2115,8 @@ void DoubleClickProc(int Win, int Mode, int App)
 //                                                             if((Sts = DoDownLoad(AskCmdCtrlSkt(), &MainTransPkt, NO)) == 429)\r
 //                                                             {\r
 //                                                                     ReConnectCmdSkt();\r
+                                                                       // 同時接続対応\r
+                                                                       CancelFlg = NO;\r
                                                                        Sts = DoDownLoad(AskCmdCtrlSkt(), &MainTransPkt, NO, &CancelFlg);\r
 //                                                             }\r
                                                        }\r
@@ -2040,6 +2169,11 @@ static void ChangeDir(int Win, char *Path)
        char Local[FMAX_PATH+1];\r
        char Remote[FMAX_PATH+1];\r
 \r
+       // 同時接続対応\r
+       CancelFlg = NO;\r
+\r
+       // デッドロック対策\r
+       DisableUserOpe();\r
        Sync = AskSyncMoveMode();\r
        if(Sync == YES)\r
        {\r
@@ -2071,6 +2205,8 @@ static void ChangeDir(int Win, char *Path)
                                GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
                }\r
        }\r
+       // デッドロック対策\r
+       EnableUserOpe();\r
        return;\r
 }\r
 \r
@@ -2328,6 +2464,8 @@ void ExecViewer(char *Fname, int App)
        char AssocProg[FMAX_PATH+1];\r
        char ComLine[FMAX_PATH*2+3+1];\r
        char CurDir[FMAX_PATH+1];\r
+       // 任意のコードが実行されるバグ修正\r
+       char SysDir[FMAX_PATH+1];\r
 \r
        /* FindExecutable()は関連付けられたプログラムのパス名にスペースが        */\r
        /* 含まれている時、間違ったパス名を返す事がある。                                        */\r
@@ -2335,7 +2473,10 @@ void ExecViewer(char *Fname, int App)
 \r
        AskLocalCurDir(CurDir, FMAX_PATH);\r
 \r
-       if((App == -1) && (FindExecutable(Fname, NULL, AssocProg) > (HINSTANCE)32))\r
+       // 任意のコードが実行されるバグ修正\r
+       // 拡張子が無いと補完されるため\r
+//     if((App == -1) && (FindExecutable(Fname, NULL, AssocProg) > (HINSTANCE)32))\r
+       if((App == -1) && strrchr(Fname, '.') > strrchr(Fname, '\\') && (FindExecutable(Fname, NULL, AssocProg) > (HINSTANCE)32))\r
        {\r
                DoPrintf("ShellExecute - %s", Fname);\r
                ShellExecute(NULL, "open", Fname, NULL, CurDir, SW_SHOW);\r
@@ -2355,10 +2496,26 @@ void ExecViewer(char *Fname, int App)
                memset(&Startup, NUL, sizeof(STARTUPINFO));\r
                Startup.cb = sizeof(STARTUPINFO);\r
                Startup.wShowWindow = SW_SHOW;\r
-               if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE)\r
+               // 任意のコードが実行されるバグ修正\r
+//             if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE)\r
+//             {\r
+//                     SetTaskMsg(MSGJPN182, GetLastError());\r
+//                     SetTaskMsg(">>%s", ComLine);\r
+//             }\r
+               if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0)\r
                {\r
-                       SetTaskMsg(MSGJPN182, GetLastError());\r
-                       SetTaskMsg(">>%s", ComLine);\r
+                       if(GetSystemDirectory(SysDir, FMAX_PATH) > 0)\r
+                       {\r
+                               if(SetCurrentDirectory(SysDir))\r
+                               {\r
+                                       if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE)\r
+                                       {\r
+                                               SetTaskMsg(MSGJPN182, GetLastError());\r
+                                               SetTaskMsg(">>%s", ComLine);\r
+                                       }\r
+                                       SetCurrentDirectory(CurDir);\r
+                               }\r
+                       }\r
                }\r
        }\r
        return;\r
@@ -2383,6 +2540,8 @@ void ExecViewer2(char *Fname1, char *Fname2, int App)
        char AssocProg[FMAX_PATH+1];\r
        char ComLine[FMAX_PATH*2+3+1];\r
        char CurDir[FMAX_PATH+1];\r
+       // 任意のコードが実行されるバグ修正\r
+       char SysDir[FMAX_PATH+1];\r
 \r
        /* FindExecutable()は関連付けられたプログラムのパス名にスペースが        */\r
        /* 含まれている時、間違ったパス名を返す事がある。                                        */\r
@@ -2402,10 +2561,26 @@ void ExecViewer2(char *Fname1, char *Fname2, int App)
        memset(&Startup, NUL, sizeof(STARTUPINFO));\r
        Startup.cb = sizeof(STARTUPINFO);\r
        Startup.wShowWindow = SW_SHOW;\r
-       if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE)\r
+       // 任意のコードが実行されるバグ修正\r
+//     if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE)\r
+//     {\r
+//             SetTaskMsg(MSGJPN182, GetLastError());\r
+//             SetTaskMsg(">>%s", ComLine);\r
+//     }\r
+       if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0)\r
        {\r
-               SetTaskMsg(MSGJPN182, GetLastError());\r
-               SetTaskMsg(">>%s", ComLine);\r
+               if(GetSystemDirectory(SysDir, FMAX_PATH) > 0)\r
+               {\r
+                       if(SetCurrentDirectory(SysDir))\r
+                       {\r
+                               if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE)\r
+                               {\r
+                                       SetTaskMsg(MSGJPN182, GetLastError());\r
+                                       SetTaskMsg(">>%s", ComLine);\r
+                               }\r
+                               SetCurrentDirectory(CurDir);\r
+                       }\r
+               }\r
        }\r
 \r
        return;\r
@@ -2613,7 +2788,6 @@ int BackgrndMessageProc(void)
        int Ret;\r
 \r
        Ret = NO;\r
-       SendMessage(GetMainHwnd(), WM_NULL, 0, 0);\r
        while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))\r
        {\r
                if(!HtmlHelp(NULL, NULL, HH_PRETRANSLATEMESSAGE, (DWORD)&Msg))\r
@@ -2682,12 +2856,29 @@ int AskAutoExit(void)
 int EnterMasterPasswordAndSet( int Res, HWND hWnd )\r
 {\r
        char buf[MAX_PASSWORD_LEN + 1];\r
+       // パスワードの入力欄を非表示\r
+       // 非表示にしたため新しいパスワードを2回入力させる\r
+       char buf1[MAX_PASSWORD_LEN + 1];\r
        char *p;\r
        int Flag;\r
 \r
        buf[0] = NUL;\r
        if( InputDialogBox(Res, hWnd, NULL, buf, MAX_PASSWORD_LEN + 1,\r
                &Flag, IDH_HELP_TOPIC_0000064) == YES){\r
+               // パスワードの入力欄を非表示\r
+               if(Res == newmasterpasswd_dlg)\r
+               {\r
+                       buf1[0] = NUL;\r
+                       if( InputDialogBox(Res, hWnd, NULL, buf1, MAX_PASSWORD_LEN + 1,\r
+                               &Flag, IDH_HELP_TOPIC_0000064) != YES){\r
+                               return 0;\r
+                       }\r
+                       if(strcmp(buf, buf1) != 0)\r
+                       {\r
+                               MessageBox(hWnd, MSGJPN325, "FFFTP", MB_OK | MB_ICONERROR);\r
+                               return 0;\r
+                       }\r
+               }\r
                /* 末尾の空白を削除 */\r
                RemoveTailingSpaces(buf);\r
                /* 先頭の空白を削除 */\r
@@ -2708,17 +2899,51 @@ int EnterMasterPasswordAndSet( int Res, HWND hWnd )
 }\r
 \r
 // 暗号化通信対応\r
-BOOL __stdcall SSLTimeoutCallback()\r
+BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted)\r
 {\r
        Sleep(1);\r
        if(BackgrndMessageProc() == YES)\r
                return TRUE;\r
-       // 念のためツールバーのMENU_ABORTも確認\r
-//     if(MainTransPkt.Abort != ABORT_NONE)\r
-//     {\r
-//             MainTransPkt.Abort = ABORT_NONE;\r
-//             return TRUE;\r
-//     }\r
+       if(*pbAborted == YES)\r
+               return TRUE;\r
        return FALSE;\r
 }\r
 \r
+BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName)\r
+{\r
+       BOOL bResult;\r
+       int i;\r
+       uint32 Hash[5];\r
+       char* pm0;\r
+       bResult = FALSE;\r
+       sha_memory((char*)Certificate, (uint32)(strlen(Certificate) * sizeof(char)), (uint32*)&Hash);\r
+       i = 0;\r
+       while(i < MAX_CERT_CACHE_HASH)\r
+       {\r
+               if(memcmp(&CertificateCacheHash[i], &Hash, 20) == 0)\r
+               {\r
+                       bResult = TRUE;\r
+                       break;\r
+               }\r
+               i++;\r
+       }\r
+       if(!bResult)\r
+       {\r
+               if(pm0 = AllocateStringM(strlen(Certificate) + 1024))\r
+               {\r
+                       sprintf(pm0, MSGJPN326, IsHostNameMatched(AskHostAdrs(), CommonName) ? MSGJPN327 : MSGJPN328, bVerified ? MSGJPN327 : MSGJPN328, Certificate);\r
+                       if(MessageBox(GetMainHwnd(), pm0, "FFFTP", MB_YESNO) == IDYES)\r
+                       {\r
+                               for(i = MAX_CERT_CACHE_HASH - 1; i >= 1; i--)\r
+                                       memcpy(&CertificateCacheHash[i], &CertificateCacheHash[i - 1], 20);\r
+                               memcpy(&CertificateCacheHash[0], &Hash, 20);\r
+                               bResult = TRUE;\r
+                       }\r
+                       FreeDuplicatedString(pm0);\r
+               }\r
+       }\r
+       if(!bResult)\r
+               *pbAborted = YES;\r
+       return bResult;\r
+}\r
+\r