1

I am trying to get Last Wake Time using CallNtPowerInformation and the value that is being copied into OutputBuffer is of type ULONGLONG in C++ that I believe is equivalent to ulong in C#.

When trying to use Marshal static methods, I do not see a way to get an ulong, only long. Is there a way to get ulong?

My code:

[DllImport("powrprof.dll", SetLastError = true)]
public static extern uint CallNtPowerInformation(
    InformationLevel informationLevel,
    IntPtr lpInputBuffer,
    uint nInputBufferSize,
    IntPtr lpOutpuBuffer,
    nOutputBuffer);

public enum InformationLevel
{
    AdministratorPowerPolicy = 9,
    LastSleepTime = 15,
    LastWakeTime = 14,
    ProcessorInformation = 11,
    ProcessorPowerPolicyAc = 18,
    ProcessorPowerPolicyCurrent = 22,
    ProcessorPowerPolicyDc = 19,
    SystemBatteryState = 5,
    SystemExecutionState = 16,
    SystemPowerCapabilities = 4,
    SystemPowerInformation = 12,
    SystemPowerPolicyAc = 0,
    SystemPowerPolicyCurrent = 8,
    SystemPowerPolicyDc = 1,
    SystemReserveHiberFile = 10,
    VerifyProcessorPowerPolicyAc = 20,
    VerifyProcessorPowerPolicyDc = 21,
    VerifySystemPolicyAc = 2,
    VerifySystemPolicyDc = 3
}

public static ulong GetLastWakeTime()
{
    var lpOutputBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ulong)));
    var ntstatusResult = CallNtPowerInformation(
        InformationLevel.LastWakeTime,
        IntPtr.Zero,
        0,
        lpOuputBuffer,
        (uint)Marshal.SizeOf(typeof(ulong)));
    var lastWakeTime = Marshal.ReadInt64(lpOutputBuffer); // This is where ulong should get read from unmanaged memory
    Marshal.FreeHGlobal(lpOutputBuffer);
    return lastWakeTime;
}
spektro37
  • 187
  • 1
  • 3
  • 12
  • 1
    The Marshal class is CLSCompliant, so is missing overloads for unsigned types. Using `long` is just fine, that machine can be booted 29227 years ago before the program runs into trouble. – Hans Passant Apr 11 '20 at 12:03
  • @HansPassant, thank you for the advise. Good point about 29227 years.:) – spektro37 Apr 11 '20 at 12:07
  • 1
    Check [this post](https://stackoverflow.com/a/17354960/17034) for a technique that lets you avoid using the Marshal class. So in this case `IntPtr` for the 2nd parameter (pass IntPtr.Zero) and `out ulong` for the 4th. – Hans Passant Apr 11 '20 at 12:20

0 Answers0