[Ttssh2-commit] [5665] インストーラはインストールされている Cygwin が 32bit か 64bit か判定して、適切な cygterm.exe をコピーする

svnno****@sourc***** svnno****@sourc*****
2014年 9月 20日 (土) 00:05:02 JST


Revision: 5665
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5665
Author:   maya
Date:     2014-09-20 00:05:02 +0900 (Sat, 20 Sep 2014)
Log Message:
-----------
インストーラはインストールされている Cygwin が 32bit か 64bit か判定して、適切な cygterm.exe をコピーする
  32bit 版の cygterm.exe もフォルダを作ってインストールする
  {app} に cygterm.exe がないときだけ、cygwin1.dll を探して判定して適切な cygterm.exe をコピーする
  アンインストール時には {app}\cygterm.exe を必ず削除する
64bit Cygwin でコンパイルした cyglaunch.exe の同梱をやめた
  cyglaunch.exe は単体で動くので、32bit 版バイナリでも 64bit の cygterm.exe を起動できるため

Modified Paths:
--------------
    trunk/installer/build.bat
    trunk/installer/makearchive.bat
    trunk/installer/teraterm.iss

Added Paths:
-----------
    trunk/installer/cygtool/
    trunk/installer/cygtool/cygtool.c
    trunk/installer/cygtool/cygtool.def
    trunk/installer/cygtool/cygtool.mak

Removed Paths:
-------------
    trunk/cygterm/cygterm+-x86_64/cyglaunch.exe

-------------- next part --------------
Deleted: trunk/cygterm/cygterm+-x86_64/cyglaunch.exe
===================================================================
(Binary files differ)

Modified: trunk/installer/build.bat
===================================================================
--- trunk/installer/build.bat	2014-09-18 14:49:40 UTC (rev 5664)
+++ trunk/installer/build.bat	2014-09-19 15:05:02 UTC (rev 5665)
@@ -28,3 +28,8 @@
 if "%BUILD%" == "rebuild" make clean
 make
 popd
+
+rem cygtool \x82\xF0\x83R\x83\x93\x83p\x83C\x83\x8B
+pushd cygtool
+nmake -f cygtool.mak
+popd


Property changes on: trunk/installer/cygtool
___________________________________________________________________
Added: svn:ignore
   + *.dll
*.exe
*.exp
*.lib
*.obj


Added: trunk/installer/cygtool/cygtool.c
===================================================================
--- trunk/installer/cygtool/cygtool.c	                        (rev 0)
+++ trunk/installer/cygtool/cygtool.c	2014-09-19 15:05:02 UTC (rev 5665)
@@ -0,0 +1,224 @@
+#pragma comment(lib, "version.lib")
+
+#include <windows.h>
+#include <stdio.h>
+
+#include "compat_w95.h"
+
+int __stdcall FindCygwinPath(char *CygwinDirectory, char *Dir, int Dirlen)
+{
+	char c, *envptr, *p, *p2;
+
+	envptr = getenv("PATH");
+	if (envptr == NULL) {
+		return 0;
+	}
+#ifdef EXE
+	printf("  PATH => %s\n", envptr);
+#endif
+	if ((p = strstr(envptr, "cygwin\\bin")) != NULL) {
+		goto found_path;
+	}
+	if ((p = strstr(envptr, "cygwin64\\bin")) != NULL) {
+		goto found_path;
+	}
+
+	_snprintf_s(Dir, Dirlen, _TRUNCATE, "%s\\bin", CygwinDirectory);
+	if (GetFileAttributes(Dir) != -1) { // open success
+		goto found_dll;
+	}
+
+	_snprintf_s(Dir, Dirlen, _TRUNCATE, "C:\\cygwin\\bin");
+	for (c = 'C' ; c <= 'Z' ; c++) {
+		Dir[0] = c;
+		if (GetFileAttributes(Dir) != -1) { // open success
+			goto found_dll;
+		}
+	}
+	_snprintf_s(Dir, Dirlen, _TRUNCATE, "C:\\cygwin64\\bin");
+	for (c = 'C' ; c <= 'Z' ; c++) {
+		Dir[0] = c;
+		if (GetFileAttributes(Dir) != -1) { // open success
+			goto found_dll;
+		}
+	}
+
+	return 0;
+
+found_dll:;
+	Dir[strlen(Dir)-4] = '\0'; // delete "\\bin"
+	return 1;
+
+found_path:;
+	if ((p2 = strchr(p, ';')) == NULL) {
+		p2 += strlen(p);
+	}
+	else {
+		p2--;
+	}
+	while (envptr < p) {
+		p--;
+		if (*p == ';') {
+			p++;
+			break;
+		}
+	}
+	strncpy_s(Dir, Dirlen, p, _TRUNCATE);
+	if (p2 - p < Dirlen-1) {
+		Dir[p2 - p + 1] = '\0';
+	}
+	Dir[strlen(Dir)-4] = '\0'; // delete "\\bin"
+	return 1;
+}
+
+int __stdcall CygwinMachine(char *file)
+{
+	FILE *fp;
+	unsigned char buf[4];
+	long e_lfanew;
+	WORD Machine;
+
+	if ((fp = fopen(file, "rb")) == NULL) {
+		return IMAGE_FILE_MACHINE_UNKNOWN;
+	}
+
+	// IMAGE_DOS_HEADER
+	if (fseek(fp, 0x3c, SEEK_SET) != 0) {
+		fclose(fp);
+		return IMAGE_FILE_MACHINE_UNKNOWN;
+	}
+	if (fread(buf, sizeof(char), 4, fp) < 4) {
+		fclose(fp);
+		return IMAGE_FILE_MACHINE_UNKNOWN;
+	}
+	e_lfanew = buf[0] + (buf[1] << 8) + (buf[1] << 16) + (buf[1] << 24);
+#ifdef EXE
+	printf("  e_lfanew => x%08x\n", e_lfanew);
+#endif
+
+	// IMAGE_NT_HEADERS32
+	//   DWORD Signature;
+	//   IMAGE_FILE_HEADER FileHeader;
+	if (fseek(fp, e_lfanew + 4, SEEK_SET) != 0) {
+		fclose(fp);
+		return IMAGE_FILE_MACHINE_UNKNOWN;
+	}
+	if (fread(buf, sizeof(char), 2, fp) < 2) {
+		fclose(fp);
+		return IMAGE_FILE_MACHINE_UNKNOWN;
+	}
+	Machine = buf[0] + (buf[1] << 8);
+
+	fclose(fp);
+
+	return Machine;
+}
+
+int __stdcall CygwinVersion(char *dll, int *major, int *minor)
+{
+	DWORD dwSize;
+	DWORD dwHandle;
+	DWORD dwLen;
+	LPVOID lpBuf;
+	UINT uLen;
+	VS_FIXEDFILEINFO *pFileInfo;
+	
+	dwSize = GetFileVersionInfoSize(dll, &dwHandle);
+	if (dwSize == 0) {
+		return 0;
+	}
+	
+	lpBuf = malloc(dwSize);
+	if (!GetFileVersionInfo(dll, dwHandle, dwSize, lpBuf)) {
+		free(lpBuf);
+		return 0;
+	}
+	
+	if (!VerQueryValue(lpBuf, "\\", (LPVOID*)&pFileInfo, &uLen)) {
+		free(lpBuf);
+		return 0;
+	}
+	
+	*major = HIWORD(pFileInfo->dwFileVersionMS);
+	*minor = LOWORD(pFileInfo->dwFileVersionMS);
+	
+	free(lpBuf);
+	
+	return 1;
+}
+
+#ifdef EXE
+int main(void)
+{
+	char file[MAX_PATH];
+	char version[MAX_PATH];
+	int file_len = sizeof(file);
+	int version_major, version_minor;
+	int res;
+	
+	printf("FindCygwinPath()\n");
+	res = FindCygwinPath("C:\\cygwin", file, file_len);
+	printf("  result => %d\n", res);
+	if (!res) {
+		printf("\n");
+		return -1;
+	}
+	printf("  Cygwin directory => %s\n", file);
+	printf("\n");
+	
+	printf("CygwinMachine()\n");
+	strncat_s(file, sizeof(file), "\\bin\\cygwin1.dll", _TRUNCATE);
+	printf("  Cygwin DLL => %s\n", file);
+	res = CygwinMachine(file);
+	printf("  Machine => x%04x", res);
+	switch (res) {
+		case IMAGE_FILE_MACHINE_I386:
+			printf(" = %s\n", "IMAGE_FILE_MACHINE_I386");
+			break;
+		case IMAGE_FILE_MACHINE_AMD64:
+			printf(" = %s\n", "IMAGE_FILE_MACHINE_AMD64");
+			break;
+		default:
+			printf("\n");
+			return -1;
+			break;
+	}
+	printf("\n");
+	
+	printf("CygwinVersion()\n");
+	printf("  Cygwin DLL => %s\n", file);
+	res = CygwinVersion(file, &version_major, &version_minor);
+	printf("  result => %d\n", res);
+	if (!res) {
+	printf("\n");
+		return -1;
+	}
+	printf("  version_major => %d\n", version_major);
+	printf("  version_minor => %d\n", version_minor);
+	printf("\n");
+	
+	return 0;
+}
+#else
+BOOL WINAPI DllMain(HANDLE hInstance,
+		    ULONG ul_reason_for_call,
+		    LPVOID lpReserved)
+{
+  switch( ul_reason_for_call ) {
+    case DLL_THREAD_ATTACH:
+      /* do thread initialization */
+      break;
+    case DLL_THREAD_DETACH:
+      /* do thread cleanup */
+      break;
+    case DLL_PROCESS_ATTACH:
+      /* do process initialization */
+      DoCover_IsDebuggerPresent();
+      break;
+    case DLL_PROCESS_DETACH:
+      /* do process cleanup */
+      break;
+  }
+  return TRUE;
+}
+#endif

Added: trunk/installer/cygtool/cygtool.def
===================================================================
--- trunk/installer/cygtool/cygtool.def	                        (rev 0)
+++ trunk/installer/cygtool/cygtool.def	2014-09-19 15:05:02 UTC (rev 5665)
@@ -0,0 +1,4 @@
+EXPORTS
+  FindCygwinPath
+  CygwinMachine
+  CygwinVersion

Added: trunk/installer/cygtool/cygtool.mak
===================================================================
--- trunk/installer/cygtool/cygtool.mak	                        (rev 0)
+++ trunk/installer/cygtool/cygtool.mak	2014-09-19 15:05:02 UTC (rev 5665)
@@ -0,0 +1,17 @@
+CPP=cl.exe
+LINK32=link.exe
+
+CFLAG=/nologo /I "..\..\teraterm\common" /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /W2
+LDFLAG=/nologo /SUBSYSTEM:WINDOWS /DLL
+
+all: cygtool.dll cygtool.exe
+
+cygtool.dll: cygtool.c
+	$(CPP) $(CFLAG) /MT /c cygtool.c
+	$(LINK32) $(LDFLAG) /DEF:cygtool.def cygtool.obj
+
+cygtool.exe: cygtool.c
+	$(CPP) $(CFLAG) /D "EXE" cygtool.c
+
+clean:
+	del *.exe *.dll *.obj *.exp *.lib

Modified: trunk/installer/makearchive.bat
===================================================================
--- trunk/installer/makearchive.bat	2014-09-18 14:49:40 UTC (rev 5664)
+++ trunk/installer/makearchive.bat	2014-09-19 15:05:02 UTC (rev 5665)
@@ -47,9 +47,11 @@
 copy /y ..\cygterm\cygterm.cfg %dst%
 copy /y ..\cygterm\cyglaunch.exe %dst%
 copy /y "..\cygterm\cygterm+.tar.gz" %dst%
+copy /y "..\cygterm\cygterm.exe" %dst%
+mkdir "%dst%\cygterm+-i686"
+copy /y "..\cygterm\cygterm.exe" "%dst%\cygterm+-i686"
 mkdir "%dst%\cygterm+-x86_64"
 copy /y "..\cygterm\cygterm+-x86_64\cygterm.exe" "%dst%\cygterm+-x86_64"
-copy /y "..\cygterm\cygterm+-x86_64\cyglaunch.exe" "%dst%\cygterm+-x86_64"
 copy /y ..\ttpmenu\Release\ttpmenu.exe %dst%
 copy /y ..\TTProxy\Release\TTXProxy.dll %dst%
 copy /y ..\TTXKanjiMenu\Release\ttxkanjimenu.dll %dst%

Modified: trunk/installer/teraterm.iss
===================================================================
--- trunk/installer/teraterm.iss	2014-09-18 14:49:40 UTC (rev 5664)
+++ trunk/installer/teraterm.iss	2014-09-19 15:05:02 UTC (rev 5665)
@@ -96,12 +96,12 @@
 Source: release\lang\Simplified Chinese.lng; DestDir: {app}\lang; Components: TeraTerm; Attribs: readonly; Flags: uninsremovereadonly overwritereadonly
 Source: ..\ttssh2\ttxssh\Release\ttxssh.dll; DestDir: {app}; Components: TTSSH; Flags: ignoreversion
 Source: release\ssh_known_hosts; DestDir: {app}; Components: TTSSH; Flags: onlyifdoesntexist uninsneveruninstall; Permissions: authusers-modify
-Source: ..\cygterm\cygterm.exe; DestDir: {app}; Components: cygterm
+Source: ..\cygterm\cygterm.exe; DestDir: {app}\cygterm+-i686; Components: cygterm
 Source: ..\cygterm\cygterm.cfg; DestDir: {app}; Components: cygterm; Flags: onlyifdoesntexist uninsneveruninstall; Permissions: authusers-modify
 Source: ..\cygterm\cyglaunch.exe; DestDir: {app}; Components: cygterm
 Source: ..\cygterm\cygterm+.tar.gz; DestDir: {app}; Components: cygterm
 Source: ..\cygterm\cygterm+-x86_64\cygterm.exe; DestDir: {app}\cygterm+-x86_64; Components: cygterm
-Source: ..\cygterm\cygterm+-x86_64\cyglaunch.exe; DestDir: {app}\cygterm+-x86_64; Components: cygterm
+Source: cygtool\cygtool.dll; Components: cygterm; Flags: dontcopy
 Source: ..\libs\logmett\Setup_LogMeTT_2_10_2.exe; DestDir: {tmp}; Components: LogMeTT; Flags: deleteafterinstall
 Source: ..\libs\logmett\Setup_TTLEditor_1_5_1.exe; DestDir: {tmp}; Components: TTLEdit; Flags: deleteafterinstall
 Source: ..\ttpmenu\Release\ttpmenu.exe; DestDir: {app}; Components: TeraTerm_Menu; Flags: ignoreversion
@@ -334,10 +334,19 @@
 const
   SHCNF_IDLIST = $0000;
   SHCNE_ASSOCCHANGED = $08000000;
+  IMAGE_FILE_MACHINE_UNKNOWN = $0000;
+  IMAGE_FILE_MACHINE_I386 = $014c;
+  IMAGE_FILE_MACHINE_AMD64 = $8664;
 
 procedure SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2: Integer);
 external 'SHCha****@shell***** stdcall';
 
+function FindCygwinPath(CygwinDirectory, CygwinDir: AnsiString; Dirlen: Cardinal): Integer;
+external 'FindCygwinPath @ files:cygtool.dll stdcall setuponly';
+
+function CygwinMachine(CygwinDir: AnsiString): Integer;
+external 'CygwinMachine @ files:cygtool.dll stdcall setuponly';
+
 var
   UILangFilePage: TInputOptionWizardPage;
 
@@ -747,6 +756,12 @@
 procedure CurStepChanged(CurStep: TSetupStep);
 var
   iniFile : String;
+  CygDir  : String;
+  CygPath : String;
+  CygDll  : String;
+  Cygterm : String;
+  Res     : Integer;
+  Machine : Integer;
 begin
   case CurStep of
     ssPostInstall:
@@ -754,6 +769,26 @@
         iniFile := GetDefaultIniFilename();
         SetIniFile(iniFile);
 
+        if IsComponentSelected('cygterm') then
+        begin;
+            Cygterm := ExpandConstant('{app}') + '\cygterm.exe';
+            if not FileExists(Cygterm) then
+            begin;
+                CygDir := GetIniString('Tera Term', 'CygwinDirectory', 'C:\cygwin', iniFile);
+                SetLength(CygPath, 256);
+                Res := FindCygwinPath(CygDir, CygPath, 256);
+                If Res = 1 then
+                begin;
+                    CygDll := Copy(CygPath, 1, Pos(#0, CygPath) - 1) + '\bin\cygwin1.dll';
+                    Machine := CygwinMachine(CygDll);
+                    if Machine = IMAGE_FILE_MACHINE_AMD64 then
+                        FileCopy(ExpandConstant('{app}') + '\cygterm+-x86_64\cygterm.exe', Cygterm, True)
+                    else
+                        FileCopy(ExpandConstant('{app}') + '\cygterm+-i686\cygterm.exe', Cygterm, True);
+                end;
+            end;
+        end;
+
         if not IsTaskSelected('cygtermhere') then
         begin;
           RegDeleteKeyIncludingSubkeys(HKEY_CURRENT_USER, 'Software\Classes\Folder\shell\cygterm');
@@ -863,3 +898,7 @@
 Name: {app}\copyfont.bat; Type: files
 Name: {app}\copyfont.pif; Type: files
 Name: {app}\libeay.txt; Type: files
+Name: {app}\cygterm+-x86_64\cyglaunch.exe; Type: files
+
+[UninstallDelete]
+Name: {app}\cygterm.exe; Type: files



Ttssh2-commit メーリングリストの案内