EventActivityIdControl
関数シグネチャ
// ADVAPI32.dll
#include <windows.h>
DWORD EventActivityIdControl(
DWORD ControlCode,
GUID* ActivityId
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| ControlCode | DWORD | in | 実行する操作を指定する制御コードです。
|
| ActivityId | GUID* | inout | 128 ビットのアクティビティ ID を格納するバッファーへのポインターです。このバッファーは、ControlCode パラメーターの値に応じて、読み取りや書き込みが行われる場合があります。 |
戻り値の型: DWORD
公式ドキュメント
ETW イベントで使用するアクティビティ識別子を作成、照会、設定します。
戻り値
成功した場合は ERROR_SUCCESS を返します。
解説(Remarks)
EventWrite API のいずれかを使用して書き込まれた ETW イベントには、128 ビットの 「アクティビティ ID」フィールドが含まれ、オプションで 128 ビットの「関連アクティビティ ID」 フィールドを含めることができます。トレース処理ツールは、これらのフィールドの値を使用して、 イベントをアクティビティと呼ばれるグループに整理できます。
- アクティビティ ID がゼロ (すなわち GUID_NULL) であるすべてのイベントは、 いかなるアクティビティにも属さないものとみなされます。
- 特定の非ゼロのアクティビティ ID を持つすべてのイベントは、 同じアクティビティの一部であるとみなされます。
- アクティビティの開始を示すには、プロバイダーは特定の非ゼロのアクティビティ ID を持つ 最初のイベント (start イベント) の Opcode を WINEVENT_OPCODE_START に設定する必要があります。アクティビティが論理的に別のアクティビティの内側に入れ子になっている場合、 プロバイダーは start イベントの関連アクティビティ ID フィールドを親アクティビティの ID に設定する必要があります。
- アクティビティの終了を示すには、プロバイダーは特定の非ゼロのアクティビティ ID を持つ 最後のイベント (stop イベント) の Opcode を WINEVENT_OPCODE_STOP に設定する必要があります。
アクティビティ ID が有用であるためには、新しく生成されるアクティビティ ID が ローカルで一意である必要があります。すなわち、同じ ID がトレース内で 2 回生成されてはなりません。
アクティビティ ID は EventActivityIdControl を使用して作成できます。これは、 システムが再起動するまでローカルシステム上のすべてのプロセスにわたって一意であることが保証された、 ローカルで一意な ID を生成します。アクティビティ ID として GUID (グローバルで一意な識別子) を 使用することもできます。GUID は UuidCreate などの API を使用して作成できます。
ユーザーモードのスレッドは、スレッドローカルな 128 ビットのアクティビティ ID 値 (スレッドのアクティビティ ID) を持ちます。スレッドのアクティビティ ID は、スレッドが作成されるときに 0 (すなわち GUID_NULL) に初期化されます。スレッドのアクティビティ ID は EventActivityIdControl を使用して読み取りまたは更新できます。スレッドのアクティビティ ID は、 EventWrite によって書き込まれるすべてのイベント、および ActivityId パラメーターが NULL である EventWriteTransfer または EventWriteEx によって書き込まれる すべてのイベントのアクティビティ ID として使用されます。
スレッドのアクティビティ ID を変更する関数は、終了する前に元のアクティビティ ID を確実に復元するよう注意してください。そうしないと、その関数によるスレッドのアクティビティ ID への変更が、その関数を呼び出すコンポーネントのアクティビティに干渉してしまいます。
明示的に指定したアクティビティ ID の使用
アクティビティが単一のスレッドに限定されない場合、または他のコンポーネントがスレッドのアクティビティ ID を上書きすることによる干渉の可能性を回避したい場合は、自動的なスレッドのアクティビティ ID を使用する代わりに、 EventWriteTransfer または EventWriteEx の ActivityId フィールドを介して イベントアクティビティを明示的に指定することを検討してください。
イベントの書き込みに マニフェスト と
Message Compiler を使用する場合、
MC.exe -um によって生成されるマクロはスレッドのアクティビティ ID を使用し、
MC.exe -km によって生成されるマクロはアクティビティ ID パラメーターをサポートします。
当初、-um マクロはユーザーモードでのみ動作し、-km マクロはカーネルモードでのみ動作したため、
ユーザーモードのコードは現在のスレッドのアクティビティ ID しか使用できませんでした。しかし、
MC.exe バージョン 10.0.17741 以降では、MC.exe -km によって生成されるマクロは
ユーザーモードとカーネルモードの両方で使用できるため、MC.exe -km を使用して
アクティビティ ID パラメーターを受け取るマクロを生成できます。
(MC が生成するコードは、イベントの関連アクティビティ ID の設定をサポートしていません。)
イベントの書き込みに TraceLoggingProvider.h を使用する場合、TraceLoggingWrite マクロはスレッドのアクティビティ ID を使用し、 TraceLoggingWriteActivity はアクティビティ ID と関連アクティビティ ID のパラメーターを受け取ります。 あるいは、TraceLogging アクティビティのために TraceLoggingActivity.h の C++ クラスを 使用することもできます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// ADVAPI32.dll
#include <windows.h>
DWORD EventActivityIdControl(
DWORD ControlCode,
GUID* ActivityId
);[DllImport("ADVAPI32.dll", ExactSpelling = true)]
static extern uint EventActivityIdControl(
uint ControlCode, // DWORD
ref Guid ActivityId // GUID* in/out
);<DllImport("ADVAPI32.dll", ExactSpelling:=True)>
Public Shared Function EventActivityIdControl(
ControlCode As UInteger, ' DWORD
ByRef ActivityId As Guid ' GUID* in/out
) As UInteger
End Function' ControlCode : DWORD
' ActivityId : GUID* in/out
Declare PtrSafe Function EventActivityIdControl Lib "advapi32" ( _
ByVal ControlCode As Long, _
ByVal ActivityId As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
EventActivityIdControl = ctypes.windll.advapi32.EventActivityIdControl
EventActivityIdControl.restype = wintypes.DWORD
EventActivityIdControl.argtypes = [
wintypes.DWORD, # ControlCode : DWORD
ctypes.c_void_p, # ActivityId : GUID* in/out
]require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('ADVAPI32.dll')
EventActivityIdControl = Fiddle::Function.new(
lib['EventActivityIdControl'],
[
-Fiddle::TYPE_INT, # ControlCode : DWORD
Fiddle::TYPE_VOIDP, # ActivityId : GUID* in/out
],
-Fiddle::TYPE_INT)#[link(name = "advapi32")]
extern "system" {
fn EventActivityIdControl(
ControlCode: u32, // DWORD
ActivityId: *mut GUID // GUID* in/out
) -> u32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("ADVAPI32.dll")]
public static extern uint EventActivityIdControl(uint ControlCode, ref Guid ActivityId);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ADVAPI32_EventActivityIdControl' -Namespace Win32 -PassThru
# $api::EventActivityIdControl(ControlCode, ActivityId)#uselib "ADVAPI32.dll"
#func global EventActivityIdControl "EventActivityIdControl" sptr, sptr
; EventActivityIdControl ControlCode, varptr(ActivityId) ; 戻り値は stat
; ControlCode : DWORD -> "sptr"
; ActivityId : GUID* in/out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "ADVAPI32.dll" #cfunc global EventActivityIdControl "EventActivityIdControl" int, var ; res = EventActivityIdControl(ControlCode, ActivityId) ; ControlCode : DWORD -> "int" ; ActivityId : GUID* in/out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "ADVAPI32.dll" #cfunc global EventActivityIdControl "EventActivityIdControl" int, sptr ; res = EventActivityIdControl(ControlCode, varptr(ActivityId)) ; ControlCode : DWORD -> "int" ; ActivityId : GUID* in/out -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; DWORD EventActivityIdControl(DWORD ControlCode, GUID* ActivityId) #uselib "ADVAPI32.dll" #cfunc global EventActivityIdControl "EventActivityIdControl" int, var ; res = EventActivityIdControl(ControlCode, ActivityId) ; ControlCode : DWORD -> "int" ; ActivityId : GUID* in/out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; DWORD EventActivityIdControl(DWORD ControlCode, GUID* ActivityId) #uselib "ADVAPI32.dll" #cfunc global EventActivityIdControl "EventActivityIdControl" int, intptr ; res = EventActivityIdControl(ControlCode, varptr(ActivityId)) ; ControlCode : DWORD -> "int" ; ActivityId : GUID* in/out -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
procEventActivityIdControl = advapi32.NewProc("EventActivityIdControl")
)
// ControlCode (DWORD), ActivityId (GUID* in/out)
r1, _, err := procEventActivityIdControl.Call(
uintptr(ControlCode),
uintptr(ActivityId),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // DWORDfunction EventActivityIdControl(
ControlCode: DWORD; // DWORD
ActivityId: PGUID // GUID* in/out
): DWORD; stdcall;
external 'ADVAPI32.dll' name 'EventActivityIdControl';result := DllCall("ADVAPI32\EventActivityIdControl"
, "UInt", ControlCode ; DWORD
, "Ptr", ActivityId ; GUID* in/out
, "UInt") ; return: DWORD●EventActivityIdControl(ControlCode, ActivityId) = DLL("ADVAPI32.dll", "dword EventActivityIdControl(dword, void*)")
# 呼び出し: EventActivityIdControl(ControlCode, ActivityId)
# ControlCode : DWORD -> "dword"
# ActivityId : GUID* in/out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "advapi32" fn EventActivityIdControl(
ControlCode: u32, // DWORD
ActivityId: [*c]GUID // GUID* in/out
) callconv(std.os.windows.WINAPI) u32;proc EventActivityIdControl(
ControlCode: uint32, # DWORD
ActivityId: ptr GUID # GUID* in/out
): uint32 {.importc: "EventActivityIdControl", stdcall, dynlib: "ADVAPI32.dll".}pragma(lib, "advapi32");
extern(Windows)
uint EventActivityIdControl(
uint ControlCode, // DWORD
GUID* ActivityId // GUID* in/out
);ccall((:EventActivityIdControl, "ADVAPI32.dll"), stdcall, UInt32,
(UInt32, Ptr{GUID}),
ControlCode, ActivityId)
# ControlCode : DWORD -> UInt32
# ActivityId : GUID* in/out -> Ptr{GUID}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
uint32_t EventActivityIdControl(
uint32_t ControlCode,
void* ActivityId);
]]
local advapi32 = ffi.load("advapi32")
-- advapi32.EventActivityIdControl(ControlCode, ActivityId)
-- ControlCode : DWORD
-- ActivityId : GUID* in/out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('ADVAPI32.dll');
const EventActivityIdControl = lib.func('__stdcall', 'EventActivityIdControl', 'uint32_t', ['uint32_t', 'void *']);
// EventActivityIdControl(ControlCode, ActivityId)
// ControlCode : DWORD -> 'uint32_t'
// ActivityId : GUID* in/out -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("ADVAPI32.dll", {
EventActivityIdControl: { parameters: ["u32", "pointer"], result: "u32" },
});
// lib.symbols.EventActivityIdControl(ControlCode, ActivityId)
// ControlCode : DWORD -> "u32"
// ActivityId : GUID* in/out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
uint32_t EventActivityIdControl(
uint32_t ControlCode,
void* ActivityId);
C, "ADVAPI32.dll");
// $ffi->EventActivityIdControl(ControlCode, ActivityId);
// ControlCode : DWORD
// ActivityId : GUID* in/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 EventActivityIdControl(
int ControlCode, // DWORD
Pointer ActivityId // GUID* in/out
);
}@[Link("advapi32")]
lib LibADVAPI32
fun EventActivityIdControl = EventActivityIdControl(
ControlCode : UInt32, # DWORD
ActivityId : GUID* # GUID* in/out
) : UInt32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef EventActivityIdControlNative = Uint32 Function(Uint32, Pointer<Void>);
typedef EventActivityIdControlDart = int Function(int, Pointer<Void>);
final EventActivityIdControl = DynamicLibrary.open('ADVAPI32.dll')
.lookupFunction<EventActivityIdControlNative, EventActivityIdControlDart>('EventActivityIdControl');
// ControlCode : DWORD -> Uint32
// ActivityId : GUID* in/out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function EventActivityIdControl(
ControlCode: DWORD; // DWORD
ActivityId: PGUID // GUID* in/out
): DWORD; stdcall;
external 'ADVAPI32.dll' name 'EventActivityIdControl';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "EventActivityIdControl"
c_EventActivityIdControl :: Word32 -> Ptr () -> IO Word32
-- ControlCode : DWORD -> Word32
-- ActivityId : GUID* in/out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let eventactivityidcontrol =
foreign "EventActivityIdControl"
(uint32_t @-> (ptr void) @-> returning uint32_t)
(* ControlCode : DWORD -> uint32_t *)
(* ActivityId : GUID* in/out -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library advapi32 (t "ADVAPI32.dll"))
(cffi:use-foreign-library advapi32)
(cffi:defcfun ("EventActivityIdControl" event-activity-id-control :convention :stdcall) :uint32
(control-code :uint32) ; DWORD
(activity-id :pointer)) ; GUID* in/out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $EventActivityIdControl = Win32::API::More->new('ADVAPI32',
'DWORD EventActivityIdControl(DWORD ControlCode, LPVOID ActivityId)');
# my $ret = $EventActivityIdControl->Call($ControlCode, $ActivityId);
# ControlCode : DWORD -> DWORD
# ActivityId : GUID* in/out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。