Pregunta

Estoy desarrollando un COM sustituto objeto en C, que será utilizado por mis aplicaciones para llamar al diálogo de elevación de UAC para ciertas acciones que requieren derechos de administrador.

El plan es hacer que este se exporta una función que toma un puntero a una función con un número variable de argumentos y lo ejecuta en un contexto diferente. De esta manera, una aplicación puede utilizar este objeto para realizar algunas acciones con derechos de administrador, todo lo que necesitan hacer es usar ese objeto y pasar un puntero a la función que tiene que ser ejecutada con dichos derechos.

Esto funciona parcialmente, llamando a CoCreateInstance va bien, el puntero de función se pasa y se ejecuta mi función. Sin embargo, cuando se crea una instancia de este objeto utilizando CoCreateInstanceAsAdmin , se producen problemas; aquí está el código:


HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
 // Manual implementation of CreateInstanceAsAdmin
 CComPtr BindCtx;
 HRESULT hr = CreateBindCtx(0,&BindCtx);
 BIND_OPTS3 bo;
 memset(&bo, 0, sizeof(bo));
 bo.cbStruct = sizeof(bo);
 bo.grfMode = STGM_READWRITE;
 bo.hwnd = hwnd;
 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 Moniker;
  WCHAR wszCLSID[50];
  WCHAR wszMonikerName[300];
  StringFromGUID2(rclsid,wszCLSID,sizeof(wszCLSID) / sizeof(wszCLSID[0]));
  //Elevation:Administrator!new
  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;
}

Llamar a CoCreateInstanceAsAdmin falla con "Clase no registrada".

El objeto se ha registrado mediante la creación de las siguientes claves del registro (aquí está el cuerpo del archivo REG)


[HKEY_CLASSES_ROOT\COMsurrogate]
@="COMsurrogate Class"

[HKEY_CLASSES_ROOT\COMsurrogate\CurVer]
@="COMsurrogate.1"

[HKEY_CLASSES_ROOT\COMsurrogate\CLSID]
@="{686B6F70-06AE-4dfd-8C26-4564684D9F9F}"

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}]
@="COMsurrogate Class"
"LocalizedString"="@C:\\Windows\\system32\\COMsurrogate.dll,-101"
"DllSurrogate"=""

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\ProgID]
@="COMsurrogate.1"

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\VersionIndependentProgID]
@="COMsurrogate"

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\InprocServer32]
@="@C:\\windows\system32\COMsurrogate.dll"
"ThreadingModel"="Apartment"

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\NotInsertable]

[HKEY_CLASSES_ROOT\CLSID\{686B6F70-06AE-4dfd-8C26-4564684D9F9F}\Programmable]

supongo que algunas entradas de registro faltan - esa es la conclusión a la que llegue al leer el mensaje de error. Sin embargo, esta lista de claves de registro fue compilado después de explorar la documentación en MSDN y otros sitios -., Así que estoy bastante seguro de que nada le haya faltado

Entre las cosas que he tratado de resolver esto es para ponerlo en práctica a través de ATL (por ejemplo, que el registro es automático). Que funciona, pero el problema es que no puedo pasar un puntero a funtion el prototipo de función de MIDL generado.

Traté de pasarlo con el VARIANTE tipo:


 v.vt = VT_PTR;
 void (*myptr)(void);
 myptr = &DoTheStuff;
 v.byref = myptr;
 hr = theElevated->CoTaskExecuter(0, v);

como resultado consigo "tipo de argumento no válido".

Podría alguien arrojar alguna luz sobre el tema? Quizás lo que estoy tratando de lograr no es posible por el diseño?

No hay solución correcta

Otros consejos

Creo que los problemas que tengas es por diseño y que la intención de las mejoras de seguridad de la ventana eran a los riesgos potenciales de seguridad ayuda a evitar.

Microsoft realmente no quiere que elevar los privilegios si se puede dejar de hacerlo. La ejecución de funciones arbitrarias como usuario privilegiado no debe ser fácil de ninguna manera si Windows es incluso un sistema decente asegurado. Es posible que podría intentar hacerse pasar por otro usuario el uso de tokens y conseguir un mejor acceso de esa manera, pero incluso en ese caso sería una exageración. Si no recuerdo mal, imitaciones de usuario ni siquiera garantizar que obtendrá acceso completo. La mejor solución en este caso es sólo para usar la cuenta de superusuario y solicitar adecuadamente los privilegios correctos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top