• R/O
  • SSH
  • HTTPS

ttssh2: Commit


Commit MetaInfo

Revision9133 (tree)
Time2021-01-16 14:37:28
Authorzmatsuo

Log Message

MinGW による Windows 95 サポート

Change Summary

Incremental Difference

--- branches/mingw_w95/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/CMakeLists.txt (revision 9133)
@@ -59,6 +59,8 @@
5959 elseif(MINGW)
6060 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=${_WIN32_WINNT}")
6161 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=${_WIN32_WINNT}")
62+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__USE_MINGW_ANSI_STDIO=0")
63+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=0")
6264 set(CMAKE_C_CXX_WARNING_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare")
6365 set(CMAKE_C_WARNING_FLAGS "${CMAKE_C_CXX_WARNING_FLAGS} -Wno-pointer-sign")
6466 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_WARNING_FLAGS} -static -ffunction-sections -fdata-sections ${C_ONLY_FLAGS}")
@@ -172,7 +174,7 @@
172174 add_subdirectory(installer)
173175 add_subdirectory(doc)
174176 add_subdirectory(doc_internal)
175-add_subdirectory(tools)
177+#add_subdirectory(tools)
176178
177179 ### create buildinfo.txt
178180 configure_file(
--- branches/mingw_w95/TTProxy/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTProxy/CMakeLists.txt (revision 9133)
@@ -28,6 +28,20 @@
2828 ../../teraterm/common/compat_w95_vs2005.c
2929 )
3030 endif()
31+ if(MINGW)
32+ target_sources(
33+ ${PACKAGE_NAME}
34+ PRIVATE
35+ ../../teraterm/libmingw/tlssup.c
36+ )
37+ target_link_libraries(
38+ ${PACKAGE_NAME}
39+ PRIVATE
40+ -Wl,--whole-archive
41+ mingw_msvcrt
42+ -Wl,--no-whole-archive
43+ )
44+ endif()
3145 endif(SUPPORT_OLD_WINDOWS)
3246
3347 target_sources(
--- branches/mingw_w95/TTXKanjiMenu/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXKanjiMenu/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXAdditionalTitle/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXAdditionalTitle/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXAlwaysOnTop/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXAlwaysOnTop/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXCallSysMenu/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXCallSysMenu/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXCheckUpdate/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXCheckUpdate/CMakeLists.txt (revision 9133)
@@ -27,7 +27,21 @@
2727 ../../teraterm/common/compat_w95_vs2005.c
2828 )
2929 endif()
30-endif()
30+ if(MINGW)
31+ target_sources(
32+ ${PACKAGE_NAME}
33+ PRIVATE
34+ ../../teraterm/libmingw/tlssup.c
35+ )
36+ target_link_libraries(
37+ ${PACKAGE_NAME}
38+ PRIVATE
39+ -Wl,--whole-archive
40+ mingw_msvcrt
41+ -Wl,--no-whole-archive
42+ )
43+ endif()
44+endif(SUPPORT_OLD_WINDOWS)
3145
3246 source_group(
3347 "common"
--- branches/mingw_w95/TTXSamples/TTXCommandLineOpt/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXCommandLineOpt/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXCopyIniFile/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXCopyIniFile/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXFixedWinSize/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXFixedWinSize/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXKcodeChange/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXKcodeChange/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXOutputBuffering/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXOutputBuffering/CMakeLists.txt (revision 9133)
@@ -17,7 +17,14 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20-endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
27+endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
2330 ${PACKAGE_NAME}
--- branches/mingw_w95/TTXSamples/TTXRecurringCommand/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXRecurringCommand/CMakeLists.txt (revision 9133)
@@ -19,7 +19,21 @@
1919 ../../teraterm/common/compat_w95_vs2005.c
2020 )
2121 endif()
22-endif()
22+ if(MINGW)
23+ target_sources(
24+ ${PACKAGE_NAME}
25+ PRIVATE
26+ ../../teraterm/libmingw/tlssup.c
27+ )
28+ target_link_libraries(
29+ ${PACKAGE_NAME}
30+ PRIVATE
31+ -Wl,--whole-archive
32+ mingw_msvcrt
33+ -Wl,--no-whole-archive
34+ )
35+ endif()
36+endif(SUPPORT_OLD_WINDOWS)
2337
2438 source_group(
2539 "common"
--- branches/mingw_w95/TTXSamples/TTXResizeMenu/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXResizeMenu/CMakeLists.txt (revision 9133)
@@ -17,6 +17,20 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ target_link_libraries(
27+ ${PACKAGE_NAME}
28+ PRIVATE
29+ -Wl,--whole-archive
30+ mingw_msvcrt
31+ -Wl,--no-whole-archive
32+ )
33+ endif()
2034 endif(SUPPORT_OLD_WINDOWS)
2135
2236 if (MSVC)
--- branches/mingw_w95/TTXSamples/TTXResizeWin/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXResizeWin/CMakeLists.txt (revision 9133)
@@ -17,6 +17,13 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
2027 endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
--- branches/mingw_w95/TTXSamples/TTXShowCommandLine/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXShowCommandLine/CMakeLists.txt (revision 9133)
@@ -17,6 +17,13 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20+ if(MINGW)
21+ target_sources(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ endif()
2027 endif(SUPPORT_OLD_WINDOWS)
2128
2229 set_target_properties(
--- branches/mingw_w95/TTXSamples/TTXViewMode/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXViewMode/CMakeLists.txt (revision 9133)
@@ -21,6 +21,20 @@
2121 ../../teraterm/common/compat_w95_vs2005.c
2222 )
2323 endif()
24+ if(MINGW)
25+ target_sources(
26+ ${PACKAGE_NAME}
27+ PRIVATE
28+ ../../teraterm/libmingw/tlssup.c
29+ )
30+ target_link_libraries(
31+ ${PACKAGE_NAME}
32+ PRIVATE
33+ -Wl,--whole-archive
34+ mingw_msvcrt
35+ -Wl,--no-whole-archive
36+ )
37+ endif()
2438 endif(SUPPORT_OLD_WINDOWS)
2539
2640 source_group(
--- branches/mingw_w95/TTXSamples/TTXttyrec/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/TTXttyrec/CMakeLists.txt (revision 9133)
@@ -17,6 +17,20 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20+ if(MINGW)
21+ target_sources(
22+ TTXttyplay
23+ PRIVATE
24+ ../../teraterm/libmingw/tlssup.c
25+ )
26+ target_link_libraries(
27+ TTXttyplay
28+ PRIVATE
29+ -Wl,--whole-archive
30+ mingw_msvcrt
31+ -Wl,--no-whole-archive
32+ )
33+ endif()
2034 endif(SUPPORT_OLD_WINDOWS)
2135
2236 target_include_directories(
@@ -51,6 +65,20 @@
5165 ../../teraterm/common/compat_w95_vs2005.c
5266 )
5367 endif()
68+ if(MINGW)
69+ target_sources(
70+ TTXttyrec
71+ PRIVATE
72+ ../../teraterm/libmingw/tlssup.c
73+ )
74+ target_link_libraries(
75+ TTXttyrec
76+ PRIVATE
77+ -Wl,--whole-archive
78+ mingw_msvcrt
79+ -Wl,--no-whole-archive
80+ )
81+ endif()
5482 endif(SUPPORT_OLD_WINDOWS)
5583
5684 target_include_directories(
--- branches/mingw_w95/TTXSamples/ttxtest/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/TTXSamples/ttxtest/CMakeLists.txt (revision 9133)
@@ -15,6 +15,13 @@
1515 ../../teraterm/common/compat_w95_vs2005.c
1616 )
1717 endif()
18+ if(MINGW)
19+ target_sources(
20+ ${PACKAGE_NAME}
21+ PRIVATE
22+ ../../teraterm/libmingw/tlssup.c
23+ )
24+ endif()
1825 endif(SUPPORT_OLD_WINDOWS)
1926
2027 set_target_properties(
--- branches/mingw_w95/installer/cygtool/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/installer/cygtool/CMakeLists.txt (revision 9133)
@@ -14,6 +14,13 @@
1414 ../../teraterm/common/compat_w95_vs2005.c
1515 )
1616 endif()
17+ if(MINGW)
18+ target_sources(
19+ ${PACKAGE_NAME}
20+ PRIVATE
21+ ../../teraterm/libmingw/tlssup.c
22+ )
23+ endif()
1724 endif(SUPPORT_OLD_WINDOWS)
1825
1926 target_link_libraries(
--- branches/mingw_w95/teraterm/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/teraterm/CMakeLists.txt (revision 9133)
@@ -33,3 +33,10 @@
3333 set_target_properties(
3434 common_static
3535 PROPERTIES FOLDER teraterm)
36+
37+if(SUPPORT_OLD_WINDOWS AND MINGW)
38+ add_subdirectory(libmingw)
39+ set_target_properties(
40+ mingw_msvcrt
41+ PROPERTIES FOLDER teraterm)
42+endif()
--- branches/mingw_w95/teraterm/libmingw/CMakeLists.txt (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/CMakeLists.txt (revision 9133)
@@ -0,0 +1,9 @@
1+set(PACKAGE_NAME "mingw_msvcrt")
2+
3+project(${PACKAGE_NAME})
4+
5+add_library(
6+ ${PACKAGE_NAME}
7+ STATIC
8+ msvcrt_wrapper.c
9+ )
--- branches/mingw_w95/teraterm/libmingw/README.md (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/README.md (revision 9133)
@@ -0,0 +1,31 @@
1+build with MinGW
2+================
3+
4+## MinGW
5+
6+- [MinGW(Wikipedia)](https://ja.wikipedia.org/wiki/MinGW)
7+- いくつかの派生プロジェクトが存在する
8+- プロジェクトによっていくつかの選択がある
9+ - GCC(clang)のバージョン
10+ - ライブラリのバージョン
11+ - ターゲット(i686(32bit)/x86_64(64bit))
12+ - Thread model (win32/posix)
13+ - 例外 (sjlj/dwarf)
14+- 比較的新しいOSでTera Termを動作させるならどれでもokと思われる
15+
16+## printf()系の動作を Visual Studio と同じにする
17+
18+- MinGW は C99,C11 などの仕様に準拠しようとしている
19+- 古い Visual Studio は仕様策定前の実装
20+ - "%zd" など新しいフォーマット指定子
21+ - 古い Visual Studio(msvcrt.dll) の printf()系ではサポートしていない
22+ - L"%s" と "%s" の動作の違い
23+ - msvcrtでは %s は char, L"%s" は wchar_t
24+- 特に指定していないと MinGW の printf()系(stdio)を使用する
25+- このため Visual Studio と動作が異なってしまう
26+- `__USE_MINGW_ANSI_STDIO` マクロので切り替えることができる
27+ - 1 のとき mingw の stdio (デフォルト)
28+ - 0 のとき msvcrt
29+- 参考URL
30+ - [printf の %lf について](https://ja.stackoverflow.com/questions/34013/printf-%E3%81%AE-lf-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
31+
--- branches/mingw_w95/teraterm/libmingw/README_w95.md (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/README_w95.md (revision 9133)
@@ -0,0 +1,174 @@
1+
2+
3+## MinGW で古いOS(Windows95)をサポートする
4+
5+ポイント
6+
7+- ランタイム(msvcrt.dll)の違いの吸収
8+- dllのロード(loadlibrary())
9+- pthreadを使用しない
10+
11+## ランタイム(msvcrt.dll)の違いの吸収
12+
13+- MinGW は C runtime として msvcrt.dll (Visual Studioのランタイムdll)を使用する
14+- WindowsのバージョンによってインストールされているランタイムDLL のバージョンが異なる
15+- 使用可能な関数が異なっている
16+ - [msvcrt-xref.pdf](https://sourceforge.net/projects/mingw/files/MinGW/Base/mingwrt/msvcrt-xref/)
17+
18+- CランタイムDLLのバージョンを吸収するためのwrapperを作成
19+ - msvcrt_wrapper.c を作成
20+
21+### 未解決シンボルの追加について
22+
23+vsnprintf_s() 場合の例
24+
25+- msvcrt-os.a を nm で調べる
26+- 1つのオブジェクトファイルに次の2つのシンボルがあることがわかる
27+ - __imp__vsnprintf_s
28+ - _vsnprintf_s
29+- `__declspec(dllimport)` 属性の関数の場合
30+ - 関数へのポインタが `__imp_<関数名>` に収納される
31+- 2つのシンボルを解決できるようファイルに追加
32+
33+
34+```
35+libmsvcrt-oss01204.o:
36+00000000 b .bss
37+00000000 d .data
38+00000000 i .idata$4
39+00000000 i .idata$5
40+00000000 i .idata$6
41+00000000 i .idata$7
42+00000000 t .text
43+ U __head_lib32_libmsvcrt_os_a
44+00000000 I __imp__vsnprintf_s
45+00000000 T _vsnprintf_s
46+```
47+
48+## dllをロードできるようにする
49+
50+- プラグイン(dll)がロードできなくなる
51+- 原因は TLS(Thread Local Storage,スレッド毎の記憶領域)
52+- TLSを使用しないようにする
53+- MinGWのCランタイムスタートアップの一部を置き換える
54+ - tlssup.c
55+
56+### TLSについて
57+
58+- OSにはTLS(Thread Local Storage,スレッド毎の記憶領域)サポートが有る
59+- 新しいC,C++の仕様ではスレッドローカル変数が使用できる
60+ - C++11 では thread_local
61+ - C11 では _Thread_local
62+- Visual Studio では __declspec(thread) で使用できる
63+ - GCC では __thread
64+- LoadLibrary()で使用するdll(Tera Termの場合、プラグイン)では利用で問題があった
65+ - exe と同時にロードするdllはok
66+ - Windows 7以降からok
67+ - [スレッド固有記憶領域を持つ DLLを LoadLibrary すると異常動作する問題](http://seclan.dll.jp/dtdiary/2011/dt20110818.htm)
68+- Windowsではexe(PE32)内.tlsセクションを利用して、スレッドローカル変数の処理を行う
69+ - スレッドコールバックテーブル
70+- Tera Termではスレッドローカル変数を使用していない
71+- MinGWのCランタイムスタートアップの一部を置き換えてtlsセクションを生成しないようにした
72+
73+## Windows 95向けビルドで使える MinGW
74+
75+Windows 95で動作させるため、
76+Thread model が win32となっていることを確認する。
77+posix (pthread)を使用すると95に実装されていない Win32 APIを使用する
78+バイナリが生成される。
79+
80+NGな例 (msys2)
81+```
82+$ gcc -v
83+Using built-in specs.
84+COLLECT_GCC=C:\msys64\mingw32\bin\gcc.exe
85+COLLECT_LTO_WRAPPER=C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/10.2.0/lto-wrapper.exe
86+Target: i686-w64-mingw32
87+Configured with: ../gcc- ....
88+:
89+:
90+Thread model: posix
91+Supported LTO compression algorithms: zlib zstd
92+gcc version 10.2.0 (Rev5, Built by MSYS2 project)
93+```
94+cygwinも同様にNG
95+
96+OKな例 (debian gcc-mingw-w64-i686-win32 package)
97+```
98+$ i686-w64-mingw32-gcc-win32 -v
99+Using built-in specs.
100+COLLECT_GCC=i686-w64-mingw32-gcc
101+COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/10-win32/lto-wrapper
102+Target: i686-w64-mingw32
103+Configured with: ../../src/configure --build=x86_64-lin....
104+:
105+:
106+Thread model: win32
107+Supported LTO compression algorithms: zlib
108+gcc version 10-win32 20200525 (GCC)
109+```
110+
111+OKな例 (MinGW-W64)
112+```
113+>gcc -v
114+Using built-in specs.
115+COLLECT_GCC=gcc
116+COLLECT_LTO_WRAPPER=C:/Program\ Files\ (x86)/mingw-w64/i686-8.1.0-win32-sjlj-rt_v6-rev0/mingw32/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/lto-wrapper.exe
117+Target: i686-w64-mingw32
118+Configured with: ../../../src/gcc-8.1.0/configure --host=i68...
119+:
120+:
121+Thread model: win32
122+gcc version 8.1.0 (i686-win32-sjlj-rev0, Built by MinGW-W64 project)
123+```
124+
125+### ビルド例 (debian gcc-mingw-w64-i686-win32 package)
126+
127+Tera Term を Windows 95 で動作させるためのビルド
128+
129+次のパッケージをインストールしておく
130+```
131+sudo apt-get install gcc-mingw-w64-i686-win32 g++-mingw-w64-i686-win32
132+```
133+
134+thread model win32版が動作するか次のコマンドなどでチェックしておく
135+```
136+i686-w64-mingw32-gcc -v
137+i686-w64-mingw32-g++ -v
138+update-alternatives --display i686-w64-mingw32-gcc
139+update-alternatives --display i686-w64-mingw32-g++
140+```
141+
142+ビルド例
143+```
144+cd [Tera Term source dir]
145+mkdir build
146+cd build
147+cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../mingw.toolchain.cmake -DSUPPORT_OLD_WINDOWS=ON -DCMAKE_BUILD_TYPE=Release
148+make -j
149+make -j install
150+make -j zip
151+```
152+
153+### ビルド例 (MinGW-W64)
154+
155+create_locale()がうまく解決できないため今のところ使えない
156+
157+- [MinGW-W64](http://mingw-w64.org/doku.php/download/mingw-builds)
158+- Version 8.1.0
159+- Architecture i686
160+- Thread win32
161+- Exception sjlj
162+- Build revision 0
163+
164+例
165+
166+```
167+cd [Tera Term source dir]
168+mkdir build_mingw-w64
169+cd build_mingw-w64
170+cmake .. -G "MinGW Makefiles"
171+mingw32-make -j
172+mingw32-make -j install
173+```
174+
--- branches/mingw_w95/teraterm/libmingw/msvcrt_wrapper.c (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/msvcrt_wrapper.c (revision 9133)
@@ -0,0 +1,410 @@
1+/*
2+ * Copyright (C) 2020- TeraTerm Project
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ *
9+ * 1. Redistributions of source code must retain the above copyright
10+ * notice, this list of conditions and the following disclaimer.
11+ * 2. Redistributions in binary form must reproduce the above copyright
12+ * notice, this list of conditions and the following disclaimer in the
13+ * documentation and/or other materials provided with the distribution.
14+ * 3. The name of the author may not be used to endorse or promote products
15+ * derived from this software without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+ */
28+
29+#include <stdio.h>
30+#include <string.h>
31+#include <stdarg.h>
32+#include <errno.h>
33+#include <wchar.h>
34+#include <locale.h>
35+#include <windows.h>
36+#include <stdbool.h>
37+#include <time.h>
38+#include <sys/types.h>
39+#include <sys/stat.h>
40+#include "../common/compat_win.h"
41+
42+// 9x系などの古いmsvcrtが使えるようにする
43+// - _s() 系はセキュリティーの低い関数を呼び出す
44+// - W() 系関数は ANSI文字版を呼び出す
45+// - このファイルをリンクすると必ず置き換えられる
46+// TODO: msvcrtに存在するかチェックして、あればdll内の関数を使用する
47+
48+int vsnprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list ap)
49+{
50+ int truncate = count == _TRUNCATE ? 1 : 0;
51+ if (truncate) {
52+ count = sizeOfBuffer -1;
53+ }
54+ else if (count < sizeOfBuffer) {
55+ count = sizeOfBuffer;
56+ }
57+ int r = vsnprintf(buffer, count, format, ap);
58+ if (truncate && r == sizeOfBuffer) {
59+ buffer[sizeOfBuffer - 1] = 0;
60+ r = -1;
61+ }
62+ return r;
63+}
64+
65+static int inner_vsnprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list ap)
66+{
67+ return vsnprintf_s(buffer, sizeOfBuffer, count, format, ap);
68+}
69+
70+int snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...)
71+{
72+ int r;
73+ va_list ap;
74+ va_start(ap, format);
75+ r = vsnprintf_s(buffer, sizeOfBuffer, count, format, ap);
76+ va_end(ap);
77+ return r;
78+}
79+
80+static int inner_snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...)
81+{
82+ int r;
83+ va_list ap;
84+ va_start(ap, format);
85+ r = vsnprintf_s(buffer, sizeOfBuffer, count, format, ap);
86+ va_end(ap);
87+ return r;
88+}
89+
90+/**
91+ * TODO: locale無視
92+ */
93+static int inner_snprintf_s_l(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, _locale_t locale, ...)
94+{
95+ int r;
96+ va_list ap;
97+ va_start(ap, locale);
98+ r = inner_vsnprintf_s(buffer, sizeOfBuffer, count, format, ap);
99+ va_end(ap);
100+ return r;
101+}
102+
103+static int inner_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list ap)
104+{
105+ bool truncate = false;
106+ if (count == _TRUNCATE) {
107+ truncate = true;
108+ count = sizeOfBuffer;
109+ }
110+ else if (count < sizeOfBuffer) {
111+ count = sizeOfBuffer;
112+ }
113+ int r = _vsnwprintf(buffer, count, format, ap);
114+ if (r == -1) {
115+ // error or 切り捨て
116+ if (truncate) {
117+ buffer[sizeOfBuffer - 1] = 0;
118+ }
119+ r = -1;
120+ }
121+ else {
122+ // うまく書き込まれた
123+ }
124+ return r;
125+}
126+
127+static int inner_snwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, ...)
128+{
129+ int r;
130+ va_list ap;
131+ va_start(ap, format);
132+ r = inner_vsnwprintf_s(buffer, sizeOfBuffer, count, format, ap);
133+ va_end(ap);
134+ return r;
135+}
136+
137+int swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...)
138+{
139+ int r;
140+ va_list ap;
141+ va_start(ap, format);
142+ r = inner_vsnwprintf_s(buffer, sizeOfBuffer, 1, format, ap);
143+ va_end(ap);
144+ return r;
145+}
146+
147+static int inner_swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...)
148+{
149+ int r;
150+ va_list ap;
151+ va_start(ap, format);
152+ r = inner_vsnwprintf_s(buffer, sizeOfBuffer, 1, format, ap);
153+ va_end(ap);
154+ return r;
155+}
156+
157+__declspec(dllimport) int _vscprintf(const char *format, va_list ap)
158+{
159+ int r = vsnprintf(NULL, 0, format, ap);
160+ return r;
161+}
162+
163+static int inner_vscprintf(const char *format, va_list ap)
164+{
165+ int r = vsnprintf(NULL, 0, format, ap);
166+ return r;
167+}
168+
169+static errno_t inner_sscanf_s(const char *buffer, const char *format, ...)
170+{
171+ int r;
172+ va_list ap;
173+ va_start(ap, format);
174+ r = vsscanf(buffer, format, ap);
175+ va_end(ap);
176+ return r;
177+}
178+
179+static errno_t inner_strcat_s(char *strDestination, size_t numberOfElements, const char *strSource)
180+{
181+ size_t dest_len = strlen(strDestination);
182+ size_t src_len = strlen(strSource);
183+
184+ if(dest_len + src_len + 1 > numberOfElements) {
185+ return EINVAL;
186+ }
187+ strcat(strDestination, strSource);
188+ return 0;
189+}
190+
191+static errno_t inner_wcscat_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource)
192+{
193+ size_t dest_len = wcslen(strDestination);
194+ size_t src_len = wcslen(strSource);
195+
196+ if(dest_len + src_len + 1 > numberOfElements) {
197+ return EINVAL;
198+ }
199+ wcscat(strDestination, strSource);
200+ return 0;
201+}
202+
203+static errno_t inner_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource)
204+{
205+ size_t src_len = strlen(strSource);
206+
207+ if(src_len + 1 > numberOfElements) {
208+ return EINVAL;
209+ }
210+ strcpy(strDestination, strSource);
211+ return 0;
212+}
213+
214+static errno_t inner_wcscpy_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource)
215+{
216+ size_t src_len = wcslen(strSource);
217+
218+ if(src_len + 1 > numberOfElements) {
219+ return EINVAL;
220+ }
221+ wcscpy(strDestination, strSource);
222+ return 0;
223+}
224+
225+static errno_t inner_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count)
226+{
227+ size_t src_len = strlen(strSource);
228+
229+ if (count == _TRUNCATE) {
230+ size_t copy_len = numberOfElements - 1 < src_len ? numberOfElements - 1 : src_len;
231+ memcpy(strDestination, strSource, copy_len);
232+ strDestination[copy_len] = '\0';
233+ }
234+ else {
235+ if (numberOfElements - 1 < src_len) {
236+ size_t copy_len = numberOfElements - 1;
237+ memcpy(strDestination, strSource, copy_len);
238+ strDestination[copy_len] = '\0';
239+ }
240+ else {
241+ strcpy(strDestination, strSource);
242+ }
243+ }
244+ return 0;
245+}
246+
247+static errno_t inner_wcsncpy_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource, size_t count)
248+{
249+ size_t src_len = wcslen(strSource);
250+
251+ if (count == _TRUNCATE) {
252+ size_t copy_len = numberOfElements - 1 < src_len ? numberOfElements - 1 : src_len;
253+ wmemcpy(strDestination, strSource, copy_len);
254+ strDestination[copy_len] = '\0';
255+ }
256+ else {
257+ if (numberOfElements - 1 < src_len) {
258+ size_t copy_len = numberOfElements - 1;
259+ wmemcpy(strDestination, strSource, copy_len);
260+ strDestination[copy_len] = '\0';
261+ }
262+ else {
263+ wcscpy(strDestination, strSource);
264+ }
265+ }
266+ return 0;
267+}
268+
269+static errno_t inner_strncat_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count)
270+{
271+ size_t dest_len = strlen(strDest);
272+ size_t left_len = numberOfElements - dest_len;
273+
274+ char *d = strDest + dest_len;
275+ return inner_strncpy_s(d, left_len, strSource, count);
276+}
277+
278+static errno_t inner_wcsncat_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count)
279+{
280+ size_t dest_len = wcslen(strDest);
281+ size_t left_len = numberOfElements - dest_len;
282+
283+ wchar_t *d = strDest + dest_len;
284+ return inner_wcsncpy_s(d, left_len, strSource, count);
285+}
286+
287+static size_t inner_strnlen(const char *s, size_t maxlen)
288+{
289+ size_t len = 0;
290+ while(*s != 0 && maxlen != 0) {
291+ s++;
292+ maxlen--;
293+ len++;
294+ }
295+ return len;
296+}
297+
298+static size_t inner_wcsnlen(const wchar_t *s, size_t maxlen)
299+{
300+ size_t len = 0;
301+ while(*s != 0 && maxlen != 0) {
302+ s++;
303+ maxlen--;
304+ len++;
305+ }
306+ return len;
307+}
308+
309+
310+static errno_t inner_fopen_s(FILE **f, const char *name, const char *mode)
311+{
312+ *f = fopen(name, mode);
313+ return errno;
314+}
315+
316+static errno_t inner_freopen_s(FILE **f, const char *name, const char *mode)
317+{
318+ *f = freopen(name, mode, *f);
319+ return errno;
320+}
321+
322+static errno_t inner__wfopen_s(FILE **f, const wchar_t *name, const char *mode)
323+{
324+ *f = fopen((char *)name, mode); // TODO
325+ return errno;
326+}
327+
328+static char *inner_strtok_s(char* str, const char* delimiters, char** context)
329+{
330+ (void)context;
331+ char *r = strtok(str, delimiters);
332+ return r;
333+}
334+
335+static int inner__wstat64(const wchar_t *pathW, struct __stat64 *st)
336+{
337+ struct _stati64 st32;
338+ int r = _wstati64(pathW, &st32);
339+ if (r != 0) {
340+ char pathA[MAX_PATH];
341+ WideCharToMultiByte(CP_ACP, 0, pathW, -1, pathA, sizeof(pathA)-1, NULL, NULL);
342+ r = _stati64(pathA, &st32);
343+ }
344+ if (r == 0) {
345+ st->st_gid = st32.st_gid;
346+ st->st_atime = st32.st_atime;
347+ st->st_ctime = st32.st_ctime;
348+ st->st_dev = st32.st_dev;
349+ st->st_ino = st32.st_ino;
350+ st->st_mode = st32.st_mode;
351+ st->st_mtime = st32.st_mtime;
352+ st->st_nlink = st32.st_nlink;
353+ st->st_rdev = st32.st_rdev;
354+ st->st_size = st32.st_size;
355+ st->st_uid = st32.st_uid;
356+ }
357+ return r;
358+}
359+
360+static errno_t inner_tmpnam_s(char * str, size_t sizeInChars)
361+{
362+ (void)sizeInChars;
363+ tmpnam(str);
364+ return 0;
365+}
366+
367+static errno_t inner_itoa_s(int value, char * buffer, size_t size, int radix )
368+{
369+ (void)size;
370+ itoa(value, buffer, radix);
371+ return 0;
372+}
373+
374+// テスト用関数
375+#if 0
376+static void not_implemented(void)
377+{
378+ MessageBox(NULL, "not_implemented", "tera trem msvcrt_wrapper", MB_OK | MB_ICONEXCLAMATION);
379+}
380+void *_imp___itoa_s = (void *)not_implemented;
381+#endif
382+
383+void *_imp___vsnprintf_s = (void *)inner_vsnprintf_s;
384+void *_imp___snprintf_s = (void *)inner_snprintf_s;
385+void *_imp___snprintf_s_l = (void *)inner_snprintf_s_l;
386+void *_imp___vsnwprintf_s = (void *)inner_vsnwprintf_s;
387+void *_imp___snwprintf_s = (void *)inner_snwprintf_s;
388+void *_imp__swprintf_s = (void *)inner_swprintf_s;
389+void *_imp___vscprintf = (void *)inner_vscprintf;
390+void *_imp__sscanf_s = (void *)inner_sscanf_s;
391+
392+void *_imp__strcat_s = (void *)inner_strcat_s;
393+void *_imp__wcscat_s = (void *)inner_wcscat_s;
394+void *_imp__strcpy_s = (void *)inner_strcpy_s;
395+void *_imp__wcscpy_s = (void *)inner_wcscpy_s;
396+void *_imp__strncat_s = (void *)inner_strncat_s;
397+void *_imp__wcsncat_s = (void *)inner_wcsncat_s;
398+void *_imp__strncpy_s = (void *)inner_strncpy_s;
399+void *_imp__wcsncpy_s = (void *)inner_wcsncpy_s;
400+void *_imp__strnlen = (void *)inner_strnlen;
401+void *_imp__wcsnlen = (void *)inner_wcsnlen;
402+void *_imp__strtok_s = (void *)inner_strtok_s;
403+
404+void *_imp__fopen_s = (void *)inner_fopen_s;
405+void *_imp__freopen_s = (void *)inner_freopen_s;
406+void *_imp___wfopen_s = (void *)inner__wfopen_s;
407+void *_imp___wstat64 = (void *)inner__wstat64;
408+void *_imp__tmpnam_s = (void *)inner_tmpnam_s;
409+
410+void *_imp___itoa_s = (void *)inner_itoa_s;
--- branches/mingw_w95/teraterm/libmingw/test/CMakeLists.txt (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/test/CMakeLists.txt (revision 9133)
@@ -0,0 +1,83 @@
1+#cmake_minimum_required(VERSION 3.18)
2+cmake_minimum_required(VERSION 3.11)
3+
4+set(PACKAGE_NAME "msvcrt")
5+
6+project(${PACKAGE_NAME})
7+
8+if(MSVC)
9+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
10+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
11+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /ZI")
12+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /ZI")
13+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
14+elseif(MINGW)
15+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__USE_MINGW_ANSI_STDIO=0")
16+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=0")
17+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_WARNING_FLAGS} -g -static -ffunction-sections -fdata-sections ${C_ONLY_FLAGS}")
18+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_CXX_WARNING_FLAGS} -g -static -ffunction-sections -fdata-sections")
19+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
20+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++")
21+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
22+ endif()
23+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -g")
24+endif()
25+
26+add_executable(
27+ ${PACKAGE_NAME}
28+ main.c
29+ outputdebugprintf.cpp
30+ is.c
31+ ../../common/asprintf.cpp
32+ ../../common/compat_win.cpp
33+ ../../common/layer_for_unicode.cpp
34+ ../../common/codeconv.cpp
35+ ../../common/dllutil.cpp
36+ )
37+
38+if(MINGW)
39+ target_sources(
40+ ${PACKAGE_NAME}
41+ PRIVATE
42+ ../msvcrt_wrapper.c
43+ )
44+endif()
45+
46+target_include_directories(
47+ ${PACKAGE_NAME}
48+ PRIVATE
49+ .
50+ ../../common
51+ )
52+
53+if(MINGW)
54+ target_compile_options(
55+ ${PACKAGE_NAME}
56+ PUBLIC -Wall
57+ )
58+endif()
59+
60+target_link_libraries(
61+ ${PACKAGE_NAME}
62+ PRIVATE
63+ gdi32
64+ )
65+
66+
67+#target_link_libraries(
68+# msvcr70
69+# PRIVATE
70+# mingw_msvcrt
71+# )
72+
73+if(false)
74+add_executable(
75+ crt_snprintf_s
76+ crt_snprintf_s.cpp
77+ )
78+
79+target_compile_options(
80+ crt_snprintf_s
81+ PUBLIC -Wall
82+ )
83+endif()
--- branches/mingw_w95/teraterm/libmingw/test/is.c (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/test/is.c (revision 9133)
@@ -0,0 +1,216 @@
1+
2+#include <windows.h>
3+#include "ttlib.h"
4+
5+#if (_MSC_VER < 1800)
6+BOOL vercmp(
7+ DWORD cond_val,
8+ DWORD act_val,
9+ DWORD dwTypeMask)
10+{
11+ switch (dwTypeMask) {
12+ case VER_EQUAL:
13+ if (act_val == cond_val) {
14+ return TRUE;
15+ }
16+ break;
17+ case VER_GREATER:
18+ if (act_val > cond_val) {
19+ return TRUE;
20+ }
21+ break;
22+ case VER_GREATER_EQUAL:
23+ if (act_val >= cond_val) {
24+ return TRUE;
25+ }
26+ break;
27+ case VER_LESS:
28+ if (act_val < cond_val) {
29+ return TRUE;
30+ }
31+ break;
32+ case VER_LESS_EQUAL:
33+ if (act_val <= cond_val) {
34+ return TRUE;
35+ }
36+ break;
37+ }
38+ return FALSE;
39+}
40+
41+#endif
42+
43+BOOL _myVerifyVersionInfo(
44+ LPOSVERSIONINFOEX lpVersionInformation,
45+ DWORD dwTypeMask,
46+ DWORDLONG dwlConditionMask)
47+{
48+ OSVERSIONINFO osvi;
49+ WORD cond;
50+ BOOL ret, check_next;
51+
52+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
53+ GetVersionEx(&osvi);
54+
55+ if (dwTypeMask & VER_BUILDNUMBER) {
56+ cond = (WORD)((dwlConditionMask >> (2*3)) & 0x07);
57+ if (!vercmp(lpVersionInformation->dwBuildNumber, osvi.dwBuildNumber, cond)) {
58+ return FALSE;
59+ }
60+ }
61+ if (dwTypeMask & VER_PLATFORMID) {
62+ cond = (WORD)((dwlConditionMask >> (3*3)) & 0x07);
63+ if (!vercmp(lpVersionInformation->dwPlatformId, osvi.dwPlatformId, cond)) {
64+ return FALSE;
65+ }
66+ }
67+ ret = TRUE;
68+ if (dwTypeMask & (VER_MAJORVERSION | VER_MINORVERSION)) {
69+ check_next = TRUE;
70+ if (dwTypeMask & VER_MAJORVERSION) {
71+ cond = (WORD)((dwlConditionMask >> (1*3)) & 0x07);
72+ if (cond == VER_EQUAL) {
73+ if (!vercmp(lpVersionInformation->dwMajorVersion, osvi.dwMajorVersion, cond)) {
74+ return FALSE;
75+ }
76+ }
77+ else {
78+ ret = vercmp(lpVersionInformation->dwMajorVersion, osvi.dwMajorVersion, cond);
79+ // ret: result of major version
80+ if (!vercmp(lpVersionInformation->dwMajorVersion, osvi.dwMajorVersion, VER_EQUAL)) {
81+ // !vercmp(...: result of GRATOR/LESS than (not "GRATOR/LESS than or equal to") of major version
82+ // e.g.
83+ // lpvi:5.1 actual:5.0 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:FALSE must check minor
84+ // lpvi:5.1 actual:5.1 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:FALSE must check minor
85+ // lpvi:5.1 actual:5.2 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:FALSE must check minor
86+ // lpvi:5.1 actual:6.0 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:TRUE must not check minor
87+ // lpvi:5.1 actual:6.1 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:TRUE must not check minor
88+ // lpvi:5.1 actual:6.2 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:TRUE must not check minor
89+ // lpvi:5.1 actual:5.0 cond:VER_GREATER ret:FALSE !vercmp(...:FALSE must check minor
90+ // lpvi:5.1 actual:5.1 cond:VER_GREATER ret:FALSE !vercmp(...:FALSE must check minor
91+ // lpvi:5.1 actual:5.2 cond:VER_GREATER ret:FALSE !vercmp(...:FALSE must check minor
92+ // lpvi:5.1 actual:6.0 cond:VER_GREATER ret:TRUE !vercmp(...:TRUE must not check minor
93+ // lpvi:5.1 actual:6.1 cond:VER_GREATER ret:TRUE !vercmp(...:TRUE must not check minor
94+ // lpvi:5.1 actual:6.2 cond:VER_GREATER ret:TRUE !vercmp(...:TRUE must not check minor
95+ check_next = FALSE;
96+ }
97+ }
98+ }
99+ if (check_next && (dwTypeMask & VER_MINORVERSION)) {
100+ cond = (WORD)((dwlConditionMask >> (0*3)) & 0x07);
101+ if (cond == VER_EQUAL) {
102+ if (!vercmp(lpVersionInformation->dwMinorVersion, osvi.dwMinorVersion, cond)) {
103+ return FALSE;
104+ }
105+ }
106+ else {
107+ ret = vercmp(lpVersionInformation->dwMinorVersion, osvi.dwMinorVersion, cond);
108+ }
109+ }
110+ }
111+ return ret;
112+}
113+
114+ULONGLONG _myVerSetConditionMask(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask)
115+{
116+ ULONGLONG result, mask;
117+ BYTE op = dwConditionMask & 0x07;
118+
119+ switch (dwTypeBitMask) {
120+ case VER_MINORVERSION:
121+ mask = 0x07 << (0 * 3);
122+ result = dwlConditionMask & ~mask;
123+ result |= op << (0 * 3);
124+ break;
125+ case VER_MAJORVERSION:
126+ mask = 0x07 << (1 * 3);
127+ result = dwlConditionMask & ~mask;
128+ result |= op << (1 * 3);
129+ break;
130+ case VER_BUILDNUMBER:
131+ mask = 0x07 << (2 * 3);
132+ result = dwlConditionMask & ~mask;
133+ result |= op << (2 * 3);
134+ break;
135+ case VER_PLATFORMID:
136+ mask = 0x07 << (3 * 3);
137+ result = dwlConditionMask & ~mask;
138+ result |= op << (3 * 3);
139+ break;
140+ case VER_SERVICEPACKMINOR:
141+ mask = 0x07 << (4 * 3);
142+ result = dwlConditionMask & ~mask;
143+ result |= op << (4 * 3);
144+ break;
145+ case VER_SERVICEPACKMAJOR:
146+ mask = 0x07 << (5 * 3);
147+ result = dwlConditionMask & ~mask;
148+ result |= op << (5 * 3);
149+ break;
150+ case VER_SUITENAME:
151+ mask = 0x07 << (6 * 3);
152+ result = dwlConditionMask & ~mask;
153+ result |= op << (6 * 3);
154+ break;
155+ case VER_PRODUCT_TYPE:
156+ mask = 0x07 << (7 * 3);
157+ result = dwlConditionMask & ~mask;
158+ result |= op << (7 * 3);
159+ break;
160+ default:
161+ result = 0;
162+ break;
163+ }
164+
165+ return result;
166+}
167+
168+ULONGLONG myVerSetConditionMask(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask)
169+{
170+ typedef ULONGLONG(WINAPI *func)(ULONGLONG, DWORD, BYTE);
171+ static HMODULE hmodKernel32 = NULL;
172+ static func pVerSetConditionMask = NULL;
173+ char kernel32_dll[MAX_PATH];
174+
175+ GetSystemDirectory(kernel32_dll, sizeof(kernel32_dll));
176+ strncat_s(kernel32_dll, sizeof(kernel32_dll), "\\kernel32.dll", _TRUNCATE);
177+ if (hmodKernel32 == NULL) {
178+ hmodKernel32 = LoadLibrary(kernel32_dll);
179+ if (hmodKernel32 != NULL) {
180+ pVerSetConditionMask = (func)GetProcAddress(hmodKernel32, "VerSetConditionMask");
181+ }
182+ }
183+
184+ if (pVerSetConditionMask == NULL) {
185+ return _myVerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask);
186+ }
187+
188+ return pVerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask);
189+}
190+
191+BOOL myVerifyVersionInfo(
192+ LPOSVERSIONINFOEX lpVersionInformation,
193+ DWORD dwTypeMask,
194+ DWORDLONG dwlConditionMask)
195+{
196+#if (_MSC_VER >= 1800)
197+ return VerifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask);
198+#else
199+ return _myVerifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask);
200+#endif
201+}
202+
203+BOOL IsWindowsNTKernel()
204+{
205+ OSVERSIONINFOEX osvi;
206+ DWORDLONG dwlConditionMask = 0;
207+ int op = VER_EQUAL;
208+ BOOL ret;
209+
210+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
211+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
212+ osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
213+ dwlConditionMask = myVerSetConditionMask(dwlConditionMask, VER_PLATFORMID, op);
214+ ret = myVerifyVersionInfo(&osvi, VER_PLATFORMID, dwlConditionMask);
215+ return (ret);
216+}
--- branches/mingw_w95/teraterm/libmingw/test/main.c (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/test/main.c (revision 9133)
@@ -0,0 +1,45 @@
1+//gcc -g -o test main.c -Wall -Wl,-wrap=_imp__fopen_s -Wl,-Map=test.map
2+//gcc -g -o test main.c -Wall -Wl,-Map=test.map,--allow-multiple-definition
3+
4+//#define __USE_MINGW_ANSI_STDIO 0
5+#include <stdio.h>
6+#include <string.h>
7+#include <errno.h>
8+#include <wchar.h>
9+#include <windows.h>
10+#include <locale.h>
11+
12+#include "../../common/ttlib.h"
13+#include "../../common/asprintf.h"
14+
15+int vaswprintf_test(const wchar_t *fmt, ...)
16+{
17+ wchar_t *message;
18+ va_list ap;
19+ va_start(ap, fmt);
20+ vaswprintf(&message, fmt, ap);
21+ wprintf(L"message='%ls'\n", message);
22+ wprintf(L"message='%s'\n", message);
23+ free(message);
24+ return 0;
25+}
26+
27+int main(int argc, char *argv[])
28+{
29+ FILE *fp;
30+ printf("1\n");
31+ fopen_s(&fp, "test.txt", "w");
32+ fclose(fp);
33+ printf("2\n");
34+
35+ vaswprintf_test(L"test %s %ls %hs", L"wide", L"wide", "narrow");
36+
37+ {
38+ wchar_t buf[128];
39+ swprintf(buf, _countof(buf), L"test %s %ls %hs", L"wide", L"wide", "narrow");
40+ wprintf(L"buf='%s'\n", buf);
41+ __ms_wprintf(L"buf='%s'\n", buf);
42+ }
43+
44+ return 0;
45+}
--- branches/mingw_w95/teraterm/libmingw/test/outputdebugprintf.cpp (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/test/outputdebugprintf.cpp (revision 9133)
@@ -0,0 +1,27 @@
1+
2+#include <stdio.h>
3+#include <windows.h>
4+
5+#include "ttlib.h"
6+#include "layer_for_unicode.h"
7+#include "compat_win.h"
8+
9+void OutputDebugPrintf(const char *fmt, ...)
10+{
11+ char tmp[1024];
12+ va_list arg;
13+ va_start(arg, fmt);
14+ _vsnprintf_s(tmp, sizeof(tmp), _TRUNCATE, fmt, arg);
15+ va_end(arg);
16+ OutputDebugStringA(tmp);
17+}
18+
19+void OutputDebugPrintfW(const wchar_t *fmt, ...)
20+{
21+ wchar_t tmp[1024];
22+ va_list arg;
23+ va_start(arg, fmt);
24+ _vsnwprintf_s(tmp, _countof(tmp), _TRUNCATE, fmt, arg);
25+ va_end(arg);
26+ _OutputDebugStringW(tmp);
27+}
--- branches/mingw_w95/teraterm/libmingw/tlssup.c (nonexistent)
+++ branches/mingw_w95/teraterm/libmingw/tlssup.c (revision 9133)
@@ -0,0 +1,186 @@
1+/**
2+ * This file has no copyright assigned and is placed in the Public Domain.
3+ * This file is part of the w64 mingw-runtime package.
4+ * No warranty is given; refer to the file DISCLAIMER within this package.
5+ *
6+ * Written by Kai Tietz <kai.tietz@onevision.com>
7+ */
8+
9+#ifdef CRTDLL
10+#undef CRTDLL
11+#endif
12+
13+#include <windows.h>
14+#include <stdio.h>
15+#include <memory.h>
16+#include <malloc.h>
17+
18+#ifndef _CRTALLOC
19+#define _CRTALLOC(x) __attribute__ ((section (x) ))
20+#endif
21+
22+#ifndef __INTERNAL_FUNC_DEFINED
23+#define __INTERNAL_FUNC_DEFINED
24+ typedef void (__cdecl *_PVFV)(void);
25+ typedef int (__cdecl *_PIFV)(void);
26+ typedef void (__cdecl *_PVFI)(int);
27+#endif
28+
29+extern WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
30+
31+#define FUNCS_PER_NODE 30
32+
33+typedef struct TlsDtorNode {
34+ int count;
35+ struct TlsDtorNode *next;
36+ _PVFV funcs[FUNCS_PER_NODE];
37+} TlsDtorNode;
38+
39+ULONG _tls_index = 0;
40+
41+/* TLS raw template data start and end. */
42+_CRTALLOC(".tls$AAA") char _tls_start = 0;
43+_CRTALLOC(".tls$ZZZ") char _tls_end = 0;
44+
45+_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
46+_CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
47+
48+#if 0
49+#ifdef _WIN64
50+_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY64 _tls_used = {
51+ (ULONGLONG) &_tls_start+1, (ULONGLONG) &_tls_end, (ULONGLONG) &_tls_index,
52+ (ULONGLONG) (&__xl_a+1), (ULONG) 0, (ULONG) 0
53+};
54+#else
55+_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY _tls_used = {
56+ (ULONG)(ULONG_PTR) &_tls_start+1, (ULONG)(ULONG_PTR) &_tls_end,
57+ (ULONG)(ULONG_PTR) &_tls_index, (ULONG)(ULONG_PTR) (&__xl_a+1),
58+ (ULONG) 0, (ULONG) 0
59+};
60+#endif
61+#endif
62+
63+#ifndef __CRT_THREAD
64+#ifdef HAVE_ATTRIBUTE_THREAD
65+#define __CRT_THREAD __declspec(thread)
66+#else
67+#define __CRT_THREAD __thread
68+#endif
69+#endif
70+
71+#define DISABLE_MS_TLS 1
72+
73+static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
74+static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
75+
76+#if !defined (DISABLE_MS_TLS)
77+static __CRT_THREAD TlsDtorNode *dtor_list;
78+static __CRT_THREAD TlsDtorNode dtor_list_head;
79+#endif
80+
81+extern int _CRT_MT;
82+
83+BOOL WINAPI __dyn_tls_init (HANDLE, DWORD, LPVOID);
84+
85+BOOL WINAPI
86+__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
87+{
88+ _PVFV *pfunc;
89+ int nfuncs, ifunc;
90+
91+ /* We don't let us trick here. */
92+ if (_CRT_MT != 2)
93+ _CRT_MT = 2;
94+
95+ if (dwReason != DLL_THREAD_ATTACH)
96+ {
97+ if (dwReason == DLL_PROCESS_ATTACH)
98+ __mingw_TLScallback (hDllHandle, dwReason, lpreserved);
99+ return TRUE;
100+ }
101+
102+ /* Use the nfuncs variable to iterate the TLS functions instead of pfunc to
103+ avoid nasty compiler optimizations when comparing two global pointers. */
104+ nfuncs = &__xd_z - (&__xd_a + 1);
105+ for (ifunc=0; ifunc < nfuncs; ++ifunc)
106+ {
107+ pfunc = (&__xd_a + 1) + ifunc;
108+ if (*pfunc != NULL)
109+ (*pfunc)();
110+ }
111+ return TRUE;
112+}
113+
114+const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = (const PIMAGE_TLS_CALLBACK) __dyn_tls_init;
115+_CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK) __dyn_tls_init;
116+
117+int __cdecl __tlregdtor (_PVFV);
118+
119+int __cdecl
120+__tlregdtor (_PVFV func)
121+{
122+ if (!func)
123+ return 0;
124+#if !defined (DISABLE_MS_TLS)
125+ if (dtor_list == NULL)
126+ {
127+ dtor_list = &dtor_list_head;
128+ dtor_list_head.count = 0;
129+ }
130+ else if (dtor_list->count == FUNCS_PER_NODE)
131+ {
132+ TlsDtorNode *pnode = (TlsDtorNode *) malloc (sizeof (TlsDtorNode));
133+ if (pnode == NULL)
134+ return -1;
135+ pnode->count = 0;
136+ pnode->next = dtor_list;
137+ dtor_list = pnode;
138+
139+ dtor_list->count = 0;
140+ }
141+ dtor_list->funcs[dtor_list->count++] = func;
142+#endif
143+ return 0;
144+}
145+
146+static BOOL WINAPI
147+__dyn_tls_dtor (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
148+{
149+#if !defined (DISABLE_MS_TLS)
150+ TlsDtorNode *pnode, *pnext;
151+ int i;
152+#endif
153+
154+ if (dwReason != DLL_THREAD_DETACH && dwReason != DLL_PROCESS_DETACH)
155+ return TRUE;
156+ /* As TLS variables are detroyed already by DLL_THREAD_DETACH
157+ call, we have to avoid access on the possible DLL_PROCESS_DETACH
158+ call the already destroyed TLS vars.
159+ TODO: The used local thread based variables have to be handled
160+ manually, so that we can control their lifetime here. */
161+#if !defined (DISABLE_MS_TLS)
162+ if (dwReason != DLL_PROCESS_DETACH)
163+ {
164+ for (pnode = dtor_list; pnode != NULL; pnode = pnext)
165+ {
166+ for (i = pnode->count - 1; i >= 0; --i)
167+ {
168+ if (pnode->funcs[i] != NULL)
169+ (*pnode->funcs[i])();
170+ }
171+ pnext = pnode->next;
172+ if (pnext != NULL)
173+ free ((void *) pnode);
174+ }
175+ }
176+#endif
177+ __mingw_TLScallback (hDllHandle, dwReason, lpreserved);
178+ return TRUE;
179+}
180+
181+_CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d = (PIMAGE_TLS_CALLBACK) __dyn_tls_dtor;
182+
183+
184+int mingw_initltsdrot_force = 0;
185+int mingw_initltsdyn_force=0;
186+int mingw_initltssuo_force = 0;
--- branches/mingw_w95/teraterm/teraterm/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/teraterm/teraterm/CMakeLists.txt (revision 9133)
@@ -212,6 +212,15 @@
212212 ../../teraterm/common/compat_w95_vs2005.c
213213 )
214214 endif()
215+ if(MINGW)
216+ target_link_libraries(
217+ ${PACKAGE_NAME}
218+ PRIVATE
219+ -Wl,--whole-archive
220+ mingw_msvcrt
221+ -Wl,--no-whole-archive
222+ )
223+ endif()
215224 endif(SUPPORT_OLD_WINDOWS)
216225
217226 if (MSVC)
--- branches/mingw_w95/teraterm/ttpcmn/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/teraterm/ttpcmn/CMakeLists.txt (revision 9133)
@@ -26,6 +26,20 @@
2626 ../../teraterm/common/compat_w95_vs2005.c
2727 )
2828 endif()
29+ if(MINGW)
30+ target_sources(
31+ ${PACKAGE_NAME}
32+ PRIVATE
33+ ../../teraterm/libmingw/tlssup.c
34+ )
35+ target_link_libraries(
36+ ${PACKAGE_NAME}
37+ PRIVATE
38+ -Wl,--whole-archive
39+ mingw_msvcrt
40+ -Wl,--no-whole-archive
41+ )
42+ endif()
2943 endif(SUPPORT_OLD_WINDOWS)
3044
3145 target_sources(
--- branches/mingw_w95/teraterm/ttpset/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/teraterm/ttpset/CMakeLists.txt (revision 9133)
@@ -17,6 +17,15 @@
1717 ../../teraterm/common/compat_w95_vs2005.c
1818 )
1919 endif()
20+ if(MINGW)
21+ target_link_libraries(
22+ ${PACKAGE_NAME}
23+ PRIVATE
24+ -Wl,--whole-archive
25+ mingw_msvcrt
26+ -Wl,--no-whole-archive
27+ )
28+ endif()
2029 endif(SUPPORT_OLD_WINDOWS)
2130
2231 target_sources(
--- branches/mingw_w95/teraterm/ttptek/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/teraterm/ttptek/CMakeLists.txt (revision 9133)
@@ -20,6 +20,13 @@
2020 ../../teraterm/common/compat_w95_vs2005.c
2121 )
2222 endif()
23+ if(MINGW)
24+ target_sources(
25+ ${PACKAGE_NAME}
26+ PRIVATE
27+ ../../teraterm/libmingw/tlssup.c
28+ )
29+ endif()
2330 endif(SUPPORT_OLD_WINDOWS)
2431
2532 target_sources(
--- branches/mingw_w95/tools/ttbroadcast/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/tools/ttbroadcast/CMakeLists.txt (revision 9133)
@@ -28,6 +28,7 @@
2828 target_link_libraries(
2929 ttbroadcast
3030 PRIVATE
31+ ttpcmn
3132 common_static
3233 )
3334
--- branches/mingw_w95/ttssh2/ttxssh/CMakeLists.txt (revision 9132)
+++ branches/mingw_w95/ttssh2/ttxssh/CMakeLists.txt (revision 9133)
@@ -111,6 +111,20 @@
111111 ../../teraterm/common/compat_w95_vs2005.c
112112 )
113113 endif()
114+ if(MINGW)
115+ target_sources(
116+ ${PACKAGE_NAME}
117+ PRIVATE
118+ ../../teraterm/libmingw/tlssup.c
119+ )
120+ target_link_libraries(
121+ ${PACKAGE_NAME}
122+ PRIVATE
123+ -Wl,--whole-archive
124+ mingw_msvcrt
125+ -Wl,--no-whole-archive
126+ )
127+ endif()
114128 endif(SUPPORT_OLD_WINDOWS)
115129
116130 target_include_directories(
Show on old repository browser