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

  • Anonymous
    November 20, 2008
    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; }