Support optional Class parameter in SetupOpenInfFileW

svn path=/trunk/; revision=19243
This commit is contained in:
Hervé Poussineau 2005-11-15 08:55:31 +00:00
parent 4c4a431c18
commit ab4ca6fcf8

View file

@ -899,7 +899,7 @@ static void append_inf_file( struct inf_file *parent, struct inf_file *child )
*
* parse an INF file.
*/
static struct inf_file *parse_file( HANDLE handle, const WCHAR *class, UINT *error_line )
static struct inf_file *parse_file( HANDLE handle, UINT *error_line )
{
void *buffer;
DWORD err = 0;
@ -912,8 +912,6 @@ static struct inf_file *parse_file( HANDLE handle, const WCHAR *class, UINT *err
NtClose( mapping );
if (!buffer) return NULL;
if (class) FIXME( "class %s not supported yet\n", debugstr_w(class) );
if (!(file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*file) )))
{
err = ERROR_NOT_ENOUGH_MEMORY;
@ -1042,6 +1040,72 @@ HINF WINAPI SetupOpenInfFileA( PCSTR name, PCSTR class, DWORD style, UINT *error
}
static BOOL
GetInfClassW(
IN HINF hInf,
OUT LPGUID ClassGuid,
OUT PWSTR ClassName,
IN DWORD ClassNameSize,
OUT PDWORD RequiredSize OPTIONAL)
{
DWORD requiredSize;
WCHAR guidW[MAX_GUID_STRING_LEN + 1];
BOOL ret = FALSE;
/* Read class Guid */
if (!SetupGetLineTextW(NULL, hInf, L"Version", L"ClassGUID", guidW, sizeof(guidW), NULL))
goto cleanup;
guidW[37] = '\0'; /* Replace the } by a NULL character */
if (UuidFromStringW(&guidW[1], ClassGuid) != RPC_S_OK)
goto cleanup;
/* Read class name */
ret = SetupGetLineTextW(NULL, hInf, L"Version", L"Class", ClassName, ClassNameSize, &requiredSize);
if (ret && ClassName == NULL && ClassNameSize == 0)
{
if (RequiredSize)
*RequiredSize = requiredSize;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
ret = FALSE;
goto cleanup;
}
if (!ret)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (RequiredSize)
*RequiredSize = requiredSize;
goto cleanup;
}
else if (!SetupDiClassNameFromGuidW(ClassGuid, ClassName, ClassNameSize, &requiredSize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (RequiredSize)
*RequiredSize = requiredSize;
goto cleanup;
}
/* Return a NULL class name */
if (RequiredSize)
*RequiredSize = 1;
if (ClassNameSize < 1)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
goto cleanup;
}
memcpy(ClassGuid, &GUID_NULL, sizeof(GUID));
*ClassName = UNICODE_NULL;
}
}
ret = TRUE;
cleanup:
TRACE("Returning %d\n", ret);
return ret;
}
/***********************************************************************
* SetupOpenInfFileW (SETUPAPI.@)
*/
@ -1091,7 +1155,7 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err
if (handle != INVALID_HANDLE_VALUE)
{
file = parse_file( handle, class, error );
file = parse_file( handle, error );
CloseHandle( handle );
}
if (!file)
@ -1102,6 +1166,37 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err
TRACE( "%s -> %p\n", debugstr_w(path), file );
file->src_root = path;
if ((p = strrchrW( path, '\\' ))) p[1] = 0; /* remove file name */
if (class)
{
GUID ClassGuid;
LPWSTR ClassName = HeapAlloc(GetProcessHeap(), 0, (strlenW(class) + 1) * sizeof(WCHAR));
if (!ClassName)
{
/* Not enough memory */
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
SetupCloseInfFile((HINF)file);
return NULL;
}
else if (!GetInfClassW((HINF)file, &ClassGuid, ClassName, strlenW(class) + 1, NULL))
{
/* Unable to get class name in .inf file */
HeapFree(GetProcessHeap(), 0, ClassName);
SetLastError(ERROR_CLASS_MISMATCH);
SetupCloseInfFile((HINF)file);
return NULL;
}
else if (strcmpW(class, ClassName) != 0)
{
/* Provided name name is not the expected one */
HeapFree(GetProcessHeap(), 0, ClassName);
SetLastError(ERROR_CLASS_MISMATCH);
SetupCloseInfFile((HINF)file);
return NULL;
}
HeapFree(GetProcessHeap(), 0, ClassName);
}
SetLastError( 0 );
return (HINF)file;
}
@ -2111,8 +2206,6 @@ SetupDiGetINFClassW(
OUT PDWORD RequiredSize OPTIONAL)
{
HINF hInf = INVALID_HANDLE_VALUE;
DWORD requiredSize;
WCHAR guidW[MAX_GUID_STRING_LEN + 1];
BOOL ret = FALSE;
TRACE("%S %p %p %ld %p\n", InfName, ClassGuid,
@ -2123,53 +2216,7 @@ SetupDiGetINFClassW(
if (hInf == INVALID_HANDLE_VALUE)
goto cleanup;
/* Read class Guid */
if (!SetupGetLineTextW(NULL, hInf, L"Version", L"ClassGUID", guidW, sizeof(guidW), NULL))
goto cleanup;
guidW[37] = '\0'; /* Replace the } by a NULL character */
if (UuidFromStringW(&guidW[1], ClassGuid) != RPC_S_OK)
goto cleanup;
/* Read class name */
ret = SetupGetLineTextW(NULL, hInf, L"Version", L"Class", ClassName, ClassNameSize, &requiredSize);
if (ret && ClassName == NULL && ClassNameSize == 0)
{
if (RequiredSize)
*RequiredSize = requiredSize;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
ret = FALSE;
goto cleanup;
}
if (!ret)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (RequiredSize)
*RequiredSize = requiredSize;
goto cleanup;
}
else if (!SetupDiClassNameFromGuidW(ClassGuid, ClassName, ClassNameSize, &requiredSize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (RequiredSize)
*RequiredSize = requiredSize;
goto cleanup;
}
/* Return a NULL class name */
if (RequiredSize)
*RequiredSize = 1;
if (ClassNameSize < 1)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
goto cleanup;
}
memcpy(ClassGuid, &GUID_NULL, sizeof(GUID));
*ClassName = UNICODE_NULL;
}
}
ret = TRUE;
ret = GetInfClassW(hInf, ClassGuid, ClassName, ClassNameSize, RequiredSize);
cleanup:
if (hInf != INVALID_HANDLE_VALUE)