X-Git-Url: http://git.sourceforge.jp/view?p=ffftp%2Fffftp.git;a=blobdiff_plain;f=main.c;h=3b7df5b966cf82de0a46cb63fa29dd4f100461ba;hp=72b34c3b335d770031211ba4643af9718527bd5c;hb=619b82a7a7f0c24da339c76ef9a102960ce928b0;hpb=4a6f29d2616cdecbb9366e5f462c5815c64fbaf6 diff --git a/main.c b/main.c index 72b34c3..3b7df5b 100644 --- a/main.c +++ b/main.c @@ -28,6 +28,8 @@ /============================================================================*/ #define STRICT +// IPv6対応 +#include #include #include #include @@ -37,7 +39,8 @@ #include #include #include -#include +// IPv6対応 +//#include #include "common.h" #include "resource.h" @@ -127,6 +130,11 @@ static int SuppressRefresh = 0; static DWORD dwCookie; +// 暗号化通信対応 +static char SSLRootCAFilePath[FMAX_PATH+1]; +// マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策 +static DWORD MainThreadId; + /*===== グローバルなワーク =====*/ @@ -135,12 +143,20 @@ HWND hHelpWin = NULL; /* 設定値 */ int WinPosX = CW_USEDEFAULT; int WinPosY = 0; -int WinWidth = 630; -int WinHeight = 393; -int LocalWidth = 309; -int TaskHeight = 50; -int LocalTabWidth[4] = { 120, 90, 60, 37 }; -int RemoteTabWidth[6] = { 120, 90, 60, 37, 60, 60 }; +// 機能が増えたためサイズ変更 +// VGAサイズに収まるようになっていたのをSVGAサイズに引き上げ +//int WinWidth = 630; +//int WinHeight = 393; +//int LocalWidth = 309; +//int TaskHeight = 50; +//int LocalTabWidth[4] = { 120, 90, 60, 37 }; +//int RemoteTabWidth[6] = { 120, 90, 60, 37, 60, 60 }; +int WinWidth = 790; +int WinHeight = 513; +int LocalWidth = 389; +int TaskHeight = 100; +int LocalTabWidth[4] = { 160, 110, 60, 37 }; +int RemoteTabWidth[6] = { 160, 110, 60, 37, 60, 60 }; char UserMailAdrs[USER_MAIL_LEN+1] = { "who@example.com" }; char ViewerName[VIEWERS][FMAX_PATH+1] = { { "notepad" }, { "" }, { "" } }; HFONT ListFont = NULL; @@ -210,10 +226,9 @@ int MirUpDelNotify = YES; int MirDownDelNotify = YES; int FolderAttr = NO; int FolderAttrNum = 777; -// 同時接続対応 -int MaxThreadCount = 1; // 暗号化通信対応 BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20]; +BYTE SSLRootCAFileHash[20]; @@ -300,9 +315,11 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi InitializeLoadLibraryHook(); #endif + // マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策 #ifdef DISABLE_MULTI_CPUS SetProcessAffinityMask(GetCurrentProcess(), 1); #endif + MainThreadId = GetCurrentThreadId(); // yutaka if(OleInitialize(NULL) != S_OK){ @@ -463,6 +480,9 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow) // 暗号化通信対応 SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback); SetSSLConfirmCallback(SSLConfirmCallback); + GetModuleFileName(NULL, SSLRootCAFilePath, FMAX_PATH); + strcpy(GetFileName(SSLRootCAFilePath), "ssl.pem"); + LoadSSLRootCAFile(); LoadJre(); if(NoRasControl == NO) @@ -504,7 +524,7 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow) DispWindowTitle(); // SourceForge.JPによるフォーク // SetTaskMsg("FFFTP Ver." VER_STR " Copyright(C) 1997-2010 Sota & cooperators."); - 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, raido)."); + 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)."); if(ForceIni) SetTaskMsg("%s%s", MSGJPN283, IniPath); @@ -612,13 +632,7 @@ static int MakeAllWindows(int cmdShow) WinPosX = CW_USEDEFAULT; WinPosY = 0; } - // UTF-8対応 - // ユーザー定義のクラスはデフォルトのWNDPROCがShift_JIS専用のため -// hWndFtp = CreateWindow(FtpClassStr, "FFFTP", -// WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, -// WinPosX, WinPosY, WinWidth, WinHeight, -// HWND_DESKTOP, 0, hInstFtp, NULL); - hWndFtp = CreateWindowA(FtpClassStr, "FFFTP", + hWndFtp = CreateWindow(FtpClassStr, "FFFTP", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WinPosX, WinPosY, WinWidth, WinHeight, HWND_DESKTOP, 0, hInstFtp, NULL); @@ -825,21 +839,43 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA { PAINTSTRUCT ps; LPTOOLTIPTEXT lpttt; + // UTF-8対応 + LPTOOLTIPTEXTW wlpttt; RECT Rect; int TmpTransType; switch (message) { + // 自動切断対策 + case WM_TIMER : + if(wParam == 1) + NoopProc(); + break; + case WM_COMMAND : + // 同時接続対応 + // 中断後に受信バッファに応答が残っていると次のコマンドの応答が正しく処理できない + if(CancelFlg == YES) + RemoveReceivedData(AskCmdCtrlSkt()); switch(LOWORD(wParam)) { case MENU_CONNECT : + // 自動切断対策 + KillTimer(hWnd, 1); ConnectProc(DLG_TYPE_CON, -1); + // 自動切断対策 + if(AskNoopInterval() > 0) + SetTimer(hWnd, 1, AskNoopInterval() * 1000, NULL); break; case MENU_CONNECT_NUM : + // 自動切断対策 + KillTimer(hWnd, 1); ConnectProc(DLG_TYPE_CON, (int)lParam); + // 自動切断対策 + if(AskNoopInterval() > 0) + SetTimer(hWnd, 1, AskNoopInterval() * 1000, NULL); if(AskConnecting() == YES) { if(HIWORD(wParam) & OPT_MIRROR) @@ -860,11 +896,21 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA break; case MENU_SET_CONNECT : + // 自動切断対策 + KillTimer(hWnd, 1); ConnectProc(DLG_TYPE_SET, -1); + // 自動切断対策 + if(AskNoopInterval() > 0) + SetTimer(hWnd, 1, AskNoopInterval() * 1000, NULL); break; case MENU_QUICK : + // 自動切断対策 + KillTimer(hWnd, 1); QuickConnectProc(); + // 自動切断対策 + if(AskNoopInterval() > 0) + SetTimer(hWnd, 1, AskNoopInterval() * 1000, NULL); break; case MENU_DISCONNECT : @@ -898,7 +944,12 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA case MENU_HIST_18 : case MENU_HIST_19 : case MENU_HIST_20 : + // 自動切断対策 + KillTimer(hWnd, 1); HistoryConnectProc(LOWORD(wParam)); + // 自動切断対策 + if(AskNoopInterval() > 0) + SetTimer(hWnd, 1, AskNoopInterval() * 1000, NULL); break; case MENU_UPDIR : @@ -1081,12 +1132,16 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA break; case MENU_FILTER : + // 同時接続対応 + CancelFlg = NO; SetFilter(&CancelFlg); break; case MENU_SORT : if(SortSetting() == YES) { + // 同時接続対応 + CancelFlg = NO; LocalFileSort = AskSortType(ITEM_LFILE); LocalDirSort = AskSortType(ITEM_LDIR); RemoteFileSort = AskSortType(ITEM_RFILE); @@ -1140,6 +1195,7 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA case MENU_KNJ_EUC : case MENU_KNJ_JIS : case MENU_KNJ_UTF8N : + case MENU_KNJ_UTF8BOM : case MENU_KNJ_NONE : SetHostKanjiCode(LOWORD(wParam)); break; @@ -1148,6 +1204,7 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA case MENU_L_KNJ_EUC : case MENU_L_KNJ_JIS : case MENU_L_KNJ_UTF8N : + case MENU_L_KNJ_UTF8BOM : SetLocalKanjiCode(LOWORD(wParam)); break; @@ -1156,6 +1213,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA break; case MENU_REFRESH : + // 同時接続対応 + CancelFlg = NO; SuppressRefresh = 1; GetLocalDirForWnd(); if(CheckClosedAndReconnect() == FFFTP_SUCCESS) @@ -1180,6 +1239,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA break; case REFRESH_REMOTE : + // 同時接続対応 + CancelFlg = NO; SuppressRefresh = 1; if(CheckClosedAndReconnect() == FFFTP_SUCCESS) GetRemoteDirForWnd(CACHE_REFRESH, &CancelFlg); @@ -1208,7 +1269,9 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA break; case MENU_HELP_TROUBLE : - ShellExecute(NULL, "open", MYWEB_URL, NULL, ".", SW_SHOW); + // 任意のコードが実行されるバグ修正 +// ShellExecute(NULL, "open", MYWEB_URL, NULL, ".", SW_SHOW); + ShellExecute(NULL, "open", MYWEB_URL, NULL, NULL, SW_SHOW); break; case MENU_BMARK_ADD : @@ -1244,6 +1307,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA break; case MENU_DOTFILE : + // 同時接続対応 + CancelFlg = NO; DotFile ^= 1; DispDotFileMode(); GetLocalDirForWnd(); @@ -1341,8 +1406,13 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA switch(((LPNMHDR)lParam)->code) { /* ツールチップコントロールメッセージの処理 */ - case TTN_NEEDTEXT: + // UTF-8対応 +// case TTN_NEEDTEXT: + case TTN_NEEDTEXTW: lpttt = (LPTOOLTIPTEXT)lParam; + // UTF-8対応 + // lptttは単なる警告回避用 + wlpttt = (LPTOOLTIPTEXTW)lParam; lpttt->hinst = hInstFtp; switch(lpttt->hdr.idFrom) { @@ -1432,6 +1502,10 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA lpttt->lpszText = MSGJPN308; break; + case MENU_KNJ_UTF8BOM : + lpttt->lpszText = MSGJPN330; + break; + case MENU_KNJ_NONE : lpttt->lpszText = MSGJPN173; break; @@ -1452,6 +1526,10 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA lpttt->lpszText = MSGJPN312; break; + case MENU_L_KNJ_UTF8BOM : + lpttt->lpszText = MSGJPN331; + break; + case MENU_KANACNV : lpttt->lpszText = MSGJPN174; break; @@ -1464,15 +1542,14 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA lpttt->lpszText = MSGJPN176; break; } - // UTF-8からShift_JISへ変換 + // UTF-8対応 + // UTF-8からUTF-16 LEへ変換 { static wchar_t StringBufferUTF16[1024]; - static char StringBufferSJIS[1024]; if(lpttt->lpszText) { MtoW(StringBufferUTF16, sizeof(StringBufferUTF16)/ sizeof(wchar_t), lpttt->lpszText, -1); - WtoA(StringBufferSJIS, sizeof(StringBufferSJIS)/ sizeof(char), StringBufferUTF16, -1); - lpttt->lpszText = StringBufferSJIS; + wlpttt->lpszText = StringBufferUTF16; } } break; @@ -1480,6 +1557,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA case LVN_COLUMNCLICK : if(((NMHDR *)lParam)->hwndFrom == GetLocalHwnd()) { + // 同時接続対応 + CancelFlg = NO; SetSortTypeByColumn(WIN_LOCAL, ((NM_LISTVIEW *)lParam)->iSubItem); ReSortDispList(WIN_LOCAL, &CancelFlg); } @@ -1487,6 +1566,8 @@ static LRESULT CALLBACK FtpWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA { if(((NM_LISTVIEW *)lParam)->iSubItem != 4) { + // 同時接続対応 + CancelFlg = NO; SetSortTypeByColumn(WIN_REMOTE, ((NM_LISTVIEW *)lParam)->iSubItem); ReSortDispList(WIN_REMOTE, &CancelFlg); } @@ -2079,6 +2160,8 @@ void DoubleClickProc(int Win, int Mode, int App) // if((Sts = DoDownLoad(AskCmdCtrlSkt(), &MainTransPkt, NO)) == 429) // { // ReConnectCmdSkt(); + // 同時接続対応 + CancelFlg = NO; Sts = DoDownLoad(AskCmdCtrlSkt(), &MainTransPkt, NO, &CancelFlg); // } } @@ -2131,6 +2214,11 @@ static void ChangeDir(int Win, char *Path) char Local[FMAX_PATH+1]; char Remote[FMAX_PATH+1]; + // 同時接続対応 + CancelFlg = NO; + + // デッドロック対策 + DisableUserOpe(); Sync = AskSyncMoveMode(); if(Sync == YES) { @@ -2162,6 +2250,8 @@ static void ChangeDir(int Win, char *Path) GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg); } } + // デッドロック対策 + EnableUserOpe(); return; } @@ -2419,6 +2509,8 @@ void ExecViewer(char *Fname, int App) char AssocProg[FMAX_PATH+1]; char ComLine[FMAX_PATH*2+3+1]; char CurDir[FMAX_PATH+1]; + // 任意のコードが実行されるバグ修正 + char SysDir[FMAX_PATH+1]; /* FindExecutable()は関連付けられたプログラムのパス名にスペースが */ /* 含まれている時、間違ったパス名を返す事がある。 */ @@ -2426,7 +2518,10 @@ void ExecViewer(char *Fname, int App) AskLocalCurDir(CurDir, FMAX_PATH); - if((App == -1) && (FindExecutable(Fname, NULL, AssocProg) > (HINSTANCE)32)) + // 任意のコードが実行されるバグ修正 + // 拡張子が無いと補完されるため +// if((App == -1) && (FindExecutable(Fname, NULL, AssocProg) > (HINSTANCE)32)) + if((App == -1) && (strlen(GetFileExt(GetFileName(Fname))) > 0) && (FindExecutable(Fname, NULL, AssocProg) > (HINSTANCE)32)) { DoPrintf("ShellExecute - %s", Fname); ShellExecute(NULL, "open", Fname, NULL, CurDir, SW_SHOW); @@ -2446,10 +2541,26 @@ void ExecViewer(char *Fname, int App) memset(&Startup, NUL, sizeof(STARTUPINFO)); Startup.cb = sizeof(STARTUPINFO); Startup.wShowWindow = SW_SHOW; - if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE) + // 任意のコードが実行されるバグ修正 +// if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE) +// { +// SetTaskMsg(MSGJPN182, GetLastError()); +// SetTaskMsg(">>%s", ComLine); +// } + if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0) { - SetTaskMsg(MSGJPN182, GetLastError()); - SetTaskMsg(">>%s", ComLine); + if(GetSystemDirectory(SysDir, FMAX_PATH) > 0) + { + if(SetCurrentDirectory(SysDir)) + { + if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE) + { + SetTaskMsg(MSGJPN182, GetLastError()); + SetTaskMsg(">>%s", ComLine); + } + SetCurrentDirectory(CurDir); + } + } } } return; @@ -2474,6 +2585,8 @@ void ExecViewer2(char *Fname1, char *Fname2, int App) char AssocProg[FMAX_PATH+1]; char ComLine[FMAX_PATH*2+3+1]; char CurDir[FMAX_PATH+1]; + // 任意のコードが実行されるバグ修正 + char SysDir[FMAX_PATH+1]; /* FindExecutable()は関連付けられたプログラムのパス名にスペースが */ /* 含まれている時、間違ったパス名を返す事がある。 */ @@ -2493,10 +2606,26 @@ void ExecViewer2(char *Fname1, char *Fname2, int App) memset(&Startup, NUL, sizeof(STARTUPINFO)); Startup.cb = sizeof(STARTUPINFO); Startup.wShowWindow = SW_SHOW; - if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE) + // 任意のコードが実行されるバグ修正 +// if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE) +// { +// SetTaskMsg(MSGJPN182, GetLastError()); +// SetTaskMsg(">>%s", ComLine); +// } + if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0) { - SetTaskMsg(MSGJPN182, GetLastError()); - SetTaskMsg(">>%s", ComLine); + if(GetSystemDirectory(SysDir, FMAX_PATH) > 0) + { + if(SetCurrentDirectory(SysDir)) + { + if(CreateProcess(NULL, ComLine, NULL, NULL, FALSE, 0, NULL, NULL, &Startup, &Info) == FALSE) + { + SetTaskMsg(MSGJPN182, GetLastError()); + SetTaskMsg(">>%s", ComLine); + } + SetCurrentDirectory(CurDir); + } + } } return; @@ -2706,7 +2835,9 @@ int BackgrndMessageProc(void) Ret = NO; while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) { - if(!HtmlHelp(NULL, NULL, HH_PRETRANSLATEMESSAGE, (DWORD)&Msg)) + // マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策 +// if(!HtmlHelp(NULL, NULL, HH_PRETRANSLATEMESSAGE, (DWORD)&Msg)) + if(!IsMainThread() || !HtmlHelp(NULL, NULL, HH_PRETRANSLATEMESSAGE, (DWORD)&Msg)) { /* ディレクトリ名の表示コンボボックスでBSやRETが効くように */ /* コンボボックス内ではアクセラレータを無効にする */ @@ -2815,32 +2946,36 @@ int EnterMasterPasswordAndSet( int Res, HWND hWnd ) } // 暗号化通信対応 -BOOL __stdcall SSLTimeoutCallback() +BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted) { Sleep(1); if(BackgrndMessageProc() == YES) return TRUE; - // 念のためツールバーのMENU_ABORTも確認 -// if(MainTransPkt.Abort != ABORT_NONE) -// { -// MainTransPkt.Abort = ABORT_NONE; -// return TRUE; -// } + if(*pbAborted == YES) + return TRUE; return FALSE; } -BOOL __stdcall SSLConfirmCallback(BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName) +BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName) { BOOL bResult; - int i; uint32 Hash[5]; + int i; char* pm0; bResult = FALSE; sha_memory((char*)Certificate, (uint32)(strlen(Certificate) * sizeof(char)), (uint32*)&Hash); - for(i = 0; i < MAX_CERT_CACHE_HASH; i++) + // sha.cはビッグエンディアンのため + for(i = 0; i < 5; i++) + Hash[i] = _byteswap_ulong(Hash[i]); + i = 0; + while(i < MAX_CERT_CACHE_HASH) { if(memcmp(&CertificateCacheHash[i], &Hash, 20) == 0) + { bResult = TRUE; + break; + } + i++; } if(!bResult) { @@ -2858,7 +2993,50 @@ BOOL __stdcall SSLConfirmCallback(BOOL bVerified, LPCSTR Certificate, LPCSTR Com } } if(!bResult) - CancelFlg = YES; + *pbAborted = YES; return bResult; } +BOOL LoadSSLRootCAFile() +{ + BOOL bResult; + HANDLE hFile; + DWORD Size; + BYTE* pBuffer; + uint32 Hash[5]; + int i; + bResult = FALSE; + if((hFile = CreateFile(SSLRootCAFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) + { + Size = GetFileSize(hFile, NULL); + if(pBuffer = (BYTE*)malloc(Size)) + { + if(ReadFile(hFile, pBuffer, Size, &Size, NULL)) + { + sha_memory((char*)pBuffer, (uint32)Size, (uint32*)&Hash); + // sha.cはビッグエンディアンのため + for(i = 0; i < 5; i++) + Hash[i] = _byteswap_ulong(Hash[i]); + // 同梱する"ssl.pem"に合わせてSHA1ハッシュ値を変更すること + if(memcmp(&Hash, &SSLRootCAFileHash, 20) == 0 || memcmp(&Hash, "\xF0\x1B\x48\x26\x67\x44\x3A\xFF\x0A\x16\xD3\xBB\x8A\x33\xEB\x70\x6D\x75\xA6\x0D", 20) == 0 + || DialogBox(GetFtpInst(), MAKEINTRESOURCE(updatesslroot_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) + { + memcpy(&SSLRootCAFileHash, &Hash, 20); + if(SetSSLRootCertificate(pBuffer, Size)) + bResult = TRUE; + } + } + free(pBuffer); + } + CloseHandle(hFile); + } + return bResult; +} + +// マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策 +BOOL IsMainThread() +{ + if(GetCurrentThreadId() != MainThreadId) + return FALSE; + return TRUE; +} \ No newline at end of file