PowerReadFriendlyName сообщает о ложной длине буфераC#

Место общения программистов C#
Anonymous
PowerReadFriendlyName сообщает о ложной длине буфера

Сообщение Anonymous »

Я создаю программу на C#, которая извлекает имя схемы управления питанием из ее GUID путем P-вызова функции Win32 PowerReadFriendlyName. Однако функция, похоже, сообщает ложную длину буфера.

Код: Выделить всё

Guid id = new Guid("381b4222-f694-41f0-9685-ff5bb260df2e"); // "Balanced" scheme GUID
uint length = 0;

IntPtr ptr = GCHandle.ToIntPtr(GCHandle.Alloc(id));
Marshal.StructureToPtr(id, ptr, true);

PowerReadFriendlyName(IntPtr.Zero, ptr, IntPtr.Zero, IntPtr.Zero, null, ref length);
byte[] buffer = new byte[length];
PowerReadFriendlyName(IntPtr.Zero, ptr, IntPtr.Zero, IntPtr.Zero, buffer, ref length);

Код: Выделить всё

PowerReadFriendlyName
вызывается дважды. Один раз с нулевым указателем в качестве буфера для получения необходимой длины буфера. Опять же с буфером правильной длины для фактического чтения имени.

После первого вызова длина представляет собой абсурдно большое число, но для схемы Balanced она всегда равна 126.

После второго вызова буфер заполняется правильными символами, и длина внезапно становится равной 20, что звучит более убедительно. правильно.

Оба вызова возвращают ERROR_SUCCESS.

TL;DR: Согласно документации MSDN, нулевая ссылка в качестве буфера заставляет функцию сообщать необходимую длину буфера. Однако при наличии нулевой ссылки сообщается о неправильной минимальной длине. Передача массива (пустого или нет) заставляет функцию сообщать правильную минимальную длину.

Что вызывает такое поведение и как его можно предотвратить?

Код: Выделить всё

PowerReadFriendlyName
объявляется следующим образом:

Код: Выделить всё

[DllImport("powrprof.dll")]
public static extern UInt32 PowerReadFriendlyName
(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingsGuid,
IntPtr PowerSettingGuid,
Byte[] Buffer,
ref UInt32 BufferSize
);
Тестирование другой схемы: схема Высокая производительность создает отчет о первом вызове 114, а отчет о втором вызове — 22.

РЕДАКТИРОВАТЬ: Вероятно, стоит отметить, что Balanced является локализованным Balansert, а Высокая производительность Подробнее в среде отладки.

Подробнее здесь: https://stackoverflow.com/questions/265 ... fer-length

Вернуться в «C#»