AzMan Data Store through COM Interop
If you have an ASP.NET application, you can use the AuthorizationStoreRoleProvider which adheres to the Role Provider model expected by ASP.NET and retrieves role information from Microsoft Authorization Manager (AzMan).
AzMan itself is a COM based application and all communications with the store occur through COM Introp exposed in Microsoft.Interop.Security.AzRoles namespace. If you decide not to use the AuthorizationStoreRoleProvider (for instance if you are in a Windows Application), you can directly use the COM Introp layer provided by Microsoft. See here for a list of wrapper methods and objects.
When directly using these wrappers, you need to ensure that you always release the COM objects that are no longer required. For instance when creating and submitting a new Role in AzMan then you must use Marshal. FinalReleaseComObject or Marshal. ReleaseComObject to release the COM object:
IAzRole role = app.CreateRole("Test", null);
role.Submit(0, null);
Marshal.FinalReleaseComObject(role);
And here is another example:
IAzRole role = app.OpenRole("Test", null);
app.DeleteRole("Test", null);
Marshal.FinalReleaseComObject(role);
If you don’t release the COM object, the code snippet below may throw a “Cannot create a file when that file already exists. (Exception from HRESULT: 0x800700B7)” COMException or some other unexpected exceptions:
app.CreateRole("Test", null);
app.DeleteRole("Test", null);
app.CreateRole("Test", null);
The above is also applied to enumerators – only on some versions of Windows. Many of the enumerators automatically generated by the wrapper library internally use COM objects which need to be released. For instance the code below does not release all COM objects:
foreach (IAzRole role in app.Roles)
{
app.DeleteRole(role.Name, null);
Marshal.FinalReleaseComObject(role);
}
What you really want is the following:
IEnumerable roles = app.Roles;
IEnumerator enumerator = roles.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
IAzRole role = enumerator.Current as IAzRole;
try
{
app.DeleteRole(role.Name, null);
}
finally
{
Marshal.FinalReleaseComObject(role);
}
}
}
finally
{
ICustomAdapter adapter = (ICustomAdapter)enumerator;
Marshal.ReleaseComObject(adapter.GetUnderlyingObject());
Marshal.FinalReleaseComObject(roles);
}
As you can see the enumerator also internally uses a COM object which may not be released automatically and should be released manually. This underlying COM object is accessible through:
((ICustomAdapter)enumerator).GetUnderlyingObject()
Comments
Anonymous
October 03, 2007
PingBack from http://www.artofbam.com/wordpress/?p=5108Anonymous
February 05, 2008
WoW, This blog was a life saver. Having zero experience with COM, I would of never guessed to do this. I was having the exact COMExceptions, but thanks to your post I know what to do now.