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

EVENT_TRACE_PROPERTIES_V2

構造体
サイズx64: 152 バイト / x86: 136 バイト

サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。

フィールド

フィールドサイズx64x86説明
WnodeWNODE_HEADER48+0+0

WNODE_HEADER 構造体です。BufferSizeFlagsGuid の各メンバーを指定する必要があります。ClientContext メンバーは任意で指定できます。

重要

バージョン 2 のフィールド (FilterDescV2Options など) を認識させるには、Wnode.FlagsWNODE_FLAG_VERSIONED_PROPERTIES フラグを設定する必要があります。

BufferSizeDWORD4+48+48

イベント トレース セッションの各バッファーに割り当てられるメモリのキロバイト数です。最小のバッファー サイズは 4 (4KB) です。最大のバッファー サイズは 16384 (16MB) です。メモリとディスク領域の浪費を避けるため、ほとんどのトレース セッションでは 64KB 以下のバッファー サイズを使用してください。Windows 8 より前: 最大のバッファー サイズは 1024 (1MB) です。

バッファー サイズを小さくすると、セッションのメモリ使用量が減少します。バッファー サイズを大きくすると (最大 64KB)、より大きなイベントを収集できます。ETW はバッファー サイズより大きいイベントを収集できず、またバッファー サイズにかかわらず 64KB を超えるイベントは収集できません。データ スループットが極めて高いシナリオでは、バッファー サイズを大きくすることで CPU のオーバーヘッドを削減できます。

  • イベントが小さく、イベント レートが低い (数 KB/秒) セッションでは、小さなバッファー サイズ (4KB ~ 16KB) を使用してください。
  • イベントが小さく、イベント レートが中程度のセッションでは、中程度のバッファー サイズ (16KB ~ 32KB) を使用してください。
  • イベントが大きい、またはイベント レートが高い (数 MB/秒) セッションでは、大きなバッファー サイズ (64KB ~ 128KB) を使用してください。
  • 毎秒数百メガバイトのデータを扱う診断トレースのために大量のメモリを確保する必要があるまれなケースでは、非常に大きなバッファー サイズ (256KB ~ 1024KB) によって CPU のオーバーヘッドを削減できます。

特定のシナリオでは、ETW が要求された BufferSize をより大きな値に調整することがあります。たとえば、トレース ファイルをディスクに書き込む場合、ETW はバッファー サイズをディスクの物理ブロック サイズの倍数に増やすことがあります。

重要

BufferSize はトレース セッションで最も重要なパラメーターの 1 つです。大きなバッファーは通常、メモリとディスク領域を浪費します。大きなバッファー (256KB 以上) を使用するトレース セッションは、運用環境でのトレースではなく、診断調査やテストの場合にのみ使用してください。

ヒント

トレース セッションのメモリ使用量を制御するために BufferSize を使用しないでください。 代わりに、セッションのイベント サイズとイベント レートに基づいてバッファー サイズを選択し、MinimumBuffersMaximumBuffers の各パラメーターでセッションのメモリ使用量を調整してください。

MinimumBuffersDWORD4+52+52

トレース セッションのバッファー プールに予約されるバッファーの最小数です。

特定のシナリオでは、ETW がこの値を調整することがあります。

  • ログ モードに EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING フラグが含まれる場合、ETW は少なくとも 2 個のバッファーを予約します。
  • ログ モードに EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING フラグが含まれない場合、ETW は論理プロセッサごとに少なくとも 2 個のバッファーを予約します。
  • この値が ETW の定める上限より大きい場合、ETW は過剰なメモリ使用を避けるため、値を上限まで引き下げることがあります。

イベント レートが中程度のファイル モードおよびリアルタイム トレースでは、ほとんどのユーザーは MinimumBuffers を 0 または小さな最小値 (4 や 8 など) に設定してメモリ使用量を最小限に抑え、プロセッサ数に基づいて ETW が値を上方に調整できるようにしてください。ETW はトレースの開始時に (調整後の) 最小数のバッファーを予約します。バッファーが処理できる速度よりも速く満たされる場合、ETW は MaximumBuffers で指定された数まで追加のバッファーを割り当てます。

バッファリング モード (メモリ内の循環) のトレースでは、ETW にセッション用として予約させたいメモリの総量に応じて MinimumBuffers パラメーターを設定してください。これは通常、想定されるイベント レートと、トレースで対象としたい時間の長さに基づいて計算します。たとえば、毎秒 16KB のデータ レートが想定され、少なくとも 60 秒分のデータをトレースに記録したい場合は、960KB が必要になります。バッファー サイズが 32KB であるとすると、MinimumBuffers には 30 を設定します (合計 960KB ÷ バッファーあたり 32KB = 30 個のバッファー)。ETW はトレースの開始時に (調整後の) 最小数のバッファーを予約します。すべてのバッファーが満杯になると、ETW は最も古い満杯のバッファーを新しいイベント用に再利用します。ETW が追加のバッファーを割り当てることはない点に注意してください (バッファリング モードのトレースでは、ETW は MaximumBuffers を無視します)。

MaximumBuffersDWORD4+56+56

トレース セッションのバッファー プールに割り当てられるバッファーの最大数です。

特定のシナリオでは、ETW がこの値を調整することがあります。

  • この値が調整後の MinimumBuffers の値より小さい場合、ETW は MinimumBuffers 以上の適切な値まで引き上げることがあります。
  • この値が ETW の定める上限より大きい場合、ETW は値を上限まで引き下げることがあります。

ほとんどのユーザーは、まず MinimumBuffersMaximumBuffers を同じ値に設定してセッションのチューニングを開始してください。イベント レートのピーク時にトレースがイベントを取りこぼす場合は、MaximumBuffers の値を大きくするとよいでしょう。

メモ

バッファリング モードのセッション (ログ モードに EVENT_TRACE_BUFFERING_MODE を含むセッション) では、ETW はこのフィールドを無視します。バッファリング モードのセッションは、トレース収集の開始時に常に MinimumBuffers 個のバッファーを割り当て、追加のバッファーを割り当てることはありません。

MaximumFileSizeDWORD4+60+60

イベントの記録に使用されるファイルの最大サイズ (メガバイト単位) です。サイズ制限を設けない場合は 0 を指定します。通常、このメンバーは LogFileModeEVENT_TRACE_FILE_MODE_CIRCULAR を設定したときに、循環ログ ファイルのサイズを制限するために使用します。LogFileModeEVENT_TRACE_FILE_MODE_PREALLOCATEEVENT_TRACE_FILE_MODE_CIRCULAR、または EVENT_TRACE_FILE_MODE_NEWFILE が含まれる場合、このメンバーには 0 以外の値を設定しなければなりません。

ログ記録にシステム ドライブ (オペレーティング システムが格納されているドライブ) を使用している場合、最大ファイル サイズ パラメーターを使用しているかどうかにかかわらず、ETW は追加で 200MB のディスク空き容量を確認します。したがって、システム ドライブ上のトレース ファイルの最大サイズとして 100MB を指定する場合は、そのドライブに 300MB の空き容量が必要です。

LogFileModeDWORD4+64+64

イベント トレース セッションのログ フラグです。このメンバーを使用して、イベントをメモリ内の循環バッファー、ログ ファイル、リアルタイム コンシューマーのいずれに書き込むかを指定します。また、このメンバーを使用して、セッションがプライベート ロガー セッションであるなど、その他のセッションの特性を指定することもできます。指定可能なフラグの一覧については、 Logging Mode Constants を参照してください。

リアルタイム コンシューマーがイベントを消費する準備ができていない限り、リアルタイム ログを指定しないでください。リアルタイム コンシューマーが存在しない場合、ETW はリアルタイム セッションのイベントをバッファーに保持します。コンシューマーのないリアルタイム セッションはシステム リソースを浪費します。このバッファリングには制限がある点に注意してください。制限に達すると、新しいイベントは無視され、ログ記録関数は STATUS_LOG_FILE_FULL で失敗します。Windows Vista より前: リアルタイム コンシューマーが存在しない場合、イベントは破棄され、ログ記録は継続されます。

コンシューマーがリアルタイム イベントの処理を開始すると、まず再生ファイル内のイベントが消費されます。再生ファイル内のすべてのイベントが消費された後、セッションは新しいイベントの報告を開始します。

FlushTimerDWORD4+68+68

空でないトレース バッファーをフラッシュする間隔 (秒単位) です。

  • ファイル モードのセッションでは、最小のフラッシュ時間は 1 秒です。FlushTimer を 0 に設定すると、時間に基づくフラッシュは無効になります (バッファーが満杯になったとき、セッションが停止したとき、またはセッションが明示的にフラッシュされたときにフラッシュが行われます)。トレース ファイル内の無駄な領域を避けるため、ほとんどのファイル モードのトレースでは FlushTimer を 0 に設定してください。トレースが閉じられない可能性がある場合 (たとえば、システムがクラッシュしてもイベントを確実に取得したい場合) は、タイマーに 0 以外の値を設定するとよいでしょう。
  • リアルタイム セッションでは、最小のフラッシュ時間は 1 秒です。FlushTimer に 0 を設定した場合、既定のタイムアウトとして 1 秒が使用されます。リアルタイム セッションでは、データをどれだけ早く受け取る必要があるかに基づいてフラッシュ タイマーを設定してください。タイマーの値を大きくすると、トレースの CPU オーバーヘッドが減少する点に注意してください。ほとんどのリアルタイム トレースでは、まず 5 秒または 10 秒のタイマーから始め、必要に応じて調整してください。
  • バッファリング モード (メモリ内の循環) のセッションでは、FlushTimer は使用されません。トレース データはオンデマンドでのみフラッシュされます (つまり、 ControlTrace によってファイルにフラッシュされます)。
EnableFlagsEVENT_TRACE_FLAG4+72+72

システム ロガー セッションでは、EnableFlags を設定して、SystemTraceProvider のどのイベントをトレースに含めるかを指定できます。

メモ

EnableFlags が有効なのはシステム ロガー、つまり EVENT_TRACE_SYSTEM_LOGGER_MODE ロガー モード フラグ、 KERNEL_LOGGER_NAME セッション名、SystemTraceControlGuid セッション GUID、または GlobalLoggerGuid セッション GUID を使用して開始されたトレース セッションのみです。

このメンバーには、次の値を 1 つ以上指定できます。指定したイベントに加えて、EVENT_TRACE_FLAG_NO_SYSCONFIG を指定しない限り、ロガーは Windows XP ではハードウェア構成イベントを、Windows Server 2003 以降ではシステム構成イベントも記録します。

Anonymous1_Anonymous1_e__Union4+76+76AgeLimitとFlushThresholdを含む共用体。
NumberOfBuffersDWORD4+80+80出力時に、イベント トレース セッションのバッファー プールに割り当てられているバッファーの数が格納されます。
FreeBuffersDWORD4+84+84出力時に、イベント トレース セッションのバッファー プール内で割り当て済みだが未使用のバッファーの数が格納されます。
EventsLostDWORD4+88+88出力時に、記録されなかったイベントの数が格納されます。
BuffersWrittenDWORD4+92+92出力時に、書き込まれたバッファーの数が格納されます。
LogBuffersLostDWORD4+96+96出力時に、ログ ファイルに書き込めなかったバッファーの数が格納されます。
RealTimeBuffersLostDWORD4+100+100出力時に、コンシューマーへリアルタイムで配信できなかったバッファーの数が格納されます。
LoggerThreadIdHANDLE8/4+104+104出力時に、イベント トレース セッションのスレッド識別子が格納されます。
LogFileNameOffsetDWORD4+112+108

この構造体に割り当てられたメモリの先頭から、ログ ファイル名を格納する null 終端文字列の先頭までのオフセット (バイト単位) です。

ファイル名には通常 .etl 拡張子を使用します。パス中のすべてのフォルダーはあらかじめ存在している必要があります (ETW がフォルダーを作成することはありません)。パスは相対パス、絶対パス、ローカル パス、リモート パスのいずれでもかまいません。パス内の環境変数は展開されません。ユーザーはそのフォルダーへの書き込み権限を持っている必要があります。

ログ ファイル名は 1,024 文字までに制限されています。LogFileModeEVENT_TRACE_PRIVATE_LOGGER_MODE または EVENT_TRACE_FILE_MODE_NEWFILE を設定する場合は、プライベート ロガー セッションでファイル名に付加されるプロセス識別子や、新規ファイル ログ モードで作成されるログ ファイルに追加される連番を含められるだけの十分なメモリを確保してください。

ログ ファイルにイベントを記録しない場合 (たとえば EVENT_TRACE_REAL_TIME_MODE のみを指定する場合) は、LogFileNameOffset に 0 を設定します。リアルタイム ログのみを指定し、かつ有効なログ ファイル名へのオフセットも指定した場合、ETW はそのログ ファイル名を使用して順次ログ ファイルを作成し、リアルタイム コンシューマーへイベントを送信するのに加えて、ログ ファイルにもイベントを記録します。LogFileMode が 0 で、有効なログ ファイル名へのオフセットを指定した場合も、ETW は順次ログ ファイルを作成します。

ログ ファイルにイベントを記録する場合は、この構造体に続けてログ ファイル名とセッション名を含められるだけの十分なメモリを、この構造体用に確保する必要があります。メモリ上では、ログ ファイル名はセッション名の後に配置しなければなりません。例については解説を参照してください。

トレース ファイルは既定のセキュリティ記述子を使用して作成されます。つまり、ログ ファイルは親ディレクトリと同じ ACL を持ちます。ファイルへのアクセスを制限したい場合は、適切な ACL を設定した親ディレクトリを作成してください。

LoggerNameOffsetDWORD4+116+112

この構造体に割り当てられたメモリの先頭から、セッション名を格納する null 終端文字列の先頭までのオフセット (バイト単位) です。

重要

セッション名からセッションの所有者と用途が判別できるように、わかりやすい名前を使用してください。GUID などの内容を表さない値は使用しないでください。セッション名を一意にするためにランダムな数字を付加しないでください。ETW セッションは限られたリソースであるため、コンポーネントが複数のセッションを開始すべきではありません。コンポーネントの開始時に自身のセッションが既に実行されている場合は、2 つ目のセッションを作成するのではなく、取り残されたセッションをクリーンアップしてください。

セッション名は 1,024 文字までに制限されています。セッション名では大文字と小文字は区別されません。同じ名前の別のセッションが既に実行されている場合、システムは新しいセッションを開始しません。

Windows 2000: セッション名では大文字と小文字が区別されます。そのため、大文字と小文字だけが異なるセッションも許可されます。ただし、混乱を避けるため、セッション名が一意になるようにしてください。

Anonymous2_Anonymous2_e__Union8/4+120+116V2の制御フラグやFilteredVersion等を含む共用体。
FilterDescCountDWORD4+128+120FilterDesc が指すフィルターの数です。システム全体のプライベート ロガーを構成する場合を除き、0 でなければなりません。
FilterDescEVENT_FILTER_DESCRIPTOR*8/4+136+124

システム全体のプライベート ロガーでサポートされる EVENT_FILTER_DESCRIPTOR のフィルターの種類は次のとおりです。 EVENT_FILTER_TYPE_EXECUTABLE_NAME および EVENT_FILTER_TYPE_PID

フィルター データを指す EVENT_FILTER_DESCRIPTOR 構造体の配列へのポインターです。配列の要素数は FilterDescCount メンバーで指定します。EVENT_FILTER_DESCRIPTOR 構造体の Type メンバーで指定される特定のフィルターの種類ごとに、フィルターは 1 つしか指定できません。

システム全体のプライベート ロガーを構成する場合を除き、これは NULL でなければなりません。

Anonymous3_Anonymous3_e__Union8+144+128QpcDeltaTracking等のV2追加情報を含む共用体。

共用体: _Anonymous1_e__Union x64 4B / x86 4B

フィールドサイズx64x86説明
AgeLimitINT4+0+0

使用されません。

Windows 2000: 未使用のバッファーが解放されるまでの遅延時間 (分単位) です。既定値は 15 分です。

FlushThresholdINT4+0+0

共用体: _Anonymous2_e__Union x64 8B / x86 4B

フィールドサイズx64x86説明
Anonymous_Anonymous_e__Struct8/4+0+0
V2ControlDWORD4+0+0使用されません。

共用体: _Anonymous3_e__Union x64 8B / x86 8B

フィールドサイズx64x86説明
Anonymous_Anonymous_e__Struct8/4+0+0
V2OptionsULONGLONG8+0+0使用されません。

公式ドキュメント

EVENT_TRACE_PROPERTIES_V2 構造体は、イベント トレース セッションに関する情報を格納します。この構造体は、セッションのプロパティを定義、更新、または照会するときに、StartTraceControlTrace などの API と共に使用します。

メモ

これは EVENT_TRACE_PROPERTIES 構造体を拡張したバージョン 2 の構造体です。この構造体は Windows 10 バージョン 1703 以降でサポートされます。それより前のバージョンの Windows で使用した場合、追加のフィールド (FilterDescV2Options など) は無視されます。

解説(Remarks)

この構造体は、いくつかの例外を除いて EVENT_TRACE_PROPERTIES と同様に動作します。

この構造体の先頭部分は EVENT_TRACE_PROPERTIES とまったく同じ定義になっています。これにより、この新しい構造体は Windows 10 バージョン 1703 より前のバージョンの Windows を実行しているシステムとも互換性があり、そのようなシステムでは EVENT_TRACE_PROPERTIES として扱われます。

この構造体を使用する場合は、バージョン 2 の構造体であることを示すため、Wnode.Flags に WNODE_FLAG_VERSIONED_PROPERTIES を必ず含めてください。

この構造体を介して StartTraceControlTrace に渡されるフィルターは、 EnableTraceEx2 関数が扱うフィルターと同じセマンティクスを持つ点に注意してください。

この構造体のメモリを割り当てる際は、構造体に続けてセッション名とログ ファイル名を含められるだけの十分なメモリを割り当てる必要があります。メモリ上では、セッション名はログ ファイル名より前に配置しなければなりません。ログ ファイル名はオフセットの位置にコピーする必要がありますが、セッション名をオフセットの位置にコピーする必要はありません。 StartTrace 関数が名前をコピーします。

メンバーを設定する前に、この構造体のメモリを必ず 0 に初期化してください。例:

typedef struct EventTracePropertyData2 {
    EVENT_TRACE_PROPERTIES_V2 Props;
    WCHAR LoggerName[128];
    WCHAR LogFileName[1024];
} EventTracePropertyData2;

EventTracePropertyData2 data = { 0 };
data.Props.Wnode.BufferSize = sizeof(data);
data.Props.Wnode.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_VERSIONED_PROPERTIES;
data.Props.LogFileNameOffset = offsetof(EventTracePropertyData2, LogFileName);
data.Props.LoggerNameOffset = offsetof(EventTracePropertyData2, LoggerName);

プロバイダーからのイベントは、セッションのバッファーに書き込まれます。ファイル セッションまたはリアルタイム セッションのバッファーが満杯になると (または FlushTimer が満了すると)、セッションはイベントをログ ファイルに書き込む、リアルタイム コンシューマーに配信する、またはその両方を行ってバッファーをフラッシュします。セッションのバッファーがフラッシュできる速度よりも速く満たされる場合は、新しいバッファーが割り当てられ、MaximumBuffers を上限としてセッションのバッファー プールに追加されます。この上限を超えると、セッションは利用可能なバッファーができるまで、受信したイベントを破棄します。各セッションは破棄されたイベントの数を記録します (EventsLost メンバーを参照してください)。

ETW は未使用のバッファーを解放しません。

Windows 2000: ETW は AgeLimit メンバーの値に基づいて未使用のバッファーを解放します。

セッションの実行中に EventsLost などのセッションの統計情報を確認するには、 ControlTrace 関数を呼び出し、ControlCode パラメーターに EVENT_TRACE_CONTROL_QUERY を設定します。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での定義

#include <windows.h>

// WNODE_HEADER  (x64 48 / x86 48 バイト)
typedef struct WNODE_HEADER {
    DWORD BufferSize;
    DWORD ProviderId;
    _Anonymous1_e__Union Anonymous1;
    _Anonymous2_e__Union Anonymous2;
    GUID Guid;
    DWORD ClientContext;
    DWORD Flags;
} WNODE_HEADER;

// EVENT_TRACE_PROPERTIES_V2  (x64 152 / x86 136 バイト)
typedef struct EVENT_TRACE_PROPERTIES_V2 {
    WNODE_HEADER Wnode;
    DWORD BufferSize;
    DWORD MinimumBuffers;
    DWORD MaximumBuffers;
    DWORD MaximumFileSize;
    DWORD LogFileMode;
    DWORD FlushTimer;
    EVENT_TRACE_FLAG EnableFlags;
    _Anonymous1_e__Union Anonymous1;
    DWORD NumberOfBuffers;
    DWORD FreeBuffers;
    DWORD EventsLost;
    DWORD BuffersWritten;
    DWORD LogBuffersLost;
    DWORD RealTimeBuffersLost;
    HANDLE LoggerThreadId;
    DWORD LogFileNameOffset;
    DWORD LoggerNameOffset;
    _Anonymous2_e__Union Anonymous2;
    DWORD FilterDescCount;
    EVENT_FILTER_DESCRIPTOR* FilterDesc;
    _Anonymous3_e__Union Anonymous3;
} EVENT_TRACE_PROPERTIES_V2;
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WNODE_HEADER
{
    public uint BufferSize;
    public uint ProviderId;
    public _Anonymous1_e__Union Anonymous1;
    public _Anonymous2_e__Union Anonymous2;
    public Guid Guid;
    public uint ClientContext;
    public uint Flags;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct EVENT_TRACE_PROPERTIES_V2
{
    public WNODE_HEADER Wnode;
    public uint BufferSize;
    public uint MinimumBuffers;
    public uint MaximumBuffers;
    public uint MaximumFileSize;
    public uint LogFileMode;
    public uint FlushTimer;
    public uint EnableFlags;
    public _Anonymous1_e__Union Anonymous1;
    public uint NumberOfBuffers;
    public uint FreeBuffers;
    public uint EventsLost;
    public uint BuffersWritten;
    public uint LogBuffersLost;
    public uint RealTimeBuffersLost;
    public IntPtr LoggerThreadId;
    public uint LogFileNameOffset;
    public uint LoggerNameOffset;
    public _Anonymous2_e__Union Anonymous2;
    public uint FilterDescCount;
    public IntPtr FilterDesc;
    public _Anonymous3_e__Union Anonymous3;
}
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure WNODE_HEADER
    Public BufferSize As UInteger
    Public ProviderId As UInteger
    Public Anonymous1 As _Anonymous1_e__Union
    Public Anonymous2 As _Anonymous2_e__Union
    Public Guid As Guid
    Public ClientContext As UInteger
    Public Flags As UInteger
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure EVENT_TRACE_PROPERTIES_V2
    Public Wnode As WNODE_HEADER
    Public BufferSize As UInteger
    Public MinimumBuffers As UInteger
    Public MaximumBuffers As UInteger
    Public MaximumFileSize As UInteger
    Public LogFileMode As UInteger
    Public FlushTimer As UInteger
    Public EnableFlags As UInteger
    Public Anonymous1 As _Anonymous1_e__Union
    Public NumberOfBuffers As UInteger
    Public FreeBuffers As UInteger
    Public EventsLost As UInteger
    Public BuffersWritten As UInteger
    Public LogBuffersLost As UInteger
    Public RealTimeBuffersLost As UInteger
    Public LoggerThreadId As IntPtr
    Public LogFileNameOffset As UInteger
    Public LoggerNameOffset As UInteger
    Public Anonymous2 As _Anonymous2_e__Union
    Public FilterDescCount As UInteger
    Public FilterDesc As IntPtr
    Public Anonymous3 As _Anonymous3_e__Union
End Structure
import ctypes
from ctypes import wintypes

class WNODE_HEADER(ctypes.Structure):
    _fields_ = [
        ("BufferSize", wintypes.DWORD),
        ("ProviderId", wintypes.DWORD),
        ("Anonymous1", _Anonymous1_e__Union),
        ("Anonymous2", _Anonymous2_e__Union),
        ("Guid", GUID),
        ("ClientContext", wintypes.DWORD),
        ("Flags", wintypes.DWORD),
    ]

class EVENT_TRACE_PROPERTIES_V2(ctypes.Structure):
    _fields_ = [
        ("Wnode", WNODE_HEADER),
        ("BufferSize", wintypes.DWORD),
        ("MinimumBuffers", wintypes.DWORD),
        ("MaximumBuffers", wintypes.DWORD),
        ("MaximumFileSize", wintypes.DWORD),
        ("LogFileMode", wintypes.DWORD),
        ("FlushTimer", wintypes.DWORD),
        ("EnableFlags", wintypes.DWORD),
        ("Anonymous1", _Anonymous1_e__Union),
        ("NumberOfBuffers", wintypes.DWORD),
        ("FreeBuffers", wintypes.DWORD),
        ("EventsLost", wintypes.DWORD),
        ("BuffersWritten", wintypes.DWORD),
        ("LogBuffersLost", wintypes.DWORD),
        ("RealTimeBuffersLost", wintypes.DWORD),
        ("LoggerThreadId", ctypes.c_void_p),
        ("LogFileNameOffset", wintypes.DWORD),
        ("LoggerNameOffset", wintypes.DWORD),
        ("Anonymous2", _Anonymous2_e__Union),
        ("FilterDescCount", wintypes.DWORD),
        ("FilterDesc", ctypes.c_void_p),
        ("Anonymous3", _Anonymous3_e__Union),
    ]
#[repr(C)]
pub struct WNODE_HEADER {
    pub BufferSize: u32,
    pub ProviderId: u32,
    pub Anonymous1: _Anonymous1_e__Union,
    pub Anonymous2: _Anonymous2_e__Union,
    pub Guid: GUID,
    pub ClientContext: u32,
    pub Flags: u32,
}

#[repr(C)]
pub struct EVENT_TRACE_PROPERTIES_V2 {
    pub Wnode: WNODE_HEADER,
    pub BufferSize: u32,
    pub MinimumBuffers: u32,
    pub MaximumBuffers: u32,
    pub MaximumFileSize: u32,
    pub LogFileMode: u32,
    pub FlushTimer: u32,
    pub EnableFlags: u32,
    pub Anonymous1: _Anonymous1_e__Union,
    pub NumberOfBuffers: u32,
    pub FreeBuffers: u32,
    pub EventsLost: u32,
    pub BuffersWritten: u32,
    pub LogBuffersLost: u32,
    pub RealTimeBuffersLost: u32,
    pub LoggerThreadId: *mut core::ffi::c_void,
    pub LogFileNameOffset: u32,
    pub LoggerNameOffset: u32,
    pub Anonymous2: _Anonymous2_e__Union,
    pub FilterDescCount: u32,
    pub FilterDesc: *mut core::ffi::c_void,
    pub Anonymous3: _Anonymous3_e__Union,
}
import "golang.org/x/sys/windows"

type WNODE_HEADER struct {
	BufferSize uint32
	ProviderId uint32
	Anonymous1 _Anonymous1_e__Union
	Anonymous2 _Anonymous2_e__Union
	Guid windows.GUID
	ClientContext uint32
	Flags uint32
}

type EVENT_TRACE_PROPERTIES_V2 struct {
	Wnode WNODE_HEADER
	BufferSize uint32
	MinimumBuffers uint32
	MaximumBuffers uint32
	MaximumFileSize uint32
	LogFileMode uint32
	FlushTimer uint32
	EnableFlags uint32
	Anonymous1 _Anonymous1_e__Union
	NumberOfBuffers uint32
	FreeBuffers uint32
	EventsLost uint32
	BuffersWritten uint32
	LogBuffersLost uint32
	RealTimeBuffersLost uint32
	LoggerThreadId uintptr
	LogFileNameOffset uint32
	LoggerNameOffset uint32
	Anonymous2 _Anonymous2_e__Union
	FilterDescCount uint32
	FilterDesc uintptr
	Anonymous3 _Anonymous3_e__Union
}
type
  WNODE_HEADER = record
    BufferSize: DWORD;
    ProviderId: DWORD;
    Anonymous1: _Anonymous1_e__Union;
    Anonymous2: _Anonymous2_e__Union;
    Guid: TGUID;
    ClientContext: DWORD;
    Flags: DWORD;
  end;

  EVENT_TRACE_PROPERTIES_V2 = record
    Wnode: WNODE_HEADER;
    BufferSize: DWORD;
    MinimumBuffers: DWORD;
    MaximumBuffers: DWORD;
    MaximumFileSize: DWORD;
    LogFileMode: DWORD;
    FlushTimer: DWORD;
    EnableFlags: DWORD;
    Anonymous1: _Anonymous1_e__Union;
    NumberOfBuffers: DWORD;
    FreeBuffers: DWORD;
    EventsLost: DWORD;
    BuffersWritten: DWORD;
    LogBuffersLost: DWORD;
    RealTimeBuffersLost: DWORD;
    LoggerThreadId: Pointer;
    LogFileNameOffset: DWORD;
    LoggerNameOffset: DWORD;
    Anonymous2: _Anonymous2_e__Union;
    FilterDescCount: DWORD;
    FilterDesc: Pointer;
    Anonymous3: _Anonymous3_e__Union;
  end;
const WNODE_HEADER = extern struct {
    BufferSize: u32,
    ProviderId: u32,
    Anonymous1: _Anonymous1_e__Union,
    Anonymous2: _Anonymous2_e__Union,
    Guid: GUID,
    ClientContext: u32,
    Flags: u32,
};

const EVENT_TRACE_PROPERTIES_V2 = extern struct {
    Wnode: WNODE_HEADER,
    BufferSize: u32,
    MinimumBuffers: u32,
    MaximumBuffers: u32,
    MaximumFileSize: u32,
    LogFileMode: u32,
    FlushTimer: u32,
    EnableFlags: u32,
    Anonymous1: _Anonymous1_e__Union,
    NumberOfBuffers: u32,
    FreeBuffers: u32,
    EventsLost: u32,
    BuffersWritten: u32,
    LogBuffersLost: u32,
    RealTimeBuffersLost: u32,
    LoggerThreadId: ?*anyopaque,
    LogFileNameOffset: u32,
    LoggerNameOffset: u32,
    Anonymous2: _Anonymous2_e__Union,
    FilterDescCount: u32,
    FilterDesc: ?*anyopaque,
    Anonymous3: _Anonymous3_e__Union,
};
type
  WNODE_HEADER {.bycopy.} = object
    BufferSize: uint32
    ProviderId: uint32
    Anonymous1: _Anonymous1_e__Union
    Anonymous2: _Anonymous2_e__Union
    Guid: GUID
    ClientContext: uint32
    Flags: uint32

  EVENT_TRACE_PROPERTIES_V2 {.bycopy.} = object
    Wnode: WNODE_HEADER
    BufferSize: uint32
    MinimumBuffers: uint32
    MaximumBuffers: uint32
    MaximumFileSize: uint32
    LogFileMode: uint32
    FlushTimer: uint32
    EnableFlags: uint32
    Anonymous1: _Anonymous1_e__Union
    NumberOfBuffers: uint32
    FreeBuffers: uint32
    EventsLost: uint32
    BuffersWritten: uint32
    LogBuffersLost: uint32
    RealTimeBuffersLost: uint32
    LoggerThreadId: pointer
    LogFileNameOffset: uint32
    LoggerNameOffset: uint32
    Anonymous2: _Anonymous2_e__Union
    FilterDescCount: uint32
    FilterDesc: pointer
    Anonymous3: _Anonymous3_e__Union
struct WNODE_HEADER
{
    uint BufferSize;
    uint ProviderId;
    _Anonymous1_e__Union Anonymous1;
    _Anonymous2_e__Union Anonymous2;
    GUID Guid;
    uint ClientContext;
    uint Flags;
}

struct EVENT_TRACE_PROPERTIES_V2
{
    WNODE_HEADER Wnode;
    uint BufferSize;
    uint MinimumBuffers;
    uint MaximumBuffers;
    uint MaximumFileSize;
    uint LogFileMode;
    uint FlushTimer;
    uint EnableFlags;
    _Anonymous1_e__Union Anonymous1;
    uint NumberOfBuffers;
    uint FreeBuffers;
    uint EventsLost;
    uint BuffersWritten;
    uint LogBuffersLost;
    uint RealTimeBuffersLost;
    void* LoggerThreadId;
    uint LogFileNameOffset;
    uint LoggerNameOffset;
    _Anonymous2_e__Union Anonymous2;
    uint FilterDescCount;
    void* FilterDesc;
    _Anonymous3_e__Union Anonymous3;
}

HSP用 定義

HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。

; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; EVENT_TRACE_PROPERTIES_V2 サイズ: 136 バイト(x86)
dim st, 34    ; 4byte整数×34(構造体サイズ 136 / 4 切り上げ)
; Wnode : WNODE_HEADER (+0, 48byte)  varptr(st)+0 を基点に操作(48byte:入れ子/配列)
; BufferSize : DWORD (+48, 4byte)  st.12 = 値  /  値 = st.12   (lpoke/lpeek も可)
; MinimumBuffers : DWORD (+52, 4byte)  st.13 = 値  /  値 = st.13   (lpoke/lpeek も可)
; MaximumBuffers : DWORD (+56, 4byte)  st.14 = 値  /  値 = st.14   (lpoke/lpeek も可)
; MaximumFileSize : DWORD (+60, 4byte)  st.15 = 値  /  値 = st.15   (lpoke/lpeek も可)
; LogFileMode : DWORD (+64, 4byte)  st.16 = 値  /  値 = st.16   (lpoke/lpeek も可)
; FlushTimer : DWORD (+68, 4byte)  st.17 = 値  /  値 = st.17   (lpoke/lpeek も可)
; EnableFlags : EVENT_TRACE_FLAG (+72, 4byte)  st.18 = 値  /  値 = st.18   (lpoke/lpeek も可)
; Anonymous1 : _Anonymous1_e__Union (+76, 4byte)  varptr(st)+76 を基点に操作(4byte:入れ子/配列)
; NumberOfBuffers : DWORD (+80, 4byte)  st.20 = 値  /  値 = st.20   (lpoke/lpeek も可)
; FreeBuffers : DWORD (+84, 4byte)  st.21 = 値  /  値 = st.21   (lpoke/lpeek も可)
; EventsLost : DWORD (+88, 4byte)  st.22 = 値  /  値 = st.22   (lpoke/lpeek も可)
; BuffersWritten : DWORD (+92, 4byte)  st.23 = 値  /  値 = st.23   (lpoke/lpeek も可)
; LogBuffersLost : DWORD (+96, 4byte)  st.24 = 値  /  値 = st.24   (lpoke/lpeek も可)
; RealTimeBuffersLost : DWORD (+100, 4byte)  st.25 = 値  /  値 = st.25   (lpoke/lpeek も可)
; LoggerThreadId : HANDLE (+104, 4byte)  st.26 = 値  /  値 = st.26   (lpoke/lpeek も可)
; LogFileNameOffset : DWORD (+108, 4byte)  st.27 = 値  /  値 = st.27   (lpoke/lpeek も可)
; LoggerNameOffset : DWORD (+112, 4byte)  st.28 = 値  /  値 = st.28   (lpoke/lpeek も可)
; Anonymous2 : _Anonymous2_e__Union (+116, 4byte)  varptr(st)+116 を基点に操作(4byte:入れ子/配列)
; FilterDescCount : DWORD (+120, 4byte)  st.30 = 値  /  値 = st.30   (lpoke/lpeek も可)
; FilterDesc : EVENT_FILTER_DESCRIPTOR* (+124, 4byte)  varptr(st)+124 を基点に操作(4byte:入れ子/配列)
; Anonymous3 : _Anonymous3_e__Union (+128, 8byte)  varptr(st)+128 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; EVENT_TRACE_PROPERTIES_V2 サイズ: 152 バイト(x64)
dim st, 38    ; 4byte整数×38(構造体サイズ 152 / 4 切り上げ)
; Wnode : WNODE_HEADER (+0, 48byte)  varptr(st)+0 を基点に操作(48byte:入れ子/配列)
; BufferSize : DWORD (+48, 4byte)  st.12 = 値  /  値 = st.12   (lpoke/lpeek も可)
; MinimumBuffers : DWORD (+52, 4byte)  st.13 = 値  /  値 = st.13   (lpoke/lpeek も可)
; MaximumBuffers : DWORD (+56, 4byte)  st.14 = 値  /  値 = st.14   (lpoke/lpeek も可)
; MaximumFileSize : DWORD (+60, 4byte)  st.15 = 値  /  値 = st.15   (lpoke/lpeek も可)
; LogFileMode : DWORD (+64, 4byte)  st.16 = 値  /  値 = st.16   (lpoke/lpeek も可)
; FlushTimer : DWORD (+68, 4byte)  st.17 = 値  /  値 = st.17   (lpoke/lpeek も可)
; EnableFlags : EVENT_TRACE_FLAG (+72, 4byte)  st.18 = 値  /  値 = st.18   (lpoke/lpeek も可)
; Anonymous1 : _Anonymous1_e__Union (+76, 4byte)  varptr(st)+76 を基点に操作(4byte:入れ子/配列)
; NumberOfBuffers : DWORD (+80, 4byte)  st.20 = 値  /  値 = st.20   (lpoke/lpeek も可)
; FreeBuffers : DWORD (+84, 4byte)  st.21 = 値  /  値 = st.21   (lpoke/lpeek も可)
; EventsLost : DWORD (+88, 4byte)  st.22 = 値  /  値 = st.22   (lpoke/lpeek も可)
; BuffersWritten : DWORD (+92, 4byte)  st.23 = 値  /  値 = st.23   (lpoke/lpeek も可)
; LogBuffersLost : DWORD (+96, 4byte)  st.24 = 値  /  値 = st.24   (lpoke/lpeek も可)
; RealTimeBuffersLost : DWORD (+100, 4byte)  st.25 = 値  /  値 = st.25   (lpoke/lpeek も可)
; LoggerThreadId : HANDLE (+104, 8byte)  qpoke st,104,値 / qpeek(st,104)  ※IronHSPのみ。3.7/3.8は lpoke st,104,下位 : lpoke st,108,上位
; LogFileNameOffset : DWORD (+112, 4byte)  st.28 = 値  /  値 = st.28   (lpoke/lpeek も可)
; LoggerNameOffset : DWORD (+116, 4byte)  st.29 = 値  /  値 = st.29   (lpoke/lpeek も可)
; Anonymous2 : _Anonymous2_e__Union (+120, 8byte)  varptr(st)+120 を基点に操作(8byte:入れ子/配列)
; FilterDescCount : DWORD (+128, 4byte)  st.32 = 値  /  値 = st.32   (lpoke/lpeek も可)
; FilterDesc : EVENT_FILTER_DESCRIPTOR* (+136, 8byte)  varptr(st)+136 を基点に操作(8byte:入れ子/配列)
; Anonymous3 : _Anonymous3_e__Union (+144, 8byte)  varptr(st)+144 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
; ※GUID・入れ子構造体はデフォルト型でないため、依存する #defstruct を先に定義(下記に同梱)。
#defstruct global GUID, pack=1
    #field int Data1
    #field short Data2
    #field short Data3
    #field byte Data4 8
#endstruct

#defstruct global WNODE_HEADER
    #field int BufferSize
    #field int ProviderId
    #field byte Anonymous1 8
    #field byte Anonymous2 8
    #field GUID Guid
    #field int ClientContext
    #field int Flags
#endstruct

#defstruct global EVENT_TRACE_PROPERTIES_V2
    #field WNODE_HEADER Wnode
    #field int BufferSize
    #field int MinimumBuffers
    #field int MaximumBuffers
    #field int MaximumFileSize
    #field int LogFileMode
    #field int FlushTimer
    #field int EnableFlags
    #field byte Anonymous1 4
    #field int NumberOfBuffers
    #field int FreeBuffers
    #field int EventsLost
    #field int BuffersWritten
    #field int LogBuffersLost
    #field int RealTimeBuffersLost
    #field intptr LoggerThreadId
    #field int LogFileNameOffset
    #field int LoggerNameOffset
    #field byte Anonymous2 8
    #field int FilterDescCount
    #field intptr FilterDesc
    #field byte Anonymous3 8
#endstruct

stdim st, EVENT_TRACE_PROPERTIES_V2        ; NSTRUCT 変数を確保
st->BufferSize = 100
mes "BufferSize=" + st->BufferSize
; ※union フィールドは byte 列で確保(NSTRUCT は union 非対応)。必要に応じ手動でアクセス。