diff --git a/dll/win32/batt/CMakeLists.txt b/dll/win32/batt/CMakeLists.txt index cf775185b37..ac11165ce96 100644 --- a/dll/win32/batt/CMakeLists.txt +++ b/dll/win32/batt/CMakeLists.txt @@ -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) diff --git a/dll/win32/batt/batt.c b/dll/win32/batt/batt.c index 03695e319be..59def5430a7 100644 --- a/dll/win32/batt/batt.c +++ b/dll/win32/batt/batt.c @@ -15,27 +15,192 @@ #include #include +#include +#include + #define NDEBUG #include - -BOOL -WINAPI -DllMain(HINSTANCE hinstDll, - DWORD dwReason, - LPVOID reserved) +static +DWORD +InstallCompositeBattery( + _In_ HDEVINFO DeviceInfoSet, + _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, + _In_ PSP_DEVINSTALL_PARAMS_W DeviceInstallParams) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDll); - break; + 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; - case DLL_PROCESS_DETACH: - break; + 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; } - return TRUE; + 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 +BatteryClassInstall( + _In_ DI_FUNCTION InstallFunction, + _In_ HDEVINFO DeviceInfoSet, + _In_opt_ PSP_DEVINFO_DATA DeviceInfoData) +{ + 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)) + { + DPRINT1("SetupDiGetDeviceInstallParamsW() failed (Error %lu)\n", GetLastError()); + return GetLastError(); + } + + /* Install the composite battery device */ + dwError = InstallCompositeBattery(DeviceInfoSet, + DeviceInfoData, + &DeviceInstallParams); + if (dwError == ERROR_SUCCESS) + { + /* Install the battery device */ + dwError = ERROR_DI_DO_DEFAULT; + } + + 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 */