文件中有类型SECURITY_IDENTIFIER结构的对象。我需要从这个结构获得所有者SID。为了做到这一点,我调用GetSecurityDescriptorOwner
WinAPI函数并创建System.Security.Principal.SecurityIdentifier
(它有重载以IntPtr作为参数)
问题是文件中的结构有时会被破坏,因此我从GetSecurityDescriptorOwner获取的指针无效。它不是IntPtr.Zero,它是无效的,所以当我创建SecurityIdentifier
类型的对象时,我得到AccessViolationException
,这是不可能用简单的try-catch来捕获.NET 4。
我知道允许捕获此类异常的属性,所以我暂时使用它,但我不喜欢这个解决方案。不建议捕获Corrupted State Exceptions(CSE),但我没有看到任何其他解决方案。这个WinAPI函数返回无效指针,我看不到检查它的有效性。有什么想法吗?
更新
WinAPI的
BOOL WINAPI GetSecurityDescriptorOwner(
_In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
_Out_ PSID *pOwner,
_Out_ LPBOOL lpbOwnerDefaulted
);
外部定义
[DllImport("Advapi32.dll")]
static extern bool GetSecurityDescriptorOwner(
IntPtr pSecurityDescriptor,
out IntPtr owner,
out bool defaulted);
更新
private static SecurityIdentifier GetSecurityIdentifier()
{
// Allocate managed buffer for invalid security descriptor structure (20 bytes)
int[] b = new int[5] {1, 1, 1, 1, 1};
// Allocate unmanaged memory for security descriptor
IntPtr descriptorPtr = Marshal.AllocHGlobal(b.Length);
// Copy invalid security descriptor structure to the unmanaged buffer
Marshal.Copy(b, 0, descriptorPtr, b.Length);
IntPtr ownerSid;
bool defaulted;
if (GetSecurityDescriptorGroup(descriptorPtr, out ownerSid, out defaulted))
{
// GetSecurityDescriptorGroup returns true, but `ownerSid` is `1`
// Marshal.GetLastWin32Error returns 0 here
return new SecurityIdentifier(ownerSid);
}
return null;
}
此代码抛出有时会从SecurityIdentifier构造函数中抛出损坏的状态异常。任何解决方案?
答案 0 :(得分:1)
您是否尝试过调用IsValidSecurityDescriptor
?
[DllImport("Advapi32.dll")]
static extern bool IsValidSecurityDescriptor(IntPtr pSecurityDescriptor);
if (IsValidSecurityDescriptor(descriptorPtr) &&
GetSecurityDescriptorOwner(descriptorPtr, out ownerSid, out defaulted))
{
return new SecurityIdentifier(ownerSid);
}
答案 1 :(得分:0)
<强>更新强>
请改为尝试:
[DllImport("Advapi32.dll")]
static extern bool GetSecurityDescriptorOwner(
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)]
Int32[] securityDescriptor,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)]
out Byte[] owner,
out Boolean defaulted);
[DllImport("Advapi32.dll")]
static extern bool IsValidSecurityDescriptor(
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)]
Int32[] securityDescriptor);
private static SecurityIdentifier GetSecurityIdentifier()
{
// Allocate managed buffer for invalid security descriptor structure (20 bytes)
Int32[] b = new[] { 1, 1, 1, 1, 1 };
Byte[] ownerSid;
bool defaulted;
if (IsValidSecurityDescriptor(b) &&
GetSecurityDescriptorOwner(b, out ownerSid, out defaulted))
{
return new SecurityIdentifier(ownerSid, 0);
}
return null;
}
static void Main()
{
for (Int32 index = 0; index < 1000; index++)
{
SecurityIdentifier identifier = GetSecurityIdentifier();
String text = identifier == null ? "(none)" : identifier.Value;
Console.WriteLine(text);
}
Console.ReadKey();
}