There is object of type SECURITY_IDENTIFIER structure in the file. I need to get owner SID from this structure. In order to do this I call GetSecurityDescriptorOwner WinAPI function and create System.Security.Principal.SecurityIdentifier (it has overload taking IntPtr as an argument)
The problem is this structure in file is broken sometimes, so the pointer I get from GetSecurityDescriptorOwner is invalid. It's not IntPtr.Zero, it's invalid, so when I create object of type SecurityIdentifier I get AccessViolationException, which is not possible to catch with .NET 4 with a simple try-catch.
I am aware of attribute which allows to catch such exceptions, so I used it for the time being, but I don't like this solution. It's not recommended to catch Corrupted State Exceptions (CSE), but I don't see any other solutions. This WinAPI function returns me invalid pointer and I see no way to check it for validness. Any ideas?
update
WinAPI
BOOL WINAPI GetSecurityDescriptorOwner(
_In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
_Out_ PSID *pOwner,
_Out_ LPBOOL lpbOwnerDefaulted
);
Extern definition
[DllImport("Advapi32.dll")]
static extern bool GetSecurityDescriptorOwner(
IntPtr pSecurityDescriptor,
out IntPtr owner,
out bool defaulted);
update
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;
}
This code throws sometimes throws Corrupted State Exceptions from SecurityIdentifier constructor. Any solutions?
Have you tried calling
IsValidSecurityDescriptor?