diff --git a/PInvoke/Kernel32/WinBase.Power.cs b/PInvoke/Kernel32/WinBase.Power.cs index 50f2b070..0131fb28 100644 --- a/PInvoke/Kernel32/WinBase.Power.cs +++ b/PInvoke/Kernel32/WinBase.Power.cs @@ -12,6 +12,8 @@ namespace Vanara.PInvoke AC_OFFLINE = 0, /// Online AC_ONLINE = 1, + /// On backup power. + AC_LINE_BACKUP_POWER = 2, /// Unknown status AC_UNKNOWN = 255 } diff --git a/PInvoke/PowrProf/PowerBase.cs b/PInvoke/PowrProf/PowerBase.cs index 9d697916..d76338b0 100644 --- a/PInvoke/PowrProf/PowerBase.cs +++ b/PInvoke/PowrProf/PowerBase.cs @@ -317,6 +317,20 @@ namespace Vanara.PInvoke PowerInformationLevelMaximum, } + /// + /// The version of the POWER_PLATFORM_ROLE enumeration for the platform used by . + /// + [PInvokeData("powerbase.h", MSDNShortId = "64b597d3-ca7a-4ff7-8527-72c3625147cd")] + public enum PowerPlatformRoleVersion + { + /// The version of the POWER_PLATFORM_ROLE enumeration for Windows 7, Windows Server 2008 R2, Windows Vista or Windows Server 2008. + /// Calling PowerDeterminePlatformRoleEx with this value returns the same result as calling PowerDeterminePlatformRole on Windows 7, Windows Server 2008 R2, Windows Vista or Windows Server 2008. + POWER_PLATFORM_ROLE_V1 = 1, + + /// The version of the POWER_PLATFORM_ROLE enumeration for Windows 8 and Windows Server 2012. + POWER_PLATFORM_ROLE_V2 = 2 + } + /// Flags for . [PInvokeData("powerbase.h", MSDNShortId = "3b39ec3a-417c-4ce4-a581-ed967f1baec9")] public enum RegisterSuspendResumeNotificationFlags @@ -568,7 +582,7 @@ namespace Vanara.PInvoke // PowerDeterminePlatformRoleEx( ULONG Version ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("powerbase.h", MSDNShortId = "64b597d3-ca7a-4ff7-8527-72c3625147cd")] - public static extern POWER_PLATFORM_ROLE PowerDeterminePlatformRoleEx(uint Version); + public static extern POWER_PLATFORM_ROLE PowerDeterminePlatformRoleEx(PowerPlatformRoleVersion Version); /// Registers to receive notification when the system is suspended or resumed. /// This parameter must be DEVICE_NOTIFY_CALLBACK. diff --git a/PInvoke/PowrProf/PowrProf.cs b/PInvoke/PowrProf/PowrProf.cs index fb153644..6b8d625b 100644 --- a/PInvoke/PowrProf/PowrProf.cs +++ b/PInvoke/PowrProf/PowrProf.cs @@ -36,6 +36,8 @@ namespace Vanara.PInvoke [return: MarshalAs(UnmanagedType.U1)] public delegate bool PWRSCHEMESENUMPROC(uint uiIndex, uint dwName, string sName, uint dwDesc, string sDesc, in POWER_POLICY pp, IntPtr lParam); + private delegate Win32Error PwrReadMemFunc(HKEY h, IntPtr a, IntPtr b, IntPtr c, IntPtr d, ref uint e); + /// The global flags constants are used to enable or disable user power policy options. [PInvokeData("powrprof.h", MSDNShortId = "0e89ae66-a889-4929-b028-125fcef5c89c")] [Flags] @@ -549,10 +551,10 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/desktop/api/powrprof/nf-powrprof-devicepowerenumdevices BOOLEAN DevicePowerEnumDevices( // ULONG QueryIndex, ULONG QueryInterpretationFlags, ULONG QueryFlags, PBYTE pReturnBuffer, PULONG pBufferSize ); - [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] + [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("powrprof.h", MSDNShortId = "bb67634c-69d9-4194-ac27-4f9740d73a1a")] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool DevicePowerEnumDevices(uint QueryIndex, PDQUERY QueryInterpretationFlags, PDCAP QueryFlags, IntPtr pReturnBuffer, ref uint pBufferSize); + public static extern bool DevicePowerEnumDevices(uint QueryIndex, PDQUERY QueryInterpretationFlags, PDCAP QueryFlags, StringBuilder pReturnBuffer, ref uint pBufferSize); /// Initializes a device list by querying all the devices. /// Reserved; must be 0. @@ -595,7 +597,7 @@ namespace Vanara.PInvoke [DllImport(Lib.PowrProf, SetLastError = true, ExactSpelling = true)] [PInvokeData("powrprof.h", MSDNShortId = "300842ae-d7d4-42c2-959c-e1713f466d32")] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DevicePowerSetDeviceState([MarshalAs(UnmanagedType.LPWStr)] string DeviceDescription, PDSET SetFlags, IntPtr SetData); + public static extern bool DevicePowerSetDeviceState([MarshalAs(UnmanagedType.LPWStr)] string DeviceDescription, PDSET SetFlags, IntPtr SetData = default); /// /// @@ -1062,13 +1064,7 @@ namespace Vanara.PInvoke // DWORD *BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("powrprof.h", MSDNShortId = "5b2c8263-d916-4909-be56-ec784537bdc3")] - public static extern Win32Error PowerEnumerate([Optional] HKEY RootPowerKey, [Optional] in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, POWER_DATA_ACCESSOR AccessFlags, uint Index, IntPtr Buffer, ref uint BufferSize); - - [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] - private static extern Win32Error PowerEnumerate([Optional] HKEY RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, POWER_DATA_ACCESSOR AccessFlags, uint Index, IntPtr Buffer, ref uint BufferSize); - - [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] - private static extern Win32Error PowerEnumerate([Optional] HKEY RootPowerKey, in Guid SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, POWER_DATA_ACCESSOR AccessFlags, uint Index, IntPtr Buffer, ref uint BufferSize); + public static extern Win32Error PowerEnumerate([Optional] HKEY RootPowerKey, [Optional, In] IntPtr SchemeGuid, [Optional, In] IntPtr SubGroupOfPowerSettingsGuid, POWER_DATA_ACCESSOR AccessFlags, uint Index, IntPtr Buffer, ref uint BufferSize); /// /// Enumerates the specified elements in a power scheme. This function is normally called in a loop incrementing the Index parameter @@ -1154,32 +1150,29 @@ namespace Vanara.PInvoke { if (AccessFlags == (POWER_DATA_ACCESSOR)(-1)) AccessFlags = SchemeGuid is null ? POWER_DATA_ACCESSOR.ACCESS_SCHEME : (SubGroupOfPowerSettingsGuid is null ? POWER_DATA_ACCESSOR.ACCESS_SUBGROUP : POWER_DATA_ACCESSOR.ACCESS_INDIVIDUAL_SETTING); - var checkSize = true; - for (var i = 0U; ; i++) - { - var sz = 0U; - var err = CallEnum(i, default, ref sz); - if (err == Win32Error.ERROR_NO_MORE_ITEMS) - break; - if (err != Win32Error.ERROR_MORE_DATA) - throw err.GetException(); - if (checkSize && sz < Marshal.SizeOf(typeof(T))) throw new ArgumentException("Size mismatch between returned value and size of T.", nameof(T)); - checkSize = false; - using (var mem = new SafeHGlobalHandle((int)sz)) + var l = new List(); + PwrGuidTsl(SchemeGuid, SubGroupOfPowerSettingsGuid, null, (p1, p2, p3) => { + var checkSize = true; + for (var i = 0U; ; i++) { - CallEnum(i, (IntPtr)mem, ref sz).ThrowIfFailed(); - yield return mem.ToStructure(); + var sz = 0U; + var err = PowerEnumerate(default, p1, p2, AccessFlags, i, IntPtr.Zero, ref sz); + if (err == Win32Error.ERROR_NO_MORE_ITEMS) + break; + if (err != Win32Error.ERROR_MORE_DATA) + return err; + if (checkSize && sz < Marshal.SizeOf(typeof(T))) throw new ArgumentException("Size mismatch between returned value and size of T.", nameof(T)); + checkSize = false; + using (var mem = new SafeHGlobalHandle((int)sz)) + { + err = PowerEnumerate(default, p1, p2, AccessFlags, i, (IntPtr)mem, ref sz); + if (err.Failed) return err; + l.Add(mem.ToStructure()); + } } - } - - Win32Error CallEnum(uint Index, IntPtr Buffer, ref uint BufferSize) - { - if (!SchemeGuid.HasValue && !SubGroupOfPowerSettingsGuid.HasValue) - return PowerEnumerate(default, IntPtr.Zero, IntPtr.Zero, AccessFlags, Index, Buffer, ref BufferSize); - if (SchemeGuid.HasValue && !SubGroupOfPowerSettingsGuid.HasValue) - return PowerEnumerate(default, SchemeGuid.Value, IntPtr.Zero, AccessFlags, Index, Buffer, ref BufferSize); - return PowerEnumerate(default, SchemeGuid.Value, SubGroupOfPowerSettingsGuid.Value, AccessFlags, Index, Buffer, ref BufferSize); - } + return Win32Error.ERROR_SUCCESS; + }).ThrowIfFailed(); + return l; } /// Imports a power scheme from a file. @@ -1269,7 +1262,7 @@ namespace Vanara.PInvoke // *SubGroupOfPowerSettingsGuid, _In_ const GUID *PowerSettingGuid, _Out_ LPDWORD AcDefaultIndex); https://msdn.microsoft.com/en-us/library/windows/desktop/aa372733(v=vs.85).aspx [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("PowrProf.h", MSDNShortId = "aa372733")] - public static extern Win32Error PowerReadACDefaultIndex([Optional] HKEY RootPowerKey, in Guid SchemePersonalityGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint AcDefaultIndex); + public static extern Win32Error PowerReadACDefaultIndex([Optional] HKEY RootPowerKey, in Guid SchemePersonalityGuid, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint AcDefaultIndex); /// Retrieves the AC index of the specified power setting. /// This parameter is reserved for future use and must be set to NULL. @@ -1325,7 +1318,7 @@ namespace Vanara.PInvoke // RootPowerKey, const GUID *SchemeGuid, const GUID *SubGroupOfPowerSettingsGuid, const GUID *PowerSettingGuid, LPDWORD AcValueIndex ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("powrprof.h", MSDNShortId = "e8760e78-78cd-4652-94b1-f42a72df5db2")] - public static extern Win32Error PowerReadACValueIndex([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint AcValueIndex); + public static extern Win32Error PowerReadACValueIndex([Optional] HKEY RootPowerKey, in Guid SchemeGuid, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint AcValueIndex); /// Retrieves the default DC index of the specified power setting. /// This parameter is reserved for future use and must be set to NULL. @@ -1386,7 +1379,7 @@ namespace Vanara.PInvoke // *SubGroupOfPowerSettingsGuid, _In_ const GUID *PowerSettingGuid, _Out_ LPDWORD DcDefaultIndex); https://msdn.microsoft.com/en-us/library/windows/desktop/aa372736(v=vs.85).aspx [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("PowrProf.h", MSDNShortId = "aa372736")] - public static extern Win32Error PowerReadDCDefaultIndex([Optional] HKEY RootPowerKey, in Guid SchemePersonalityGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint DcDefaultIndex); + public static extern Win32Error PowerReadDCDefaultIndex([Optional] HKEY RootPowerKey, in Guid SchemePersonalityGuid, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint DcDefaultIndex); /// Retrieves the DC value index of the specified power setting. /// This parameter is reserved for future use and must be set to NULL. @@ -1440,7 +1433,7 @@ namespace Vanara.PInvoke // RootPowerKey, const GUID *SchemeGuid, const GUID *SubGroupOfPowerSettingsGuid, const GUID *PowerSettingGuid, LPDWORD DcValueIndex ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("powrprof.h", MSDNShortId = "91ba83bd-3e28-4933-a1ad-0cd8414fee37")] - public static extern Win32Error PowerReadDCValueIndex([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint DcValueIndex); + public static extern Win32Error PowerReadDCValueIndex([Optional] HKEY RootPowerKey, in Guid SchemeGuid, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, out uint DcValueIndex); /// /// Retrieves the description for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL @@ -1515,12 +1508,72 @@ namespace Vanara.PInvoke /// specified by the BufferSize parameter is too small, the function returns ERROR_SUCCESS and the DWORD pointed to by /// the BufferSize parameter is filled in with the required buffer size. /// - // https://docs.microsoft.com/en-us/windows/desktop/api/powrprof/nf-powrprof-powerreaddescription DWORD PowerReadDescription( HKEY - // RootPowerKey, const GUID *SchemeGuid, const GUID *SubGroupOfPowerSettingsGuid, const GUID *PowerSettingGuid, PUCHAR Buffer, - // LPDWORD BufferSize ); + // https://docs.microsoft.com/en-us/windows/desktop/api/powrprof/nf-powrprof-powerreaddescription + // DWORD PowerReadDescription( HKEY RootPowerKey, const GUID *SchemeGuid, const GUID *SubGroupOfPowerSettingsGuid, const GUID *PowerSettingGuid, PUCHAR Buffer, LPDWORD BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("powrprof.h", MSDNShortId = "3c264f4f-fd1b-466b-ba76-fe78593a3628")] - public static extern Win32Error PowerReadDescription([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, StringBuilder Buffer, ref uint BufferSize); + public static extern Win32Error PowerReadDescription([Optional] HKEY RootPowerKey, [In] IntPtr SchemeGuid, [In] IntPtr SubGroupOfPowerSettingsGuid, [In] IntPtr PowerSettingGuid, IntPtr Buffer, ref uint BufferSize); + + /// + /// Retrieves the description for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL + /// but both the SubGroupOfPowerSettingsGuid and PowerSettingGuid parameters are NULL, the description of the power scheme + /// will be returned. If the SchemeGuid and SubGroupOfPowerSettingsGuid parameters are not NULL and the PowerSettingGuid + /// parameter is NULL, the description of the subgroup will be returned. If the SchemeGuid, SubGroupOfPowerSettingsGuid, and + /// PowerSettingGuid parameters are not NULL, the description of the power setting will be returned. + /// + /// This parameter is reserved for future use and must be set to NULL. + /// The identifier of the power scheme. + /// + /// + /// The subgroup of power settings. This parameter can be one of the following values defined in WinNT.h. Use NO_SUBGROUP_GUID + /// to refer to the default power scheme. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NO_SUBGROUP_GUID fea3413e-7e05-4911-9a71-700331f1c294 + /// Settings in this subgroup are part of the default power scheme. + /// + /// + /// GUID_DISK_SUBGROUP 0012ee47-9041-4b5d-9b77-535fba8b1442 + /// Settings in this subgroup control power management configuration of the system's hard disk drives. + /// + /// + /// GUID_SYSTEM_BUTTON_SUBGROUP 4f971e89-eebd-4455-a8de-9e59040e7347 + /// Settings in this subgroup control configuration of the system power buttons. + /// + /// + /// GUID_PROCESSOR_SETTINGS_SUBGROUP 54533251-82be-4824-96c1-47b60b740d00 + /// Settings in this subgroup control configuration of processor power management features. + /// + /// + /// GUID_VIDEO_SUBGROUP 7516b95f-f776-4464-8c53-06167f40cc99 + /// Settings in this subgroup control configuration of the video power management features. + /// + /// + /// GUID_BATTERY_SUBGROUP e73a048d-bf27-4f12-9731-8b2076e8891f + /// Settings in this subgroup control battery alarm trip points and actions. + /// + /// + /// GUID_SLEEP_SUBGROUP 238C9FA8-0AAD-41ED-83F4-97BE242C8F20 + /// Settings in this subgroup control system sleep settings. + /// + /// + /// GUID_PCIEXPRESS_SETTINGS_SUBGROUP 501a4d13-42af-4429-9fd1-a8218c268e20 + /// Settings in this subgroup control PCI Express settings. + /// + /// + /// + /// The identifier of the power setting that is being used. + /// + /// The description. + /// + [PInvokeData("powrprof.h", MSDNShortId = "3c264f4f-fd1b-466b-ba76-fe78593a3628")] + public static string PowerReadDescription([In] Guid? SchemeGuid = null, [In] Guid? SubGroupOfPowerSettingsGuid = null, [In] Guid? PowerSettingGuid = null) => + PwrReadMem(PowerReadDescription, SchemeGuid, SubGroupOfPowerSettingsGuid, PowerSettingGuid)?.ToString(-1) ?? string.Empty; /// /// Retrieves the friendly name for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL @@ -1597,7 +1650,63 @@ namespace Vanara.PInvoke // LPDWORD BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("powrprof.h", MSDNShortId = "e6e46bbf-f9be-4dee-8976-df48bb1ccdf4")] - public static extern Win32Error PowerReadFriendlyName([Optional] HKEY RootPowerKey, in Guid SchemeGuid, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, StringBuilder Buffer, ref uint BufferSize); + public static extern Win32Error PowerReadFriendlyName([Optional] HKEY RootPowerKey, [In] IntPtr SchemeGuid, [In] IntPtr SubGroupOfPowerSettingsGuid, [In] IntPtr PowerSettingGuid, IntPtr Buffer, ref uint BufferSize); + + /// + /// Retrieves the friendly name for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL + /// but both the SubGroupOfPowerSettingsGuid and PowerSettingGuid parameters are NULL, the friendly name of the power scheme + /// will be returned. If the SchemeGuid and SubGroupOfPowerSettingsGuid parameters are not NULL and the PowerSettingGuid + /// parameter is NULL, the friendly name of the subgroup will be returned. If the SchemeGuid, SubGroupOfPowerSettingsGuid, and + /// PowerSettingGuid parameters are not NULL, the friendly name of the power setting will be returned. + /// + /// The identifier of the power scheme. + /// The subgroup of power settings. Use NO_SUBGROUP_GUID to refer to the default power scheme. + /// + /// + /// Value + /// Meaning + /// + /// + /// NO_SUBGROUP_GUID fea3413e-7e05-4911-9a71-700331f1c294 + /// Settings in this subgroup are part of the default power scheme. + /// + /// + /// GUID_DISK_SUBGROUP 0012ee47-9041-4b5d-9b77-535fba8b1442 + /// Settings in this subgroup control power management configuration of the system's hard disk drives. + /// + /// + /// GUID_SYSTEM_BUTTON_SUBGROUP 4f971e89-eebd-4455-a8de-9e59040e7347 + /// Settings in this subgroup control configuration of the system power buttons. + /// + /// + /// GUID_PROCESSOR_SETTINGS_SUBGROUP 54533251-82be-4824-96c1-47b60b740d00 + /// Settings in this subgroup control configuration of processor power management features. + /// + /// + /// GUID_VIDEO_SUBGROUP 7516b95f-f776-4464-8c53-06167f40cc99 + /// Settings in this subgroup control configuration of the video power management features. + /// + /// + /// GUID_BATTERY_SUBGROUP e73a048d-bf27-4f12-9731-8b2076e8891f + /// Settings in this subgroup control battery alarm trip points and actions. + /// + /// + /// GUID_SLEEP_SUBGROUP 238C9FA8-0AAD-41ED-83F4-97BE242C8F20 + /// Settings in this subgroup control system sleep settings. + /// + /// + /// GUID_PCIEXPRESS_SETTINGS_SUBGROUP 501a4d13-42af-4429-9fd1-a8218c268e20 + /// Settings in this subgroup control PCI Express settings. + /// + /// + /// The identifier of the power setting that is being used. + /// The friendly name. + // https://docs.microsoft.com/en-us/windows/desktop/api/powrprof/nf-powrprof-powerreadfriendlyname DWORD PowerReadFriendlyName( HKEY + // RootPowerKey, const GUID *SchemeGuid, const GUID *SubGroupOfPowerSettingsGuid, const GUID *PowerSettingGuid, PUCHAR Buffer, + // LPDWORD BufferSize ); + [PInvokeData("powrprof.h", MSDNShortId = "e6e46bbf-f9be-4dee-8976-df48bb1ccdf4")] + public static string PowerReadFriendlyName([In] Guid? SchemeGuid = null, [In] Guid? SubGroupOfPowerSettingsGuid = null, [In] Guid? PowerSettingGuid = null) => + PwrReadMem(PowerReadFriendlyName, SchemeGuid, SubGroupOfPowerSettingsGuid, PowerSettingGuid)?.ToString(-1) ?? string.Empty; /// /// Retrieves the icon resource for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL @@ -1677,7 +1786,7 @@ namespace Vanara.PInvoke // *PowerSettingGuid, PUCHAR Buffer, LPDWORD BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("powrprof.h", MSDNShortId = "d9454acd-7a4a-4f54-b614-beee8763f1ef")] - public static extern Win32Error PowerReadIconResourceSpecifier([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, IntPtr Buffer, ref uint BufferSize); + public static extern Win32Error PowerReadIconResourceSpecifier([Optional] HKEY RootPowerKey, [In] IntPtr SchemeGuid, [In] IntPtr SubGroupOfPowerSettingsGuid, [In] IntPtr PowerSettingGuid, IntPtr Buffer, ref uint BufferSize); /// Retrieves the description for one of the possible choices of a power setting value. /// This parameter is reserved for future use and must be set to NULL. @@ -1748,9 +1857,9 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/desktop/api/powrprof/nf-powrprof-powerreadpossibledescription DWORD // PowerReadPossibleDescription( HKEY RootPowerKey, const GUID *SubGroupOfPowerSettingsGuid, const GUID *PowerSettingGuid, ULONG // PossibleSettingIndex, PUCHAR Buffer, LPDWORD BufferSize ); - [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] + [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("powrprof.h", MSDNShortId = "e803dc6b-706a-49fc-8c8d-ba9b0ccf8491")] - public static extern Win32Error PowerReadPossibleDescription([Optional] HKEY RootPowerKey, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, uint PossibleSettingIndex, IntPtr Buffer, ref uint BufferSize); + public static extern Win32Error PowerReadPossibleDescription([Optional] HKEY RootPowerKey, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, uint PossibleSettingIndex, StringBuilder Buffer, ref uint BufferSize); /// Retrieves the friendly name for one of the possible choices of a power setting value. /// This parameter is reserved for future use and must be set to NULL. @@ -2648,7 +2757,70 @@ namespace Vanara.PInvoke // BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("powrprof.h", MSDNShortId = "42ee26ac-1a9c-4390-92e8-879b401168c7")] - public static extern Win32Error PowerWriteDescription([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, string Buffer, uint BufferSize); + public static extern Win32Error PowerWriteDescription([Optional] HKEY RootPowerKey, [In] IntPtr SchemeGuid, [In] IntPtr SubGroupOfPowerSettingsGuid, [In] IntPtr PowerSettingGuid, string Buffer, uint BufferSize); + + /// Sets the description for the specified power setting, subgroup, or scheme. + /// The identifier of the power scheme. + /// + /// + /// The subgroup of power settings. This parameter can be one of the following values defined in WinNT.h. Use NO_SUBGROUP_GUID + /// to refer to the default power scheme. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NO_SUBGROUP_GUID fea3413e-7e05-4911-9a71-700331f1c294 + /// Settings in this subgroup are part of the default power scheme. + /// + /// + /// GUID_DISK_SUBGROUP 0012ee47-9041-4b5d-9b77-535fba8b1442 + /// Settings in this subgroup control power management configuration of the system's hard disk drives. + /// + /// + /// GUID_SYSTEM_BUTTON_SUBGROUP 4f971e89-eebd-4455-a8de-9e59040e7347 + /// Settings in this subgroup control configuration of the system power buttons. + /// + /// + /// GUID_PROCESSOR_SETTINGS_SUBGROUP 54533251-82be-4824-96c1-47b60b740d00 + /// Settings in this subgroup control configuration of processor power management features. + /// + /// + /// GUID_VIDEO_SUBGROUP 7516b95f-f776-4464-8c53-06167f40cc99 + /// Settings in this subgroup control configuration of the video power management features. + /// + /// + /// GUID_BATTERY_SUBGROUP e73a048d-bf27-4f12-9731-8b2076e8891f + /// Settings in this subgroup control battery alarm trip points and actions. + /// + /// + /// GUID_SLEEP_SUBGROUP 238C9FA8-0AAD-41ED-83F4-97BE242C8F20 + /// Settings in this subgroup control system sleep settings. + /// + /// + /// GUID_PCIEXPRESS_SETTINGS_SUBGROUP 501a4d13-42af-4429-9fd1-a8218c268e20 + /// Settings in this subgroup control PCI Express settings. + /// + /// + /// + /// The identifier of the power setting. + /// The description, in wide (Unicode) characters. + /// Returns ERROR_SUCCESS (zero) if the call was successful, and a nonzero value if the call failed. + /// + /// + /// If the SchemeGuid parameter is not NULL but both the SubGroupOfPowerSettingsGuid and PowerSettingGuid parameters are + /// NULL, the description of the power scheme will be set. If the SchemeGuid and SubGroupOfPowerSettingsGuid parameters are + /// not NULL and the PowerSettingGuid parameter is NULL, the description of the subgroup will be set. If the + /// SchemeGuid, SubGroupOfPowerSettingsGuid, and PowerSettingGuid parameters are not NULL, the description of the power + /// setting will be set. + /// + /// Changes to the settings for the active power scheme do not take effect until you call the PowerSetActiveScheme function. + /// + [PInvokeData("powrprof.h", MSDNShortId = "42ee26ac-1a9c-4390-92e8-879b401168c7")] + public static Win32Error PowerWriteDescription([In] Guid? SchemeGuid, [In] Guid? SubGroupOfPowerSettingsGuid, [In] Guid? PowerSettingGuid, string Buffer) => + PwrGuidTsl(SchemeGuid, SubGroupOfPowerSettingsGuid, PowerSettingGuid, (p1, p2, p3) => PowerWriteDescription(default, p1, p2, p3, Buffer, (uint)(Buffer.Length + 1) * 2)); /// /// Sets the friendly name for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL but @@ -2715,7 +2887,68 @@ namespace Vanara.PInvoke // DWORD BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("powrprof.h", MSDNShortId = "3d81f634-8095-49c6-a5fe-6fe5e33bf0aa")] - public static extern Win32Error PowerWriteFriendlyName([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, string Buffer, uint BufferSize); + public static extern Win32Error PowerWriteFriendlyName([Optional] HKEY RootPowerKey, [In] IntPtr SchemeGuid, [In] IntPtr SubGroupOfPowerSettingsGuid, [In] IntPtr PowerSettingGuid, string Buffer, uint BufferSize); + + /// + /// Sets the friendly name for the specified power setting, subgroup, or scheme. If the SchemeGuid parameter is not NULL but + /// both the SubGroupOfPowerSettingsGuid and PowerSettingGuid parameters are NULL, the friendly name of the power scheme will + /// be set. If the SchemeGuid and SubGroupOfPowerSettingsGuid parameters are not NULL and the PowerSettingGuid parameter is + /// NULL, the friendly name of the subgroup will be set. If the SchemeGuid, SubGroupOfPowerSettingsGuid, and PowerSettingGuid + /// parameters are not NULL, the friendly name of the power setting will be set. + /// + /// This parameter is reserved for future use and must be set to NULL. + /// The identifier of the power scheme. + /// + /// + /// The subgroup of power settings. This parameter can be one of the following values defined in WinNT.h. Use NO_SUBGROUP_GUID + /// to refer to the default power scheme. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NO_SUBGROUP_GUID fea3413e-7e05-4911-9a71-700331f1c294 + /// Settings in this subgroup are part of the default power scheme. + /// + /// + /// GUID_DISK_SUBGROUP 0012ee47-9041-4b5d-9b77-535fba8b1442 + /// Settings in this subgroup control power management configuration of the system's hard disk drives. + /// + /// + /// GUID_SYSTEM_BUTTON_SUBGROUP 4f971e89-eebd-4455-a8de-9e59040e7347 + /// Settings in this subgroup control configuration of the system power buttons. + /// + /// + /// GUID_PROCESSOR_SETTINGS_SUBGROUP 54533251-82be-4824-96c1-47b60b740d00 + /// Settings in this subgroup control configuration of processor power management features. + /// + /// + /// GUID_VIDEO_SUBGROUP 7516b95f-f776-4464-8c53-06167f40cc99 + /// Settings in this subgroup control configuration of the video power management features. + /// + /// + /// GUID_BATTERY_SUBGROUP e73a048d-bf27-4f12-9731-8b2076e8891f + /// Settings in this subgroup control battery alarm trip points and actions. + /// + /// + /// GUID_SLEEP_SUBGROUP 238C9FA8-0AAD-41ED-83F4-97BE242C8F20 + /// Settings in this subgroup control system sleep settings. + /// + /// + /// GUID_PCIEXPRESS_SETTINGS_SUBGROUP 501a4d13-42af-4429-9fd1-a8218c268e20 + /// Settings in this subgroup control PCI Express settings. + /// + /// + /// + /// The identifier of the power setting. + /// The friendly name, in wide (Unicode) characters. + /// Returns ERROR_SUCCESS (zero) if the call was successful, and a nonzero value if the call failed. + /// Changes to the settings for the active power scheme do not take effect until you call the PowerSetActiveScheme function. + [PInvokeData("powrprof.h", MSDNShortId = "3d81f634-8095-49c6-a5fe-6fe5e33bf0aa")] + public static Win32Error PowerWriteFriendlyName([In] Guid? SchemeGuid, [In] Guid? SubGroupOfPowerSettingsGuid, [In] Guid? PowerSettingGuid, string Buffer) => + PwrGuidTsl(SchemeGuid, SubGroupOfPowerSettingsGuid, PowerSettingGuid, (p1, p2, p3) => PowerWriteFriendlyName(default, p1, p2, p3, Buffer, (uint)(Buffer.Length + 1) * 2)); /// Sets the icon resource for the specified power setting, subgroup, or scheme. /// This parameter is reserved for future use and must be set to NULL. @@ -2783,7 +3016,7 @@ namespace Vanara.PInvoke // *PowerSettingGuid, UCHAR *Buffer, DWORD BufferSize ); [DllImport(Lib.PowrProf, SetLastError = false, ExactSpelling = true)] [PInvokeData("powrprof.h", MSDNShortId = "968b068a-f62a-4148-b96c-48f47218f368")] - public static extern Win32Error PowerWriteIconResourceSpecifier([Optional] HKEY RootPowerKey, in Guid SchemeGuid, [Optional] in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, IntPtr Buffer, uint BufferSize); + public static extern Win32Error PowerWriteIconResourceSpecifier([Optional] HKEY RootPowerKey, in Guid SchemeGuid, in Guid SubGroupOfPowerSettingsGuid, in Guid PowerSettingGuid, IntPtr Buffer, uint BufferSize); /// Sets the description for one of the possible choices of a power setting value. /// This parameter is reserved for future use and must be set to NULL. @@ -3539,6 +3772,29 @@ namespace Vanara.PInvoke [return: MarshalAs(UnmanagedType.U1)] public static extern bool WritePwrScheme(ref uint puiID, [MarshalAs(UnmanagedType.LPWStr)] string lpszSchemeName, [MarshalAs(UnmanagedType.LPWStr)] string lpszDescription, in POWER_POLICY lpScheme); + private static unsafe TRet PwrGuidTsl(Guid? g1, Guid? g2, Guid? g3, Func f) + { + var guids = new Guid[] { g1.GetValueOrDefault(), g2.GetValueOrDefault(), g3.GetValueOrDefault() }; + fixed (Guid* ptrs = guids) + return f(g1.HasValue ? (IntPtr)(void*)&ptrs[0] : IntPtr.Zero, g2.HasValue ? (IntPtr)(void*)&ptrs[1] : IntPtr.Zero, g3.HasValue ? (IntPtr)(void*)&ptrs[2] : IntPtr.Zero); + } + + private static SafeHGlobalHandle PwrReadMem(PwrReadMemFunc f, Guid? g1, Guid? g2, Guid? g3) + { + return PwrGuidTsl(g1, g2, g3, (p1, p2, p3) => { + var sz = 0U; + var err = f(HKEY.NULL, p1, p2, p3, IntPtr.Zero, ref sz); + if (err.Failed) + { + if (err == Win32Error.ERROR_FILE_NOT_FOUND) return null; + if (err != Win32Error.ERROR_MORE_DATA) throw err.GetException(); + } + var p = new SafeHGlobalHandle((int)sz); + f(HKEY.NULL, p1, p2, p3, (IntPtr)p, ref sz).ThrowIfFailed(); + return p; + }); + } + /// Contains parameters used when registering for a power notification. // https://docs.microsoft.com/en-us/windows/desktop/api/powrprof/ns-powrprof-device_notify_subscribe_parameters typedef struct // _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS { PDEVICE_NOTIFY_CALLBACK_ROUTINE Callback; PVOID Context; } diff --git a/UnitTests/PInvoke/PowrProf/PowrProf.cs b/UnitTests/PInvoke/PowrProf/PowrProf.cs index 95dc628d..5d608890 100644 --- a/UnitTests/PInvoke/PowrProf/PowrProf.cs +++ b/UnitTests/PInvoke/PowrProf/PowrProf.cs @@ -27,38 +27,23 @@ namespace Vanara.PInvoke.Tests [Test] public void PowerEnumerateTest() { - var sb = new StringBuilder(1024, 1024); - - Guid? scheme = null; - Guid? subgroup = null; - TestContext.WriteLine("========================= null, null"); - foreach (var value in PowerEnumerate(scheme, subgroup)) - WriteName(value); - - PowerGetActiveScheme(out var gScheme).ThrowIfFailed(); - scheme = gScheme; - subgroup = GUID_SYSTEM_BUTTON_SUBGROUP; - TestContext.WriteLine("========================= Active, GUID_SYSTEM_BUTTON_SUBGROUP"); - foreach (var value in PowerEnumerate(scheme, subgroup)) - WriteName(value); - - subgroup = null; - TestContext.WriteLine("========================= Active, null"); - foreach (var value in PowerEnumerate(scheme, subgroup)) - WriteName(value); - - subgroup = NO_SUBGROUP_GUID; - TestContext.WriteLine("========================= Active, NO_SUBGROUP_GUID"); - foreach (var value in PowerEnumerate(scheme, subgroup)) - WriteName(value); - - void WriteName(in Guid setting) + foreach (var scheme in PowerEnumerate(null, null)) { - sb.Clear(); - var sbSz = (uint)sb.Capacity; - if (PowerReadFriendlyName(default, scheme.GetValueOrDefault(), subgroup.GetValueOrDefault(), setting, sb, ref sbSz).Succeeded) - TestContext.WriteLine($"{sb.ToString()} : {setting}"); + PowerGetActiveScheme(out var active); + TestContext.WriteLine($"Scheme: {scheme} {(scheme == active ? "(Active)" : "")}"); + foreach (var subgroup in PowerEnumerate(scheme, null).Concat(new[] { NO_SUBGROUP_GUID })) + { + TestContext.Write(" "); + WriteName(scheme, subgroup, null); + foreach (var value in PowerEnumerate(scheme, subgroup)) + { + TestContext.Write(" "); + WriteName(scheme, subgroup, value); + } + } } + + void WriteName(Guid? sch, Guid? grp, Guid? setting) { TestContext.WriteLine($"{PowerReadFriendlyName(sch, grp, setting)} : {PowerReadDescription(sch, grp, setting)} : {setting}"); } } [Test] @@ -70,4 +55,4 @@ namespace Vanara.PInvoke.Tests TestContext.WriteLine($"GUID_SYSTEM_BUTTON_SUBGROUP={attr}"); } } -} +} \ No newline at end of file