Чтение регистрационных файлов

октября 12 2009 by admin in Администрирование

Для изучения регистрационных файлов обычно хватает модульного компонента Event Viewer из состава Windows. Но в Windows все же имеются функции, позволяющие осуществлять доступ к журналам событий из других приложений. Они находят множество применений, например, можно создать программу, посылающую по электронной почте сообщения о добавлении в регистрационный файл событий с определенным идентификатором.
Чтобы начать чтение регистрационного файла, приложение должно получить его описатель, вызвав для этого функцию OpenEventLog:
HANDLE OpenEventLog(
PCTSTR pszUNCServerName, PCTSTR pszLogName);
Параметр pszUNCServerName определяет компьютер, содержащий регистрационный файл, доступ к которому вы хотите получить. Параметр pszLogName определяет конкретный файл на сервере. Получив описатель, вы можете приступить к чтению событий. Окончив работу с регистрационным файлом, его описатель, как обычно, нужно закрыть с помощью CloseEventLog.
BOOL CloseEventLog(HANDLE hEventLog);
Для чтения событий вызывается функция ReadEventLog:
BOOL ReadEventLog( HANDLE hEventLog, DWORD dwReadFlags, DWORD dwRecordOffset, PVOID pvBuffer, DWORD nNumberOfBytesToRead, PDWORD pnBytesRead, PDWORD pnMinNumberOfBytesNeeded);
Параметр hEventLog должен содержать описатель, полученный с помощью функции OpenEventLog. Параметр dwReadFlags определяет, будете ли вы считывать регистрационный файл последовательно или начав с какой-либо конкретной записи. Обычно в него помещается значение EVENTLOG_ FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ.
Чтобы получить данные из регистрационного файла, в ReadEventLog нужно передать указатель на буфер {pvBuffer) и указать размер этого буфера в байтах {nNumberOfBytesToRead). Если буфер мал для сохранения в нем записи о событии, функция завершит свое выполнение с ошибкой, a GetLastError вернет F.RROR_INSUFFICIENT_BUFFER. При этом переменная, на которую указывает параметр pnMinNumherOj'BytesNeeded, будет содержать количество байтов, нужное для получения записи. Но если буфер большой и в него может поместиться одна или несколько записей, ReadEventLog заполнит его полностью, сохранив в нем максимально возможное число записей. Я предлагаю сначала вызывать ReadEventl.og для определения размера буфера, затем выделять для него память и только после этого повторно обращаться к ReadEventLog для считывания данных. Конечно, можно считывать сразу несколько событий, но значительно повысить эффективность приложения таким путем не получится, зато код синтаксического анализа записей усложнится, так как длина возвращаемых данных не фиксирована.
Если записей для чтения больше не осталось, ReadEventLog вернет FALSE, при этом CetlastError сообщит об ошибке ERROR_HANDLE_EOF.