MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / ReadRegString

Function ReadRegString

source/util.cpp:1901–1950  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1899
1900
1901DWORD ReadRegString(HKEY aRootKey, LPTSTR aSubkey, LPTSTR aValueName, LPTSTR aBuf, DWORD aBufSize, DWORD aFlag)
1902// Returns the length of the string (0 if empty).
1903// Caller must ensure that size of aBuf is REALLY aBufSize (even when it knows aBufSize is more than
1904// it needs) because the API apparently reads/writes parts of the buffer beyond the string it writes!
1905// Caller must ensure that aBuf isn't NULL because it doesn't seem worth having a "give me the size only" mode.
1906// This is because the API might return a size that omits the zero terminator, and the only way to find out for
1907// sure is probably to actually fetch the data and check if the terminator is present.
1908{
1909 HKEY hkey;
1910 if (RegOpenKeyEx(aRootKey, aSubkey, 0, KEY_QUERY_VALUE | aFlag, &hkey) != ERROR_SUCCESS)
1911 {
1912 *aBuf = '\0';
1913 return 0;
1914 }
1915 DWORD buf_size = aBufSize * sizeof(TCHAR); // Caller's value might be a constant memory area, so need a modifiable copy.
1916 LONG result = RegQueryValueEx(hkey, aValueName, NULL, NULL, (LPBYTE)aBuf, &buf_size);
1917 RegCloseKey(hkey);
1918 if (result != ERROR_SUCCESS || !buf_size) // Relies on short-circuit boolean order.
1919 {
1920 *aBuf = '\0'; // MSDN says the contents of the buffer is undefined after the call in some cases, so reset it.
1921 return 0;
1922 }
1923 buf_size /= sizeof(TCHAR); // RegQueryValueEx returns size in bytes.
1924 // Otherwise success and non-empty result. This also means that buf_size is accurate and <= to what we sent in.
1925 // Fix for v1.0.47: ENSURE PROPER STRING TERMINATION. This is suspected to be a source of crashing.
1926 // MSDN: "If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been
1927 // stored with the proper null-terminating characters. Therefore, even if the function returns
1928 // ERROR_SUCCESS, the application should ensure that the string is properly terminated before using
1929 // it; otherwise, it may overwrite a buffer. (Note that REG_MULTI_SZ strings should have two
1930 // null-terminating characters.)"
1931 // MSDN: "If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, this size includes any
1932 // terminating null character or characters."
1933 --buf_size; // Convert to the index of the last character written. This is safe because above already checked that buf_size>0.
1934 if (aBuf[buf_size] == '\0') // It wrote at least one zero terminator (it might write more than one for Unicode, or if it's simply stored with more than one in the registry).
1935 {
1936 while (buf_size && !aBuf[buf_size - 1]) // Scan leftward in case more than one consecutive terminator.
1937 --buf_size;
1938 return buf_size; // There's a tiny chance that this could the wrong length, namely when the string contains binary zero(s) to the left of non-zero characters. But that seems too rare to be worth calling strlen() for.
1939 }
1940 // Otherwise, it didn't write a terminator, so provide one.
1941 ++buf_size; // To reflect the fact that we're about to write an extra char.
1942 if (buf_size >= aBufSize) // There's no room for a terminator without truncating the data (very rare). Seems best to indicate failure.
1943 {
1944 *aBuf = '\0';
1945 return 0;
1946 }
1947 // Otherwise, there's room for the terminator.
1948 aBuf[buf_size] = '\0';
1949 return buf_size; // There's a tiny chance that this could the wrong length, namely when the string contains binary zero(s) to the left of non-zero characters. But that seems too rare to be worth calling strlen() for.
1950}
1951
1952
1953

Callers 2

LoadKeyboardLayoutModuleFunction · 0.85
GetAHKInstallDirFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected