P调用AddSecurityPackageA

时间:2019-02-12 15:05:24

标签: c# .net security pinvoke

我正在一个需要P调用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行,MSDN上的C ++结构将其作为void指针,但是在研究时我发现C#等效项是IntPtr。正确吗?还是我需要使用unsafe
  3. 总的来说,除了阅读他人的代码外,还有没有人找到任何非常好的PInvoke教程?我要从Python迁移过来,所以它有很大的不同,我发现的大部分内容是“画一个圆,画出猫头鹰的其余部分”或冗长而冗长的MSDN文档,这些文档做出了许多假设。 li>

谢谢!

2 个答案:

答案 0 :(得分:1)

一些评论:

  1. 使用W函数而不是A函数。您不想将自己局限于ANSI。这是一个Unicode世界。
  2. 该函数具有返回值。您必须使用匹配的返回值类型声明该函数。大概是uintint,但是您应该签入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是正确的,但这仍未解决如何声明数字签名并获得指向它的指针的问题。我认为这不是我们要解决的一个示例。

答案 1 :(得分:0)

这个对我有用:

    [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
    );