Author: tfaber
Date: Sat Apr 25 19:57:27 2015
New Revision: 67425
URL:
http://svn.reactos.org/svn/reactos?rev=67425&view=rev
Log:
[ADVAPI32]
Fix RegQueryInfoKey
- Return a value in lpcClass if lpClass is NULL
- Return correct error codes as shown by tests
- Correctly name parameters -- most of these are NOT byte counts
CORE-6976
Modified:
trunk/reactos/dll/win32/advapi32/reg/reg.c
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Sat Apr 25 19:57:27 2015
@@ -1961,7 +1961,7 @@
* NOTES
* - Unless RRF_NOEXPAND is specified, REG_EXPAND_SZ values are automatically
* expanded and pdwType is set to REG_SZ instead.
- * - Restrictions are applied after expanding, using RRF_RT_REG_EXPAND_SZ
+ * - Restrictions are applied after expanding, using RRF_RT_REG_EXPAND_SZ
* without RRF_NOEXPAND is thus not allowed.
* An exception is the case where RRF_RT_ANY is specified, because then
* RRF_NOEXPAND is allowed.
@@ -2720,11 +2720,14 @@
if ((lpData && !lpcbData) || lpdwReserved)
return ERROR_INVALID_PARAMETER;
- /* Get the size of the buffer we must use for the first call ro RegEnumValueW */
+ /* Get the size of the buffer we must use for the first call to RegEnumValueW */
ErrorCode = RegQueryInfoKeyW(
hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &NameBufferSize, NULL, NULL,
NULL);
if (ErrorCode != ERROR_SUCCESS)
return ErrorCode;
+
+ /* Add space for the null terminator */
+ NameBufferSize++;
/* Allocate the buffer for the unicode name */
NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NameBufferSize *
sizeof(WCHAR));
@@ -3583,14 +3586,14 @@
LONG WINAPI
RegQueryInfoKeyA(HKEY hKey,
LPSTR lpClass,
- LPDWORD lpcbClass,
+ LPDWORD lpcClass,
LPDWORD lpReserved,
LPDWORD lpcSubKeys,
- LPDWORD lpcbMaxSubKeyLen,
- LPDWORD lpcbMaxClassLen,
+ LPDWORD lpcMaxSubKeyLen,
+ LPDWORD lpcMaxClassLen,
LPDWORD lpcValues,
- LPDWORD lpcbMaxValueNameLen,
- LPDWORD lpcbMaxValueLen,
+ LPDWORD lpcMaxValueNameLen,
+ LPDWORD lpcMaxValueLen,
LPDWORD lpcbSecurityDescriptor,
PFILETIME lpftLastWriteTime)
{
@@ -3598,38 +3601,51 @@
UNICODE_STRING UnicodeString;
ANSI_STRING AnsiString;
LONG ErrorCode;
+ NTSTATUS Status;
+ DWORD cClass = 0;
RtlInitUnicodeString(&UnicodeString,
NULL);
if (lpClass != NULL)
{
- UnicodeString.Buffer = &ClassName[0];
- UnicodeString.MaximumLength = sizeof(ClassName);
- AnsiString.MaximumLength = *lpcbClass;
+ RtlInitEmptyUnicodeString(&UnicodeString,
+ ClassName,
+ sizeof(ClassName));
+ cClass = sizeof(ClassName) / sizeof(WCHAR);
}
ErrorCode = RegQueryInfoKeyW(hKey,
UnicodeString.Buffer,
- lpcbClass,
+ &cClass,
lpReserved,
lpcSubKeys,
- lpcbMaxSubKeyLen,
- lpcbMaxClassLen,
+ lpcMaxSubKeyLen,
+ lpcMaxClassLen,
lpcValues,
- lpcbMaxValueNameLen,
- lpcbMaxValueLen,
+ lpcMaxValueNameLen,
+ lpcMaxValueLen,
lpcbSecurityDescriptor,
lpftLastWriteTime);
if ((ErrorCode == ERROR_SUCCESS) && (lpClass != NULL))
{
- AnsiString.Buffer = lpClass;
- AnsiString.Length = 0;
- UnicodeString.Length = *lpcbClass * sizeof(WCHAR);
- RtlUnicodeStringToAnsiString(&AnsiString,
- &UnicodeString,
- FALSE);
- *lpcbClass = AnsiString.Length;
- lpClass[AnsiString.Length] = 0;
+ if (*lpcClass == 0)
+ {
+ return ErrorCode;
+ }
+
+ RtlInitEmptyAnsiString(&AnsiString, lpClass, *lpcClass);
+ UnicodeString.Length = cClass * sizeof(WCHAR);
+ Status = RtlUnicodeStringToAnsiString(&AnsiString,
+ &UnicodeString,
+ FALSE);
+ ErrorCode = RtlNtStatusToDosError(Status);
+ cClass = AnsiString.Length;
+ lpClass[*lpcClass - 1] = 0;
+ }
+
+ if (lpcClass != NULL)
+ {
+ *lpcClass = cClass;
}
return ErrorCode;
@@ -3644,14 +3660,14 @@
LONG WINAPI
RegQueryInfoKeyW(HKEY hKey,
LPWSTR lpClass,
- LPDWORD lpcbClass,
+ LPDWORD lpcClass,
LPDWORD lpReserved,
LPDWORD lpcSubKeys,
- LPDWORD lpcbMaxSubKeyLen,
- LPDWORD lpcbMaxClassLen,
+ LPDWORD lpcMaxSubKeyLen,
+ LPDWORD lpcMaxClassLen,
LPDWORD lpcValues,
- LPDWORD lpcbMaxValueNameLen,
- LPDWORD lpcbMaxValueLen,
+ LPDWORD lpcMaxValueNameLen,
+ LPDWORD lpcMaxValueLen,
LPDWORD lpcbSecurityDescriptor,
PFILETIME lpftLastWriteTime)
{
@@ -3664,7 +3680,7 @@
ULONG Length;
LONG ErrorCode = ERROR_SUCCESS;
- if ((lpClass) && (!lpcbClass))
+ if ((lpClass) && (!lpcClass))
{
return ERROR_INVALID_PARAMETER;
}
@@ -3678,9 +3694,9 @@
if (lpClass != NULL)
{
- if (*lpcbClass > 0)
- {
- ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+ if (*lpcClass > 0)
+ {
+ ClassLength = min(*lpcClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
}
else
{
@@ -3696,16 +3712,12 @@
ErrorCode = ERROR_OUTOFMEMORY;
goto Cleanup;
}
-
- FullInfo->ClassLength = ClassLength;
}
else
{
FullInfoSize = sizeof(KEY_FULL_INFORMATION);
FullInfo = &FullInfoBuffer;
- FullInfo->ClassLength = 0;
- }
- FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+ }
Status = NtQueryKey(KeyHandle,
KeyFullInformation,
@@ -3713,15 +3725,8 @@
FullInfoSize,
&Length);
TRACE("NtQueryKey() returned status 0x%X\n", Status);
- if (!NT_SUCCESS(Status))
- {
- if (lpClass != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- FullInfo);
- }
-
+ if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
+ {
ErrorCode = RtlNtStatusToDosError(Status);
goto Cleanup;
}
@@ -3733,15 +3738,15 @@
}
TRACE("MaxNameLen %lu\n", FullInfo->MaxNameLen);
- if (lpcbMaxSubKeyLen != NULL)
- {
- *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
+ if (lpcMaxSubKeyLen != NULL)
+ {
+ *lpcMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR);
}
TRACE("MaxClassLen %lu\n", FullInfo->MaxClassLen);
- if (lpcbMaxClassLen != NULL)
- {
- *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
+ if (lpcMaxClassLen != NULL)
+ {
+ *lpcMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR);
}
TRACE("Values %lu\n", FullInfo->Values);
@@ -3751,15 +3756,15 @@
}
TRACE("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
- if (lpcbMaxValueNameLen != NULL)
- {
- *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
+ if (lpcMaxValueNameLen != NULL)
+ {
+ *lpcMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR);
}
TRACE("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
- if (lpcbMaxValueLen != NULL)
- {
- *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
+ if (lpcMaxValueLen != NULL)
+ {
+ *lpcMaxValueLen = FullInfo->MaxValueDataLen;
}
if (lpcbSecurityDescriptor != NULL)
@@ -3773,13 +3778,6 @@
lpcbSecurityDescriptor);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
{
- if (lpClass != NULL)
- {
- RtlFreeHeap(ProcessHeap,
- 0,
- FullInfo);
- }
-
ErrorCode = RtlNtStatusToDosError(Status);
goto Cleanup;
}
@@ -3791,27 +3789,40 @@
lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
}
+ ErrorCode = ERROR_SUCCESS;
if (lpClass != NULL)
{
+ if (*lpcClass == 0)
+ {
+ goto Cleanup;
+ }
+
if (FullInfo->ClassLength > ClassLength)
{
- ErrorCode = ERROR_BUFFER_OVERFLOW;
+ ErrorCode = ERROR_INSUFFICIENT_BUFFER;
}
else
{
RtlCopyMemory(lpClass,
FullInfo->Class,
FullInfo->ClassLength);
- *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
- lpClass[*lpcbClass] = 0;
- }
-
+ lpClass[FullInfo->ClassLength / sizeof(WCHAR)] = UNICODE_NULL;
+ }
+ }
+
+ if (lpcClass != NULL)
+ {
+ *lpcClass = FullInfo->ClassLength / sizeof(WCHAR);
+ }
+
+Cleanup:
+ if (lpClass != NULL)
+ {
RtlFreeHeap(ProcessHeap,
0,
FullInfo);
}
-Cleanup:
ClosePredefKey(KeyHandle);
return ErrorCode;
@@ -3979,9 +3990,9 @@
* Failure: ERROR_INVALID_HANDLE, if hkey is invalid.
* ERROR_INVALID_PARAMETER, if any other parameter is invalid.
* ERROR_MORE_DATA, if on input *count is too small to hold the contents.
- *
+ *
* NOTES
- * MSDN states that if data is too small it is partially filled. In reality
+ * MSDN states that if data is too small it is partially filled. In reality
* it remains untouched.
*/
LONG
@@ -4218,15 +4229,15 @@
if (name && name[0])
{
ret = RegOpenKeyW( hkey, name, &subkey);
- if (ret != ERROR_SUCCESS)
+ if (ret != ERROR_SUCCESS)
{
return ret;
}
}
ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
-
- if (subkey != hkey)
+
+ if (subkey != hkey)
{
RegCloseKey( subkey );
}
@@ -4234,9 +4245,9 @@
if (ret == ERROR_FILE_NOT_FOUND)
{
/* return empty string if default value not found */
- if (data)
+ if (data)
*data = 0;
- if (count)
+ if (count)
*count = sizeof(WCHAR);
ret = ERROR_SUCCESS;
}