Implement SetupInstallServicesFromInfSectionExW
Process {DDInstall}.HW section in SetupDiInstallDevice
Modified: trunk/reactos/lib/setupapi/devinst.c
Modified: trunk/reactos/lib/setupapi/install.c
Modified: trunk/reactos/lib/setupapi/stubs.c

Modified: trunk/reactos/lib/setupapi/devinst.c
--- trunk/reactos/lib/setupapi/devinst.c	2005-09-27 04:53:33 UTC (rev 18118)
+++ trunk/reactos/lib/setupapi/devinst.c	2005-09-27 08:52:17 UTC (rev 18119)
@@ -4389,9 +4389,12 @@
     DWORD RequiredSize;
     HINF hInf = NULL;
     LPCWSTR AssociatedService = NULL;
+    LPWSTR pSectionName = NULL;
     BOOL RebootRequired = FALSE;
     HKEY hEnumKey, hKey;
     LONG rc;
+    HWND hWnd;
+    PVOID callback_context;
 
     TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
 
@@ -4419,9 +4422,15 @@
     /* FIXME: If DI_FLAGSEX_SETFAILEDINSTALL is set, set FAILEDINSTALL flag in ConfigFlags registry and exit */
 
     if (DeviceInfoData)
+    {
         DriverInfo = ((struct DeviceInfoElement *)DeviceInfoData->Reserved)->SelectedDriver;
+        hWnd = ((struct DeviceInfoElement *)DeviceInfoData->Reserved)->hwndParent;
+    }
     else
+    {
         DriverInfo = ((struct DeviceInfoSet *)DeviceInfoSet)->SelectedDriver;
+        hWnd = ((struct DeviceInfoSet *)DeviceInfoSet)->hwndParent;
+    }
     FileTimeToSystemTime(&DriverInfo->Info.DriverDate, &DriverDate);
 
     hInf = SetupOpenInfFileW(DriverInfo->InfPath, NULL, INF_STYLE_WIN4, NULL);
@@ -4435,6 +4444,7 @@
         SetupCloseInfFile(hInf);
         return FALSE;
     }
+    pSectionName = &SectionName[wcslen(SectionName)];
 
     /* Create driver key information */
     FIXME("FIXME: Create driver key information\n");
@@ -4442,7 +4452,6 @@
     /* Write information to driver key */
     FIXME("FIXME: Write information to driver key\n");
     FIXME("DriverDate      : '%u-%u-%u'\n", 0, DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
-    FIXME("DriverDateData  :"); { ULONG i; for (i = 0; i < sizeof(DriverInfo->Info.DriverDate); i++) DbgPrint(" %02x", ((PCHAR)&DriverInfo->Info.DriverDate)[i] & 0xff); } DbgPrint("\n");
     FIXME("DriverDesc      : '%S'\n", DriverInfo->Info.Description);
     FIXME("DriverVersion   : '%u.%u.%u.%u'\n", DriverInfo->Info.DriverVersion & 0xff, (DriverInfo->Info.DriverVersion >> 8) & 0xff, (DriverInfo->Info.DriverVersion >> 16) & 0xff, (DriverInfo->Info.DriverVersion >> 24) & 0xff);
     FIXME("InfPath         : '%S'\n", DriverInfo->InfPath);
@@ -4451,8 +4460,8 @@
     FIXME("MatchingDeviceId: '%S'\n", L"???"); /* FIXME */
     FIXME("ProviderName    : '%S'\n", DriverInfo->Info.ProviderName);
 
-    /* Install services */
-    wcscat(SectionName, L".Services");
+    /* Install .Services section */
+    wcscpy(pSectionName, L".Services");
     Result = SetupFindFirstLineW(hInf, SectionName, NULL, &ContextService);
     while (Result)
     {
@@ -4517,7 +4526,7 @@
                goto cleanup;
         }
         SetLastError(ERROR_SUCCESS);
-        Result = SetupInstallServicesFromInfSectionExW(hInf, ServiceSection, Flags, DeviceInfoSet, DeviceInfoData, NULL, NULL);
+        Result = SetupInstallServicesFromInfSectionExW(hInf, ServiceSection, Flags, DeviceInfoSet, DeviceInfoData, ServiceName, NULL);
         if (Result && (Flags & SPSVCINST_ASSOCSERVICE))
         {
             AssociatedService = ServiceName;
@@ -4540,7 +4549,7 @@
     /* Copy .inf file to Inf\ directory */
     FIXME("FIXME: Copy .inf file to Inf\\ directory\n"); /* SetupCopyOEMInf */
 
-    /* Write information to enum key */
+    /* Open enum key */
     rc = RegOpenKeyExW(DevInfoSet->HKLM,
         EnumKeyName,
         0,
@@ -4567,14 +4576,32 @@
        SetupCloseInfFile(hInf);
        return FALSE;
     }
+
+    /* Install .HW section */
+    wcscpy(pSectionName, L".HW");
+    callback_context = SetupInitDefaultQueueCallback(hWnd);
+    Result = SetupInstallFromInfSectionW(hWnd, hInf, SectionName,
+        SPINST_REGISTRY, hKey, NULL, 0,
+        SetupDefaultQueueCallbackW, callback_context,
+        NULL, NULL);
+    SetupTermDefaultQueueCallback(callback_context);
+    if (!Result)
+    {
+        RegCloseKey(hKey);
+        HeapFree(GetProcessHeap(), 0, (LPWSTR)AssociatedService);
+        SetupCloseInfFile(hInf);
+        return FALSE;
+    }
+
+    /* Write information to enum key */
     FIXME("FIXME: Write information to enum key\n");
     FIXME("ParentIdPrefix  : '%S'\n", L"0000"); /* FIXME */
-    //FIXME("Service         : '%S'\n", AssociatedService);
+    TRACE("Service         : '%S'\n", AssociatedService);
     FIXME("Class           : '%S'\n", L"???"); /* FIXME: SetupDiGetINFClass */
     FIXME("ClassGUID       : '%S'\n", L"???"); /* FIXME: SetupDiGetINFClass */
-    //FIXME("DeviceDesc      : '%S'\n", DriverInfo->Info.Description);
+    TRACE("DeviceDesc      : '%S'\n", DriverInfo->Info.Description);
     FIXME("Driver          : '%S'\n", L"???"); /* FIXME: autogenerated key */
-    //FIXME("Mfg             : '%S'\n", DriverInfo->Info.MfgName);
+    TRACE("Mfg             : '%S'\n", DriverInfo->Info.MfgName);
     rc = RegSetValueEx(hKey, L"Service", 0, REG_SZ, (const BYTE *)AssociatedService, (wcslen(AssociatedService) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS)
         rc = RegSetValueEx(hKey, L"DeviceDesc", 0, REG_SZ, (const BYTE *)DriverInfo->Info.Description, (wcslen(DriverInfo->Info.Description) + 1) * sizeof(WCHAR));

Modified: trunk/reactos/lib/setupapi/install.c
--- trunk/reactos/lib/setupapi/install.c	2005-09-27 04:53:33 UTC (rev 18118)
+++ trunk/reactos/lib/setupapi/install.c	2005-09-27 08:52:17 UTC (rev 18119)
@@ -993,3 +993,136 @@
 
     return ret;
 }
+
+
+static BOOL GetLineText( HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR *value)
+{
+    DWORD required;
+    PWSTR buf = NULL;
+
+    *value = NULL;
+
+    if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, NULL, 0, &required )
+        && GetLastError() != ERROR_INSUFFICIENT_BUFFER )
+        return FALSE;
+
+    buf = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) );
+    if ( ! buf )
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    if (! SetupGetLineTextW( NULL, hinf, section_name, key_name, buf, required, &required ) )
+    {
+        HeapFree( GetProcessHeap(), 0, buf );
+        return FALSE;
+    }
+
+    *value = buf;
+    return TRUE;
+}
+
+
+static BOOL GetIntField( HINF hinf, PCWSTR section_name, PCWSTR key_name, INT *value)
+{
+    LPWSTR buffer, end;
+    INT res;
+
+    if (! GetLineText( hinf, section_name, key_name, &buffer ) )
+        return FALSE;
+
+    res = wcstol( buffer, &end, 0 );
+    if (end != buffer && !*end)
+    {
+        HeapFree(GetProcessHeap(), 0, buffer);
+        *value = res;
+        return TRUE;
+    }
+    else
+    {
+        HeapFree(GetProcessHeap(), 0, buffer);
+        SetLastError( ERROR_INVALID_DATA );
+        return FALSE;
+    }
+}
+
+
+/***********************************************************************
+ *		SetupInstallServicesFromInfSectionExW  (SETUPAPI.@)
+ */
+BOOL WINAPI SetupInstallServicesFromInfSectionExW( HINF hinf, PCWSTR sectionname, DWORD flags, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data, PVOID reserved1, PVOID reserved2 )
+{
+    SC_HANDLE hSCManager, hService;
+    LPWSTR ServiceBinary, LoadOrderGroup;
+    LPWSTR DisplayName, Description, Dependencies;
+    INT ServiceType, StartType, ErrorControl;
+
+    TRACE("%p, %s, 0x%lx, %p, %p, %p, %p\n", hinf, debugstr_w(sectionname),
+        flags, devinfo, devinfo_data, reserved1, reserved2);
+
+    if (!reserved1)
+    {
+        /* FIXME: I don't know how to get the service name. ATM, just fail the call */
+        DPRINT1("Service name not specified!\n");
+        return FALSE;
+    }
+    /* FIXME: use the flags parameters */
+    /* FIXME: use DeviceInfoSet, DeviceInfoData parameters */
+
+    if (!GetIntField(hinf, sectionname, L"ServiceType", &ServiceType))
+        return FALSE;
+    if (!GetIntField(hinf, sectionname, L"StartType", &StartType))
+        return FALSE;
+    if (!GetIntField(hinf, sectionname, L"ErrorControl", &ErrorControl))
+        return FALSE;
+
+    hSCManager = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
+    if (hSCManager == NULL)
+        return FALSE;
+
+    if (!GetLineText(hinf, sectionname, L"ServiceBinary", &ServiceBinary))
+    {
+        CloseServiceHandle(hSCManager);
+        return FALSE;
+    }
+    if (!GetLineText(hinf, sectionname, L"LoadOrderGroup", &LoadOrderGroup))
+    {
+        CloseServiceHandle(hSCManager);
+        HeapFree(GetProcessHeap(), 0, ServiceBinary);
+        return FALSE;
+    }
+
+    /* Don't check return value, as these fields are optional and
+     * GetLineText initialize output parameter even on failure */
+    GetLineText(hinf, sectionname, L"DisplayName", &DisplayName);
+    GetLineText(hinf, sectionname, L"Description", &Description);
+    GetLineText(hinf, sectionname, L"Dependencies", &Dependencies);
+
+    hService = CreateServiceW(
+        hSCManager,
+        reserved1,
+        Description,
+        0,
+        ServiceType,
+        StartType,
+        ErrorControl,
+        ServiceBinary,
+        LoadOrderGroup,
+        NULL,
+        Dependencies,
+        NULL, NULL);
+    HeapFree(GetProcessHeap(), 0, ServiceBinary);
+    HeapFree(GetProcessHeap(), 0, LoadOrderGroup);
+    HeapFree(GetProcessHeap(), 0, DisplayName);
+    HeapFree(GetProcessHeap(), 0, Description);
+    HeapFree(GetProcessHeap(), 0, Dependencies);
+    if (hService == NULL)
+    {
+        CloseServiceHandle(hSCManager);
+        return FALSE;
+    }
+    CloseServiceHandle(hService);
+
+    return CloseServiceHandle(hSCManager);
+}

Modified: trunk/reactos/lib/setupapi/stubs.c
--- trunk/reactos/lib/setupapi/stubs.c	2005-09-27 04:53:33 UTC (rev 18118)
+++ trunk/reactos/lib/setupapi/stubs.c	2005-09-27 08:52:17 UTC (rev 18119)
@@ -125,15 +125,6 @@
 }
 
 /***********************************************************************
- *		SetupInstallServicesFromInfSectionExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupInstallServicesFromInfSectionExW( HINF hinf, PCWSTR sectionname, DWORD flags, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data, PVOID reserved1, PVOID reserved2 )
-{
-    FIXME("Stub %p, %s, 0x%lx, %p, %p, %p, %p\n", hinf, debugstr_w(sectionname), flags, devinfo, devinfo_data, reserved1, reserved2);
-    return TRUE;
-}
-
-/***********************************************************************
  *		SetupTerminateFileLog(SETUPAPI.@)
  */
 BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle)