CoCreateInstanceAsAdmin and the Elevation Moniker


You might see that API referred here and there to help with the new UAC scenarios. And you’ll also read that some people are wondering where the API declaration is…


I understand that the COM team implemented Elevation Moniker to super-set this API functionality: The COM Elevation Moniker. From that page:

HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, void ** ppv) {
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];

StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));
HRESULT hr = StringCchPrintf(wszMonikerName,
sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),
L”Elevation:Administrator!new:%s”,
wszCLSID);
if (FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
return CoGetObject(wszMonikerName, &bo, riid, ppv);
}


Auf wiedersehen!

Comments (2)

  1. Andy Bantly says:

    I had problems using the canned CoCreateInstanceAsAdmin from within a DLL.  I wrote this version which works for .exe’s and .dll’s

    HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)

    {

    // Manual implementation of CreateInstanceAsAdmin

    CComPtr<IBindCtx> BindCtx;

    HRESULT hr = CreateBindCtx(0,&BindCtx);

    BIND_OPTS3 bo;

    memset(&bo, 0, sizeof(bo));

    bo.cbStruct = sizeof(bo);

    bo.grfMode = STGM_READWRITE;

    bo.hwnd = NULL;

    bo.dwClassContext = CLSCTX_LOCAL_SERVER;

    hr = BindCtx->SetBindOptions(&bo);

    if (SUCCEEDED(hr))

    {

    // Use the passed in CLSID to help create the COM elevation moniker string

    CComPtr<IMoniker> Moniker;

    WCHAR wszCLSID[50];

    WCHAR wszMonikerName[300];

    StringFromGUID2(rclsid,wszCLSID,sizeof(wszCLSID) / sizeof(wszCLSID[0]));

    hr = StringCchPrintfW(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);

    if (SUCCEEDED(hr))

    {

    // Create the COM elevation moniker

    ULONG ulEaten = 0;

    ULONG ulLen = (ULONG)wcslen(wszMonikerName);

    LPBC pBindCtx = BindCtx.p;

    hr = MkParseDisplayName(pBindCtx,wszMonikerName,&ulEaten,&Moniker);

    if (SUCCEEDED(hr) && ulEaten == ulLen)

    {

    // Use passed in reference to IID to bind to the object

    IDispatch * pv = NULL;

    hr = Moniker->BindToObject(pBindCtx,NULL,riid,ppv);

    }

    }

    }

    return hr;

    }