| 28 |
*/ |
*/ |
| 29 |
|
|
| 30 |
/* TTCMN.DLL, main */ |
/* TTCMN.DLL, main */ |
|
#include <direct.h> |
|
| 31 |
#include <string.h> |
#include <string.h> |
| 32 |
#include <stdio.h> |
#include <stdio.h> |
| 33 |
#include <windows.h> |
#include <windows.h> |
| 34 |
#include <setupapi.h> |
#include <setupapi.h> |
| 35 |
#include <htmlhelp.h> |
#include <htmlhelp.h> |
| 36 |
#include <assert.h> |
#include <assert.h> |
| 37 |
|
#define _CRTDBG_MAP_ALLOC |
| 38 |
|
#include <stdlib.h> |
| 39 |
#include <crtdbg.h> |
#include <crtdbg.h> |
|
#include <time.h> |
|
| 40 |
|
|
| 41 |
#define DllExport __declspec(dllexport) |
#define DllExport __declspec(dllexport) |
| 42 |
#include "language.h" |
#include "language.h" |
| 45 |
#include "teraterm.h" |
#include "teraterm.h" |
| 46 |
#include "tttypes.h" |
#include "tttypes.h" |
| 47 |
#include "ttlib.h" |
#include "ttlib.h" |
|
#include "tt_res.h" |
|
| 48 |
#include "codeconv.h" |
#include "codeconv.h" |
| 49 |
#include "compat_win.h" |
#include "compat_win.h" |
| 50 |
#include "win32helper.h" |
#include "win32helper.h" |
|
#include "asprintf.h" |
|
|
#include "fileread.h" |
|
| 51 |
#include "../teraterm/unicode.h" |
#include "../teraterm/unicode.h" |
| 52 |
|
|
| 53 |
#include "ttcmn_dup.h" |
#include "ttcmn_shared_memory.h" |
|
|
|
|
#define DllExport __declspec(dllexport) |
|
| 54 |
#include "ttcommon.h" |
#include "ttcommon.h" |
| 55 |
|
#include "ttcmn_i.h" |
|
/* shared memory */ |
|
|
typedef struct { |
|
|
size_t size_tmap; /* sizeof TMap */ |
|
|
size_t size_tttset; /* sizeof TTTSet */ |
|
|
// Window list |
|
|
int NWin; |
|
|
HWND WinList[MAXNWIN]; |
|
|
/* COM port use flag |
|
|
* bit 8 7 6 5 4 3 2 1 |
|
|
* char[0] : COM 8 7 6 5 4 3 2 1 |
|
|
* char[1] : COM16 15 14 13 12 11 10 9 ... |
|
|
*/ |
|
|
unsigned char ComFlag[(MAXCOMPORT-1)/CHAR_BIT+1]; |
|
|
/* Previous window rect (Tera Term 4.78 or later) */ |
|
|
WINDOWPLACEMENT WinPrevRect[MAXNWIN]; |
|
|
BOOL WinUndoFlag; |
|
|
int WinUndoStyle; |
|
|
// Duplicate Teraterm data |
|
|
HANDLE DuplicateDataHandle; |
|
|
DWORD DuplicateDataSizeLow; |
|
|
} TMap; |
|
|
typedef TMap *PMap; |
|
|
|
|
|
// TMap を格納するファイルマッピングオブジェクト(共有メモリ)の名前 |
|
|
// TMap(とそのメンバ)の更新時は旧バージョンとの同時起動の為に変える必要があるが |
|
|
// 連番からバージョン番号を使うように変更した為、通常は手動で変更する必要は無い |
|
|
#define TT_FILEMAPNAME "ttset_memfilemap_" TT_VERSION_STR("_") |
|
|
|
|
|
/* first instance flag */ |
|
|
static BOOL FirstInstance = TRUE; |
|
|
|
|
|
static HINSTANCE hInst; |
|
| 56 |
|
|
| 57 |
static PMap pm; |
static PMap pm; |
| 58 |
|
|
|
static HANDLE HMap = NULL; |
|
| 59 |
#define VTCLASSNAME "VTWin32" |
#define VTCLASSNAME "VTWin32" |
| 60 |
#define TEKCLASSNAME "TEKWin32" |
#define TEKCLASSNAME "TEKWin32" |
| 61 |
|
|
| 65 |
WIN_SIDEBYSIDE, |
WIN_SIDEBYSIDE, |
| 66 |
}; |
}; |
| 67 |
|
|
|
static const char DupDataName[] = "dupdata"; |
|
|
|
|
|
void WINAPI CopyShmemToTTSet(PTTSet ts) |
|
|
{ |
|
|
DWORD size = pm->DuplicateDataSizeLow; |
|
|
HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, DupDataName); |
|
|
void *ptr = (void *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); |
|
|
TTCMNUnserialize(ptr, (size_t)size, ts); |
|
|
UnmapViewOfFile(ptr); |
|
|
CloseHandle(handle); |
|
|
pm->DuplicateDataSizeLow = 0; |
|
|
} |
|
|
|
|
|
void WINAPI CopyTTSetToShmem(PTTSet ts) |
|
|
{ |
|
|
size_t size; |
|
|
void *ptr = TTCMNSerialize(ts, &size); |
|
|
if (ptr != NULL) { |
|
|
HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)size, DupDataName); |
|
|
void *dest = (void *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS,0,0,0); |
|
|
memcpy(dest, ptr, size); |
|
|
UnmapViewOfFile(dest); |
|
|
//CloseHandle(handle); do not close, 使用しない状態になるとなくなってしまう |
|
|
|
|
|
if (pm->DuplicateDataHandle != NULL) { |
|
|
// 1回前の情報を削除する |
|
|
CloseHandle(pm->DuplicateDataHandle); |
|
|
} |
|
|
pm->DuplicateDataHandle = handle; |
|
|
pm->DuplicateDataSizeLow = (DWORD)size; |
|
|
free(ptr); |
|
|
} |
|
|
} |
|
|
|
|
|
static void CopyFiles(const wchar_t *file_list[], const wchar_t *src_dir, const wchar_t *dest_dir) |
|
|
{ |
|
|
for (;;) { |
|
|
wchar_t *dest; |
|
|
size_t len; |
|
|
const wchar_t *filename = *file_list; |
|
|
file_list++; |
|
|
if (filename == NULL) { |
|
|
break; |
|
|
} |
|
|
|
|
|
dest = NULL; |
|
|
awcscats(&dest, dest_dir, L"\\", filename, NULL); |
|
|
|
|
|
len = wcslen(dest); |
|
|
if (dest[len - 1] == '\\') { |
|
|
// フォルダ作成 |
|
|
CreateDirectoryW(dest, NULL); |
|
|
} |
|
|
else { |
|
|
wchar_t *src = NULL; |
|
|
awcscats(&src, src_dir, L"\\", filename, NULL); |
|
|
CopyFileW(src, dest, TRUE); // TRUE = do not copy if exists |
|
|
free(src); |
|
|
} |
|
|
free(dest); |
|
|
} |
|
|
} |
|
|
|
|
|
static void ConvertIniFiles(const wchar_t *filelist[], const wchar_t *dir, const wchar_t *date_str) |
|
|
{ |
|
|
while(1) { |
|
|
wchar_t *fname; |
|
|
if (*filelist == NULL) { |
|
|
break; |
|
|
} |
|
|
|
|
|
fname = NULL; |
|
|
awcscats(&fname, dir, L"\\", *filelist, NULL); |
|
|
ConvertIniFileCharCode(fname, date_str); |
|
|
free(fname); |
|
|
filelist++; |
|
|
} |
|
|
} |
|
|
|
|
|
BOOL WINAPI StartTeraTerm(PTTSet ts) |
|
|
{ |
|
|
if (FirstInstance) { |
|
|
// init window list |
|
|
pm->NWin = 0; |
|
|
} |
|
|
else { |
|
|
/* only the first instance uses saved position */ |
|
|
ts->VTPos.x = CW_USEDEFAULT; |
|
|
ts->VTPos.y = CW_USEDEFAULT; |
|
|
ts->TEKPos.x = CW_USEDEFAULT; |
|
|
ts->TEKPos.y = CW_USEDEFAULT; |
|
|
} |
|
|
|
|
|
// if (FirstInstance) { の部分から移動 (2008.3.13 maya) |
|
|
// 起動時には、共有メモリの HomeDir と SetupFName は空になる |
|
|
/* Get home directory (ttermpro.exeのフォルダ) */ |
|
|
ts->ExeDirW = GetExeDirW(hInst); |
|
|
|
|
|
// LogDir |
|
|
ts->LogDirW = GetLogDirW(hInst); |
|
|
|
|
|
// HomeDir |
|
|
ts->HomeDirW = GetHomeDirW(hInst); |
|
|
WideCharToACP_t(ts->HomeDirW, ts->HomeDir, _countof(ts->HomeDir)); |
|
|
SetCurrentDirectoryW(ts->HomeDirW); // TODO 必要?? |
|
|
|
|
|
// TERATERM.INI のフルパス |
|
|
ts->SetupFNameW = NULL; |
|
|
awcscats(&ts->SetupFNameW, ts->HomeDirW, L"\\TERATERM.INI", NULL); |
|
|
WideCharToACP_t(ts->SetupFNameW, ts->SetupFName, _countof(ts->SetupFName)); |
|
|
|
|
|
// KEYBOARD.CNF のフルパス |
|
|
ts->KeyCnfFNW = NULL; |
|
|
awcscats(&ts->KeyCnfFNW, ts->HomeDirW, L"\\KEYBOARD.CNF", NULL); |
|
|
WideCharToACP_t(ts->KeyCnfFNW, ts->KeyCnfFN, _countof(ts->KeyCnfFN)); |
|
|
|
|
|
// ポータブルモードではなく、 |
|
|
// 個人設定ファイルのあるフォルダ HomeDirW に TERATERM.INI が存在しないとき |
|
|
if (!IsPortableMode() && |
|
|
(GetFileAttributesW(ts->SetupFNameW) == INVALID_FILE_ATTRIBUTES)) { |
|
|
// 設定ファイルを個人フォルダへコピーする |
|
|
static const wchar_t *filelist[] = { |
|
|
L"TERATERM.INI", |
|
|
L"KEYBOARD.CNF", |
|
|
L"cygterm.cfg", |
|
|
L"ssh_known_hosts", |
|
|
L"theme\\", |
|
|
L"theme\\Advanced.sample", |
|
|
L"theme\\ImageFile.INI", |
|
|
L"theme\\scale\\", |
|
|
L"theme\\scale\\23.jpg", |
|
|
L"theme\\scale\\43.jpg", |
|
|
L"theme\\Scale.INI", |
|
|
L"theme\\tile\\", |
|
|
L"theme\\tile\\03.jpg", |
|
|
L"theme\\tile\\44.jpg", |
|
|
L"theme\\Tile.INI", |
|
|
NULL, |
|
|
}; |
|
|
CopyFiles(filelist, ts->ExeDirW, ts->HomeDirW); |
|
|
} |
|
|
|
|
|
// iniファイルの文字コードを変換する |
|
|
{ |
|
|
static const wchar_t *filelist[] = { |
|
|
L"TERATERM.INI", |
|
|
L"KEYBOARD.CNF", |
|
|
NULL, |
|
|
}; |
|
|
|
|
|
// backup ファイルにつける日付文字列 |
|
|
wchar_t *date_str = MakeISO8601Str(0); |
|
|
awcscat(&date_str, L"_"); |
|
|
|
|
|
// iniファイルを変換する |
|
|
ConvertIniFiles(filelist, ts->HomeDirW, date_str); |
|
|
|
|
|
free(date_str); |
|
|
} |
|
|
|
|
|
if (FirstInstance) { |
|
|
FirstInstance = FALSE; |
|
|
return TRUE; |
|
|
} |
|
|
else { |
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
ts->PluginVTIconInstance = NULL; |
|
|
ts->PluginVTIconID = 0; |
|
|
} |
|
|
|
|
|
// 設定ファイルをディスクに保存し、Tera Term本体を再起動する。 |
|
|
// (2012.4.30 yutaka) |
|
|
// 使っていない? |
|
|
void WINAPI RestartTeraTerm(HWND hwnd, PTTSet ts) |
|
|
{ |
|
|
wchar_t *path; |
|
|
int ret; |
|
|
|
|
|
static const TTMessageBoxInfoW info = { |
|
|
"Tera Term", |
|
|
NULL, L"Tera Term: Configuration Warning", |
|
|
"MSG_TT_TAKE_EFFECT", |
|
|
L"This option takes effect the next time a session is started.\n" |
|
|
L"Are you sure that you want to relaunch Tera Term?", |
|
|
MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2 |
|
|
}; |
|
|
ret = TTMessageBoxA(hwnd, &info, ts->UILanguageFile); |
|
|
if (ret != IDYES) |
|
|
return; |
|
|
|
|
|
SendMessage(hwnd, WM_COMMAND, ID_SETUP_SAVE, 0); |
|
|
// ID_FILE_EXIT メッセージではアプリが落ちることがあるため、WM_QUIT をポストする。 |
|
|
//PostMessage(hwnd, WM_COMMAND, ID_FILE_EXIT, 0); |
|
|
PostQuitMessage(0); |
|
|
|
|
|
// 自プロセスの再起動。 |
|
|
if (hGetModuleFileNameW(NULL, &path) == 0) { |
|
|
TTWinExec(path); |
|
|
free(path); |
|
|
} |
|
|
} |
|
|
|
|
| 68 |
void WINAPI SetCOMFlag(int Com) |
void WINAPI SetCOMFlag(int Com) |
| 69 |
{ |
{ |
| 70 |
pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT); |
pm->ComFlag[(Com-1)/CHAR_BIT] |= 1 << ((Com-1)%CHAR_BIT); |
| 131 |
} |
} |
| 132 |
} |
} |
| 133 |
|
|
| 134 |
char GetWindowTypeChar(HWND Hw, HWND HWin) |
static char GetWindowTypeChar(HWND Hw, HWND HWin) |
| 135 |
{ |
{ |
| 136 |
#if 0 |
#if 0 |
| 137 |
if (HWin == Hw) |
if (HWin == Hw) |
| 1066 |
code_page = 936; |
code_page = 936; |
| 1067 |
break; |
break; |
| 1068 |
} |
} |
| 1069 |
|
} else { |
| 1070 |
|
assert(FALSE); |
| 1071 |
|
code_page = 0; |
| 1072 |
} |
} |
| 1073 |
/* code_page に変換して出力 */ |
/* code_page に変換して出力 */ |
| 1074 |
mb_len = sizeof(mb_char); |
mb_len = sizeof(mb_char); |
| 1207 |
return i; |
return i; |
| 1208 |
} |
} |
| 1209 |
|
|
| 1210 |
/* |
/** |
| 1211 |
* @return エラーが有る場合 FALSE |
* 共有メモリへのポインタをセット |
|
* @param[in] BOOL first_instance |
|
| 1212 |
*/ |
*/ |
| 1213 |
static BOOL OpenSharedMemory(BOOL *first_instance_) |
DllExport void WINAPI SetPMPtr(PMap pm_) |
| 1214 |
{ |
{ |
| 1215 |
int i; |
pm = pm_; |
|
HMap = NULL; |
|
|
pm = NULL; |
|
|
for (i = 0; i < 100; i++) { |
|
|
char tmp[32]; |
|
|
HANDLE hMap; |
|
|
BOOL first_instance; |
|
|
TMap *map; |
|
|
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, i == 0 ? "%s" : "%s_%d", TT_FILEMAPNAME, i); |
|
|
hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, |
|
|
0, sizeof(TMap), tmp); |
|
|
if (hMap == NULL) { |
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
first_instance = (GetLastError() != ERROR_ALREADY_EXISTS); |
|
|
|
|
|
map = (TMap *)MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0); |
|
|
if (map == NULL) { |
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
if (first_instance || |
|
|
(map->size_tmap == sizeof(TMap) && |
|
|
map->size_tttset == sizeof(TTTSet))) |
|
|
{ |
|
|
map->size_tmap = sizeof(TMap); |
|
|
map->size_tttset = sizeof(TTTSet); |
|
|
HMap = hMap; |
|
|
pm = map; |
|
|
*first_instance_ = first_instance; |
|
|
return TRUE; |
|
|
} |
|
|
|
|
|
// next try |
|
|
UnmapViewOfFile(map); |
|
|
CloseHandle(hMap); |
|
|
} |
|
|
return FALSE; |
|
| 1216 |
} |
} |
| 1217 |
|
|
| 1218 |
BOOL WINAPI DllMain(HANDLE hInstance, |
BOOL WINAPI DllMain(HANDLE hInstance, |
| 1231 |
#ifdef _DEBUG |
#ifdef _DEBUG |
| 1232 |
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); |
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); |
| 1233 |
#endif |
#endif |
|
hInst = hInstance; |
|
|
if (OpenSharedMemory(&FirstInstance) == FALSE) { |
|
|
// dllロード失敗、teratermが起動しない |
|
|
return FALSE; |
|
|
} |
|
| 1234 |
WinCompatInit(); |
WinCompatInit(); |
| 1235 |
break; |
break; |
| 1236 |
case DLL_PROCESS_DETACH: |
case DLL_PROCESS_DETACH: |
| 1237 |
/* do process cleanup */ |
/* do process cleanup */ |
| 1238 |
UnmapViewOfFile(pm); |
// TODO ttermpro.exeで行う |
| 1239 |
CloseHandle(HMap); |
// CloseSharedMemory(pm, HMap); |
| 1240 |
break; |
break; |
| 1241 |
} |
} |
| 1242 |
return TRUE; |
return TRUE; |