I'm trying to get SystemBatteryState
using CallNtPowerInformation
. I set SetLastError
attribute to true
, but Marshal.GetLastWin32Error()
always returns 0, even when status code returned by CallNtPowerInformation
not equals to 0.
Example of code where I'm expecting to GetLastWin32Error
return non-zero value (I allocate for outputBuffer less memory than needed):
var outputBufferLength = Marshal.SizeOf(typeof(SYSTEM_BATTERY_STATE)) - 1;
var outputBuffer = Marshal.AllocHGlobal(outputBufferLength);
var statusCode = CallNtPowerInformation(
POWER_INFORMATION_LEVEL.SystemBatteryState,
IntPtr.Zero,
0,
outputBuffer,
(uint)outputBufferLength
);
var errorCode = Marshal.GetLastWin32Error();
Console.WriteLine("Win32 error code: " errorCode);
My CallNtPowerInformation
:
[DllImport("powrprof.dll", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
private static extern uint CallNtPowerInformation(
[In] POWER_INFORMATION_LEVEL informationLevel,
[In] IntPtr inputBuffer,
[In] uint inputBufferLength,
[Out] IntPtr outputBuffer,
[In] uint outputBufferLength
);
CallNtPowerInformation
returns code 3221225507 (STATUS_BUFFER_TOO_SMALL), but GetLastWin32Error
returns 0. Should it at all return some error? Or what am I doing wrong?
P.S. Maybe it's enough to have only status code from CallNtPowerInformation
, but why do we need then SetLastError = true
?
CodePudding user response:
GetLastWin32Error
will only work for methods where the documentation says that they set the last error value. CallNtPowerInformation
is not one of those. This method directly returns an error code, so the last error code will not be updated. Using SetLastError = true
in the declaration of a method that does not use the last error value is useless and has no effect (other than eventually returning the error code from a previous failed system call).
The documentation explicitly says something like "Use GetLastError to get more information" for functions that update the value returned by GetLastError.