Move latency timer updates to openPort() function
This commit is contained in:
parent
adddb318b4
commit
ba48714bcb
|
@ -272,7 +272,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the port description and latency if not already open
|
// Update the port description if not already open
|
||||||
if (!isOpen)
|
if (!isOpen)
|
||||||
{
|
{
|
||||||
LONG comPortNumber = 0;
|
LONG comPortNumber = 0;
|
||||||
|
@ -284,85 +284,6 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
|
||||||
for (int j = 0; j < serialPorts.length; ++j)
|
for (int j = 0; j < serialPorts.length; ++j)
|
||||||
if (wcscmp(serialPorts.ports[j]->portPath, comPort) == 0)
|
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
|
// Update the port description
|
||||||
serialPorts.ports[j]->enumerated = 1;
|
serialPorts.ports[j]->enumerated = 1;
|
||||||
size_t descLength = 8+strlen(devInfo[i].Description);
|
size_t descLength = 8+strlen(devInfo[i].Description);
|
||||||
|
@ -523,6 +444,86 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
|
||||||
return 0;
|
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
|
// 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)
|
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)
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue