Skip to content

Commit

Permalink
ttpmenuプログラム起動部分を修正
Browse files Browse the repository at this point in the history
- プログラム起動に失敗したとき生成したマクロファイルを削除するようにした
- ttpmenu内で作成するコマンドライン長の上限なくした
  - Windows API(ShellExecuteExW(),ExecInfo.lpParameters)に渡す文字列
  - Windows側には(8191文字など)制限があると思われる
- 設定ダイアログのレイアウトを変更
  • Loading branch information
zmatsuo committed Dec 2, 2023
1 parent d667ebd commit d2a52cc
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 69 deletions.
2 changes: 1 addition & 1 deletion installer/release/lang_utf8/Japanese.lng
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ DLG_CONFIG_PASS=パスワード
DLG_CONFIG_MACRO=マクロファイルを指定して実行
DLG_CONFIG_LAUNCH=起動のみ
DLG_CONFIG_STARTUP=起動時に実行
DLG_CONFIG_SSH=ttsshを使う
DLG_CONFIG_SSH=sshを使用
DLG_CONFIG_KEYFILE=鍵ファイル
DLG_CONFIG_CHALLENGE=チャレンジレスポンス認証
DLG_CONFIG_PAGEANT=Pageantを使う
Expand Down
122 changes: 72 additions & 50 deletions ttpmenu/ttpmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <assert.h>

#include "ttpmenu.h"
#include "ttpmenu-version.h"
Expand Down Expand Up @@ -1077,15 +1078,13 @@ BOOL ConnectHost(HWND hWnd, UINT idItem, const wchar_t *szJobName)
{
wchar_t szName[MAX_PATH];
wchar_t szDefault[MAX_PATH] = DEFAULT_PATH;

wchar_t szDirectory[MAX_PATH];
wchar_t szHostName[MAX_PATH];
wchar_t szTempPath[MAX_PATH];
// https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/command-line-string-limitation
wchar_t szArgment[8192] = L"";
wchar_t szTemp[8192];
wchar_t szMacroFile[MAX_PATH];
bool MacroFileCreated = false;
wchar_t *szArgment = NULL;
wchar_t *szTemp;
wchar_t *pHostName;
wchar_t *pt;
JobInfo jobInfo;

DWORD dwErr;
Expand Down Expand Up @@ -1113,18 +1112,20 @@ BOOL ConnectHost(HWND hWnd, UINT idItem, const wchar_t *szJobName)
if ((pHostName = _wcstok(szHostName, L" ([{'\"|*")) != NULL)
pHostName = szHostName;

szArgment = wcsdup(L"");

if (jobInfo.dwMode != MODE_DIRECT)
if (wcslen(jobInfo.szInitFile) != 0) {
_snwprintf_s(szTemp, _countof(szTemp), _TRUNCATE, L"/F=\"%s\"", jobInfo.szInitFile);
wcsncat_s(szArgment, _countof(szArgment), szTemp, _TRUNCATE);
aswprintf(&szTemp, L"/F=\"%s\"", jobInfo.szInitFile);
awcscat(&szArgment, szTemp);
free(szTemp);
}


// SSH自動ログインの場合はマクロは不要
if (jobInfo.bTtssh != TRUE) {
wchar_t szMacroFile[MAX_PATH];
switch (jobInfo.dwMode) {
case MODE_AUTOLOGIN:
switch (jobInfo.dwMode) {
case MODE_AUTOLOGIN:
if (jobInfo.bTtssh != TRUE) {
// TTSSHを使用しない, 自動ログインマクロを生成、使用する
wchar_t szTempPath[MAX_PATH];
::GetTempPathW(MAX_PATH, szTempPath);
::GetTempFileNameW(szTempPath, L"ttm", 0, szMacroFile);
if (MakeTTL(szMacroFile, &jobInfo) == FALSE) {
Expand All @@ -1134,87 +1135,97 @@ BOOL ConnectHost(HWND hWnd, UINT idItem, const wchar_t *szJobName)
ErrorMessage(hWnd, dwErr, uimsg);
return FALSE;
}
break;
case MODE_MACRO:
wcscpy(szMacroFile, jobInfo.szMacroFile);
break;
}
if (jobInfo.dwMode != MODE_DIRECT) {
_snwprintf_s(szTemp, _countof(szTemp), _TRUNCATE, L" /M=\"%s\"", szMacroFile);
wcsncat_s(szArgment, _countof(szArgment), szTemp, _TRUNCATE);
}
}
MacroFileCreated = true;
wchar_t *m_option;
aswprintf(&m_option, L" /M=\"%s\"", szMacroFile);
awcscat(&szArgment, m_option);
free(m_option);

if (wcslen(jobInfo.szOption) != 0) {
_snwprintf_s(szTemp, _countof(szTemp), _TRUNCATE, L" %s", jobInfo.szOption);
wcsncat_s(szArgment, _countof(szArgment), szTemp, _TRUNCATE);
}

// TTSSHが有効の場合は、自動ログインのためのコマンドラインを付加する。
if (jobInfo.dwMode == MODE_AUTOLOGIN) {
if (jobInfo.bTtssh == TRUE) {
// SSHを使わない場合、/nossh オプションを付けておく。
awcscat(&szArgment, L" /nossh");
}
else {
// TTSSHが有効の場合は、自動ログインのためのコマンドラインを付加する。
wchar_t passwd[MAX_PATH], keyfile[MAX_PATH];

wcsncpy_s(szTemp, _countof(szTemp), szArgment, _TRUNCATE);
wchar_t *szPasswordW = ToWcharA(jobInfo.szPassword);
dquote_string(szPasswordW, passwd, _countof(passwd));
free(szPasswordW);
dquote_string(jobInfo.PrivateKeyFile, keyfile, _countof(keyfile));

wchar_t *options;
if (jobInfo.bChallenge) { // keyboard-interactive
_snwprintf_s(szArgment, _countof(szArgment), _TRUNCATE,
aswprintf(&options,
L"%s:22 /ssh /auth=challenge /user=%s /passwd=%s %s",
jobInfo.szHostName,
jobInfo.szUsername,
passwd,
szTemp
szArgment
);

} else if (jobInfo.bPageant) { // Pageant
_snwprintf_s(szArgment, _countof(szArgment), _TRUNCATE,
aswprintf(&options,
L"%s:22 /ssh /auth=pageant /user=%s %s",
jobInfo.szHostName,
jobInfo.szUsername,
szTemp
szArgment
);

}
else if (jobInfo.PrivateKeyFile[0] == L'\0') { // password authentication
_snwprintf_s(szArgment, _countof(szArgment), _TRUNCATE,
aswprintf(&options,
L"%s:22 /ssh /auth=password /user=%s /passwd=%s %s",
jobInfo.szHostName,
jobInfo.szUsername,
passwd,
szTemp
szArgment
);

} else { // publickey
_snwprintf_s(szArgment, _countof(szArgment), _TRUNCATE,
aswprintf(&options,
L"%s:22 /ssh /auth=publickey /user=%s /passwd=%s /keyfile=%s %s",
jobInfo.szHostName,
jobInfo.szUsername,
passwd,
keyfile,
szTemp
szArgment
);

}

} else {
// SSHを使わない場合、/nossh オプションを付けておく。
wcsncpy_s(szArgment, _countof(szArgment), L" /nossh", _TRUNCATE);
free(szArgment);
szArgment = options;
}
break;
case MODE_MACRO:
aswprintf(&szTemp, L" /M=\"%s\"", jobInfo.szMacroFile);
awcscat(&szArgment, szTemp);
free(szTemp);
break;
case MODE_DIRECT:
break;
default:
assert(FALSE);
break;
}

if (wcslen(jobInfo.szOption) != 0) {
aswprintf(&szTemp, L" %s", jobInfo.szOption);
awcscat(&szArgment, szTemp);
free(szTemp);
}

// フルパス化する
wchar_t *exe_fullpath = GetFullPath(jobInfo.szTeraTerm);
wcscpy_s(jobInfo.szTeraTerm, exe_fullpath);
free(exe_fullpath);

// 実行するプログラムのカレントパス
// プログラムのあるフォルダ
wcscpy(szDirectory, jobInfo.szTeraTerm);
if ((::GetFileAttributesW(jobInfo.szTeraTerm) & FILE_ATTRIBUTE_DIRECTORY) == 0)
if ((pt = wcsrchr(szDirectory, '\\')) != NULL)
if ((::GetFileAttributesW(jobInfo.szTeraTerm) & FILE_ATTRIBUTE_DIRECTORY) == 0) {
wchar_t *pt = wcsrchr(szDirectory, '\\');
if (pt != NULL)
*pt = '\0';
}

SHELLEXECUTEINFOW ExecInfo;
memset((void *) &ExecInfo, 0, sizeof(ExecInfo));
Expand All @@ -1233,9 +1244,14 @@ BOOL ConnectHost(HWND hWnd, UINT idItem, const wchar_t *szJobName)
UTIL_get_lang_msgW("MSG_ERROR_LAUNCH", uimsg, _countof(uimsg),
L"Launching the application was failure.\n", UILanguageFileW);
ErrorMessage(hWnd, dwErr, uimsg);
::DeleteFileW(szTempPath);
if (MacroFileCreated) {
::DeleteFileW(szMacroFile);
}
}

free(szArgment);
szArgment = NULL;

if (wcslen(jobInfo.szLog) != 0) {
Sleep(500);
HWND hLog = ::FindWindowW(NULL, L"Tera Term: Log");
Expand Down Expand Up @@ -1500,6 +1516,7 @@ BOOL RegLoadLoginHostInformation(const wchar_t *szName, JobInfo *job_Info)
char szEncodePassword[MAX_PATH];
DWORD dwSize = MAX_PATH;
JobInfo jobInfo;
DWORD dword_tmp;

memset(&jobInfo, 0, sizeof(JobInfo));

Expand All @@ -1510,7 +1527,8 @@ BOOL RegLoadLoginHostInformation(const wchar_t *szName, JobInfo *job_Info)
wcscpy(jobInfo.szName, szName);

RegGetStr(hKey, KEY_HOSTNAME, jobInfo.szHostName, MAX_PATH);
RegGetDword(hKey, KEY_MODE, &(jobInfo.dwMode));
RegGetDword(hKey, KEY_MODE, &dword_tmp);
jobInfo.dwMode = (JobMode)dword_tmp;

RegGetDword(hKey, KEY_USERFLAG, (DWORD *) &(jobInfo.bUsername));
RegGetStr(hKey, KEY_USERNAME, jobInfo.szUsername, MAX_PATH);
Expand Down Expand Up @@ -1936,6 +1954,10 @@ BOOL ManageWMCommand_Config(HWND hWnd, WPARAM wParam)
return TRUE;
case BUTTON_ETC:
::GetDlgItemTextW(hWnd, EDIT_ENTRY, g_JobInfo.szName, MAX_PATH);

// TODO
// 実行ファイル名に L"ttermpro.exe" か含まれていると ttsshチェックを入れるしょり
// 必要?
g_JobInfo.bTtssh = ::IsDlgButtonChecked(hWnd, CHECK_TTSSH);
if (TTDialogBox(g_hI, MAKEINTRESOURCE(DIALOG_ETC), hWnd, DlgCallBack_Etc) == TRUE) {
::CheckDlgButton(hWnd, CHECK_TTSSH, 0);
Expand Down
12 changes: 7 additions & 5 deletions ttpmenu/ttpmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@
#define MODE_SMALLICON 0x0000
#define MODE_LARGEICON 0x0001

#define MODE_AUTOLOGIN 0x0000
#define MODE_MACRO 0x0001
#define MODE_DIRECT 0x0002

// レジストリの値名(一般設定)
#define KEY_ICONMODE L"IconMode"
#define KEY_LEFTBUTTONPOPUP L"LeftButtonPopup"
Expand Down Expand Up @@ -83,12 +79,18 @@
#define STR_HOTKEY L"showing list hotkey(Ctl+Alt+M)"
#define STR_NOENTRY L"(none)"

typedef enum {
MODE_AUTOLOGIN = 0x0000, // 自動でログイン,sshではないときマクロを使用する
MODE_MACRO = 0x0001, // 指定マクロを起動する
MODE_DIRECT = 0x0002,
} JobMode;

// 設定情報構造体
struct JobInfo {
wchar_t szName[MAX_PATH]; // ジョブ名
BOOL bStartup; // 起動時にジョブを実行するかどうかのフラグ
BOOL bTtssh; // ttsshを使用するかどうかのフラグ
DWORD dwMode; // ジョブの種類
JobMode dwMode; // ジョブの種類

// 自動ログイン用設定
wchar_t szHostName[MAX_PATH]; // ホスト名
Expand Down
26 changes: 13 additions & 13 deletions ttpmenu/ttpmenu.rc
Original file line number Diff line number Diff line change
Expand Up @@ -102,26 +102,26 @@ BEGIN
GROUPBOX "Configuration",GRP_CONFIG,157,1,135,249
CTEXT "Name",LBL_ENTRY,164,16,32,12,SS_CENTERIMAGE | SS_SUNKEN
EDITTEXT EDIT_ENTRY,202,16,83,12,ES_AUTOHSCROLL
PUSHBUTTON "details",BUTTON_ETC,168,181,44,16
CONTROL "autologin",RADIO_LOGIN,"Button",BS_AUTORADIOBUTTON | BS_LEFT | BS_VCENTER | WS_GROUP,168,52,108,16
CONTROL "specified macro file",RADIO_MACRO,"Button",BS_AUTORADIOBUTTON | BS_LEFT | BS_VCENTER,168,178,114,12
CONTROL "launch only",RADIO_DIRECT,"Button",BS_AUTORADIOBUTTON | BS_LEFT | BS_VCENTER,168,209,108,12
CTEXT "Host Name",LBL_HOST,176,68,40,12,SS_CENTERIMAGE | SS_SUNKEN | NOT WS_GROUP
EDITTEXT EDIT_HOST,220,68,56,12,ES_AUTOHSCROLL
CONTROL "User Name",CHECK_USER,"Button",BS_AUTOCHECKBOX | BS_CENTER | BS_VCENTER | BS_PUSHLIKE | WS_TABSTOP,176,84,40,12
EDITTEXT EDIT_USER,220,84,56,12,ES_AUTOHSCROLL
CONTROL "Password",CHECK_PASSWORD,"Button",BS_AUTOCHECKBOX | BS_CENTER | BS_VCENTER | BS_PUSHLIKE | WS_TABSTOP,176,100,40,12
EDITTEXT EDIT_PASSWORD,220,100,56,12,ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "specified macro file",RADIO_MACRO,"Button",BS_AUTORADIOBUTTON | BS_LEFT | BS_VCENTER,168,118,114,12
EDITTEXT EDIT_MACRO,176,130,84,12,ES_AUTOHSCROLL
PUSHBUTTON "....",BUTTON_MACRO,264,130,12,12
CONTROL "launch only",RADIO_DIRECT,"Button",BS_AUTORADIOBUTTON | BS_LEFT | BS_VCENTER,168,148,108,12
CONTROL "use SSH",CHECK_TTSSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,220,190,65,8
GROUPBOX "Launch Pattern",GRP_LAUNCH,164,40,121,127
CONTROL "kick at starting",CHECK_STARTUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,220,177,64,8
EDITTEXT IDC_KEYFILE_PATH,211,204,58,14,ES_AUTOHSCROLL | WS_DISABLED
LTEXT "Keyfile",IDC_KEYFILE_LABEL,169,207,37,8
PUSHBUTTON "...",IDC_KEYFILE_BUTTON,273,204,12,14,WS_DISABLED
CONTROL "use Challenge",IDC_CHALLENGE_CHECK,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,170,222,115,10
CONTROL "use Pageant",IDC_PAGEANT_CHECK,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,170,236,115,10
CONTROL "use SSH",CHECK_TTSSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,176,116,65,8
LTEXT "Keyfile",IDC_KEYFILE_LABEL,176,129,37,8
EDITTEXT IDC_KEYFILE_PATH,176,139,84,14,ES_AUTOHSCROLL | WS_DISABLED
PUSHBUTTON "...",IDC_KEYFILE_BUTTON,264,138,12,14,WS_DISABLED
EDITTEXT EDIT_MACRO,176,194,84,12,ES_AUTOHSCROLL
PUSHBUTTON "....",BUTTON_MACRO,264,194,12,12
PUSHBUTTON "details",BUTTON_ETC,165,229,44,16
CONTROL "kick at starting",CHECK_STARTUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,220,235,64,8
CONTROL "use Challenge",IDC_CHALLENGE_CHECK,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,177,156,101,10
CONTROL "use Pageant",IDC_PAGEANT_CHECK,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,177,168,103,10
GROUPBOX "Launch Pattern",GRP_LAUNCH,164,40,121,186
END

DIALOG_ETC DIALOGEX 0, 0, 214, 177
Expand Down

0 comments on commit d2a52cc

Please sign in to comment.