从C#调用Advapi32.dll本机EventWrite函数?

佩蒂B

我正在尝试使用C#.Net来触发Window的服务触发事件

具体来说,我试图触发此事件,以便从非特权帐户启动WebClient服务。

C:\>sc qtriggerinfo WebClient
[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: WebClient

        START SERVICE
          CUSTOM                       : 22b6d684-fa63-4578-87c9-effcbe6643c7 [ETW PROVIDER UUID]

我能够在C ++中启动服务时找到此参考,但是不确定如何在C#中实现相同的功能:

bool StartWebClientService()
{
    const GUID _MS_Windows_WebClntLookupServiceTrigger_Provider =
        { 0x22B6D684, 0xFA63, 0x4578, 
        { 0x87, 0xC9, 0xEF, 0xFC, 0xBE, 0x66, 0x43, 0xC7 } };
    REGHANDLE Handle;
    bool success = false;

    if (EventRegister(&_MS_Windows_WebClntLookupServiceTrigger_Provider,
        nullptr, nullptr, &Handle) == ERROR_SUCCESS)
    {
        EVENT_DESCRIPTOR desc;

        EventDescCreate(&desc, 1, 0, 0, 4, 0, 0, 0);

        success = EventWrite(Handle, &desc, 0, nullptr) == ERROR_SUCCESS;

        EventUnregister(Handle);
    }

    return success;
}

这是我正在使用的代码:

[StructLayout(LayoutKind.Explicit, Size=12)]
public class EVENT_DESCRIPTOR
{
    [FieldOffset(0)]ushort Id = 1;
    [FieldOffset(2)]byte Version = 0;
    [FieldOffset(3)]byte Channel = 0;
    [FieldOffset(4)]byte Level = 4;
    [FieldOffset(5)]byte Opcode = 0;
    [FieldOffset(6)]ushort Task = 0;
    [FieldOffset(8)]ulong Keyword = 0;
}

//...

    void startService()
    {
        Guid webCleintTrigger = new Guid(0x22B6D684, 0xFA63, 0x4578, 0x87, 0xC9, 0xEF, 0xFC, 0xBE, 0x66, 0x43, 0xC7);

        IntPtr handle;
        uint output = EventRegister(ref webCleintTrigger, IntPtr.Zero, IntPtr.Zero, out handle);

        //This is what is returned:
        //output = 0 <- Good 
        //handle = 65537  <- Good handle?

        bool success = false;

        if (output == 0)
        {
            //Create event descriptor
            EVENT_DESCRIPTOR desc = new EVENT_DESCRIPTOR();

            //Write the event
            uint writeOutput = EventWrite(handle, ref desc, 0, IntPtr.Zero); //Throws PInvokeStackImbalance

            success = writeOutput == 0;

            EventUnregister(handle);
        }
    }

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern uint EventRegister(ref Guid guid, [Optional] IntPtr EnableCallback, [Optional] IntPtr CallbackContext, out IntPtr RegHandle);

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern uint EventWrite(IntPtr RegHandle, ref EVENT_DESCRIPTOR EventDescriptor, uint UserDataCount, [Optional] IntPtr UserData);

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern uint EventUnregister(IntPtr RegHandle);

的调用EventWrite引发PInvokeStackImbalance异常。这可能是我的EVENT_DESCRIPTOR结构有错误吗?

这是本机Event_Descriptor的结构

typedef struct _EVENT_DESCRIPTOR {
  USHORT    Id;
  UCHAR     Version;
  UCHAR     Channel;
  UCHAR     Level;
  UCHAR     Opcode;
  USHORT    Task;
  ULONGLONG Keyword;
} EVENT_DESCRIPTOR, *PEVENT_DESCRIPTOR;typedef const EVENT_DESCRIPTOR *PCEVENT_DESCRIPTOR;

这是我的C#结构:

[StructLayout(LayoutKind.Explicit, Size=16)]
public class EVENT_DESCRIPTOR
{
    [FieldOffset(0)]ushort Id = 1;
    [FieldOffset(2)]byte Version = 0;
    [FieldOffset(3)]byte Channel = 0;
    [FieldOffset(4)]byte Level = 4;
    [FieldOffset(5)]byte Opcode = 0;
    [FieldOffset(6)]ushort Task = 0;
    [FieldOffset(8)]ulong Keyword = 0;
}

这是本机EventWrite函数的结构

ULONG EventWrite(
  _In_      REGHANDLE RegHandle,
  _In_      PCEVENT_DESCRIPTOR EventDescriptor,
  _In_      ULONG UserDataCount,
  _In_opt_  PEVENT_DATA_DESCRIPTOR UserData
);

这是我对事件写入的PInvoke调用:

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern uint EventWrite(IntPtr RegHandle, ref EVENT_DESCRIPTOR EventDescriptor, uint UserDataCount, [Optional] IntPtr UserData);

这是我正在进行的调用,它引发PInvokeStackImbalance异常:

    EVENT_DESCRIPTOR desc = new EVENT_DESCRIPTOR();
    uint writeOutput = EventWrite(handle, ref desc, 0, IntPtr.Zero); //Throws PInvokeStackImbalance
佩蒂B

感谢BenVoigt向我指出他们已经实现了PInvoke调用Microsoft源参考

这是解决方案:

[StructLayout(LayoutKind.Explicit, Size=16)]
public class EVENT_DESCRIPTOR
{
    [FieldOffset(0)]ushort Id = 1;
    [FieldOffset(2)]byte Version = 0;
    [FieldOffset(3)]byte Channel = 0;
    [FieldOffset(4)]byte Level = 4;
    [FieldOffset(5)]byte Opcode = 0;
    [FieldOffset(6)]ushort Task = 0;
    [FieldOffset(8)]long Keyword = 0;
}

[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct EventData
{
    [FieldOffset(0)]
    internal UInt64 DataPointer;
    [FieldOffset(8)]
    internal uint Size;
    [FieldOffset(12)]
    internal int Reserved;
}

//...

    void startService()
    {
        Guid webCleintTrigger = new Guid(0x22B6D684, 0xFA63, 0x4578, 0x87, 0xC9, 0xEF, 0xFC, 0xBE, 0x66, 0x43, 0xC7);

        long handle = 0;
        uint output = EventRegister(ref webCleintTrigger, IntPtr.Zero, IntPtr.Zero, ref handle);

        //This is what is returned:
        //output = 0 <- Good 
        //handle = 65537  <- Good handle?

        bool success = false;

        if (output == 0)
        {
            //Create event descriptor
            EVENT_DESCRIPTOR desc = new EVENT_DESCRIPTOR();

            //Write the event
            unsafe
            {
                uint writeOutput = EventWrite(handle, ref desc, 0, null);
                success = writeOutput == 0;

                EventUnregister(handle);
            }

        }
    }

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern uint EventRegister(ref Guid guid, [Optional] IntPtr EnableCallback, [Optional] IntPtr CallbackContext, [In][Out] ref long RegHandle);

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern unsafe uint EventWrite(long RegHandle, ref EVENT_DESCRIPTOR EventDescriptor, uint UserDataCount, EventData* UserData);

    [DllImport("Advapi32.dll", SetLastError = true)]
    public static extern uint EventUnregister(long RegHandle);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从C#调用Advapi32.dll本机EventWrite函数?

来自分类Dev

如何将C函数签名转换为C#并在本机DLL中调用该函数?

来自分类Dev

如何将整数从C#方法复制到本机C DLL函数

来自分类Dev

如何将指针从C#传递到DLL中的本机函数?

来自分类Dev

如何从C#调用C ++ DLL函数

来自分类Dev

C#调用本机dll-结构封送处理

来自分类Dev

本机DLL-C#

来自分类Dev

从C#中的C ++ DLL P /调用DLL函数

来自分类Dev

为什么成功调用EventWrite函数后我的Windows日志为空

来自分类Dev

C#加载本机dll动态简单

来自分类Dev

从dll调用C函数后,C#代码中的ArithmeticException

来自分类Dev

调用更改C#中传递的参数的C dll函数

来自分类Dev

从C#调用C ++ DLL函数时崩溃

来自分类Dev

从托管代码调用本机函数

来自分类Dev

从本机代码调用 JavaScript 函数

来自分类Dev

Web服务调用32位dll函数

来自分类Dev

Web Service C#中DLL的调用函数动态

来自分类Dev

查找调用函数C#的代码的DLL名称

来自分类Dev

C# - 从动态库 dll 调用函数

来自分类Dev

区别:本机 DLL、UWP DLL 和 C++/CLI DLL

来自分类Dev

调用函数C#

来自分类Dev

C#导出函数dll

来自分类Dev

使用多个指针在C#中编组本机.dll

来自分类Dev

使用多个指针在C#中编组本机.dll

来自分类Dev

如何使用C#在单独运行的本机进程中调用函数?

来自分类Dev

从C#调用本机C ++的Stackoverflow

来自分类Dev

如何调用C DLL函数C ++ / CLI

来自分类Dev

从Python调用C DLL函数时出错

来自分类Dev

从C#Ironpython调用.dll函数