Implemented the following functions with a bit of a hack: PowerGetActiveScheme PowerSetActiveScheme PowerEnumerate PowerReadFriendlyName
-- v2: powrprof.dll: fix CI compile issues
From: Robert Lippmann robert.lippmann.development@gmail.com
--- include/winnt.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h index 722d2c3a542..e7d345f254b 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -5799,6 +5799,20 @@ typedef enum _POWER_REQUEST_TYPE #define POWER_REQUEST_CONTEXT_SIMPLE_STRING 0x00000001 #define POWER_REQUEST_CONTEXT_DETAILED_STRING 0x00000002
+/* Definitions of well known power schemes */ + +/* Power Saver - {a1841308-3541-4fab-bc81-f71556f20b4a} */ +DEFINE_GUID( GUID_MAX_POWER_SAVINGS, 0xA1841308, 0x3541, 0x4FAB, 0xBC, 0x81, 0xF + 7, 0x15, 0x56, 0xF2, 0x0B, 0x4A ); + +/* High Performance - {8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c} */ +DEFINE_GUID( GUID_MIN_POWER_SAVINGS, 0x8C5E7FDA, 0xE8BF, 0x4A96, 0x9A, 0x85, 0xA + 6, 0xE2, 0x3A, 0x8C, 0x63, 0x5C ); + +/* Balanced - {381b4222-f694-41f0-9685-ff5bb260df2e} */ +DEFINE_GUID( GUID_TYPICAL_POWER_SAVINGS, 0x381B4222, 0xF694, 0x41F0, 0x96, 0x85, + 0xFF, 0x5B, 0xB2, 0x60, 0xDF, 0x2E ); + typedef union _FILE_SEGMENT_ELEMENT { PVOID64 Buffer; ULONGLONG Alignment;
From: Robert Lippmann robert.lippmann.development@gmail.com
--- include/winnt.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/include/winnt.h b/include/winnt.h index e7d345f254b..90acdaf7f92 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -5802,16 +5802,13 @@ typedef enum _POWER_REQUEST_TYPE /* Definitions of well known power schemes */
/* Power Saver - {a1841308-3541-4fab-bc81-f71556f20b4a} */ -DEFINE_GUID( GUID_MAX_POWER_SAVINGS, 0xA1841308, 0x3541, 0x4FAB, 0xBC, 0x81, 0xF - 7, 0x15, 0x56, 0xF2, 0x0B, 0x4A ); +DEFINE_GUID( GUID_MAX_POWER_SAVINGS, 0xA1841308, 0x3541, 0x4FAB, 0xBC, 0x81, 0xF7, 0x15, 0x56, 0xF2, 0x0B, 0x4A );
/* High Performance - {8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c} */ -DEFINE_GUID( GUID_MIN_POWER_SAVINGS, 0x8C5E7FDA, 0xE8BF, 0x4A96, 0x9A, 0x85, 0xA - 6, 0xE2, 0x3A, 0x8C, 0x63, 0x5C ); +DEFINE_GUID( GUID_MIN_POWER_SAVINGS, 0x8C5E7FDA, 0xE8BF, 0x4A96, 0x9A, 0x85, 0xA6, 0xE2, 0x3A, 0x8C, 0x63, 0x5C );
/* Balanced - {381b4222-f694-41f0-9685-ff5bb260df2e} */ -DEFINE_GUID( GUID_TYPICAL_POWER_SAVINGS, 0x381B4222, 0xF694, 0x41F0, 0x96, 0x85, - 0xFF, 0x5B, 0xB2, 0x60, 0xDF, 0x2E ); +DEFINE_GUID( GUID_TYPICAL_POWER_SAVINGS, 0x381B4222, 0xF694, 0x41F0, 0x96, 0x85, 0xFF, 0x5B, 0xB2, 0x60, 0xDF, 0x2E );
typedef union _FILE_SEGMENT_ELEMENT { PVOID64 Buffer;
From: Robert Lippmann robert.lippmann.development@gmail.com
Implemented the following functions with a bit of a hack: PowerGetActiveScheme PowerSetActiveScheme PowerEnumerate PowerReadFriendlyName --- dlls/powrprof/powrprof.c | 90 +++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 10 deletions(-)
diff --git a/dlls/powrprof/powrprof.c b/dlls/powrprof/powrprof.c index dcc7126b920..d00d240cec1 100644 --- a/dlls/powrprof/powrprof.c +++ b/dlls/powrprof/powrprof.c @@ -19,7 +19,7 @@
#include <stdarg.h> #include <stdlib.h> - +#include "initguid.h" #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -48,6 +48,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(powrprof); static const WCHAR szPowerCfgSubKey[] = L"Software\Microsoft\Windows\CurrentVersion\Controls Folder\PowerCfg"; static HANDLE PPRegSemaphore = NULL;
+/* Hacks to get and set power schemes + These should really be stored in the registry */ +typedef struct { + const GUID guid; + const WCHAR *name; + } power_scheme_info; + +/* Static array for storing predefined power schemes */ +static const power_scheme_info valid_power_schemes[] = +{ + {GUID_TYPICAL_POWER_SAVINGS, L"Balanced"}, + {GUID_MAX_POWER_SAVINGS, L"High Performance"}, + {GUID_MIN_POWER_SAVINGS, L"Power Saver"} +}; +/* Static variable for storing the active power scheme, set to Balanced by default */ +static GUID active_power_scheme = GUID_TYPICAL_POWER_SAVINGS; + NTSTATUS WINAPI CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel, PVOID lpInputBuffer, ULONG nInputBufferSize, @@ -286,14 +303,28 @@ BOOLEAN WINAPI WritePwrScheme(PUINT puiID, LPWSTR lpszName, LPWSTR lpszDescripti
DWORD WINAPI PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) { - FIXME("(%p,%p) stub!\n", UserRootPowerKey, polguid); - return ERROR_CALL_NOT_IMPLEMENTED; + /* Windows SDK docs say use LocalFree to free this */ + *polguid = LocalAlloc(LMEM_FIXED, sizeof(GUID)); + if (*polguid == NULL) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + memcpy(*polguid, &active_power_scheme, sizeof(GUID)); + return ERROR_SUCCESS; }
DWORD WINAPI PowerSetActiveScheme(HKEY UserRootPowerKey, GUID *polguid) { - FIXME("(%p,%s) stub!\n", UserRootPowerKey, wine_dbgstr_guid(polguid)); - return ERROR_SUCCESS; + size_t i; + for (i = 0; i < ARRAYSIZE(valid_power_schemes); i++) + { + if (IsEqualGUID(polguid, &valid_power_schemes[i].guid)) + { + active_power_scheme = *polguid; + return ERROR_SUCCESS; + } + } + return ERROR_INVALID_PARAMETER; }
DWORD WINAPI PowerReadDCValue(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, PULONG Type, PUCHAR Buffer, DWORD *BufferSize) @@ -306,10 +337,36 @@ DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, const GUID *SubGroup, const GUID *PowerSettings, UCHAR *Buffer, DWORD *BufferSize) { - FIXME("(%p,%s,%s,%s,%p,%p) stub!\n", RootPowerKey, debugstr_guid(Scheme), debugstr_guid(SubGroup), debugstr_guid(PowerSettings), Buffer, BufferSize); - return ERROR_CALL_NOT_IMPLEMENTED; + size_t i; + const WCHAR *name; + DWORD name_len; + + /* Check for invalid sub-group or power-setting GUIDs */ + if (SubGroup != NULL || PowerSettings != NULL) + { + return ERROR_CALL_NOT_IMPLEMENTED; + } + for (i = 0; i < ARRAYSIZE(valid_power_schemes); i++) + { + if (IsEqualGUID(Scheme, &valid_power_schemes[i].guid)) + { + name = valid_power_schemes[i].name; + name_len = (wcslen(name) + 1) * sizeof(WCHAR); + if (*BufferSize < name_len) + { + *BufferSize = name_len; + return ERROR_MORE_DATA; + } + wcscpy((WCHAR *)Buffer, name); + *BufferSize = name_len; + return ERROR_SUCCESS; + } + } + + return ERROR_INVALID_PARAMETER; /* Scheme not found */ }
+ POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRole(void) { FIXME("stub\n"); @@ -325,9 +382,22 @@ POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRoleEx(ULONG version) DWORD WINAPI PowerEnumerate(HKEY key, const GUID *scheme, const GUID *subgroup, POWER_DATA_ACCESSOR flags, ULONG index, UCHAR *buffer, DWORD *buffer_size) { - FIXME("(%p,%s,%s,%d,%ld,%p,%p) stub!\n", key, debugstr_guid(scheme), debugstr_guid(subgroup), - flags, index, buffer, buffer_size); - return ERROR_CALL_NOT_IMPLEMENTED; + /* Only care about ACCESS_SCHEME */ + if (flags != ACCESS_SCHEME || scheme != NULL || subgroup != NULL) + { + return ERROR_CALL_NOT_IMPLEMENTED; + } + if(index >= ARRAYSIZE(valid_power_schemes)) + { + return ERROR_NO_MORE_ITEMS; + } + if(buffer == NULL || *buffer_size < sizeof(GUID)) + { + *buffer_size = sizeof(GUID); + return ERROR_MORE_DATA; + } + memcpy(buffer, &valid_power_schemes[index].guid, sizeof(GUID)); + return ERROR_SUCCESS; }
DWORD WINAPI PowerRegisterSuspendResumeNotification(DWORD flags, HANDLE recipient, PHPOWERNOTIFY handle)
From: Robert Lippmann robert.lippmann.development@gmail.com
--- include/winnt.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/winnt.h b/include/winnt.h index 90acdaf7f92..f58cfd62880 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -5802,13 +5802,13 @@ typedef enum _POWER_REQUEST_TYPE /* Definitions of well known power schemes */
/* Power Saver - {a1841308-3541-4fab-bc81-f71556f20b4a} */ -DEFINE_GUID( GUID_MAX_POWER_SAVINGS, 0xA1841308, 0x3541, 0x4FAB, 0xBC, 0x81, 0xF7, 0x15, 0x56, 0xF2, 0x0B, 0x4A ); +DEFINE_GUID( GUID_MAX_POWER_SAVINGS, 0xa1841308, 0x3541, 0x4fab, 0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a );
/* High Performance - {8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c} */ -DEFINE_GUID( GUID_MIN_POWER_SAVINGS, 0x8C5E7FDA, 0xE8BF, 0x4A96, 0x9A, 0x85, 0xA6, 0xE2, 0x3A, 0x8C, 0x63, 0x5C ); +DEFINE_GUID( GUID_MIN_POWER_SAVINGS, 0x8c5e7fda, 0xe8bf, 0x4a96, 0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c );
/* Balanced - {381b4222-f694-41f0-9685-ff5bb260df2e} */ -DEFINE_GUID( GUID_TYPICAL_POWER_SAVINGS, 0x381B4222, 0xF694, 0x41F0, 0x96, 0x85, 0xFF, 0x5B, 0xB2, 0x60, 0xDF, 0x2E ); +DEFINE_GUID( GUID_TYPICAL_POWER_SAVINGS, 0x381b4222, 0xf694, 0x41f0, 0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e );
typedef union _FILE_SEGMENT_ELEMENT { PVOID64 Buffer;
From: Robert Lippmann robert.lippmann.development@gmail.com
--- dlls/powrprof/powrprof.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/powrprof/powrprof.c b/dlls/powrprof/powrprof.c index d00d240cec1..7cfc6b20c13 100644 --- a/dlls/powrprof/powrprof.c +++ b/dlls/powrprof/powrprof.c @@ -58,12 +58,12 @@ typedef struct { /* Static array for storing predefined power schemes */ static const power_scheme_info valid_power_schemes[] = { - {GUID_TYPICAL_POWER_SAVINGS, L"Balanced"}, - {GUID_MAX_POWER_SAVINGS, L"High Performance"}, - {GUID_MIN_POWER_SAVINGS, L"Power Saver"} + {(const GUID) GUID_TYPICAL_POWER_SAVINGS, L"Balanced"}, + {(const GUID) GUID_MAX_POWER_SAVINGS, L"High Performance"}, + {(const GUID) GUID_MIN_POWER_SAVINGS, L"Power Saver"} }; /* Static variable for storing the active power scheme, set to Balanced by default */ -static GUID active_power_scheme = GUID_TYPICAL_POWER_SAVINGS; +static GUID active_power_scheme = (const GUID) GUID_TYPICAL_POWER_SAVINGS;
NTSTATUS WINAPI CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel,
It's the merge commit, we don't want those. Rebase, delete the now-empty commit, and force push.
We're not huge fans of commits that fix previous commits either; squash those three to one and force push, so it looks like you got it right the first time.
You've got the names backwards in that list - minimum power savings equals maximum power use and maximum performance.
This MR could also use some more tests, FIXME("stub") on the ERROR_CALL_NOT_IMPLEMENTED returns, and FIXME("semi-stub") for that piece about storing power profiles in registry.
(I'm not the local maintainer, so I don't know how much of the above, and how much else, needs to be done for the MR to be approved. Feel free to ignore me if you feel I'm crazy.)
I think those (const GUID) casts are better fixed by slinging around pointers to the GUIDs. That's how it usually is in most other Wine DLLs, at least.
On Wed Mar 26 18:18:50 2025 +0000, Alfred Agrell wrote:
It's the merge commit, we don't want those. Rebase, delete the now-empty commit, and force push. We're not huge fans of commits that fix previous commits either; squash those three to one and force push, so it looks like you got it right the first time. You've got the names backwards in that list - minimum power savings equals maximum power use and maximum performance. This MR could also use some more tests, FIXME("stub") on the ERROR_CALL_NOT_IMPLEMENTED returns, and FIXME("semi-stub") for that piece about storing power profiles in registry. (I'm not the local maintainer, so I don't know how much of the above, and how much else, needs to be done for the MR to be approved. Feel free to ignore me if you feel I'm crazy.)
Thank you! That username issue was driving me crazy.
I'll probably just copy the files I modified, blow away the fork, recreate and add back.
And good catch on the GUID names :smile: