mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:45:41 +00:00
[EVENTLOG]
- Use NT functions to retrieve timestamps for events. - Log kernel events with the current computer name. - Don't hardcode variables types for sizeofs. - Add type-checks for the data to be retrieved from the registry, and use default values in case the values do not exist or are invalid. - Use ULONG_PTR to perform pointer arithmetics. - Use string-safe functions for copy/concatenation. - Cache EventLog source for eventlog service self-logging. - Unlock the LogFile in LogfClearFile. - Fix rounding in LogfAllocAndBuildNewRecord. - Verify ELF handle validity in ElfrGetLogInformation. - Implement IELF_HANDLE_rundown to correctly cleanup ELF handles when client apps shut down. Adapt also the parameter of ElfDeleteEventLogHandle for reusing it there. - Update some code formatting. CORE-11842 #resolve I don't completely touch file.c as it contains most of my upcoming eventlog fixes... svn path=/trunk/; revision=72213
This commit is contained in:
parent
275590c74e
commit
f7cb5ca5c0
6 changed files with 758 additions and 650 deletions
|
@ -33,6 +33,8 @@ SERVICE_STATUS_HANDLE ServiceStatusHandle;
|
|||
BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
|
||||
HANDLE MyHeap = NULL;
|
||||
|
||||
PEVENTSOURCE EventLogSource = NULL;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static VOID
|
||||
|
@ -74,7 +76,6 @@ ServiceControlHandler(DWORD dwControl,
|
|||
0,
|
||||
EVENT_EventlogStopped, 0, NULL, 0, NULL);
|
||||
|
||||
|
||||
/* Stop listening to incoming RPC messages */
|
||||
RpcMgmtStopServerListening(NULL);
|
||||
UpdateServiceStatus(SERVICE_STOPPED);
|
||||
|
@ -120,15 +121,13 @@ ServiceInit(VOID)
|
|||
|
||||
hThread = CreateThread(NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)
|
||||
PortThreadRoutine,
|
||||
(LPTHREAD_START_ROUTINE)PortThreadRoutine,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!hThread)
|
||||
{
|
||||
DPRINT("Can't create PortThread\n");
|
||||
DPRINT("Cannot create PortThread\n");
|
||||
return GetLastError();
|
||||
}
|
||||
else
|
||||
|
@ -136,15 +135,14 @@ ServiceInit(VOID)
|
|||
|
||||
hThread = CreateThread(NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)
|
||||
RpcThreadRoutine,
|
||||
RpcThreadRoutine,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!hThread)
|
||||
{
|
||||
DPRINT("Can't create RpcThread\n");
|
||||
DPRINT("Cannot create RpcThread\n");
|
||||
return GetLastError();
|
||||
}
|
||||
else
|
||||
|
@ -165,14 +163,14 @@ ReportProductInfoEvent(VOID)
|
|||
DWORD dwType;
|
||||
LONG lResult = ERROR_SUCCESS;
|
||||
|
||||
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFO));
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
ZeroMemory(&versionInfo, sizeof(versionInfo));
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||
|
||||
/* Get version information */
|
||||
if (!GetVersionExW(&versionInfo))
|
||||
return;
|
||||
|
||||
ZeroMemory(szBuffer, 512 * sizeof(WCHAR));
|
||||
ZeroMemory(szBuffer, sizeof(szBuffer));
|
||||
|
||||
/* Write version into the buffer */
|
||||
dwLength = swprintf(szBuffer,
|
||||
|
@ -197,7 +195,7 @@ ReportProductInfoEvent(VOID)
|
|||
&hKey);
|
||||
if (lResult == ERROR_SUCCESS)
|
||||
{
|
||||
dwValueLength = 512 - dwLength;
|
||||
dwValueLength = ARRAYSIZE(szBuffer) - dwLength;
|
||||
lResult = RegQueryValueEx(hKey,
|
||||
L"CurrentType",
|
||||
NULL,
|
||||
|
@ -268,7 +266,8 @@ ServiceMain(DWORD argc,
|
|||
}
|
||||
|
||||
|
||||
PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
|
||||
static PLOGFILE
|
||||
LoadLogFile(HKEY hKey, WCHAR* LogName)
|
||||
{
|
||||
DWORD MaxValueLen, ValueLen, Type, ExpandedLen;
|
||||
WCHAR *Buf = NULL, *Expanded = NULL;
|
||||
|
@ -280,58 +279,81 @@ PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
|
|||
|
||||
DPRINT("LoadLogFile: %S\n", LogName);
|
||||
|
||||
Result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &MaxValueLen, NULL, NULL);
|
||||
Result = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &MaxValueLen, NULL, NULL);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
|
||||
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MaxValueLen = ROUND_DOWN(MaxValueLen, sizeof(WCHAR));
|
||||
Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
|
||||
if (!Buf)
|
||||
{
|
||||
DPRINT1("Can't allocate heap!\n");
|
||||
DPRINT1("Cannot allocate heap!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ValueLen = MaxValueLen;
|
||||
|
||||
Result = RegQueryValueEx(hKey,
|
||||
L"File",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE) Buf,
|
||||
&ValueLen);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
Result = RegQueryValueExW(hKey,
|
||||
L"File",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE)Buf,
|
||||
&ValueLen);
|
||||
/*
|
||||
* If we failed, because the registry value was inexistent
|
||||
* or the value type was incorrect, create a new "File" value
|
||||
* that holds the default event log path.
|
||||
*/
|
||||
if ((Result != ERROR_SUCCESS) || (Type != REG_EXPAND_SZ && Type != REG_SZ))
|
||||
{
|
||||
DPRINT1("RegQueryValueEx failed: %lu\n", Result);
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return NULL;
|
||||
MaxValueLen = (wcslen(L"%SystemRoot%\\System32\\Config\\") +
|
||||
wcslen(LogName) + wcslen(L".evt") + 1) * sizeof(WCHAR);
|
||||
|
||||
Expanded = HeapReAlloc(MyHeap, 0, Buf, MaxValueLen);
|
||||
if (!Expanded)
|
||||
{
|
||||
DPRINT1("Cannot reallocate heap!\n");
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return NULL;
|
||||
}
|
||||
Buf = Expanded;
|
||||
|
||||
StringCbCopyW(Buf, MaxValueLen, L"%SystemRoot%\\System32\\Config\\");
|
||||
StringCbCatW(Buf, MaxValueLen, LogName);
|
||||
StringCbCatW(Buf, MaxValueLen, L".evt");
|
||||
|
||||
ValueLen = MaxValueLen;
|
||||
Result = RegSetValueExW(hKey,
|
||||
L"File",
|
||||
0,
|
||||
REG_EXPAND_SZ,
|
||||
(LPBYTE)Buf,
|
||||
ValueLen);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegSetValueEx failed: %lu\n", Result);
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (Type != REG_EXPAND_SZ && Type != REG_SZ)
|
||||
{
|
||||
DPRINT1("%S\\File - value of wrong type %x.\n", LogName, Type);
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExpandedLen = ExpandEnvironmentStrings(Buf, NULL, 0);
|
||||
ExpandedLen = ExpandEnvironmentStringsW(Buf, NULL, 0);
|
||||
Expanded = HeapAlloc(MyHeap, 0, ExpandedLen * sizeof(WCHAR));
|
||||
if (!Expanded)
|
||||
{
|
||||
DPRINT1("Can't allocate heap!\n");
|
||||
DPRINT1("Cannot allocate heap!\n");
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen);
|
||||
ExpandEnvironmentStringsW(Buf, Expanded, ExpandedLen);
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName,
|
||||
NULL, NULL))
|
||||
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName, NULL, NULL))
|
||||
{
|
||||
DPRINT1("Can't convert path!\n");
|
||||
DPRINT1("Cannot convert path!\n");
|
||||
HeapFree(MyHeap, 0, Expanded);
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return NULL;
|
||||
|
@ -339,73 +361,92 @@ PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
|
|||
|
||||
DPRINT("%S -> %S\n", Buf, Expanded);
|
||||
|
||||
ValueLen = sizeof(ULONG);
|
||||
Result = RegQueryValueEx(hKey,
|
||||
L"MaxSize",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE)&ulMaxSize,
|
||||
&ValueLen);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
ValueLen = sizeof(ulMaxSize);
|
||||
Result = RegQueryValueExW(hKey,
|
||||
L"MaxSize",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE)&ulMaxSize,
|
||||
&ValueLen);
|
||||
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
|
||||
{
|
||||
ulMaxSize = 512 * 1024; /* 512 kBytes */
|
||||
|
||||
ValueLen = sizeof(ULONG);
|
||||
Result = RegQueryValueEx(hKey,
|
||||
L"Retention",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE)&ulRetention,
|
||||
&ValueLen);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
Result = RegSetValueExW(hKey,
|
||||
L"MaxSize",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPBYTE)&ulMaxSize,
|
||||
sizeof(ulMaxSize));
|
||||
}
|
||||
|
||||
ValueLen = sizeof(ulRetention);
|
||||
Result = RegQueryValueExW(hKey,
|
||||
L"Retention",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE)&ulRetention,
|
||||
&ValueLen);
|
||||
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
|
||||
{
|
||||
/* On Windows 2003 it is 604800 (secs) == 7 days */
|
||||
ulRetention = 0;
|
||||
|
||||
Result = RegSetValueExW(hKey,
|
||||
L"Retention",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPBYTE)&ulRetention,
|
||||
sizeof(ulRetention));
|
||||
}
|
||||
|
||||
// TODO: Add, or use, default values for "AutoBackupLogFiles" (REG_DWORD)
|
||||
// and "CustomSD" (REG_SZ).
|
||||
|
||||
Status = LogfCreate(&pLogf, LogName, &FileName, ulMaxSize, ulRetention, TRUE, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create %S! (Status %08lx)\n", Expanded, Status);
|
||||
}
|
||||
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
HeapFree(MyHeap, 0, Expanded);
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return pLogf;
|
||||
}
|
||||
|
||||
BOOL LoadLogFiles(HKEY eventlogKey)
|
||||
static BOOL
|
||||
LoadLogFiles(HKEY eventlogKey)
|
||||
{
|
||||
LONG Result;
|
||||
DWORD MaxLognameLen, LognameLen;
|
||||
WCHAR *Buf = NULL;
|
||||
INT i;
|
||||
DWORD dwIndex;
|
||||
PLOGFILE pLogFile;
|
||||
|
||||
Result = RegQueryInfoKey(eventlogKey,
|
||||
NULL, NULL, NULL, NULL,
|
||||
&MaxLognameLen,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
Result = RegQueryInfoKeyW(eventlogKey, NULL, NULL, NULL, NULL, &MaxLognameLen,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
|
||||
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MaxLognameLen++;
|
||||
|
||||
Buf = HeapAlloc(MyHeap, 0, MaxLognameLen * sizeof(WCHAR));
|
||||
|
||||
if (!Buf)
|
||||
{
|
||||
DPRINT1("Error: can't allocate heap!\n");
|
||||
DPRINT1("Error: cannot allocate heap!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
LognameLen = MaxLognameLen;
|
||||
|
||||
while (RegEnumKeyEx(eventlogKey,
|
||||
i,
|
||||
Buf,
|
||||
&LognameLen,
|
||||
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||
dwIndex = 0;
|
||||
while (RegEnumKeyExW(eventlogKey,
|
||||
dwIndex,
|
||||
Buf,
|
||||
&LognameLen,
|
||||
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||
{
|
||||
HKEY SubKey;
|
||||
|
||||
|
@ -431,15 +472,17 @@ BOOL LoadLogFiles(HKEY eventlogKey)
|
|||
}
|
||||
|
||||
RegCloseKey(SubKey);
|
||||
|
||||
LognameLen = MaxLognameLen;
|
||||
i++;
|
||||
dwIndex++;
|
||||
}
|
||||
|
||||
HeapFree(MyHeap, 0, Buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
INT wmain()
|
||||
|
||||
int wmain(int argc, WCHAR* argv[])
|
||||
{
|
||||
WCHAR LogPath[MAX_PATH];
|
||||
INT RetCode = 0;
|
||||
|
@ -458,9 +501,9 @@ INT wmain()
|
|||
goto bye_bye;
|
||||
}
|
||||
|
||||
GetWindowsDirectory(LogPath, MAX_PATH);
|
||||
GetWindowsDirectoryW(LogPath, MAX_PATH);
|
||||
|
||||
if (GetDriveType(LogPath) == DRIVE_CDROM)
|
||||
if (GetDriveTypeW(LogPath) == DRIVE_CDROM)
|
||||
{
|
||||
DPRINT("LiveCD detected\n");
|
||||
onLiveCD = TRUE;
|
||||
|
@ -475,7 +518,7 @@ INT wmain()
|
|||
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("Fatal error: can't open eventlog registry key.\n");
|
||||
DPRINT1("Fatal error: cannot open eventlog registry key.\n");
|
||||
RetCode = 1;
|
||||
goto bye_bye;
|
||||
}
|
||||
|
@ -483,9 +526,15 @@ INT wmain()
|
|||
LoadLogFiles(elogKey);
|
||||
}
|
||||
|
||||
EventLogSource = GetEventSourceByName(L"EventLog");
|
||||
if (!EventLogSource)
|
||||
{
|
||||
DPRINT1("No EventLog source available, the EventLog service will not be able to log its own events.\n");
|
||||
}
|
||||
|
||||
StartServiceCtrlDispatcher(ServiceTable);
|
||||
|
||||
bye_bye:
|
||||
bye_bye:
|
||||
LogfCloseAll();
|
||||
|
||||
if (MyHeap)
|
||||
|
@ -494,40 +543,10 @@ INT wmain()
|
|||
return RetCode;
|
||||
}
|
||||
|
||||
VOID EventTimeToSystemTime(DWORD EventTime, SYSTEMTIME * pSystemTime)
|
||||
{
|
||||
SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
|
||||
FILETIME ftLocal;
|
||||
union
|
||||
{
|
||||
FILETIME ft;
|
||||
ULONGLONG ll;
|
||||
} u1970, uUCT;
|
||||
|
||||
uUCT.ft.dwHighDateTime = 0;
|
||||
uUCT.ft.dwLowDateTime = EventTime;
|
||||
SystemTimeToFileTime(&st1970, &u1970.ft);
|
||||
uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
|
||||
FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
|
||||
FileTimeToSystemTime(&ftLocal, pSystemTime);
|
||||
}
|
||||
|
||||
VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime, DWORD * pEventTime)
|
||||
{
|
||||
SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
|
||||
union
|
||||
{
|
||||
FILETIME ft;
|
||||
ULONGLONG ll;
|
||||
} Time, u1970;
|
||||
|
||||
SystemTimeToFileTime(pSystemTime, &Time.ft);
|
||||
SystemTimeToFileTime(&st1970, &u1970.ft);
|
||||
*pEventTime = (DWORD)((Time.ll - u1970.ll) / 10000000ull);
|
||||
}
|
||||
|
||||
VOID PRINT_HEADER(PEVENTLOGHEADER header)
|
||||
{
|
||||
ULONG Flags = header->Flags;
|
||||
|
||||
DPRINT("HeaderSize = %lu\n", header->HeaderSize);
|
||||
DPRINT("Signature = 0x%x\n", header->Signature);
|
||||
DPRINT("MajorVersion = %lu\n", header->MajorVersion);
|
||||
|
@ -540,10 +559,30 @@ VOID PRINT_HEADER(PEVENTLOGHEADER header)
|
|||
DPRINT("Retention = 0x%x\n", header->Retention);
|
||||
DPRINT("EndHeaderSize = %lu\n", header->EndHeaderSize);
|
||||
DPRINT("Flags: ");
|
||||
if (header->Flags & ELF_LOGFILE_HEADER_DIRTY) DPRINT("ELF_LOGFILE_HEADER_DIRTY");
|
||||
if (header->Flags & ELF_LOGFILE_HEADER_WRAP) DPRINT("| ELF_LOGFILE_HEADER_WRAP ");
|
||||
if (header->Flags & ELF_LOGFILE_LOGFULL_WRITTEN) DPRINT("| ELF_LOGFILE_LOGFULL_WRITTEN ");
|
||||
if (header->Flags & ELF_LOGFILE_ARCHIVE_SET) DPRINT("| ELF_LOGFILE_ARCHIVE_SET ");
|
||||
if (Flags & ELF_LOGFILE_HEADER_DIRTY)
|
||||
{
|
||||
DPRINT("ELF_LOGFILE_HEADER_DIRTY");
|
||||
Flags &= ~ELF_LOGFILE_HEADER_DIRTY;
|
||||
}
|
||||
if (Flags) DPRINT(" | ");
|
||||
if (Flags & ELF_LOGFILE_HEADER_WRAP)
|
||||
{
|
||||
DPRINT("ELF_LOGFILE_HEADER_WRAP");
|
||||
Flags &= ~ELF_LOGFILE_HEADER_WRAP;
|
||||
}
|
||||
if (Flags) DPRINT(" | ");
|
||||
if (Flags & ELF_LOGFILE_LOGFULL_WRITTEN)
|
||||
{
|
||||
DPRINT("ELF_LOGFILE_LOGFULL_WRITTEN");
|
||||
Flags &= ~ELF_LOGFILE_LOGFULL_WRITTEN;
|
||||
}
|
||||
if (Flags) DPRINT(" | ");
|
||||
if (Flags & ELF_LOGFILE_ARCHIVE_SET)
|
||||
{
|
||||
DPRINT("ELF_LOGFILE_ARCHIVE_SET");
|
||||
Flags &= ~ELF_LOGFILE_ARCHIVE_SET;
|
||||
}
|
||||
if (Flags) DPRINT(" | 0x%x", Flags);
|
||||
DPRINT("\n");
|
||||
}
|
||||
|
||||
|
@ -551,21 +590,24 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
|||
{
|
||||
UINT i;
|
||||
WCHAR *str;
|
||||
SYSTEMTIME time;
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS Time;
|
||||
|
||||
DPRINT("Length = %lu\n", pRec->Length);
|
||||
DPRINT("Reserved = 0x%x\n", pRec->Reserved);
|
||||
DPRINT("RecordNumber = %lu\n", pRec->RecordNumber);
|
||||
|
||||
EventTimeToSystemTime(pRec->TimeGenerated, &time);
|
||||
RtlSecondsSince1970ToTime(pRec->TimeGenerated, &SystemTime);
|
||||
RtlTimeToTimeFields(&SystemTime, &Time);
|
||||
DPRINT("TimeGenerated = %hu.%hu.%hu %hu:%hu:%hu\n",
|
||||
time.wDay, time.wMonth, time.wYear,
|
||||
time.wHour, time.wMinute, time.wSecond);
|
||||
Time.Day, Time.Month, Time.Year,
|
||||
Time.Hour, Time.Minute, Time.Second);
|
||||
|
||||
EventTimeToSystemTime(pRec->TimeWritten, &time);
|
||||
RtlSecondsSince1970ToTime(pRec->TimeWritten, &SystemTime);
|
||||
RtlTimeToTimeFields(&SystemTime, &Time);
|
||||
DPRINT("TimeWritten = %hu.%hu.%hu %hu:%hu:%hu\n",
|
||||
time.wDay, time.wMonth, time.wYear,
|
||||
time.wHour, time.wMinute, time.wSecond);
|
||||
Time.Day, Time.Month, Time.Year,
|
||||
Time.Hour, Time.Minute, Time.Second);
|
||||
|
||||
DPRINT("EventID = %lu\n", pRec->EventID);
|
||||
|
||||
|
@ -600,17 +642,17 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
|||
DPRINT("DataLength = %lu\n", pRec->DataLength);
|
||||
DPRINT("DataOffset = %lu\n", pRec->DataOffset);
|
||||
|
||||
DPRINT("SourceName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD)));
|
||||
DPRINT("SourceName: %S\n", (WCHAR *) ((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD)));
|
||||
|
||||
i = (lstrlenW((WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD))) + 1) *
|
||||
i = (lstrlenW((WCHAR *) ((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD))) + 1) *
|
||||
sizeof(WCHAR);
|
||||
|
||||
DPRINT("ComputerName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD) + i));
|
||||
DPRINT("ComputerName: %S\n", (WCHAR *) ((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD) + i));
|
||||
|
||||
if (pRec->StringOffset < pRec->Length && pRec->NumStrings)
|
||||
{
|
||||
DPRINT("Strings:\n");
|
||||
str = (WCHAR *) (((PBYTE) pRec) + pRec->StringOffset);
|
||||
str = (WCHAR *) ((ULONG_PTR)pRec + pRec->StringOffset);
|
||||
for (i = 0; i < pRec->NumStrings; i++)
|
||||
{
|
||||
DPRINT("[%u] %S\n", i, str);
|
||||
|
@ -618,5 +660,5 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
|||
}
|
||||
}
|
||||
|
||||
DPRINT("Length2 = %lu\n", *(PDWORD) (((PBYTE) pRec) + pRec->Length - 4));
|
||||
DPRINT("Length2 = %lu\n", *(PDWORD) ((ULONG_PTR)pRec + pRec->Length - 4));
|
||||
}
|
||||
|
|
|
@ -11,12 +11,18 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
/* PSDK/NDK Headers */
|
||||
#define WIN32_NO_STATUS
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include <ndk/obfuncs.h>
|
||||
|
||||
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
|
||||
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
|
||||
|
||||
#include <eventlogrpc_s.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
|
@ -26,21 +32,21 @@ typedef struct _IO_ERROR_LPC
|
|||
IO_ERROR_LOG_MESSAGE Message;
|
||||
} IO_ERROR_LPC, *PIO_ERROR_LPC;
|
||||
|
||||
#define MAJORVER 1
|
||||
#define MINORVER 1
|
||||
|
||||
/*
|
||||
* Our file format will be compatible with NT's
|
||||
*/
|
||||
#define MAJORVER 1
|
||||
#define MINORVER 1
|
||||
#define LOGFILE_SIGNATURE 0x654c664c
|
||||
|
||||
/*
|
||||
* Flags used in logfile header
|
||||
*/
|
||||
#define ELF_LOGFILE_HEADER_DIRTY 1
|
||||
#define ELF_LOGFILE_HEADER_WRAP 2
|
||||
#define ELF_LOGFILE_HEADER_DIRTY 1
|
||||
#define ELF_LOGFILE_HEADER_WRAP 2
|
||||
#define ELF_LOGFILE_LOGFULL_WRITTEN 4
|
||||
#define ELF_LOGFILE_ARCHIVE_SET 8
|
||||
#define ELF_LOGFILE_ARCHIVE_SET 8
|
||||
|
||||
/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
|
||||
typedef struct _EVENTLOGHEADER
|
||||
|
@ -114,22 +120,38 @@ typedef struct _LOGHANDLE
|
|||
WCHAR szName[1];
|
||||
} LOGHANDLE, *PLOGHANDLE;
|
||||
|
||||
|
||||
/* eventlog.c */
|
||||
extern HANDLE MyHeap;
|
||||
extern PEVENTSOURCE EventLogSource;
|
||||
|
||||
VOID PRINT_HEADER(PEVENTLOGHEADER header);
|
||||
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
|
||||
|
||||
|
||||
/* eventsource.c */
|
||||
VOID InitEventSourceList(VOID);
|
||||
|
||||
BOOL
|
||||
LoadEventSources(HKEY hKey,
|
||||
PLOGFILE pLogFile);
|
||||
|
||||
PEVENTSOURCE
|
||||
GetEventSourceByName(LPCWSTR Name);
|
||||
|
||||
|
||||
/* file.c */
|
||||
VOID LogfListInitialize(VOID);
|
||||
|
||||
PLOGFILE LogfListHead(VOID);
|
||||
DWORD LogfListItemCount(VOID);
|
||||
|
||||
INT LogfListItemCount(VOID);
|
||||
PLOGFILE LogfListItemByIndex(DWORD Index);
|
||||
|
||||
PLOGFILE LogfListItemByIndex(INT Index);
|
||||
PLOGFILE LogfListItemByName(LPCWSTR Name);
|
||||
|
||||
PLOGFILE LogfListItemByName(WCHAR * Name);
|
||||
// DWORD LogfListItemIndexByName(WCHAR * Name);
|
||||
|
||||
INT LogfListItemIndexByName(WCHAR * Name);
|
||||
|
||||
VOID LogfListAddItem(PLOGFILE Item);
|
||||
|
||||
VOID LogfListRemoveItem(PLOGFILE Item);
|
||||
|
||||
DWORD LogfReadEvent(PLOGFILE LogFile,
|
||||
DWORD Flags,
|
||||
|
@ -171,61 +193,34 @@ DWORD LogfGetOldestRecord(PLOGFILE LogFile);
|
|||
|
||||
DWORD LogfGetCurrentRecord(PLOGFILE LogFile);
|
||||
|
||||
ULONG LogfOffsetByNumber(PLOGFILE LogFile,
|
||||
DWORD RecordNumber);
|
||||
PBYTE
|
||||
LogfAllocAndBuildNewRecord(PULONG lpRecSize,
|
||||
ULONG dwRecordNumber, // FIXME!
|
||||
USHORT wType,
|
||||
USHORT wCategory,
|
||||
ULONG dwEventId,
|
||||
PCWSTR SourceName,
|
||||
PCWSTR ComputerName,
|
||||
ULONG dwSidLength,
|
||||
PSID lpUserSid,
|
||||
USHORT wNumStrings,
|
||||
WCHAR* lpStrings,
|
||||
ULONG dwDataSize,
|
||||
PVOID lpRawData);
|
||||
|
||||
BOOL LogfAddOffsetInformation(PLOGFILE LogFile,
|
||||
ULONG ulNumber,
|
||||
ULONG ulOffset);
|
||||
|
||||
BOOL LogfDeleteOffsetInformation(PLOGFILE LogFile,
|
||||
ULONG ulNumber);
|
||||
|
||||
PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
|
||||
DWORD dwRecordNumber,
|
||||
WORD wType,
|
||||
WORD wCategory,
|
||||
DWORD dwEventId,
|
||||
LPCWSTR SourceName,
|
||||
LPCWSTR ComputerName,
|
||||
DWORD dwSidLength,
|
||||
PSID lpUserSid,
|
||||
WORD wNumStrings,
|
||||
WCHAR * lpStrings,
|
||||
DWORD dwDataSize,
|
||||
LPVOID lpRawData);
|
||||
static __inline void LogfFreeRecord(LPVOID Rec)
|
||||
{
|
||||
HeapFree(MyHeap, 0, Rec);
|
||||
}
|
||||
|
||||
VOID
|
||||
LogfReportEvent(WORD wType,
|
||||
WORD wCategory,
|
||||
DWORD dwEventId,
|
||||
WORD wNumStrings,
|
||||
WCHAR *lpStrings,
|
||||
DWORD dwDataSize,
|
||||
LPVOID lpRawData);
|
||||
|
||||
/* eventlog.c */
|
||||
extern HANDLE MyHeap;
|
||||
|
||||
VOID PRINT_HEADER(PEVENTLOGHEADER header);
|
||||
|
||||
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
|
||||
|
||||
VOID EventTimeToSystemTime(DWORD EventTime,
|
||||
SYSTEMTIME * SystemTime);
|
||||
|
||||
VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime,
|
||||
DWORD * pEventTime);
|
||||
|
||||
/* eventsource.c */
|
||||
VOID InitEventSourceList(VOID);
|
||||
|
||||
BOOL
|
||||
LoadEventSources(HKEY hKey,
|
||||
PLOGFILE pLogFile);
|
||||
|
||||
PEVENTSOURCE
|
||||
GetEventSourceByName(LPCWSTR Name);
|
||||
LogfReportEvent(USHORT wType,
|
||||
USHORT wCategory,
|
||||
ULONG dwEventId,
|
||||
USHORT wNumStrings,
|
||||
WCHAR* lpStrings,
|
||||
ULONG dwDataSize,
|
||||
PVOID lpRawData);
|
||||
|
||||
|
||||
/* logport.c */
|
||||
|
@ -238,9 +233,4 @@ NTSTATUS ProcessPortMessage(VOID);
|
|||
/* rpc.c */
|
||||
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter);
|
||||
|
||||
static __inline void LogfFreeRecord(LPVOID Rec)
|
||||
{
|
||||
HeapFree(MyHeap, 0, Rec);
|
||||
}
|
||||
|
||||
#endif /* __EVENTLOG_H__ */
|
||||
|
|
|
@ -70,7 +70,7 @@ LoadEventSources(HKEY hKey,
|
|||
NULL, NULL, NULL, NULL, NULL);
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
|
||||
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -81,12 +81,11 @@ LoadEventSources(HKEY hKey,
|
|||
Buf = HeapAlloc(MyHeap, 0, dwMaxSubKeyLength * sizeof(WCHAR));
|
||||
if (!Buf)
|
||||
{
|
||||
DPRINT1("Error: can't allocate heap!\n");
|
||||
DPRINT1("Error: cannot allocate heap!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dwEventSourceNameLength = dwMaxSubKeyLength;
|
||||
|
||||
dwIndex = 0;
|
||||
while (RegEnumKeyExW(hKey,
|
||||
dwIndex,
|
||||
|
@ -127,7 +126,7 @@ PEVENTSOURCE
|
|||
GetEventSourceByName(LPCWSTR Name)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PEVENTSOURCE Result = NULL;
|
||||
PEVENTSOURCE Item, Result = NULL;
|
||||
|
||||
DPRINT("GetEventSourceByName(%S)\n", Name);
|
||||
EnterCriticalSection(&EventSourceListCs);
|
||||
|
@ -135,9 +134,9 @@ GetEventSourceByName(LPCWSTR Name)
|
|||
CurrentEntry = EventSourceListHead.Flink;
|
||||
while (CurrentEntry != &EventSourceListHead)
|
||||
{
|
||||
PEVENTSOURCE Item = CONTAINING_RECORD(CurrentEntry,
|
||||
EVENTSOURCE,
|
||||
EventSourceListEntry);
|
||||
Item = CONTAINING_RECORD(CurrentEntry,
|
||||
EVENTSOURCE,
|
||||
EventSourceListEntry);
|
||||
|
||||
DPRINT("Item->szName: %S\n", Item->szName);
|
||||
// if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))
|
||||
|
|
|
@ -4,24 +4,253 @@
|
|||
* FILE: base/services/eventlog/file.c
|
||||
* PURPOSE: Event logging service
|
||||
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
|
||||
Michael Martin
|
||||
* Michael Martin
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "eventlog.h"
|
||||
|
||||
#include <ndk/iofuncs.h>
|
||||
#include <ndk/kefuncs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
/* LOG FILE LIST - GLOBALS ***************************************************/
|
||||
|
||||
static LIST_ENTRY LogFileListHead;
|
||||
static CRITICAL_SECTION LogFileListCs;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
/* LOG FILE LIST - FUNCTIONS *************************************************/
|
||||
|
||||
VOID LogfCloseAll(VOID)
|
||||
{
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
while (!IsListEmpty(&LogFileListHead))
|
||||
{
|
||||
LogfClose(CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry), TRUE);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
|
||||
DeleteCriticalSection(&LogFileListCs);
|
||||
}
|
||||
|
||||
VOID LogfListInitialize(VOID)
|
||||
{
|
||||
InitializeCriticalSection(&LogFileListCs);
|
||||
InitializeListHead(&LogFileListHead);
|
||||
}
|
||||
|
||||
PLOGFILE LogfListItemByName(LPCWSTR Name)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLOGFILE Item, Result = NULL;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
Item = CONTAINING_RECORD(CurrentEntry,
|
||||
LOGFILE,
|
||||
ListEntry);
|
||||
|
||||
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
|
||||
{
|
||||
Result = Item;
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return Result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Index starting from 1 */
|
||||
DWORD LogfListItemIndexByName(WCHAR * Name)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
DWORD Result = 0;
|
||||
DWORD i = 1;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
|
||||
LOGFILE,
|
||||
ListEntry);
|
||||
|
||||
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
|
||||
{
|
||||
Result = i;
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return Result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Index starting from 1 */
|
||||
PLOGFILE LogfListItemByIndex(DWORD Index)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLOGFILE Result = NULL;
|
||||
DWORD i = 1;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
if (i == Index)
|
||||
{
|
||||
Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return Result;
|
||||
}
|
||||
|
||||
DWORD LogfListItemCount(VOID)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
DWORD i = 0;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return i;
|
||||
}
|
||||
|
||||
static VOID
|
||||
LogfListAddItem(PLOGFILE Item)
|
||||
{
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
InsertTailList(&LogFileListHead, &Item->ListEntry);
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
}
|
||||
|
||||
static VOID
|
||||
LogfListRemoveItem(PLOGFILE Item)
|
||||
{
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
RemoveEntryList(&Item->ListEntry);
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
}
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/* Returns 0 if nothing is found */
|
||||
static ULONG
|
||||
LogfOffsetByNumber(PLOGFILE LogFile,
|
||||
DWORD RecordNumber)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < LogFile->OffsetInfoNext; i++)
|
||||
{
|
||||
if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
|
||||
return LogFile->OffsetInfo[i].EventOffset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD LogfGetOldestRecord(PLOGFILE LogFile)
|
||||
{
|
||||
return LogFile->Header.OldestRecordNumber;
|
||||
}
|
||||
|
||||
DWORD LogfGetCurrentRecord(PLOGFILE LogFile)
|
||||
{
|
||||
return LogFile->Header.CurrentRecordNumber;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
LogfAddOffsetInformation(PLOGFILE LogFile,
|
||||
ULONG ulNumber,
|
||||
ULONG ulOffset)
|
||||
{
|
||||
LPVOID NewOffsetInfo;
|
||||
|
||||
if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
|
||||
{
|
||||
NewOffsetInfo = HeapReAlloc(MyHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
LogFile->OffsetInfo,
|
||||
(LogFile->OffsetInfoSize + 64) *
|
||||
sizeof(EVENT_OFFSET_INFO));
|
||||
|
||||
if (!NewOffsetInfo)
|
||||
{
|
||||
DPRINT1("Cannot reallocate heap.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LogFile->OffsetInfo = (PEVENT_OFFSET_INFO)NewOffsetInfo;
|
||||
LogFile->OffsetInfoSize += 64;
|
||||
}
|
||||
|
||||
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
|
||||
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
|
||||
LogFile->OffsetInfoNext++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
LogfDeleteOffsetInformation(PLOGFILE LogFile,
|
||||
ULONG ulNumber)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
/*
|
||||
* As the offset information is listed in increasing order, and we want
|
||||
* to keep the list without holes, we demand that ulNumber is the first
|
||||
* element in the list.
|
||||
*/
|
||||
if (ulNumber != LogFile->OffsetInfo[0].EventNumber)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* RtlMoveMemory(&LogFile->OffsetInfo[0],
|
||||
* &LogFile->OffsetInfo[1],
|
||||
* sizeof(EVENT_OFFSET_INFO) * (LogFile->OffsetInfoNext - 1));
|
||||
*/
|
||||
for (i = 0; i < LogFile->OffsetInfoNext - 1; i++)
|
||||
{
|
||||
LogFile->OffsetInfo[i].EventNumber = LogFile->OffsetInfo[i + 1].EventNumber;
|
||||
LogFile->OffsetInfo[i].EventOffset = LogFile->OffsetInfo[i + 1].EventOffset;
|
||||
}
|
||||
LogFile->OffsetInfoNext--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
LogfInitializeNew(PLOGFILE LogFile,
|
||||
|
@ -466,141 +695,6 @@ LogfClose(PLOGFILE LogFile,
|
|||
return;
|
||||
}
|
||||
|
||||
VOID LogfCloseAll(VOID)
|
||||
{
|
||||
while (!IsListEmpty(&LogFileListHead))
|
||||
{
|
||||
LogfClose(LogfListHead(), TRUE);
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&LogFileListCs);
|
||||
}
|
||||
|
||||
VOID LogfListInitialize(VOID)
|
||||
{
|
||||
InitializeCriticalSection(&LogFileListCs);
|
||||
InitializeListHead(&LogFileListHead);
|
||||
}
|
||||
|
||||
PLOGFILE LogfListHead(VOID)
|
||||
{
|
||||
return CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry);
|
||||
}
|
||||
|
||||
PLOGFILE LogfListItemByName(WCHAR * Name)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLOGFILE Result = NULL;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
|
||||
LOGFILE,
|
||||
ListEntry);
|
||||
|
||||
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
|
||||
{
|
||||
Result = Item;
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* Index starting from 1 */
|
||||
INT LogfListItemIndexByName(WCHAR * Name)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
INT Result = 0;
|
||||
INT i = 1;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
|
||||
LOGFILE,
|
||||
ListEntry);
|
||||
|
||||
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
|
||||
{
|
||||
Result = i;
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* Index starting from 1 */
|
||||
PLOGFILE LogfListItemByIndex(INT Index)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLOGFILE Result = NULL;
|
||||
INT i = 1;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
if (i == Index)
|
||||
{
|
||||
Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return Result;
|
||||
}
|
||||
|
||||
INT LogfListItemCount(VOID)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
INT i = 0;
|
||||
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
|
||||
CurrentEntry = LogFileListHead.Flink;
|
||||
while (CurrentEntry != &LogFileListHead)
|
||||
{
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
i++;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
return i;
|
||||
}
|
||||
|
||||
VOID LogfListAddItem(PLOGFILE Item)
|
||||
{
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
InsertTailList(&LogFileListHead, &Item->ListEntry);
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
}
|
||||
|
||||
VOID LogfListRemoveItem(PLOGFILE Item)
|
||||
{
|
||||
EnterCriticalSection(&LogFileListCs);
|
||||
RemoveEntryList(&Item->ListEntry);
|
||||
LeaveCriticalSection(&LogFileListCs);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ReadAnsiLogEntry(HANDLE hFile,
|
||||
|
@ -930,7 +1024,7 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
|
|||
{
|
||||
DWORD dwWritten;
|
||||
DWORD dwRead;
|
||||
SYSTEMTIME st;
|
||||
LARGE_INTEGER SystemTime;
|
||||
EVENTLOGEOF EofRec;
|
||||
PEVENTLOGRECORD RecBuf;
|
||||
LARGE_INTEGER logFileSize;
|
||||
|
@ -940,11 +1034,11 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
|
|||
if (!Buffer)
|
||||
return FALSE;
|
||||
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);
|
||||
|
||||
RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
|
||||
|
||||
NtQuerySystemTime(&SystemTime);
|
||||
RtlTimeToSecondsSince1970(&SystemTime, &((PEVENTLOGRECORD)Buffer)->TimeWritten);
|
||||
|
||||
if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
|
||||
{
|
||||
RtlReleaseResource(&LogFile->Lock);
|
||||
|
@ -1111,7 +1205,6 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
LogfClearFile(PLOGFILE LogFile,
|
||||
PUNICODE_STRING BackupFileName)
|
||||
|
@ -1123,12 +1216,11 @@ LogfClearFile(PLOGFILE LogFile,
|
|||
if (BackupFileName->Length > 0)
|
||||
{
|
||||
/* Write a backup file */
|
||||
Status = LogfBackupFile(LogFile,
|
||||
BackupFileName);
|
||||
Status = LogfBackupFile(LogFile, BackupFileName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("LogfBackupFile failed (Status: 0x%08lx)\n", Status);
|
||||
return Status;
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1140,12 +1232,11 @@ LogfClearFile(PLOGFILE LogFile,
|
|||
DPRINT1("LogfInitializeNew failed (Status: 0x%08lx)\n", Status);
|
||||
}
|
||||
|
||||
Quit:
|
||||
RtlReleaseResource(&LogFile->Lock);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
LogfBackupFile(PLOGFILE LogFile,
|
||||
PUNICODE_STRING BackupFileName)
|
||||
|
@ -1347,134 +1438,84 @@ Done:
|
|||
}
|
||||
|
||||
|
||||
/* Returns 0 if nothing found. */
|
||||
ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < LogFile->OffsetInfoNext; i++)
|
||||
{
|
||||
if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
|
||||
return LogFile->OffsetInfo[i].EventOffset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD LogfGetOldestRecord(PLOGFILE LogFile)
|
||||
{
|
||||
return LogFile->Header.OldestRecordNumber;
|
||||
}
|
||||
|
||||
DWORD LogfGetCurrentRecord(PLOGFILE LogFile)
|
||||
{
|
||||
return LogFile->Header.CurrentRecordNumber;
|
||||
}
|
||||
|
||||
BOOL LogfDeleteOffsetInformation(PLOGFILE LogFile, ULONG ulNumber)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if (ulNumber != LogFile->OffsetInfo[0].EventNumber)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < LogFile->OffsetInfoNext - 1; i++)
|
||||
{
|
||||
LogFile->OffsetInfo[i].EventNumber = LogFile->OffsetInfo[i + 1].EventNumber;
|
||||
LogFile->OffsetInfo[i].EventOffset = LogFile->OffsetInfo[i + 1].EventOffset;
|
||||
}
|
||||
LogFile->OffsetInfoNext--;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LogfAddOffsetInformation(PLOGFILE LogFile, ULONG ulNumber, ULONG ulOffset)
|
||||
{
|
||||
LPVOID NewOffsetInfo;
|
||||
|
||||
if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
|
||||
{
|
||||
NewOffsetInfo = HeapReAlloc(MyHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
LogFile->OffsetInfo,
|
||||
(LogFile->OffsetInfoSize + 64) *
|
||||
sizeof(EVENT_OFFSET_INFO));
|
||||
|
||||
if (!NewOffsetInfo)
|
||||
{
|
||||
DPRINT1("Can't reallocate heap.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) NewOffsetInfo;
|
||||
LogFile->OffsetInfoSize += 64;
|
||||
}
|
||||
|
||||
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
|
||||
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
|
||||
LogFile->OffsetInfoNext++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
|
||||
DWORD dwRecordNumber,
|
||||
WORD wType,
|
||||
WORD wCategory,
|
||||
DWORD dwEventId,
|
||||
LPCWSTR SourceName,
|
||||
LPCWSTR ComputerName,
|
||||
DWORD dwSidLength,
|
||||
PSID lpUserSid,
|
||||
WORD wNumStrings,
|
||||
WCHAR * lpStrings,
|
||||
DWORD dwDataSize,
|
||||
LPVOID lpRawData)
|
||||
PBYTE
|
||||
LogfAllocAndBuildNewRecord(PULONG lpRecSize,
|
||||
ULONG dwRecordNumber, // FIXME!
|
||||
USHORT wType,
|
||||
USHORT wCategory,
|
||||
ULONG dwEventId,
|
||||
PCWSTR SourceName,
|
||||
PCWSTR ComputerName,
|
||||
ULONG dwSidLength,
|
||||
PSID lpUserSid,
|
||||
USHORT wNumStrings,
|
||||
WCHAR* lpStrings,
|
||||
ULONG dwDataSize,
|
||||
PVOID lpRawData)
|
||||
{
|
||||
DWORD dwRecSize;
|
||||
PEVENTLOGRECORD pRec;
|
||||
SYSTEMTIME SysTime;
|
||||
LARGE_INTEGER SystemTime;
|
||||
WCHAR *str;
|
||||
UINT i, pos;
|
||||
PBYTE Buffer;
|
||||
|
||||
dwRecSize =
|
||||
sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) +
|
||||
lstrlenW(SourceName) + 2) * sizeof(WCHAR);
|
||||
sizeof(EVENTLOGRECORD) + (lstrlenW(SourceName) +
|
||||
lstrlenW(ComputerName) + 2) * sizeof(WCHAR);
|
||||
|
||||
if (dwRecSize % 4 != 0)
|
||||
dwRecSize += 4 - (dwRecSize % 4);
|
||||
/* Align on DWORD boundary for the SID */
|
||||
dwRecSize = ROUND_UP(dwRecSize, sizeof(ULONG));
|
||||
|
||||
dwRecSize += dwSidLength;
|
||||
|
||||
/* Add the sizes for the strings array */
|
||||
for (i = 0, str = lpStrings; i < wNumStrings; i++)
|
||||
{
|
||||
dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||
str += lstrlenW(str) + 1;
|
||||
}
|
||||
|
||||
/* Add the data size */
|
||||
dwRecSize += dwDataSize;
|
||||
if (dwRecSize % 4 != 0)
|
||||
dwRecSize += 4 - (dwRecSize % 4);
|
||||
|
||||
dwRecSize += 4;
|
||||
/* Align on DWORD boundary for the full structure */
|
||||
dwRecSize = ROUND_UP(dwRecSize, sizeof(ULONG));
|
||||
|
||||
/* Size of the trailing 'Length' member */
|
||||
dwRecSize += sizeof(ULONG);
|
||||
|
||||
Buffer = HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, dwRecSize);
|
||||
|
||||
if (!Buffer)
|
||||
{
|
||||
DPRINT1("Can't allocate heap!\n");
|
||||
DPRINT1("Cannot allocate heap!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRec = (PEVENTLOGRECORD) Buffer;
|
||||
pRec = (PEVENTLOGRECORD)Buffer;
|
||||
pRec->Length = dwRecSize;
|
||||
pRec->Reserved = LOGFILE_SIGNATURE;
|
||||
|
||||
// FIXME: The problem with this technique is that it is possible
|
||||
// to allocate different records with the same number. Suppose that
|
||||
// two concurrent events writes happen for the same log, and the
|
||||
// execution goes inside this function. The callers of this function
|
||||
// have normally retrieved the 'CurrentRecordNumber' of this log, where
|
||||
// the access to the log was non locked and no write operation happened
|
||||
// in between. Then we have two different records for the same log with
|
||||
// the very same record number, that will be written later. It is only in
|
||||
// 'LogfWriteRecord' that the 'CurrentRecordNumber' is incremented!!
|
||||
//
|
||||
// Therefore we need to rewrite those functions. This function must
|
||||
// not take any "precomputed" record number. It should attribute a new
|
||||
// record number under lock, and then increment it atomically, so that
|
||||
// all event records have unique record numbers.
|
||||
pRec->RecordNumber = dwRecordNumber;
|
||||
|
||||
GetSystemTime(&SysTime);
|
||||
SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
|
||||
SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);
|
||||
NtQuerySystemTime(&SystemTime);
|
||||
RtlTimeToSecondsSince1970(&SystemTime, &pRec->TimeGenerated);
|
||||
// FIXME: Already done in LogfWriteRecord. Is it needed to do that here first??
|
||||
RtlTimeToSecondsSince1970(&SystemTime, &pRec->TimeWritten);
|
||||
|
||||
pRec->EventID = dwEventId;
|
||||
pRec->EventType = wType;
|
||||
|
@ -1487,11 +1528,10 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
|
|||
lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
|
||||
pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
|
||||
|
||||
/* Align on DWORD boundary for the SID */
|
||||
pos = ROUND_UP(pos, sizeof(ULONG));
|
||||
|
||||
pRec->UserSidOffset = pos;
|
||||
|
||||
if (pos % 4 != 0)
|
||||
pos += 4 - (pos % 4);
|
||||
|
||||
if (dwSidLength)
|
||||
{
|
||||
CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
|
||||
|
@ -1517,53 +1557,49 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
|
|||
pos += dwDataSize;
|
||||
}
|
||||
|
||||
if (pos % 4 != 0)
|
||||
pos += 4 - (pos % 4);
|
||||
/* Align on DWORD boundary for the full structure */
|
||||
pos = ROUND_UP(pos, sizeof(ULONG));
|
||||
|
||||
/* Initialize the trailing 'Length' member */
|
||||
*((PDWORD) (Buffer + pos)) = dwRecSize;
|
||||
|
||||
*lpRecSize = dwRecSize;
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
LogfReportEvent(WORD wType,
|
||||
WORD wCategory,
|
||||
DWORD dwEventId,
|
||||
WORD wNumStrings,
|
||||
WCHAR *lpStrings,
|
||||
DWORD dwDataSize,
|
||||
LPVOID lpRawData)
|
||||
LogfReportEvent(USHORT wType,
|
||||
USHORT wCategory,
|
||||
ULONG dwEventId,
|
||||
USHORT wNumStrings,
|
||||
WCHAR* lpStrings,
|
||||
ULONG dwDataSize,
|
||||
PVOID lpRawData)
|
||||
{
|
||||
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
PEVENTSOURCE pEventSource = NULL;
|
||||
PBYTE logBuffer;
|
||||
DWORD lastRec;
|
||||
DWORD recSize;
|
||||
DWORD dwError;
|
||||
|
||||
if (!EventLogSource)
|
||||
return;
|
||||
|
||||
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
|
||||
{
|
||||
szComputerName[0] = 0;
|
||||
szComputerName[0] = L'\0';
|
||||
}
|
||||
|
||||
pEventSource = GetEventSourceByName(L"EventLog");
|
||||
if (pEventSource == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastRec = LogfGetCurrentRecord(pEventSource->LogFile);
|
||||
lastRec = LogfGetCurrentRecord(EventLogSource->LogFile);
|
||||
|
||||
logBuffer = LogfAllocAndBuildNewRecord(&recSize,
|
||||
lastRec,
|
||||
lastRec, // FIXME!
|
||||
wType,
|
||||
wCategory,
|
||||
dwEventId,
|
||||
pEventSource->szName,
|
||||
(LPCWSTR)szComputerName,
|
||||
EventLogSource->szName,
|
||||
szComputerName,
|
||||
0,
|
||||
NULL,
|
||||
wNumStrings,
|
||||
|
@ -1571,10 +1607,10 @@ LogfReportEvent(WORD wType,
|
|||
dwDataSize,
|
||||
lpRawData);
|
||||
|
||||
dwError = LogfWriteData(pEventSource->LogFile, recSize, logBuffer);
|
||||
dwError = LogfWriteData(EventLogSource->LogFile, recSize, logBuffer);
|
||||
if (!dwError)
|
||||
{
|
||||
DPRINT1("ERROR WRITING TO EventLog %S\n", pEventSource->LogFile->FileName);
|
||||
DPRINT1("ERROR WRITING TO EventLog %S\n", EventLogSource->LogFile->FileName);
|
||||
}
|
||||
|
||||
LogfFreeRecord(logBuffer);
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
HANDLE ConnectPortHandle = NULL;
|
||||
HANDLE MessagePortHandle = NULL;
|
||||
static HANDLE ConnectPortHandle = NULL;
|
||||
static HANDLE MessagePortHandle = NULL;
|
||||
extern BOOL onLiveCD;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
@ -70,7 +70,6 @@ NTSTATUS InitLogPort(VOID)
|
|||
}
|
||||
|
||||
Status = NtListenPort(ConnectPortHandle, &Request);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
|
||||
|
@ -79,7 +78,6 @@ NTSTATUS InitLogPort(VOID)
|
|||
|
||||
Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle,
|
||||
NULL, TRUE, NULL, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
|
||||
|
@ -93,7 +91,7 @@ NTSTATUS InitLogPort(VOID)
|
|||
goto ByeBye;
|
||||
}
|
||||
|
||||
ByeBye:
|
||||
ByeBye:
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (ConnectPortHandle != NULL)
|
||||
|
@ -114,6 +112,8 @@ NTSTATUS ProcessPortMessage(VOID)
|
|||
DWORD dwRecSize;
|
||||
NTSTATUS Status;
|
||||
PLOGFILE SystemLog = NULL;
|
||||
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
|
||||
DPRINT("ProcessPortMessage() called\n");
|
||||
|
||||
|
@ -150,18 +150,27 @@ NTSTATUS ProcessPortMessage(VOID)
|
|||
Message = (PIO_ERROR_LOG_MESSAGE) & Request.Message;
|
||||
ulRecNum = SystemLog ? SystemLog->Header.CurrentRecordNumber : 0;
|
||||
|
||||
pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(&dwRecSize,
|
||||
ulRecNum, Message->Type, Message->EntryData.EventCategory,
|
||||
Message->EntryData.ErrorCode,
|
||||
(WCHAR *) (((PBYTE) Message) + Message->DriverNameOffset),
|
||||
L"MyComputer", /* FIXME */
|
||||
0,
|
||||
NULL,
|
||||
Message->EntryData.NumberOfStrings,
|
||||
(WCHAR *) (((PBYTE) Message) + Message->EntryData.StringOffset),
|
||||
Message->EntryData.DumpDataSize,
|
||||
(LPVOID) (((PBYTE) Message) + sizeof(IO_ERROR_LOG_PACKET) -
|
||||
sizeof(ULONG)));
|
||||
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
|
||||
{
|
||||
szComputerName[0] = L'\0';
|
||||
}
|
||||
|
||||
// TODO: Log more information??
|
||||
|
||||
pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(
|
||||
&dwRecSize,
|
||||
ulRecNum, // FIXME!
|
||||
Message->Type,
|
||||
Message->EntryData.EventCategory,
|
||||
Message->EntryData.ErrorCode,
|
||||
(WCHAR *) ((ULONG_PTR)Message + Message->DriverNameOffset), // FIXME: Use DriverNameLength too!
|
||||
szComputerName,
|
||||
0,
|
||||
NULL,
|
||||
Message->EntryData.NumberOfStrings,
|
||||
(WCHAR *) ((ULONG_PTR)Message + Message->EntryData.StringOffset),
|
||||
Message->EntryData.DumpDataSize,
|
||||
(LPVOID) ((ULONG_PTR)Message + FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData)));
|
||||
|
||||
if (pRec == NULL)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* PURPOSE: Event logging service
|
||||
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
|
||||
* Copyright 2008 Michael Martin
|
||||
* Copyright 2010-2011 Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -49,27 +50,31 @@ DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
|
|||
|
||||
|
||||
static NTSTATUS
|
||||
ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
|
||||
LPCWSTR Name,
|
||||
BOOL Create)
|
||||
ElfCreateEventLogHandle(PLOGHANDLE* LogHandle,
|
||||
PUNICODE_STRING LogName,
|
||||
BOOLEAN Create)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PLOGHANDLE lpLogHandle;
|
||||
PLOGFILE currentLogFile = NULL;
|
||||
INT i, LogsActive;
|
||||
DWORD i, LogsActive;
|
||||
PEVENTSOURCE pEventSource;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
|
||||
DPRINT("ElfCreateEventLogHandle(Name: %wZ)\n", LogName);
|
||||
|
||||
lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
|
||||
+ ((wcslen(Name) + 1) * sizeof(WCHAR)));
|
||||
*LogHandle = NULL;
|
||||
|
||||
i = (LogName->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
|
||||
lpLogHandle = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
FIELD_OFFSET(LOGHANDLE, szName[i]));
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
DPRINT1("Failed to allocate Heap!\n");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
wcscpy(lpLogHandle->szName, Name);
|
||||
StringCchCopy(lpLogHandle->szName, i, LogName->Buffer);
|
||||
|
||||
/* Get the number of Log Files the EventLog service found */
|
||||
LogsActive = LogfListItemCount();
|
||||
|
@ -81,9 +86,9 @@ ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
|
|||
}
|
||||
|
||||
/* If Creating, default to the Application Log in case we fail, as documented on MSDN */
|
||||
if (Create == TRUE)
|
||||
if (Create)
|
||||
{
|
||||
pEventSource = GetEventSourceByName(Name);
|
||||
pEventSource = GetEventSourceByName(LogName->Buffer);
|
||||
DPRINT("EventSource: %p\n", pEventSource);
|
||||
if (pEventSource)
|
||||
{
|
||||
|
@ -106,9 +111,9 @@ ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
|
|||
{
|
||||
currentLogFile = LogfListItemByIndex(i);
|
||||
|
||||
if (_wcsicmp(Name, currentLogFile->LogName) == 0)
|
||||
if (_wcsicmp(LogName->Buffer, currentLogFile->LogName) == 0)
|
||||
{
|
||||
lpLogHandle->LogFile = LogfListItemByIndex(i);
|
||||
lpLogHandle->LogFile = currentLogFile;
|
||||
lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
|
||||
break;
|
||||
}
|
||||
|
@ -150,15 +155,16 @@ Done:
|
|||
|
||||
|
||||
static NTSTATUS
|
||||
ElfCreateBackupLogHandle(PLOGHANDLE *LogHandle,
|
||||
ElfCreateBackupLogHandle(PLOGHANDLE* LogHandle,
|
||||
PUNICODE_STRING FileName)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PLOGHANDLE lpLogHandle;
|
||||
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("ElfCreateBackupLogHandle(FileName: %wZ)\n", FileName);
|
||||
|
||||
*LogHandle = NULL;
|
||||
|
||||
lpLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGHANDLE));
|
||||
if (lpLogHandle == NULL)
|
||||
{
|
||||
|
@ -202,7 +208,8 @@ Done:
|
|||
}
|
||||
|
||||
|
||||
PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
||||
static PLOGHANDLE
|
||||
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLOGHANDLE lpLogHandle;
|
||||
|
@ -224,26 +231,28 @@ PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
|||
|
||||
|
||||
static NTSTATUS
|
||||
ElfDeleteEventLogHandle(IELF_HANDLE LogHandle)
|
||||
ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle)
|
||||
{
|
||||
PLOGHANDLE lpLogHandle;
|
||||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(*LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
RemoveEntryList(&lpLogHandle->LogHandleListEntry);
|
||||
LogfClose(lpLogHandle->LogFile, FALSE);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, lpLogHandle);
|
||||
|
||||
*LogHandle = NULL;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Function 0 */
|
||||
NTSTATUS ElfrClearELFW(
|
||||
NTSTATUS
|
||||
ElfrClearELFW(
|
||||
IELF_HANDLE LogHandle,
|
||||
PRPC_UNICODE_STRING BackupFileName)
|
||||
{
|
||||
|
@ -253,9 +262,7 @@ NTSTATUS ElfrClearELFW(
|
|||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Fail, if the log file is a backup file */
|
||||
if (lpLogHandle->Flags & LOG_HANDLE_BACKUP_FILE)
|
||||
|
@ -267,7 +274,8 @@ NTSTATUS ElfrClearELFW(
|
|||
|
||||
|
||||
/* Function 1 */
|
||||
NTSTATUS ElfrBackupELFW(
|
||||
NTSTATUS
|
||||
ElfrBackupELFW(
|
||||
IELF_HANDLE LogHandle,
|
||||
PRPC_UNICODE_STRING BackupFileName)
|
||||
{
|
||||
|
@ -277,9 +285,7 @@ NTSTATUS ElfrBackupELFW(
|
|||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return LogfBackupFile(lpLogHandle->LogFile,
|
||||
(PUNICODE_STRING)BackupFileName);
|
||||
|
@ -287,25 +293,28 @@ NTSTATUS ElfrBackupELFW(
|
|||
|
||||
|
||||
/* Function 2 */
|
||||
NTSTATUS ElfrCloseEL(
|
||||
IELF_HANDLE *LogHandle)
|
||||
NTSTATUS
|
||||
ElfrCloseEL(
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
return ElfDeleteEventLogHandle(*LogHandle);
|
||||
return ElfDeleteEventLogHandle(LogHandle);
|
||||
}
|
||||
|
||||
|
||||
/* Function 3 */
|
||||
NTSTATUS ElfrDeregisterEventSource(
|
||||
IELF_HANDLE *LogHandle)
|
||||
NTSTATUS
|
||||
ElfrDeregisterEventSource(
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
return ElfDeleteEventLogHandle(*LogHandle);
|
||||
return ElfDeleteEventLogHandle(LogHandle);
|
||||
}
|
||||
|
||||
|
||||
/* Function 4 */
|
||||
NTSTATUS ElfrNumberOfRecords(
|
||||
NTSTATUS
|
||||
ElfrNumberOfRecords(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD *NumberOfRecords)
|
||||
PULONG NumberOfRecords)
|
||||
{
|
||||
PLOGHANDLE lpLogHandle;
|
||||
PLOGFILE lpLogFile;
|
||||
|
@ -314,9 +323,10 @@ NTSTATUS ElfrNumberOfRecords(
|
|||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (!NumberOfRecords)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
lpLogFile = lpLogHandle->LogFile;
|
||||
|
||||
|
@ -332,22 +342,19 @@ NTSTATUS ElfrNumberOfRecords(
|
|||
|
||||
|
||||
/* Function 5 */
|
||||
NTSTATUS ElfrOldestRecord(
|
||||
NTSTATUS
|
||||
ElfrOldestRecord(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD *OldestRecordNumber)
|
||||
PULONG OldestRecordNumber)
|
||||
{
|
||||
PLOGHANDLE lpLogHandle;
|
||||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (!OldestRecordNumber)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
|
||||
|
||||
|
@ -356,26 +363,26 @@ NTSTATUS ElfrOldestRecord(
|
|||
|
||||
|
||||
/* Function 6 */
|
||||
NTSTATUS ElfrChangeNotify(
|
||||
NTSTATUS
|
||||
ElfrChangeNotify(
|
||||
IELF_HANDLE LogHandle,
|
||||
RPC_CLIENT_ID ClientId,
|
||||
DWORD Event)
|
||||
ULONG Event)
|
||||
{
|
||||
DPRINT("ElfrChangeNotify()");
|
||||
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* Function 7 */
|
||||
NTSTATUS ElfrOpenELW(
|
||||
NTSTATUS
|
||||
ElfrOpenELW(
|
||||
EVENTLOG_HANDLE_W UNCServerName,
|
||||
PRPC_UNICODE_STRING ModuleName,
|
||||
PRPC_UNICODE_STRING RegModuleName,
|
||||
DWORD MajorVersion,
|
||||
DWORD MinorVersion,
|
||||
IELF_HANDLE *LogHandle)
|
||||
ULONG MajorVersion,
|
||||
ULONG MinorVersion,
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
if ((MajorVersion != 1) || (MinorVersion != 1))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -384,24 +391,25 @@ NTSTATUS ElfrOpenELW(
|
|||
if (RegModuleName->Length > 0)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/*FIXME: UNCServerName must specify the server */
|
||||
/* FIXME: UNCServerName must specify the server */
|
||||
|
||||
/*FIXME: Must verify that caller has read access */
|
||||
/* FIXME: Must verify that caller has read access */
|
||||
|
||||
return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
|
||||
ModuleName->Buffer,
|
||||
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||
(PUNICODE_STRING)ModuleName,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* Function 8 */
|
||||
NTSTATUS ElfrRegisterEventSourceW(
|
||||
NTSTATUS
|
||||
ElfrRegisterEventSourceW(
|
||||
EVENTLOG_HANDLE_W UNCServerName,
|
||||
PRPC_UNICODE_STRING ModuleName,
|
||||
PRPC_UNICODE_STRING RegModuleName,
|
||||
DWORD MajorVersion,
|
||||
DWORD MinorVersion,
|
||||
IELF_HANDLE *LogHandle)
|
||||
ULONG MajorVersion,
|
||||
ULONG MinorVersion,
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
DPRINT("ElfrRegisterEventSourceW()\n");
|
||||
|
||||
|
@ -412,49 +420,51 @@ NTSTATUS ElfrRegisterEventSourceW(
|
|||
if (RegModuleName->Length > 0)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
DPRINT("ModuleName: %S\n", ModuleName->Buffer);
|
||||
DPRINT("ModuleName: %wZ\n", ModuleName);
|
||||
|
||||
/*FIXME: UNCServerName must specify the server or empty for local */
|
||||
/* FIXME: UNCServerName must specify the server or empty for local */
|
||||
|
||||
/*FIXME: Must verify that caller has write access */
|
||||
/* FIXME: Must verify that caller has write access */
|
||||
|
||||
return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
|
||||
ModuleName->Buffer,
|
||||
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||
(PUNICODE_STRING)ModuleName,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* Function 9 */
|
||||
NTSTATUS ElfrOpenBELW(
|
||||
NTSTATUS
|
||||
ElfrOpenBELW(
|
||||
EVENTLOG_HANDLE_W UNCServerName,
|
||||
PRPC_UNICODE_STRING BackupFileName,
|
||||
DWORD MajorVersion,
|
||||
DWORD MinorVersion,
|
||||
IELF_HANDLE *LogHandle)
|
||||
ULONG MajorVersion,
|
||||
ULONG MinorVersion,
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName);
|
||||
|
||||
if ((MajorVersion != 1) || (MinorVersion != 1))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/*FIXME: UNCServerName must specify the server */
|
||||
/* FIXME: UNCServerName must specify the server */
|
||||
|
||||
/*FIXME: Must verify that caller has read access */
|
||||
/* FIXME: Must verify that caller has read access */
|
||||
|
||||
return ElfCreateBackupLogHandle((PLOGHANDLE *)LogHandle,
|
||||
return ElfCreateBackupLogHandle((PLOGHANDLE*)LogHandle,
|
||||
(PUNICODE_STRING)BackupFileName);
|
||||
}
|
||||
|
||||
|
||||
/* Function 10 */
|
||||
NTSTATUS ElfrReadELW(
|
||||
NTSTATUS
|
||||
ElfrReadELW(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD ReadFlags,
|
||||
DWORD RecordOffset,
|
||||
ULONG ReadFlags,
|
||||
ULONG RecordOffset,
|
||||
RULONG NumberOfBytesToRead,
|
||||
BYTE *Buffer,
|
||||
DWORD *NumberOfBytesRead,
|
||||
DWORD *MinNumberOfBytesNeeded)
|
||||
PBYTE Buffer,
|
||||
PULONG NumberOfBytesRead,
|
||||
PULONG MinNumberOfBytesNeeded)
|
||||
{
|
||||
PLOGHANDLE lpLogHandle;
|
||||
DWORD dwError;
|
||||
|
@ -462,9 +472,7 @@ NTSTATUS ElfrReadELW(
|
|||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (!Buffer)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -479,11 +487,16 @@ NTSTATUS ElfrReadELW(
|
|||
RecordNumber = RecordOffset;
|
||||
}
|
||||
|
||||
dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
|
||||
NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded,
|
||||
dwError = LogfReadEvent(lpLogHandle->LogFile,
|
||||
ReadFlags,
|
||||
&RecordNumber,
|
||||
NumberOfBytesToRead,
|
||||
Buffer,
|
||||
NumberOfBytesRead,
|
||||
MinNumberOfBytesNeeded,
|
||||
FALSE);
|
||||
|
||||
/* Update the handles CurrentRecord if success*/
|
||||
/* Update the handle's CurrentRecord if success */
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpLogHandle->CurrentRecord = RecordNumber;
|
||||
|
@ -498,21 +511,22 @@ NTSTATUS ElfrReadELW(
|
|||
|
||||
|
||||
/* Function 11 */
|
||||
NTSTATUS ElfrReportEventW(
|
||||
NTSTATUS
|
||||
ElfrReportEventW(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD Time,
|
||||
ULONG Time,
|
||||
USHORT EventType,
|
||||
USHORT EventCategory,
|
||||
DWORD EventID,
|
||||
ULONG EventID,
|
||||
USHORT NumStrings,
|
||||
DWORD DataSize,
|
||||
ULONG DataSize,
|
||||
PRPC_UNICODE_STRING ComputerName,
|
||||
PRPC_SID UserSID,
|
||||
PRPC_UNICODE_STRING Strings[],
|
||||
BYTE *Data,
|
||||
PBYTE Data,
|
||||
USHORT Flags,
|
||||
DWORD *RecordNumber,
|
||||
DWORD *TimeWritten)
|
||||
PULONG RecordNumber,
|
||||
PULONG TimeWritten)
|
||||
{
|
||||
USHORT i;
|
||||
PBYTE LogBuffer;
|
||||
|
@ -527,15 +541,11 @@ NTSTATUS ElfrReportEventW(
|
|||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Flags must be 0 */
|
||||
if (Flags)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile);
|
||||
|
||||
|
@ -571,7 +581,7 @@ NTSTATUS ElfrReportEventW(
|
|||
DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
|
||||
break;
|
||||
}
|
||||
dwStringsSize += Strings[i]->Length + sizeof UNICODE_NULL;
|
||||
dwStringsSize += Strings[i]->Length + sizeof(UNICODE_NULL);
|
||||
}
|
||||
|
||||
lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
|
||||
|
@ -583,16 +593,16 @@ NTSTATUS ElfrReportEventW(
|
|||
|
||||
for (i = 0; i < NumStrings; i++)
|
||||
{
|
||||
CopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
|
||||
RtlCopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
|
||||
pos += Strings[i]->Length / sizeof(WCHAR);
|
||||
lpStrings[pos] = UNICODE_NULL;
|
||||
pos += sizeof UNICODE_NULL / sizeof(WCHAR);
|
||||
pos += sizeof(UNICODE_NULL) / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
if (UserSID)
|
||||
dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
|
||||
LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
|
||||
lastRec,
|
||||
lastRec, // FIXME!
|
||||
EventType,
|
||||
EventCategory,
|
||||
EventID,
|
||||
|
@ -620,7 +630,8 @@ NTSTATUS ElfrReportEventW(
|
|||
|
||||
|
||||
/* Function 12 */
|
||||
NTSTATUS ElfrClearELFA(
|
||||
NTSTATUS
|
||||
ElfrClearELFA(
|
||||
IELF_HANDLE LogHandle,
|
||||
PRPC_STRING BackupFileName)
|
||||
{
|
||||
|
@ -643,7 +654,8 @@ NTSTATUS ElfrClearELFA(
|
|||
|
||||
|
||||
/* Function 13 */
|
||||
NTSTATUS ElfrBackupELFA(
|
||||
NTSTATUS
|
||||
ElfrBackupELFA(
|
||||
IELF_HANDLE LogHandle,
|
||||
PRPC_STRING BackupFileName)
|
||||
{
|
||||
|
@ -666,13 +678,14 @@ NTSTATUS ElfrBackupELFA(
|
|||
|
||||
|
||||
/* Function 14 */
|
||||
NTSTATUS ElfrOpenELA(
|
||||
NTSTATUS
|
||||
ElfrOpenELA(
|
||||
EVENTLOG_HANDLE_A UNCServerName,
|
||||
PRPC_STRING ModuleName,
|
||||
PRPC_STRING RegModuleName,
|
||||
DWORD MajorVersion,
|
||||
DWORD MinorVersion,
|
||||
IELF_HANDLE *LogHandle)
|
||||
ULONG MajorVersion,
|
||||
ULONG MinorVersion,
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
UNICODE_STRING ModuleNameW;
|
||||
NTSTATUS Status;
|
||||
|
@ -690,8 +703,8 @@ NTSTATUS ElfrOpenELA(
|
|||
|
||||
/* FIXME: Must verify that caller has read access */
|
||||
|
||||
Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
|
||||
ModuleNameW.Buffer,
|
||||
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||
&ModuleNameW,
|
||||
FALSE);
|
||||
|
||||
RtlFreeUnicodeString(&ModuleNameW);
|
||||
|
@ -701,13 +714,14 @@ NTSTATUS ElfrOpenELA(
|
|||
|
||||
|
||||
/* Function 15 */
|
||||
NTSTATUS ElfrRegisterEventSourceA(
|
||||
NTSTATUS
|
||||
ElfrRegisterEventSourceA(
|
||||
EVENTLOG_HANDLE_A UNCServerName,
|
||||
PRPC_STRING ModuleName,
|
||||
PRPC_STRING RegModuleName,
|
||||
DWORD MajorVersion,
|
||||
DWORD MinorVersion,
|
||||
IELF_HANDLE *LogHandle)
|
||||
ULONG MajorVersion,
|
||||
ULONG MinorVersion,
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
UNICODE_STRING ModuleNameW;
|
||||
NTSTATUS Status;
|
||||
|
@ -736,8 +750,8 @@ NTSTATUS ElfrRegisterEventSourceA(
|
|||
|
||||
/* FIXME: Must verify that caller has write access */
|
||||
|
||||
Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
|
||||
ModuleNameW.Buffer,
|
||||
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||
&ModuleNameW,
|
||||
TRUE);
|
||||
|
||||
RtlFreeUnicodeString(&ModuleNameW);
|
||||
|
@ -747,12 +761,13 @@ NTSTATUS ElfrRegisterEventSourceA(
|
|||
|
||||
|
||||
/* Function 16 */
|
||||
NTSTATUS ElfrOpenBELA(
|
||||
NTSTATUS
|
||||
ElfrOpenBELA(
|
||||
EVENTLOG_HANDLE_A UNCServerName,
|
||||
PRPC_STRING BackupFileName,
|
||||
DWORD MajorVersion,
|
||||
DWORD MinorVersion,
|
||||
IELF_HANDLE *LogHandle)
|
||||
ULONG MajorVersion,
|
||||
ULONG MinorVersion,
|
||||
PIELF_HANDLE LogHandle)
|
||||
{
|
||||
UNICODE_STRING BackupFileNameW;
|
||||
NTSTATUS Status;
|
||||
|
@ -774,11 +789,11 @@ NTSTATUS ElfrOpenBELA(
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/*FIXME: UNCServerName must specify the server */
|
||||
/* FIXME: UNCServerName must specify the server */
|
||||
|
||||
/*FIXME: Must verify that caller has read access */
|
||||
/* FIXME: Must verify that caller has read access */
|
||||
|
||||
Status = ElfCreateBackupLogHandle((PLOGHANDLE *)LogHandle,
|
||||
Status = ElfCreateBackupLogHandle((PLOGHANDLE*)LogHandle,
|
||||
&BackupFileNameW);
|
||||
|
||||
RtlFreeUnicodeString(&BackupFileNameW);
|
||||
|
@ -788,14 +803,15 @@ NTSTATUS ElfrOpenBELA(
|
|||
|
||||
|
||||
/* Function 17 */
|
||||
NTSTATUS ElfrReadELA(
|
||||
NTSTATUS
|
||||
ElfrReadELA(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD ReadFlags,
|
||||
DWORD RecordOffset,
|
||||
ULONG ReadFlags,
|
||||
ULONG RecordOffset,
|
||||
RULONG NumberOfBytesToRead,
|
||||
BYTE *Buffer,
|
||||
DWORD *NumberOfBytesRead,
|
||||
DWORD *MinNumberOfBytesNeeded)
|
||||
PBYTE Buffer,
|
||||
PULONG NumberOfBytesRead,
|
||||
PULONG MinNumberOfBytesNeeded)
|
||||
{
|
||||
PLOGHANDLE lpLogHandle;
|
||||
DWORD dwError;
|
||||
|
@ -803,9 +819,7 @@ NTSTATUS ElfrReadELA(
|
|||
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (!Buffer)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -829,7 +843,7 @@ NTSTATUS ElfrReadELA(
|
|||
MinNumberOfBytesNeeded,
|
||||
TRUE);
|
||||
|
||||
/* Update the handles CurrentRecord if success*/
|
||||
/* Update the handle's CurrentRecord if success */
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
lpLogHandle->CurrentRecord = RecordNumber;
|
||||
|
@ -844,21 +858,22 @@ NTSTATUS ElfrReadELA(
|
|||
|
||||
|
||||
/* Function 18 */
|
||||
NTSTATUS ElfrReportEventA(
|
||||
NTSTATUS
|
||||
ElfrReportEventA(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD Time,
|
||||
ULONG Time,
|
||||
USHORT EventType,
|
||||
USHORT EventCategory,
|
||||
DWORD EventID,
|
||||
ULONG EventID,
|
||||
USHORT NumStrings,
|
||||
DWORD DataSize,
|
||||
ULONG DataSize,
|
||||
PRPC_STRING ComputerName,
|
||||
PRPC_SID UserSID,
|
||||
PRPC_STRING Strings[],
|
||||
BYTE *Data,
|
||||
PBYTE Data,
|
||||
USHORT Flags,
|
||||
DWORD *RecordNumber,
|
||||
DWORD *TimeWritten)
|
||||
PULONG RecordNumber,
|
||||
PULONG TimeWritten)
|
||||
{
|
||||
UNICODE_STRING ComputerNameW;
|
||||
PUNICODE_STRING *StringsArrayW = NULL;
|
||||
|
@ -891,7 +906,7 @@ NTSTATUS ElfrReportEventA(
|
|||
{
|
||||
StringsArrayW = HeapAlloc(MyHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
NumStrings * sizeof (PUNICODE_STRING));
|
||||
NumStrings * sizeof(PUNICODE_STRING));
|
||||
if (StringsArrayW == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
|
@ -964,7 +979,8 @@ Done:
|
|||
|
||||
|
||||
/* Function 19 */
|
||||
NTSTATUS ElfrRegisterClusterSvc(
|
||||
NTSTATUS
|
||||
ElfrRegisterClusterSvc(
|
||||
handle_t BindingHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
@ -973,7 +989,8 @@ NTSTATUS ElfrRegisterClusterSvc(
|
|||
|
||||
|
||||
/* Function 20 */
|
||||
NTSTATUS ElfrDeregisterClusterSvc(
|
||||
NTSTATUS
|
||||
ElfrDeregisterClusterSvc(
|
||||
handle_t BindingHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
@ -982,7 +999,8 @@ NTSTATUS ElfrDeregisterClusterSvc(
|
|||
|
||||
|
||||
/* Function 21 */
|
||||
NTSTATUS ElfrWriteClusterEvents(
|
||||
NTSTATUS
|
||||
ElfrWriteClusterEvents(
|
||||
handle_t BindingHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
@ -991,16 +1009,20 @@ NTSTATUS ElfrWriteClusterEvents(
|
|||
|
||||
|
||||
/* Function 22 */
|
||||
NTSTATUS ElfrGetLogInformation(
|
||||
NTSTATUS
|
||||
ElfrGetLogInformation(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD InfoLevel,
|
||||
BYTE *Buffer,
|
||||
DWORD cbBufSize,
|
||||
DWORD *pcbBytesNeeded)
|
||||
ULONG InfoLevel,
|
||||
PBYTE Buffer,
|
||||
ULONG cbBufSize,
|
||||
PULONG pcbBytesNeeded)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PLOGHANDLE lpLogHandle;
|
||||
|
||||
/* FIXME: check handle first */
|
||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||
if (!lpLogHandle)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
switch (InfoLevel)
|
||||
{
|
||||
|
@ -1011,10 +1033,16 @@ NTSTATUS ElfrGetLogInformation(
|
|||
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
|
||||
if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
Status = STATUS_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
|
||||
efi->dwFull = 0; /* FIXME */
|
||||
/*
|
||||
* FIXME. To check whether an event log is "full" one needs
|
||||
* to compare its current size with respect to the maximum
|
||||
* size threshold "MaxSize" contained in its header.
|
||||
*/
|
||||
efi->dwFull = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1028,7 +1056,8 @@ NTSTATUS ElfrGetLogInformation(
|
|||
|
||||
|
||||
/* Function 23 */
|
||||
NTSTATUS ElfrFlushEL(
|
||||
NTSTATUS
|
||||
ElfrFlushEL(
|
||||
IELF_HANDLE LogHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
@ -1037,22 +1066,23 @@ NTSTATUS ElfrFlushEL(
|
|||
|
||||
|
||||
/* Function 24 */
|
||||
NTSTATUS ElfrReportEventAndSourceW(
|
||||
NTSTATUS
|
||||
ElfrReportEventAndSourceW(
|
||||
IELF_HANDLE LogHandle,
|
||||
DWORD Time,
|
||||
ULONG Time,
|
||||
USHORT EventType,
|
||||
USHORT EventCategory,
|
||||
ULONG EventID,
|
||||
PRPC_UNICODE_STRING SourceName,
|
||||
USHORT NumStrings,
|
||||
DWORD DataSize,
|
||||
ULONG DataSize,
|
||||
PRPC_UNICODE_STRING ComputerName,
|
||||
PRPC_SID UserSID,
|
||||
PRPC_UNICODE_STRING Strings[],
|
||||
BYTE *Data,
|
||||
PBYTE Data,
|
||||
USHORT Flags,
|
||||
DWORD *RecordNumber,
|
||||
DWORD *TimeWritten)
|
||||
PULONG RecordNumber,
|
||||
PULONG TimeWritten)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -1073,4 +1103,6 @@ void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
|
|||
|
||||
void __RPC_USER IELF_HANDLE_rundown(IELF_HANDLE LogHandle)
|
||||
{
|
||||
/* Close the handle */
|
||||
ElfDeleteEventLogHandle(&LogHandle); // ElfrCloseEL(&LogHandle);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue