IUrlHistoryStg2::ClearHistory() 无法在服务中工作?

发布于 2024-10-05 00:13:02 字数 2891 浏览 1 评论 0原文

IUrlHistoryStg2::ClearHistory() 方法被记录为每用户。

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

当从 SYSTEM 帐户下运行的服务调用它时,我无法定位特定的登录用户。我已通过 WindowsIdentity.Impersonate() 成功模拟用户,但对 ClearHistory() 的调用始终返回 0 表示成功,但不会清除用户的历史记录。

这适用于 XP 和 Win7,因此似乎不是会话隔离问题。

也许因为它是COM,所以在模拟时会查看调用者的进程令牌而不是其线程令牌?

我很困惑为什么冒充用户并不能简单地导致这种方法的成功?

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

The IUrlHistoryStg2::ClearHistory() method is documented as Per-User.

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

When calling it from a service running under the SYSTEM account, I am unable to target particular logged-on users. I have successfully impersonated the users via WindowsIdentity.Impersonate() but the call to ClearHistory() always returns 0 for success but does not clear the history of the user.

This applies on both XP and Win7 so appears to be not a session isolation issue.

Perhaps because it is COM, something is looking at the Process token of the caller rather than its Thread token when impersonating?

I am confused why impersonating the user does not simply lead to success of this method?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

惯饮孤独 2024-10-12 00:13:02

如果服务或应用程序冒充用户,系统不会加载用户的配置文件。首先尝试调用 LoadUserProfile

If a service or an application impersonates a user, the system does not load the user's profile. Try call LoadUserProfile first.

梨涡少年 2024-10-12 00:13:02

IUrlHistoryStg2 最终使用 Wininet API,例如CommitUrlCacheEntryW

Microsoft 文档指出那:

与 WinINet API 的所有其他方面一样,此函数不能
从 DllMain 或构造函数和析构函数中安全地调用
全局对象。注意 WinINet 不支持服务器
实施。此外,不应从服务中使用它。
对于服务器实现或服务,请使用 Microsoft Windows HTTP
服务 (WinHTTP)。

我反转了这些 API,发现他们检查了从

  • 模拟
  • 服务运行的

如果其中任何一个为真,则该 API 存在,错误代码为 0x80070078

因此,幸运的是,您试图实现的目标不可能从服务中实现,您必须使用 CreateProcessAsUser

IUrlHistoryStg2 eventually uses the Wininet APIs such as CommitUrlCacheEntryW

Microsoft documentation states that:

Like all other aspects of the WinINet API, this function cannot be
safely called from within DllMain or the constructors and destructors
of global objects. Note WinINet does not support server
implementations. In addition, it should not be used from a service.
For server implementations or services use Microsoft Windows HTTP
Services (WinHTTP).

I reversed those API and found out the they have check for

  • Impersonation
  • Running from a service

If either is true, the API exists with error code 0x80070078

So, fortunately what you are trying to achieve is not possible from a service and you must use CreateProcessAsUser

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文