[Ttssh2-commit] [9197] comポートの列挙、情報取得を一か所にまとめた

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2021年 3月 13日 (土) 23:42:48 JST


Revision: 9197
          https://osdn.net/projects/ttssh2/scm/svn/commits/9197
Author:   zmatsuo
Date:     2021-03-13 23:42:48 +0900 (Sat, 13 Mar 2021)
Log Message:
-----------
comポートの列挙、情報取得を一か所にまとめた

- 機能を一か所(ComPortInfoGet())にまとめた
- DetectComPorts() から ComPortInfoGet() を利用するようにした
  - comport関連を ttpcmn/ttpcmn.c から ttpcmn/ttpcmn_cominfo.c に分離
  - 従来の動作
    - QueryDosDeviceA(NULL) でデバイスを列挙
    - "COM0" などを探して列挙
    - しかし 95 ではQueryDosDeviceA(NULL)は常に失敗
    - fopen() して成功したときデバイスが存在する、と判定
      - "\\.\COM0" など
  - 修正後
    - ComPortInfoGet() の結果を使用するようにした
- ttpcmn/comportinfo.cpp の ComPortInfoGet()
  - 従来
    - Windows 95 では列挙できていなかった
      - 多分 NT4も
      - setupapi がうまく使用できないOS
  - 修正後
    - 95,NT4の場合は "\\.\COM0" などをオープンしてデバイス存在判定を行う
    - その他のOSの場合は従来とおなじ
      - setupapi を使用する方法
  - comportinfo.cpp,h を common/ へ移動
- QueryDosDeviceA(NULL)
  - 成功するOSでは setupapi が正しく動作
  - 失敗するOSでは setupapi は動作しない

Modified Paths:
--------------
    trunk/teraterm/common/CMakeLists.txt
    trunk/teraterm/common/common_static.v16.vcxproj
    trunk/teraterm/common/common_static.v8.vcproj
    trunk/teraterm/teraterm/ttermpro.v16.vcxproj
    trunk/teraterm/teraterm/ttermpro.v8.vcproj
    trunk/teraterm/ttpcmn/CMakeLists.txt
    trunk/teraterm/ttpcmn/ttcmn.c
    trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj
    trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters
    trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj

Added Paths:
-----------
    trunk/teraterm/common/comportinfo.cpp
    trunk/teraterm/common/comportinfo.h
    trunk/teraterm/common/devpkey_teraterm.h
    trunk/teraterm/ttpcmn/ttcmn_cominfo.c

Removed Paths:
-------------
    trunk/teraterm/ttpcmn/comportinfo.cpp
    trunk/teraterm/ttpcmn/comportinfo.h
    trunk/teraterm/ttpcmn/devpkey_teraterm.h

-------------- next part --------------
Modified: trunk/teraterm/common/CMakeLists.txt
===================================================================
--- trunk/teraterm/common/CMakeLists.txt	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/common/CMakeLists.txt	2021-03-13 14:42:48 UTC (rev 9197)
@@ -1,7 +1,9 @@
-project(teraterm)
+set(PACKAGE_NAME "common_static")
 
+project(${PACKAGE_NAME})
+
 add_library(
-  common_static
+  ${PACKAGE_NAME}
   STATIC
   asprintf.cpp
   asprintf.h
@@ -9,6 +11,8 @@
   codeconv.h
   compat_win.cpp
   compat_win.h
+  comportinfo.cpp
+  comportinfo.h
   dlglib.c
   dlglib.h
   dlglib_cpp.cpp
@@ -40,7 +44,13 @@
   )
 
 target_include_directories(
-  common_static
+  ${PACKAGE_NAME}
   PRIVATE
   .
   )
+
+target_link_libraries(
+  ${PACKAGE_NAME}
+  PUBLIC
+  setupapi
+  )

Modified: trunk/teraterm/common/common_static.v16.vcxproj
===================================================================
--- trunk/teraterm/common/common_static.v16.vcxproj	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/common/common_static.v16.vcxproj	2021-03-13 14:42:48 UTC (rev 9197)
@@ -132,6 +132,7 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="asprintf.cpp" />
+    <ClCompile Include="comportinfo.cpp" />
     <ClCompile Include="dlglib.c" />
     <ClCompile Include="dlglib_cpp.cpp" />
     <ClCompile Include="dlglib_tmpl.cpp" />
@@ -154,6 +155,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="asprintf.h" />
+    <ClInclude Include="comportinfo.h" />
     <ClInclude Include="dlglib.h" />
     <ClInclude Include="fileread.h" />
     <ClInclude Include="layer_for_unicode_crt.h" />

Modified: trunk/teraterm/common/common_static.v8.vcproj
===================================================================
--- trunk/teraterm/common/common_static.v8.vcproj	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/common/common_static.v8.vcproj	2021-03-13 14:42:48 UTC (rev 9197)
@@ -189,6 +189,10 @@
 			>
 		</File>
 		<File
+			RelativePath=".\comportinfo.cpp"
+			>
+		</File>
+		<File
 			RelativePath=".\comportinfo.h"
 			>
 		</File>

Copied: trunk/teraterm/common/comportinfo.cpp (from rev 9196, trunk/teraterm/ttpcmn/comportinfo.cpp)
===================================================================
--- trunk/teraterm/common/comportinfo.cpp	                        (rev 0)
+++ trunk/teraterm/common/comportinfo.cpp	2021-03-13 14:42:48 UTC (rev 9197)
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2019- 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.
+ */
+
+#include <windows.h>
+#include <devguid.h>
+#include <setupapi.h>
+#include <stdio.h>
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#include <assert.h>
+
+#include "devpkey_teraterm.h"
+#include "ttlib.h"
+#include "codeconv.h"
+
+#include "comportinfo.h"
+
+typedef BOOL (WINAPI *TSetupDiGetDevicePropertyW)(
+	HDEVINFO DeviceInfoSet,
+	PSP_DEVINFO_DATA DeviceInfoData,
+	const DEVPROPKEY *PropertyKey,
+	DEVPROPTYPE *PropertyType,
+	PBYTE PropertyBuffer,
+	DWORD PropertyBufferSize,
+	PDWORD RequiredSize,
+	DWORD Flags
+	);
+
+typedef BOOL (WINAPI *TSetupDiGetDeviceRegistryPropertyW)(
+	HDEVINFO DeviceInfoSet,
+	PSP_DEVINFO_DATA DeviceInfoData,
+	DWORD Property,
+	PDWORD PropertyRegDataType,
+	PBYTE PropertyBuffer,
+	DWORD PropertyBufferSize,
+	PDWORD RequiredSize
+	);
+
+typedef LONG (WINAPI *TRegQueryValueExW)(
+	HKEY hKey,
+	LPCWSTR lpValueName,
+	LPDWORD lpReserved,
+	LPDWORD lpType,
+	LPBYTE lpData,
+	LPDWORD lpcbData
+	);
+
+static BOOL IsWindows9X()
+{
+	return !IsWindowsNTKernel();
+}
+
+static wchar_t *ToWcharA(const char *strA_ptr, size_t strA_len)
+{
+	size_t strW_len = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
+										  strA_ptr, (int)strA_len,
+										  NULL, 0);
+	wchar_t *strW_ptr = (wchar_t*)malloc(sizeof(wchar_t) * strW_len);
+	MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
+						strA_ptr, (int)strA_len,
+						strW_ptr, (int)strW_len);
+	return strW_ptr;
+}
+
+/**
+ *	\x83|\x81[\x83g\x96\xBC\x82\xF0\x8E擾
+ */
+static BOOL GetComPortName(HDEVINFO hDevInfo, SP_DEVINFO_DATA *DeviceInfoData, wchar_t **str)
+{
+	TRegQueryValueExW pRegQueryValueExW =
+		(TRegQueryValueExW)GetProcAddress(
+			GetModuleHandleA("ADVAPI32.dll"), "RegQueryValueExW");
+	DWORD byte_len;
+	DWORD dwType = REG_SZ;
+	HKEY hKey = SetupDiOpenDevRegKey(hDevInfo,
+									 DeviceInfoData,
+									 DICS_FLAG_GLOBAL,
+									 0, DIREG_DEV, KEY_READ);
+	if (hKey == NULL){
+		// \x83|\x81[\x83g\x96\xBC\x82\xAA\x8E擾\x82ł\xAB\x82Ȃ\xA2?
+		*str = NULL;
+		return FALSE;
+	}
+
+	wchar_t* port_name = NULL;
+	long r;
+	if (pRegQueryValueExW != NULL && !IsWindows9X()) {
+		// 9x\x8Cn\x82ł͂\xA4\x82܂\xAD\x93\xAE\x8D삵\x82Ȃ\xA2
+		r = pRegQueryValueExW(hKey, L"PortName", 0,
+			&dwType, NULL, &byte_len);
+		if (r != ERROR_FILE_NOT_FOUND) {
+			port_name = (wchar_t*)malloc(byte_len);
+			r = pRegQueryValueExW(hKey, L"PortName", 0,
+				&dwType, (LPBYTE)port_name, &byte_len);
+		}
+	} else {
+		r = RegQueryValueExA(hKey, "PortName", 0,
+								&dwType, (LPBYTE)NULL, &byte_len);
+		if (r != ERROR_FILE_NOT_FOUND) {
+			char* port_name_a = (char*)malloc(byte_len);
+			r = RegQueryValueExA(hKey, "PortName", 0,
+				&dwType, (LPBYTE)port_name_a, &byte_len);
+			if (r == ERROR_SUCCESS) {
+				port_name = ToWcharA(port_name_a, byte_len);
+			}
+			free(port_name_a);
+		}
+	}
+	if (r == ERROR_SUCCESS) {
+		RegCloseKey(hKey);
+		*str = port_name;
+		return TRUE;
+	}
+	else {
+		free(port_name);
+		*str = NULL;
+		return FALSE;
+	}
+}
+
+/**
+ *	\x83v\x83\x8D\x83p\x83e\x83B\x8E擾
+ *
+ * \x83\x8C\x83W\x83X\x83g\x83\x8A\x82̏ꏊ(Windows10)
+ * HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{GUID}\0000
+ *
+ */
+static void GetComPropartys(HDEVINFO hDevInfo, SP_DEVINFO_DATA *DeviceInfoData,
+							wchar_t **friendly_name, wchar_t **prop_str)
+{
+	typedef struct {
+		const wchar_t *name;
+		const DEVPROPKEY *PropertyKey;	// for SetupDiGetDeviceProperty() Vista+
+		DWORD Property;					// for SetupDiGetDeviceRegistryProperty() 2000+
+	} list_t;
+	static const list_t list[] = {
+		{ L"Device Friendly Name",
+		  &DEVPKEY_Device_FriendlyName,
+		  SPDRP_FRIENDLYNAME },
+		{ L"Device Instance ID",
+		  &DEVPKEY_Device_InstanceId,
+		  SPDRP_MAXIMUM_PROPERTY },
+		{ L"Device Manufacturer",
+		  &DEVPKEY_Device_Manufacturer,
+		  SPDRP_MFG },
+		{ L"Provider Name",
+		  &DEVPKEY_Device_DriverProvider,
+		  SPDRP_MAXIMUM_PROPERTY },
+		{ L"Driver Date",
+		  &DEVPKEY_Device_DriverDate,
+		  SPDRP_MAXIMUM_PROPERTY },
+		{ L"Driver Version",
+		  &DEVPKEY_Device_DriverVersion,
+		  SPDRP_MAXIMUM_PROPERTY },
+	};
+	TSetupDiGetDevicePropertyW pSetupDiGetDevicePropertyW =
+		(TSetupDiGetDevicePropertyW)GetProcAddress(
+			GetModuleHandleA("Setupapi.dll"),
+			"SetupDiGetDevicePropertyW");
+	TSetupDiGetDeviceRegistryPropertyW pSetupDiGetDeviceRegistryPropertyW =
+		(TSetupDiGetDeviceRegistryPropertyW)GetProcAddress(
+			GetModuleHandleA("Setupapi.dll"),
+			"SetupDiGetDeviceRegistryPropertyW");
+
+	*friendly_name = NULL;
+	*prop_str = NULL;
+	wchar_t *p_ptr = NULL;
+	size_t p_len = 0;
+	for (size_t i = 0; i < _countof(list); i++) {
+		const list_t *p = &list[i];
+		BOOL r;
+		wchar_t *prop = NULL;
+
+		if (pSetupDiGetDevicePropertyW != NULL) {
+			// vista\x88ȏ\xE3\x82͂\xB7\x82ׂĂ\xB1\x82\xB1\x82ɓ\xFC\x82\xE9
+			DEVPROPTYPE ulPropertyType;
+			DWORD size;
+			r = pSetupDiGetDevicePropertyW(hDevInfo, DeviceInfoData, p->PropertyKey,
+										   &ulPropertyType, NULL, 0, &size, 0);
+			if (r == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+				BYTE *buf = (BYTE *)malloc(size);
+
+				r = pSetupDiGetDevicePropertyW(hDevInfo, DeviceInfoData, p->PropertyKey,
+											   &ulPropertyType, buf, size, &size, 0);
+				if (ulPropertyType == DEVPROP_TYPE_STRING) {
+					// \x95\xB6\x8E\x9A\x97\xF1\x82Ȃ̂ł\xBB\x82̂܂\xDC
+					prop = (wchar_t *)buf;
+				} else if (ulPropertyType ==  DEVPROP_TYPE_FILETIME) {
+					// buf = FILETIME \x8D\\x91\xA2\x91̂\xCC8\x83o\x83C\x83g
+					SYSTEMTIME stFileTime = {};
+					FileTimeToSystemTime((FILETIME *)buf , &stFileTime);
+					int wbuflen = 64;
+					int buflen = sizeof(wchar_t) * wbuflen;
+					prop = (wchar_t *)malloc(buflen);
+					_snwprintf_s(prop, wbuflen, _TRUNCATE, L"%d-%d-%d",
+								 stFileTime.wMonth, stFileTime.wDay, stFileTime.wYear
+						);
+					free(buf);
+				}
+				else {
+					assert(FALSE);
+				}
+			}
+		} else if (p->PropertyKey == &DEVPKEY_Device_InstanceId) {
+			// InstanceId\x82\xCDA\x8Cn\x82Ō\x88\x82ߑł\xBF
+			DWORD len_a;
+			r = SetupDiGetDeviceInstanceIdA(hDevInfo,
+											DeviceInfoData,
+											NULL, 0,
+											&len_a);
+			if (r == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+				char *str_instance_a = (char *)malloc(len_a);
+				r = SetupDiGetDeviceInstanceIdA(hDevInfo,
+												DeviceInfoData,
+												str_instance_a, len_a,
+												&len_a);
+				if (r != FALSE) {
+					prop = ToWcharA(str_instance_a, len_a);
+				}
+				free(str_instance_a);
+			}
+		} else if (p->Property == SPDRP_MAXIMUM_PROPERTY) {
+			// SetupDiGetDeviceRegistryProperty() \x8Cn\x82ɂ͑\xB6\x8D݂\xB5\x82Ȃ\xA2\x83v\x83\x8D\x83p\x83e\x83B
+			r = FALSE;
+		} else if (pSetupDiGetDeviceRegistryPropertyW != NULL && !IsWindows9X()) {
+			// 9x\x8Cn\x82ł͂\xA4\x82܂\xAD\x93\xAE\x8D삵\x82Ȃ\xA2
+			DWORD dwPropType;
+			DWORD size;
+			r = pSetupDiGetDeviceRegistryPropertyW(hDevInfo,
+												   DeviceInfoData,
+												   p->Property,
+												   &dwPropType,
+												   NULL, 0,
+												   &size);
+			if (r == FALSE) {
+				prop = (wchar_t *)malloc(size);
+				r = pSetupDiGetDeviceRegistryPropertyW(hDevInfo,
+													   DeviceInfoData,
+													   p->Property,
+													   &dwPropType,
+													   (LPBYTE)prop, size,
+													   &size);
+			}
+		} else {
+			DWORD dwPropType;
+			DWORD len_a;
+			r = SetupDiGetDeviceRegistryPropertyA(hDevInfo,
+												  DeviceInfoData,
+												  p->Property,
+												  &dwPropType,
+												  NULL, 0,
+												  &len_a);
+			if (r != FALSE) {
+				char *prop_a = (char *)malloc(len_a);
+				r = SetupDiGetDeviceRegistryPropertyA(hDevInfo,
+													  DeviceInfoData,
+													  p->Property,
+													  &dwPropType,
+													  (PBYTE)prop_a, len_a,
+													  &len_a);
+				if (r != FALSE) {
+					prop = ToWcharA(prop_a, len_a);
+				}
+				free(prop_a);
+			}
+		}
+
+		// prop
+		if (r != FALSE && prop != NULL) {
+			if (i == 0) {
+				// \x83t\x83\x8C\x83\x93\x83h\x83\x8A\x81[\x83l\x81[\x83\x80\x82̂\xDD
+				*friendly_name = prop;
+			}
+
+			// \x83t\x83\x8C\x83\x93\x83h\x83\x8A\x81[\x83l\x81[\x83\x80\x82\xE0\x8A܂߂\xBD\x82\xB7\x82ׂẴv\x83\x8D\x83p\x83e\x83B
+			const size_t name_len = wcslen(p->name);
+			const size_t prop_len = wcslen(prop);
+
+			if (p_len == 0) {
+				p_len = p_len + (name_len + 2 + prop_len + 1);
+				p_ptr = (wchar_t *)malloc(sizeof(wchar_t) * p_len);
+				p_ptr[0] = L'\0';
+			}
+			else {
+				p_len = p_len + (2 + name_len + 2 + prop_len);
+				p_ptr = (wchar_t *)realloc(p_ptr, sizeof(wchar_t) * p_len);
+				wcscat_s(p_ptr, p_len, L"\r\n");
+			}
+			wcscat_s(p_ptr, p_len, p->name);
+			wcscat_s(p_ptr, p_len, L": ");
+			wcscat_s(p_ptr, p_len, prop);
+
+			if (i != 0) {
+				free(prop);
+			}
+		}
+	}
+
+	*prop_str = p_ptr;
+}
+
+/* \x94z\x97\xF1\x83\\x81[\x83g\x97p */
+static int sort_sub(const void *a_, const void *b_)
+{
+	const ComPortInfo_t *a = (ComPortInfo_t *)a_;
+	const ComPortInfo_t *b = (ComPortInfo_t *)b_;
+	if (wcsncmp(a->port_name, L"COM", 3) == 0 &&
+		wcsncmp(b->port_name, L"COM", 3) == 0) {
+		int a_no = _wtoi(&a->port_name[3]);
+		int b_no = _wtoi(&b->port_name[3]);
+		return a_no > b_no;
+	}
+	return wcscmp(a->port_name, b->port_name);
+}
+
+/**
+ *	\x8E\xC0\x8DۂɃf\x83o\x83C\x83X\x82\xF0\x83I\x81[\x83v\x83\x93\x82\xB7\x82邱\x82Ƃ\xC5com\x83|\x81[\x83g\x8C\x9F\x8Fo
+ */
+static ComPortInfo_t *ComPortInfoGetByCreatefile(int *count)
+{
+	const int ComPortMax = 256;
+	int comport_count = 0;
+	ComPortInfo_t *comport_infos = NULL;
+	for (int i = 1; i <= ComPortMax; i++) {
+		char buf[12];  // \\.\COMxxxx + NULL
+		_snprintf_s(buf, sizeof(buf), _TRUNCATE, "\\\\.\\COM%d", i);
+		HANDLE h = CreateFileA(buf, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+		if (h != INVALID_HANDLE_VALUE) {
+			CloseHandle(h);
+
+			comport_count++;
+			comport_infos = (ComPortInfo_t *)realloc(comport_infos, sizeof(ComPortInfo_t) * comport_count);
+
+			ComPortInfo_t *p = &comport_infos[comport_count - 1];
+			wchar_t com_name[12];
+			_snwprintf_s(com_name, _countof(com_name), _TRUNCATE, L"COM%d", i);
+			p->port_name = _wcsdup(com_name);  // COM\x83|\x81[\x83g\x96\xBC
+			p->port_no = i;  // COM\x83|\x81[\x83g\x94ԍ\x86
+			p->friendly_name = NULL;
+			p->property = NULL;
+		}
+	}
+
+	*count = comport_count;
+	return comport_infos;
+}
+
+static ComPortInfo_t *ComPortInfoGetByGetSetupAPI(int *count)
+{
+	int comport_count = 0;
+	ComPortInfo_t *comport_infos = NULL;
+	const GUID *pClassGuid = &GUID_DEVCLASS_PORTS;
+
+	// List all connected serial devices
+	HDEVINFO hDevInfo = SetupDiGetClassDevsA(pClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
+	if (hDevInfo == INVALID_HANDLE_VALUE) {
+		return NULL;
+	}
+
+	// Find the ones that are driverless
+	for (int i = 0; ; i++) {
+		SP_DEVINFO_DATA DeviceInfoData = {};
+		DeviceInfoData.cbSize = sizeof (DeviceInfoData);
+		if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData)) {
+			break;
+		}
+
+		wchar_t *port_name;
+		if (!GetComPortName(hDevInfo, &DeviceInfoData, &port_name)) {
+			continue;
+		}
+		int port_no = 0;
+		if (wcsncmp(port_name, L"COM", 3) == 0) {
+			port_no = _wtoi(port_name+3);
+		}
+
+		// \x8F\xEE\x95\xF1\x8E擾
+		wchar_t *str_friendly_name = NULL;
+		wchar_t *str_prop = NULL;
+		GetComPropartys(hDevInfo, &DeviceInfoData, &str_friendly_name, &str_prop);
+
+		comport_count++;
+		comport_infos = (ComPortInfo_t *)realloc(comport_infos,
+								sizeof(ComPortInfo_t) * comport_count);
+		ComPortInfo_t *p = &comport_infos[comport_count-1];
+		p->port_name = port_name;  // COM\x83|\x81[\x83g\x96\xBC
+		p->port_no = port_no;  // COM\x83|\x81[\x83g\x94ԍ\x86
+		p->friendly_name = str_friendly_name;  // Device Description
+		p->property = str_prop;  // \x91S\x8Fڍ׏\xEE\x95\xF1
+	}
+
+	/* \x83|\x81[\x83g\x96\xBC\x8F\x87\x82ɕ\xC0\x82ׂ\xE9 */
+	qsort(comport_infos, comport_count, sizeof(comport_infos[0]), sort_sub);
+
+	*count = comport_count;
+	return comport_infos;
+}
+
+/**
+ *	com\x83|\x81[\x83g\x82̏\xEE\x95\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9
+ *
+ *	@param[out]	count		\x8F\xEE\x95\xF1\x90\x94(0\x82̂Ƃ\xABcom\x83|\x81[\x83g\x82Ȃ\xB5)
+ *	@return		\x8F\xEE\x95\xF1\x82ւ̃|\x83C\x83\x93\x83^(\x94z\x97\xF1)\x81A\x83|\x81[\x83g\x94ԍ\x86\x82̏\xAC\x82\xB3\x82\xA2\x8F\x87
+ *				NULL\x82̂Ƃ\xABcom\x83|\x81[\x83g\x82Ȃ\xB5
+ *				\x8Eg\x97p\x8C\xE3ComPortInfoFree()\x82\xF0\x8CĂԂ\xB1\x82\xC6
+ */
+ComPortInfo_t *ComPortInfoGet(int *count, const char *lang)
+{
+	OSVERSIONINFO osvi;
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+	GetVersionEx(&osvi);
+	bool is_setupapi_supported = true;
+	if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) {
+		// Windows 95
+		is_setupapi_supported = false;
+	}
+	else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 4) {
+		// Windows NT4.0
+		is_setupapi_supported = false;
+	}
+
+	if (is_setupapi_supported) {
+		return ComPortInfoGetByGetSetupAPI(count);
+	}
+	else {
+		// setupapi \x82̓\xAE\x8D삪\x8D\xA1\x88\xEA\x82‚\xCCOS\x82̂Ƃ\xAB
+		return ComPortInfoGetByCreatefile(count);
+	}
+}
+
+/**
+ *	com\x83|\x81[\x83g\x82̏\xEE\x95\xF1\x82\xF0\x83\x81\x83\x82\x83\x8A\x82\xF0\x94j\x8A\xFC\x82\xB7\x82\xE9
+ */
+void ComPortInfoFree(ComPortInfo_t *info, int count)
+{
+	for (int i=0; i< count; i++) {
+		ComPortInfo_t *p = &info[i];
+		free(p->port_name);
+		free(p->friendly_name);
+		free(p->property);
+	}
+	free(info);
+}

Copied: trunk/teraterm/common/comportinfo.h (from rev 9196, trunk/teraterm/ttpcmn/comportinfo.h)
===================================================================
--- trunk/teraterm/common/comportinfo.h	                        (rev 0)
+++ trunk/teraterm/common/comportinfo.h	2021-03-13 14:42:48 UTC (rev 9197)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019- 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	wchar_t *port_name;			// \x83|\x81[\x83g\x96\xBC
+	int port_no;				// 0..128(9x)/255(xp)
+	wchar_t *friendly_name;		// \x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x8Fꍇ\x82\xCD NULL
+	wchar_t *property;			// \x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x8Fꍇ\x82\xCD NULL
+} ComPortInfo_t;
+
+ComPortInfo_t *ComPortInfoGet(int *count, const char *lang);
+void ComPortInfoFree(ComPortInfo_t *info, int count);
+
+#ifdef __cplusplus
+}
+#endif

Copied: trunk/teraterm/common/devpkey_teraterm.h (from rev 9196, trunk/teraterm/ttpcmn/devpkey_teraterm.h)
===================================================================
--- trunk/teraterm/common/devpkey_teraterm.h	                        (rev 0)
+++ trunk/teraterm/common/devpkey_teraterm.h	2021-03-13 14:42:48 UTC (rev 9197)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019- 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.
+ */
+
+#pragma once
+
+/*
+ * Visual Studio 2005\x82Ńr\x83\x8B\x83h\x82\xF0\x92ʂ\xB7\x82\xBD\x82߂ɂ͉\xBA\x8BL\x82̒\xE8\x8B`\x82\xAA\x95K\x97v\x81B
+ * Visual Studio 2019\x82ł͕s\x97v\x81B
+ */
+#if _MSC_VER == 1400 && !defined(DEVPROPKEY_DEFINED)
+typedef ULONG DEVPROPTYPE, *PDEVPROPTYPE;
+
+typedef GUID  DEVPROPGUID, *PDEVPROPGUID;
+typedef ULONG DEVPROPID,   *PDEVPROPID;
+
+typedef struct _DEVPROPKEY {
+    DEVPROPGUID fmtid;
+    DEVPROPID   pid;
+} DEVPROPKEY, *PDEVPROPKEY;
+#endif
+
+#undef DEFINE_DEVPROPKEY
+#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }, pid }
+
+/*
+ * Platform SDK\x82\xCCdevpkey.h\x82\xE6\x82\xE8
+ */
+
+DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);    // DEVPROP_TYPE_STRING
+DEFINE_DEVPROPKEY(DEVPKEY_Device_InstanceId,             0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 256);   // DEVPROP_TYPE_STRING
+DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13);    // DEVPROP_TYPE_STRING
+DEFINE_DEVPROPKEY(DEVPKEY_Device_DriverProvider,           0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 9);     // DEVPROP_TYPE_STRING
+DEFINE_DEVPROPKEY(DEVPKEY_Device_DriverDate,               0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 2);     // DEVPROP_TYPE_FILETIME
+DEFINE_DEVPROPKEY(DEVPKEY_Device_DriverVersion,            0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 3);     // DEVPROP_TYPE_STRING
+

Modified: trunk/teraterm/teraterm/ttermpro.v16.vcxproj
===================================================================
--- trunk/teraterm/teraterm/ttermpro.v16.vcxproj	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/teraterm/ttermpro.v16.vcxproj	2021-03-13 14:42:48 UTC (rev 9197)
@@ -81,7 +81,7 @@
       <AdditionalIncludeDirectories>$(SolutionDir)common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>onig_sd.lib;comctl32.lib;ws2_32.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>onig_sd.lib;comctl32.lib;ws2_32.lib;imagehlp.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>$(SolutionDir)..\libs\oniguruma\src;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <DelayLoadDLLs>imagehlp.dll;user32.dll;shell32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -122,7 +122,7 @@
       <AdditionalIncludeDirectories>$(SolutionDir)common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>onig_s.lib;comctl32.lib;ws2_32.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>onig_s.lib;comctl32.lib;ws2_32.lib;imagehlp.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>$(SolutionDir)..\libs\oniguruma\src;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <DelayLoadDLLs>imagehlp.dll;user32.dll;shell32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
@@ -311,4 +311,4 @@
       <UserProperties RESOURCE_FILE="ttermpro.rc" />
     </VisualStudio>
   </ProjectExtensions>
-</Project>
+</Project>
\ No newline at end of file

Modified: trunk/teraterm/teraterm/ttermpro.v8.vcproj
===================================================================
--- trunk/teraterm/teraterm/ttermpro.v8.vcproj	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/teraterm/ttermpro.v8.vcproj	2021-03-13 14:42:48 UTC (rev 9197)
@@ -71,7 +71,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="onig_sd.lib comctl32.lib ws2_32.lib imagehlp.lib user32.lib gdi32.lib SHELL32.lib comctl32.lib comdlg32.lib ole32.lib ADVAPI32.lib OleAut32.lib"
+				AdditionalDependencies="onig_sd.lib comctl32.lib ws2_32.lib imagehlp.lib user32.lib gdi32.lib SHELL32.lib comdlg32.lib ole32.lib ADVAPI32.lib OleAut32.lib setupapi.lib"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
 				AdditionalLibraryDirectories="$(SolutionDir)..\libs\oniguruma\src;$(OutDir)"
@@ -164,7 +164,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="onig_s.lib comctl32.lib ws2_32.lib imagehlp.lib user32.lib gdi32.lib SHELL32.lib comctl32.lib comdlg32.lib ole32.lib ADVAPI32.lib OleAut32.lib"
+				AdditionalDependencies="onig_s.lib comctl32.lib ws2_32.lib imagehlp.lib user32.lib gdi32.lib SHELL32.lib comdlg32.lib ole32.lib ADVAPI32.lib OleAut32.lib setupapi.lib"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
 				AdditionalLibraryDirectories="$(SolutionDir)..\libs\oniguruma\src;$(OutDir)"

Modified: trunk/teraterm/ttpcmn/CMakeLists.txt
===================================================================
--- trunk/teraterm/ttpcmn/CMakeLists.txt	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/CMakeLists.txt	2021-03-13 14:42:48 UTC (rev 9197)
@@ -9,10 +9,7 @@
   language.h
   ttcmn.c
   ttcmn_notify.cpp
-  comportinfo.cpp
-  comportinfo.h
-  comportinfo.cpp
-  devpkey_teraterm.h
+  ttcmn_cominfo.c
   ttpcmn-version.rc
   ttpcmn.def
   ${COMMON_SRC}

Deleted: trunk/teraterm/ttpcmn/comportinfo.cpp
===================================================================
--- trunk/teraterm/ttpcmn/comportinfo.cpp	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/comportinfo.cpp	2021-03-13 14:42:48 UTC (rev 9197)
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2019- 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.
- */
-
-// for comportinfo_test
-//#define TEST_FOR_NT
-//#define TEST_FOR_9X
-
-#include <windows.h>
-#include <devguid.h>
-#include <setupapi.h>
-#include <tchar.h>
-#include <stdio.h>
-#define _CRTDBG_MAP_ALLOC
-#include <crtdbg.h>
-
-#include "devpkey_teraterm.h"
-#include "ttlib.h"
-#include "codeconv.h"
-
-#define DllExport __declspec(dllexport)
-#include "comportinfo.h"
-
-typedef BOOL (WINAPI *TSetupDiGetDevicePropertyW)(
-	HDEVINFO DeviceInfoSet,
-	PSP_DEVINFO_DATA DeviceInfoData,
-	const DEVPROPKEY *PropertyKey,
-	DEVPROPTYPE *PropertyType,
-	PBYTE PropertyBuffer,
-	DWORD PropertyBufferSize,
-	PDWORD RequiredSize,
-	DWORD Flags
-	);
-
-typedef BOOL (WINAPI *TSetupDiGetDeviceRegistryPropertyW)(
-	HDEVINFO DeviceInfoSet,
-	PSP_DEVINFO_DATA DeviceInfoData,
-	DWORD Property,
-	PDWORD PropertyRegDataType,
-	PBYTE PropertyBuffer,
-	DWORD PropertyBufferSize,
-	PDWORD RequiredSize
-	);
-
-typedef LONG (WINAPI *TRegQueryValueExW)(
-	HKEY hKey,
-	LPCWSTR lpValueName,
-	LPDWORD lpReserved,
-	LPDWORD lpType,
-	LPBYTE lpData,
-	LPDWORD lpcbData
-	);
-
-static BOOL IsWindows9X()
-{
-	return !IsWindowsNTKernel();
-}
-
-/**
- *	\x83|\x81[\x83g\x96\xBC\x82\xF0\x8E擾
- */
-static BOOL GetComPortName(HDEVINFO hDevInfo, SP_DEVINFO_DATA *DeviceInfoData, wchar_t **str)
-{
-	TRegQueryValueExW pRegQueryValueExW =
-		(TRegQueryValueExW)GetProcAddress(
-			GetModuleHandleA("ADVAPI32.dll"), "RegQueryValueExW");
-	DWORD byte_len;
-	DWORD dwType = REG_SZ;
-	HKEY hKey = SetupDiOpenDevRegKey(hDevInfo,
-									 DeviceInfoData,
-									 DICS_FLAG_GLOBAL,
-									 0, DIREG_DEV, KEY_READ);
-	if (hKey == NULL){
-		// \x83|\x81[\x83g\x96\xBC\x82\xAA\x8E擾\x82ł\xAB\x82Ȃ\xA2?
-		*str = NULL;
-		return FALSE;
-	}
-
-	wchar_t* port_name = NULL;
-	long r;
-	if (pRegQueryValueExW != NULL && !IsWindows9X()) {
-		// 9x\x8Cn\x82ł͂\xA4\x82܂\xAD\x93\xAE\x8D삵\x82Ȃ\xA2
-		r = pRegQueryValueExW(hKey, L"PortName", 0,
-			&dwType, NULL, &byte_len);
-		port_name = (wchar_t* )malloc(byte_len);
-		r = pRegQueryValueExW(hKey, L"PortName", 0,
-								&dwType, (LPBYTE)port_name, &byte_len);
-	} else {
-		r = RegQueryValueExA(hKey, "PortName", 0,
-								&dwType, (LPBYTE)NULL, &byte_len);
-		char *port_name_a = (char *)malloc(byte_len);
-		r = RegQueryValueExA(hKey, "PortName", 0,
-								&dwType, (LPBYTE)port_name_a, &byte_len);
-		if (r == ERROR_SUCCESS) {
-			size_t len_w = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
-											   port_name_a, byte_len,
-											   NULL, 0);
-			port_name = (wchar_t *)malloc(sizeof(wchar_t) * len_w);
-			MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
-								port_name_a, byte_len,
-								port_name, (int)len_w);
-		}
-		free(port_name_a);
-	}
-	RegCloseKey(hKey);
-	if (r != ERROR_SUCCESS) {
-		free(port_name);
-		*str = NULL;
-		return FALSE;
-	}
-	*str = port_name;
-	return TRUE;
-}
-
-/**
- *	\x83v\x83\x8D\x83p\x83e\x83B\x8E擾
- *
- * \x83\x8C\x83W\x83X\x83g\x83\x8A\x82̏ꏊ(Windows10)
- * HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{GUID}\0000
- *
- */
-static void GetComPropartys(HDEVINFO hDevInfo, SP_DEVINFO_DATA *DeviceInfoData, const char *lang,
-							wchar_t **friendly_name, wchar_t **str)
-{
-	const char *FriendlyNameString = "FRIENDLY_NAME";
-	const char *DriverDateString = "DRIVER_DATE";
-	typedef struct {
-		const wchar_t *name;  // \x96{\x8A֐\x94\x93\xE0\x82Ŏg\x82\xA4
-		const char *key;      // \x96{\x8A֐\x94\x93\xE0\x82Ŏg\x82\xA4
-		const DEVPROPKEY *PropertyKey; // \x83\x8C\x83W\x83X\x83g\x83\x8A\x8E擾\x82Ɏg\x82\xA4\x82̂͂\xB1\x82\xEA\x82̂\xDD
-		DWORD Property;       // \x96\xA2\x8Eg\x97p
-	} list_t;
-	static const list_t list[] = {
-		{ L"Device Friendly Name",
-		  FriendlyNameString,
-		  &DEVPKEY_Device_FriendlyName,
-		  SPDRP_FRIENDLYNAME },
-		{ L"Device Instance ID",
-		  "DEVICE_INSTANCE_ID",
-		  &DEVPKEY_Device_InstanceId,
-		  SPDRP_MAXIMUM_PROPERTY },
-		{ L"Device Manufacturer",
-		  "DEVICE_MANUFACTURER",
-		  &DEVPKEY_Device_Manufacturer,
-		  SPDRP_MFG },
-		{ L"Provider Name",
-		  "PROVIDER_NAME",
-		  &DEVPKEY_Device_DriverProvider,
-		  SPDRP_MAXIMUM_PROPERTY },
-		{ L"Driver Date",
-		  DriverDateString,
-		  &DEVPKEY_Device_DriverDate,
-		  SPDRP_MAXIMUM_PROPERTY },
-		{ L"Driver Version",
-		  "DRIVER_VERSION",
-		  &DEVPKEY_Device_DriverVersion,
-		  SPDRP_MAXIMUM_PROPERTY },
-	};
-	TSetupDiGetDevicePropertyW pSetupDiGetDevicePropertyW =
-		(TSetupDiGetDevicePropertyW)GetProcAddress(
-			GetModuleHandleA("Setupapi.dll"),
-			"SetupDiGetDevicePropertyW");
-	TSetupDiGetDeviceRegistryPropertyW pSetupDiGetDeviceRegistryPropertyW =
-		(TSetupDiGetDeviceRegistryPropertyW)GetProcAddress(
-			GetModuleHandleA("Setupapi.dll"),
-			"SetupDiGetDeviceRegistryPropertyW");
-
-	wchar_t *s = _wcsdup(L"");
-	size_t len = 0;
-	for (size_t i = 0; i < _countof(list); i++) {
-		const list_t *p = &list[i];
-		BOOL r;
-		wchar_t *str_prop = NULL;
-		DWORD size;
-
-		if (pSetupDiGetDevicePropertyW != NULL) {
-			DEVPROPTYPE ulPropertyType;
-			pSetupDiGetDevicePropertyW(hDevInfo, DeviceInfoData, p->PropertyKey,
-									   &ulPropertyType, NULL, 0, &size, 0);
-			str_prop = (wchar_t *)malloc(size);
-			r = pSetupDiGetDevicePropertyW(hDevInfo, DeviceInfoData, p->PropertyKey,
-										   &ulPropertyType, (PBYTE)str_prop, size, &size, 0);
-		} else if (p->PropertyKey == &DEVPKEY_Device_InstanceId) {
-			// InstanceId\x82\xCDA\x8Cn\x82Ō\x88\x82ߑł\xBF
-			DWORD len_a;
-			SetupDiGetDeviceInstanceIdA(hDevInfo,
-										DeviceInfoData,
-										NULL, 0,
-										&len_a);
-			char *str_instance_a = (char *)malloc(len_a);
-			r = SetupDiGetDeviceInstanceIdA(hDevInfo,
-											DeviceInfoData,
-											str_instance_a, len_a,
-											&len_a);
-			if (r != FALSE) {
-				int len_w = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
-												str_instance_a, len_a,
-												NULL, 0);
-				str_prop = (wchar_t *)malloc(sizeof(wchar_t) * len_w);
-				MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
-									str_instance_a, len_a,
-									str_prop, (int)len_w);
-			}
-			free(str_instance_a);
-		} else if (p->Property == SPDRP_MAXIMUM_PROPERTY) {
-			r = FALSE;
-		} else if (pSetupDiGetDeviceRegistryPropertyW != NULL && !IsWindows9X()) {
-			// 9x\x8Cn\x82ł͂\xA4\x82܂\xAD\x93\xAE\x8D삵\x82Ȃ\xA2
-			DWORD dwPropType;
-			r = pSetupDiGetDeviceRegistryPropertyW(hDevInfo,
-												   DeviceInfoData,
-												   p->Property,
-												   &dwPropType,
-												   NULL, 0,
-												   &size);
-			str_prop = (wchar_t *)malloc(size);
-			r = pSetupDiGetDeviceRegistryPropertyW(hDevInfo,
-												   DeviceInfoData,
-												   p->Property,
-												   &dwPropType,
-												   (LPBYTE)str_prop, size,
-												   &size);
-		} else {
-			DWORD dwPropType;
-			DWORD len_a;
-			r = SetupDiGetDeviceRegistryPropertyA(hDevInfo,
-												  DeviceInfoData,
-												  p->Property,
-												  &dwPropType,
-												  NULL, 0,
-												  &len_a);
-			char *str_prop_a = (char *)malloc(len_a);
-			r = SetupDiGetDeviceRegistryPropertyA(hDevInfo,
-												  DeviceInfoData,
-												  p->Property,
-												  &dwPropType,
-												  (PBYTE)str_prop_a, len_a,
-												  &len_a);
-			if (r != FALSE) {
-				int len_w = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
-												str_prop_a, len_a,
-												NULL, 0);
-				str_prop = (wchar_t *)malloc(sizeof(wchar_t) * len_w);
-				MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
-									str_prop_a, len_a,
-									str_prop, (int)len_w);
-			}
-			free(str_prop_a);
-		}
-		if (r != FALSE) {
-			/* Driver Date\x82\xCD DEVPROP_TYPE_FILETIME \x82ł\xA0\x82邽\x82߁A
-			 * FILETIME \x8D\\x91\xA2\x91̂\xCC8\x83o\x83C\x83g\x82ŕԂ邽\x82߁ASYSTEMTIME \x82ɕϊ\xB7\x82\xB7\x82\xE9\x81B
-			 */
-			if (strcmp(list[i].key, DriverDateString) == 0) {
-				FILETIME ftFileTime;
-				SYSTEMTIME stFileTime;
-				int wbuflen = 64;
-				int buflen = sizeof(wchar_t) * wbuflen;
-
-				ZeroMemory(&ftFileTime, sizeof(FILETIME));
-				if (sizeof(ftFileTime) >= size) {
-					// str_prop\x82\xCDsize\x83o\x83C\x83g
-					memcpy(&ftFileTime, str_prop, size);  
-				}
-				ZeroMemory(&stFileTime, sizeof(SYSTEMTIME));
-				FileTimeToSystemTime(&ftFileTime , &stFileTime);
-				str_prop = (wchar_t *)realloc(str_prop, buflen);
-				_snwprintf_s(str_prop, wbuflen, _TRUNCATE, L"%d-%d-%d",
-					stFileTime.wMonth, stFileTime.wDay, stFileTime.wYear				
-					);
-			}
-
-			size_t name_len = wcslen(p->name);
-			size_t prop_len = wcslen(str_prop);
-			len = len + (name_len + (i==0?1:2) + 2 + 2 + prop_len);
-			s = (wchar_t *)realloc(s, sizeof(wchar_t) * len);
-			if (i != 0) 
-				wcscat_s(s, len, L"\r\n");
-			wcscat_s(s, len, p->name);
-			wcscat_s(s, len, L": ");
-			wcscat_s(s, len, str_prop);
-		}
-
-		if (strcmp(list[i].key, FriendlyNameString) == 0) {
-			// str_prop\x82̃\x81\x83\x82\x83\x8A\x82\xCD ComPortInfoFree() \x82ʼn\xF0\x95\xFA\x82\xB3\x82\xEA\x82\xE9\x81B
-			*friendly_name = str_prop;
-
-		} else {
-			// s \x82ɃR\x83s\x81[\x82\xB5\x82\xBD\x82̂\xC5str_prop\x82̃\x81\x83\x82\x83\x8A\x82͕s\x97v\x82ƂȂ\xE9\x81B
-			if (str_prop != NULL) {
-				free(str_prop);
-			}
-		}
-	}
-
-	*str = s;
-}
-
-/* \x94z\x97\xF1\x83\\x81[\x83g\x97p */
-static int sort_sub(const void *a_, const void *b_)
-{
-	const ComPortInfo_t *a = (ComPortInfo_t *)a_;
-	const ComPortInfo_t *b = (ComPortInfo_t *)b_;
-	if (wcsncmp(a->port_name, L"COM", 3) == 0 &&
-		wcsncmp(b->port_name, L"COM", 3) == 0) {
-		int a_no = _wtoi(&a->port_name[3]);
-		int b_no = _wtoi(&b->port_name[3]);
-		return a_no > b_no;
-	}
-	return wcscmp(a->port_name, b->port_name);
-}
-
-/**
- *	com\x83|\x81[\x83g\x82̏\xEE\x95\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9
- *
- *	@param[out]	count	 	\x8F\xEE\x95\xF1\x90\x94(0\x82̂Ƃ\xABcom\x83|\x81[\x83g\x82Ȃ\xB5)
- *	@return		\x8F\xEE\x95\xF1\x82ւ̃|\x83C\x83\x93\x83^(\x94z\x97\xF1)\x81A\x83|\x81[\x83g\x94ԍ\x86\x82̏\xAC\x82\xB3\x82\xA2\x8F\x87
- *				NULL\x82̂Ƃ\xABcom\x83|\x81[\x83g\x82Ȃ\xB5
- *				\x8Eg\x97p\x8C\xE3ComPortInfoFree()\x82\xF0\x8CĂԂ\xB1\x82\xC6
- */
-ComPortInfo_t * WINAPI ComPortInfoGet(int *count, const char *lang)
-{
-	int comport_count = 0;
-	ComPortInfo_t *comport_infos = NULL;
-	const GUID *pClassGuid = &GUID_DEVCLASS_PORTS;
-
-	// List all connected serial devices
-	HDEVINFO hDevInfo = SetupDiGetClassDevsA(pClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
-	if (hDevInfo == INVALID_HANDLE_VALUE) {
-		*count = 0;
-		return NULL;
-	}
-
-	// Find the ones that are driverless
-	for (int i = 0; ; i++) {
-		SP_DEVINFO_DATA DeviceInfoData;
-		DeviceInfoData.cbSize = sizeof (DeviceInfoData);
-		if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
-			break;
-
-		// \x83|\x81[\x83g\x96\xBC\x8E擾 ("COM1"\x82Ȃ\xC7)
-		wchar_t *port_name;
-		if (!GetComPortName(hDevInfo, &DeviceInfoData, &port_name)) {
-			continue;
-		}
-		int port_no = 0;
-		if (wcsncmp(port_name, L"COM", 3) == 0) {
-			port_no = _wtoi(port_name+3);
-		}
-
-		// \x8F\xEE\x95\xF1\x8E擾
-		wchar_t *str_friendly_name = NULL;
-		wchar_t *str_prop = NULL;
-		GetComPropartys(hDevInfo, &DeviceInfoData, lang, &str_friendly_name, &str_prop);
-
-		comport_count++;
-		comport_infos = (ComPortInfo_t *)realloc(comport_infos,
-								sizeof(ComPortInfo_t) * comport_count);
-		ComPortInfo_t *p = &comport_infos[comport_count-1];
-		p->port_name = port_name;  // COM\x83|\x81[\x83g\x96\xBC
-		p->port_no = port_no;  // COM\x83|\x81[\x83g\x94ԍ\x86
-		p->friendly_name = str_friendly_name;  // Device Description
-		p->property = str_prop;  // \x91S\x8Fڍ׏\xEE\x95\xF1
-
-#if 0
-		{
-		char *a, *b, *c;
-		a = ToCharW(p->port_name);
-		b = ToCharW(p->friendly_name);
-		c = ToCharW(p->property);
-		OutputDebugPrintf("%s: [%s] [%d] [%s] [%s]\n", __FUNCTION__,
-			a, p->port_no, b, c
-			);
-		free(a);
-		free(b);
-		free(c);
-		}
-#endif
-	}
-
-	/* \x83|\x81[\x83g\x96\xBC\x8F\x87\x82ɕ\xC0\x82ׂ\xE9 */
-	qsort(comport_infos, comport_count, sizeof(comport_infos[0]), sort_sub);
-
-	*count = comport_count;
-	return comport_infos;
-}
-
-void WINAPI ComPortInfoFree(ComPortInfo_t *info, int count)
-{
-	for (int i=0; i< count; i++) {
-		ComPortInfo_t *p = &info[i];
-		free(p->port_name);
-		free(p->friendly_name);
-		free(p->property);
-	}
-	free(info);
-}

Deleted: trunk/teraterm/ttpcmn/comportinfo.h
===================================================================
--- trunk/teraterm/ttpcmn/comportinfo.h	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/comportinfo.h	2021-03-13 14:42:48 UTC (rev 9197)
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2019- 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.
- */
-
-#pragma once
-
-#include <windows.h>	// for WORD
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(DllExport)
-#define DllExport __declspec(dllimport)
-#endif
-
-typedef struct {
-	wchar_t *port_name;			// \x83|\x81[\x83g\x96\xBC
-	int port_no;				// 0..128(9x)/255(xp)
-	wchar_t *friendly_name;
-	wchar_t *property;
-} ComPortInfo_t;
-
-DllExport ComPortInfo_t * WINAPI ComPortInfoGet(int *count, const char *lang);
-DllExport void WINAPI ComPortInfoFree(ComPortInfo_t *info, int count);
-
-#ifdef __cplusplus
-}
-#endif

Deleted: trunk/teraterm/ttpcmn/devpkey_teraterm.h
===================================================================
--- trunk/teraterm/ttpcmn/devpkey_teraterm.h	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/devpkey_teraterm.h	2021-03-13 14:42:48 UTC (rev 9197)
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019- 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.
- */
-
-#pragma once
-
-/*
- * Visual Studio 2005\x82Ńr\x83\x8B\x83h\x82\xF0\x92ʂ\xB7\x82\xBD\x82߂ɂ͉\xBA\x8BL\x82̒\xE8\x8B`\x82\xAA\x95K\x97v\x81B
- * Visual Studio 2019\x82ł͕s\x97v\x81B
- */
-#if _MSC_VER == 1400 && !defined(DEVPROPKEY_DEFINED)
-typedef ULONG DEVPROPTYPE, *PDEVPROPTYPE;
-
-typedef GUID  DEVPROPGUID, *PDEVPROPGUID;
-typedef ULONG DEVPROPID,   *PDEVPROPID;
-
-typedef struct _DEVPROPKEY {
-    DEVPROPGUID fmtid;
-    DEVPROPID   pid;
-} DEVPROPKEY, *PDEVPROPKEY;
-#endif
-
-#undef DEFINE_DEVPROPKEY
-#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }, pid }
-
-/*
- * Platform SDK\x82\xCCdevpkey.h\x82\xE6\x82\xE8
- */
-
-DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);    // DEVPROP_TYPE_STRING
-DEFINE_DEVPROPKEY(DEVPKEY_Device_InstanceId,             0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 256);   // DEVPROP_TYPE_STRING
-DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13);    // DEVPROP_TYPE_STRING
-DEFINE_DEVPROPKEY(DEVPKEY_Device_DriverProvider,           0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 9);     // DEVPROP_TYPE_STRING
-DEFINE_DEVPROPKEY(DEVPKEY_Device_DriverDate,               0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 2);     // DEVPROP_TYPE_FILETIME
-DEFINE_DEVPROPKEY(DEVPKEY_Device_DriverVersion,            0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 3);     // DEVPROP_TYPE_STRING
-

Modified: trunk/teraterm/ttpcmn/ttcmn.c
===================================================================
--- trunk/teraterm/ttpcmn/ttcmn.c	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/ttcmn.c	2021-03-13 14:42:48 UTC (rev 9197)
@@ -2563,264 +2563,7 @@
 	return i;
 }
 
-// listup serial port driver
-// cf. http://www.codeproject.com/system/setupdi.asp?df=100&forumid=4368&exp=0&select=479661
-// (2007.8.17 yutaka)
-static void ListupSerialPort(LPWORD ComPortTable, int comports, char **ComPortDesc, int ComPortMax)
-{
-	GUID ClassGuid[1];
-	DWORD dwRequiredSize;
-	BOOL bRet;
-	HDEVINFO DeviceInfoSet = NULL;
-	SP_DEVINFO_DATA DeviceInfoData;
-	DWORD dwMemberIndex = 0;
-	int i;
-
-	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-
-	// \x88ȑO\x82̃\x81\x83\x82\x83\x8A\x82\xF0\x83t\x83\x8A\x81[\x82\xB5\x82Ă\xA8\x82\xAD
-	for (i = 0 ; i < ComPortMax ; i++) {
-		free(ComPortDesc[i]);
-		ComPortDesc[i] = NULL;
-	}
-
-// Get ClassGuid from ClassName for PORTS class
-	bRet =
-		SetupDiClassGuidsFromName(_T("PORTS"), (LPGUID) & ClassGuid, 1,
-		                          &dwRequiredSize);
-	if (!bRet) {
-		goto cleanup;
-	}
-
-// Get class devices
-	// COM\x83|\x81[\x83g\x94ԍ\x86\x82\xF0\x8B\xAD\x90\xA7\x95t\x82\xAF\x91ւ\xA6\x82\xB5\x82\xBD\x8Fꍇ\x82ɁA\x8C\xBB\x8D݂̂\xE0\x82̂ł͂Ȃ\xAD\x81A\x83\x8C\x83W\x83X\x83g\x83\x8A\x82Ɏc\x82\xC1\x82Ă\xA2\x82\xE9
-	// \x8CÂ\xA2FriendlyName\x82\xAA\x95\\x8E\xA6\x82\xB3\x82\xEA\x82Ă\xB5\x82܂\xA4\x96\xE2\x91\xE8\x82ւ̑Ώ\x88\x81B(2007.11.8 yutaka)
-	DeviceInfoSet =
-		SetupDiGetClassDevs(&ClassGuid[0], NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
-
-	if (DeviceInfoSet) {
-// Enumerate devices
-		dwMemberIndex = 0;
-		while (SetupDiEnumDeviceInfo
-		       (DeviceInfoSet, dwMemberIndex++, &DeviceInfoData)) {
-			TCHAR szFriendlyName[MAX_PATH];
-			TCHAR szPortName[MAX_PATH];
-			//TCHAR szMessage[MAX_PATH];
-			DWORD dwReqSize = 0;
-			DWORD dwPropType;
-			DWORD dwType = REG_SZ;
-			HKEY hKey = NULL;
-
-// Get friendlyname
-			bRet = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
-			                                        &DeviceInfoData,
-			                                        SPDRP_FRIENDLYNAME,
-			                                        &dwPropType,
-			                                        (LPBYTE)
-			                                        szFriendlyName,
-			                                        sizeof(szFriendlyName),
-			                                        &dwReqSize);
-
-// Open device parameters reg key
-			hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
-			                            &DeviceInfoData,
-			                            DICS_FLAG_GLOBAL,
-			                            0, DIREG_DEV, KEY_READ);
-			if (hKey) {
-// Qurey for portname
-				long lRet;
-				dwReqSize = sizeof(szPortName);
-				lRet = RegQueryValueEx(hKey,
-				                       _T("PortName"),
-				                       0,
-				                       &dwType,
-				                       (LPBYTE) & szPortName,
-				                       &dwReqSize);
-
-// Close reg key
-				RegCloseKey(hKey);
-			}
-
-#if 0
-			sprintf(szMessage, _T("Name: %s\nPort: %s\n"), szFriendlyName,
-			        szPortName);
-			printf("%s\n", szMessage);
-#endif
-
-			if (_strnicmp(szPortName, "COM", 3) == 0) {  // COM\x83|\x81[\x83g\x83h\x83\x89\x83C\x83o\x82𔭌\xA9
-				int port = atoi(&szPortName[3]);
-				int i;
-
-				for (i = 0 ; i < comports ; i++) {
-					if (ComPortTable[i] == port) {  // \x90ڑ\xB1\x82\xF0\x8Am\x94F
-						ComPortDesc[i] = _strdup(szFriendlyName);
-						break;
-					}
-				}
-			}
-
-		}
-	}
-
-cleanup:
-// Destroy device info list
-	SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-}
-
-
 /*
- *
- * [return]
- *   1\x88ȏ\xE3   \x83A\x83v\x83\x8A\x82\xAA\x8Eg\x97p\x89”\\x82\xC8COM\x83|\x81[\x83g\x82̑\x8D\x90\x94
- *   0       \x83A\x83v\x83\x8A\x82\xAA\x8Eg\x97p\x89”\\x82\xC8COM\x83|\x81[\x83g\x82\xAA\x82Ȃ\xA2
- *   -1      \x81\xA6\x96\xA2\x8Eg\x97p
- *
- */
-int WINAPI DetectComPorts(LPWORD ComPortTable, int ComPortMax, char **ComPortDesc)
-{
-	HMODULE h;
-	char   *devicesBuff;
-	char   *p;
-	int     comports = 0;
-	int     i, j, min;
-	WORD    s;
-	size_t buf_size = 65535;
-
-	devicesBuff = malloc(buf_size);
-	if (devicesBuff == NULL) {
-		return 0;
-	}
-
-	if (((h = GetModuleHandle("kernel32.dll")) != NULL) &&
-	    (GetProcAddress(h, "QueryDosDeviceA") != NULL) &&
-	    (QueryDosDevice(NULL, devicesBuff, buf_size) != 0)) {
-		p = devicesBuff;
-		while (*p != '\0') {
-			if (strncmp(p, "COM", 3) == 0 && p[3] != '\0') {
-				ComPortTable[comports++] = atoi(p+3);
-				if (comports >= ComPortMax)
-					break;
-			}
-			p += (strlen(p)+1);
-		}
-
-		for (i=0; i<comports-1; i++) {
-			min = i;
-			for (j=i+1; j<comports; j++) {
-				if (ComPortTable[min] > ComPortTable[j]) {
-					min = j;
-				}
-			}
-			if (min != i) {
-				s = ComPortTable[i];
-				ComPortTable[i] = ComPortTable[min];
-				ComPortTable[min] = s;
-			}
-		}
-	}
-	else {
-#if 1
-		for (i=1; i<=ComPortMax; i++) {
-			FILE *fp;
-			char buf[12]; // \\.\COMxxxx + NULL
-			_snprintf_s(buf, sizeof(buf), _TRUNCATE, "\\\\.\\COM%d", i);
-			if ((fp = fopen(buf, "r")) != NULL) {
-				fclose(fp);
-				ComPortTable[comports++] = i;
-			}
-		}
-#else
-		comports = -1;
-#endif
-	}
-
-	free(devicesBuff);
-
-	ListupSerialPort(ComPortTable, comports, ComPortDesc, ComPortMax);
-
-	return comports;
-}
-
-int WINAPI CheckComPort(WORD ComPort)
-{
-	HMODULE h;
-	char *devicesBuff;
-	char    com_str[64];
-	BOOL bRet;
-	GUID ClassGuid[1];
-	DWORD dwRequiredSize;
-	HDEVINFO DeviceInfoSet = NULL;
-	SP_DEVINFO_DATA DeviceInfoData;
-	int found = 0;
-	size_t buf_size = 65535;
-
-	_snprintf_s(com_str, sizeof(com_str), _TRUNCATE, "COM%d", ComPort);
-
-	if (((h = GetModuleHandle("kernel32.dll")) == NULL) | (GetProcAddress(h, "QueryDosDeviceA") == NULL) ) {
-		/* ERROR */
-		return -1;
-	}
-
-	devicesBuff = malloc(buf_size);
-	if (devicesBuff == NULL) {
-		return -1;
-	}
-
-	if (QueryDosDevice(com_str, devicesBuff, buf_size) == 0) {
-		DWORD err = GetLastError();
-		free(devicesBuff);
-		if (err == ERROR_FILE_NOT_FOUND) {
-			/* NOT FOUND */
-			return 0;
-		}
-		/* ERROR */
-		return -1;
-	}
-
-	/* QueryDosDevice\x82Őؒf\x82\xF0\x8C\x9F\x92m\x82ł\xAB\x82Ȃ\xA2\x8A‹\xAB\x82\xAA\x82\xA0\x82\xE9\x82ł\xB3\x82\xE7\x82Ƀ`\x83F\x83b\x83N */
-	bRet = SetupDiClassGuidsFromName(_T("PORTS"), (LPGUID) & ClassGuid, 1, &dwRequiredSize);
-	if (bRet == FALSE) {
-		free(devicesBuff);
-		return -1;
-	}
-
-	DeviceInfoSet = SetupDiGetClassDevs(&ClassGuid[0], NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
-	if (DeviceInfoSet == NULL) {
-		free(devicesBuff);
-		return -1;
-	}
-
-	if (DeviceInfoSet) {
-		DWORD dwMemberIndex = 0;
-		HKEY hKey = NULL;
-		TCHAR szPortName[MAX_PATH];
-		DWORD dwReqSize;
-		DWORD dwType;
-
-		DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-		while (SetupDiEnumDeviceInfo(DeviceInfoSet, dwMemberIndex, &DeviceInfoData)) {
-			hKey = SetupDiOpenDevRegKey(DeviceInfoSet, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
-			if (hKey) {
-				long lRet;
-				dwReqSize = sizeof(szPortName);
-				lRet = RegQueryValueEx(hKey, _T("PortName"), 0, &dwType, (LPBYTE)& szPortName, &dwReqSize);
-				RegCloseKey(hKey);
-				if (_stricmp(szPortName, com_str) == 0) {
-					found = TRUE;
-					break;
-				}
-			}
-			dwMemberIndex++;
-		}
-	}
-
-	SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-
-	free(devicesBuff);
-	return found;
-}
-
-/*
  *	@return		\x83G\x83\x89\x81[\x82\xAA\x97L\x82\xE9\x8Fꍇ FALSE
  *	@param[in]	BOOL first_instance
  */

Added: trunk/teraterm/ttpcmn/ttcmn_cominfo.c
===================================================================
--- trunk/teraterm/ttpcmn/ttcmn_cominfo.c	                        (rev 0)
+++ trunk/teraterm/ttpcmn/ttcmn_cominfo.c	2021-03-13 14:42:48 UTC (rev 9197)
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+#include <windows.h>
+
+#include "codeconv.h"
+#include "comportinfo.h"
+
+/**
+ *	COM\x83|\x81[\x83g\x82\xF0\x97\xF1\x8B\x93
+ *
+ *	@param[out]	ComPortTable[MAXCOMPORT]
+ *	@param[in]	ComPortMax		\x83e\x81[\x83u\x83\x8B\x82̍ő\xE5\x8Eg\x97p\x90\x94(\x8Dő\xE5MAXCOMPORT)
+ *	@param[out]	ComPortDesc[MAXCOMPORT]	(4096 in tttypes.h)
+ *	@retval	\x8Eg\x97p\x89”\\x82\xC8COM\x83|\x81[\x83g\x90\x94 (0=\x8Eg\x97p\x89”\\x83|\x81[\x83g\x82\xAA\x82Ȃ\xA2)
+ *
+ *		MAXCOMPORT = 4096 in tttypes.h
+ *		\x82\xB1\x82̒l\x82̓e\x81[\x83u\x83\x8B(COM\x83|\x81[\x83g\x82̌\x94)\x82̍ő吔\x82\xF0\x95\\x82\xB7
+ *
+ *		\x92\x8D\x88\xD3
+ *			ComPortDesc\x82̓P\x83A\x82\xB5\x82Ȃ\xA2\x82ƃ\x81\x83\x82\x83\x8A\x83\x8A\x81[\x83N\x82\xB7\x82\xE9
+ */
+int WINAPI DetectComPorts(LPWORD ComPortTable, int ComPortMax, char **ComPortDesc)
+{
+	int count;
+	int i;
+	ComPortInfo_t *port_info = ComPortInfoGet(&count, NULL);
+	const ComPortInfo_t *p = port_info;
+	for (i = 0; i < count; i++) {
+		ComPortTable[i] = p->port_no;
+		ComPortDesc[i] = ToCharW(p->friendly_name);
+		p++;
+	}
+
+	ComPortInfoFree(port_info, count);
+
+	return count;
+}
+
+/**
+ *	COM\x83|\x81[\x83g\x82\xF0\x97񋓂\xB5\x82đ\xB6\x8D݂\xB7\x82邩\x83`\x83F\x83b\x83N\x82\xB7\x82\xE9
+ *
+ *	@param[in]	ComPort		\x83`\x83F\x83b\x83N\x82\xB7\x82\xE9\x83|\x81[\x83g\x94ԍ\x86
+ *	@retval	-1	error(\x8C\xBB\x8D݂͎g\x97p\x82\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2)
+ *	@retval	0	NOT FOUND;
+ *	@retval	1	FOUND
+ */
+int WINAPI CheckComPort(WORD ComPort)
+{
+	int count;
+	int i;
+	ComPortInfo_t *port_info = ComPortInfoGet(&count, NULL);
+	const ComPortInfo_t *p = port_info;
+	int found = 0;
+	for (i = 0; i < count; i++) {
+		if (ComPort == p->port_no) {
+			found = 1;
+			break;
+		}
+		p++;
+	}
+
+	ComPortInfoFree(port_info, count);
+
+	return found;
+}

Modified: trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj
===================================================================
--- trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj	2021-03-13 14:42:48 UTC (rev 9197)
@@ -134,9 +134,9 @@
     <ClCompile Include="..\common\i18n.c" />
     <ClCompile Include="..\common\servicenames.c" />
     <ClCompile Include="..\common\ttlib.c" />
-    <ClCompile Include="comportinfo.cpp" />
     <ClCompile Include="language.c" />
     <ClCompile Include="ttcmn.c" />
+    <ClCompile Include="ttcmn_cominfo.c" />
     <ClCompile Include="ttcmn_notify.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -145,7 +145,6 @@
     <ClInclude Include="..\common\i18n.h" />
     <ClInclude Include="..\common\servicenames.h" />
     <ClInclude Include="..\common\ttlib.h" />
-    <ClInclude Include="comportinfo.h" />
     <ClInclude Include="devpkey_teraterm.h" />
     <ClInclude Include="language.h" />
   </ItemGroup>

Modified: trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters
===================================================================
--- trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/ttpcmn.v16.vcxproj.filters	2021-03-13 14:42:48 UTC (rev 9197)
@@ -31,9 +31,6 @@
     <ClCompile Include="..\common\ttlib.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="comportinfo.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="ttcmn_notify.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -40,6 +37,9 @@
     <ClCompile Include="..\common\i18n.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="ttcmn_cominfo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\common\i18n.h">
@@ -57,9 +57,6 @@
     <ClInclude Include="devpkey_teraterm.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="comportinfo.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\common\compat_win.h">
       <Filter>Header Files</Filter>
     </ClInclude>

Modified: trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj
===================================================================
--- trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj	2021-03-13 14:42:32 UTC (rev 9196)
+++ trunk/teraterm/ttpcmn/ttpcmn.v8.vcproj	2021-03-13 14:42:48 UTC (rev 9197)
@@ -211,10 +211,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\comportinfo.cpp"
-				>
-			</File>
-			<File
 				RelativePath="..\common\i18n.c"
 				>
 			</File>
@@ -231,6 +227,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\ttcmn_cominfo.c"
+				>
+			</File>
+			<File
 				RelativePath=".\ttcmn_notify.cpp"
 				>
 			</File>
@@ -248,10 +248,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\comportinfo.h"
-				>
-			</File>
-			<File
 				RelativePath=".\devpkey_teraterm.h"
 				>
 			</File>


Ttssh2-commit メーリングリストの案内
Back to archive index