Я работаю над проектом, в котором мне нужно 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);
Мои вопросы:
ref и правильно ли это в соответствии с документацией MSDN?IntPtr. Это правильно или мне нужно использовать unsafe?Спасибо!





Некоторые комментарии:
W, а не функцию A. Вы не хотите ограничивать себя ANSI. Это мир Юникода.uint или int, но вы должны проверить заголовочный файл C++.ref string неправильный. Это должен быть string.ref SECURITY_PACKAGE_OPTIONS[] неправильный. Это не массив. Это указатель на struct. Поскольку вы объявили SECURITY_PACKAGE_OPTIONS как класс, ссылочный тип, вы можете заменить ref SECURITY_PACKAGE_OPTIONS[] на SECURITY_PACKAGE_OPTIONS.unsigned long — 32-битный, поэтому в C# он должен быть uint.IntPtr прав, но остается нерешенным вопрос о том, как объявить цифровую подпись и получить указатель на нее. Я думаю, что это выходит за рамки этого вопроса, чтобы мы могли найти пример того, как это сделать.Приносим извинения за задержку с ответом вам. Это было очень полезно. У меня есть еще несколько вопросов, если вы не возражаете.
Сначала я проверил заголовочный файл sspi.h и обнаружил, что опция SECURITY_PACKAGE_OPTIONS помечена как необязательная. Из-за этого могу ли я полностью удалить структуру и обнулить ее? Во-вторых, я не смог найти типы вывода в заголовке, но я нашел это, который показывает, что в случае успеха возвращается 0x00000000. Могу я просто сказать if output != 0, cw(something went wrong)?
Этот работает для меня:
[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
);
C++ ulong является 32-разрядным, поэтому он должен быть C# uint, options — это всего лишь один элемент, а не массив, поэтому он должен быть
ref SECURITY_PACKAGE_OPTIONS Options, если SECURITY_PACKAGE_OPTIONS является структурой, или без ссылки, если это класс. IntPtr правильный, вам не нужен unsafe (он вам почти никогда не нужен, он больше используется по соображениям производительности). Функция возвращает 32-битный (для проверки на ошибки)