【发布时间】:2012-08-31 16:05:49
【问题描述】:
文件中有 SECURITY_IDENTIFIER 结构类型的对象。我需要从此结构中获取所有者 SID。为此,我调用GetSecurityDescriptorOwner WinAPI 函数并创建System.Security.Principal.SecurityIdentifier(它具有以 IntPtr 作为参数的重载)
问题是文件中的这个结构有时会被破坏,所以我从 GetSecurityDescriptorOwner 得到的指针是无效的。它不是 IntPtr.Zero,它是无效的,所以当我创建 SecurityIdentifier 类型的对象时,我得到了 AccessViolationException,这在 .NET 4 中无法通过简单的 try-catch 捕获。
我知道允许捕获此类异常的属性,所以我暂时使用它,但我不喜欢这种解决方案。不建议捕获损坏状态异常 (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 构造函数中抛出 Corrupted State Exceptions。有什么解决办法吗?
【问题讨论】:
-
你能给我那个 API 方法的外部定义吗?因为也许你应该使用某种 SafeHandle 而不是 IntPtr。 SafeHandle 得到 IsInvalid。
-
这是一种在其中存储安全描述符的自定义文件格式吗?如果是这样,您为什么要花时间尝试处理这个损坏的描述符,而不是首先修复损坏它的任何东西?
-
这不是定制的。这是HIVE文件。我正在从 SK 记录中提取 SECURITY_IDENTIFIER。我无法修复它,我不需要这样做。我真的不知道它为什么会损坏,它只是在处理大量数据时有时会发生。
标签: c# .net exception error-handling corrupted-state-exception