[EVENTLOG]

- Implement ElfrReadELA.
- Improve LogfReadEvent in such a way that it can return ANSI and UNICODE log entries.
- Add a hack to ElfrReadELW in order to return a proper status code in case of an end-of-file situation.

svn path=/trunk/; revision=54672
This commit is contained in:
Eric Kohl 2011-12-17 13:22:10 +00:00
parent 7f9124d391
commit 4e9b968c96
3 changed files with 259 additions and 22 deletions

View file

@ -134,7 +134,8 @@ DWORD LogfReadEvent(PLOGFILE LogFile,
DWORD BufSize,
PBYTE Buffer,
DWORD * BytesRead,
DWORD * BytesNeeded);
DWORD * BytesNeeded,
BOOL Ansi);
BOOL LogfWriteData(PLOGFILE LogFile,
DWORD BufSize,

View file

@ -511,7 +511,7 @@ PLOGFILE LogfListItemByIndex(INT Index)
return Result;
}
INT LogfListItemCount()
INT LogfListItemCount(VOID)
{
PLIST_ENTRY CurrentEntry;
INT i = 0;
@ -543,13 +543,171 @@ VOID LogfListRemoveItem(PLOGFILE Item)
LeaveCriticalSection(&LogFileListCs);
}
static BOOL
ReadAnsiLogEntry(HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead)
{
PEVENTLOGRECORD Dst;
PEVENTLOGRECORD Src;
ANSI_STRING StringA;
UNICODE_STRING StringW;
LPWSTR SrcPtr;
LPSTR DstPtr;
LPWSTR SrcString;
LPSTR DstString;
LPVOID lpUnicodeBuffer = NULL;
DWORD dwRead = 0;
DWORD i;
DWORD dwPadding;
DWORD dwEntryLength;
PDWORD pLength;
NTSTATUS Status;
BOOL ret = TRUE;
*lpNumberOfBytesRead = 0;
lpUnicodeBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nNumberOfBytesToRead);
if (lpUnicodeBuffer == NULL)
{
DPRINT1("Alloc failed!\n");
return FALSE;
}
if (!ReadFile(hFile, lpUnicodeBuffer, nNumberOfBytesToRead, &dwRead, NULL))
{
DPRINT1("Read failed!\n");
ret = FALSE;
goto done;
}
Dst = (PEVENTLOGRECORD)lpBuffer;
Src = (PEVENTLOGRECORD)lpUnicodeBuffer;
Dst->TimeGenerated = Src->TimeGenerated;
Dst->Reserved = Src->Reserved;
Dst->RecordNumber = Src->RecordNumber;
Dst->TimeWritten = Src->TimeWritten;
Dst->EventID = Src->EventID;
Dst->EventType = Src->EventType;
Dst->EventCategory = Src->EventCategory;
Dst->NumStrings = Src->NumStrings;
Dst->UserSidLength = Src->UserSidLength;
Dst->DataLength = Src->DataLength;
SrcPtr = (LPWSTR)((DWORD_PTR)Src + sizeof(EVENTLOGRECORD));
DstPtr = (LPSTR)((DWORD_PTR)Dst + sizeof(EVENTLOGRECORD));
/* Convert the module name */
RtlInitUnicodeString(&StringW, SrcPtr);
Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
if (NT_SUCCESS(Status))
{
RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
DstPtr = (PVOID)((DWORD_PTR)DstPtr + StringA.MaximumLength);
RtlFreeAnsiString(&StringA);
}
/* Convert the computer name */
if (NT_SUCCESS(Status))
{
SrcPtr = (PWSTR)((DWORD_PTR)SrcPtr + StringW.MaximumLength);
RtlInitUnicodeString(&StringW, SrcPtr);
Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
if (NT_SUCCESS(Status))
{
RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
DstPtr = (PVOID)((DWORD_PTR)DstPtr + StringA.MaximumLength);
RtlFreeAnsiString(&StringA);
}
}
/* Add the padding and the User SID*/
if (NT_SUCCESS(Status))
{
dwPadding = sizeof(DWORD) - (((DWORD_PTR)DstPtr - (DWORD_PTR)Dst) % sizeof(DWORD));
RtlZeroMemory(DstPtr, dwPadding);
DstPtr = (LPSTR)((DWORD_PTR)DstPtr + dwPadding);
RtlCopyMemory(DstPtr,
(PVOID)((DWORD_PTR)Src + Src->UserSidOffset),
Src->UserSidLength);
Dst->UserSidOffset = (DWORD)((DWORD_PTR)DstPtr - (DWORD_PTR)Dst);
}
/* Convert the strings */
if (NT_SUCCESS(Status))
{
DstPtr = (PVOID)((DWORD_PTR)DstPtr + Src->UserSidLength);
SrcString = (LPWSTR)((DWORD_PTR)Src + (DWORD)Src->StringOffset);
DstString = (LPSTR)DstPtr;
for (i = 0; i < Dst->NumStrings; i++)
{
RtlInitUnicodeString(&StringW, SrcString);
RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
RtlCopyMemory(DstString, StringA.Buffer, StringA.MaximumLength);
SrcString = (LPWSTR)((DWORD_PTR)SrcString +
(DWORD)StringW.MaximumLength);
DstString = (LPSTR)((DWORD_PTR)DstString +
(DWORD)StringA.MaximumLength);
RtlFreeAnsiString(&StringA);
}
Dst->StringOffset = (DWORD)((DWORD_PTR)DstPtr - (DWORD_PTR)Dst);
/* Copy the binary data */
DstPtr = (PVOID)DstString;
Dst->DataOffset = (DWORD_PTR)DstPtr - (DWORD_PTR)Dst;
RtlCopyMemory(DstPtr, (PVOID)((DWORD_PTR)Src + Src->DataOffset), Src->DataLength);
/* Add the padding */
DstPtr = (PVOID)((DWORD_PTR)DstPtr + Src->DataLength);
dwPadding = sizeof(DWORD) - (((DWORD_PTR)DstPtr-(DWORD_PTR)Dst) % sizeof(DWORD));
RtlZeroMemory(DstPtr, dwPadding);
dwEntryLength = (DWORD)((DWORD_PTR)DstPtr + dwPadding + sizeof(DWORD) - (DWORD_PTR)Dst);
/* Set the entry length at the end of the entry*/
pLength = (PDWORD)((DWORD_PTR)DstPtr + dwPadding);
*pLength = dwEntryLength;
Dst->Length = dwEntryLength;
*lpNumberOfBytesRead = dwEntryLength;
}
done:
if (lpUnicodeBuffer != NULL)
HeapFree(GetProcessHeap(), 0, lpUnicodeBuffer);
return ret;
}
DWORD LogfReadEvent(PLOGFILE LogFile,
DWORD Flags,
DWORD * RecordNumber,
DWORD BufSize,
PBYTE Buffer,
DWORD * BytesRead,
DWORD * BytesNeeded)
DWORD * BytesNeeded,
BOOL Ansi)
{
DWORD dwOffset, dwRead, dwRecSize;
DWORD dwBufferUsage = 0, dwRecNum;
@ -611,10 +769,21 @@ DWORD LogfReadEvent(PLOGFILE LogFile,
goto Done;
}
if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL))
if (Ansi == TRUE)
{
DPRINT1("ReadFile() failed!\n");
goto Done;
if (!ReadAnsiLogEntry(LogFile->hFile, Buffer, dwRecSize, &dwRead))
{
DPRINT1("ReadAnsiLogEntry() failed!\n");
goto Done;
}
}
else
{
if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL))
{
DPRINT1("ReadFile() failed!\n");
goto Done;
}
}
dwBufferUsage += dwRead;
@ -659,14 +828,28 @@ DWORD LogfReadEvent(PLOGFILE LogFile,
goto Done;
}
if (!ReadFile(LogFile->hFile,
Buffer + dwBufferUsage,
dwRecSize,
&dwRead,
NULL))
if (Ansi == TRUE)
{
DPRINT1("ReadFile() failed!\n");
goto Done;
if (!ReadAnsiLogEntry(LogFile->hFile,
Buffer + dwBufferUsage,
dwRecSize,
&dwRead))
{
DPRINT1("ReadAnsiLogEntry() failed!\n");
goto Done;
}
}
else
{
if (!ReadFile(LogFile->hFile,
Buffer + dwBufferUsage,
dwRecSize,
&dwRead,
NULL))
{
DPRINT1("ReadFile() failed!\n");
goto Done;
}
}
dwBufferUsage += dwRead;
@ -870,9 +1053,8 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
return TRUE;
}
ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
/* Returns 0 if nothing found. */
ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
{
DWORD i;
@ -1012,10 +1194,12 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
pRec->UserSidOffset = pos;
if (pos % 4 != 0)
pos += 4 - (pos % 4);
if (dwSidLength)
{
if (pos % 4 != 0)
pos += 4 - (pos % 4);
CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
pRec->UserSidLength = dwSidLength;
pRec->UserSidOffset = pos;

View file

@ -225,6 +225,8 @@ NTSTATUS ElfrNumberOfRecords(
PLOGHANDLE lpLogHandle;
PLOGFILE lpLogFile;
DPRINT("ElfrNumberOfRecords()");
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
@ -233,6 +235,10 @@ NTSTATUS ElfrNumberOfRecords(
lpLogFile = lpLogHandle->LogFile;
DPRINT("Oldest: %lu Current: %lu\n",
lpLogFile->Header.OldestRecordNumber,
lpLogFile->Header.CurrentRecordNumber);
if (lpLogFile->Header.OldestRecordNumber == 0)
*NumberOfRecords = 0;
else
@ -372,8 +378,8 @@ NTSTATUS ElfrReadELW(
return STATUS_INVALID_HANDLE;
}
if (!Buffer)
return I_RpcMapWin32Status(ERROR_INVALID_PARAMETER);
if (!Buffer)
return STATUS_INVALID_PARAMETER;
/* If sequential read, retrieve the CurrentRecord from this log handle */
if (ReadFlags & EVENTLOG_SEQUENTIAL_READ)
@ -386,7 +392,8 @@ NTSTATUS ElfrReadELW(
}
dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded);
NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded,
FALSE);
/* Update the handles CurrentRecord if success*/
if (dwError == ERROR_SUCCESS)
@ -394,6 +401,10 @@ NTSTATUS ElfrReadELW(
lpLogHandle->CurrentRecord = RecordNumber;
}
/* HACK!!! */
if (dwError == ERROR_HANDLE_EOF)
return STATUS_END_OF_FILE;
return I_RpcMapWin32Status(dwError);
}
@ -664,8 +675,49 @@ NTSTATUS ElfrReadELA(
DWORD *NumberOfBytesRead,
DWORD *MinNumberOfBytesNeeded)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PLOGHANDLE lpLogHandle;
DWORD dwError;
DWORD RecordNumber;
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
if (!Buffer)
return STATUS_INVALID_PARAMETER;
/* If sequential read, retrieve the CurrentRecord from this log handle */
if (ReadFlags & EVENTLOG_SEQUENTIAL_READ)
{
RecordNumber = lpLogHandle->CurrentRecord;
}
else
{
RecordNumber = RecordOffset;
}
dwError = LogfReadEvent(lpLogHandle->LogFile,
ReadFlags,
&RecordNumber,
NumberOfBytesToRead,
Buffer,
NumberOfBytesRead,
MinNumberOfBytesNeeded,
TRUE);
/* Update the handles CurrentRecord if success*/
if (dwError == ERROR_SUCCESS)
{
lpLogHandle->CurrentRecord = RecordNumber;
}
/* HACK!!! */
if (dwError == ERROR_HANDLE_EOF)
return STATUS_END_OF_FILE;
return I_RpcMapWin32Status(dwError);
}