From 09a48bfbbfd056aa8929f29ca67a26d1e9e93ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Wed, 21 Dec 2005 14:43:02 +0000 Subject: [PATCH] Partly implement SetupDiInstallDeviceInterfaces svn path=/trunk/; revision=20284 --- reactos/lib/setupapi/devinst.c | 136 +++++++++++++++++++++++- reactos/lib/setupapi/install.c | 2 +- reactos/lib/setupapi/setupapi_private.h | 2 + 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/reactos/lib/setupapi/devinst.c b/reactos/lib/setupapi/devinst.c index c3130033977..6b8389dfeb3 100644 --- a/reactos/lib/setupapi/devinst.c +++ b/reactos/lib/setupapi/devinst.c @@ -7154,6 +7154,24 @@ cleanup: return ret; } +static BOOL +InstallOneInterface( + IN LPGUID InterfaceGuid, + IN LPCWSTR ReferenceString, + IN LPCWSTR InterfaceSection, + IN UINT InterfaceFlags) +{ + if (InterfaceFlags != 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + FIXME("Need to AddInterface(%s %s %s %u)\n", debugstr_guid(InterfaceGuid), + debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags); + return TRUE; +} + /*********************************************************************** * SetupDiInstallDeviceInterfaces (SETUPAPI.@) */ @@ -7162,12 +7180,122 @@ SetupDiInstallDeviceInterfaces( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData) { + struct DeviceInfoSet *list = NULL; + BOOL ret = FALSE; + TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData); - FIXME("SetupDiInstallDeviceInterfaces not implemented. Doing nothing\n"); - //SetLastError(ERROR_GEN_FAILURE); - //return FALSE; - return TRUE; + if (!DeviceInfoSet) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE) + SetLastError(ERROR_INVALID_HANDLE); + else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) + SetLastError(ERROR_INVALID_HANDLE); + else if (!DeviceInfoData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + struct DriverInfoElement *SelectedDriver; + SP_DEVINSTALL_PARAMS_W InstallParams; + WCHAR SectionName[MAX_PATH]; + DWORD SectionNameLength = 0; + INFCONTEXT ContextInterface; + LPWSTR InterfaceGuidString = NULL; + LPWSTR ReferenceString = NULL; + LPWSTR InterfaceSection = NULL; + UINT InterfaceFlags; + GUID InterfaceGuid; + BOOL Result; + + InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); + Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams); + if (!Result) + goto cleanup; + + SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved; + if (SelectedDriver == NULL) + { + SetLastError(ERROR_NO_DRIVER_SELECTED); + ret = FALSE; + goto cleanup; + } + + /* Get .Interfaces section name */ + Result = SetupDiGetActualSectionToInstallW( + SelectedDriver->InfFileDetails->hInf, + SelectedDriver->Details.SectionName, + SectionName, MAX_PATH, &SectionNameLength, NULL); + if (!Result || SectionNameLength > MAX_PATH - wcslen(L".Interfaces") - 1) + goto cleanup; + wcscat(SectionName, L".Interfaces"); + + ret = TRUE; + Result = SetupFindFirstLineW( + SelectedDriver->InfFileDetails->hInf, + SectionName, + L"AddInterface", + &ContextInterface); + while (ret && Result) + { + ret = GetStringField(&ContextInterface, 1, &InterfaceGuidString); + if (!ret) + goto cleanup; + else if (strlenW(InterfaceGuidString) != MAX_GUID_STRING_LEN - 1) + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + goto cleanup; + } + + InterfaceGuidString[MAX_GUID_STRING_LEN - 2] = '\0'; /* Replace the } by a NULL character */ + if (UuidFromStringW(&InterfaceGuidString[1], &InterfaceGuid) != RPC_S_OK) + { + /* Bad GUID, skip the entry */ + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + goto cleanup; + } + + ret = GetStringField(&ContextInterface, 2, &ReferenceString); + if (!ret) + goto cleanup; + + ret = GetStringField(&ContextInterface, 3, &InterfaceSection); + if (!ret) + goto cleanup; + + ret = SetupGetIntField( + &ContextInterface, + 4, /* Field index */ + &InterfaceFlags); + if (!ret) + { + if (GetLastError() == ERROR_INVALID_PARAMETER) + { + /* The field may be empty. Ignore the error */ + InterfaceFlags = 0; + ret = TRUE; + } + else + goto cleanup; + } + + /* Install Interface */ + ret = InstallOneInterface(&InterfaceGuid, ReferenceString, InterfaceSection, InterfaceFlags); + +cleanup: + MyFree(InterfaceGuidString); + MyFree(ReferenceString); + MyFree(InterfaceSection); + InterfaceGuidString = ReferenceString = InterfaceSection = NULL; + Result = SetupFindNextMatchLineW(&ContextInterface, L"AddInterface", &ContextInterface); + } + } + + TRACE("Returning %d\n", ret); + return ret; } BOOL diff --git a/reactos/lib/setupapi/install.c b/reactos/lib/setupapi/install.c index 5b329713df0..fa03025c170 100644 --- a/reactos/lib/setupapi/install.c +++ b/reactos/lib/setupapi/install.c @@ -1109,7 +1109,7 @@ static BOOL GetIntField( HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *v } -static BOOL GetStringField( PINFCONTEXT context, DWORD index, PWSTR *value) +BOOL GetStringField( PINFCONTEXT context, DWORD index, PWSTR *value) { DWORD RequiredSize; BOOL ret; diff --git a/reactos/lib/setupapi/setupapi_private.h b/reactos/lib/setupapi/setupapi_private.h index a56374b6af7..3f8a8f5a6b0 100644 --- a/reactos/lib/setupapi/setupapi_private.h +++ b/reactos/lib/setupapi/setupapi_private.h @@ -216,4 +216,6 @@ extern OSVERSIONINFOW OsVersionInfo; DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst); +BOOL GetStringField( PINFCONTEXT context, DWORD index, PWSTR *value); + #endif /* __SETUPAPI_PRIVATE_H */