Einzelnen Beitrag anzeigen

Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#1

UAC-Elevation ClassFactory: An die COM-Kenner

  Alt 12. Okt 2007, 00:52
Ich implementiere gerade UAC Elevation und hab es auch eigentlich geschafft.
Jetzt gibt es aber noch die Möglichkeit laut http://msdn2.microsoft.com/en-us/library/ms679687.aspx
mit "Elevation:Administrator!clsid:{guid}" eine IClassFactory zu implementieren, mit der man dann Objekte elevated erstellen kann.

Dafür muss ich eine TypeLibrary erstellen, die ein Objekt enthält, welches von IClassFactory abgeleitet ist. Es sind aber nur ganz wenige Ableitung (IUnknown, IDispatch...)
vorhanden.

Deshalb habe ich mal probehalber die Methoden der IClassFactory einfach in eine eigenes Interface portiert - über den TBL-Editor und implementiert - komisch, geht aber net anders.
Die Typelibrary definiert das Interface IElevationDemoObject, welches ich dann ableite und implementiere (nur Testausgaben).

Der Test schlägt in CoGetClassFactoyAsAdmin::CoCreateInstanceAsEx::CoG etObject fehl mit OleSysError "Schnittstelle nicht unterstützt" und zwar nachdem der Elevationprompt kam.
Ich erstelle hier sozusagen die Classfactory und sag ihr einfach: Gib mir ein Pointer auf dich selbst.

Das ganze funktioniert übrigens, wenn in CoCreateInstanceAsEx CoCreateInstance ausgeführt wird.

Delphi-Quellcode:
var
  ElevatedObject2,
  ElevatedObject: IElevationDemoObject;

 CoGetClassFactoyAsAdmin(
    GetForegroundWindow,
    CLASS_ElevationDemoObject,
    IID_IElevationDemoObject,
    ElevatedObject); <<-- Fehler

  if ElevatedObject.CreateInstance(nil,IID_IElevationDemoObject,IUnknown(ElevatedObject2)) = S_OK then
    ElevatedObject2.DoTest;
....


procedure CoGetClassFactoyAsAdmin(
  const ParentWindowHandle: HWND;
  const ClassId: TGUID;
  const IID: TGUID;
  out ObjectInterface);
begin
  CoCreateInstanceAsEx(
    'Elevation:Administrator!clsid:', ParentWindowHandle, ClassId, IID, ObjectInterface);
end;

procedure CoCreateInstanceAsEx(
  const MonikerSequence : WideString;
  const ParentWindowHandle: HWND;
  const ClassId: TGUID;
  const IID: TGUID;
  out ObjectInterface);
var
  MonikerName : WideString;
  BindOptions : TBindOpts3;
  Token : TJwSecurityToken;
  iLen : Cardinal;
begin
  Token := TJwSecurityToken.CreateTokenEffective(TOKEN_QUERY or TOKEN_READ);

  try
    if Token.RunElevation = 0 then
    begin
      MonikerName := MonikerSequence + GUIDToString(ClassId);

      iLen := SizeOf(TBindOpts3);
      FillChar(BindOptions, iLen, 0);

      BindOptions.cbStruct := iLen;
      BindOptions.dwClassContext := CLSCTX_LOCAL_SERVER;
      BindOptions.hwnd := ParentWindowHandle;

      OleCheck(CoGetObject(PWideChar(MonikerName), @BindOptions, IID, ObjectInterface));
    end
    else
    begin
      OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_ALL, IID, ObjectInterface));
    end;
  finally
    Token.Free;
  end;
end;
Was könnte das sein?

THX

P.S.
Ich hoffe jemand kann etwas dazu erzählen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat