mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[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:
parent
7f9124d391
commit
4e9b968c96
3 changed files with 259 additions and 22 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue