mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 15:36:04 +00:00
[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:
parent
1cd9389032
commit
916ec376d6
1 changed files with 44 additions and 52 deletions
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue