| 2563 |
return i; |
return i; |
| 2564 |
} |
} |
| 2565 |
|
|
|
// 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); |
|
|
|
|
|
// 以前のメモリをフリーしておく |
|
|
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ポート番号を強制付け替えした場合に、現在のものではなく、レジストリに残っている |
|
|
// 古いFriendlyNameが表示されてしまう問題への対処。(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ポートドライバを発見 |
|
|
int port = atoi(&szPortName[3]); |
|
|
int i; |
|
|
|
|
|
for (i = 0 ; i < comports ; i++) { |
|
|
if (ComPortTable[i] == port) { // 接続を確認 |
|
|
ComPortDesc[i] = _strdup(szFriendlyName); |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
cleanup: |
|
|
// Destroy device info list |
|
|
SetupDiDestroyDeviceInfoList(DeviceInfoSet); |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
* |
|
|
* [return] |
|
|
* 1以上 アプリが使用可能なCOMポートの総数 |
|
|
* 0 アプリが使用可能なCOMポートがない |
|
|
* -1 ※未使用 |
|
|
* |
|
|
*/ |
|
|
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で切断を検知できない環境があるでさらにチェック */ |
|
|
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; |
|
|
} |
|
|
|
|
| 2566 |
/* |
/* |
| 2567 |
* @return エラーが有る場合 FALSE |
* @return エラーが有る場合 FALSE |
| 2568 |
* @param[in] BOOL first_instance |
* @param[in] BOOL first_instance |