Получение и настройка свойств конфигурации канала
Канал изначально настраивается в манифесте (см. раздел определение каналов). Чтобы получить настраиваемые свойства канала, вызовите функцию EvtOpenChannelConfig, чтобы получить дескриптор канала. Затем вызовите функцию EvtGetChannelConfigProperty, чтобы получить значение настраиваемого свойства канала. Список настраиваемых свойств см. в перечислении EVT_CHANNEL_CONFIG_PROPERTY_ID. Свойства строки сообщений и имени канала считаются метаданными и не могут быть извлечены с помощью функции EvtGetChannelConfigProperty. Для получения дополнительных сведений о получении этих свойств см. Получение метаданных поставщика.
Во время выполнения можно настроить множество свойств канала. Перечисление EVT_CHANNEL_CONFIG_PROPERTY_ID определяет эти свойства, которые нельзя задать. Чтобы настроить свойства канала, пользователь должен находиться в группе администраторов и работать с повышенными привилегиями. Чтобы задать настраиваемые свойства канала, вызовите функцию EvtOpenChannelConfig, чтобы получить дескриптор канала. Затем вызовите функцию EvtSetChannelConfigProperty, чтобы задать значение настраиваемого свойства. После задания настраиваемых свойств вызовите функцию EvtSaveChannelConfig, чтобы сохранить и применить изменения.
Примеры получения и задания свойств канала см. в следующих разделах:
Перечисление каналов
В следующем примере показано, как перечислить каналы, зарегистрированные на компьютере.
#include <windows.h>
#include <stdio.h>
#include <winevt.h>
#pragma comment(lib, "wevtapi.lib")
void main(void)
{
EVT_HANDLE hChannels = NULL;
LPWSTR pBuffer = NULL;
LPWSTR pTemp = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD status = ERROR_SUCCESS;
// Get a handle to an enumerator that contains all the names of the
// channels registered on the computer.
hChannels = EvtOpenChannelEnum(NULL, 0);
if (NULL == hChannels)
{
wprintf(L"EvtOpenChannelEnum failed with %lu.\n", GetLastError());
goto cleanup;
}
wprintf(L"List of Channels\n\n");
// Enumerate through the list of channel names. If the buffer is not big
// enough reallocate the buffer. To get the configuration information for
// a channel, call the EvtOpenChannelConfig function.
while (true)
{
if (!EvtNextChannelPath(hChannels, dwBufferSize, pBuffer, &dwBufferUsed))
{
status = GetLastError();
if (ERROR_NO_MORE_ITEMS == status)
{
break;
}
else if (ERROR_INSUFFICIENT_BUFFER == status)
{
dwBufferSize = dwBufferUsed;
pTemp = (LPWSTR)realloc(pBuffer, dwBufferSize * sizeof(WCHAR));
if (pTemp)
{
pBuffer = pTemp;
pTemp = NULL;
EvtNextChannelPath(hChannels, dwBufferSize, pBuffer, &dwBufferUsed);
}
else
{
wprintf(L"realloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
else
{
wprintf(L"EvtNextChannelPath failed with %lu.\n", status);
}
}
wprintf(L"%s\n", pBuffer);
}
cleanup:
if (hChannels)
EvtClose(hChannels);
if (pBuffer)
free(pBuffer);
}
Получение свойств канала
В следующем примере показано, как получить настраиваемые свойства канала.
#include <windows.h>
#include <stdio.h>
#include <winevt.h>
#pragma comment(lib, "wevtapi.lib")
#pragma comment(lib, "ole32.lib")
LPWSTR pwcsChannelTypes[] = {L"Admin", L"Operational", L"Analytic", L"Debug"};
LPWSTR pwcsIsolationTypes[] = {L"Application", L"System", L"Custom"};
LPWSTR pwcsClockTypes[] = {L"System", L"QPC"};
DWORD PrintChannelProperties(EVT_HANDLE hChannel);
DWORD PrintChannelProperty(int Id, PEVT_VARIANT pProperty);
void main(void)
{
EVT_HANDLE hChannel = NULL;
DWORD status = ERROR_SUCCESS;
LPWSTR pwsChannelName = L"<name of channel goes here>";
hChannel = EvtOpenChannelConfig(NULL, pwsChannelName, 0);
if (NULL == hChannel) // Fails with 15007 (ERROR_EVT_CHANNEL_NOT_FOUND) if the channel is not found
{
wprintf(L"EvtOpenChannelConfig failed with %lu.\n", GetLastError());
goto cleanup;
}
status = PrintChannelProperties(hChannel);
cleanup:
if (hChannel)
EvtClose(hChannel);
}
// Print the channel's configuration properties. Use the EVT_CHANNEL_CONFIG_PROPERTY_ID
// enumeration values to loop through all the properties.
DWORD PrintChannelProperties(EVT_HANDLE hChannel)
{
PEVT_VARIANT pProperty = NULL; // Buffer that receives the property value
PEVT_VARIANT pTemp = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD status = ERROR_SUCCESS;
for (int Id = 0; Id < EvtChannelConfigPropertyIdEND; Id++)
{
// Get the specified property. If the buffer is too small, reallocate it.
if (!EvtGetChannelConfigProperty(hChannel, (EVT_CHANNEL_CONFIG_PROPERTY_ID)Id, 0, dwBufferSize, pProperty, &dwBufferUsed))
{
status = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == status)
{
dwBufferSize = dwBufferUsed;
pTemp = (PEVT_VARIANT)realloc(pProperty, dwBufferSize);
if (pTemp)
{
pProperty = pTemp;
pTemp = NULL;
EvtGetChannelConfigProperty(hChannel, (EVT_CHANNEL_CONFIG_PROPERTY_ID)Id, 0, dwBufferSize, pProperty, &dwBufferUsed);
}
else
{
wprintf(L"realloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtGetChannelConfigProperty failed with %d\n", GetLastError());
goto cleanup;
}
}
if (status = PrintChannelProperty(Id, pProperty))
break;
}
cleanup:
if (pProperty)
free(pProperty);
return status;
}
// Print the property value.
DWORD PrintChannelProperty(int Id, PEVT_VARIANT pProperty)
{
DWORD status = ERROR_SUCCESS;
WCHAR wszSessionGuid[50];
LPWSTR lpws = NULL;
switch(Id)
{
case EvtChannelConfigEnabled:
wprintf(L"Enabled: %s\n", (TRUE == pProperty->BooleanVal) ? L"TRUE" : L"FALSE");
break;
case EvtChannelConfigIsolation:
wprintf(L"Isolation: %s\n", pwcsIsolationTypes[pProperty->UInt32Val]);
break;
case EvtChannelConfigType:
wprintf(L"Type: %s\n", pwcsChannelTypes[pProperty->UInt32Val]);
break;
// This will contain a value if the channel is imported.
case EvtChannelConfigOwningPublisher:
wprintf(L"Publisher that defined the channel: %s\n", pProperty->StringVal);
break;
case EvtChannelConfigClassicEventlog:
wprintf(L"ClassicEventlog: %s\n", (TRUE == pProperty->BooleanVal) ? L"TRUE" : L"FALSE");
break;
case EvtChannelConfigAccess:
wprintf(L"Access: %s\n", pProperty->StringVal);
break;
case EvtChannelLoggingConfigRetention:
wprintf(L"Retention: %s\n", (TRUE == pProperty->BooleanVal) ? L"TRUE (Sequential)" : L"FALSE (Circular)");
break;
case EvtChannelLoggingConfigAutoBackup:
wprintf(L"AutoBackup: %s\n", (TRUE == pProperty->BooleanVal) ? L"TRUE" : L"FALSE");
break;
case EvtChannelLoggingConfigMaxSize:
wprintf(L"MaxSize: %I64u MB\n", pProperty->UInt64Val / (1024*1024));
break;
case EvtChannelLoggingConfigLogFilePath:
wprintf(L"LogFilePath: %s\n", pProperty->StringVal);
break;
case EvtChannelPublishingConfigLevel:
if (EvtVarTypeNull == pProperty->Type)
wprintf(L"Level: \n");
else
wprintf(L"Level: %lu\n", pProperty->UInt32Val);
break;
// The upper 8 bits can contain reserved bit values, so do not include them
// when checking to see if any keywords are set.
case EvtChannelPublishingConfigKeywords:
if (EvtVarTypeNull == pProperty->Type)
wprintf(L"Keywords: \n");
else
wprintf(L"Keywords: %I64u\n", pProperty->UInt64Val & 0x00FFFFFFFFFFFFFF);
break;
case EvtChannelPublishingConfigControlGuid:
if (EvtVarTypeNull == pProperty->Type)
wprintf(L"ControlGuid: \n");
else
{
StringFromGUID2(*(pProperty->GuidVal), wszSessionGuid, sizeof(wszSessionGuid)/sizeof(WCHAR));
wprintf(L"ControlGuid: %s\n", wszSessionGuid);
}
break;
case EvtChannelPublishingConfigBufferSize:
wprintf(L"BufferSize: %lu KB\n", pProperty->UInt32Val);
break;
case EvtChannelPublishingConfigMinBuffers:
wprintf(L"MinBuffers: %lu\n", pProperty->UInt32Val);
break;
case EvtChannelPublishingConfigMaxBuffers:
wprintf(L"MaxBuffers: %lu\n", pProperty->UInt32Val);
break;
case EvtChannelPublishingConfigLatency:
wprintf(L"Latency: %lu (sec)\n", pProperty->UInt32Val / 1000); // 1 ms
break;
case EvtChannelPublishingConfigClockType:
wprintf(L"ClockType: %s\n", pwcsClockTypes[pProperty->UInt32Val]);
break;
case EvtChannelPublishingConfigSidType:
wprintf(L"Include security ID (SID): %s\n", (EvtChannelSidTypeNone == pProperty->UInt32Val) ? L"No" : L"Yes");
break;
case EvtChannelPublisherList:
wprintf(L"List of providers that import this channel: \n");
for (DWORD i = 0; i < pProperty->Count; i++)
{
wprintf(L" %s\n", pProperty->StringArr[i]);
}
break;
case EvtChannelPublishingConfigFileMax:
wprintf(L"FileMax: %lu\n", pProperty->UInt32Val);
break;
default:
wprintf(L"Unknown property Id: %d\n", Id);
}
return status;
}
Установка свойств канала
В следующем примере показано, как задать настраиваемые свойства канала.
#include <windows.h>
#include <stdio.h>
#include <winevt.h>
#include <winmeta.h>
// For this example, including the keywords that were defined in the header file
// that the message compiler generated for the manifest.
//
// Keywords
//
#define READ_KEYWORD 0x10
#define WRITE_KEYWORD 0x20
// #include "myprovider.h" // Contains the keywords defined for my provider
#pragma comment(lib, "wevtapi.lib")
void main(void)
{
EVT_HANDLE hChannel = NULL;
DWORD status = ERROR_SUCCESS;
EVT_VARIANT ChannelProperty;
DWORD dwBufferSize = sizeof(EVT_VARIANT);
DWORD dwBufferUsed = 0;
hChannel = EvtOpenChannelConfig(NULL, L"<name of channel goes here>", 0);
if (NULL == hChannel)
{
wprintf(L"EvtOpenChannelConfig failed with %lu.\n", GetLastError());
goto cleanup;
}
RtlZeroMemory(&ChannelProperty, dwBufferSize);
ChannelProperty.Type = EvtVarTypeBoolean;
ChannelProperty.BooleanVal = FALSE;
if (!EvtSetChannelConfigProperty(hChannel, EvtChannelConfigEnabled, 0, &ChannelProperty))
{
wprintf(L"EvtSetChannelConfigProperty for Enabled property failed with %lu\n", GetLastError());
goto cleanup;
}
RtlZeroMemory(&ChannelProperty, dwBufferSize);
ChannelProperty.Type = EvtVarTypeUInt32;
ChannelProperty.UInt32Val = WINEVENT_LEVEL_WARNING; // Found in winmeta.h
if (!EvtSetChannelConfigProperty(hChannel, EvtChannelPublishingConfigLevel, 0, &ChannelProperty))
{
wprintf(L"EvtSetChannelConfigProperty for Level failed with %lu\n", GetLastError());
goto cleanup;
}
RtlZeroMemory(&ChannelProperty, dwBufferSize);
ChannelProperty.Type = EvtVarTypeUInt64;
ChannelProperty.UInt64Val = READ_KEYWORD | WRITE_KEYWORD;
if (!EvtSetChannelConfigProperty(hChannel, EvtChannelPublishingConfigKeywords, 0, &ChannelProperty))
{
wprintf(L"EvtSetChannelConfigProperty for Keywords failed with %lu\n", GetLastError());
goto cleanup;
}
RtlZeroMemory(&ChannelProperty, dwBufferSize);
ChannelProperty.Type = EvtVarTypeBoolean;
ChannelProperty.BooleanVal = TRUE;
if (!EvtSetChannelConfigProperty(hChannel, EvtChannelConfigEnabled, 0, &ChannelProperty))
{
wprintf(L"EvtSetChannelConfigProperty for Enabled property failed with %lu\n", GetLastError());
goto cleanup;
}
// The user needs to be in the administrators group and be running with
// elevated permissions for this call to work.
if (!EvtSaveChannelConfig(hChannel, 0))
{
wprintf(L"EvtSaveChannelConfig failed with %lu\n", GetLastError());
goto cleanup;
}
wprintf(L"Channel properties updated.\n");
cleanup:
if (hChannel)
EvtClose(hChannel);
}