<November 2014>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

On this page...

Search

Links

Member of...


ASP Insiders

MVP Visual Developer ASP/ASP.NET

Enter CodeZone

Blog Categories

Microsoft

Blogroll

Deutsche Resourcen

Management

Sign In
 

#  Tuesday, January 30, 2007

The previous installment UAC Elevation in Managed Code: Starting Elevated Processes dealt with starting executables with the "real" administrative token. In this blog post, we deal with starting a COM component with elevated privileges. For in-depth background information, please consult Kenny Kerr's absolutely excellent post on Windows Vista for Developers – Part 4 – User Account Control.

To start with, we need a COM component. Instead of writing an ATL C++ COM component from scratch, I took the MyElevateCom sample from CoCreateInstanceAsAdmin or CreateElevatedComObject sample from the Vista Compatibility Team Blog. Note that for building it, check out my post Visual Studio on Vista: Not so Fast!

Assuming that you built and successfully registered the COM component (it is built to the instuctions from Kenny's post), you can go about and write the managed caller. First, we need a reference to the component:

Then comes the tricky part - actually instantiating the COM component. When you take a look at the C++ example, you see that quite some "moniker magic" is involved that cannot be replicated by simply newing up the component. So how to mimic this behavior in managed code? The Microsoft® Windows® Software Development Kit for Windows Vista™ and .NET Framework 3.0 Runtime Components comes to the rescue: inside, you find C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\CrossTechnologySamples.zip, which contains the VistaBridge sample.

From that, I took the VistaBridgeLibary, and modified the static UACManager.LaunchElevatedCOMObject method a bit:

[return: MarshalAs(UnmanagedType.Interface)]
public static object LaunchElevatedCOMObject(Guid Clsid, Guid InterfaceID)
{
  string CLSID = Clsid.ToString("B");
  string monikerName = "Elevation:Administrator!new:" + CLSID;

  NativeMethods.BIND_OPTS3 bo = new NativeMethods.BIND_OPTS3();
  bo.cbStruct = (uint)Marshal.SizeOf(bo);
  bo.hwnd = IntPtr.Zero;
  bo.dwClassContext = (int)NativeMethods.CLSCTX.CLSCTX_LOCAL_SERVER;

  object retVal = UnsafeNativeMethods.CoGetObject(monikerName, ref bo, InterfaceID);

  return (retVal);
}

Modifications: the method is now public instead of internal, and CLSCTX changed to local server (otherwise it wouldn't work).

Next, we need a UI:

This button is the CommandLinkWinForms control from VistaBridgeLibary, with the ShieldIcon property set to true.

Let's hook up the event code:

private void tryItButton_Click(object sender, EventArgs e)
{
 Guid IID_ITheElevated =
  new Guid(0x5EFC3EFB, 0xC7D3, 0x4D00, 0xB7, 0x2E, 0x2F, 0x86, 0x4A, 0x1E, 0xAD, 0x06);

 Guid CLSID_TheElevated =
  new Guid(0x253E7696, 0xA524, 0x4E49, 0x9E, 0x50, 0xBF, 0xCC, 0x29, 0x91, 0x31, 0x23);

 object o = UACManager.LaunchElevatedCOMObject(CLSID_TheElevated, IID_ITheElevated);

 ITheElevated iface = (ITheElevated)o;

 // Call the method on the interface just like in the C++ example
 iface.ShowMe();

 // Release the object
 Marshal.ReleaseComObject(o);
}

The interface ID as well as class ID guids come directly from the C++ project (it is always a good idea to "speak" more than one language), but you could obtain those from the type library or registry as well if you don't have the source code of the component handy.

Object creation is handled via LaunchElevatedCOMObject, and the resultant object is cast to the interface from the imported type library. Noteable (and important) is the last line: because the object wasn't created by the runtime, we have to take care of its destruction (the created interface doesn't have a Release() method, so we use Marshal.ReleaseComObject).

That's it - your managed code is now instantiating an elevated COM object that has full reign over the system.

ElevateCOMComponentSample.zip (117.07 KB)

Categories: .NET | Security | UAC | Use the source Luke | Vista
Tuesday, January 30, 2007 10:14:50 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]

 



© Copyright 2014 Christoph Wille

newtelligence dasBlog 2.3.9074.18820
Subscribe to this weblog's RSS feed with SharpReader, Radio Userland, NewsGator or any other aggregator listening on port 5335 by clicking this button.   RSS 2.0|Atom 1.0  Send mail to the author(s)

 
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.