summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-03 15:46:24 +0200
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-03 15:46:24 +0200
commit5657453dcc8626b9f7f13f7ade1eb3e5afa13cc8 (patch)
tree9e0f6204a546a3e4da38b2747cd85a550bb58c59
parent9e7bea7606d6fed31cb71a9e1682757be47a8b8f (diff)
ability to change key password (because of fucked gpg which does not want to give us his stdin/stdout only via ugly windows console)
-rwxr-xr-xcommonheaders.h3
-rwxr-xr-xgpg_wrapper.cpp177
-rwxr-xr-xgpg_wrapper.h19
-rwxr-xr-xmain.cpp50
-rwxr-xr-xnew_gpg.rc35
-rwxr-xr-xnew_gpg.vcxproj2
-rwxr-xr-xresource.h10
-rwxr-xr-xutilities.cpp123
8 files changed, 398 insertions, 21 deletions
diff --git a/commonheaders.h b/commonheaders.h
index 459d76e..5dc34a3 100755
--- a/commonheaders.h
+++ b/commonheaders.h
@@ -49,6 +49,9 @@ using std::fstream;
#include <boost/random/variate_generator.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/date_time.hpp>
+#include <boost/iostreams/stream.hpp>
+//boost process
+#include <boost/process.hpp>
//utf8cpp
diff --git a/gpg_wrapper.cpp b/gpg_wrapper.cpp
index f253b25..adce958 100755
--- a/gpg_wrapper.cpp
+++ b/gpg_wrapper.cpp
@@ -173,3 +173,180 @@ void pxEexcute_thread(void *param)
gpg_execution_params *params = (gpg_execution_params*)param;
pxResult result = pxExecute(params->cmd, params->useless, params->out, params->code, params->result, params->hProcess, params->proc);
}
+
+
+
+pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr, string &old_pass, string &new_pass)
+{
+// gpg_mutex.lock();
+ if(!gpg_valid)
+ return pxNotConfigured;
+ extern logtofile debuglog;
+
+ TCHAR *bin_path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T(""));
+ {
+ if(_waccess(bin_path, 0) == -1)
+ {
+ if(errno == ENOENT)
+ {
+ mir_free(bin_path);
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": GPG executable not found");
+ *result = pxNotFound;
+ return pxNotFound;
+ }
+ }
+ }
+
+ using namespace boost::process;
+ using namespace boost::process::initializers;
+ using namespace boost::iostreams;
+
+
+ std::vector<std::wstring> argv;
+ std::vector<std::wstring> env;
+ env.push_back(L"LANGUAGE=en@quot");
+ env.push_back(L"LC_ALL=English");
+ argv.push_back(bin_path);
+ argv.push_back(L"--homedir");
+ TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ argv.push_back(home_dir);
+ mir_free(home_dir);
+ argv.push_back(L"--display-charset");
+ argv.push_back(L"utf-8");
+ argv.push_back(L"-z9");
+ argv.insert(argv.end(), aargv.begin(), aargv.end());
+
+// pipe pout = create_pipe();
+ pipe pin = create_pipe();
+// file_descriptor_sink sout(pout.sink, close_handle);
+ file_descriptor_source sin(pin.source, close_handle);
+
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+
+ //execute(set_args(argv), bind_stdout(sout), bind_stdin(sin), show_window(SW_HIDE), hide_console(), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
+ child c = execute(set_args(argv), bind_stdin(sin), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
+ //child c = execute(run_exe("c:\\windows\\system32\\cmd.exe"), bind_stdin(sin), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path)));
+
+ delete [] mir_path;
+
+// file_descriptor_source source(pout.source, close_handle);
+/* file_descriptor_sink _sin(pin.sink, close_handle);
+
+ stream<file_descriptor_sink> out(_sin);
+
+
+ std::wstring cmd;
+ for(int i = 0; i < argv.size(); i++)
+ {
+ cmd += argv[i];
+ cmd += L" ";
+ }
+ */
+// out<<toUTF8(cmd)<<std::endl;
+
+ //fucked gpg does not want to give us stdin/stdout
+ wait_for_exit(c);
+
+/* out<<old_pass<<std::endl;
+ out<<new_pass<<std::endl;
+ out<<new_pass<<std::endl;
+ out<<"save"<<std::endl; */
+
+// stream<file_descriptor_source> is(source);
+/* std::string s;
+
+ is>>s;
+
+ MessageBoxA(NULL, s.c_str(), "", MB_OK); */
+
+
+/* ctx.environment = boost::process::self::get_environment();
+ ctx.environment.insert(boost::process::environment::value_type("LANGUAGE", "en@quot"));
+ ctx.environment["LC_ALL"] = "English";
+
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ ctx.work_directory = mir_path;
+ delete [] mir_path;
+
+ boost::process::win32_child proc = boost::process::win32_launch(toUTF8(bin_path), argv, ctx);
+
+ mir_free(bin_path);
+
+// boost::process::pistream &_stdout = proc.get_stdout();
+ boost::process::postream &_stdin = proc.get_stdin();
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+
+ std::string buf; */
+
+
+/* std::getline(_stdout, buf);
+ while(_stdout.good())
+ {
+ *aoutput += buf;
+ if(aoutput->find("Enter passphrase") != std::string::npos)
+ break;
+ boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+ std::getline(_stdout, buf);
+ }
+ *aoutput += buf; */
+
+ //_stdin<<old_pass<<std::endl;
+
+/* std::getline(_stdout, buf);
+ while(_stdout.good())
+ {
+ *aoutput += buf;
+ if(aoutput->find("Enter the new passphrase for this secret key.") != std::string::npos)
+ break;
+ boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+ std::getline(_stdout, buf);
+ }
+
+ *aoutput += buf;
+
+ if(aoutput->find("Enter passphrase") != std::string::npos)*/
+ //_stdin<<new_pass<<std::endl;
+
+/* std::getline(_stdout, buf);
+ while(_stdout.good())
+ {
+ *aoutput += buf;
+ if(aoutput->find("Repeat passphrase") != std::string::npos)
+ break;
+ boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+ std::getline(_stdout, buf);
+ }
+ *aoutput += buf; */
+
+ //_stdin<<new_pass<<std::endl;
+
+/* std::getline(_stdout, buf);
+ while(_stdout.good())
+ {
+ *aoutput += buf;
+ if(aoutput->find("Command") != std::string::npos)
+ break;
+ boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+ std::getline(_stdout, buf);
+ }
+ *aoutput += buf; */
+
+ //_stdin<<"save"<<std::endl;
+
+ //proc.wait();
+
+ //MessageBoxA(NULL, aoutput->c_str(), "info", MB_OK);
+
+ return pxSuccess;
+}
+
+
+void pxEexcute_passwd_change_thread(void *param)
+{
+ gpg_execution_params_pass *params = (gpg_execution_params_pass*)param;
+ pxResult result = pxExecute_passwd_change(params->args, params->useless, params->out, params->code, params->result, params->hProcess, params->proc, params->old_pass, params->new_pass);
+}
diff --git a/gpg_wrapper.h b/gpg_wrapper.h
index 5501297..44b2f4f 100755
--- a/gpg_wrapper.h
+++ b/gpg_wrapper.h
@@ -32,7 +32,8 @@ typedef enum {
}
pxResult;
-pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result);
+pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr);
+pxResult pxExecute_passwd_change(std::vector<std::string> &aargv, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr, string &old_pass, string &new_pass);
struct gpg_execution_params
{
@@ -45,6 +46,22 @@ struct gpg_execution_params
PROCESS_INFORMATION *proc;
};
+struct gpg_execution_params_pass
+{
+ std::vector<std::wstring> &args;
+ string &old_pass, &new_pass;
+ char *useless;
+ string *out;
+ LPDWORD code;
+ pxResult *result;
+ HANDLE hProcess;
+ PROCESS_INFORMATION *proc;
+ gpg_execution_params_pass(std::vector<std::wstring> &a, std::string &o, std::string &n): args(a), old_pass(o), new_pass(n)
+ {}
+};
+
+
void pxEexcute_thread(void *param);
+void pxEexcute_passwd_change_thread(void *param);
#endif \ No newline at end of file
diff --git a/main.cpp b/main.cpp
index 495f025..2578995 100755
--- a/main.cpp
+++ b/main.cpp
@@ -27,6 +27,8 @@ int itemnum = 0;
HWND hwndList_g = NULL;
BOOL CheckStateStoreDB(HWND hwndDlg, int idCtrl, const char* szSetting);
+TCHAR key_id_global[17] = {0};
+
static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
HWND hwndList=GetDlgItem(hwndDlg, IDC_KEY_LIST);
@@ -44,6 +46,7 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR
SetWindowText(hwndDlg, TranslateT("Set own key"));
EnableWindow(GetDlgItem(hwndDlg, IDC_COPY_PUBKEY), 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PRIVATE), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE_PASSWD), 0);
col.pszText = _T("Key ID");
col.mask = LVCF_TEXT | LVCF_WIDTH;
col.fmt = LVCFMT_LEFT;
@@ -178,8 +181,8 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR
if(expired)
{
mir_free(key_len);
- mir_free(expire_date);
mir_free(creation_date);
+ mir_free(expire_date);
//mimic normal behaviour
p = out.find("uid ", p);
p2 = out.find_first_not_of(" ", p+5);
@@ -187,15 +190,18 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR
p++;
p2 = out.find(">", p);
//
- continue;
+ continue; //does not add to key list
}
}
}
iRow = ListView_InsertItem(hwndList, &item);
ListView_SetItemText(hwndList, iRow, 3, creation_date);
mir_free(creation_date);
- ListView_SetItemText(hwndList, iRow, 4, expire_date);
- mir_free(expire_date);
+ if(expire_date)
+ {
+ ListView_SetItemText(hwndList, iRow, 4, expire_date);
+ mir_free(expire_date);
+ }
ListView_SetItemText(hwndList, iRow, 5, key_len);
mir_free(key_len);
ListView_SetItemText(hwndList, iRow, 0, (TCHAR*)key_id.c_str());
@@ -811,7 +817,40 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR
file.close();
}
break;
-
+ case IDC_CHANGE_PASSWD:
+ ListView_GetItemText(hwndList, itemnum, 0, key_id_global, 16);
+// extern void ShowChangePasswdDlg();
+// ShowChangePasswdDlg();
+ //temporary code follows
+ std::vector<std::wstring> cmd;
+ std::string old_pass, new_pass;
+ TCHAR tmp2[MAX_PATH] = {0};
+ string output;
+ DWORD exitcode;
+ cmd.push_back(L"--edit-key");
+ cmd.push_back(key_id_global);
+ cmd.push_back(L"passwd");
+ gpg_execution_params_pass params(cmd, old_pass, new_pass);
+ pxResult result;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, &params));
+ if(!gpg_thread.timed_join(boost::posix_time::minutes(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": GPG execution timed out, aborted");
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ //
+ break;
}
break;
}
@@ -825,6 +864,7 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR
EnableWindow(GetDlgItem(hwndDlg, ID_OK), 1);
EnableWindow(GetDlgItem(hwndDlg, IDC_COPY_PUBKEY), 1);
EnableWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PRIVATE), 1);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE_PASSWD), 1);
itemnum = hdr->iItem;
}
}
diff --git a/new_gpg.rc b/new_gpg.rc
index caf8096..81b614e 100755
--- a/new_gpg.rc
+++ b/new_gpg.rc
@@ -83,6 +83,7 @@ BEGIN
COMBOBOX IDC_ACCOUNT,66,9,104,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Copy public key",IDC_COPY_PUBKEY,7,169,101,14
PUSHBUTTON "Export private key",IDC_EXPORT_PRIVATE,182,169,102,14
+ PUSHBUTTON "Change password",IDC_CHANGE_PASSWD,182,187,102,14
END
IDD_BIN_PATH DIALOGEX 0, 0, 354, 108
@@ -199,6 +200,19 @@ BEGIN
CONTROL "Export public and private keys",IDC_ALL,"Button",BS_AUTORADIOBUTTON,15,50,248,10
END
+IDD_CHANGE_PASSWD DIALOGEX 0, 0, 256, 74
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Change private key password"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_OLD_PASSWD,81,16,158,14,ES_PASSWORD | ES_AUTOHSCROLL
+ EDITTEXT IDC_NEW_PASSWD1,82,33,156,14,ES_PASSWORD | ES_AUTOHSCROLL
+ EDITTEXT IDC_NEW_PASSWD2,81,50,157,14,ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "Current password:",IDC_STATIC,7,17,61,8
+ LTEXT "New password twice:",IDC_STATIC,7,32,69,8
+ PUSHBUTTON "Ok",IDC_OK,7,55,50,14
+END
+
/////////////////////////////////////////////////////////////////////////////
//
@@ -226,6 +240,7 @@ BEGIN
HORZGUIDE, 20
HORZGUIDE, 166
HORZGUIDE, 183
+ HORZGUIDE, 201
END
IDD_BIN_PATH, DIALOG
@@ -293,6 +308,14 @@ BEGIN
BOTTOMMARGIN, 85
HORZGUIDE, 70
END
+
+ IDD_CHANGE_PASSWD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 249
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 69
+ END
END
#endif // APSTUDIO_INVOKED
@@ -431,18 +454,6 @@ END
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
- IDD_OPT_GPG, DIALOG
- BEGIN
- END
-
- IDD_OPT_GPG_BIN, DIALOG
- BEGIN
- END
-
- IDD_OPT_GPG_MESSAGES, DIALOG
- BEGIN
- END
-
IDD_OPT_GPG_ADVANCED, DIALOG
BEGIN
VERTGUIDE, 12
diff --git a/new_gpg.vcxproj b/new_gpg.vcxproj
index 45d9be6..c6de2ed 100755
--- a/new_gpg.vcxproj
+++ b/new_gpg.vcxproj
@@ -745,7 +745,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>x:\temp\windows\libs\utf8cpp\include;x:\temp\windows\libs\Boost\include;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>X:\temp\windows\libs\boost_process;x:\temp\windows\libs\utf8cpp\include;x:\temp\windows\libs\Boost\include;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
diff --git a/resource.h b/resource.h
index 38f790f..cd607fb 100755
--- a/resource.h
+++ b/resource.h
@@ -18,6 +18,7 @@
#define IDD_OPT_GPG_ADVANCED 113
#define IDD_ENCRYPTED_FILE_MSG_BOX 114
#define IDD_EXPORT_TYPE 115
+#define IDD_CHANGE_PASSWD 116
#define IDC_SET_BIN_PATH 1016
#define IDC_SET_HOME_DIR 1017
#define IDC_BIN_PATH 1018
@@ -97,14 +98,19 @@
#define IDC_PRIVATE 1074
#define IDC_ALL 1075
#define IDC_EXPORT_PRIVATE 1076
+#define IDC_CHANGE_PASSWD 1077
+#define IDC_OLD_PASSWD 1078
+#define IDC_NEW_PASSWD1 1079
+#define IDC_NEW_PASSWD2 1080
+
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 115
+#define _APS_NEXT_RESOURCE_VALUE 117
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1077
+#define _APS_NEXT_CONTROL_VALUE 1081
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/utilities.cpp b/utilities.cpp
index dd94ac9..b42d8e7 100755
--- a/utilities.cpp
+++ b/utilities.cpp
@@ -2253,3 +2253,126 @@ void ShowExportKeysDlg()
extern HINSTANCE hInst;
DialogBox(hInst, MAKEINTRESOURCE(IDD_EXPORT_TYPE), NULL, DlgProcExportKeys);
}
+
+static INT_PTR CALLBACK DlgProcChangePasswd(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_OK:
+ //TODO: show some prgress
+ {
+ std::string old_pass, new_pass;
+ extern TCHAR key_id_global[17];
+ TCHAR buf[256] = {0};
+ GetDlgItemText(hwndDlg, IDC_NEW_PASSWD1, buf, 255);
+ new_pass = toUTF8(buf);
+ GetDlgItemText(hwndDlg, IDC_NEW_PASSWD2, buf, 255);
+ if(new_pass != toUTF8(buf))
+ {
+ MessageBox(hwndDlg, TranslateT("New passwords not match"), TranslateT("Error"), MB_OK);
+ //key_id_global[0] = 0;
+ break;
+ }
+ GetDlgItemText(hwndDlg, IDC_OLD_PASSWD, buf, 255);
+ old_pass = toUTF8(buf);
+ bool old_pass_match = false;
+ TCHAR *pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T(""));
+ if(!_tcscmp(pass,buf))
+ old_pass_match = true;
+ mir_free(pass);
+ if(!old_pass_match)
+ {
+ if(key_id_global[0])
+ {
+ string dbsetting = "szKey_";
+ dbsetting += toUTF8(key_id_global);
+ dbsetting += "_Password";
+ pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T(""));
+ if(!_tcscmp(pass,buf))
+ old_pass_match = true;
+ mir_free(pass);
+ }
+ }
+ if(!old_pass_match)
+ {
+ if(MessageBox(hwndDlg, TranslateT("Old password not match, you can continue, but gpg will reject wrong password.\nDo you want to continue?"), TranslateT("Error"), MB_YESNO) == IDNO)
+ {
+ //key_id_global[0] = 0;
+ break;
+ }
+ }
+ std::vector<std::wstring> cmd;
+ TCHAR tmp2[MAX_PATH] = {0};
+ string output;
+ DWORD exitcode;
+ cmd.push_back(L"--edit-key");
+ cmd.push_back(key_id_global);
+ cmd.push_back(L"passwd");
+ gpg_execution_params_pass params(cmd, old_pass, new_pass);
+ pxResult result;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, &params));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(100)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": GPG execution timed out, aborted");
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ //if(result == pxSuccess)
+ //TODO: save to db
+
+
+ }
+ DestroyWindow(hwndDlg);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ extern TCHAR key_id_global[17];
+ key_id_global[0] = 0;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+void ShowChangePasswdDlg()
+{
+ extern HINSTANCE hInst;
+ HWND hwndPaaswdDlg = NULL;
+ hwndPaaswdDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_CHANGE_PASSWD), NULL, DlgProcChangePasswd);
+ SetForegroundWindow(hwndPaaswdDlg);
+}