Implemented the following functions with a bit of a hack: PowerGetActiveScheme PowerSetActiveScheme PowerEnumerate PowerReadFriendlyName
-- v6: initguid move
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,
From: Robert Lippmann robert.lippmann.development@gmail.com
--- dlls/powrprof/powrprof.c | 49 ++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 15 deletions(-)
diff --git a/dlls/powrprof/powrprof.c b/dlls/powrprof/powrprof.c index 7cfc6b20c13..c3078decc87 100644 --- a/dlls/powrprof/powrprof.c +++ b/dlls/powrprof/powrprof.c @@ -19,7 +19,6 @@
#include <stdarg.h> #include <stdlib.h> -#include "initguid.h" #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -51,19 +50,19 @@ 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; + const GUID *const guid; + const WCHAR *const name; } power_scheme_info;
/* Static array for storing predefined power schemes */ static const power_scheme_info valid_power_schemes[] = { - {(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"} + {&GUID_TYPICAL_POWER_SAVINGS, L"Balanced"}, + {&GUID_MAX_POWER_SAVINGS, L"Power Saver"}, + {&GUID_MIN_POWER_SAVINGS, L"High Performance"} }; /* Static variable for storing the active power scheme, set to Balanced by default */ -static GUID active_power_scheme = (const GUID) GUID_TYPICAL_POWER_SAVINGS; +static GUID const *active_power_scheme = &GUID_TYPICAL_POWER_SAVINGS;
NTSTATUS WINAPI CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel, @@ -303,24 +302,32 @@ BOOLEAN WINAPI WritePwrScheme(PUINT puiID, LPWSTR lpszName, LPWSTR lpszDescripti
DWORD WINAPI PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) { + FIXME("should use registry\n"); + /* Windows throws an access violation if **polguid is NULL, + so I guess we will too. */ + TRACE("*polguid %p, active_power_scheme %s\n", wine_dbgstr_point(*polguid), + debugstr_guid(*active_power_scheme)); /* 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)); + memcpy(*polguid, active_power_scheme, sizeof(GUID)); return ERROR_SUCCESS; }
DWORD WINAPI PowerSetActiveScheme(HKEY UserRootPowerKey, GUID *polguid) { size_t i; + + FIXME("should use registry\n"); + TRACE("polguid %s\n", debugstr_guid(*polguid)); for (i = 0; i < ARRAYSIZE(valid_power_schemes); i++) { - if (IsEqualGUID(polguid, &valid_power_schemes[i].guid)) + if (IsEqualGUID(polguid, valid_power_schemes[i].guid)) { - active_power_scheme = *polguid; + active_power_scheme = polguid; return ERROR_SUCCESS; } } @@ -339,16 +346,28 @@ DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, { size_t i; const WCHAR *name; - DWORD name_len; + DWORD name_len, result; + GUID current_guid;
+ FIXME("should use registry\n"); /* Check for invalid sub-group or power-setting GUIDs */ if (SubGroup != NULL || PowerSettings != NULL) { + FIXME("partial implementation\n"); return ERROR_CALL_NOT_IMPLEMENTED; } - for (i = 0; i < ARRAYSIZE(valid_power_schemes); i++) + for (i = 0; ; i++) { - if (IsEqualGUID(Scheme, &valid_power_schemes[i].guid)) + result = PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, i, (UCHAR *)¤t_guid, sizeof(GUID)); + if (result != ERROR_SUCCESS) + { + return result; + } + if (result == ERROR_NO_MORE_ITEMS) + { + break; + } + if (IsEqualGUID(Scheme, ¤t_guid)) { name = valid_power_schemes[i].name; name_len = (wcslen(name) + 1) * sizeof(WCHAR); @@ -357,7 +376,7 @@ DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, *BufferSize = name_len; return ERROR_MORE_DATA; } - wcscpy((WCHAR *)Buffer, name); + memcpy(Buffer, name, name_len); *BufferSize = name_len; return ERROR_SUCCESS; } @@ -396,7 +415,7 @@ DWORD WINAPI PowerEnumerate(HKEY key, const GUID *scheme, const GUID *subgroup, *buffer_size = sizeof(GUID); return ERROR_MORE_DATA; } - memcpy(buffer, &valid_power_schemes[index].guid, sizeof(GUID)); + memcpy(buffer, valid_power_schemes[index].guid, sizeof(GUID)); return ERROR_SUCCESS; }
From: Robert Lippmann robert.lippmann.development@gmail.com
--- dlls/powrprof/powrprof.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/dlls/powrprof/powrprof.c b/dlls/powrprof/powrprof.c index c3078decc87..c6a9bf8c56c 100644 --- a/dlls/powrprof/powrprof.c +++ b/dlls/powrprof/powrprof.c @@ -305,8 +305,8 @@ DWORD WINAPI PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) FIXME("should use registry\n"); /* Windows throws an access violation if **polguid is NULL, so I guess we will too. */ - TRACE("*polguid %p, active_power_scheme %s\n", wine_dbgstr_point(*polguid), - debugstr_guid(*active_power_scheme)); + TRACE("*polguid %p, active_power_scheme %s\n",*polguid, + debugstr_guid(active_power_scheme)); /* Windows SDK docs say use LocalFree to free this */ *polguid = LocalAlloc(LMEM_FIXED, sizeof(GUID)); if (*polguid == NULL) @@ -322,7 +322,7 @@ DWORD WINAPI PowerSetActiveScheme(HKEY UserRootPowerKey, GUID *polguid) size_t i;
FIXME("should use registry\n"); - TRACE("polguid %s\n", debugstr_guid(*polguid)); + TRACE("polguid %s\n", debugstr_guid((const GUID *)polguid)); for (i = 0; i < ARRAYSIZE(valid_power_schemes); i++) { if (IsEqualGUID(polguid, valid_power_schemes[i].guid)) @@ -346,7 +346,7 @@ DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, { size_t i; const WCHAR *name; - DWORD name_len, result; + DWORD buffer_size = sizeof(GUID), result; GUID current_guid;
FIXME("should use registry\n"); @@ -358,9 +358,10 @@ DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, } for (i = 0; ; i++) { - result = PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, i, (UCHAR *)¤t_guid, sizeof(GUID)); + result = PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, i, (UCHAR *)¤t_guid, &buffer_size); if (result != ERROR_SUCCESS) { + ERR("PowerEnumerate failed: %lu\n", result); return result; } if (result == ERROR_NO_MORE_ITEMS) @@ -370,14 +371,14 @@ DWORD WINAPI PowerReadFriendlyName(HKEY RootPowerKey, const GUID *Scheme, if (IsEqualGUID(Scheme, ¤t_guid)) { name = valid_power_schemes[i].name; - name_len = (wcslen(name) + 1) * sizeof(WCHAR); - if (*BufferSize < name_len) + buffer_size = (wcslen(name) + 1) * sizeof(WCHAR); + if (*BufferSize < buffer_size) { - *BufferSize = name_len; + *BufferSize = buffer_size; return ERROR_MORE_DATA; } - memcpy(Buffer, name, name_len); - *BufferSize = name_len; + memcpy(Buffer, name, buffer_size); + *BufferSize = buffer_size; return ERROR_SUCCESS; } }
From: Robert Lippmann robert.lippmann.development@gmail.com
--- dlls/powrprof/Makefile.in | 2 +- dlls/powrprof/powrprof.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/powrprof/Makefile.in b/dlls/powrprof/Makefile.in index d081c6af81e..258a6d23d06 100644 --- a/dlls/powrprof/Makefile.in +++ b/dlls/powrprof/Makefile.in @@ -1,6 +1,6 @@ MODULE = powrprof.dll IMPORTLIB = powrprof -IMPORTS = advapi32 +IMPORTS = advapi32 ole32
SOURCES = \ powrprof.c diff --git a/dlls/powrprof/powrprof.c b/dlls/powrprof/powrprof.c index c6a9bf8c56c..63356e93d4a 100644 --- a/dlls/powrprof/powrprof.c +++ b/dlls/powrprof/powrprof.c @@ -21,6 +21,7 @@ #include <stdlib.h> #include "ntstatus.h" #define WIN32_NO_STATUS +#include <initguid.h> #include "windef.h" #include "winbase.h" #include "winnt.h"
From: Robert Lippmann robert.lippmann.development@gmail.com
--- dlls/powrprof/powrprof.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/powrprof/powrprof.c b/dlls/powrprof/powrprof.c index 63356e93d4a..ae0aa1c8641 100644 --- a/dlls/powrprof/powrprof.c +++ b/dlls/powrprof/powrprof.c @@ -19,9 +19,9 @@
#include <stdarg.h> #include <stdlib.h> +#include <initguid.h> #include "ntstatus.h" #define WIN32_NO_STATUS -#include <initguid.h> #include "windef.h" #include "winbase.h" #include "winnt.h"
Alfred Agrell (@Alcaro) commented about dlls/powrprof/powrprof.c:
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 *const guid;
- const WCHAR *const name;
I don't think those right-hand consts do anything useful.
Alfred Agrell (@Alcaro) commented about dlls/powrprof/powrprof.c:
DWORD WINAPI PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **polguid) {
- FIXME("(%p,%p) stub!\n", UserRootPowerKey, polguid);
- return ERROR_CALL_NOT_IMPLEMENTED;
- FIXME("should use registry\n");
- /* Windows throws an access violation if **polguid is NULL,
so I guess we will too. */
- TRACE("*polguid %p, active_power_scheme %s\n",*polguid,
*polguid is some uninitialized stack garbage from the caller, and will soon be overwritten. Better remove the asterisk. Better trace that HKEY too.
Tracing global variables like that is rare; sounds useful, but nothing else in Wine does that. I don't know if it's a good or bad idea.
Alfred Agrell (@Alcaro) commented about dlls/powrprof/powrprof.c:
- 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;
- FIXME("should use registry\n");
- TRACE("polguid %s\n", debugstr_guid((const GUID *)polguid));
You sure like const, don't you?
That cast does nothing, compiler will insert it for you. Better remove it.
Feel free to make the function's argument const, though.
Alfred Agrell (@Alcaro) commented about dlls/powrprof/powrprof.c:
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 buffer_size = sizeof(GUID), result;
- GUID current_guid;
- FIXME("should use registry\n");
I think details on what's missing usually goes in comments (or looking for unused function arguments or not-implemented errors). Not sure, though... Wine has a lot of policies, I can't keep track of them all. (Some of them even vary between DLLs, and/or aren't written down.)
Alfred Agrell (@Alcaro) commented about dlls/powrprof/powrprof.c:
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),
No need to remove the previous fixmes, just change them to trace or semi-stub.
If latter, I don't think the ERROR_CALL_NOT_IMPLEMENTED returns need separate fixmes.
Alfred Agrell (@Alcaro) commented about dlls/powrprof/powrprof.c:
- {
FIXME("partial implementation\n");
return ERROR_CALL_NOT_IMPLEMENTED;
- }
- for (i = 0; ; i++)
- {
result = PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, i, (UCHAR *)¤t_guid, &buffer_size);
if (result != ERROR_SUCCESS)
{
ERR("PowerEnumerate failed: %lu\n", result);
return result;
}
if (result == ERROR_NO_MORE_ITEMS)
{
break;
}
Certainly that's not the correct order?
CI will try to build every commit in the MR, not just the latest. You can't append commits til it passes, you need to force push.
I usually use `git rebase --interactive origin/master` to rebuild commit series, but beginners may find it less intimidating to `git reset origin/master` then recreate the commits from scratch.
On Thu Mar 27 10:55:34 2025 +0000, Alfred Agrell wrote:
You sure like const, don't you? That cast does nothing, compiler will insert it for you. Better remove it. Feel free to make the function's argument const, though.
lol, have been doing a lot of python coding. if you don't set something to immutable, someone somewhere down the line will modify and break things.
I actually inserted the const there because the compile was failing on clang without it.
On Thu Mar 27 18:37:08 2025 +0000, Alfred Agrell wrote:
Certainly that's not the correct order?
No, it's not :disappointed:
On Thu Mar 27 18:32:28 2025 +0000, Robert Lippmann wrote:
lol, have been doing a lot of python coding. if you don't set something to immutable, someone somewhere down the line will modify and break things. I actually inserted the const there because the compile was failing on clang without it.
`PowerSetActiveScheme` prototype is also wrong.
What does SteamVR actually need from all of this? Do we need to store anything in registry at all? Could we instead return something static for "active" scheme?
On Thu Mar 27 10:55:34 2025 +0000, Alfred Agrell wrote:
*polguid is some uninitialized stack garbage from the caller, and will soon be overwritten. Better remove the asterisk. Better trace that HKEY too. Tracing global variables like that is rare; sounds useful, but nothing else in Wine does that. I don't know if it's a good or bad idea.
Well, according to the SDK docs, the HKEY is unused and should be set to NULL. I've set it to non-null under Windows, and it doesn't seem to matter. Windows doesn't even throw an invalid parameter.
On Thu Mar 27 18:55:20 2025 +0000, Nikolay Sivov wrote:
What does SteamVR actually need from all of this? Do we need to store anything in registry at all? Could we instead return something static for "active" scheme?
It does this (from my Windows logs):
`Wed Mar 05 2025 00:54:53.220 [Info] - [System] Prepare operating system environment `
`Wed Mar 05 2025 00:54:53.220 [Info] - [System] Setting power settings to minimum power savings. Wed Mar 05 2025 00:54:53.221`
`[Info] - [System] Found power mode {381B4222-F694-41F0-9685-FF5BB260DF2E} Balanced Wed Mar 05 2025 00:54:53.222 `
`[Info] - [System] Found power mode {8C5E7FDA-E8BF-4A96-9A85-A6E23A8C635C} High performance (current) `
`Wed Mar 05 2025 00:54:53.222 [Info] - [System] Found power mode {A1841308-3541-4FAB-BC81-F71556F20B4A} Power saver `
`Wed Mar 05 2025 00:54:53.223 [Info] - [System] Setting High Performance power mode`
And, I'd rather not have to implement via the registry. That's just how Windows does it. Was documenting for anyone who wants to implement it properly in the future.
On Thu Mar 27 18:38:06 2025 +0000, Nikolay Sivov wrote:
`PowerSetActiveScheme` prototype is also wrong.
@nsivov That was the prototype that was there before, I should have double checked it.
On Thu Mar 27 18:55:20 2025 +0000, Robert Lippmann wrote:
It does this (from my Windows logs): `Wed Mar 05 2025 00:54:53.220 [Info] - [System] Prepare operating system environment ` `Wed Mar 05 2025 00:54:53.220 [Info] - [System] Setting power settings to minimum power savings. Wed Mar 05 2025 00:54:53.221` `[Info] - [System] Found power mode {381B4222-F694-41F0-9685-FF5BB260DF2E} Balanced Wed Mar 05 2025 00:54:53.222 ` `[Info] - [System] Found power mode {8C5E7FDA-E8BF-4A96-9A85-A6E23A8C635C} High performance (current) ` `Wed Mar 05 2025 00:54:53.222 [Info] - [System] Found power mode {A1841308-3541-4FAB-BC81-F71556F20B4A} Power saver ` `Wed Mar 05 2025 00:54:53.223 [Info] - [System] Setting High Performance power mode` And, I'd rather not have to implement via the registry. That's just how Windows does it. Was documenting for anyone who wants to implement it properly in the future.
So, it's obviously calling PowerGetActiveScheme, PowerSetActiveScheme, PowerEnumerate, and PowerReadFriendlyName...
Should I just simplify the implementations to just read from the static array, and not perform any validation?
On Thu Mar 27 19:00:32 2025 +0000, Robert Lippmann wrote:
So, it's obviously calling PowerGetActiveScheme, PowerSetActiveScheme, PowerEnumerate, and PowerReadFriendlyName... Should I just simplify the implementations to just read from the static array, and not perform any validation?
We don't need windows logs really. You can what it's calling using wine. But yes, to me it looks premature to try to implement something that potentially is not going to work - I can't imagine we are going to switch power scheme on the host, if there is even a concept for that. First question is what application needs exactly, and what is enough.
On Thu Mar 27 19:05:20 2025 +0000, Nikolay Sivov wrote:
We don't need windows logs really. You can what it's calling using wine. But yes, to me it looks premature to try to implement something that potentially is not going to work - I can't imagine we are going to switch power scheme on the host, if there is even a concept for that. First question is what application needs exactly, and what is enough.
Well, in wine it throws an access violation right after "Setting power settings to minimum power savings".
On Thu Mar 27 19:08:36 2025 +0000, Robert Lippmann wrote:
Well, in wine it throws an access violation right after "Setting power settings to minimum power savings".
Do i need to write tests for this? Or just do the implementation? I'm not sure what is standard operating procedure.
This merge request was closed by Robert Lippmann.