dosgatos
dosgatos

Reputation: 43

PInvoking AddSecurityPackageA

I am working on a project where I need to PInvoke the secur32!AddSecurityPackageA function, but I am still learning the ins and outs of how to do this by hand and could use some help.

Here are a the references I am working with:

And here's a sample of my code where I am trying to define the struct and call the function:

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

My questions are:

  1. At lines 3 and 4, is this an appropriate use of ref and is this generally correct according to the MSDN docs?
  2. At line 14, the C++ struct on MSDN has this as a void pointer, but while researching I found that the C# equivalent is an IntPtr. Is that correct or do I need to use unsafe?
  3. In general, has anyone found any really good PInvoke tutorials outside of reading other people's code? I'm moving over from Python so it is quite a bit different and much of what I've found is either "draw a circle, draw the rest of the owl" or insanely lengthy MSDN documentation that makes a lot of assumptions.

Thank you!

Upvotes: 0

Views: 376

Answers (2)

daisy
daisy

Reputation: 23501

This one works for me:

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

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 612993

Some comments:

  1. Use the W function rather than the A function. You don't want to limit yourself to ANSI. This is a Unicode world.
  2. The function has a return value. You must declare the function with a matching return value type. Presumably it is uint or int but you should check in the C++ header file.
  3. ref string is wrong. It should be string.
  4. ref SECURITY_PACKAGE_OPTIONS[] is wrong. It is not an array. It is a pointer to a struct. Since you declared SECURITY_PACKAGE_OPTIONS as a class, a reference type, you can replace ref SECURITY_PACKAGE_OPTIONS[] with SECURITY_PACKAGE_OPTIONS.
  5. C++ unsigned long is 32 bits, so it should be uint in C#.
  6. IntPtr is correct, but that leaves unresolved the question of how to declare the digital signature and obtain a pointer to it. I think it's outside the remit of this question for us to track down an example of how to do that.

Upvotes: 1

Related Questions