Implemented the ability to query the EnumerateSecurityPackages native API safely.
This commit is contained in:
@@ -33,5 +33,10 @@ namespace NSspi
|
||||
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||
[DllImport( "Secur32.dll", EntryPoint = "QuerySecurityPackageInfo", CharSet = CharSet.Unicode )]
|
||||
internal static extern SecurityStatus QuerySecurityPackageInfo( string packageName, ref IntPtr pkgInfo );
|
||||
|
||||
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||
[DllImport( "Secur32.dll", EntryPoint = "EnumerateSecurityPackages", CharSet = CharSet.Unicode )]
|
||||
internal static extern SecurityStatus EnumerateSecurityPackages( ref int numPackages, ref IntPtr pkgInfoArry );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace NSspi
|
||||
internal static SecPkgInfo GetPackageCapabilities( string packageName )
|
||||
{
|
||||
SecPkgInfo info;
|
||||
SecurityStatus status;
|
||||
SecurityStatus status = SecurityStatus.InternalError;
|
||||
SecurityStatus freeStatus;
|
||||
|
||||
IntPtr rawInfoPtr;
|
||||
@@ -45,8 +45,71 @@ namespace NSspi
|
||||
}
|
||||
}
|
||||
|
||||
if( status != SecurityStatus.OK )
|
||||
{
|
||||
throw new SSPIException( "Failed to query security package provider details", status );
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public static SecPkgInfo[] EnumeratePackages()
|
||||
{
|
||||
SecurityStatus status = SecurityStatus.InternalError;
|
||||
SecPkgInfo[] packages = null;
|
||||
IntPtr pkgArrayPtr;
|
||||
IntPtr pkgPtr;
|
||||
int numPackages = 0;
|
||||
int pkgSize = Marshal.SizeOf( typeof(SecPkgInfo) );
|
||||
|
||||
pkgArrayPtr = new IntPtr();
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try { }
|
||||
finally
|
||||
{
|
||||
status = NativeMethods.EnumerateSecurityPackages( ref numPackages, ref pkgArrayPtr );
|
||||
|
||||
if( pkgArrayPtr != IntPtr.Zero )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( status == SecurityStatus.OK )
|
||||
{
|
||||
// Bwooop Bwooop Alocation Alert
|
||||
// 1) We allocate the array
|
||||
// 2) We allocate the individual elements in the array (they're class objects).
|
||||
// 3) We allocate the strings in the individual elements in the array when we
|
||||
// call Marshal.PtrToStructure()
|
||||
|
||||
packages = new SecPkgInfo[numPackages];
|
||||
|
||||
for( int i = 0; i < numPackages; i++ )
|
||||
{
|
||||
packages[i] = new SecPkgInfo();
|
||||
}
|
||||
|
||||
for( int i = 0; i < numPackages; i++ )
|
||||
{
|
||||
pkgPtr = IntPtr.Add( pkgArrayPtr, i * pkgSize );
|
||||
|
||||
Marshal.PtrToStructure( pkgPtr, packages[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.FreeContextBuffer( pkgArrayPtr );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( status != SecurityStatus.OK )
|
||||
{
|
||||
throw new SSPIException( "Failed to enumerate security package providers", status );
|
||||
}
|
||||
|
||||
return packages;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user