Вызов AddSecurityPackageA

Я работаю над проектом, в котором мне нужно PInvoke функцию secur32!AddSecurityPackageA, но я все еще изучаю все тонкости того, как это сделать вручную, и мне может понадобиться помощь.

Вот ссылки, с которыми я работаю:

А вот пример моего кода, где я пытаюсь определить структуру и вызвать функцию:

[DllImport("secur32.dll", EntryPoint = "AddSecurityPackageA")]
  public static extern void AddSecurityPackageA(
  ref string pszPackageName,
  ref SECURITY_PACKAGE_OPTIONS[] Options
);

[StructLayout(LayoutKind.Sequential, CharSet =CharSet.Ansi)]
public class SECURITY_PACKAGE_OPTIONS
{
  public ulong Size;
  public ulong Type;
  public ulong Flags;
  public ulong SignatureSize;
  public IntPtr Signature;
}

string dll = @"c:\temp\test.dll";
SECURITY_PACKAGE_OPTIONS[] pkgOpts = new SECURITY_PACKAGE_OPTIONS();

AddSecurityPackageA(ref dll, ref pkgOpts);

Мои вопросы:

  1. В строках 3 и 4 правильно ли используется ref и правильно ли это в соответствии с документацией MSDN?
  2. В строке 14 структура C++ в MSDN имеет this как недействительный указатель, но при исследовании я обнаружил, что эквивалентом C# является IntPtr. Это правильно или мне нужно использовать unsafe?
  3. В общем, нашел ли кто-нибудь действительно хорошие туториалы по PInvoke помимо чтения чужого кода? Я перехожу с Python, поэтому он немного отличается, и многое из того, что я нашел, это либо «нарисуй круг, нарисуй остальную часть совы», либо безумно длинная документация MSDN, которая делает много предположений.

Спасибо!

C++ ulong является 32-разрядным, поэтому он должен быть C# uint, options — это всего лишь один элемент, а не массив, поэтому он должен быть ref SECURITY_PACKAGE_OPTIONS Options, если SECURITY_PACKAGE_OPTIONS является структурой, или без ссылки, если это класс. IntPtr правильный, вам не нужен unsafe (он вам почти никогда не нужен, он больше используется по соображениям производительности). Функция возвращает 32-битный (для проверки на ошибки)

Simon Mourier 12.02.2019 16:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
166
2

Ответы 2

Некоторые комментарии:

  1. Используйте функцию W, а не функцию A. Вы не хотите ограничивать себя ANSI. Это мир Юникода.
  2. Функция имеет возвращаемое значение. Вы должны объявить функцию с соответствующим типом возвращаемого значения. Предположительно это uint или int, но вы должны проверить заголовочный файл C++.
  3. ref string неправильный. Это должен быть string.
  4. ref SECURITY_PACKAGE_OPTIONS[] неправильный. Это не массив. Это указатель на struct. Поскольку вы объявили SECURITY_PACKAGE_OPTIONS как класс, ссылочный тип, вы можете заменить ref SECURITY_PACKAGE_OPTIONS[] на SECURITY_PACKAGE_OPTIONS.
  5. C++ unsigned long — 32-битный, поэтому в C# он должен быть uint.
  6. IntPtr прав, но остается нерешенным вопрос о том, как объявить цифровую подпись и получить указатель на нее. Я думаю, что это выходит за рамки этого вопроса, чтобы мы могли найти пример того, как это сделать.

Приносим извинения за задержку с ответом вам. Это было очень полезно. У меня есть еще несколько вопросов, если вы не возражаете.

dosgatos 15.02.2019 01:43

Сначала я проверил заголовочный файл sspi.h и обнаружил, что опция SECURITY_PACKAGE_OPTIONS помечена как необязательная. Из-за этого могу ли я полностью удалить структуру и обнулить ее? Во-вторых, я не смог найти типы вывода в заголовке, но я нашел это, который показывает, что в случае успеха возвращается 0x00000000. Могу я просто сказать if output != 0, cw(something went wrong)?

dosgatos 15.02.2019 01:49

Этот работает для меня:

    [DllImport("secur32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern uint AddSecurityPackage(
        string pszPackageName,
        SECURITY_PACKAGE_OPTIONS Options
    );

    [DllImport("secur32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern uint DeleteSecurityPackage(
        string pszPackageName
    );

Другие вопросы по теме