Win32 API 日本語リファレンス
ホームSystem.Diagnostics.Etw › EventActivityIdControl

EventActivityIdControl

関数
ETWのアクティビティIDの作成や取得などを制御する。
DLLADVAPI32.dll呼出規約winapi対応OSWindows Vista 以降

シグネチャ

// ADVAPI32.dll
#include <windows.h>

DWORD EventActivityIdControl(
    DWORD ControlCode,
    GUID* ActivityId
);

パラメーター

名前方向説明
ControlCodeDWORDin

実行する操作を指定する制御コードです。

  • EVENT_ACTIVITY_CTRL_GET_ID

    ActivityId パラメーターに、現在のスレッドのアクティビティ ID の値を設定します。

  • EVENT_ACTIVITY_CTRL_SET_ID

    現在のスレッドのアクティビティ ID に、ActivityId パラメーターの値を設定します。

  • EVENT_ACTIVITY_CTRL_CREATE_ID

    ActivityId パラメーターに、新しく生成された ローカルで一意なアクティビティ ID の値を設定します。

  • EVENT_ACTIVITY_CTRL_GET_SET_ID

    ActivityId パラメーターと現在のスレッドのアクティビティ ID の値を入れ替えます。(現在のスレッドのアクティビティ ID の値を保存し、次に 現在のスレッドのアクティビティ ID に ActivityId パラメーターの値を設定し、 その後 ActivityId パラメーターに保存した値を設定します。)

  • EVENT_ACTIVITY_CTRL_CREATE_SET_ID

    ActivityId パラメーターに現在のスレッドのアクティビティ ID の値を設定し、その後現在のスレッドのアクティビティ ID に 新しく生成されたローカルで一意なアクティビティ ID の値を設定します。

ActivityIdGUID*inout128 ビットのアクティビティ ID を格納するバッファーへのポインターです。このバッファーは、ControlCode パラメーターの値に応じて、読み取りや書き込みが行われる場合があります。

戻り値の型: DWORD

公式ドキュメント

ETW イベントで使用するアクティビティ識別子を作成、照会、設定します。

戻り値

成功した場合は ERROR_SUCCESS を返します。

解説(Remarks)

EventWrite API のいずれかを使用して書き込まれた ETW イベントには、128 ビットの 「アクティビティ ID」フィールドが含まれ、オプションで 128 ビットの「関連アクティビティ ID」 フィールドを含めることができます。トレース処理ツールは、これらのフィールドの値を使用して、 イベントをアクティビティと呼ばれるグループに整理できます。

アクティビティ 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 または EventWriteExActivityId フィールドを介して イベントアクティビティを明示的に指定することを検討してください。

イベントの書き込みに マニフェスト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 の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
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 方式にも切替可。
出力引数:
; 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 方式にも切替可。
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   // DWORD
function 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 を使用。