diff --git a/reactos/lib/setupapi/parser.c b/reactos/lib/setupapi/parser.c index 49f5949a6a3..1fdb710159b 100644 --- a/reactos/lib/setupapi/parser.c +++ b/reactos/lib/setupapi/parser.c @@ -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)