none
UAC Privilege Elevation RRS feed

  • Question

  • I have created a very simple IDispatch COM object that I want to access through a simple Visual Basic Elevation moniker so that I will get the UAC Elevation dialog box. I have added what I believe are the appropriate modifications to the registry for this COM object so that UAC Elevation will be successful i.e. Elevation key and value, LocalizedString, DllSurrogate. In fact, I have been successful at getting the UAC Elevation prompt when I have accessed the COM object from a C++ client, a Jscript client and a VBScript client. However, I am not successful with a VB Application. Following is a snippet of the VB application that I am using to get to the COM object

    Dim obj  As Object

    Set obj = GetObject("Elevation:Administrator!new:jade.pearl")

    obj.dive()   //call a method on the interface

     

    jade.pearl is the friendly name of the IDispatch COM object that I created. Is there something special about a VB application which is different from the other 3 clients that I mentioned above that would explain why the VB application doesn't work? The result of running my VB Application is: Unhandled exception....  Cannot create ActiveX component.

     

    Thanks in advance.

    Fred

    Monday, December 4, 2006 9:26 PM

Answers

  • I have been looking into the problem I described above and I understand the problem a bit better now. I also have a solution although it wasn't quite what I had in mind.The issues revolve around the fact that I am running in a Vista x64 environment. This means that I can have an x64 bit client, or an x32 bit client. I can also have a COM object that is x64 bit or x32 bit. It is important to be mindful of which combination we are working with to understand the behavior we are seeing. The issues also revolve around the fact that while with a C++ client we can specify in-proc or local server activation (CLSCTX_LOCAL_SERVER), we are unable to do so with a Visual Basic application client or with a VBScript or JScript client.

    In my case I had created a dual interface (IDispatch and vtbl) x32 bit in-proc COM object. It was registered with an AppID where DLLSurrogate was set to NULL. My C++ client was also x32 bit. For the C++ case you can specify directly that you want local server activation using the statement

    bo.dwClassContext = CLSCTX_LOCAL_SERVER;

    and this is what you need for UAC elevation to work. Following is the code that I used which shows the CLSCTX_LOCAL_SERVER specification. The code was grabbed from existing articles on the web regarding UAC elevation.

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

    {

    BIND_OPTS3 bo;

    WCHAR wszCLSID[50];

    WCHAR wszMonikerName[300];

    StringFromGUID2(rclsid, wszCLSID, cntof(wszCLSID));

    HRESULT hr = StringCchPrintfW(wszMonikerName,

    cntof(wszMonikerName),

    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);

    }

     

    This functionality worked just fine. I got the UAC elevation I was looking for and was able to access the methods on the COM object just fine.

    I then created a three line VBScript client as follows:

     

    Dim obj As Object

    Set obj = GetObject("Elevation:Administrator!new:jade.pearl")

    obj.dive() //call a method on the interface

     

    What I observed with this client is that it ran with the x64 bit version of WScript.exe. So in this case I had an x64 bit client instantiating my x32 bit COM object. In this case the COM subsystem had no option but to activate my COM object with the DLLSurrogate as an local server process and in this case my elevation logic worked also.

    So finally we get to the VB application client. In this case the client was x32 bit. Because the client was x32 bit and with VB you can't explicitly request local server activation like you can with C++, the COM subsystem activated the COM object as an in-proc server. UAC Elevation logic won't work for in-proc activation - it only works for local server activation. So, in this case I didn't get my UAC Elevation. My solution was to change my COM object so that it was implemented as a local server (i.e. exe) COM object (rather than an in-proc COM object that could run with a DLL surrogate).

    At the beginning of this response, I stated that this was not my preferred solution. I was hoping I would be able to use an in-proc server COM object with a DLL Surrogate because I like the option of using the DLL in either the local server mode (with DLL Surrogate) or the in-proc server mode. If anyone knows of a way to provide for using a DLL COM object in either local server mode or in-proc server mode with a VB application client, please let me know!

     

    Friday, December 8, 2006 10:12 PM

All replies

  • I have been looking into the problem I described above and I understand the problem a bit better now. I also have a solution although it wasn't quite what I had in mind.The issues revolve around the fact that I am running in a Vista x64 environment. This means that I can have an x64 bit client, or an x32 bit client. I can also have a COM object that is x64 bit or x32 bit. It is important to be mindful of which combination we are working with to understand the behavior we are seeing. The issues also revolve around the fact that while with a C++ client we can specify in-proc or local server activation (CLSCTX_LOCAL_SERVER), we are unable to do so with a Visual Basic application client or with a VBScript or JScript client.

    In my case I had created a dual interface (IDispatch and vtbl) x32 bit in-proc COM object. It was registered with an AppID where DLLSurrogate was set to NULL. My C++ client was also x32 bit. For the C++ case you can specify directly that you want local server activation using the statement

    bo.dwClassContext = CLSCTX_LOCAL_SERVER;

    and this is what you need for UAC elevation to work. Following is the code that I used which shows the CLSCTX_LOCAL_SERVER specification. The code was grabbed from existing articles on the web regarding UAC elevation.

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

    {

    BIND_OPTS3 bo;

    WCHAR wszCLSID[50];

    WCHAR wszMonikerName[300];

    StringFromGUID2(rclsid, wszCLSID, cntof(wszCLSID));

    HRESULT hr = StringCchPrintfW(wszMonikerName,

    cntof(wszMonikerName),

    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);

    }

     

    This functionality worked just fine. I got the UAC elevation I was looking for and was able to access the methods on the COM object just fine.

    I then created a three line VBScript client as follows:

     

    Dim obj As Object

    Set obj = GetObject("Elevation:Administrator!new:jade.pearl")

    obj.dive() //call a method on the interface

     

    What I observed with this client is that it ran with the x64 bit version of WScript.exe. So in this case I had an x64 bit client instantiating my x32 bit COM object. In this case the COM subsystem had no option but to activate my COM object with the DLLSurrogate as an local server process and in this case my elevation logic worked also.

    So finally we get to the VB application client. In this case the client was x32 bit. Because the client was x32 bit and with VB you can't explicitly request local server activation like you can with C++, the COM subsystem activated the COM object as an in-proc server. UAC Elevation logic won't work for in-proc activation - it only works for local server activation. So, in this case I didn't get my UAC Elevation. My solution was to change my COM object so that it was implemented as a local server (i.e. exe) COM object (rather than an in-proc COM object that could run with a DLL surrogate).

    At the beginning of this response, I stated that this was not my preferred solution. I was hoping I would be able to use an in-proc server COM object with a DLL Surrogate because I like the option of using the DLL in either the local server mode (with DLL Surrogate) or the in-proc server mode. If anyone knows of a way to provide for using a DLL COM object in either local server mode or in-proc server mode with a VB application client, please let me know!

     

    Friday, December 8, 2006 10:12 PM