[SETUPAPI]

- SetupDiClassNameFromGuidExW: Simplify interaction with registry.
- SetupDiCreateDeviceInfoW: Check for correct error value.
- SetupDiGetClassDescriptionExW: Rewrite to return the correct required size and prevent WCHAR sized buffer overflow.
- SetupDiGetClassDevsExW: Return INVALID_HANDLE_VALUE instead of NULL in failure case.

svn path=/trunk/; revision=50272
This commit is contained in:
Roel Messiant 2011-01-03 00:45:34 +00:00
parent 1cd9389032
commit 916ec376d6

View file

@ -1158,29 +1158,8 @@ BOOL WINAPI SetupDiClassNameFromGuidExW(
if (hKey == INVALID_HANDLE_VALUE) if (hKey == INVALID_HANDLE_VALUE)
return FALSE; return FALSE;
/* Retrieve the class name data */ /* Retrieve the class name data and close the key */
dwLength = ClassNameSize * sizeof(WCHAR); rc = QueryRegistryValue(hKey, Class, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
do
{
/* Allocate a buffer to retrieve the class name data */
Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
if (Buffer == NULL)
{
rc = GetLastError();
break;
}
/* Query for the class name data */
rc = RegQueryValueExW(hKey, Class, NULL, &dwRegType, (LPBYTE) Buffer, &dwLength);
/* Clean up the buffer if needed */
if (rc != ERROR_SUCCESS)
HeapFree(GetProcessHeap(), 0, Buffer);
} while (rc == ERROR_MORE_DATA);
/* Close the key */
RegCloseKey(hKey); RegCloseKey(hKey);
/* Make sure we got the data */ /* Make sure we got the data */
@ -1193,7 +1172,7 @@ BOOL WINAPI SetupDiClassNameFromGuidExW(
/* Make sure the data is a string */ /* Make sure the data is a string */
if (dwRegType != REG_SZ) if (dwRegType != REG_SZ)
{ {
HeapFree(GetProcessHeap(), 0, Buffer); MyFree(Buffer);
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
@ -1217,7 +1196,7 @@ BOOL WINAPI SetupDiClassNameFromGuidExW(
*RequiredSize = dwLength; *RequiredSize = dwLength;
/* Clean up the buffer */ /* Clean up the buffer */
HeapFree(GetProcessHeap(), 0, Buffer); MyFree(Buffer);
/* Make sure the buffer was large enough */ /* Make sure the buffer was large enough */
if ((ClassName == NULL) || (dwLength > ClassNameSize)) if ((ClassName == NULL) || (dwLength > ClassNameSize))
@ -1757,7 +1736,7 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(
*/ */
SetLastError(ERROR_DEVINST_ALREADY_EXISTS); SetLastError(ERROR_DEVINST_ALREADY_EXISTS);
} }
else if (GetLastError() == ERROR_FILE_NOT_FOUND) else if (GetLastError() == ERROR_NO_SUCH_DEVINST)
{ {
struct DeviceInfo *deviceInfo; struct DeviceInfo *deviceInfo;
@ -2198,69 +2177,82 @@ BOOL WINAPI SetupDiGetClassDescriptionExW(
DWORD dwLength; DWORD dwLength;
DWORD dwRegType; DWORD dwRegType;
LONG rc; LONG rc;
PWSTR Buffer;
TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription, TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription,
ClassDescriptionSize, RequiredSize, debugstr_w(MachineName), Reserved); ClassDescriptionSize, RequiredSize, debugstr_w(MachineName), Reserved);
/* Make sure there's a GUID */
if (!ClassGuid) if (!ClassGuid)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
else if (!ClassDescription && ClassDescriptionSize > 0)
/* Make sure there's a real buffer when there's a size */
if (!ClassDescription && ClassDescriptionSize > 0)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
/* Open the key for the GUID */
hKey = SetupDiOpenClassRegKeyExW(ClassGuid, hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
KEY_QUERY_VALUE, KEY_QUERY_VALUE,
DIOCR_INSTALLER, DIOCR_INSTALLER,
MachineName, MachineName,
Reserved); Reserved);
if (hKey == INVALID_HANDLE_VALUE) if (hKey == INVALID_HANDLE_VALUE)
{ return FALSE;
WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
return FALSE;
}
if (ClassDescriptionSize < sizeof(UNICODE_NULL) || !ClassDescription) /* Retrieve the class description data and close the key */
dwLength = 0; rc = QueryRegistryValue(hKey, NULL, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
else
dwLength = ClassDescriptionSize * sizeof(WCHAR) - sizeof(UNICODE_NULL);
rc = RegQueryValueExW(hKey,
NULL,
NULL,
&dwRegType,
(LPBYTE)ClassDescription,
&dwLength);
RegCloseKey(hKey); RegCloseKey(hKey);
if (rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS)
/* Make sure we got the data */
if (rc != ERROR_SUCCESS)
{ {
SetLastError(rc); SetLastError(rc);
return FALSE; return FALSE;
} }
else if (dwRegType != REG_SZ)
/* Make sure the data is a string */
if (dwRegType != REG_SZ)
{ {
MyFree(Buffer);
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
if (RequiredSize) /* Determine the length of the class description */
*RequiredSize = dwLength / sizeof(WCHAR) + 1; dwLength /= sizeof(WCHAR);
if (ClassDescriptionSize * sizeof(WCHAR) >= dwLength + sizeof(UNICODE_NULL)) /* Count the null-terminator if none is present */
if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
dwLength++;
/* Inform the caller about the class description */
if ((ClassDescription != NULL) && (dwLength <= ClassDescriptionSize))
{ {
if (ClassDescriptionSize > sizeof(UNICODE_NULL)) memcpy(ClassDescription, Buffer, (dwLength - 1) * sizeof(WCHAR));
ClassDescription[ClassDescriptionSize / sizeof(WCHAR)] = UNICODE_NULL; ClassDescription[dwLength - 1] = UNICODE_NULL;
return TRUE;
} }
else
/* Inform the caller about the required size */
if (RequiredSize != NULL)
*RequiredSize = dwLength;
/* Clean up the buffer */
MyFree(Buffer);
/* Make sure the buffer was large enough */
if ((ClassDescription == NULL) || (dwLength > ClassDescriptionSize))
{ {
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
return TRUE;
} }
/*********************************************************************** /***********************************************************************
@ -2357,7 +2349,7 @@ HDEVINFO WINAPI SetupDiGetClassDevsExW(
if (!(flags & DIGCF_ALLCLASSES) && !class) if (!(flags & DIGCF_ALLCLASSES) && !class)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return NULL; return INVALID_HANDLE_VALUE;
} }
/* Create the deviceset if not set */ /* Create the deviceset if not set */