文件中有一种类型为SECURITY_IDENTIFIER结构的对象。我需要从这个结构中获取所有者SID。为了做到这一点,我调用了GetSecurityDescriptorOwner WinAPI函数,并创建了System.Security.Principal.SecurityIdentifier(它有一个重载,以IntPtr作为参数)。
问题在于,文件中的这个结构有时会损坏,因此我从GetSecurityDescriptorOwner获得的指针是无效的。它不是IntPtr.Zero,而是无效的,因此当我创建SecurityIdentifier类型的对象时,我会得到AccessViolationException异常,这是无法用.NET 4的简单try-catch捕获的。
我知道有一个属性可以捕获这样的异常,所以我暂时使用了它,但我不喜欢这个解决方案。不建议捕获Corrupted State Exceptions(CSE),但我没有看到其他解决方案。这个WinAPI函数给我返回了无效的指针,我看不到检查它是否有效的方法。有什么想法吗?
更新
WinAPI
问题在于,文件中的这个结构有时会损坏,因此我从GetSecurityDescriptorOwner获得的指针是无效的。它不是IntPtr.Zero,而是无效的,因此当我创建SecurityIdentifier类型的对象时,我会得到AccessViolationException异常,这是无法用.NET 4的简单try-catch捕获的。
我知道有一个属性可以捕获这样的异常,所以我暂时使用了它,但我不喜欢这个解决方案。不建议捕获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构造函数中抛出损坏状态异常。有什么解决方法吗?