Вызовите функцию EventWrite Advapi32.dll из C #?

Я пытаюсь использовать C # .Net для запуска окна События запуска службы.

В частности, я пытаюсь вызвать это событие, чтобы служба 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;
}

Это структура родного ОтзывНовое функция:

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

Это мой PInvoke вызов Event Write:

    [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

1

Решение

Спасибо BenVoigt за указание мне на Ссылка на источник Microsoft где они уже реализовали вызовы PInvoke.

Это было решение:

[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);
1

Другие решения