void reduceLatencyToMinimum()

in src/main/c/Windows/WindowsHelperFunctions.c [205:300]


void reduceLatencyToMinimum(const wchar_t* portName, unsigned char requestElevatedPermissions)
{
	// Search for this port in all FTDI enumerated ports
	HKEY key, paramKey;
	DWORD maxSubkeySize, maxPortNameSize = 8;
	if ((RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS", 0, KEY_READ, &key) == ERROR_SUCCESS) &&
			(RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, &maxSubkeySize, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS))
	{
		maxSubkeySize += 32;
		DWORD index = 0, subkeySize = maxSubkeySize;
		wchar_t *subkey = (wchar_t*)malloc(maxSubkeySize * sizeof(wchar_t)), *portPath = (wchar_t*)malloc(maxPortNameSize * sizeof(wchar_t));
		while (subkey && portPath && (RegEnumKeyExW(key, index++, subkey, &subkeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS))
		{
			// Retrieve the current port latency value
			size_t convertedSize;
			char *subkeyString = NULL;
			subkeySize = maxSubkeySize;
			DWORD desiredLatency = 2, oldLatency = 2;
			if ((wcstombs_s(&convertedSize, NULL, 0, subkey, 0) == 0) && (convertedSize < 255))
			{
				subkeyString = (char*)malloc(convertedSize);
				if (subkeyString && (wcstombs_s(NULL, subkeyString, convertedSize, subkey, convertedSize - 1) == 0) &&
						(wcscat_s(subkey, maxSubkeySize, L"\\0000\\Device Parameters") == 0))
				{
					if (RegOpenKeyExW(key, subkey, 0, KEY_QUERY_VALUE, &paramKey) == ERROR_SUCCESS)
					{
						DWORD oldLatencySize = sizeof(DWORD), portNameSize = maxPortNameSize * sizeof(wchar_t);
						if ((RegQueryValueExW(paramKey, L"PortName", NULL, NULL, (LPBYTE)portPath, &portNameSize) == ERROR_SUCCESS) && (wcscmp(portName, portPath) == 0))
							RegQueryValueExW(paramKey, L"LatencyTimer", NULL, NULL, (LPBYTE)&oldLatency, &oldLatencySize);
						RegCloseKey(paramKey);
					}
				}
			}

			// Update the port latency value if it is too high
			if (oldLatency > desiredLatency)
			{
				if (RegOpenKeyExW(key, subkey, 0, KEY_SET_VALUE, &paramKey) == ERROR_SUCCESS)
				{
					RegSetValueExW(paramKey, L"LatencyTimer", 0, REG_DWORD, (LPBYTE)&desiredLatency, sizeof(desiredLatency));
					RegCloseKey(paramKey);
				}
				else if (requestElevatedPermissions)
				{
					// 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);
				}
			}

			// Clean up memory
			if (subkeyString)
				free(subkeyString);
		}
		RegCloseKey(key);
		free(portPath);
		free(subkey);
	}
}