Implement SetupDiGetDeviceInfoListClass
Parse 'Include' and 'Needs' directives in SetupInstallFromInfSectionW and when installing services
Modified: trunk/reactos/lib/setupapi/devinst.c
Modified: trunk/reactos/lib/setupapi/install.c
Modified: trunk/reactos/lib/setupapi/setupapi.spec

Modified: trunk/reactos/lib/setupapi/devinst.c
--- trunk/reactos/lib/setupapi/devinst.c	2005-12-19 13:26:53 UTC (rev 20270)
+++ trunk/reactos/lib/setupapi/devinst.c	2005-12-19 15:08:55 UTC (rev 20271)
@@ -3184,10 +3184,70 @@
         OUT PBOOL pRebootRequired OPTIONAL)
 {
     INFCONTEXT ContextService;
+    INFCONTEXT ContextInclude;
     DWORD RequiredSize;
     INT Flags;
     BOOL ret = FALSE;
 
+    /* Parse 'Include' line */
+    if (SetupFindFirstLineW(hInf, SectionName, L"Include", &ContextInclude))
+    {
+        DWORD Index = 1;
+        while (TRUE)
+        {
+            static WCHAR szBuffer[MAX_PATH];
+            PWSTR pBuffer = NULL;
+            DWORD required;
+
+            ret = SetupGetStringFieldW(&ContextInclude, Index, szBuffer, MAX_PATH, &required);
+            if (!ret && GetLastError() == ERROR_INVALID_PARAMETER)
+                break;
+            else if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                pBuffer = MyMalloc(required);
+                ret = SetupGetStringFieldW(&ContextInclude, Index, pBuffer, required, &required);
+            }
+            if (ret)
+                ret = SetupOpenAppendInfFileW(pBuffer ? pBuffer : szBuffer, hInf, NULL);
+
+            MyFree(pBuffer);
+            if (!ret)
+                goto done;
+            Index++;
+        }
+    }
+
+    /* Parse 'Needs' line */
+    if (SetupFindFirstLineW(hInf, SectionName, L"Needs", &ContextInclude))
+    {
+        DWORD Index = 1;
+        while (TRUE)
+        {
+            static WCHAR szBuffer[MAX_PATH];
+            PWSTR pBuffer = NULL;
+            DWORD required;
+
+            ret = SetupGetStringFieldW(&ContextInclude, Index, szBuffer, MAX_PATH, &required);
+            if (!ret && GetLastError() == ERROR_INVALID_PARAMETER)
+                break;
+            else if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                pBuffer = MyMalloc(required);
+                ret = SetupGetStringFieldW(&ContextInclude, Index, pBuffer, required, &required);
+            }
+            if (ret)
+            {
+                ret = InstallServicesSection(hInf, pBuffer ? pBuffer : szBuffer,
+                    DeviceInfoSet, DeviceInfoData, pAssociatedService, pRebootRequired);
+            }
+
+            MyFree(pBuffer);
+            if (!ret)
+                goto done;
+            Index++;
+        }
+    }
+
     ret = SetupFindFirstLineW(hInf, SectionName, NULL, &ContextService);
     while (ret)
     {
@@ -4133,6 +4193,35 @@
 }
 
 /***********************************************************************
+ *		SetupDiGetDeviceInfoListClass  (SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetDeviceInfoListClass(
+        IN HDEVINFO DeviceInfoSet,
+        OUT LPGUID ClassGuid)
+{
+    struct DeviceInfoSet *list;
+    BOOL ret = FALSE;
+
+    TRACE("%p %p\n", DeviceInfoSet, ClassGuid);
+
+    if (!DeviceInfoSet)
+        SetLastError(ERROR_INVALID_HANDLE);
+    else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
+        SetLastError(ERROR_INVALID_HANDLE);
+    else if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
+        SetLastError(ERROR_NO_ASSOCIATED_CLASS);
+    else
+    {
+        memcpy(&ClassGuid, &list->ClassGuid, sizeof(GUID));
+
+        ret = TRUE;
+    }
+
+    TRACE("Returning %d\n", ret);
+    return ret;
+}
+
+/***********************************************************************
  *		SetupDiGetDeviceInfoListDetailW  (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiGetDeviceInfoListDetailW(

Modified: trunk/reactos/lib/setupapi/install.c
--- trunk/reactos/lib/setupapi/install.c	2005-12-19 13:26:53 UTC (rev 20270)
+++ trunk/reactos/lib/setupapi/install.c	2005-12-19 15:08:55 UTC (rev 20271)
@@ -64,6 +64,8 @@
 static const WCHAR RegisterDlls[]    = {'R','e','g','i','s','t','e','r','D','l','l','s',0};
 static const WCHAR UnregisterDlls[]  = {'U','n','r','e','g','i','s','t','e','r','D','l','l','s',0};
 static const WCHAR ProfileItems[]    = {'P','r','o','f','i','l','e','I','t','e','m','s',0};
+static const WCHAR Include[]         = {'I','n','c','l','u','d','e',0};
+static const WCHAR Needs[]           = {'N','e','e','d','s',0};
 
 
 /***********************************************************************
@@ -789,6 +791,67 @@
                                          PSP_FILE_CALLBACK_W callback, PVOID context,
                                          HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
 {
+    INFCONTEXT include_context;
+
+    /* Parse 'Include' line */
+    if (SetupFindFirstLineW( hinf, section, Include, &include_context ))
+    {
+        DWORD index = 1;
+        while (TRUE)
+        {
+            static WCHAR szBuffer[MAX_PATH];
+            PWSTR pBuffer = NULL;
+            DWORD required;
+            BOOL ok;
+
+            ok = SetupGetStringFieldW( &include_context, index, szBuffer, MAX_PATH, &required );
+            if (!ok && GetLastError() == ERROR_INVALID_PARAMETER)
+                break;
+            else if (!ok && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                pBuffer = MyMalloc(required);
+                ok = SetupGetStringFieldW( &include_context, index, pBuffer, required, &required );
+            }
+            if (ok)
+                ok = SetupOpenAppendInfFileW( pBuffer ? pBuffer : szBuffer, hinf, NULL );
+
+            MyFree(pBuffer);
+            if (!ok) return FALSE;
+            index++;
+        }
+    }
+
+    /* Parse 'Needs' line */
+    if (SetupFindFirstLineW( hinf, section, Needs, &include_context ))
+    {
+        DWORD index = 1;
+        while (TRUE)
+        {
+            static WCHAR szBuffer[MAX_PATH];
+            PWSTR pBuffer = NULL;
+            DWORD required;
+            BOOL ok;
+
+            ok = SetupGetStringFieldW( &include_context, index, szBuffer, MAX_PATH, &required );
+            if (!ok && GetLastError() == ERROR_INVALID_PARAMETER)
+                break;
+            else if (!ok && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                pBuffer = MyMalloc(required);
+                ok = SetupGetStringFieldW( &include_context, index, pBuffer, required, &required );
+            }
+            if (ok)
+            {
+                ok = SetupInstallFromInfSectionW( owner, hinf, pBuffer ? pBuffer : szBuffer,
+                    flags, key_root, src_root, copy_flags, callback, context, devinfo, devinfo_data );
+            }
+
+            MyFree(pBuffer);
+            if (!ok) return FALSE;
+            index++;
+        }
+    }
+
     if (flags & SPINST_FILES)
     {
         struct files_callback_info info;

Modified: trunk/reactos/lib/setupapi/setupapi.spec
--- trunk/reactos/lib/setupapi/setupapi.spec	2005-12-19 13:26:53 UTC (rev 20270)
+++ trunk/reactos/lib/setupapi/setupapi.spec	2005-12-19 15:08:55 UTC (rev 20271)
@@ -320,7 +320,7 @@
 @ stdcall SetupDiGetClassImageListExW(ptr wstr ptr)
 @ stub SetupDiGetClassInstallParamsA
 @ stub SetupDiGetClassInstallParamsW
-@ stub SetupDiGetDeviceInfoListClass
+@ stdcall SetupDiGetDeviceInfoListClass(ptr ptr)
 @ stdcall SetupDiGetDeviceInfoListDetailA(ptr ptr)
 @ stdcall SetupDiGetDeviceInfoListDetailW(ptr ptr)
 @ stdcall SetupDiGetDeviceInstallParamsA(ptr ptr ptr)