michaelmwelch

I'm trying to make a library that I write Vista compatible. UAC is proving a headache because my library writes and modifies data that needs to be shared across all users. So my writes and modifications cannot be virtualized. However, since my library is not a stand alone app itself, I can't specify that virtualization be disabled for the whole app.

So . . . what I need is to request elevation credentials of the user on the fly when my library reaches the point of needing to do a file write. From my reading, the cleanest way to do this seemed to be to isolate my writes into a COM object and then use the Elevated COM Moniker techinque. My COM knowledge is spotty, but this didn't seem to complicated a project, so I've given it a go.

With regard to just getting the writes moved and getting the object working, all is fine. But I am stuck with how to get the elevation portion to run correctly. Specifically, when I return from CoGetClassobject, i always get an error of "0x80080017 The class is not configured to support Elevated activation." But I'm at a loss for how to do this configuration properly.

I note the MSDN class indicates the class must be firutred to run as Activation as Activator. I added a "RunAs" subkey to my object's CLSID key in the registry. I set the value to "Launching User" or to "Acivate as Activator" and I have verified the subkey is indeed present after registering the object with regsvr32. But I still always get the same error.

Vista build 5384

As I said, my knowledge of COM is admittedly spotty to begin with. So I know it's entirely possible (likely, even ) that I'm doing some very elemental COM 101 thing incorrectly.

The code, after I LoadLibrary my DLL, looks like:

_errorCode = CoInitialize(NULL);

if (FAILED(_errorCode))

{

return;

}

hr = StringCchPrintf(monikerName,

RTL_NUMBER_OF(monikerName),

L"Elevation:Administrator!new:%s",

szCLSID);

// monikerName now correctly set to "Elevation:Administrator!new:{<<My GUID>>}"

BIND_OPTS2 bo;

::ZeroMemory(&bo, sizeof(BIND_OPTS2));

bo.cbStruct = sizeof(BIND_OPTS2);

bo.dwClassContext = CLSCTX_LOCAL_SERVER;

_errorCode = CoGetObject(monikerName, &bo, _uuidof(IMyComObjectr), (void **) &_pMyObj);

if ( FAILED(_errorCode) )

{

// Always fails here: 0x80080017 the class is not configured to support Elevated activation.

return;

}

Do the symptoms described above bring to mind any possibilityes among those of you who have managed to do this successfully

- Michael




Re: Application Compatibility for Windows Vista UAC - Elevated COM Moniker

Matthew Braun - MSFT

Hello michaelmwelch,

I am in the same boat as you, my COM is at best extremely basic (in fact you're doing better than me by just writing the code ). My question however is regarding virtualization, if the data you are writing is public accross all users then why not write the data to C:\Users\Public. No virtualization will take place and all users can access this directory and as a bonus your app is still running within a standard user context .

 

Thanks!

Matthew Braun






Re: Application Compatibility for Windows Vista UAC - Elevated COM Moniker

michaelmwelch

Mostly because that's not the best place for it given the nature of the data. \PrograrmData (formerly \Documents and Settings\All Users\Application Data\ in pre-Vista versions of Windows) is really the best place for it. Putting it some place non-virtualized is certainly an option if I can't get this to work. But understandably, I'd much rather just get this to work so I can keep it where it is supposed to be.

I mean I'm sure someone out there has gotten this working, so there has to be a way to do it.

I'm told that the error I'm getting is CO_E_ELEVATION_DISABLED, which supposedly indicates that the Elevation\Enabled key is not present or not populated. I've verfied in regedit, though, that mine is present and indeed set to a value of 1. But I still get this same error every time.


- Michael






Re: Application Compatibility for Windows Vista UAC - Elevated COM Moniker

Matthew Braun - MSFT

The C:\Users\Public directory is the best place to put public data to be shared across all users. C:\ProgramData is the location for shared application data, please see http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=654928&SiteID=1.

Thanks!

Matthew Braun