gpt4 book ai didi

C# p/invoke Secur32.dll 问题

转载 作者:行者123 更新时间:2023-12-04 06:26:55 27 4
gpt4 key购买 nike

我正在尝试包装 Secur32.dll 的 EnumerateSecurityPackages下面声明的函数:

SECURITY_STATUS SEC_Entry EnumerateSecurityPackages(
__in PULONG pcPackages,
__in PSecPkgInfo *ppPackageInfo
);

我有以下 C# 代码,但是当我尝试运行它时得到了 AccessViolationException。在调试器中,pcPackages 变量确实设置正确,但我认为我对 SecPkgInfos 数组做错了。
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgInfo
{
public ulong fCapabilities;
public ushort wVersion;
public ushort wRPCID;
public ulong cbMaxToken;
public string Name;
public string Comment;
}

[DllImport("Secur32.dll")]
public extern static int EnumerateSecurityPackages(
ref ulong pcPackages,
ref SecPkgInfo[] ppPackageInfo
);

///Calling code
ulong count = 0;
SecPkgInfo[] buffer = new SecPkgInfo[256];
EnumerateSecurityPackages(ref count, ref buffer);

任何想法我做错了什么?

最佳答案

试试这段代码,它是从 VB.Net(我的母语)转换而来的,但在 C# 中对我来说运行良好。只需调用Call_EnumerateSecurityPackages()它会为您返回一个列表。

    public static List<SecPkgInfo> Call_EnumerateSecurityPackages()
{
//Will hold the number of security packages found
UInt32 count = 0;

//Will hold a pointer to our array
IntPtr SourcePoint = IntPtr.Zero;

//Call function
int MSG = EnumerateSecurityPackages(ref count, ref SourcePoint);
//See if there was an error
if (MSG == 0)
{
//Create a copy of our pointer so that we can clear it later
IntPtr ArrayPtr = new IntPtr(SourcePoint.ToInt32());
//The type of our structure
Type T = typeof(SecPkgInfo);
//The size of our structure
int ObjSize = Marshal.SizeOf(T);
//We'll store our information in a standard list object
List<SecPkgInfo> SecPackages = new List<SecPkgInfo>();

//Create a loop and increment our pointer by the size of the SecPkgInfo structure, effectively walking the array
for (ulong I = 0; I <= (count - 1); I++)
{
//This converts the current bytes at the pointer to the given structure
SecPackages.Add((SecPkgInfo)Marshal.PtrToStructure(ArrayPtr, T));

//Increment our pointer by the size of the structure
ArrayPtr = IntPtr.Add(ArrayPtr, ObjSize);
}

//Cleanup our pointer
MSG = FreeContextBuffer(ref SourcePoint);

//Make sure cleanup worked
if (MSG == 0)
{
//Return our values
return SecPackages;
}
else
{
//Do something better with the error code here
throw new ApplicationException("Error cleaning up pointer");
}
}
else
{
//Do something better with the error code here
throw new ApplicationException("Error calling native function");
}

}

[StructLayout(LayoutKind.Sequential)]
public struct SecPkgInfo
{
//ulong is 32 bit so we need to use a 32 bit int
public UInt32 fCapabilities;
//ushort is 16 bit
public UInt16 wVersion;
public UInt16 wRPCID;
public UInt32 cbMaxToken;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string Name;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string Comment;
}

[DllImport("Secur32.dll")]
public static extern int EnumerateSecurityPackages(ref UInt32 pcPackages, ref IntPtr ppPackageInfo);

[DllImport("Secur32.dll")]
public static extern int FreeContextBuffer(ref IntPtr pvContextBuffer);

为了将来使用,这里是 VB 版本:
Public Shared Function Call_EnumerateSecurityPackages() As List(Of SecPkgInfo)
''//Will hold the number of security packages found
Dim count As UInt32 = 0

''//Will hold a pointer to our array
Dim SourcePoint As IntPtr

''//Call function
Dim MSG = EnumerateSecurityPackages(count, SourcePoint)
''//See if there was an error
If MSG = 0 Then
''//Create a copy of our pointer so that we can clear it later
Dim ArrayPtr As New IntPtr(SourcePoint.ToInt32())
''//The type of our structure
Dim T = GetType(SecPkgInfo)
''//The size of our structure
Dim ObjSize = Marshal.SizeOf(T)
''//We will store our information in a standard list object
Dim SecPackages As New List(Of SecPkgInfo)

''//Create a loop and increment our pointer by the size of the SecPkgInfo structure, effectively walking the array
For I = 0 To (count - 1)
''//This converts the current bytes at the pointer to the given structure
SecPackages.Add(CType(Marshal.PtrToStructure(ArrayPtr, T), SecPkgInfo))
''//Increment our pointer by the size of the structure
ArrayPtr = IntPtr.Add(ArrayPtr, ObjSize)
Next

''//Cleanup our pointer
MSG = FreeContextBuffer(SourcePoint)

''//Make sure cleanup worked
If MSG = 0 Then
''//Return our values
Return SecPackages
Else
''//Do something better with the error code here
Throw New ApplicationException("Error cleaning up pointer")
End If
Else
''//Do something better with the error code here
Throw New ApplicationException("Error calling native function")
End If

End Function

<StructLayout(LayoutKind.Sequential)>
Public Structure SecPkgInfo
Public fCapabilities As UInt32 ''//ulong is 32 bit so we need to use a 32 bit int
Public wVersion As UInt16 ''//ushort is 16 bit
Public wRPCID As UInt16
Public cbMaxToken As UInt32
<MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)> Public Name As String
<MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)> Public Comment As String
End Structure

<DllImport("Secur32.dll")>
Public Shared Function EnumerateSecurityPackages(ByRef pcPackages As UInt32, ByRef ppPackageInfo As IntPtr) As Integer
End Function

<DllImport("Secur32.dll")>
Public Shared Function FreeContextBuffer(ByRef pvContextBuffer As IntPtr) As Integer
End Function

关于C# p/invoke Secur32.dll 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5940386/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com