EventRegister
関数シグネチャ
// ADVAPI32.dll
#include <windows.h>
DWORD EventRegister(
const GUID* ProviderId,
PENABLECALLBACK EnableCallback, // optional
void* CallbackContext, // optional
REGHANDLE* RegHandle
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| ProviderId | GUID* | in | プロバイダーを一意に識別する GUID で、コントロール GUID と呼ばれることもあります。 これは安定した識別子である必要があります。トレースコントローラーがこの GUID を使用して、 このプロバイダーからのイベントをサブスクライブできるようにするためです。 |
| EnableCallback | PENABLECALLBACK | inoptional | 省略可能な
EnableCallback で、
トレースセッションがこのプロバイダーを有効化または無効化したときに ETW が呼び出します。コールバックが
不要な場合は NULL を使用してください。 |
| CallbackContext | void* | inoptional | 省略可能なコンテキストデータで、ETW が EnableCallback を呼び出す際に渡します。コールバックコンテキストが
不要な場合は NULL を使用してください。 |
| RegHandle | REGHANDLE* | out | イベントプロバイダーの登録ハンドルを受け取ります。このハンドルは、 EventWrite、EventProviderEnabled、EventRegister などのプロバイダー API への 以降の呼び出しで使用します。 プロバイダーがアンロードまたは終了する前に、 EventUnregister を呼び出して プロバイダー登録ハンドルを解放してください。登録したすべてのプロバイダーハンドルを解放せずに アンロードする DLL は、プロセスをクラッシュさせる可能性があります。 |
戻り値の型: DWORD
公式ドキュメント
ETW イベントプロバイダーを登録し、イベントの書き込みに使用できるハンドルを作成します。
戻り値
成功した場合は ERROR_SUCCESS を返します。
EventRegister が返すエラーコードは、主にデバッグおよび診断のシナリオでの使用を 想定しています。ほとんどの本番コードは、ETW プロバイダーの登録に失敗しても実行を継続すべきであるため、 リリースビルドでは通常 EventRegister が返すエラーコードを無視すべきです。
解説(Remarks)
EventRegister は、 EventWrite、 EventWriteTransfer、 または EventWriteEx を介して ETW イベントを書き込むために使用できるハンドルを作成します。
ほとんどのイベントプロバイダーは EventRegister を直接呼び出しません。 代わりに、ほとんどのイベントプロバイダーは、EventRegister、EventWrite、 EventUnregister の呼び出しをラップする ETW フレームワークを使用して実装されます。 たとえば、 イベントマニフェストを記述 し、 Message Compiler を使用して イベント用の C/C++ コードを生成する方法や、 TraceLogging を使用して マニフェストを不要にする方法があります。
イベントプロバイダーの登録は、イベントプロバイダーのマニフェストのインストールと 混同しないでください。
- EventRegister API は、プロバイダーハンドルを作成するためにイベントプロバイダーの登録を 実行します。これはプロセススコープの操作です(ハンドルはプロセス内でのみ有効です)。このハンドルは ETW イベントの書き込みに使用できます。このハンドルを使用して書き込まれたすべてのイベントには、 プロバイダー登録時に指定された ProviderId がタグ付けされます。イベントを書き込んだり トレースをキャプチャしたりするためにマニフェストをインストールする必要はありません(ただし、 プロバイダーのイベントをデコードするため、またはプロバイダーが Event Log と連携するためには、 マニフェストのインストールが必要な場合があります)。
- wevtutil.exe ツールは、イベントプロバイダーのマニフェストのインストールまたはアンインストールに使用します。 イベントプロバイダーマニフェストのインストールとは、マニフェストの情報がシステムに記録される ことを意味します。記録された情報はシステム全体で有効であり、マニフェストがアンインストールされる まで保持されます。記録される情報には、マニフェストで定義されたプロバイダーの名前、GUID、 チャネル、リソース DLL のパスが含まれます。マニフェストの情報は、トレースデコードツールおよび Event Log によって使用されます。
ほとんどのコンポーネントは、コンポーネントの初期化時にイベントプロバイダーを登録し、
コンポーネントのシャットダウン時にイベントプロバイダーの登録を解除します。たとえば、
アプリケーション(EXE)はアプリケーションの起動時に登録し、アプリケーションの終了時に
登録を解除する場合があります。ダイナミックライブラリ(DLL)は、プロセスアタッチ時に
DllMain 内で登録し、プロセスデタッチ時に DllMain 内で登録を解除する場合があります。
イベントトレースはデバッグ/診断に関わるものであり、通常はアプリケーションにとって 重要な機能ではないため、ほとんどの製品アプリケーションは EventRegister が返す失敗を 暗黙的に無視すべきです。失敗した場合、EventRegister は RegHandle パラメーターをゼロに 設定するため、以降の RegHandle の使用(つまり EventWrite および EventUnregister の 呼び出し)は効果を持ちません。
Windows Vista より前: プロセスが登録できるプロバイダーの数に特定の制限はありませんでした。 Windows 7 以降では、各プロセスは最大 1,024 個のプロバイダーを登録できます。Windows 8 以降では、各プロセスは最大 2048 個のプロバイダーを登録できます。ただし、コンポーネントが登録する プロバイダーの数は 1 つか 2 つに制限すべきです。この制限には、この関数を使用して登録されたプロバイダーと、 RegisterTraceGuids を使用して登録された プロバイダーが含まれます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// ADVAPI32.dll
#include <windows.h>
DWORD EventRegister(
const GUID* ProviderId,
PENABLECALLBACK EnableCallback, // optional
void* CallbackContext, // optional
REGHANDLE* RegHandle
);[DllImport("ADVAPI32.dll", ExactSpelling = true)]
static extern uint EventRegister(
ref Guid ProviderId, // GUID*
IntPtr EnableCallback, // PENABLECALLBACK optional
IntPtr CallbackContext, // void* optional
out long RegHandle // REGHANDLE* out
);<DllImport("ADVAPI32.dll", ExactSpelling:=True)>
Public Shared Function EventRegister(
ByRef ProviderId As Guid, ' GUID*
EnableCallback As IntPtr, ' PENABLECALLBACK optional
CallbackContext As IntPtr, ' void* optional
<Out> ByRef RegHandle As Long ' REGHANDLE* out
) As UInteger
End Function' ProviderId : GUID*
' EnableCallback : PENABLECALLBACK optional
' CallbackContext : void* optional
' RegHandle : REGHANDLE* out
Declare PtrSafe Function EventRegister Lib "advapi32" ( _
ByVal ProviderId As LongPtr, _
ByVal EnableCallback As LongPtr, _
ByVal CallbackContext As LongPtr, _
ByRef RegHandle As LongLong) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
EventRegister = ctypes.windll.advapi32.EventRegister
EventRegister.restype = wintypes.DWORD
EventRegister.argtypes = [
ctypes.c_void_p, # ProviderId : GUID*
ctypes.c_void_p, # EnableCallback : PENABLECALLBACK optional
ctypes.POINTER(None), # CallbackContext : void* optional
ctypes.c_void_p, # RegHandle : REGHANDLE* out
]require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('ADVAPI32.dll')
EventRegister = Fiddle::Function.new(
lib['EventRegister'],
[
Fiddle::TYPE_VOIDP, # ProviderId : GUID*
Fiddle::TYPE_VOIDP, # EnableCallback : PENABLECALLBACK optional
Fiddle::TYPE_VOIDP, # CallbackContext : void* optional
Fiddle::TYPE_VOIDP, # RegHandle : REGHANDLE* out
],
-Fiddle::TYPE_INT)#[link(name = "advapi32")]
extern "system" {
fn EventRegister(
ProviderId: *const GUID, // GUID*
EnableCallback: *const core::ffi::c_void, // PENABLECALLBACK optional
CallbackContext: *mut (), // void* optional
RegHandle: *mut i64 // REGHANDLE* out
) -> u32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("ADVAPI32.dll")]
public static extern uint EventRegister(ref Guid ProviderId, IntPtr EnableCallback, IntPtr CallbackContext, out long RegHandle);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ADVAPI32_EventRegister' -Namespace Win32 -PassThru
# $api::EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle)#uselib "ADVAPI32.dll"
#func global EventRegister "EventRegister" sptr, sptr, sptr, sptr
; EventRegister varptr(ProviderId), EnableCallback, CallbackContext, varptr(RegHandle) ; 戻り値は stat
; ProviderId : GUID* -> "sptr"
; EnableCallback : PENABLECALLBACK optional -> "sptr"
; CallbackContext : void* optional -> "sptr"
; RegHandle : REGHANDLE* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "ADVAPI32.dll" #cfunc global EventRegister "EventRegister" var, sptr, sptr, var ; res = EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle) ; ProviderId : GUID* -> "var" ; EnableCallback : PENABLECALLBACK optional -> "sptr" ; CallbackContext : void* optional -> "sptr" ; RegHandle : REGHANDLE* out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "ADVAPI32.dll" #cfunc global EventRegister "EventRegister" sptr, sptr, sptr, sptr ; res = EventRegister(varptr(ProviderId), EnableCallback, CallbackContext, varptr(RegHandle)) ; ProviderId : GUID* -> "sptr" ; EnableCallback : PENABLECALLBACK optional -> "sptr" ; CallbackContext : void* optional -> "sptr" ; RegHandle : REGHANDLE* out -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; DWORD EventRegister(GUID* ProviderId, PENABLECALLBACK EnableCallback, void* CallbackContext, REGHANDLE* RegHandle) #uselib "ADVAPI32.dll" #cfunc global EventRegister "EventRegister" var, intptr, intptr, var ; res = EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle) ; ProviderId : GUID* -> "var" ; EnableCallback : PENABLECALLBACK optional -> "intptr" ; CallbackContext : void* optional -> "intptr" ; RegHandle : REGHANDLE* out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; DWORD EventRegister(GUID* ProviderId, PENABLECALLBACK EnableCallback, void* CallbackContext, REGHANDLE* RegHandle) #uselib "ADVAPI32.dll" #cfunc global EventRegister "EventRegister" intptr, intptr, intptr, intptr ; res = EventRegister(varptr(ProviderId), EnableCallback, CallbackContext, varptr(RegHandle)) ; ProviderId : GUID* -> "intptr" ; EnableCallback : PENABLECALLBACK optional -> "intptr" ; CallbackContext : void* optional -> "intptr" ; RegHandle : REGHANDLE* out -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
procEventRegister = advapi32.NewProc("EventRegister")
)
// ProviderId (GUID*), EnableCallback (PENABLECALLBACK optional), CallbackContext (void* optional), RegHandle (REGHANDLE* out)
r1, _, err := procEventRegister.Call(
uintptr(ProviderId),
uintptr(EnableCallback),
uintptr(CallbackContext),
uintptr(RegHandle),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // DWORDfunction EventRegister(
ProviderId: PGUID; // GUID*
EnableCallback: Pointer; // PENABLECALLBACK optional
CallbackContext: Pointer; // void* optional
RegHandle: Pointer // REGHANDLE* out
): DWORD; stdcall;
external 'ADVAPI32.dll' name 'EventRegister';result := DllCall("ADVAPI32\EventRegister"
, "Ptr", ProviderId ; GUID*
, "Ptr", EnableCallback ; PENABLECALLBACK optional
, "Ptr", CallbackContext ; void* optional
, "Ptr", RegHandle ; REGHANDLE* out
, "UInt") ; return: DWORD●EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle) = DLL("ADVAPI32.dll", "dword EventRegister(void*, void*, void*, void*)")
# 呼び出し: EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle)
# ProviderId : GUID* -> "void*"
# EnableCallback : PENABLECALLBACK optional -> "void*"
# CallbackContext : void* optional -> "void*"
# RegHandle : REGHANDLE* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "advapi32" fn EventRegister(
ProviderId: [*c]GUID, // GUID*
EnableCallback: ?*anyopaque, // PENABLECALLBACK optional
CallbackContext: ?*anyopaque, // void* optional
RegHandle: [*c]i64 // REGHANDLE* out
) callconv(std.os.windows.WINAPI) u32;proc EventRegister(
ProviderId: ptr GUID, # GUID*
EnableCallback: pointer, # PENABLECALLBACK optional
CallbackContext: pointer, # void* optional
RegHandle: ptr int64 # REGHANDLE* out
): uint32 {.importc: "EventRegister", stdcall, dynlib: "ADVAPI32.dll".}pragma(lib, "advapi32");
extern(Windows)
uint EventRegister(
GUID* ProviderId, // GUID*
void* EnableCallback, // PENABLECALLBACK optional
void* CallbackContext, // void* optional
long* RegHandle // REGHANDLE* out
);ccall((:EventRegister, "ADVAPI32.dll"), stdcall, UInt32,
(Ptr{GUID}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Int64}),
ProviderId, EnableCallback, CallbackContext, RegHandle)
# ProviderId : GUID* -> Ptr{GUID}
# EnableCallback : PENABLECALLBACK optional -> Ptr{Cvoid}
# CallbackContext : void* optional -> Ptr{Cvoid}
# RegHandle : REGHANDLE* out -> Ptr{Int64}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
uint32_t EventRegister(
void* ProviderId,
void* EnableCallback,
void* CallbackContext,
int64_t* RegHandle);
]]
local advapi32 = ffi.load("advapi32")
-- advapi32.EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle)
-- ProviderId : GUID*
-- EnableCallback : PENABLECALLBACK optional
-- CallbackContext : void* optional
-- RegHandle : REGHANDLE* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('ADVAPI32.dll');
const EventRegister = lib.func('__stdcall', 'EventRegister', 'uint32_t', ['void *', 'void *', 'void *', 'int64_t *']);
// EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle)
// ProviderId : GUID* -> 'void *'
// EnableCallback : PENABLECALLBACK optional -> 'void *'
// CallbackContext : void* optional -> 'void *'
// RegHandle : REGHANDLE* out -> 'int64_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
// コールバック(関数ポインタ)は koffi.proto/koffi.register で型を定義して渡す(素の void* では JS 関数を渡せない)。const lib = Deno.dlopen("ADVAPI32.dll", {
EventRegister: { parameters: ["pointer", "pointer", "pointer", "pointer"], result: "u32" },
});
// lib.symbols.EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle)
// ProviderId : GUID* -> "pointer"
// EnableCallback : PENABLECALLBACK optional -> "pointer"
// CallbackContext : void* optional -> "pointer"
// RegHandle : REGHANDLE* out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
uint32_t EventRegister(
void* ProviderId,
void* EnableCallback,
void* CallbackContext,
int64_t* RegHandle);
C, "ADVAPI32.dll");
// $ffi->EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle);
// ProviderId : GUID*
// EnableCallback : PENABLECALLBACK optional
// CallbackContext : void* optional
// RegHandle : REGHANDLE* out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public interface Advapi32 extends StdCallLibrary {
Advapi32 INSTANCE = Native.load("advapi32", Advapi32.class);
int EventRegister(
Pointer ProviderId, // GUID*
Callback EnableCallback, // PENABLECALLBACK optional
Pointer CallbackContext, // void* optional
LongByReference RegHandle // REGHANDLE* out
);
}@[Link("advapi32")]
lib LibADVAPI32
fun EventRegister = EventRegister(
ProviderId : GUID*, # GUID*
EnableCallback : Void*, # PENABLECALLBACK optional
CallbackContext : Void*, # void* optional
RegHandle : Int64* # REGHANDLE* out
) : UInt32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef EventRegisterNative = Uint32 Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Int64>);
typedef EventRegisterDart = int Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Int64>);
final EventRegister = DynamicLibrary.open('ADVAPI32.dll')
.lookupFunction<EventRegisterNative, EventRegisterDart>('EventRegister');
// ProviderId : GUID* -> Pointer<Void>
// EnableCallback : PENABLECALLBACK optional -> Pointer<Void>
// CallbackContext : void* optional -> Pointer<Void>
// RegHandle : REGHANDLE* out -> Pointer<Int64>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function EventRegister(
ProviderId: PGUID; // GUID*
EnableCallback: Pointer; // PENABLECALLBACK optional
CallbackContext: Pointer; // void* optional
RegHandle: Pointer // REGHANDLE* out
): DWORD; stdcall;
external 'ADVAPI32.dll' name 'EventRegister';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "EventRegister"
c_EventRegister :: Ptr () -> Ptr () -> Ptr () -> Ptr Int64 -> IO Word32
-- ProviderId : GUID* -> Ptr ()
-- EnableCallback : PENABLECALLBACK optional -> Ptr ()
-- CallbackContext : void* optional -> Ptr ()
-- RegHandle : REGHANDLE* out -> Ptr Int64
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let eventregister =
foreign "EventRegister"
((ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr int64_t) @-> returning uint32_t)
(* ProviderId : GUID* -> (ptr void) *)
(* EnableCallback : PENABLECALLBACK optional -> (ptr void) *)
(* CallbackContext : void* optional -> (ptr void) *)
(* RegHandle : REGHANDLE* out -> (ptr int64_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library advapi32 (t "ADVAPI32.dll"))
(cffi:use-foreign-library advapi32)
(cffi:defcfun ("EventRegister" event-register :convention :stdcall) :uint32
(provider-id :pointer) ; GUID*
(enable-callback :pointer) ; PENABLECALLBACK optional
(callback-context :pointer) ; void* optional
(reg-handle :pointer)) ; REGHANDLE* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $EventRegister = Win32::API::More->new('ADVAPI32',
'DWORD EventRegister(LPVOID ProviderId, LPVOID EnableCallback, LPVOID CallbackContext, LPVOID RegHandle)');
# my $ret = $EventRegister->Call($ProviderId, $EnableCallback, $CallbackContext, $RegHandle);
# ProviderId : GUID* -> LPVOID
# EnableCallback : PENABLECALLBACK optional -> LPVOID
# CallbackContext : void* optional -> LPVOID
# RegHandle : REGHANDLE* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。