diff --git a/src/main/c/Windows/SerialPort_Windows.c b/src/main/c/Windows/SerialPort_Windows.c index 19a1d7b..e2b38ec 100644 --- a/src/main/c/Windows/SerialPort_Windows.c +++ b/src/main/c/Windows/SerialPort_Windows.c @@ -272,7 +272,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP break; } - // Update the port description and latency if not already open + // Update the port description if not already open if (!isOpen) { LONG comPortNumber = 0; @@ -284,85 +284,6 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP for (int j = 0; j < serialPorts.length; ++j) if (wcscmp(serialPorts.ports[j]->portPath, comPort) == 0) { - // Reduce the port's latency timer to minimum value of 2 - HKEY key, paramKey = 0; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS", 0, KEY_READ, &key) == ERROR_SUCCESS) - { - DWORD index = 0, latency = 2, subkeySize = 255, portNameSize = 16, oldLatency = 2, oldLatencySize = sizeof(DWORD); - wchar_t *subkey = (wchar_t*)malloc(subkeySize*sizeof(wchar_t)), *regPortName = (wchar_t*)malloc(portNameSize*sizeof(wchar_t)); - while (RegEnumKeyExW(key, index++, subkey, &subkeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) - { - char *subkeyString = (char*)malloc(subkeySize); - memset(subkeyString, 0, subkeySize); - wcstombs(subkeyString, subkey, subkeySize); - subkeySize = 255; - portNameSize = 16; - memset(regPortName, 0, portNameSize * sizeof(wchar_t)); - wcscat_s(subkey, subkeySize, L"\\0000\\Device Parameters"); - if (RegOpenKeyExW(key, subkey, 0, KEY_QUERY_VALUE, ¶mKey) == ERROR_SUCCESS) - { - if ((RegQueryValueExW(paramKey, L"PortName", NULL, NULL, (LPBYTE)regPortName, &portNameSize) == ERROR_SUCCESS) && (wcscmp(serialPorts.ports[j]->portPath, regPortName) == 0)) - RegQueryValueExW(paramKey, L"LatencyTimer", NULL, NULL, (LPBYTE)&oldLatency, &oldLatencySize); - RegCloseKey(paramKey); - } - if (oldLatency > latency) - { - if (RegOpenKeyExW(key, subkey, 0, KEY_SET_VALUE, ¶mKey) == ERROR_SUCCESS) - { - RegSetValueExW(paramKey, L"LatencyTimer", 0, REG_DWORD, (LPBYTE)&latency, sizeof(latency)); - RegCloseKey(paramKey); - } - else - { - // Create registry update file - char *workingDirectory = _getcwd(NULL, 0); - wchar_t *workingDirectoryWide = _wgetcwd(NULL, 0); - int workingDirectoryLength = strlen(workingDirectory) + 1; - char *registryFileName = (char*)malloc(workingDirectoryLength + 8); - wchar_t *paramsString = (wchar_t*)malloc((workingDirectoryLength + 11) * sizeof(wchar_t)); - sprintf(registryFileName, "%s\\del.reg", workingDirectory); - swprintf(paramsString, workingDirectoryLength + 11, L"/s %s\\del.reg", workingDirectoryWide); - FILE *registryFile = fopen(registryFileName, "wb"); - if (registryFile) - { - fprintf(registryFile, "Windows Registry Editor Version 5.00\n\n"); - fprintf(registryFile, "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS\\%s\\0000\\Device Parameters]\n", subkeyString); - fprintf(registryFile, "\"LatencyTimer\"=dword:00000002\n\n"); - fclose(registryFile); - } - - // Launch a new administrative process to update the registry value - SHELLEXECUTEINFOW shExInfo = { 0 }; - shExInfo.cbSize = sizeof(shExInfo); - shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExInfo.hwnd = NULL; - shExInfo.lpVerb = L"runas"; - shExInfo.lpFile = L"C:\\Windows\\regedit.exe"; - shExInfo.lpParameters = paramsString; - shExInfo.lpDirectory = NULL; - shExInfo.nShow = SW_SHOW; - shExInfo.hInstApp = 0; - if (ShellExecuteExW(&shExInfo)) - { - WaitForSingleObject(shExInfo.hProcess, INFINITE); - CloseHandle(shExInfo.hProcess); - } - - // Delete the registry update file - remove(registryFileName); - free(workingDirectoryWide); - free(workingDirectory); - free(registryFileName); - free(paramsString); - } - } - free(subkeyString); - } - RegCloseKey(key); - free(regPortName); - free(subkey); - } - // Update the port description serialPorts.ports[j]->enumerated = 1; size_t descLength = 8+strlen(devInfo[i].Description); @@ -523,6 +444,86 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( return 0; } + // Reduce the port's latency timer to minimum value of 2 + HKEY key, paramKey = 0; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS", 0, KEY_READ, &key) == ERROR_SUCCESS) + { + DWORD index = 0, subkeySize = 255, portNameSize = 16; + wchar_t *subkey = (wchar_t*)malloc(subkeySize*sizeof(wchar_t)), *regPortName = (wchar_t*)malloc(portNameSize*sizeof(wchar_t)); + while (RegEnumKeyExW(key, index++, subkey, &subkeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + DWORD latency = 2, oldLatency = 2, oldLatencySize = sizeof(DWORD); + char *subkeyString = (char*)malloc(subkeySize + 2); + memset(subkeyString, 0, subkeySize + 2); + wcstombs(subkeyString, subkey, subkeySize + 1); + subkeySize = 255; + portNameSize = 16; + memset(regPortName, 0, portNameSize * sizeof(wchar_t)); + wcscat_s(subkey, subkeySize, L"\\0000\\Device Parameters"); + if (RegOpenKeyExW(key, subkey, 0, KEY_QUERY_VALUE, ¶mKey) == ERROR_SUCCESS) + { + if ((RegQueryValueExW(paramKey, L"PortName", NULL, NULL, (LPBYTE)regPortName, &portNameSize) == ERROR_SUCCESS) && (wcscmp(port->portPath + 4, regPortName) == 0)) + RegQueryValueExW(paramKey, L"LatencyTimer", NULL, NULL, (LPBYTE)&oldLatency, &oldLatencySize); + RegCloseKey(paramKey); + } + if (oldLatency > latency) + { + if (RegOpenKeyExW(key, subkey, 0, KEY_SET_VALUE, ¶mKey) == ERROR_SUCCESS) + { + RegSetValueExW(paramKey, L"LatencyTimer", 0, REG_DWORD, (LPBYTE)&latency, sizeof(latency)); + RegCloseKey(paramKey); + } + else + { + // Create registry update file + char *workingDirectory = _getcwd(NULL, 0); + wchar_t *workingDirectoryWide = _wgetcwd(NULL, 0); + int workingDirectoryLength = strlen(workingDirectory) + 1; + char *registryFileName = (char*)malloc(workingDirectoryLength + 8); + wchar_t *paramsString = (wchar_t*)malloc((workingDirectoryLength + 11) * sizeof(wchar_t)); + sprintf(registryFileName, "%s\\del.reg", workingDirectory); + swprintf(paramsString, workingDirectoryLength + 11, L"/s %s\\del.reg", workingDirectoryWide); + FILE *registryFile = fopen(registryFileName, "wb"); + if (registryFile) + { + fprintf(registryFile, "Windows Registry Editor Version 5.00\n\n"); + fprintf(registryFile, "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS\\%s\\0000\\Device Parameters]\n", subkeyString); + fprintf(registryFile, "\"LatencyTimer\"=dword:00000002\n\n"); + fclose(registryFile); + } + + // Launch a new administrative process to update the registry value + SHELLEXECUTEINFOW shExInfo = { 0 }; + shExInfo.cbSize = sizeof(shExInfo); + shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + shExInfo.hwnd = NULL; + shExInfo.lpVerb = L"runas"; + shExInfo.lpFile = L"C:\\Windows\\regedit.exe"; + shExInfo.lpParameters = paramsString; + shExInfo.lpDirectory = NULL; + shExInfo.nShow = SW_SHOW; + shExInfo.hInstApp = 0; + if (ShellExecuteExW(&shExInfo)) + { + WaitForSingleObject(shExInfo.hProcess, INFINITE); + CloseHandle(shExInfo.hProcess); + } + + // Delete the registry update file + remove(registryFileName); + free(workingDirectoryWide); + free(workingDirectory); + free(registryFileName); + free(paramsString); + } + } + free(subkeyString); + } + RegCloseKey(key); + free(regPortName); + free(subkey); + } + // Try to open the serial port with read/write access if ((port->handle = CreateFileW(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, NULL)) != INVALID_HANDLE_VALUE) { diff --git a/src/main/resources/Windows/aarch64/jSerialComm.dll b/src/main/resources/Windows/aarch64/jSerialComm.dll index 50d7f3f..ff68add 100644 Binary files a/src/main/resources/Windows/aarch64/jSerialComm.dll and b/src/main/resources/Windows/aarch64/jSerialComm.dll differ diff --git a/src/main/resources/Windows/armv7/jSerialComm.dll b/src/main/resources/Windows/armv7/jSerialComm.dll index 6e7f7b8..c6c5545 100644 Binary files a/src/main/resources/Windows/armv7/jSerialComm.dll and b/src/main/resources/Windows/armv7/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86/jSerialComm.dll b/src/main/resources/Windows/x86/jSerialComm.dll index 79e35b1..2b1ff89 100644 Binary files a/src/main/resources/Windows/x86/jSerialComm.dll and b/src/main/resources/Windows/x86/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86_64/jSerialComm.dll b/src/main/resources/Windows/x86_64/jSerialComm.dll index 954a180..9d568fc 100644 Binary files a/src/main/resources/Windows/x86_64/jSerialComm.dll and b/src/main/resources/Windows/x86_64/jSerialComm.dll differ