[BATT] Add the composite battery installer
authorEric Kohl <eric.kohl@reactos.org>
Mon, 25 Apr 2022 21:33:25 +0000 (23:33 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 25 Apr 2022 21:33:51 +0000 (23:33 +0200)
dll/win32/batt/CMakeLists.txt
dll/win32/batt/batt.c

index cf77518..ac11165 100644 (file)
@@ -7,5 +7,5 @@ add_library(batt MODULE
     ${CMAKE_CURRENT_BINARY_DIR}/batt.def)
 
 set_module_type(batt win32dll UNICODE)
-add_importlibs(batt msvcrt kernel32 ntdll)
+add_importlibs(batt setupapi msvcrt kernel32 ntdll)
 add_cd_file(TARGET batt DESTINATION reactos/system32 FOR all)
index 03695e3..59def54 100644 (file)
 #include <winuser.h>
 #include <setupapi.h>
 
+#include <initguid.h>
+#include <devguid.h>
+
 #define NDEBUG
 #include <debug.h>
 
+static
+DWORD
+InstallCompositeBattery(
+    _In_ HDEVINFO DeviceInfoSet,
+    _In_opt_ PSP_DEVINFO_DATA DeviceInfoData,
+    _In_ PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
+{
+    WCHAR szDeviceId[32];
+    SP_DRVINFO_DATA DriverInfoData;
+    HDEVINFO NewDeviceInfoSet = INVALID_HANDLE_VALUE;
+    PSP_DEVINFO_DATA NewDeviceInfoData = NULL;
+    BOOL  bDeviceRegistered = FALSE, bHaveDriverInfoList = FALSE;
+    DWORD dwError = ERROR_SUCCESS;
 
-BOOL
+    DPRINT("InstallCompositeBattery(%p %p %p)\n",
+           DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
+
+    NewDeviceInfoSet = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_SYSTEM,
+                                                   DeviceInstallParams->hwndParent);
+    if (NewDeviceInfoSet == INVALID_HANDLE_VALUE)
+    {
+        DPRINT1("SetupDiCreateDeviceInfoList() failed (Error %lu)\n", GetLastError());
+        return GetLastError();
+    }
+    NewDeviceInfoData = HeapAlloc(GetProcessHeap(),
+                                  HEAP_ZERO_MEMORY,
+                                  sizeof(SP_DEVINFO_DATA));
+    if (NewDeviceInfoData == NULL)
+    {
+        dwError = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    NewDeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
+    if (!SetupDiCreateDeviceInfoW(NewDeviceInfoSet,
+                                  L"Root\\COMPOSITE_BATTERY\\0000",
+                                  &GUID_DEVCLASS_SYSTEM,
+                                  NULL,
+                                  DeviceInstallParams->hwndParent,
+                                  0,
+                                  NewDeviceInfoData))
+    {
+        dwError = GetLastError();
+        if (dwError == ERROR_DEVINST_ALREADY_EXISTS)
+        {
+            dwError = ERROR_SUCCESS;
+            goto done;
+        }
+
+        DPRINT1("SetupDiCreateDeviceInfoW() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    if (!SetupDiRegisterDeviceInfo(NewDeviceInfoSet,
+                                   NewDeviceInfoData,
+                                   0,
+                                   NULL,
+                                   NULL,
+                                   NULL))
+    {
+        dwError = GetLastError();
+        DPRINT1("SetupDiRegisterDeviceInfo() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    bDeviceRegistered = TRUE;
+
+    ZeroMemory(szDeviceId, sizeof(szDeviceId));
+    wcscpy(szDeviceId, L"COMPOSITE_BATTERY");
+
+    if (!SetupDiSetDeviceRegistryPropertyW(NewDeviceInfoSet,
+                                           NewDeviceInfoData,
+                                           SPDRP_HARDWAREID,
+                                           (PBYTE)szDeviceId,
+                                           (wcslen(szDeviceId) + 2) * sizeof(WCHAR)))
+    {
+        dwError = GetLastError();
+        DPRINT1("SetupDiSetDeviceRegistryPropertyW() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    if (!SetupDiBuildDriverInfoList(NewDeviceInfoSet,
+                                    NewDeviceInfoData,
+                                    SPDIT_COMPATDRIVER))
+    {
+        dwError = GetLastError();
+        DPRINT1("SetupDiBuildDriverInfoList() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    bHaveDriverInfoList = TRUE;
+
+    DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
+    if (!SetupDiEnumDriverInfo(NewDeviceInfoSet,
+                               NewDeviceInfoData,
+                               SPDIT_COMPATDRIVER,
+                               0,
+                               &DriverInfoData))
+    {
+        dwError = GetLastError();
+        DPRINT1("SetupDiEnumDriverInfo() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    if (!SetupDiSetSelectedDriver(NewDeviceInfoSet,
+                                  NewDeviceInfoData,
+                                  &DriverInfoData))
+    {
+        dwError = GetLastError();
+        DPRINT1("SetupDiSetSelectedDriver() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    if (!SetupDiInstallDevice(NewDeviceInfoSet,
+                              NewDeviceInfoData))
+    {
+        dwError = GetLastError();
+        DPRINT1("SetupDiInstallDevice() failed (Error %lu 0x%08lx)\n", dwError, dwError);
+        goto done;
+    }
+
+    dwError = ERROR_SUCCESS;
+
+done:
+    if (bHaveDriverInfoList)
+        SetupDiDestroyDriverInfoList(NewDeviceInfoSet,
+                                     NewDeviceInfoData,
+                                     SPDIT_COMPATDRIVER);
+
+    if (bDeviceRegistered)
+        SetupDiDeleteDeviceInfo(NewDeviceInfoSet,
+                                NewDeviceInfoData);
+
+    if (NewDeviceInfoData != NULL)
+        HeapFree(GetProcessHeap(), 0, NewDeviceInfoData);
+
+    if (NewDeviceInfoSet != INVALID_HANDLE_VALUE)
+        SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);
+
+    return dwError;
+}
+
+
+DWORD
 WINAPI
-DllMain(HINSTANCE hinstDll,
-        DWORD dwReason,
-        LPVOID reserved)
+BatteryClassInstall(
+    _In_ DI_FUNCTION InstallFunction,
+    _In_ HDEVINFO DeviceInfoSet,
+    _In_opt_ PSP_DEVINFO_DATA DeviceInfoData)
 {
-    switch (dwReason)
+    SP_DEVINSTALL_PARAMS_W DeviceInstallParams;
+    DWORD dwError;
+
+    DPRINT("BatteryClassInstall(%u %p %p)\n",
+           InstallFunction, DeviceInfoSet, DeviceInfoData);
+
+    if (InstallFunction != DIF_INSTALLDEVICE)
+        return ERROR_DI_DO_DEFAULT;
+
+    DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
+    if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet,
+                                        DeviceInfoData,
+                                        &DeviceInstallParams))
     {
-        case DLL_PROCESS_ATTACH:
-            DisableThreadLibraryCalls(hinstDll);
-            break;
+        DPRINT1("SetupDiGetDeviceInstallParamsW() failed (Error %lu)\n", GetLastError());
+        return GetLastError();
+    }
 
-        case DLL_PROCESS_DETACH:
-            break;
+    /* Install the composite battery device */
+    dwError = InstallCompositeBattery(DeviceInfoSet,
+                                      DeviceInfoData,
+                                      &DeviceInstallParams);
+    if (dwError == ERROR_SUCCESS)
+    {
+        /* Install the battery device */
+        dwError = ERROR_DI_DO_DEFAULT;
     }
 
-   return TRUE;
+    return dwError;
 }
 
 
@@ -55,18 +220,24 @@ BatteryClassCoInstaller(IN DI_FUNCTION InstallFunction,
 }
 
 
-DWORD
+BOOL
 WINAPI
-BatteryClassInstall(IN DI_FUNCTION InstallFunction,
-                    IN HDEVINFO DeviceInfoSet,
-                    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+DllMain(
+    _In_ HINSTANCE hinstDll,
+    _In_ DWORD dwReason,
+    _In_ LPVOID reserved)
 {
-    switch (InstallFunction)
+    switch (dwReason)
     {
-        default:
-            DPRINT("Install function %u ignored\n", InstallFunction);
-            return ERROR_DI_DO_DEFAULT;
+        case DLL_PROCESS_ATTACH:
+            DisableThreadLibraryCalls(hinstDll);
+            break;
+
+        case DLL_PROCESS_DETACH:
+            break;
     }
+
+   return TRUE;
 }
 
 /* EOF */