[ttssh2-commit] [9429] plugin iniファイルの読み書きをUnicode化

Zurück zum Archiv-Index
scmno****@osdn***** scmno****@osdn*****
2021年 9月 20日 (月) 00:13:52 JST


Revision: 9429
          https://osdn.net/projects/ttssh2/scm/svn/commits/9429
Author:   zmatsuo
Date:     2021-09-20 00:13:51 +0900 (Mon, 20 Sep 2021)
Log Message:
-----------
plugin iniファイルの読み書きをUnicode化

- teraterm/ttsetup.h 引数のファイル名をUnicode化
  - PReadIniFile()
  - PWriteIniFile()
- TTProxy/YCL/include/YCL/wstring.h 追加
  - Unicode版 string.h
  - ファイル名の保持はできる
    - 他の関数はテストしていない

Modified Paths:
--------------
    trunk/TTProxy/CMakeLists.txt
    trunk/TTProxy/TTProxy.h
    trunk/TTProxy/YCL/include/YCL/Dialog.h
    trunk/TTProxy/YCL/include/YCL/IniFile.h
    trunk/TTProxy/YCL/include/YCL/String.h
    trunk/TTXKanjiMenu/CMakeLists.txt
    trunk/TTXKanjiMenu/ttxkanjimenu.c
    trunk/TTXSamples/TTXAdditionalTitle/CMakeLists.txt
    trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.c
    trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v16.vcxproj
    trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v8.vcproj
    trunk/TTXSamples/TTXCopyIniFile/TTXCopyIniFile.c
    trunk/TTXSamples/TTXFixedWinSize/TTXFixedWinSize.c
    trunk/TTXSamples/TTXRecurringCommand/TTXRecurringCommand.c
    trunk/TTXSamples/TTXResizeMenu/TTXResizeMenu.c
    trunk/TTXSamples/TTXViewMode/TTXViewMode.c
    trunk/TTXSamples/TTXttyrec/CMakeLists.txt
    trunk/TTXSamples/TTXttyrec/TTXttyplay.c
    trunk/TTXSamples/TTXttyrec/TTXttyplay.v16.vcxproj
    trunk/TTXSamples/TTXttyrec/TTXttyplay.v8.vcproj
    trunk/TTXSamples/TTXttyrec/TTXttyrec.c
    trunk/TTXSamples/TTXttyrec/TTXttyrec.v16.vcxproj
    trunk/TTXSamples/TTXttyrec/TTXttyrec.v8.vcproj
    trunk/teraterm/teraterm/ttsetup.h
    trunk/teraterm/teraterm/vtwin.cpp
    trunk/teraterm/ttpset/ttset.c
    trunk/ttssh2/ttxssh/ttxssh.c
    trunk/ttssh2/ttxssh/ttxssh.h

Added Paths:
-----------
    trunk/TTProxy/YCL/include/YCL/wstring.h

-------------- next part --------------
Modified: trunk/TTProxy/CMakeLists.txt
===================================================================
--- trunk/TTProxy/CMakeLists.txt	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTProxy/CMakeLists.txt	2021-09-19 15:13:51 UTC (rev 9429)
@@ -89,6 +89,7 @@
   YCL/include/YCL/ValueCtrl.h
   YCL/include/YCL/Vector.h
   YCL/include/YCL/Window.h
+  YCL/include/YCL/wstring.h
   )
 
 source_group(

Modified: trunk/TTProxy/TTProxy.h
===================================================================
--- trunk/TTProxy/TTProxy.h	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTProxy/TTProxy.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -1,6 +1,8 @@
 #ifndef _YEBISOCKS_TTX_H_
 #define _YEBISOCKS_TTX_H_
 
+#include "codeconv.h"
+
 #include <YCL/DynamicLinkLibrary.h>
 using namespace yebisuya;
 
@@ -58,12 +60,12 @@
 		}
 		::PostMessage(getInstance().cv->HWin, WM_COMMAND, ID_ASYNCMESSAGEBOX, 0);
 	}
-	static void read_options(const char* filename) {
+	static void read_options(const wchar_t* filename) {
 		IniFile inifile(filename, "TTProxy");
 		ProxyWSockHook::load(inifile);
 		getInstance().initialized = true;
 	}
-	static void write_options(const char* filename) {
+	static void write_options(const wchar_t* filename) {
 		IniFile inifile(filename, "TTProxy");
 		ProxyWSockHook::save(inifile);
 	}
@@ -88,11 +90,11 @@
 		return buffer.toString();
 	}
 
-	static void PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts) {
+	static void PASCAL TTXReadINIFile(const wchar_t *fileName, PTTSet ts) {
 		getInstance().ORIG_ReadIniFile(fileName, ts);
 		read_options(fileName);
 	}
-	static void PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts) {
+	static void PASCAL TTXWriteINIFile(const wchar_t *fileName, PTTSet ts) {
 		getInstance().ORIG_WriteIniFile(fileName, ts);
 		write_options(fileName);
 	}
@@ -116,7 +118,10 @@
 
 			if ((option[0] == '-' || option[0] == '/')) {
 				if ((option[1] == 'F' || option[1] == 'f') && option[2] == '=') {
-					read_options(get_teraterm_dir_relative_name(option + 3));
+					const char *f = get_teraterm_dir_relative_name(option + 3);
+					wchar_t *fW = ToWcharA(f);
+					read_options(fW);
+					free(fW);
 				}
 			}
 
@@ -211,7 +216,7 @@
 
 	static void PASCAL TTXOpenTCP(TTXSockHooks* hooks) {
 		if (!getInstance().initialized) {
-			read_options(getInstance().ts->SetupFName);
+			read_options(getInstance().ts->SetupFNameW);
 		}
 		(FARPROC&) *hooks->Pconnect = ProxyWSockHook::hook_connect((FARPROC) *hooks->Pconnect);
 		(FARPROC&) *hooks->PWSAAsyncGetHostByName = ProxyWSockHook::hook_WSAAsyncGetHostByName((FARPROC) *hooks->PWSAAsyncGetHostByName);

Modified: trunk/TTProxy/YCL/include/YCL/Dialog.h
===================================================================
--- trunk/TTProxy/YCL/include/YCL/Dialog.h	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTProxy/YCL/include/YCL/Dialog.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -96,10 +96,10 @@
 	}
 
 
-	int open(int resourceId, HWND owner = NULL) {
+	INT_PTR open(int resourceId, HWND owner = NULL) {
 		return open(GetInstanceHandle(), resourceId, owner);
 	}
-	int open(HINSTANCE instance, int resourceId, HWND owner = NULL) {
+	INT_PTR open(HINSTANCE instance, int resourceId, HWND owner = NULL) {
 		YCLVERIFY(prepareOpen(this) == NULL, "Another dialog has been opening yet.");
 #if 0
 		return ::DialogBoxParam(instance, MAKEINTRESOURCE(resourceId), owner, DialogProc, NULL);

Modified: trunk/TTProxy/YCL/include/YCL/IniFile.h
===================================================================
--- trunk/TTProxy/YCL/include/YCL/IniFile.h	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTProxy/YCL/include/YCL/IniFile.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -16,7 +16,10 @@
 #include <YCL/Enumeration.h>
 #include <YCL/Vector.h>
 #include <YCL/Hashtable.h>
+#include <YCL/wstring.h>
 
+#include "inifile_com.h"
+
 namespace yebisuya {
 
 class IniFile {
@@ -41,7 +44,7 @@
 		Vector<String> list;
 		mutable int index;
 	public:
-		EnumKeyNames(const char* filename, const char* section):index(0) {
+		EnumKeyNames(const wchar_t* filename, const char* section):index(0) {
 			Hashtable<String, int> table;
 			int section_len = strlen(section);
 			char* buffer;
@@ -85,7 +88,7 @@
 		char* buffer;
 		mutable char* p;
 	public:
-		EnumValueNames(const char* filename, const char* section) {
+		EnumValueNames(const wchar_t* filename, const char* section) {
 			size_t size = 256;
 			while ((buffer = getValueNames(filename, section, size)) == NULL)
 				size += 256;
@@ -138,28 +141,28 @@
             return ((IniFile*) ini)->deleteValue(name);
         }
     };
-	static char* getSectionNames(const char* filename, size_t size) {
+	static char* getSectionNames(const wchar_t* filename, size_t size) {
 		char* buffer = new char[size];
-		if (::GetPrivateProfileSectionNames(buffer, size, filename) < size - 2)
+		if (::GetPrivateProfileSectionNamesAFileW(buffer, size, filename) < size - 2)
 			return buffer;
 		delete[] buffer;
 		return NULL;
 	}
-	static char* getValueNames(const char* filename, const char* section, size_t size) {
+	static char* getValueNames(const wchar_t* filename, const char* section, size_t size) {
 		static const char null = '\0';
 		char* buffer = new char[size];
-		if (::GetPrivateProfileString(section, NULL, &null, buffer, size, filename) < size - 2)
+		if (GetPrivateProfileStringAFileW(section, NULL, &null, buffer, size, filename) < size - 2)
 			return buffer;
 		delete[] buffer;
 		return NULL;
 	}
-	static String getString(const char* filename, const char* section, const char* name, bool& exists, size_t size) {
+	static String getString(const wchar_t* filename, const char* section, const char* name, bool& exists, size_t size) {
 		char* buffer = (char*) alloca(size);
-		size_t len = ::GetPrivateProfileString(section, name, INVALID(), buffer, size, filename);
+		size_t len = GetPrivateProfileStringAFileW(section, name, INVALID(), buffer, size, filename);
 		if (len < size - 2) {
 			// \x89\xFC\x8Ds\x82\xF0\x8A܂񂾕\xB6\x8E\x9A\x97\xF1\x82\xCDini\x83t\x83@\x83C\x83\x8B\x82\xA9\x82\xE7\x82͎擾\x82ł\xAB\x82Ȃ\xA2\x82̂Ŏ擾\x8E\xB8\x94s\x82\xB5\x82\xBD\x82\xB1\x82Ƃ\xAA\x95\xAA\x82\xA9\x82\xE9
 			if (buffer[0] == '\n') {
-				exists = false; 
+				exists = false;
 				return NULL;
 			}
 			// \x83G\x83X\x83P\x81[\x83v\x95\xB6\x8E\x9A\x82\xF0\x93W\x8AJ
@@ -174,7 +177,7 @@
 		buffer.append(subkeyName);
 		return buffer.toString();
 	}
-	static bool deleteAllSubsection(const char* filename, const char* section, const char* subkey) {
+	static bool deleteAllSubsection(const wchar_t* filename, const char* section, const char* subkey) {
 		String keyname = generateSectionName(section, subkey);
 		int keyname_len = keyname.length();
 
@@ -187,7 +190,7 @@
 		while (*name != '\0') {
 			if (strncmp(name, keyname, keyname_len) == 0) {
 				if (name[keyname_len] == '\0' || name[keyname_len] == '\\') {
-					if (!::WritePrivateProfileString(name, NULL, NULL, filename)) {
+					if (!WritePrivateProfileStringAFileW(name, NULL, NULL, filename)) {
 						succeeded = false;
 						break;
 					}
@@ -200,12 +203,12 @@
 		return succeeded;
 	}
 
-	String filename;
+	WString filename;
 	String section;
 public:
 	IniFile() {
 	}
-	IniFile(String filename, String section):filename(filename), section(section) {
+	IniFile(WString filename, String section):filename(filename), section(section) {
 	}
 	IniFile(const IniFile& parent, const char* subkeyName):filename(parent.filename), section(generateSectionName(parent.section, subkeyName)) {
 	}
@@ -214,7 +217,7 @@
 		return filename != NULL && section != NULL;
 	}
 	long getInteger(const char* name, long defaultValue = 0)const {
-		return filename != NULL && section != NULL ? ::GetPrivateProfileInt(section, name, defaultValue, filename) : defaultValue;
+		return filename != NULL && section != NULL ? ::GetPrivateProfileIntAFileW(section, name, defaultValue, filename) : defaultValue;
 	}
 	String getString(const char* name)const {
 		return getString(name, NULL);
@@ -256,7 +259,7 @@
 				buffer.append('"');
 				value = buffer.toString();
 			}
-			return ::WritePrivateProfileString(section, name, value, filename) != FALSE;
+			return ::WritePrivateProfileStringAFileW(section, name, value, filename) != FALSE;
 		}
 		return false;
 	}
@@ -266,7 +269,7 @@
 
 	bool existsValue(const char* name) {
 		char buffer[3];
-		::GetPrivateProfileString(section, name, INVALID(), buffer, countof(buffer), filename);
+		::GetPrivateProfileStringAFileW(section, name, INVALID(), buffer, countof(buffer), filename);
 		return buffer[0] != '\n';
 	}
 	bool deleteKey(const char* name) {
@@ -274,10 +277,10 @@
 	}
 	bool deleteValue(const char* name) {
 		return filename != NULL && section != NULL && name != NULL
-			&& ::WritePrivateProfileString(section, name, NULL, filename) != FALSE;
+			&& ::WritePrivateProfileStringAFileW(section, name, NULL, filename) != FALSE;
 	}
 
-	bool open(String filename, String section) {
+	bool open(WString filename, String section) {
 		close();
 		this->filename = filename;
 		this->section = section;

Modified: trunk/TTProxy/YCL/include/YCL/String.h
===================================================================
--- trunk/TTProxy/YCL/include/YCL/String.h	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTProxy/YCL/include/YCL/String.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -232,7 +232,7 @@
 	//	chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int indexOf(char chr)const {
+	size_t indexOf(char chr)const {
 		return indexOf(chr, 0);
 	}
 	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B
@@ -241,7 +241,7 @@
 	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int indexOf(char chr, size_t from)const {
+	size_t indexOf(char chr, size_t from)const {
 		if (from >= length())
 			return -1;
 		const char* found = strchr(string + from, chr);
@@ -254,7 +254,7 @@
 	//	str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int indexOf(const char* str)const {
+	size_t indexOf(const char* str)const {
 		return indexOf(str, 0);
 	}
 	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97񂪂ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B
@@ -264,7 +264,7 @@
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
 	// 
-	int indexOf(const char* str, size_t from)const {
+	size_t indexOf(const char* str, size_t from)const {
 		if (from >= length())
 			return -1;
 		const char* found = strstr(string + from, str);
@@ -281,7 +281,7 @@
 	//	chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int lastIndexOf(char chr)const {
+	size_t lastIndexOf(char chr)const {
 		return lastIndexOf(chr, (size_t) -1);
 	}
 	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8Ew\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82‚\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B
@@ -290,7 +290,7 @@
 	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int lastIndexOf(char chr, size_t from)const {
+	size_t lastIndexOf(char chr, size_t from)const {
 		size_t len = length();
 		if (from > len - 1)
 			from = len - 1;
@@ -311,7 +311,7 @@
 	//	str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int lastIndexOf(const char* str)const {
+	size_t lastIndexOf(const char* str)const {
 		return lastIndexOf(str, (size_t) -1);
 	}
 	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97񂪎w\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82‚\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B
@@ -320,7 +320,7 @@
 	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
 	// \x95Ԓl:
 	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
-	int lastIndexOf(const char* str, size_t from)const {
+	size_t lastIndexOf(const char* str, size_t from)const {
 		size_t len = length();
 		size_t str_len = strlen(str);
 		if (from > len - str_len)

Copied: trunk/TTProxy/YCL/include/YCL/wstring.h (from rev 9428, trunk/TTProxy/YCL/include/YCL/String.h)
===================================================================
--- trunk/TTProxy/YCL/include/YCL/wstring.h	                        (rev 0)
+++ trunk/TTProxy/YCL/include/YCL/wstring.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _YCL_WSTRING_H_
+#define _YCL_WSTRING_H_
+
+#pragma once
+
+#include <YCL/common.h>
+
+#include <string.h>
+#include <wchar.h>
+
+namespace yebisuya {
+
+// \x95\xB6\x8E\x9A\x97\xF1\x82̊Ǘ\x9D\x81E\x91\x80\x8D\xEC\x82\xF0\x8Ds\x82\xA4\x83N\x83\x89\x83X\x81B
+class WString {
+private:
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x81B
+	// \x95\xB6\x8E\x9A\x97\xF1\x82̑O\x82ɂ͎Q\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8E\x9D\x82\xBF\x81A
+	// \x91\xE3\x93\xFC\x82\xE2\x94j\x8A\xFC\x82̍ۂɂ͂\xBB\x82\xB1\x82\xF0\x95ύX\x82\xB7\x82\xE9\x81B
+	const wchar_t* string;
+
+	// utilities
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B
+	// \x95\xB6\x8E\x9A\x97\xF1\x82ƎQ\x8FƃJ\x83E\x83\x93\x83^\x82̕\xAA\x82̗̈\xE6\x82\xF0\x8Am\x95ۂ\xB7\x82\xE9\x81B
+	// \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82\xCD0\x82ɂȂ\xC1\x82Ă\xA2\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B
+	// \x95Ԓl:
+	//	\x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97񕔂̃A\x83h\x83\x8C\x83X\x81B
+	static wchar_t* createBuffer(size_t length) {
+		size_t* count = (size_t*) new unsigned char[sizeof (size_t) + sizeof (wchar_t) * (length + 1)];
+		*count = 0;
+		return (wchar_t*) (count + 1);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x8Ai\x94[\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97񕔂̃A\x83h\x83\x8C\x83X\x81B
+	static const wchar_t* create(const wchar_t* source) {
+		return source != NULL ? create(source, wcslen(source)) : NULL;
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x8Ai\x94[\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B
+	// \x95Ԓl:
+	//	\x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97񕔂̃A\x83h\x83\x8C\x83X\x81B
+	static const wchar_t* create(const wchar_t* source, size_t length) {
+		if (source != NULL) {
+			wchar_t* buffer = createBuffer(length);
+			wmemcpy(buffer, source, length);
+			buffer[length] = '\0';
+			return buffer;
+		}
+		return NULL;
+	}
+	// \x93\xF1\x82‚̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB5\x8Ai\x94[\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82\xF0\x8D쐬\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x91O)\x81B
+	//	str2 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x8C\xE3)\x81B
+	// \x95Ԓl:
+	//	\x8D쐬\x82\xB5\x82\xBD\x83o\x83b\x83t\x83@\x82̕\xB6\x8E\x9A\x97񕔂̃A\x83h\x83\x8C\x83X\x81B
+	static const wchar_t* concat(const wchar_t* str1, const wchar_t* str2) {
+		size_t len1 = wcslen(str1);
+		size_t len2 = wcslen(str2);
+		wchar_t* buffer = createBuffer(len1 + len2);
+		wmemcpy(buffer, str1, len1);
+		wmemcpy(buffer + len1, str2, len2);
+		buffer[len1 + len2] = '\0';
+		return buffer;
+	}
+	// private methods
+	// \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8C\xB8\x82炵\x81A0\x82ɂȂ\xC1\x82\xBD\x82\xE7\x83o\x83b\x83t\x83@\x82\xF0\x94j\x8A\xFC\x82\xB7\x82\xE9\x81B
+	void release() {
+		if (string != NULL) {
+			size_t* count = (size_t*) string - 1;
+			if (--*count == 0)
+				delete[] (unsigned char*) count;
+		}
+	}
+	// \x8EQ\x8FƃJ\x83E\x83\x93\x83^\x82𑝂₷\x81B
+	void add() {
+		if (string != NULL) {
+			size_t* count = (size_t*) string - 1;
+			++*count;
+		}
+	}
+	// \x95ʂ̃o\x83b\x83t\x83@\x82ƒu\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
+	// \x8C\xB3\x82̃o\x83b\x83t\x83@\x82̎Q\x8FƃJ\x83E\x83\x93\x83^\x82\xF0\x8C\xB8\x82炵\x81A
+	// \x90V\x82\xB5\x82\xA2\x83o\x83b\x83t\x83@\x82̎Q\x8FƃJ\x83E\x83\x93\x83^\x82𑝂₷\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x92u\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x90V\x82\xB5\x82\xA2\x83o\x83b\x83t\x83@\x81B
+	void set(const wchar_t* source) {
+		if (string != source) {
+			release();
+			string = source;
+			add();
+		}
+	}
+public:
+	// constructor
+	// \x83f\x83t\x83H\x83\x8B\x83g\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// NULL\x82\xAA\x93\xFC\x82\xC1\x82Ă\xA2\x82\xE9\x82̂ŁA\x82\xB1\x82̂܂܂ŕ\xB6\x8E\x9A\x97񑀍삷\x82\xE9\x82ƃA\x83N\x83Z\x83X\x88ᔽ\x82ɂȂ\xE9\x82̂Œ\x8D\x88ӁB
+	WString():string(NULL) {
+	}
+	// \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x8Ew\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	WString(const wchar_t* source):string(NULL) {
+		set(create(source));
+	}
+	// \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x82𒷂\xB3\x95t\x82\xAB\x82Ŏw\x92肷\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	//	length \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x81B
+	WString(const wchar_t* source, size_t length):string(NULL) {
+		set(create(source, length));
+	}
+	// \x83R\x83s\x81[\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x8C\xB3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	WString(const WString& source):string(NULL) {
+		set(source.string);
+	}
+	// \x93\xF1\x82‚̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x91O\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x8C\xE3\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B
+	WString(const wchar_t* str1, const wchar_t* str2):string(NULL) {
+		set(concat(str1, str2));
+	}
+	// \x93\xF1\x82‚̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x83R\x83\x93\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x91O\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x8C\xE3\x82ɂȂ镶\x8E\x9A\x97\xF1\x81B
+	WString(const WString& str1, const wchar_t* str2):string(NULL) {
+		set(*str2 != '\0' ? concat(str1.string, str2) : str1.string);
+	}
+	// destructor
+	// \x83f\x83X\x83g\x83\x89\x83N\x83^\x81B
+	// \x94h\x90\xB6\x82\xB7\x82邱\x82Ƃ͍l\x82\xA6\x82Ă\xA2\x82Ȃ\xA2\x82̂ʼn\xBC\x91z\x8A֐\x94\x82ɂ͂\xB5\x82Ȃ\xA2\x81B
+	~WString() {
+		release();
+	}
+	// public methods
+	// \x82\xB1\x82̕\xB6\x8E\x9A\x97\xF1\x82̌\xE3\x82Ɏw\x92\xE8\x82̕\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x98A\x8C\x8B\x82\xB3\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x81B
+	WString concat(const wchar_t* source)const {
+		return WString(*this, source);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x8Ds\x82\xA4\x81B
+	// NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82\xCE0\x81Astr\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82Ε\x89\x81A\x8F\xAC\x82\xB3\x82\xAF\x82\xEA\x82ΐ\xB3\x81B
+	int compareTo(const wchar_t* str)const {
+		if (str == NULL)
+			return string == NULL ? 0 : 1;
+		else if (string == NULL)
+			return -1;
+		return wcscmp(string, str);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x91啶\x8E\x9A\x8F\xAC\x95\xB6\x8E\x9A\x82̋\xE6\x95ʂȂ\xB5\x82ōs\x82\xA4\x81B
+	// NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82\xCE0\x81Astr\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82Ε\x89\x81A\x8F\xAC\x82\xB3\x82\xAF\x82\xEA\x82ΐ\xB3\x81B
+	int compareToIgnoreCase(const wchar_t* str)const {
+		if (str == NULL)
+			return string == NULL ? 0 : 1;
+		else if (string == NULL)
+			return -1;
+		return _wcsicmp(string, str);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x8Ds\x82\xA4\x81B
+	// NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool equals(const wchar_t* str)const {
+		return compareTo(str) == 0;
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82Ƃ̔\xE4\x8Ar\x82\xF0\x91啶\x8E\x9A\x8F\xAC\x95\xB6\x8E\x9A\x82̋\xE6\x95ʂȂ\xB5\x82ōs\x82\xA4\x81B
+	// NULL\x82Ƃ\xE0\x94\xE4\x8Ar\x82ł\xAB\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool equalsIgnoreCase(const wchar_t* str)const {
+		return compareToIgnoreCase(str) == 0;
+	}
+	// \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82𔻒肷\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B
+	bool startsWith(const wchar_t* str)const {
+		return startsWith(str, 0);
+	}
+	// \x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82𔻒肷\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82Ŏn\x82܂\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B
+	bool startsWith(const wchar_t* str, int offset)const {
+		return wcsncmp(string, str, wcslen(str)) == 0;
+	}
+	// \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82ŏI\x82\xED\x82\xC1\x82Ă\xA2\x82邩\x82ǂ\xA4\x82\xA9\x82𔻒肷\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82ŏI\x82\xED\x82\xC1\x82Ă\xA2\x82\xEA\x82ΐ^\x81B
+	//
+	bool endsWith(const wchar_t* str)const {
+		size_t str_length = wcslen(str);
+		size_t string_length = length();
+		if (string_length < str_length)
+			return false;
+		return wcscmp(string + string_length - str_length, str) == 0;
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x92T\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int indexOf(char chr)const {
+		return indexOf(chr, 0);
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x82ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B
+	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int indexOf(wchar_t chr, size_t from)const {
+		if (from >= length())
+			return -1;
+		const wchar_t* found = wcschr(string + from, chr);
+		if (found == NULL)
+			return -1;
+		return found - string;
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97񂪂ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x92T\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int indexOf(const wchar_t* str)const {
+		return indexOf(str, 0);
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97񂪂ǂ̈ʒu\x82ɂ\xA0\x82邩\x82\xF0\x8Ew\x92\xE8\x82̈ʒu\x82\xA9\x82\xE7\x92T\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B
+	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	//
+	int indexOf(const wchar_t* str, size_t from)const {
+		if (from >= length())
+			return -1;
+		const wchar_t* found = wcsstr(string + from, str);
+		if (found == NULL)
+			return -1;
+		return found - string;
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82̒\xB7\x82\xB3\x82\xF0\x95Ԃ\xB7\x81B
+	size_t length()const {
+		return wcslen(string);
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8DŌ\xE3\x82Ɍ\xA9\x82‚\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int lastIndexOf(char chr)const {
+		return lastIndexOf(chr, (size_t) -1);
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xAA\x8Ew\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82‚\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	chr \x92T\x82\xB7\x95\xB6\x8E\x9A\x81B
+	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int lastIndexOf(wchar_t chr, size_t from)const {
+		size_t len = length();
+		if (from > len - 1)
+			from = len - 1;
+		const wchar_t* s = string;
+		const wchar_t* end = string + from;
+		const wchar_t* found = NULL;
+		while (*s != '0' && s <= end) {
+			if (*s == chr)
+				found = s;
+			s++;
+		}
+		return found != NULL ? found - string : -1;
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97񂪍Ō\xE3\x82Ɍ\xA9\x82‚\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int lastIndexOf(const wchar_t* str)const {
+		return lastIndexOf(str, (size_t) -1);
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x97񂪎w\x92\xE8\x82̈ʒu\x82\xE6\x82\xE8\x82\xE0\x91O\x82ōŌ\xE3\x82Ɍ\xA9\x82‚\xA9\x82\xE9\x88ʒu\x82\xF0\x8E擾\x82\xB7\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x92T\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x81B
+	//	from \x92T\x82\xB5\x8En\x82߂\xE9\x88ʒu\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82̌\xA9\x82‚\xA9\x82\xC1\x82\xBD\x83C\x83\x93\x83f\x83b\x83N\x83X\x81B\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAF\x82\xEA\x82\xCE-1\x81B
+	int lastIndexOf(const wchar_t* str, size_t from)const {
+		size_t len = length();
+		size_t str_len = wcslen(str);
+		if (from > len - str_len)
+			from = len - str_len;
+		const wchar_t* s = string + from;
+		while (s >= string) {
+			if (wcsncmp(s, str, str_len) == 0)
+				return s - string;
+			s--;
+		}
+		return -1;
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	start \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̐擪\x82̈ʒu\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x81B
+	WString substring(int start)const {
+		return WString(string + start);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	start \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̐擪\x82̈ʒu\x81B
+	//	end \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x97\xF1\x82̌\xE3\x82̈ʒu\x81B
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82̈ꕔ\x81B
+	WString substring(int start, int end)const {
+		return WString(string + start, end - start);
+	}
+	// \x8Ew\x92\xE8\x82̈ʒu\x82ɂ\xA0\x82镶\x8E\x9A\x82\xF0\x8E\xE6\x82\xE8\x8Fo\x82\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	index \x8E\xE6\x82\xE8\x8Fo\x82\xB7\x95\xB6\x8E\x9A\x82̈ʒu\x81B
+	// \x95Ԓl:
+	//	\x8Ew\x92\xE8\x82̈ʒu\x82ɂ\xA0\x82镶\x8E\x9A\x81B
+	char charAt(size_t index)const {
+		return index < length() ? string[index] : '\0';
+	}
+	// \x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82\xF0\x8Ew\x92\xE8\x82̕\xB6\x8E\x9A\x82ɒu\x82\xAB\x8A\xB7\x82\xA6\x82܂\xB7\x81B
+	// \x88\xF8\x90\x94:
+	//	oldChr \x8C\xB3\x82̕\xB6\x8E\x9A\x81B
+	//	newChr \x92u\x82\xAB\x8A\xB7\x82\xA6\x82镶\x8E\x9A\x81B
+	// \x95Ԓl:
+	//	\x92u\x8A\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	WString replace(char oldChr, char newChr)const {
+		WString result(string);
+		char* s = (char*) result.string;
+		while (*s != '\0'){
+			if (WString::isLeadByte(*s))
+				s++;
+			else if (*s == oldChr)
+				*s = newChr;
+			s++;
+		}
+		return result;
+	}
+	// \x95\xB6\x8E\x9A\x97񒆂̑啶\x8E\x9A\x82\xF0\x8F\xAC\x95\xB6\x8E\x9A\x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B
+	// \x95Ԓl:
+	//	\x95ϊ\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	WString toLowerCase()const {
+		WString result(string);
+		char* s = (char*) result.string;
+		while (*s != '\0'){
+			if (WString::isLeadByte(*s))
+				s++;
+			else if ('A' <= *s && *s <= 'Z')
+				*s += 'a' - 'A';
+			s++;
+		}
+		return result;
+	}
+	// \x95\xB6\x8E\x9A\x97񒆂̏\xAC\x95\xB6\x8E\x9A\x82\xF0\x91啶\x8E\x9A\x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B
+	// \x95Ԓl:
+	//	\x95ϊ\xB7\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	WString toUpperCase()const {
+		WString result(string);
+		char* s = (char*) result.string;
+		while (*s != '\0'){
+			if (WString::isLeadByte(*s))
+				s++;
+			else if ('a' <= *s && *s <= 'z')
+				*s += 'A' - 'a';
+			s++;
+		}
+		return result;
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82̑O\x8C\xE3\x82̋󔒕\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9\x81B
+	// \x95Ԓl:
+	//	\x8D폜\x8C\xE3\x82̕\xB6\x8E\x9A\x97\xF1\x81B
+	WString trim()const {
+		const wchar_t* s = string;
+		while (*s != '\0' && (unsigned char) *s <= ' ')
+			s++;
+		const wchar_t* start = s;
+		s = string + length();
+		while (s > start && (*s != '\0' && (unsigned char) *s <= ' '))
+			s--;
+		return WString(start, s - start);
+	}
+
+	// operators
+
+	// const char*\x82ւ̃L\x83\x83\x83X\x83g\x89\x89\x8EZ\x8Eq
+	// \x95Ԓl:
+	//	\x95\xB6\x8E\x9A\x97\xF1\x82ւ̃A\x83h\x83\x8C\x83X\x81B
+	operator const wchar_t*()const {
+		return string;
+	}
+	// char\x94z\x97\xF1\x82̂悤\x82Ɉ\xB5\x82\xA4\x82\xBD\x82߂\xCC[]\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	index \x8E擾\x82\xB7\x82镶\x8E\x9A\x82̃C\x83\x93\x83f\x83b\x83N\x83X\x81B
+	// \x95Ԓl:
+	//	\x8Ew\x92\xE8\x82̃C\x83\x93\x83f\x83b\x83N\x83X\x82ɂ\xA0\x82镶\x8E\x9A\x81B
+	char operator[](size_t index)const {
+		return charAt(index);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B
+	WString operator+(const wchar_t* source)const {
+		return WString(string, source);
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B
+	WString operator+(const WString& source)const {
+		return *string != '\0' ? WString(string, source.string) : source;
+	}
+	// \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82邽\x82߂\xCC+\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x91O)\x81B
+	//	str2 \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1(\x8C\xE3)\x81B
+	// \x95Ԓl:
+	//	\x98A\x8C\x8B\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x81B
+	friend WString operator+(const wchar_t* str1, const WString& str2) {
+		return *str1 != '\0' ? WString(str1, str2.string) : str2;
+	}
+	// \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x91\xE3\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x91\xE3\x93\xFC\x8C\x8B\x89ʁB
+	WString& operator=(const wchar_t* source) {
+		set(create(source));
+		return *this;
+	}
+	// \x91\xE3\x93\xFC\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x91\xE3\x93\xFC\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x91\xE3\x93\xFC\x8C\x8B\x89ʁB
+	WString& operator=(const WString& source) {
+		set(source.string);
+		return *this;
+	}
+	// \x98A\x8C\x8B\x82\xB5\x82\xBD\x8C\x8B\x89ʂ\xF0\x91\xE3\x93\xFC\x82\xB7\x82鉉\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	source \x98A\x8C\x8B\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	\x98A\x8C\x8B\x8C\x8B\x89ʁB
+	WString& operator+=(const wchar_t* source) {
+		if (*source != '\0')
+			set(concat(string, source));
+		return *this;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator==(const WString& str)const {
+		return compareTo(str.string) == 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator==(const wchar_t* str)const {
+		return compareTo(str) == 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str1\x82\xE6\x82\xE8str2\x82̕\x{30AA4D9}\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	friend bool operator==(const wchar_t* str1, const WString& str2) {
+		return str2.compareTo(str1) == 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator!=(const WString& str)const {
+		return compareTo(str) != 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator!=(const wchar_t* str)const {
+		return compareTo(str) != 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str1\x82\xE6\x82\xE8str2\x82̕\x{30AA4D9}\x82\xB5\x82\xAD\x82Ȃ\xAF\x82\xEA\x82ΐ^\x81B
+	friend bool operator!=(const wchar_t* str1, const WString& str2) {
+		return str2.compareTo(str1) != 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator<(const WString& str)const {
+		return compareTo(str) < 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator<(const wchar_t* str)const {
+		return compareTo(str) < 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str1\x82\xE6\x82\xE8str2\x82̕\xFB\x82\xAA\x91傫\x82\xAF\x82\xEA\x82ΐ^\x81B
+	friend bool operator<(const wchar_t* str1, const WString& str2) {
+		return str2.compareTo(str1) > 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator<=(const WString& str)const {
+		return compareTo(str) <= 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator<=(const wchar_t* str)const {
+		return compareTo(str) <= 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str1\x82\xE6\x82\xE8str2\x82̕\xFB\x82\xAA\x91傫\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	friend bool operator<=(const wchar_t* str1, const WString& str2) {
+		return str2.compareTo(str1) >= 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator>(const WString& str)const {
+		return compareTo(str) > 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator>(const wchar_t* str)const {
+		return compareTo(str) > 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str1\x82\xE6\x82\xE8str2\x82̕\x{30AA3EC}\x82\xB3\x82\xAF\x82\xEA\x82ΐ^\x81B
+	friend bool operator>(const wchar_t* str1, const WString& str2) {
+		return str2.compareTo(str1) < 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator>=(const WString& str)const {
+		return compareTo(str) >= 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str \x94\xE4\x8Ar\x91Ώۂ̕\xB6\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	bool operator>=(const wchar_t* str)const {
+		return compareTo(str) >= 0;
+	}
+	// \x94\xE4\x8Ar\x89\x89\x8EZ\x8Eq\x81B
+	// \x88\xF8\x90\x94:
+	//	str1 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	//	str2 \x94\xE4\x8Ar\x82\xB7\x82镶\x8E\x9A\x97\xF1\x81B
+	// \x95Ԓl:
+	//	str1\x82\xE6\x82\xE8str2\x82̕\x{30AA3EC}\x82\xB3\x82\xA2\x82\xA9\x93\x99\x82\xB5\x82\xAF\x82\xEA\x82ΐ^\x81B
+	friend bool operator>=(const wchar_t* str1, const WString& str2) {
+		return str2.compareTo(str1) <= 0;
+	}
+
+	// public utilities
+
+	// 2\x83o\x83C\x83g\x95\xB6\x8E\x9A\x82̍ŏ\x89\x82\xCC1\x83o\x83C\x83g\x82\xA9\x82ǂ\xA4\x82\xA9\x82𔻒肷\x82\xE9\x81B
+	// \x88\xF8\x90\x94:
+	//	\x94\xBB\x92肷\x82\xE9\x83o\x83C\x83g\x81B
+	// \x95Ԓl:
+	//	2\x83o\x83C\x83g\x95\xB6\x8E\x9A\x82̍ŏ\x89\x82\xCC1\x83o\x83C\x83g\x82ł\xA0\x82\xEA\x82ΐ^\x81B
+	static bool isLeadByte(char ch) {
+	#ifdef _INC_WINDOWS
+		return ::IsDBCSLeadByte(ch) != 0;
+	#else
+		return (ch & 0x80) != 0;
+	#endif
+	}
+};
+
+}
+
+#endif//_YCL_WSTRING_H_

Modified: trunk/TTXKanjiMenu/CMakeLists.txt
===================================================================
--- trunk/TTXKanjiMenu/CMakeLists.txt	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXKanjiMenu/CMakeLists.txt	2021-09-19 15:13:51 UTC (rev 9429)
@@ -49,6 +49,7 @@
   ${PACKAGE_NAME}
   PRIVATE
   ttpcmn
+  common_static
   )
 
 install(

Modified: trunk/TTXKanjiMenu/ttxkanjimenu.c
===================================================================
--- trunk/TTXKanjiMenu/ttxkanjimenu.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXKanjiMenu/ttxkanjimenu.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -22,6 +22,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "inifile_com.h"
+
 #define IniSection "TTXKanjiMenu"
 #define ORDER 5000
 
@@ -257,13 +259,13 @@
 /*
  * \x90ݒ\xE8\x82̓ǂݍ\x9E\x82\xDD
  */
-static void PASCAL TTXKanjiMenuReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXKanjiMenuReadIniFile(const wchar_t *fn, PTTSet ts) {
 	char buff[20];
 
 	/* Call original ReadIniFile */
 	pvar->origReadIniFile(fn, ts);
 
-	GetPrivateProfileString(IniSection, "UseOneSetting", "on", buff, sizeof(buff), fn);
+	GetPrivateProfileStringAFileW(IniSection, "UseOneSetting", "on", buff, sizeof(buff), fn);
 	if (_stricmp(buff, "off") == 0) {
 		pvar->UseOneSetting = FALSE;
 	}
@@ -288,11 +290,11 @@
 /*
  * \x90ݒ\xE8\x82̕ۑ\xB6
  */
-static void PASCAL TTXKanjiMenuWriteIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXKanjiMenuWriteIniFile(const wchar_t *fn, PTTSet ts) {
 	/* Call original WriteIniFile */
 	pvar->origWriteIniFile(fn, ts);
 
-	WritePrivateProfileString(IniSection, "UseOneSetting", pvar->UseOneSetting?"on":"off", fn);
+	WritePrivateProfileStringAFileW(IniSection, "UseOneSetting", pvar->UseOneSetting?"on":"off", fn);
 
 	return;
 }

Modified: trunk/TTXSamples/TTXAdditionalTitle/CMakeLists.txt
===================================================================
--- trunk/TTXSamples/TTXAdditionalTitle/CMakeLists.txt	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXAdditionalTitle/CMakeLists.txt	2021-09-19 15:13:51 UTC (rev 9429)
@@ -49,5 +49,6 @@
   ${PACKAGE_NAME}
   PRIVATE
   ttpcmn
+  common_static
   )
 

Modified: trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.c
===================================================================
--- trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -10,6 +10,8 @@
 #include <winsock2.h>
 #include <ws2tcpip.h>
 
+#include "inifile_com.h"
+
 #define ORDER 4800
 // #define ID_MENUITEM 37000
 #define INISECTION "AdditionalTitle"
@@ -240,15 +242,15 @@
   return;
 }
 
-static void PASCAL TTXReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXReadIniFile(const wchar_t *fn, PTTSet ts) {
   char buff[sizeof(pvar->ts->Title)];
 
   (pvar->origReadIniFile)(fn, ts);
-  GetPrivateProfileString(INISECTION, "AdditionalTitle", "", pvar->add_title, sizeof(pvar->add_title), fn);
+  GetPrivateProfileStringAFileW(INISECTION, "AdditionalTitle", "", pvar->add_title, sizeof(pvar->add_title), fn);
 
   strncpy_s(pvar->orig_title, sizeof(pvar->orig_title), pvar->ts->Title, _TRUNCATE);
 
-  GetPrivateProfileString(INISECTION, "AddMode", "off", buff, sizeof(buff), fn);
+  GetPrivateProfileStringAFileW(INISECTION, "AddMode", "off", buff, sizeof(buff), fn);
   if (_stricmp(buff, "top") == 0) {
     pvar->add_mode = ADD_TOP;
     pvar->ts->AcceptTitleChangeRequest = FALSE;
@@ -264,21 +266,21 @@
   }
 }
 
-static void PASCAL TTXWriteIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXWriteIniFile(const wchar_t *fn, PTTSet ts) {
   strncpy_s(pvar->ts->Title, sizeof(pvar->ts->Title), pvar->orig_title, _TRUNCATE);
   (pvar->origWriteIniFile)(fn, ts);
   SetTitleStr(pvar->orig_title, FALSE);
 
-  WritePrivateProfileString(INISECTION, "AdditionalTitle", pvar->add_title, fn);
+  WritePrivateProfileStringAFileW(INISECTION, "AdditionalTitle", pvar->add_title, fn);
   switch (pvar->add_mode) {
     case ADD_NONE:
-      WritePrivateProfileString(INISECTION, "AddMode", "off", fn);
+      WritePrivateProfileStringAFileW(INISECTION, "AddMode", "off", fn);
       break;
     case ADD_TOP:
-      WritePrivateProfileString(INISECTION, "AddMode", "top", fn);
+      WritePrivateProfileStringAFileW(INISECTION, "AddMode", "top", fn);
       break;
     case ADD_BOTTOM:
-      WritePrivateProfileString(INISECTION, "AddMode", "bottom", fn);
+      WritePrivateProfileStringAFileW(INISECTION, "AddMode", "bottom", fn);
       break;
     default:
       ; // not reached

Modified: trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v16.vcxproj
===================================================================
--- trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v16.vcxproj	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v16.vcxproj	2021-09-19 15:13:51 UTC (rev 9429)
@@ -65,7 +65,7 @@
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\common_static.lib;$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <TargetMachine>MachineX86</TargetMachine>
@@ -82,7 +82,7 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\common_static.lib;$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>

Modified: trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v8.vcproj
===================================================================
--- trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v8.vcproj	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXAdditionalTitle/TTXAdditionalTitle.v8.vcproj	2021-09-19 15:13:51 UTC (rev 9429)
@@ -61,7 +61,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib"
+				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\common_static.lib" "$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib"
 				LinkIncremental="2"
 				GenerateDebugInformation="true"
 				SubSystem="2"
@@ -136,7 +136,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib"
+				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\common_static.lib" "$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib"
 				LinkIncremental="1"
 				GenerateDebugInformation="true"
 				SubSystem="2"

Modified: trunk/TTXSamples/TTXCopyIniFile/TTXCopyIniFile.c
===================================================================
--- trunk/TTXSamples/TTXCopyIniFile/TTXCopyIniFile.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXCopyIniFile/TTXCopyIniFile.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -13,19 +13,19 @@
 typedef struct {
 	PReadIniFile origReadIniFile;
 	PWriteIniFile origWriteIniFile;
-	char origIniFileName[MAXPATHLEN];
+	wchar_t origIniFileName[MAXPATHLEN];
 } TInstVar;
 
 static TInstVar *pvar;
 static TInstVar InstVar;
 
-static void PASCAL TTXReadIniFile(PCHAR fn, PTTSet ts) {
-	strcpy_s(pvar->origIniFileName, sizeof(pvar->origIniFileName), fn);
+static void PASCAL TTXReadIniFile(const wchar_t *fn, PTTSet ts) {
+	wcscpy_s(pvar->origIniFileName, sizeof(pvar->origIniFileName), fn);
 	(pvar->origReadIniFile)(fn, ts);
 }
 
-static void PASCAL TTXWriteIniFile(PCHAR fn, PTTSet ts) {
-	CopyFile(pvar->origIniFileName, fn, TRUE);
+static void PASCAL TTXWriteIniFile(const wchar_t *fn, PTTSet ts) {
+	CopyFileW(pvar->origIniFileName, fn, TRUE);
 	(pvar->origWriteIniFile)(fn, ts);
 }
 

Modified: trunk/TTXSamples/TTXFixedWinSize/TTXFixedWinSize.c
===================================================================
--- trunk/TTXSamples/TTXFixedWinSize/TTXFixedWinSize.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXFixedWinSize/TTXFixedWinSize.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -57,7 +57,7 @@
     *hooks->SetupTerminal = FixedSizeSetupTerminalDlg;
 }
 
-static void PASCAL FixedSizeReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL FixedSizeReadIniFile(const wchar_t *fn, PTTSet ts) {
     (pvar->origReadIniFile)(fn, ts);
     ts->TerminalWidth = WIDTH;
     ts->TerminalHeight = HEIGHT;

Modified: trunk/TTXSamples/TTXRecurringCommand/TTXRecurringCommand.c
===================================================================
--- trunk/TTXSamples/TTXRecurringCommand/TTXRecurringCommand.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXRecurringCommand/TTXRecurringCommand.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -9,6 +9,8 @@
 #include "resource.h"
 #include "i18n.h"
 #include "dlglib.h"
+#include "inifile_com.h"
+#include "codeconv.h"
 
 #define ORDER 4000
 
@@ -74,10 +76,10 @@
 	return NULL;
 }
 
-WORD GetOnOff(PCHAR Sect, PCHAR Key, PCHAR FName, BOOL Default)
+WORD GetOnOff(PCHAR Sect, PCHAR Key, const wchar_t *FName, BOOL Default)
 {
 	char Temp[4];
-	GetPrivateProfileString(Sect, Key, "", Temp, sizeof(Temp), FName);
+	GetPrivateProfileStringAFileW(Sect, Key, "", Temp, sizeof(Temp), FName);
 	if (Default) {
 		if (_stricmp(Temp, "off") == 0)
 			return 0;
@@ -328,24 +330,24 @@
 //
 // TTXReadIniFile, TTXWriteIniFile -- \x90ݒ\xE8\x83t\x83@\x83C\x83\x8B\x82̓ǂݏ\x91\x82\xAB
 //
-void ReadINI(PCHAR fn, PTTSet ts) {
-	char sect[OutBuffSize];
-	char *p;
+void ReadINI(const wchar_t *fn, PTTSet ts) {
+	wchar_t sect[OutBuffSize];
+	wchar_t *p;
 
 	// DLL \x83t\x83@\x83C\x83\x8B\x96\xBC\x82\xA9\x82\xE7\x81AINI \x82̃Z\x83N\x83V\x83\x87\x83\x93\x96\xBC\x82\xF0\x8C\x88\x82߂\xE9
 	if (fn[0] == '\\' || fn[0] == '/' || (fn[0] != 0 && fn[1] == ':')) {
-		strncpy_s(sect, sizeof(sect), fn, _TRUNCATE);
+		wcsncpy_s(sect, _countof(sect), fn, _TRUNCATE);
 	}
 	else {
-		GetModuleFileName(NULL, sect, sizeof(sect));
-		p = strrchr(sect, '\\');
+		GetModuleFileNameW(NULL, sect, _countof(sect));
+		p = wcsrchr(sect, '\\');
 		if (!p) {
 			return;
 		}
-		strncpy_s(p+1, sizeof(sect) - ((p+1)-sect), fn, _TRUNCATE);
+		wcsncpy_s(p+1, sizeof(sect) - ((p+1)-sect), fn, _TRUNCATE);
 	}
 
-	GetPrivateProfileString(SECTION, "Command", "", pvar->orgCommand, sizeof(pvar->orgCommand), sect);
+	GetPrivateProfileStringAFileW(SECTION, "Command", "", pvar->orgCommand, sizeof(pvar->orgCommand), sect);
 	strncpy_s(pvar->command, sizeof(pvar->command), pvar->orgCommand, _TRUNCATE);
 	UnEscapeStr(pvar->command);
 	pvar->cmdLen = (int)strlen(pvar->command);
@@ -356,7 +358,7 @@
 		pvar->command[pvar->cmdLen] = '\0';
 	}
 
-	pvar->interval = GetPrivateProfileInt(SECTION, "Interval", DEFAULT_INTERVAL, sect);
+	pvar->interval = GetPrivateProfileIntAFileW(SECTION, "Interval", DEFAULT_INTERVAL, sect);
 	if (pvar->interval < MINIMUM_INTERVAL) {
 		pvar->interval = MINIMUM_INTERVAL;
 	}
@@ -364,7 +366,7 @@
 	pvar->enable = GetOnOff(SECTION, "Enable", sect, FALSE);
 }
 
-static void PASCAL TTXReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXReadIniFile(const wchar_t *fn, PTTSet ts) {
 	pvar->origReadIniFile(fn, ts);
 	ReadINI(fn, ts);
 
@@ -371,19 +373,19 @@
 	return;
 }
 
-static void PASCAL TTXWriteIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXWriteIniFile(const wchar_t *fn, PTTSet ts) {
 	char buff[20];
 
 	pvar->origWriteIniFile(fn, ts);
 
-	WritePrivateProfileString(SECTION, "Enable", pvar->enable?"on":"off", fn);
+	WritePrivateProfileStringAFileW(SECTION, "Enable", pvar->enable?"on":"off", fn);
 
-	WritePrivateProfileString(SECTION, "Command", pvar->orgCommand, fn);
+	WritePrivateProfileStringAFileW(SECTION, "Command", pvar->orgCommand, fn);
 
 	_snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d", pvar->interval);
-	WritePrivateProfileString(SECTION, "Interval", buff, fn);
+	WritePrivateProfileStringAFileW(SECTION, "Interval", buff, fn);
 
-	WritePrivateProfileString(SECTION, "AddNewLine", pvar->add_nl?"on":"off", fn);
+	WritePrivateProfileStringAFileW(SECTION, "AddNewLine", pvar->add_nl?"on":"off", fn);
 
 	return;
 }
@@ -403,7 +405,10 @@
 	while (next = GetParam(buff, sizeof(buff), next)) {
 		DequoteParam(buff, sizeof(buff), buff);
 		if (_strnicmp(buff, "/F=", 3) == 0) {
-			ReadINI(buff+3, ts);
+			char *f = buff+3;
+			wchar_t *fW = ToWcharA(f);
+			ReadINI(fW, ts);
+			free(fW);
 		}
 	}
 

Modified: trunk/TTXSamples/TTXResizeMenu/TTXResizeMenu.c
===================================================================
--- trunk/TTXSamples/TTXResizeMenu/TTXResizeMenu.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXResizeMenu/TTXResizeMenu.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -7,6 +7,7 @@
 #include <string.h>
 
 #include "compat_win.h"
+#include "inifile_com.h"
 
 #define ORDER 5900
 #define SECTION "Resize Menu"
@@ -183,7 +184,7 @@
   return;
 }
 
-static void PASCAL ResizeMenuReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL ResizeMenuReadIniFile(const wchar_t *fn, PTTSet ts) {
   int i, x, y;
   char Key[20], Buff[100];
 
@@ -191,7 +192,7 @@
 
   for (i=0; i<MAX_MENU_ITEMS; i++) {
     _snprintf_s(Key, sizeof(Key), _TRUNCATE, "ResizeMenu%d", i+1);
-    GetPrivateProfileString(SECTION, Key, "\n", Buff, sizeof(Buff), fn);
+    GetPrivateProfileStringAFileW(SECTION, Key, "\n", Buff, sizeof(Buff), fn);
 
     if (sscanf_s(Buff, "%d , %d", &x, &y) == 2) {
       if (x < -1 ) {

Modified: trunk/TTXSamples/TTXViewMode/TTXViewMode.c
===================================================================
--- trunk/TTXSamples/TTXViewMode/TTXViewMode.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXViewMode/TTXViewMode.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -8,6 +8,7 @@
 #include <string.h>
 #include <windows.h>
 #include "dlglib.h"
+#include "inifile_com.h"
 
 #define ORDER 4000
 #define ID_MENU_VIEWMODE 55200
@@ -110,13 +111,13 @@
   }
 }
 
-static void PASCAL TTXReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXReadIniFile(const wchar_t *fn, PTTSet ts) {
   pvar->origReadIniFile(fn, ts);
-  GetPrivateProfileString(SECTION, "Password", "", pvar->password, sizeof(pvar->password), fn);
+  GetPrivateProfileStringAFileW(SECTION, "Password", "", pvar->password, sizeof(pvar->password), fn);
   return;
 }
 
-static void PASCAL TTXWriteIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXWriteIniFile(const wchar_t *fn, PTTSet ts) {
   pvar->origWriteIniFile(fn, ts);
 //  WritePrivateProfileString(SECTION, "Password", pvar->password, fn);
   return;

Modified: trunk/TTXSamples/TTXttyrec/CMakeLists.txt
===================================================================
--- trunk/TTXSamples/TTXttyrec/CMakeLists.txt	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/CMakeLists.txt	2021-09-19 15:13:51 UTC (rev 9429)
@@ -48,6 +48,7 @@
 target_link_libraries(
   TTXttyplay
   PRIVATE
+  common_static
   ttpcmn
   #
   comdlg32
@@ -101,7 +102,9 @@
 target_link_libraries(
   TTXttyrec
   PRIVATE
+  common_static
   ttpcmn
+  #
   comdlg32
   )
 

Modified: trunk/TTXSamples/TTXttyrec/TTXttyplay.c
===================================================================
--- trunk/TTXSamples/TTXttyrec/TTXttyplay.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/TTXttyplay.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -10,6 +10,8 @@
 #include <winsock2.h>
 #include <ws2tcpip.h>
 
+#include "inifile_com.h"
+
 #include "gettimeofday.h"
 
 #define ORDER 6001
@@ -416,11 +418,11 @@
 	}
 }
 
-static void PASCAL TTXReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXReadIniFile(const wchar_t *fn, PTTSet ts) {
 	(pvar->origReadIniFile)(fn, ts);
 //	ts->TitleFormat = 0;
-	pvar->maxwait = GetPrivateProfileInt(INISECTION, "MaxWait", 0, fn);
-	pvar->speed = GetPrivateProfileInt(INISECTION, "Speed", 0, fn);
+	pvar->maxwait = GetPrivateProfileIntAFileW(INISECTION, "MaxWait", 0, fn);
+	pvar->speed = GetPrivateProfileIntAFileW(INISECTION, "Speed", 0, fn);
 }
 
 static void PASCAL TTXGetSetupHooks(TTXSetupHooks *hooks) {

Modified: trunk/TTXSamples/TTXttyrec/TTXttyplay.v16.vcxproj
===================================================================
--- trunk/TTXSamples/TTXttyrec/TTXttyplay.v16.vcxproj	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/TTXttyplay.v16.vcxproj	2021-09-19 15:13:51 UTC (rev 9429)
@@ -65,7 +65,7 @@
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\common_static.lib;$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <TargetMachine>MachineX86</TargetMachine>
@@ -82,7 +82,7 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\common_static.lib;$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>

Modified: trunk/TTXSamples/TTXttyrec/TTXttyplay.v8.vcproj
===================================================================
--- trunk/TTXSamples/TTXttyrec/TTXttyplay.v8.vcproj	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/TTXttyplay.v8.vcproj	2021-09-19 15:13:51 UTC (rev 9429)
@@ -61,7 +61,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
+				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\common_static.lib" "$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
 				LinkIncremental="2"
 				GenerateDebugInformation="true"
 				SubSystem="2"
@@ -136,7 +136,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
+				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\common_static.lib" "$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
 				LinkIncremental="1"
 				GenerateDebugInformation="true"
 				SubSystem="2"

Modified: trunk/TTXSamples/TTXttyrec/TTXttyrec.c
===================================================================
--- trunk/TTXSamples/TTXttyrec/TTXttyrec.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/TTXttyrec.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -9,6 +9,8 @@
 #include <winsock2.h>
 #include <ws2tcpip.h>
 
+#include "inifile_com.h"
+
 #include "gettimeofday.h"
 
 #define ORDER 6000
@@ -64,10 +66,10 @@
   return NULL;
 }
 
-BOOL GetOnOff(PCHAR sect, PCHAR key, PCHAR fn, BOOL def) {
+BOOL GetOnOff(PCHAR sect, PCHAR key, const wchar_t *fn, BOOL def) {
   char buff[4];
 
-  GetPrivateProfileString(sect, key, "", buff, sizeof(buff), fn);
+  GetPrivateProfileStringAFileW(sect, key, "", buff, sizeof(buff), fn);
 
   if (def) {
     if (_stricmp(buff, "off") == 0) {
@@ -97,7 +99,7 @@
   pvar->record = FALSE;
 }
 
-static void PASCAL TTXReadIniFile(PCHAR fn, PTTSet ts) {
+static void PASCAL TTXReadIniFile(const wchar_t *fn, PTTSet ts) {
   (pvar->origReadIniFile)(fn, ts);
   pvar->rec_stsize = GetOnOff(INISECTION, "RecordStartSize", fn, TRUE);
 }

Modified: trunk/TTXSamples/TTXttyrec/TTXttyrec.v16.vcxproj
===================================================================
--- trunk/TTXSamples/TTXttyrec/TTXttyrec.v16.vcxproj	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/TTXttyrec.v16.vcxproj	2021-09-19 15:13:51 UTC (rev 9429)
@@ -65,7 +65,7 @@
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\common_static.lib;$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <TargetMachine>MachineX86</TargetMachine>
@@ -82,7 +82,7 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(SolutionDir)..\teraterm\$(Configuration)\common_static.lib;$(SolutionDir)..\teraterm\$(Configuration)\ttpcmn.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>

Modified: trunk/TTXSamples/TTXttyrec/TTXttyrec.v8.vcproj
===================================================================
--- trunk/TTXSamples/TTXttyrec/TTXttyrec.v8.vcproj	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/TTXSamples/TTXttyrec/TTXttyrec.v8.vcproj	2021-09-19 15:13:51 UTC (rev 9429)
@@ -61,7 +61,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
+				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\common_static.lib" "$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
 				LinkIncremental="2"
 				GenerateDebugInformation="true"
 				SubSystem="2"
@@ -136,7 +136,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
+				AdditionalDependencies=""$(SolutionDir)..\teraterm\$(ConfigurationName)\common_static.lib" "$(SolutionDir)..\teraterm\$(ConfigurationName)\ttpcmn.lib" user32.lib comdlg32.lib"
 				LinkIncremental="1"
 				GenerateDebugInformation="true"
 				SubSystem="2"

Modified: trunk/teraterm/teraterm/ttsetup.h
===================================================================
--- trunk/teraterm/teraterm/ttsetup.h	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/teraterm/teraterm/ttsetup.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -40,10 +40,10 @@
 // \x8E\xC0\x8Dۂ̌^\x82\xCD tttypes_key.h \x82\xF0 include
 typedef struct TKeyMap_st *PKeyMap;
 
-typedef void (PASCAL *PReadIniFile)
-  (PCHAR FName, PTTSet ts);
-typedef void (PASCAL *PWriteIniFile)
-  (PCHAR FName, PTTSet ts);
+//typedef void (PASCAL *PReadIniFile)(PCHAR FName, PTTSet ts);
+typedef void (PASCAL *PReadIniFile)(const wchar_t *FName, PTTSet ts);
+//typedef void (PASCAL *PWriteIniFile)(PCHAR FName, PTTSet ts);
+typedef void (PASCAL *PWriteIniFile)(const wchar_t *FName, PTTSet ts);
 typedef void (PASCAL *PReadKeyboardCnf)
   (PCHAR FName, PKeyMap KeyMap, BOOL ShowWarning);
 typedef void (PASCAL *PCopyHostList)

Modified: trunk/teraterm/teraterm/vtwin.cpp
===================================================================
--- trunk/teraterm/teraterm/vtwin.cpp	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/teraterm/teraterm/vtwin.cpp	2021-09-19 15:13:51 UTC (rev 9429)
@@ -255,7 +255,7 @@
 		/* first instance */
 		if (LoadTTSET()) {
 			/* read setup info from "teraterm.ini" */
-			(*ReadIniFile)(ts.SetupFName, &ts);
+			(*ReadIniFile)(ts.SetupFNameW, &ts);
 			FreeTTSET();
 		}
 		else {
@@ -266,7 +266,7 @@
 		// 2\x82‚߈ȍ~\x82̃v\x83\x8D\x83Z\x83X\x82ɂ\xA8\x82\xA2\x82Ă\xE0\x81A\x83f\x83B\x83X\x83N\x82\xA9\x82\xE7 TERATERM.INI \x82\xF0\x93ǂށB(2004.11.4 yutaka)
 		if (LoadTTSET()) {
 			/* read setup info from "teraterm.ini" */
-			(*ReadIniFile)(ts.SetupFName, &ts);
+			(*ReadIniFile)(ts.SetupFNameW, &ts);
 			FreeTTSET();
 		}
 		else {
@@ -1134,7 +1134,7 @@
 	strncat_s(ts.SetupFName,sizeof(ts.SetupFName),TempName,_TRUNCATE);
 
 	if (LoadTTSET()) {
-		(*ReadIniFile)(ts.SetupFName,&ts);
+		(*ReadIniFile)(ts.SetupFNameW, &ts);
 	}
 	FreeTTSET();
 
@@ -4726,7 +4726,7 @@
 
 		CopyFileW(PrevSetupFNW, ts.SetupFNameW, TRUE);
 		/* write current setup values to file */
-		(*WriteIniFile)(ts.SetupFName, &ts);
+		(*WriteIniFile)(ts.SetupFNameW, &ts);
 		/* copy host list */
 		char * PrevSetupFN = ToCharW(PrevSetupFNW);
 		(*CopyHostList)(PrevSetupFN, ts.SetupFName);

Modified: trunk/teraterm/ttpset/ttset.c
===================================================================
--- trunk/teraterm/ttpset/ttset.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/teraterm/ttpset/ttset.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -47,6 +47,7 @@
 #include "servicenames.h"
 #include "codeconv.h"
 #include "win32helper.h"
+#include "inifile_com.h"
 
 #define DllExport __declspec(dllexport)
 #include "ttset.h"
@@ -160,87 +161,10 @@
 	return (ret);
 }
 
-/**
- *	GetPrivateProfileStringA() \x82̃t\x83@\x83C\x83\x8B\x96\xBC\x82\xBE\x82\xAF\x82\xAA wchar_t \x94\xC5
- */
-DWORD GetPrivateProfileStringAFileW(const char *appA, const char *keyA, const char* defA, char *strA, DWORD size, const wchar_t *filenameW)
-{
-	DWORD lenA;
-	wchar_t *appW = ToWcharA(appA);
-	wchar_t *keyW = ToWcharA(keyA);
-	wchar_t *defW = ToWcharA(defA);
-	DWORD lenW_max = size;
-	wchar_t *strW = malloc(sizeof(wchar_t) * lenW_max);
-	DWORD lenW = GetPrivateProfileStringW(appW, keyW, defW, strW, lenW_max, filenameW);
-	free(appW);
-	free(keyW);
-	free(defW);
-	if (lenW == 0) {
-		free(strW);
-		*strA = '\0';
-		return 0;
-	}
-	if (lenW < lenW_max) {
-		lenW++;	// for L'\0'
-	}
-	lenA = WideCharToMultiByte(CP_ACP, 0, strW, lenW, strA, size, NULL, NULL);
-	// GetPrivateProfileStringW() \x82̖߂\xE8\x92l\x82\xCD '\0' \x82\xF0\x8A܂܂Ȃ\xA2\x95\xB6\x8E\x9A\x97\xF1\x92\xB7
-	// WideCharToMultiByte() \x82̖߂\xE8\x92l\x82\xCD '\0' \x82\xF0\x8A܂ޕ\xB6\x8E\x9A\x97\xF1\x92\xB7
-	if (lenW != 0 && strA[lenA-1] == 0) {
-		lenA--;
-	}
-	free(strW);
-	return lenA;
-}
-
-/**
- *	WritePrivateProfileStringA() \x82̃t\x83@\x83C\x83\x8B\x96\xBC\x82\xBE\x82\xAF\x82\xAA wchar_t \x94\xC5
- */
-BOOL WritePrivateProfileStringAFileW(const char *appA, const char *keyA, const char *strA, const wchar_t *filenameW)
-{
-	wchar_t *appW = ToWcharA(appA);
-	wchar_t *keyW = ToWcharA(keyA);
-	wchar_t *strW = ToWcharA(strA);
-	BOOL r = WritePrivateProfileStringW(appW, keyW, strW, filenameW);
-	free(appW);
-	free(keyW);
-	free(strW);
-	return r;
-}
-
-/**
- *	GetPrivateProfileIntFileA() \x82̃t\x83@\x83C\x83\x8B\x96\xBC\x82\xBE\x82\xAF\x82\xAA wchar_t \x94\xC5
- */
-UINT GetPrivateProfileIntFileW(const char *appA, const char *keyA, int def, const wchar_t *filenameW)
-{
-	wchar_t *appW = ToWcharA(appA);
-	wchar_t *keyW = ToWcharA(keyA);
-	UINT r = GetPrivateProfileIntW(appW, keyW, def, filenameW);
-	free(appW);
-	free(keyW);
-	return r;
-}
-
-/**
- *	WritePrivateProfileInt() \x82̃t\x83@\x83C\x83\x8B\x96\xBC\x82\xBE\x82\xAF\x82\xAA wchar_t \x94\xC5
- */
-BOOL WritePrivateProfileIntFileW(const char *appA, const char *keyA, int val, const wchar_t *filenameW)
-{
-	wchar_t strW[MAX_PATH];
-	wchar_t *appW = ToWcharA(appA);
-	wchar_t *keyW = ToWcharA(keyA);
-	BOOL r;
-	_snwprintf_s(strW, _countof(strW), _TRUNCATE, L"%d", val);
-	r = WritePrivateProfileStringW(appW, keyW, strW, filenameW);
-	free(appW);
-	free(keyW);
-	return r;
-}
-
 #if INI_FILE_IS_UNICODE
 #undef GetPrivateProfileInt
 #undef GetPrivateProfileString
-#define GetPrivateProfileInt(p1, p2, p3, p4) GetPrivateProfileIntFileW(p1, p2, p3, p4)
+#define GetPrivateProfileInt(p1, p2, p3, p4) GetPrivateProfileIntAFileW(p1, p2, p3, p4)
 #define GetPrivateProfileString(p1, p2, p3, p4, p5, p6) GetPrivateProfileStringAFileW(p1, p2, p3, p4, p5, p6)
 #define GetPrivateProfileStringA(p1, p2, p3, p4, p5, p6) GetPrivateProfileStringAFileW(p1, p2, p3, p4, p5, p6)
 #define WritePrivateProfileStringA(p1, p2, p3, p4) WritePrivateProfileStringAFileW(p1, p2, p3, p4)
@@ -392,11 +316,7 @@
 	strncpy_s(name, len, icon, _TRUNCATE);
 }
 
-#if INI_FILE_IS_UNICODE
 static WORD GetOnOff(PCHAR Sect, PCHAR Key, const wchar_t *FName, BOOL Default)
-#else
-static WORD GetOnOff(PCHAR Sect, PCHAR Key, const char *FName, BOOL Default)
-#endif
 {
 	char Temp[4];
 	GetPrivateProfileString(Sect, Key, "", Temp, sizeof(Temp), FName);
@@ -414,21 +334,13 @@
 	}
 }
 
-#if INI_FILE_IS_UNICODE
 void WriteOnOff(PCHAR Sect, PCHAR Key, const wchar_t *FName, WORD Flag)
-#else
-void WriteOnOff(PCHAR Sect, PCHAR Key, const char *FName, WORD Flag)
-#endif
 {
 	const char *on_off = (Flag != 0) ? "on" : "off";
 	WritePrivateProfileStringA(Sect, Key, on_off, FName);
 }
 
-#if INI_FILE_IS_UNICODE
 void WriteInt(PCHAR Sect, PCHAR Key, const wchar_t *FName, int i)
-#else
-void WriteInt(PCHAR Sect, PCHAR Key, const char *FName, int i)
-#endif
 {
 	char Temp[15];
 	_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%d", i);
@@ -435,11 +347,7 @@
 	WritePrivateProfileStringA(Sect, Key, Temp, FName);
 }
 
-#if INI_FILE_IS_UNICODE
 void WriteUint(PCHAR Sect, PCHAR Key, const wchar_t *FName, UINT i)
-#else
-void WriteUint(PCHAR Sect, PCHAR Key, const char *FName, UINT i)
-#endif
 {
 	char Temp[15];
 	_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%u", i);
@@ -446,11 +354,7 @@
 	WritePrivateProfileStringA(Sect, Key, Temp, FName);
 }
 
-#if INI_FILE_IS_UNICODE
 void WriteInt2(PCHAR Sect, PCHAR Key, const wchar_t *FName, int i1, int i2)
-#else
-void WriteInt2(PCHAR Sect, PCHAR Key, const char *FName, int i1, int i2)
-#endif
 {
 	char Temp[32];
 	_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%d,%d", i1, i2);
@@ -457,13 +361,8 @@
 	WritePrivateProfileStringA(Sect, Key, Temp, FName);
 }
 
-#if INI_FILE_IS_UNICODE
 void WriteInt4(PCHAR Sect, PCHAR Key, const wchar_t *FName,
 			   int i1, int i2, int i3, int i4)
-#else
-void WriteInt4(PCHAR Sect, PCHAR Key, const char *FName,
-			   int i1, int i2, int i3, int i4)
-#endif
 {
 	char Temp[64];
 	_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%d,%d,%d,%d",
@@ -471,13 +370,8 @@
 	WritePrivateProfileStringA(Sect, Key, Temp, FName);
 }
 
-#if INI_FILE_IS_UNICODE
 void WriteInt6(PCHAR Sect, PCHAR Key, const wchar_t *FName,
 			   int i1, int i2, int i3, int i4, int i5, int i6)
-#else
-void WriteInt6(PCHAR Sect, PCHAR Key, const char *FName,
-			   int i1, int i2, int i3, int i4, int i5, int i6)
-#endif
 {
 	char Temp[96];
 	_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%d,%d,%d,%d,%d,%d",
@@ -486,13 +380,8 @@
 }
 
 // \x83t\x83H\x83\x93\x83g\x8F\xEE\x95񏑂\xAB\x8D\x9E\x82݁A4\x83p\x83\x89\x83\x81\x81[\x83^\x94\xC5
-#if INI_FILE_IS_UNICODE
 static void WriteFont(PCHAR Sect, PCHAR Key, const wchar_t *FName,
 					  PCHAR Name, int x, int y, int charset)
-#else
-static void WriteFont(PCHAR Sect, PCHAR Key, const char *FName,
-					  PCHAR Name, int x, int y, int charset)
-#endif
 {
 	char Temp[80];
 	if (Name[0] != 0)
@@ -504,15 +393,9 @@
 }
 
 // \x83t\x83H\x83\x93\x83g\x8F\xEE\x95\xF1\x93ǂݍ\x9E\x82݁A4\x83p\x83\x89\x83\x81\x81[\x83^\x94\xC5
-#if INI_FILE_IS_UNICODE
 static void ReadFont(
 	const char *Sect, const char *Key, const char *Default, const wchar_t *FName,
 	char *FontName, size_t FontNameLen, POINT *FontSize, int *FontCharSet)
-#else
-static void ReadFont(
-	const char *Sect, const char *Key, const char *Default, const char *FName,
-	char *FontName, size_t FontNameLen, POINT *FontSize, int *FontCharSet)
-#endif
 {
 	char Temp[MAX_PATH];
 	GetPrivateProfileString(Sect, Key, Default,
@@ -533,15 +416,9 @@
 }
 
 // \x83t\x83H\x83\x93\x83g\x8F\xEE\x95\xF1\x93ǂݍ\x9E\x82݁A3\x83p\x83\x89\x83\x81\x81[\x83^\x94\xC5
-#if INI_FILE_IS_UNICODE
 static void ReadFont3(
 	const char *Sect, const char *Key, const char *Default, const wchar_t *FName,
 	char *FontName, size_t FontNameLen, int *FontPoint, int *FontCharSet)
-#else
-static void ReadFont3(
-	const char *Sect, const char *Key, const char *Default, const char *FName,
-	char *FontName, size_t FontNameLen, int *FontPoint, int *FontCharSet)
-#endif
 {
 	char Temp[MAX_PATH];
 	GetPrivateProfileString(Sect, Key, Default,
@@ -840,16 +717,11 @@
 
 }
 
-void PASCAL ReadIniFile(PCHAR FNameA, PTTSet ts)
+void PASCAL ReadIniFile(const wchar_t *FName, PTTSet ts)
 {
 	int i;
 	HDC TmpDC;
 	char Temp[MAX_PATH], Temp2[MAX_PATH], *p;
-#if	INI_FILE_IS_UNICODE
-	const wchar_t *FName = ToWcharA(FNameA);
-#else
-	const char *FName = FNameA;
-#endif
 
 	ts->Minimize = 0;
 	ts->HideWindow = 0;
@@ -2390,13 +2262,9 @@
 	if (ts->UnicodeEmojiWidth < 1 || 2 < ts->UnicodeEmojiWidth) {
 		ts->UnicodeEmojiWidth = 1;
 	}
-
-#if	INI_FILE_IS_UNICODE
-	free((void *)FName);
-#endif
 }
 
-void PASCAL WriteIniFile(PCHAR FNameA, PTTSet ts)
+void PASCAL WriteIniFile(const wchar_t *FName, PTTSet ts)
 {
 	int i;
 	char Temp[MAX_PATH];
@@ -2403,11 +2271,6 @@
 	char buf[20];
 	int ret;
 	char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG], msg[MAX_UIMSG];
-#if	INI_FILE_IS_UNICODE
-	const wchar_t *FName = ToWcharA(FNameA);
-#else
-	const char *FName = FNameA;
-#endif
 
 	/* version */
 	ret = WritePrivateProfileString(Section, "Version", TT_VERSION_STR("."), FName);
@@ -3323,13 +3186,8 @@
 	WritePrivateProfileString(ETERM_SECTION, "BGThemeFile",
 	                          ts->EtermLookfeel.BGThemeFile, FName);
 	{
-#if	INI_FILE_IS_UNICODE
 		wchar_t TempW[MAX_PATH];
 		_snwprintf_s(TempW, _countof(TempW), _TRUNCATE, L"%hs\\%hs", ts->HomeDir, BG_THEME_IMAGEFILE);
-#else
-		char TempW[MAX_PATH];
-		_snprintf_s(TempW, _countof(TempW), _TRUNCATE, "%s\\%s", ts->HomeDir, BG_THEME_IMAGEFILE);
-#endif
 		WritePrivateProfileStringA(BG_SECTION, BG_DESTFILE, ts->BGImageFilePath, TempW);
 		WriteInt(BG_SECTION, BG_THEME_IMAGE_BRIGHTNESS1, TempW, ts->BGImgBrightness);
 		WriteInt(BG_SECTION, BG_THEME_IMAGE_BRIGHTNESS2, TempW, ts->BGImgBrightness);
@@ -3733,10 +3591,6 @@
 	WriteInt(Section, "UnicodeAmbiguousWidth", FName, ts->UnicodeAmbiguousWidth);
 	WriteOnOff(Section, "UnicodeEmojiOverride", FName, ts->UnicodeEmojiOverride);
 	WriteInt(Section, "UnicodeEmojiWidth", FName, ts->UnicodeEmojiWidth);
-
-#if	INI_FILE_IS_UNICODE
-	free((void *)FName);
-#endif
 }
 
 void PASCAL CopySerialList(PCHAR IniSrcA, PCHAR IniDestA, PCHAR section,
@@ -4039,8 +3893,9 @@
 				if (_stricmp(ts->SetupFName, Temp) != 0) {
 					strncpy_s(ts->SetupFName, sizeof(ts->SetupFName), Temp,
 					          _TRUNCATE);
+					free(ts->SetupFNameW);
 					ts->SetupFNameW = ToWcharA(ts->SetupFName);
-					ReadIniFile(ts->SetupFName, ts);
+					ReadIniFile(ts->SetupFNameW, ts);
 				}
 			}
 		}

Modified: trunk/ttssh2/ttxssh/ttxssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ttxssh.c	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/ttssh2/ttxssh/ttxssh.c	2021-09-19 15:13:51 UTC (rev 9429)
@@ -86,6 +86,8 @@
 
 #include "compat_win.h"
 #include "codeconv.h"
+#include "inifile_com.h"
+#include "asprintf.h"
 
 #include "libputty.h"
 
@@ -98,6 +100,12 @@
 #undef EndDialog
 #define EndDialog(p1,p2) \
 	TTEndDialog(p1, p2)
+#undef GetPrivateProfileInt
+#undef GetPrivateProfileString
+#define GetPrivateProfileInt(p1, p2, p3, p4) GetPrivateProfileIntAFileW(p1, p2, p3, p4)
+#define GetPrivateProfileString(p1, p2, p3, p4, p5, p6) GetPrivateProfileStringAFileW(p1, p2, p3, p4, p5, p6)
+#define GetPrivateProfileStringA(p1, p2, p3, p4, p5, p6) GetPrivateProfileStringAFileW(p1, p2, p3, p4, p5, p6)
+#define WritePrivateProfileStringA(p1, p2, p3, p4) WritePrivateProfileStringAFileW(p1, p2, p3, p4)
 
 #define MATCH_STR(s, o) strncmp((s), (o), NUM_ELEM(o) - 1)
 #define MATCH_STR_I(s, o) _strnicmp((s), (o), NUM_ELEM(o) - 1)
@@ -223,13 +231,13 @@
 	pvar->ts_SSH->TryDefaultAuth = FALSE;
 }
 
-static BOOL read_BOOL_option(PCHAR fileName, char *keyName, BOOL def)
+static BOOL read_BOOL_option(const wchar_t *fileName, char *keyName, BOOL def)
 {
 	char buf[1024];
 
 	buf[0] = 0;
-	GetPrivateProfileString("TTSSH", keyName, "", buf, sizeof(buf),
-	                        fileName);
+	GetPrivateProfileStringAFileW("TTSSH", keyName, "", buf, sizeof(buf),
+								  fileName);
 	if (buf[0] == 0) {
 		return def;
 	} else {
@@ -239,7 +247,7 @@
 	}
 }
 
-static void read_string_option(PCHAR fileName, char *keyName,
+static void read_string_option(const wchar_t *fileName, char *keyName,
                                char *def, char *buf, int bufSize)
 {
 
@@ -247,7 +255,7 @@
 	GetPrivateProfileString("TTSSH", keyName, def, buf, bufSize, fileName);
 }
 
-static void read_ssh_options(PTInstVar pvar, PCHAR fileName)
+static void read_ssh_options(PTInstVar pvar, const wchar_t *fileName)
 {
 	char buf[1024];
 	TS_SSH *settings = pvar->ts_SSH;
@@ -381,7 +389,7 @@
 	clear_local_settings(pvar);
 }
 
-static void write_ssh_options(PTInstVar pvar, PCHAR fileName,
+static void write_ssh_options(PTInstVar pvar, const wchar_t *fileName,
                               TS_SSH *settings, BOOL copy_forward)
 {
 	char buf[1024];
@@ -1339,7 +1347,7 @@
 	*hooks->GetHostName = TTXGetHostName;
 }
 
-static void PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
+static void PASCAL TTXReadINIFile(const wchar_t *fileName, PTTSet ts)
 {
 	(pvar->ReadIniFile) (fileName, ts);
 	read_ssh_options(pvar, fileName);
@@ -1348,7 +1356,7 @@
 	FWDUI_load_settings(pvar);
 }
 
-static void PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
+static void PASCAL TTXWriteINIFile(const wchar_t *fileName, PTTSet ts)
 {
 	(pvar->WriteIniFile) (fileName, ts);
 	*pvar->ts_SSH = pvar->settings;
@@ -1358,15 +1366,16 @@
 }
 
 static void read_ssh_options_from_user_file(PTInstVar pvar,
-                                            char *user_file_name)
+                                            const wchar_t *user_file_name)
 {
 	if (user_file_name[0] == '.') {
 		read_ssh_options(pvar, user_file_name);
 	} else {
-		char buf[1024];
+		wchar_t *fname;
 
-		get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
-		read_ssh_options(pvar, buf);
+		fname = get_teraterm_dir_relative_nameW(user_file_name);
+		read_ssh_options(pvar, fname);
+		free(fname);
 	}
 
 	pvar->settings = *pvar->ts_SSH;
@@ -1433,14 +1442,19 @@
 		action = OPTION_NONE;
 
 		if ((option[0] == '-' || option[0] == '/')) {
+			wchar_t* option2W;
 			if (MATCH_STR(option + 1, "ssh") == 0) {
 				if (MATCH_STR(option + 4, "-f=") == 0) {
 					strncpy_s(option2, opt_len, option + 7, _TRUNCATE);
-					read_ssh_options_from_user_file(pvar, option2);
+					option2W = ToWcharA(option2);
+					read_ssh_options_from_user_file(pvar, option2W);
+					free(option2W);
 					action = OPTION_CLEAR;
 				} else if (MATCH_STR(option + 4, "-consume=") == 0) {
 					strncpy_s(option2, opt_len, option + 13, _TRUNCATE);
-					read_ssh_options_from_user_file(pvar, option2);
+					option2W = ToWcharA(option2);
+					read_ssh_options_from_user_file(pvar, option2W);
+					free(option2W);
 					DeleteFile(option2);
 					action = OPTION_CLEAR;
 				}
@@ -1448,7 +1462,9 @@
 			// ttermpro.exe \x82\xCC /F= \x8Ew\x92\xE8\x82ł\xE0 TTSSH \x82̐ݒ\xE8\x82\xF0\x93ǂ\xDE (2006.10.11 maya)
 			} else if (MATCH_STR_I(option + 1, "f=") == 0) {
 				strncpy_s(option2, opt_len, option + 3, _TRUNCATE);
-				read_ssh_options_from_user_file(pvar, option2);
+				option2W = ToWcharA(option2);
+				read_ssh_options_from_user_file(pvar, option2W);
+				free(option2W);
 				// Tera Term\x91\xA4\x82ł\xE0\x89\xF0\x8E߂\xB7\x82\xE9\x95K\x97v\x82\xAA\x82\xA0\x82\xE9\x82̂ŏ\xC1\x82\xB3\x82Ȃ\xA2
 			}
 		}
@@ -2454,6 +2470,27 @@
 
 }
 
+/**
+ *	\x83t\x83@\x83C\x83\x8B\x96\xBC\x82\xF0\x83t\x83\x8B\x83p\x83X\x82ɕϊ\xB7\x82\xB7\x82\xE9
+ *	@return	\x83t\x83\x8B\x83p\x83X\x83t\x83@\x83C\x83\x8B\x96\xBC
+ *			free()\x82\xB7\x82邱\x82\xC6
+ */
+wchar_t *get_teraterm_dir_relative_nameW(const wchar_t *basename)
+{
+	wchar_t *path;
+	wchar_t *ret;
+
+	if (basename[0] == '\\' || basename[0] == '/'
+	 || (basename[0] != 0 && basename[1] == ':')) {
+		return _wcsdup(basename);
+	}
+
+	// ttermpro.exe\x82̃p\x83X
+	path = GetHomeDirW(NULL);
+	aswprintf(&ret, L"%s\\%s", path, basename);
+	return ret;
+}
+
 void get_teraterm_dir_relative_name(char *buf, int bufsize,
                                     char *basename)
 {
@@ -4662,7 +4699,11 @@
 		buf[cmdlen] = 0;
 		cmd[i] = 0;
 
-		write_ssh_options(pvar, tmpFile, &pvar->settings, FALSE);
+		{
+			wchar_t *tmpFileW = ToWcharA(tmpFile);
+			write_ssh_options(pvar, tmpFileW, &pvar->settings, FALSE);
+			free(tmpFileW);
+		}
 
 		strncat_s(cmd, cmdlen, " /ssh-consume=", _TRUNCATE);
 		strncat_s(cmd, cmdlen, tmpFile, _TRUNCATE);

Modified: trunk/ttssh2/ttxssh/ttxssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ttxssh.h	2021-09-19 15:13:34 UTC (rev 9428)
+++ trunk/ttssh2/ttxssh/ttxssh.h	2021-09-19 15:13:51 UTC (rev 9429)
@@ -127,7 +127,7 @@
 
 
 /*
- * Host key rotation 
+ * Host key rotation
  */
 #define SSH_UPDATE_HOSTKEYS_NO	0
 #define SSH_UPDATE_HOSTKEYS_YES	1
@@ -384,6 +384,7 @@
 #endif
 
 void get_teraterm_dir_relative_name(char *buf, int bufsize, char *basename);
+wchar_t *get_teraterm_dir_relative_nameW(const wchar_t *basename);
 int copy_teraterm_dir_relative_path(char *dest, int destsize, char *basename);
 int uuencode(unsigned char *src, int srclen, unsigned char *target, int targsize);
 


ttssh2-commit メーリングリストの案内
Zurück zum Archiv-Index