From 26f425f0153de537bc676c9c38a68ef3edd882c5 Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Fri, 27 Aug 2010 00:00:01 +0300 Subject: using threads, gpg execution timeout, fixed high cpu usage when waiting gpg process --- main.cpp | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 245 insertions(+), 15 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index e4a92fc..efed2bc 100644 --- a/main.cpp +++ b/main.cpp @@ -78,10 +78,23 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM {//parse gpg output string out; DWORD code; + pxResult result; wstring::size_type p = 0, p2 = 0, stop = 0; { + gpg_execution_params params; wstring cmd = _T("--batch --list-secret-keys"); - if(pxExecute(&cmd, "", &out, &code) == pxNotFound) + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) { MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; @@ -152,7 +165,20 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM DWORD code; wstring cmd = _T("--batch -a --export "); cmd += fp; - if(pxExecute(&cmd, "", &out, &code) == pxNotFound) + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) { MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; @@ -181,9 +207,148 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM extern int item_num; item_num = 0; //black magic here user_data[1] = 0; - MessageBox(0, _T("Set secret key in following dialog.\nI do not know if password protected key is work..."), _T("Info"), MB_OK); ShowLoadPublicKeyDialog(); + ListView_DeleteAllItems(hwndList); + { + int i = 1, iRow = 0; + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = _T(""); + {//parse gpg output + string out; + DWORD code; + wstring::size_type p = 0, p2 = 0, stop = 0; + { + wstring cmd = _T("--batch --list-secret-keys"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + break; + } + } + while(p != string::npos) + { + if((p = out.find("sec ", p)) == string::npos) + break; + p += 5; + if(p < stop) + break; + stop = p; + p2 = out.find("/", p) - 1; + TCHAR *tmp = mir_utf8decodeW(out.substr(p,p2-p).c_str()); + item.pszText = tmp; + iRow = ListView_InsertItem(hwndList, &item); + ListView_SetItemText(hwndList, iRow, 4, tmp); + mir_free(tmp); + p2+=2; + p = out.find(" ", p2); + tmp = mir_utf8decodeW(out.substr(p2,p-p2).c_str()); + ListView_SetItemText(hwndList, iRow, 0, tmp); + mir_free(tmp); + p = out.find("uid ", p); + p2 = out.find_first_not_of(" ", p+5); + p = out.find("<", p2); + tmp = mir_utf8decodeW(out.substr(p2,p-p2).c_str()); + ListView_SetItemText(hwndList, iRow, 2, tmp); + mir_free(tmp); + p++; + p2 = out.find(">", p); + tmp = mir_utf8decodeW(out.substr(p,p2-p).c_str()); + ListView_SetItemText(hwndList, iRow, 1, tmp); + mir_free(tmp); + p = out.find("ssb ", p2) + 6; + p = out.find(" ", p) + 1; + p2 = out.find("\n", p); + tmp = mir_utf8decodeW(out.substr(p,p2-p-1).c_str()); + ListView_SetItemText(hwndList, iRow, 3, tmp); + mir_free(tmp); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); + i++; + } + } + } + } + break; + case IDC_DELETE_KEY: + ListView_GetItemText(hwndList, itemnum, 0, fp, 16); + { + string out; + DWORD code; + wstring cmd = _T("--batch --fingerprint "); + cmd += fp; + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + break; + } + string::size_type s = out.find("Key fingerprint = "); + s += strlen("Key fingerprint = "); + string::size_type s2 = out.find("\n", s); + TCHAR *fp = NULL; + { + string tmp = out.substr(s, s2-s-1).c_str(); + string::size_type p = 0; + while((p = tmp.find(" ", p)) != string::npos) + { + tmp.erase(p, 1); + } + fp = mir_a2t(tmp.c_str()); + } + cmd.clear(); + out.clear(); + cmd += _T("--batch --delete-secret-and-public-key --fingerprint "); + cmd += fp; + mir_free(fp); + gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + break; + } } + DBDeleteContactSetting(NULL, szGPGModuleName, "GPGPubKey"); + DBDeleteContactSetting(NULL, szGPGModuleName, "KeyID"); + DBDeleteContactSetting(NULL, szGPGModuleName, "KeyComment"); + DBDeleteContactSetting(NULL, szGPGModuleName, "KeyMainName"); + DBDeleteContactSetting(NULL, szGPGModuleName, "KeyMainEmail"); + DBDeleteContactSetting(NULL, szGPGModuleName, "KeyType"); + ListView_DeleteItem(hwndList, itemnum); break; } break; @@ -530,10 +695,23 @@ static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, wstring cmd; cmd += _T("--batch --yes --gen-key \""); cmd += path; - cmd += _T("\""); - if(pxExecute(&cmd, "", &out, &code) == pxNotFound) + cmd += _T("\""); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 300000) == WAIT_TIMEOUT) { - MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; } } @@ -550,10 +728,23 @@ static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, DWORD code; string::size_type p = 0, p2 = 0, stop = 0; { - wstring cmd = _T("--list-secret-keys"); - if(pxExecute(&cmd, "", &out, &code) == pxNotFound) + wstring cmd = _T("--list-secret-keys"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) { - MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; } } @@ -687,10 +878,23 @@ static BOOL CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam, DWORD code; string::size_type p = 0, p2 = 0, stop = 0; { - wstring cmd = _T("--batch --list-keys"); - if(pxExecute(&cmd, "", &out, &code) == pxNotFound) + wstring cmd = _T("--batch --list-keys"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) { - MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; } } @@ -753,7 +957,20 @@ static BOOL CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam, DWORD code; wstring cmd = _T("--batch -a --export "); cmd += id; - if(pxExecute(&cmd, "", &out, &code) == pxNotFound) + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) { MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; @@ -900,8 +1117,21 @@ void ImportKey() cmd += _T(" --import \""); cmd += tmp2; cmd += _T("\""); - } - if(pxExecute(&cmd, "", &output, &exitcode) == pxNotFound) + } + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &output; + params.code = &exitcode; + params.result = &result; + HANDLE gpg_thread = mir_forkthread(pxEexcute_thread, (void*)¶ms); + if(WaitForSingleObject(gpg_thread, 10000) == WAIT_TIMEOUT) + { + TerminateThread(gpg_thread, 0); + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) { MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); return; -- cgit v1.2.3