2010-11-29 60 views
0

La méthode IUrlHistoryStg2 :: ClearHistory() est documentée en tant que par utilisateur.IUrlHistoryStg2 :: ClearHistory() ne fonctionne pas à partir d'un service?

http://msdn.microsoft.com/en-us/library/aa767715(VS.85).aspx

lors de l'appel d'un service en cours d'exécution sous le compte SYSTEM, je suis incapable de cibler les utilisateurs connectés particuliers. J'ai réussi à emprunter l'identité des utilisateurs via WindowsIdentity.Impersonate() mais l'appel à ClearHistory() renvoie toujours 0 pour le succès mais n'efface pas l'historique de l'utilisateur.

Ceci s'applique à la fois à XP et à Win7 et semble donc ne pas être un problème d'isolation de session.

Peut-être parce que c'est COM, quelque chose regarde le jeton Processus de l'appelant plutôt que son jeton Thread lors de l'emprunt d'identité?

Je suis confus pourquoi l'usurpation d'identité de l'utilisateur ne mène pas simplement au succès de cette méthode?

using System; 
using System.Runtime.InteropServices; 

/** 
* wrapper for IUrlHistory 
*/ 
public struct STATURL 
{ 
    public static uint SIZEOF_STATURL = (uint)Marshal.SizeOf(typeof(STATURL)); 
    public uint cbSize; 
    [MarshalAs(UnmanagedType.LPWStr)] public string pwcsUrl; 
    [MarshalAs(UnmanagedType.LPWStr)] public string pwcsTitle; 
    public System.Runtime.InteropServices.ComTypes.FILETIME 
       ftLastVisited, 
       ftLastUpdated, 
       ftExpires; 
    public uint dwFlags; 
} 

[ComImport, Guid("3C374A42-BAE4-11CF-BF7D-00AA006946EE"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IEnumSTATURL 
{ 
    [PreserveSig] 
    uint Next(uint celt, out STATURL rgelt, out uint pceltFetched); 
    void Skip(uint celt); 
    void Reset(); 
    void Clone(out IEnumSTATURL ppenum); 
    void SetFilter(
     [MarshalAs(UnmanagedType.LPWStr)] string poszFilter, 
     uint dwFlags); 
} 

[ComImport, Guid("AFA0DC11-C313-11d0-831A-00C04FD5AE38"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IUrlHistoryStg2 
{ 
    #region IUrlHistoryStg methods 
    void AddUrl(
     [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl, 
     [MarshalAs(UnmanagedType.LPWStr)] string pocsTitle, 
     uint dwFlags); 

    void DeleteUrl(
     [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl, 
     uint dwFlags); 

    void QueryUrl(
     [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl, 
     uint dwFlags, 
     ref STATURL lpSTATURL); 

    void BindToObject(
     [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl, 
     ref Guid riid, 
     [MarshalAs(UnmanagedType.IUnknown)] out object ppvOut); 

    IEnumSTATURL EnumUrls(); 

    #endregion 

    void AddUrlAndNotify(
     [MarshalAs(UnmanagedType.LPWStr)] string pocsUrl, 
     [MarshalAs(UnmanagedType.LPWStr)] string pocsTitle, 
     uint dwFlags, 
     [MarshalAs(UnmanagedType.Bool)] bool fWriteHistory, 
     [MarshalAs(UnmanagedType.IUnknown)] object /*IOleCommandTarget*/ 
     poctNotify, 
     [MarshalAs(UnmanagedType.IUnknown)] object punkISFolder); 

    void ClearHistory(); 
} 

[ComImport, Guid("3C374A40-BAE4-11CF-BF7D-00AA006946EE")] 
public class UrlHistory /* : IUrlHistoryStg[2] */ {} 


public class test 
{ 
    static void Main() 
    { 
     IUrlHistoryStg2 stg = (IUrlHistoryStg2) new UrlHistory(); 
     stg.ClearHistory(); 
    } 
} 

Répondre

2

Si un service ou une application emprunte l'identité d'un utilisateur, le système ne charge pas le profil de l'utilisateur. Essayez d'appeler le LoadUserProfile en premier.

1

IUrlHistoryStg2 utilise éventuellement les API Wininet tels que CommitUrlCacheEntryW

documentation Microsoft indique que:

Comme tous les autres aspects de l'API WinINet, cette fonction ne peut pas être en toute sécurité appelée depuis DllMain ou les constructeurs et destructeurs d'objets globaux. Remarque WinINet ne prend pas en charge les implémentations du serveur . En outre, il ne doit pas être utilisé à partir d'un service. Pour les implémentations de serveur ou les services, utilisez les services Microsoft Windows HTTP (WinHTTP).

I inversé les API et a trouvé plus ils ont vérifier

  • Impersonation
  • Exécution d'un service

Si l'une est vraie, l'API existe avec le code d'erreur 0x80070078 Donc, heureusement, ce que vous essayez d'atteindre n'est pas possible à partir d'un service et vous devez utiliser CreateProcessAsUser