「JNA」イベントログのログファイルのパスを取得する

JNAを利用してイベントログのログファイル(.evtx)のパスを取得するサンプルを書いたのでメモ。

※「ログファイルのパス」は、イベントビューアの[ログのプロパティ] - [ログのパス] のこと。

public class Test {
  .....

private static final Wevtapi wevtapi = WinAPIIf.Wevtapi.INSTANCE;

private String getLogFilePath(String channel) throws Exception {
	HANDLE hChannel = wevtapi.EvtOpenChannelConfig(null, new WString(channel), 0);
	if (hChannel == null) {
		System.err.println("EvtOpenChannelConfig failed :" + kernel32.GetLastError());
	}

	int dwBufferSize = 0;
	IntByReference dwBufferUsed = new IntByReference(0);
	Memory propertyValueBuffer = null;
	boolean ret = wevtapi.EvtGetChannelConfigProperty(hChannel, wevtapi.EvtChannelLoggingConfigLogFilePath, 0,
			dwBufferSize, null, dwBufferUsed);
	if (!ret && com.sun.jna.platform.win32.Kernel32.ERROR_INSUFFICIENT_BUFFER != kernel32.GetLastError()) {
		System.err.println("EvtGetChannelConfigProperty failed (frist time):" + kernel32.GetLastError());
	} else {
		dwBufferSize = dwBufferUsed.getValue();
		propertyValueBuffer = new Memory(dwBufferSize);
		ret = wevtapi.EvtGetChannelConfigProperty(hChannel, wevtapi.EvtChannelLoggingConfigLogFilePath, 0,
				dwBufferSize, propertyValueBuffer, dwBufferUsed);
		if (!ret) {
			System.err.println("EvtGetChannelConfigProperty failed (second time):" + kernel32.GetLastError());
		}
	}
	return propertyValueBuffer.getPointer(0).getWideString(0);
}


WinAPIIf.java の定義は以下の感じです。

	HANDLE EvtOpenChannelConfig(HANDLE Session, WString ChannelPath, int Flags);

	boolean EvtGetChannelConfigProperty(HANDLE ChannelConfig, int PropertyId, int Flags,
			int PropertyValueBufferSize, Pointer PropertyValueBuffer, IntByReference PropertyValueBufferUsed);

	// EVT_CHANNEL_CONFIG_PROPERTY_ID
	public final int EvtChannelConfigEnabled = 0;
	public final int EvtChannelConfigIsolation = 1;
	public final int EvtChannelConfigType = 2;
	public final int EvtChannelConfigOwningPublisher = 3;
	public final int EvtChannelConfigClassicEventlog = 4;
	public final int EvtChannelConfigAccess = 5;
	public final int EvtChannelLoggingConfigRetention = 6;
	public final int EvtChannelLoggingConfigAutoBackup = 7;
	public final int EvtChannelLoggingConfigMaxSize = 8;
	public final int EvtChannelLoggingConfigLogFilePath = 9;
	public final int EvtChannelPublishingConfigLevel = 10;
	public final int EvtChannelPublishingConfigKeywords = 11;
	public final int EvtChannelPublishingConfigControlGuid = 12;
	public final int EvtChannelPublishingConfigBufferSize = 13;
	public final int EvtChannelPublishingConfigMinBuffers = 14;
	public final int EvtChannelPublishingConfigMaxBuffers = 15;
	public final int EvtChannelPublishingConfigLatency = 16;
	public final int EvtChannelPublishingConfigClockType = 17;
	public final int EvtChannelPublishingConfigSidType = 18;
	public final int EvtChannelPublisherList = 19;
	public final int EvtChannelPublishingConfigFileMax = 20;
	public final int EvtChannelConfigPropertyIdEND = 21;


使ってる関数のリファレンスは以下です。
EvtOpenChannelConfigでハンドルを取得して、そいつをEvtGetChannelConfigPropertyに渡す感じです。本サンプルはログファイルのパスを取得するのでEvtGetChannelConfigPropertyの引数にEvtChannelLoggingConfigLogFilePathを渡していますが、この指定によって取得する情報を変更できるみたいです(詳細は、EVT_CHANNEL_CONFIG_PROPERTY_IDを参照)

EvtOpenChannelConfig function (Windows)

EvtGetChannelConfigProperty function (Windows)

EVT_CHANNEL_CONFIG_PROPERTY_ID enumeration (Windows)

※ チャネルのプロパティの取得、設定に関するサンプルコード

Getting and Setting a Channel's Configuration Properties (Windows)


簡単ですが、以上になります。

[環境情報]
Windows 10
Java SE 8 Update 92
JNA 4.2.2