mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:52:57 +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
|
BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
|
||||||
HANDLE MyHeap = NULL;
|
HANDLE MyHeap = NULL;
|
||||||
|
|
||||||
|
PEVENTSOURCE EventLogSource = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
@ -74,7 +76,6 @@ ServiceControlHandler(DWORD dwControl,
|
||||||
0,
|
0,
|
||||||
EVENT_EventlogStopped, 0, NULL, 0, NULL);
|
EVENT_EventlogStopped, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
|
|
||||||
/* Stop listening to incoming RPC messages */
|
/* Stop listening to incoming RPC messages */
|
||||||
RpcMgmtStopServerListening(NULL);
|
RpcMgmtStopServerListening(NULL);
|
||||||
UpdateServiceStatus(SERVICE_STOPPED);
|
UpdateServiceStatus(SERVICE_STOPPED);
|
||||||
|
@ -120,15 +121,13 @@ ServiceInit(VOID)
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
hThread = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
(LPTHREAD_START_ROUTINE)
|
(LPTHREAD_START_ROUTINE)PortThreadRoutine,
|
||||||
PortThreadRoutine,
|
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!hThread)
|
if (!hThread)
|
||||||
{
|
{
|
||||||
DPRINT("Can't create PortThread\n");
|
DPRINT("Cannot create PortThread\n");
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -136,15 +135,14 @@ ServiceInit(VOID)
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
hThread = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
(LPTHREAD_START_ROUTINE)
|
RpcThreadRoutine,
|
||||||
RpcThreadRoutine,
|
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!hThread)
|
if (!hThread)
|
||||||
{
|
{
|
||||||
DPRINT("Can't create RpcThread\n");
|
DPRINT("Cannot create RpcThread\n");
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -165,14 +163,14 @@ ReportProductInfoEvent(VOID)
|
||||||
DWORD dwType;
|
DWORD dwType;
|
||||||
LONG lResult = ERROR_SUCCESS;
|
LONG lResult = ERROR_SUCCESS;
|
||||||
|
|
||||||
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFO));
|
ZeroMemory(&versionInfo, sizeof(versionInfo));
|
||||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||||
|
|
||||||
/* Get version information */
|
/* Get version information */
|
||||||
if (!GetVersionExW(&versionInfo))
|
if (!GetVersionExW(&versionInfo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ZeroMemory(szBuffer, 512 * sizeof(WCHAR));
|
ZeroMemory(szBuffer, sizeof(szBuffer));
|
||||||
|
|
||||||
/* Write version into the buffer */
|
/* Write version into the buffer */
|
||||||
dwLength = swprintf(szBuffer,
|
dwLength = swprintf(szBuffer,
|
||||||
|
@ -197,7 +195,7 @@ ReportProductInfoEvent(VOID)
|
||||||
&hKey);
|
&hKey);
|
||||||
if (lResult == ERROR_SUCCESS)
|
if (lResult == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dwValueLength = 512 - dwLength;
|
dwValueLength = ARRAYSIZE(szBuffer) - dwLength;
|
||||||
lResult = RegQueryValueEx(hKey,
|
lResult = RegQueryValueEx(hKey,
|
||||||
L"CurrentType",
|
L"CurrentType",
|
||||||
NULL,
|
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;
|
DWORD MaxValueLen, ValueLen, Type, ExpandedLen;
|
||||||
WCHAR *Buf = NULL, *Expanded = NULL;
|
WCHAR *Buf = NULL, *Expanded = NULL;
|
||||||
|
@ -280,58 +279,81 @@ PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
|
||||||
|
|
||||||
DPRINT("LoadLogFile: %S\n", LogName);
|
DPRINT("LoadLogFile: %S\n", LogName);
|
||||||
|
|
||||||
Result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
Result = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, &MaxValueLen, NULL, NULL);
|
NULL, NULL, &MaxValueLen, NULL, NULL);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
|
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaxValueLen = ROUND_DOWN(MaxValueLen, sizeof(WCHAR));
|
||||||
Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
|
Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
|
||||||
if (!Buf)
|
if (!Buf)
|
||||||
{
|
{
|
||||||
DPRINT1("Can't allocate heap!\n");
|
DPRINT1("Cannot allocate heap!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueLen = MaxValueLen;
|
ValueLen = MaxValueLen;
|
||||||
|
Result = RegQueryValueExW(hKey,
|
||||||
Result = RegQueryValueEx(hKey,
|
L"File",
|
||||||
L"File",
|
NULL,
|
||||||
NULL,
|
&Type,
|
||||||
&Type,
|
(LPBYTE)Buf,
|
||||||
(LPBYTE) Buf,
|
&ValueLen);
|
||||||
&ValueLen);
|
/*
|
||||||
if (Result != ERROR_SUCCESS)
|
* 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);
|
MaxValueLen = (wcslen(L"%SystemRoot%\\System32\\Config\\") +
|
||||||
HeapFree(MyHeap, 0, Buf);
|
wcslen(LogName) + wcslen(L".evt") + 1) * sizeof(WCHAR);
|
||||||
return NULL;
|
|
||||||
|
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)
|
ExpandedLen = ExpandEnvironmentStringsW(Buf, NULL, 0);
|
||||||
{
|
|
||||||
DPRINT1("%S\\File - value of wrong type %x.\n", LogName, Type);
|
|
||||||
HeapFree(MyHeap, 0, Buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpandedLen = ExpandEnvironmentStrings(Buf, NULL, 0);
|
|
||||||
Expanded = HeapAlloc(MyHeap, 0, ExpandedLen * sizeof(WCHAR));
|
Expanded = HeapAlloc(MyHeap, 0, ExpandedLen * sizeof(WCHAR));
|
||||||
if (!Expanded)
|
if (!Expanded)
|
||||||
{
|
{
|
||||||
DPRINT1("Can't allocate heap!\n");
|
DPRINT1("Cannot allocate heap!\n");
|
||||||
HeapFree(MyHeap, 0, Buf);
|
HeapFree(MyHeap, 0, Buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen);
|
ExpandEnvironmentStringsW(Buf, Expanded, ExpandedLen);
|
||||||
|
|
||||||
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName,
|
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName, NULL, NULL))
|
||||||
NULL, NULL))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Can't convert path!\n");
|
DPRINT1("Cannot convert path!\n");
|
||||||
HeapFree(MyHeap, 0, Expanded);
|
HeapFree(MyHeap, 0, Expanded);
|
||||||
HeapFree(MyHeap, 0, Buf);
|
HeapFree(MyHeap, 0, Buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -339,73 +361,92 @@ PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
|
||||||
|
|
||||||
DPRINT("%S -> %S\n", Buf, Expanded);
|
DPRINT("%S -> %S\n", Buf, Expanded);
|
||||||
|
|
||||||
ValueLen = sizeof(ULONG);
|
ValueLen = sizeof(ulMaxSize);
|
||||||
Result = RegQueryValueEx(hKey,
|
Result = RegQueryValueExW(hKey,
|
||||||
L"MaxSize",
|
L"MaxSize",
|
||||||
NULL,
|
NULL,
|
||||||
&Type,
|
&Type,
|
||||||
(LPBYTE)&ulMaxSize,
|
(LPBYTE)&ulMaxSize,
|
||||||
&ValueLen);
|
&ValueLen);
|
||||||
if (Result != ERROR_SUCCESS)
|
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
|
||||||
|
{
|
||||||
ulMaxSize = 512 * 1024; /* 512 kBytes */
|
ulMaxSize = 512 * 1024; /* 512 kBytes */
|
||||||
|
|
||||||
ValueLen = sizeof(ULONG);
|
Result = RegSetValueExW(hKey,
|
||||||
Result = RegQueryValueEx(hKey,
|
L"MaxSize",
|
||||||
L"Retention",
|
0,
|
||||||
NULL,
|
REG_DWORD,
|
||||||
&Type,
|
(LPBYTE)&ulMaxSize,
|
||||||
(LPBYTE)&ulRetention,
|
sizeof(ulMaxSize));
|
||||||
&ValueLen);
|
}
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
|
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;
|
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);
|
Status = LogfCreate(&pLogf, LogName, &FileName, ulMaxSize, ulRetention, TRUE, FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to create %S! (Status %08lx)\n", Expanded, Status);
|
DPRINT1("Failed to create %S! (Status %08lx)\n", Expanded, Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(MyHeap, 0, Buf);
|
|
||||||
HeapFree(MyHeap, 0, Expanded);
|
HeapFree(MyHeap, 0, Expanded);
|
||||||
|
HeapFree(MyHeap, 0, Buf);
|
||||||
return pLogf;
|
return pLogf;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL LoadLogFiles(HKEY eventlogKey)
|
static BOOL
|
||||||
|
LoadLogFiles(HKEY eventlogKey)
|
||||||
{
|
{
|
||||||
LONG Result;
|
LONG Result;
|
||||||
DWORD MaxLognameLen, LognameLen;
|
DWORD MaxLognameLen, LognameLen;
|
||||||
WCHAR *Buf = NULL;
|
WCHAR *Buf = NULL;
|
||||||
INT i;
|
DWORD dwIndex;
|
||||||
PLOGFILE pLogFile;
|
PLOGFILE pLogFile;
|
||||||
|
|
||||||
Result = RegQueryInfoKey(eventlogKey,
|
Result = RegQueryInfoKeyW(eventlogKey, NULL, NULL, NULL, NULL, &MaxLognameLen,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
&MaxLognameLen,
|
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
|
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaxLognameLen++;
|
MaxLognameLen++;
|
||||||
|
|
||||||
Buf = HeapAlloc(MyHeap, 0, MaxLognameLen * sizeof(WCHAR));
|
Buf = HeapAlloc(MyHeap, 0, MaxLognameLen * sizeof(WCHAR));
|
||||||
|
|
||||||
if (!Buf)
|
if (!Buf)
|
||||||
{
|
{
|
||||||
DPRINT1("Error: can't allocate heap!\n");
|
DPRINT1("Error: cannot allocate heap!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
LognameLen = MaxLognameLen;
|
LognameLen = MaxLognameLen;
|
||||||
|
dwIndex = 0;
|
||||||
while (RegEnumKeyEx(eventlogKey,
|
while (RegEnumKeyExW(eventlogKey,
|
||||||
i,
|
dwIndex,
|
||||||
Buf,
|
Buf,
|
||||||
&LognameLen,
|
&LognameLen,
|
||||||
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
HKEY SubKey;
|
HKEY SubKey;
|
||||||
|
|
||||||
|
@ -431,15 +472,17 @@ BOOL LoadLogFiles(HKEY eventlogKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(SubKey);
|
RegCloseKey(SubKey);
|
||||||
|
|
||||||
LognameLen = MaxLognameLen;
|
LognameLen = MaxLognameLen;
|
||||||
i++;
|
dwIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(MyHeap, 0, Buf);
|
HeapFree(MyHeap, 0, Buf);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT wmain()
|
|
||||||
|
int wmain(int argc, WCHAR* argv[])
|
||||||
{
|
{
|
||||||
WCHAR LogPath[MAX_PATH];
|
WCHAR LogPath[MAX_PATH];
|
||||||
INT RetCode = 0;
|
INT RetCode = 0;
|
||||||
|
@ -458,9 +501,9 @@ INT wmain()
|
||||||
goto bye_bye;
|
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");
|
DPRINT("LiveCD detected\n");
|
||||||
onLiveCD = TRUE;
|
onLiveCD = TRUE;
|
||||||
|
@ -475,7 +518,7 @@ INT wmain()
|
||||||
|
|
||||||
if (Result != ERROR_SUCCESS)
|
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;
|
RetCode = 1;
|
||||||
goto bye_bye;
|
goto bye_bye;
|
||||||
}
|
}
|
||||||
|
@ -483,9 +526,15 @@ INT wmain()
|
||||||
LoadLogFiles(elogKey);
|
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);
|
StartServiceCtrlDispatcher(ServiceTable);
|
||||||
|
|
||||||
bye_bye:
|
bye_bye:
|
||||||
LogfCloseAll();
|
LogfCloseAll();
|
||||||
|
|
||||||
if (MyHeap)
|
if (MyHeap)
|
||||||
|
@ -494,40 +543,10 @@ INT wmain()
|
||||||
return RetCode;
|
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)
|
VOID PRINT_HEADER(PEVENTLOGHEADER header)
|
||||||
{
|
{
|
||||||
|
ULONG Flags = header->Flags;
|
||||||
|
|
||||||
DPRINT("HeaderSize = %lu\n", header->HeaderSize);
|
DPRINT("HeaderSize = %lu\n", header->HeaderSize);
|
||||||
DPRINT("Signature = 0x%x\n", header->Signature);
|
DPRINT("Signature = 0x%x\n", header->Signature);
|
||||||
DPRINT("MajorVersion = %lu\n", header->MajorVersion);
|
DPRINT("MajorVersion = %lu\n", header->MajorVersion);
|
||||||
|
@ -540,10 +559,30 @@ VOID PRINT_HEADER(PEVENTLOGHEADER header)
|
||||||
DPRINT("Retention = 0x%x\n", header->Retention);
|
DPRINT("Retention = 0x%x\n", header->Retention);
|
||||||
DPRINT("EndHeaderSize = %lu\n", header->EndHeaderSize);
|
DPRINT("EndHeaderSize = %lu\n", header->EndHeaderSize);
|
||||||
DPRINT("Flags: ");
|
DPRINT("Flags: ");
|
||||||
if (header->Flags & ELF_LOGFILE_HEADER_DIRTY) DPRINT("ELF_LOGFILE_HEADER_DIRTY");
|
if (Flags & 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 ");
|
DPRINT("ELF_LOGFILE_HEADER_DIRTY");
|
||||||
if (header->Flags & ELF_LOGFILE_ARCHIVE_SET) DPRINT("| ELF_LOGFILE_ARCHIVE_SET ");
|
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");
|
DPRINT("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,21 +590,24 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
WCHAR *str;
|
WCHAR *str;
|
||||||
SYSTEMTIME time;
|
LARGE_INTEGER SystemTime;
|
||||||
|
TIME_FIELDS Time;
|
||||||
|
|
||||||
DPRINT("Length = %lu\n", pRec->Length);
|
DPRINT("Length = %lu\n", pRec->Length);
|
||||||
DPRINT("Reserved = 0x%x\n", pRec->Reserved);
|
DPRINT("Reserved = 0x%x\n", pRec->Reserved);
|
||||||
DPRINT("RecordNumber = %lu\n", pRec->RecordNumber);
|
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",
|
DPRINT("TimeGenerated = %hu.%hu.%hu %hu:%hu:%hu\n",
|
||||||
time.wDay, time.wMonth, time.wYear,
|
Time.Day, Time.Month, Time.Year,
|
||||||
time.wHour, time.wMinute, time.wSecond);
|
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",
|
DPRINT("TimeWritten = %hu.%hu.%hu %hu:%hu:%hu\n",
|
||||||
time.wDay, time.wMonth, time.wYear,
|
Time.Day, Time.Month, Time.Year,
|
||||||
time.wHour, time.wMinute, time.wSecond);
|
Time.Hour, Time.Minute, Time.Second);
|
||||||
|
|
||||||
DPRINT("EventID = %lu\n", pRec->EventID);
|
DPRINT("EventID = %lu\n", pRec->EventID);
|
||||||
|
|
||||||
|
@ -600,17 +642,17 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
||||||
DPRINT("DataLength = %lu\n", pRec->DataLength);
|
DPRINT("DataLength = %lu\n", pRec->DataLength);
|
||||||
DPRINT("DataOffset = %lu\n", pRec->DataOffset);
|
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);
|
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)
|
if (pRec->StringOffset < pRec->Length && pRec->NumStrings)
|
||||||
{
|
{
|
||||||
DPRINT("Strings:\n");
|
DPRINT("Strings:\n");
|
||||||
str = (WCHAR *) (((PBYTE) pRec) + pRec->StringOffset);
|
str = (WCHAR *) ((ULONG_PTR)pRec + pRec->StringOffset);
|
||||||
for (i = 0; i < pRec->NumStrings; i++)
|
for (i = 0; i < pRec->NumStrings; i++)
|
||||||
{
|
{
|
||||||
DPRINT("[%u] %S\n", i, str);
|
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>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* PSDK/NDK Headers */
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
|
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
|
|
||||||
|
#define NTOS_MODE_USER
|
||||||
#include <ndk/rtlfuncs.h>
|
#include <ndk/rtlfuncs.h>
|
||||||
#include <ndk/obfuncs.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 <eventlogrpc_s.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
@ -26,21 +32,21 @@ typedef struct _IO_ERROR_LPC
|
||||||
IO_ERROR_LOG_MESSAGE Message;
|
IO_ERROR_LOG_MESSAGE Message;
|
||||||
} IO_ERROR_LPC, *PIO_ERROR_LPC;
|
} IO_ERROR_LPC, *PIO_ERROR_LPC;
|
||||||
|
|
||||||
#define MAJORVER 1
|
|
||||||
#define MINORVER 1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our file format will be compatible with NT's
|
* Our file format will be compatible with NT's
|
||||||
*/
|
*/
|
||||||
|
#define MAJORVER 1
|
||||||
|
#define MINORVER 1
|
||||||
#define LOGFILE_SIGNATURE 0x654c664c
|
#define LOGFILE_SIGNATURE 0x654c664c
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags used in logfile header
|
* Flags used in logfile header
|
||||||
*/
|
*/
|
||||||
#define ELF_LOGFILE_HEADER_DIRTY 1
|
#define ELF_LOGFILE_HEADER_DIRTY 1
|
||||||
#define ELF_LOGFILE_HEADER_WRAP 2
|
#define ELF_LOGFILE_HEADER_WRAP 2
|
||||||
#define ELF_LOGFILE_LOGFULL_WRITTEN 4
|
#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? */
|
/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
|
||||||
typedef struct _EVENTLOGHEADER
|
typedef struct _EVENTLOGHEADER
|
||||||
|
@ -114,22 +120,38 @@ typedef struct _LOGHANDLE
|
||||||
WCHAR szName[1];
|
WCHAR szName[1];
|
||||||
} LOGHANDLE, *PLOGHANDLE;
|
} 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 */
|
/* file.c */
|
||||||
VOID LogfListInitialize(VOID);
|
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 LogfReadEvent(PLOGFILE LogFile,
|
||||||
DWORD Flags,
|
DWORD Flags,
|
||||||
|
@ -171,61 +193,34 @@ DWORD LogfGetOldestRecord(PLOGFILE LogFile);
|
||||||
|
|
||||||
DWORD LogfGetCurrentRecord(PLOGFILE LogFile);
|
DWORD LogfGetCurrentRecord(PLOGFILE LogFile);
|
||||||
|
|
||||||
ULONG LogfOffsetByNumber(PLOGFILE LogFile,
|
PBYTE
|
||||||
DWORD RecordNumber);
|
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,
|
static __inline void LogfFreeRecord(LPVOID Rec)
|
||||||
ULONG ulNumber,
|
{
|
||||||
ULONG ulOffset);
|
HeapFree(MyHeap, 0, Rec);
|
||||||
|
}
|
||||||
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);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
LogfReportEvent(WORD wType,
|
LogfReportEvent(USHORT wType,
|
||||||
WORD wCategory,
|
USHORT wCategory,
|
||||||
DWORD dwEventId,
|
ULONG dwEventId,
|
||||||
WORD wNumStrings,
|
USHORT wNumStrings,
|
||||||
WCHAR *lpStrings,
|
WCHAR* lpStrings,
|
||||||
DWORD dwDataSize,
|
ULONG dwDataSize,
|
||||||
LPVOID lpRawData);
|
PVOID 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);
|
|
||||||
|
|
||||||
|
|
||||||
/* logport.c */
|
/* logport.c */
|
||||||
|
@ -238,9 +233,4 @@ NTSTATUS ProcessPortMessage(VOID);
|
||||||
/* rpc.c */
|
/* rpc.c */
|
||||||
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter);
|
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter);
|
||||||
|
|
||||||
static __inline void LogfFreeRecord(LPVOID Rec)
|
|
||||||
{
|
|
||||||
HeapFree(MyHeap, 0, Rec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __EVENTLOG_H__ */
|
#endif /* __EVENTLOG_H__ */
|
||||||
|
|
|
@ -70,7 +70,7 @@ LoadEventSources(HKEY hKey,
|
||||||
NULL, NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL, NULL);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
|
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,11 @@ LoadEventSources(HKEY hKey,
|
||||||
Buf = HeapAlloc(MyHeap, 0, dwMaxSubKeyLength * sizeof(WCHAR));
|
Buf = HeapAlloc(MyHeap, 0, dwMaxSubKeyLength * sizeof(WCHAR));
|
||||||
if (!Buf)
|
if (!Buf)
|
||||||
{
|
{
|
||||||
DPRINT1("Error: can't allocate heap!\n");
|
DPRINT1("Error: cannot allocate heap!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwEventSourceNameLength = dwMaxSubKeyLength;
|
dwEventSourceNameLength = dwMaxSubKeyLength;
|
||||||
|
|
||||||
dwIndex = 0;
|
dwIndex = 0;
|
||||||
while (RegEnumKeyExW(hKey,
|
while (RegEnumKeyExW(hKey,
|
||||||
dwIndex,
|
dwIndex,
|
||||||
|
@ -127,7 +126,7 @@ PEVENTSOURCE
|
||||||
GetEventSourceByName(LPCWSTR Name)
|
GetEventSourceByName(LPCWSTR Name)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PEVENTSOURCE Result = NULL;
|
PEVENTSOURCE Item, Result = NULL;
|
||||||
|
|
||||||
DPRINT("GetEventSourceByName(%S)\n", Name);
|
DPRINT("GetEventSourceByName(%S)\n", Name);
|
||||||
EnterCriticalSection(&EventSourceListCs);
|
EnterCriticalSection(&EventSourceListCs);
|
||||||
|
@ -135,9 +134,9 @@ GetEventSourceByName(LPCWSTR Name)
|
||||||
CurrentEntry = EventSourceListHead.Flink;
|
CurrentEntry = EventSourceListHead.Flink;
|
||||||
while (CurrentEntry != &EventSourceListHead)
|
while (CurrentEntry != &EventSourceListHead)
|
||||||
{
|
{
|
||||||
PEVENTSOURCE Item = CONTAINING_RECORD(CurrentEntry,
|
Item = CONTAINING_RECORD(CurrentEntry,
|
||||||
EVENTSOURCE,
|
EVENTSOURCE,
|
||||||
EventSourceListEntry);
|
EventSourceListEntry);
|
||||||
|
|
||||||
DPRINT("Item->szName: %S\n", Item->szName);
|
DPRINT("Item->szName: %S\n", Item->szName);
|
||||||
// if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))
|
// if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))
|
||||||
|
|
|
@ -4,24 +4,253 @@
|
||||||
* FILE: base/services/eventlog/file.c
|
* FILE: base/services/eventlog/file.c
|
||||||
* PURPOSE: Event logging service
|
* PURPOSE: Event logging service
|
||||||
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
|
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
|
||||||
Michael Martin
|
* Michael Martin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include "eventlog.h"
|
#include "eventlog.h"
|
||||||
|
|
||||||
#include <ndk/iofuncs.h>
|
#include <ndk/iofuncs.h>
|
||||||
|
#include <ndk/kefuncs.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* LOG FILE LIST - GLOBALS ***************************************************/
|
||||||
|
|
||||||
static LIST_ENTRY LogFileListHead;
|
static LIST_ENTRY LogFileListHead;
|
||||||
static CRITICAL_SECTION LogFileListCs;
|
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
|
static NTSTATUS
|
||||||
LogfInitializeNew(PLOGFILE LogFile,
|
LogfInitializeNew(PLOGFILE LogFile,
|
||||||
|
@ -466,141 +695,6 @@ LogfClose(PLOGFILE LogFile,
|
||||||
return;
|
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
|
static BOOL
|
||||||
ReadAnsiLogEntry(HANDLE hFile,
|
ReadAnsiLogEntry(HANDLE hFile,
|
||||||
|
@ -930,7 +1024,7 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
|
||||||
{
|
{
|
||||||
DWORD dwWritten;
|
DWORD dwWritten;
|
||||||
DWORD dwRead;
|
DWORD dwRead;
|
||||||
SYSTEMTIME st;
|
LARGE_INTEGER SystemTime;
|
||||||
EVENTLOGEOF EofRec;
|
EVENTLOGEOF EofRec;
|
||||||
PEVENTLOGRECORD RecBuf;
|
PEVENTLOGRECORD RecBuf;
|
||||||
LARGE_INTEGER logFileSize;
|
LARGE_INTEGER logFileSize;
|
||||||
|
@ -940,11 +1034,11 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
GetSystemTime(&st);
|
|
||||||
SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);
|
|
||||||
|
|
||||||
RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
|
RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
|
||||||
|
|
||||||
|
NtQuerySystemTime(&SystemTime);
|
||||||
|
RtlTimeToSecondsSince1970(&SystemTime, &((PEVENTLOGRECORD)Buffer)->TimeWritten);
|
||||||
|
|
||||||
if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
|
if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
|
||||||
{
|
{
|
||||||
RtlReleaseResource(&LogFile->Lock);
|
RtlReleaseResource(&LogFile->Lock);
|
||||||
|
@ -1111,7 +1205,6 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LogfClearFile(PLOGFILE LogFile,
|
LogfClearFile(PLOGFILE LogFile,
|
||||||
PUNICODE_STRING BackupFileName)
|
PUNICODE_STRING BackupFileName)
|
||||||
|
@ -1123,12 +1216,11 @@ LogfClearFile(PLOGFILE LogFile,
|
||||||
if (BackupFileName->Length > 0)
|
if (BackupFileName->Length > 0)
|
||||||
{
|
{
|
||||||
/* Write a backup file */
|
/* Write a backup file */
|
||||||
Status = LogfBackupFile(LogFile,
|
Status = LogfBackupFile(LogFile, BackupFileName);
|
||||||
BackupFileName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("LogfBackupFile failed (Status: 0x%08lx)\n", 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);
|
DPRINT1("LogfInitializeNew failed (Status: 0x%08lx)\n", Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
RtlReleaseResource(&LogFile->Lock);
|
RtlReleaseResource(&LogFile->Lock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LogfBackupFile(PLOGFILE LogFile,
|
LogfBackupFile(PLOGFILE LogFile,
|
||||||
PUNICODE_STRING BackupFileName)
|
PUNICODE_STRING BackupFileName)
|
||||||
|
@ -1347,134 +1438,84 @@ Done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns 0 if nothing found. */
|
PBYTE
|
||||||
ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
|
LogfAllocAndBuildNewRecord(PULONG lpRecSize,
|
||||||
{
|
ULONG dwRecordNumber, // FIXME!
|
||||||
DWORD i;
|
USHORT wType,
|
||||||
|
USHORT wCategory,
|
||||||
for (i = 0; i < LogFile->OffsetInfoNext; i++)
|
ULONG dwEventId,
|
||||||
{
|
PCWSTR SourceName,
|
||||||
if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
|
PCWSTR ComputerName,
|
||||||
return LogFile->OffsetInfo[i].EventOffset;
|
ULONG dwSidLength,
|
||||||
}
|
PSID lpUserSid,
|
||||||
return 0;
|
USHORT wNumStrings,
|
||||||
}
|
WCHAR* lpStrings,
|
||||||
|
ULONG dwDataSize,
|
||||||
DWORD LogfGetOldestRecord(PLOGFILE LogFile)
|
PVOID lpRawData)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
DWORD dwRecSize;
|
DWORD dwRecSize;
|
||||||
PEVENTLOGRECORD pRec;
|
PEVENTLOGRECORD pRec;
|
||||||
SYSTEMTIME SysTime;
|
LARGE_INTEGER SystemTime;
|
||||||
WCHAR *str;
|
WCHAR *str;
|
||||||
UINT i, pos;
|
UINT i, pos;
|
||||||
PBYTE Buffer;
|
PBYTE Buffer;
|
||||||
|
|
||||||
dwRecSize =
|
dwRecSize =
|
||||||
sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) +
|
sizeof(EVENTLOGRECORD) + (lstrlenW(SourceName) +
|
||||||
lstrlenW(SourceName) + 2) * sizeof(WCHAR);
|
lstrlenW(ComputerName) + 2) * sizeof(WCHAR);
|
||||||
|
|
||||||
if (dwRecSize % 4 != 0)
|
/* Align on DWORD boundary for the SID */
|
||||||
dwRecSize += 4 - (dwRecSize % 4);
|
dwRecSize = ROUND_UP(dwRecSize, sizeof(ULONG));
|
||||||
|
|
||||||
dwRecSize += dwSidLength;
|
dwRecSize += dwSidLength;
|
||||||
|
|
||||||
|
/* Add the sizes for the strings array */
|
||||||
for (i = 0, str = lpStrings; i < wNumStrings; i++)
|
for (i = 0, str = lpStrings; i < wNumStrings; i++)
|
||||||
{
|
{
|
||||||
dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
|
dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||||
str += lstrlenW(str) + 1;
|
str += lstrlenW(str) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the data size */
|
||||||
dwRecSize += dwDataSize;
|
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);
|
Buffer = HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, dwRecSize);
|
||||||
|
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
{
|
{
|
||||||
DPRINT1("Can't allocate heap!\n");
|
DPRINT1("Cannot allocate heap!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pRec = (PEVENTLOGRECORD) Buffer;
|
pRec = (PEVENTLOGRECORD)Buffer;
|
||||||
pRec->Length = dwRecSize;
|
pRec->Length = dwRecSize;
|
||||||
pRec->Reserved = LOGFILE_SIGNATURE;
|
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;
|
pRec->RecordNumber = dwRecordNumber;
|
||||||
|
|
||||||
GetSystemTime(&SysTime);
|
NtQuerySystemTime(&SystemTime);
|
||||||
SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
|
RtlTimeToSecondsSince1970(&SystemTime, &pRec->TimeGenerated);
|
||||||
SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);
|
// FIXME: Already done in LogfWriteRecord. Is it needed to do that here first??
|
||||||
|
RtlTimeToSecondsSince1970(&SystemTime, &pRec->TimeWritten);
|
||||||
|
|
||||||
pRec->EventID = dwEventId;
|
pRec->EventID = dwEventId;
|
||||||
pRec->EventType = wType;
|
pRec->EventType = wType;
|
||||||
|
@ -1487,11 +1528,10 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
|
||||||
lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
|
lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
|
||||||
pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
|
pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
/* Align on DWORD boundary for the SID */
|
||||||
|
pos = ROUND_UP(pos, sizeof(ULONG));
|
||||||
|
|
||||||
pRec->UserSidOffset = pos;
|
pRec->UserSidOffset = pos;
|
||||||
|
|
||||||
if (pos % 4 != 0)
|
|
||||||
pos += 4 - (pos % 4);
|
|
||||||
|
|
||||||
if (dwSidLength)
|
if (dwSidLength)
|
||||||
{
|
{
|
||||||
CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
|
CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
|
||||||
|
@ -1517,53 +1557,49 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
|
||||||
pos += dwDataSize;
|
pos += dwDataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos % 4 != 0)
|
/* Align on DWORD boundary for the full structure */
|
||||||
pos += 4 - (pos % 4);
|
pos = ROUND_UP(pos, sizeof(ULONG));
|
||||||
|
|
||||||
|
/* Initialize the trailing 'Length' member */
|
||||||
*((PDWORD) (Buffer + pos)) = dwRecSize;
|
*((PDWORD) (Buffer + pos)) = dwRecSize;
|
||||||
|
|
||||||
*lpRecSize = dwRecSize;
|
*lpRecSize = dwRecSize;
|
||||||
return Buffer;
|
return Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
LogfReportEvent(WORD wType,
|
LogfReportEvent(USHORT wType,
|
||||||
WORD wCategory,
|
USHORT wCategory,
|
||||||
DWORD dwEventId,
|
ULONG dwEventId,
|
||||||
WORD wNumStrings,
|
USHORT wNumStrings,
|
||||||
WCHAR *lpStrings,
|
WCHAR* lpStrings,
|
||||||
DWORD dwDataSize,
|
ULONG dwDataSize,
|
||||||
LPVOID lpRawData)
|
PVOID lpRawData)
|
||||||
{
|
{
|
||||||
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||||||
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
|
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
|
||||||
PEVENTSOURCE pEventSource = NULL;
|
|
||||||
PBYTE logBuffer;
|
PBYTE logBuffer;
|
||||||
DWORD lastRec;
|
DWORD lastRec;
|
||||||
DWORD recSize;
|
DWORD recSize;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
|
||||||
|
if (!EventLogSource)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
|
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
|
||||||
{
|
{
|
||||||
szComputerName[0] = 0;
|
szComputerName[0] = L'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
pEventSource = GetEventSourceByName(L"EventLog");
|
lastRec = LogfGetCurrentRecord(EventLogSource->LogFile);
|
||||||
if (pEventSource == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastRec = LogfGetCurrentRecord(pEventSource->LogFile);
|
|
||||||
|
|
||||||
logBuffer = LogfAllocAndBuildNewRecord(&recSize,
|
logBuffer = LogfAllocAndBuildNewRecord(&recSize,
|
||||||
lastRec,
|
lastRec, // FIXME!
|
||||||
wType,
|
wType,
|
||||||
wCategory,
|
wCategory,
|
||||||
dwEventId,
|
dwEventId,
|
||||||
pEventSource->szName,
|
EventLogSource->szName,
|
||||||
(LPCWSTR)szComputerName,
|
szComputerName,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
wNumStrings,
|
wNumStrings,
|
||||||
|
@ -1571,10 +1607,10 @@ LogfReportEvent(WORD wType,
|
||||||
dwDataSize,
|
dwDataSize,
|
||||||
lpRawData);
|
lpRawData);
|
||||||
|
|
||||||
dwError = LogfWriteData(pEventSource->LogFile, recSize, logBuffer);
|
dwError = LogfWriteData(EventLogSource->LogFile, recSize, logBuffer);
|
||||||
if (!dwError)
|
if (!dwError)
|
||||||
{
|
{
|
||||||
DPRINT1("ERROR WRITING TO EventLog %S\n", pEventSource->LogFile->FileName);
|
DPRINT1("ERROR WRITING TO EventLog %S\n", EventLogSource->LogFile->FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogfFreeRecord(logBuffer);
|
LogfFreeRecord(logBuffer);
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
HANDLE ConnectPortHandle = NULL;
|
static HANDLE ConnectPortHandle = NULL;
|
||||||
HANDLE MessagePortHandle = NULL;
|
static HANDLE MessagePortHandle = NULL;
|
||||||
extern BOOL onLiveCD;
|
extern BOOL onLiveCD;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
@ -70,7 +70,6 @@ NTSTATUS InitLogPort(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NtListenPort(ConnectPortHandle, &Request);
|
Status = NtListenPort(ConnectPortHandle, &Request);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
|
DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
|
||||||
|
@ -79,7 +78,6 @@ NTSTATUS InitLogPort(VOID)
|
||||||
|
|
||||||
Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle,
|
Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle,
|
||||||
NULL, TRUE, NULL, NULL);
|
NULL, TRUE, NULL, NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
|
DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
|
||||||
|
@ -93,7 +91,7 @@ NTSTATUS InitLogPort(VOID)
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByeBye:
|
ByeBye:
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (ConnectPortHandle != NULL)
|
if (ConnectPortHandle != NULL)
|
||||||
|
@ -114,6 +112,8 @@ NTSTATUS ProcessPortMessage(VOID)
|
||||||
DWORD dwRecSize;
|
DWORD dwRecSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PLOGFILE SystemLog = NULL;
|
PLOGFILE SystemLog = NULL;
|
||||||
|
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||||||
|
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
|
||||||
|
|
||||||
DPRINT("ProcessPortMessage() called\n");
|
DPRINT("ProcessPortMessage() called\n");
|
||||||
|
|
||||||
|
@ -150,18 +150,27 @@ NTSTATUS ProcessPortMessage(VOID)
|
||||||
Message = (PIO_ERROR_LOG_MESSAGE) & Request.Message;
|
Message = (PIO_ERROR_LOG_MESSAGE) & Request.Message;
|
||||||
ulRecNum = SystemLog ? SystemLog->Header.CurrentRecordNumber : 0;
|
ulRecNum = SystemLog ? SystemLog->Header.CurrentRecordNumber : 0;
|
||||||
|
|
||||||
pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(&dwRecSize,
|
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
|
||||||
ulRecNum, Message->Type, Message->EntryData.EventCategory,
|
{
|
||||||
Message->EntryData.ErrorCode,
|
szComputerName[0] = L'\0';
|
||||||
(WCHAR *) (((PBYTE) Message) + Message->DriverNameOffset),
|
}
|
||||||
L"MyComputer", /* FIXME */
|
|
||||||
0,
|
// TODO: Log more information??
|
||||||
NULL,
|
|
||||||
Message->EntryData.NumberOfStrings,
|
pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(
|
||||||
(WCHAR *) (((PBYTE) Message) + Message->EntryData.StringOffset),
|
&dwRecSize,
|
||||||
Message->EntryData.DumpDataSize,
|
ulRecNum, // FIXME!
|
||||||
(LPVOID) (((PBYTE) Message) + sizeof(IO_ERROR_LOG_PACKET) -
|
Message->Type,
|
||||||
sizeof(ULONG)));
|
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)
|
if (pRec == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* PURPOSE: Event logging service
|
* PURPOSE: Event logging service
|
||||||
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
|
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
|
||||||
* Copyright 2008 Michael Martin
|
* Copyright 2008 Michael Martin
|
||||||
|
* Copyright 2010-2011 Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -49,27 +50,31 @@ DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
|
ElfCreateEventLogHandle(PLOGHANDLE* LogHandle,
|
||||||
LPCWSTR Name,
|
PUNICODE_STRING LogName,
|
||||||
BOOL Create)
|
BOOLEAN Create)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
PLOGFILE currentLogFile = NULL;
|
PLOGFILE currentLogFile = NULL;
|
||||||
INT i, LogsActive;
|
DWORD i, LogsActive;
|
||||||
PEVENTSOURCE pEventSource;
|
PEVENTSOURCE pEventSource;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
|
DPRINT("ElfCreateEventLogHandle(Name: %wZ)\n", LogName);
|
||||||
|
|
||||||
lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
|
*LogHandle = NULL;
|
||||||
+ ((wcslen(Name) + 1) * sizeof(WCHAR)));
|
|
||||||
|
i = (LogName->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
|
||||||
|
lpLogHandle = HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
FIELD_OFFSET(LOGHANDLE, szName[i]));
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to allocate Heap!\n");
|
DPRINT1("Failed to allocate Heap!\n");
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
wcscpy(lpLogHandle->szName, Name);
|
StringCchCopy(lpLogHandle->szName, i, LogName->Buffer);
|
||||||
|
|
||||||
/* Get the number of Log Files the EventLog service found */
|
/* Get the number of Log Files the EventLog service found */
|
||||||
LogsActive = LogfListItemCount();
|
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 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);
|
DPRINT("EventSource: %p\n", pEventSource);
|
||||||
if (pEventSource)
|
if (pEventSource)
|
||||||
{
|
{
|
||||||
|
@ -106,9 +111,9 @@ ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
|
||||||
{
|
{
|
||||||
currentLogFile = LogfListItemByIndex(i);
|
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);
|
lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -150,15 +155,16 @@ Done:
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
ElfCreateBackupLogHandle(PLOGHANDLE *LogHandle,
|
ElfCreateBackupLogHandle(PLOGHANDLE* LogHandle,
|
||||||
PUNICODE_STRING FileName)
|
PUNICODE_STRING FileName)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
DPRINT("ElfCreateBackupLogHandle(FileName: %wZ)\n", FileName);
|
DPRINT("ElfCreateBackupLogHandle(FileName: %wZ)\n", FileName);
|
||||||
|
|
||||||
|
*LogHandle = NULL;
|
||||||
|
|
||||||
lpLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGHANDLE));
|
lpLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGHANDLE));
|
||||||
if (lpLogHandle == NULL)
|
if (lpLogHandle == NULL)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +208,8 @@ Done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
static PLOGHANDLE
|
||||||
|
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
|
@ -224,26 +231,28 @@ PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
ElfDeleteEventLogHandle(IELF_HANDLE LogHandle)
|
ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(*LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
RemoveEntryList(&lpLogHandle->LogHandleListEntry);
|
RemoveEntryList(&lpLogHandle->LogHandleListEntry);
|
||||||
LogfClose(lpLogHandle->LogFile, FALSE);
|
LogfClose(lpLogHandle->LogFile, FALSE);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, lpLogHandle);
|
HeapFree(GetProcessHeap(), 0, lpLogHandle);
|
||||||
|
|
||||||
|
*LogHandle = NULL;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 0 */
|
/* Function 0 */
|
||||||
NTSTATUS ElfrClearELFW(
|
NTSTATUS
|
||||||
|
ElfrClearELFW(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
PRPC_UNICODE_STRING BackupFileName)
|
PRPC_UNICODE_STRING BackupFileName)
|
||||||
{
|
{
|
||||||
|
@ -253,9 +262,7 @@ NTSTATUS ElfrClearELFW(
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
/* Fail, if the log file is a backup file */
|
/* Fail, if the log file is a backup file */
|
||||||
if (lpLogHandle->Flags & LOG_HANDLE_BACKUP_FILE)
|
if (lpLogHandle->Flags & LOG_HANDLE_BACKUP_FILE)
|
||||||
|
@ -267,7 +274,8 @@ NTSTATUS ElfrClearELFW(
|
||||||
|
|
||||||
|
|
||||||
/* Function 1 */
|
/* Function 1 */
|
||||||
NTSTATUS ElfrBackupELFW(
|
NTSTATUS
|
||||||
|
ElfrBackupELFW(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
PRPC_UNICODE_STRING BackupFileName)
|
PRPC_UNICODE_STRING BackupFileName)
|
||||||
{
|
{
|
||||||
|
@ -277,9 +285,7 @@ NTSTATUS ElfrBackupELFW(
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
return LogfBackupFile(lpLogHandle->LogFile,
|
return LogfBackupFile(lpLogHandle->LogFile,
|
||||||
(PUNICODE_STRING)BackupFileName);
|
(PUNICODE_STRING)BackupFileName);
|
||||||
|
@ -287,25 +293,28 @@ NTSTATUS ElfrBackupELFW(
|
||||||
|
|
||||||
|
|
||||||
/* Function 2 */
|
/* Function 2 */
|
||||||
NTSTATUS ElfrCloseEL(
|
NTSTATUS
|
||||||
IELF_HANDLE *LogHandle)
|
ElfrCloseEL(
|
||||||
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
return ElfDeleteEventLogHandle(*LogHandle);
|
return ElfDeleteEventLogHandle(LogHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 3 */
|
/* Function 3 */
|
||||||
NTSTATUS ElfrDeregisterEventSource(
|
NTSTATUS
|
||||||
IELF_HANDLE *LogHandle)
|
ElfrDeregisterEventSource(
|
||||||
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
return ElfDeleteEventLogHandle(*LogHandle);
|
return ElfDeleteEventLogHandle(LogHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 4 */
|
/* Function 4 */
|
||||||
NTSTATUS ElfrNumberOfRecords(
|
NTSTATUS
|
||||||
|
ElfrNumberOfRecords(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD *NumberOfRecords)
|
PULONG NumberOfRecords)
|
||||||
{
|
{
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
PLOGFILE lpLogFile;
|
PLOGFILE lpLogFile;
|
||||||
|
@ -314,9 +323,10 @@ NTSTATUS ElfrNumberOfRecords(
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
if (!NumberOfRecords)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
lpLogFile = lpLogHandle->LogFile;
|
lpLogFile = lpLogHandle->LogFile;
|
||||||
|
|
||||||
|
@ -332,22 +342,19 @@ NTSTATUS ElfrNumberOfRecords(
|
||||||
|
|
||||||
|
|
||||||
/* Function 5 */
|
/* Function 5 */
|
||||||
NTSTATUS ElfrOldestRecord(
|
NTSTATUS
|
||||||
|
ElfrOldestRecord(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD *OldestRecordNumber)
|
PULONG OldestRecordNumber)
|
||||||
{
|
{
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
if (!OldestRecordNumber)
|
if (!OldestRecordNumber)
|
||||||
{
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
|
||||||
|
|
||||||
*OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
|
*OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
|
||||||
|
|
||||||
|
@ -356,26 +363,26 @@ NTSTATUS ElfrOldestRecord(
|
||||||
|
|
||||||
|
|
||||||
/* Function 6 */
|
/* Function 6 */
|
||||||
NTSTATUS ElfrChangeNotify(
|
NTSTATUS
|
||||||
|
ElfrChangeNotify(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
RPC_CLIENT_ID ClientId,
|
RPC_CLIENT_ID ClientId,
|
||||||
DWORD Event)
|
ULONG Event)
|
||||||
{
|
{
|
||||||
DPRINT("ElfrChangeNotify()");
|
|
||||||
|
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 7 */
|
/* Function 7 */
|
||||||
NTSTATUS ElfrOpenELW(
|
NTSTATUS
|
||||||
|
ElfrOpenELW(
|
||||||
EVENTLOG_HANDLE_W UNCServerName,
|
EVENTLOG_HANDLE_W UNCServerName,
|
||||||
PRPC_UNICODE_STRING ModuleName,
|
PRPC_UNICODE_STRING ModuleName,
|
||||||
PRPC_UNICODE_STRING RegModuleName,
|
PRPC_UNICODE_STRING RegModuleName,
|
||||||
DWORD MajorVersion,
|
ULONG MajorVersion,
|
||||||
DWORD MinorVersion,
|
ULONG MinorVersion,
|
||||||
IELF_HANDLE *LogHandle)
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
if ((MajorVersion != 1) || (MinorVersion != 1))
|
if ((MajorVersion != 1) || (MinorVersion != 1))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -384,24 +391,25 @@ NTSTATUS ElfrOpenELW(
|
||||||
if (RegModuleName->Length > 0)
|
if (RegModuleName->Length > 0)
|
||||||
return STATUS_INVALID_PARAMETER;
|
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,
|
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||||
ModuleName->Buffer,
|
(PUNICODE_STRING)ModuleName,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 8 */
|
/* Function 8 */
|
||||||
NTSTATUS ElfrRegisterEventSourceW(
|
NTSTATUS
|
||||||
|
ElfrRegisterEventSourceW(
|
||||||
EVENTLOG_HANDLE_W UNCServerName,
|
EVENTLOG_HANDLE_W UNCServerName,
|
||||||
PRPC_UNICODE_STRING ModuleName,
|
PRPC_UNICODE_STRING ModuleName,
|
||||||
PRPC_UNICODE_STRING RegModuleName,
|
PRPC_UNICODE_STRING RegModuleName,
|
||||||
DWORD MajorVersion,
|
ULONG MajorVersion,
|
||||||
DWORD MinorVersion,
|
ULONG MinorVersion,
|
||||||
IELF_HANDLE *LogHandle)
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
DPRINT("ElfrRegisterEventSourceW()\n");
|
DPRINT("ElfrRegisterEventSourceW()\n");
|
||||||
|
|
||||||
|
@ -412,49 +420,51 @@ NTSTATUS ElfrRegisterEventSourceW(
|
||||||
if (RegModuleName->Length > 0)
|
if (RegModuleName->Length > 0)
|
||||||
return STATUS_INVALID_PARAMETER;
|
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,
|
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||||
ModuleName->Buffer,
|
(PUNICODE_STRING)ModuleName,
|
||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 9 */
|
/* Function 9 */
|
||||||
NTSTATUS ElfrOpenBELW(
|
NTSTATUS
|
||||||
|
ElfrOpenBELW(
|
||||||
EVENTLOG_HANDLE_W UNCServerName,
|
EVENTLOG_HANDLE_W UNCServerName,
|
||||||
PRPC_UNICODE_STRING BackupFileName,
|
PRPC_UNICODE_STRING BackupFileName,
|
||||||
DWORD MajorVersion,
|
ULONG MajorVersion,
|
||||||
DWORD MinorVersion,
|
ULONG MinorVersion,
|
||||||
IELF_HANDLE *LogHandle)
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName);
|
DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName);
|
||||||
|
|
||||||
if ((MajorVersion != 1) || (MinorVersion != 1))
|
if ((MajorVersion != 1) || (MinorVersion != 1))
|
||||||
return STATUS_INVALID_PARAMETER;
|
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);
|
(PUNICODE_STRING)BackupFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 10 */
|
/* Function 10 */
|
||||||
NTSTATUS ElfrReadELW(
|
NTSTATUS
|
||||||
|
ElfrReadELW(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD ReadFlags,
|
ULONG ReadFlags,
|
||||||
DWORD RecordOffset,
|
ULONG RecordOffset,
|
||||||
RULONG NumberOfBytesToRead,
|
RULONG NumberOfBytesToRead,
|
||||||
BYTE *Buffer,
|
PBYTE Buffer,
|
||||||
DWORD *NumberOfBytesRead,
|
PULONG NumberOfBytesRead,
|
||||||
DWORD *MinNumberOfBytesNeeded)
|
PULONG MinNumberOfBytesNeeded)
|
||||||
{
|
{
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
@ -462,9 +472,7 @@ NTSTATUS ElfrReadELW(
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -479,11 +487,16 @@ NTSTATUS ElfrReadELW(
|
||||||
RecordNumber = RecordOffset;
|
RecordNumber = RecordOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
|
dwError = LogfReadEvent(lpLogHandle->LogFile,
|
||||||
NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded,
|
ReadFlags,
|
||||||
|
&RecordNumber,
|
||||||
|
NumberOfBytesToRead,
|
||||||
|
Buffer,
|
||||||
|
NumberOfBytesRead,
|
||||||
|
MinNumberOfBytesNeeded,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
/* Update the handles CurrentRecord if success*/
|
/* Update the handle's CurrentRecord if success */
|
||||||
if (dwError == ERROR_SUCCESS)
|
if (dwError == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
lpLogHandle->CurrentRecord = RecordNumber;
|
lpLogHandle->CurrentRecord = RecordNumber;
|
||||||
|
@ -498,21 +511,22 @@ NTSTATUS ElfrReadELW(
|
||||||
|
|
||||||
|
|
||||||
/* Function 11 */
|
/* Function 11 */
|
||||||
NTSTATUS ElfrReportEventW(
|
NTSTATUS
|
||||||
|
ElfrReportEventW(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD Time,
|
ULONG Time,
|
||||||
USHORT EventType,
|
USHORT EventType,
|
||||||
USHORT EventCategory,
|
USHORT EventCategory,
|
||||||
DWORD EventID,
|
ULONG EventID,
|
||||||
USHORT NumStrings,
|
USHORT NumStrings,
|
||||||
DWORD DataSize,
|
ULONG DataSize,
|
||||||
PRPC_UNICODE_STRING ComputerName,
|
PRPC_UNICODE_STRING ComputerName,
|
||||||
PRPC_SID UserSID,
|
PRPC_SID UserSID,
|
||||||
PRPC_UNICODE_STRING Strings[],
|
PRPC_UNICODE_STRING Strings[],
|
||||||
BYTE *Data,
|
PBYTE Data,
|
||||||
USHORT Flags,
|
USHORT Flags,
|
||||||
DWORD *RecordNumber,
|
PULONG RecordNumber,
|
||||||
DWORD *TimeWritten)
|
PULONG TimeWritten)
|
||||||
{
|
{
|
||||||
USHORT i;
|
USHORT i;
|
||||||
PBYTE LogBuffer;
|
PBYTE LogBuffer;
|
||||||
|
@ -527,15 +541,11 @@ NTSTATUS ElfrReportEventW(
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
/* Flags must be 0 */
|
/* Flags must be 0 */
|
||||||
if (Flags)
|
if (Flags)
|
||||||
{
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
|
||||||
|
|
||||||
lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile);
|
lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile);
|
||||||
|
|
||||||
|
@ -571,7 +581,7 @@ NTSTATUS ElfrReportEventW(
|
||||||
DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
|
DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dwStringsSize += Strings[i]->Length + sizeof UNICODE_NULL;
|
dwStringsSize += Strings[i]->Length + sizeof(UNICODE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
|
lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
|
||||||
|
@ -583,16 +593,16 @@ NTSTATUS ElfrReportEventW(
|
||||||
|
|
||||||
for (i = 0; i < NumStrings; i++)
|
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);
|
pos += Strings[i]->Length / sizeof(WCHAR);
|
||||||
lpStrings[pos] = UNICODE_NULL;
|
lpStrings[pos] = UNICODE_NULL;
|
||||||
pos += sizeof UNICODE_NULL / sizeof(WCHAR);
|
pos += sizeof(UNICODE_NULL) / sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UserSID)
|
if (UserSID)
|
||||||
dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
|
dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
|
||||||
LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
|
LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
|
||||||
lastRec,
|
lastRec, // FIXME!
|
||||||
EventType,
|
EventType,
|
||||||
EventCategory,
|
EventCategory,
|
||||||
EventID,
|
EventID,
|
||||||
|
@ -620,7 +630,8 @@ NTSTATUS ElfrReportEventW(
|
||||||
|
|
||||||
|
|
||||||
/* Function 12 */
|
/* Function 12 */
|
||||||
NTSTATUS ElfrClearELFA(
|
NTSTATUS
|
||||||
|
ElfrClearELFA(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
PRPC_STRING BackupFileName)
|
PRPC_STRING BackupFileName)
|
||||||
{
|
{
|
||||||
|
@ -643,7 +654,8 @@ NTSTATUS ElfrClearELFA(
|
||||||
|
|
||||||
|
|
||||||
/* Function 13 */
|
/* Function 13 */
|
||||||
NTSTATUS ElfrBackupELFA(
|
NTSTATUS
|
||||||
|
ElfrBackupELFA(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
PRPC_STRING BackupFileName)
|
PRPC_STRING BackupFileName)
|
||||||
{
|
{
|
||||||
|
@ -666,13 +678,14 @@ NTSTATUS ElfrBackupELFA(
|
||||||
|
|
||||||
|
|
||||||
/* Function 14 */
|
/* Function 14 */
|
||||||
NTSTATUS ElfrOpenELA(
|
NTSTATUS
|
||||||
|
ElfrOpenELA(
|
||||||
EVENTLOG_HANDLE_A UNCServerName,
|
EVENTLOG_HANDLE_A UNCServerName,
|
||||||
PRPC_STRING ModuleName,
|
PRPC_STRING ModuleName,
|
||||||
PRPC_STRING RegModuleName,
|
PRPC_STRING RegModuleName,
|
||||||
DWORD MajorVersion,
|
ULONG MajorVersion,
|
||||||
DWORD MinorVersion,
|
ULONG MinorVersion,
|
||||||
IELF_HANDLE *LogHandle)
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
UNICODE_STRING ModuleNameW;
|
UNICODE_STRING ModuleNameW;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -690,8 +703,8 @@ NTSTATUS ElfrOpenELA(
|
||||||
|
|
||||||
/* FIXME: Must verify that caller has read access */
|
/* FIXME: Must verify that caller has read access */
|
||||||
|
|
||||||
Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
|
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||||
ModuleNameW.Buffer,
|
&ModuleNameW,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&ModuleNameW);
|
RtlFreeUnicodeString(&ModuleNameW);
|
||||||
|
@ -701,13 +714,14 @@ NTSTATUS ElfrOpenELA(
|
||||||
|
|
||||||
|
|
||||||
/* Function 15 */
|
/* Function 15 */
|
||||||
NTSTATUS ElfrRegisterEventSourceA(
|
NTSTATUS
|
||||||
|
ElfrRegisterEventSourceA(
|
||||||
EVENTLOG_HANDLE_A UNCServerName,
|
EVENTLOG_HANDLE_A UNCServerName,
|
||||||
PRPC_STRING ModuleName,
|
PRPC_STRING ModuleName,
|
||||||
PRPC_STRING RegModuleName,
|
PRPC_STRING RegModuleName,
|
||||||
DWORD MajorVersion,
|
ULONG MajorVersion,
|
||||||
DWORD MinorVersion,
|
ULONG MinorVersion,
|
||||||
IELF_HANDLE *LogHandle)
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
UNICODE_STRING ModuleNameW;
|
UNICODE_STRING ModuleNameW;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -736,8 +750,8 @@ NTSTATUS ElfrRegisterEventSourceA(
|
||||||
|
|
||||||
/* FIXME: Must verify that caller has write access */
|
/* FIXME: Must verify that caller has write access */
|
||||||
|
|
||||||
Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
|
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
|
||||||
ModuleNameW.Buffer,
|
&ModuleNameW,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&ModuleNameW);
|
RtlFreeUnicodeString(&ModuleNameW);
|
||||||
|
@ -747,12 +761,13 @@ NTSTATUS ElfrRegisterEventSourceA(
|
||||||
|
|
||||||
|
|
||||||
/* Function 16 */
|
/* Function 16 */
|
||||||
NTSTATUS ElfrOpenBELA(
|
NTSTATUS
|
||||||
|
ElfrOpenBELA(
|
||||||
EVENTLOG_HANDLE_A UNCServerName,
|
EVENTLOG_HANDLE_A UNCServerName,
|
||||||
PRPC_STRING BackupFileName,
|
PRPC_STRING BackupFileName,
|
||||||
DWORD MajorVersion,
|
ULONG MajorVersion,
|
||||||
DWORD MinorVersion,
|
ULONG MinorVersion,
|
||||||
IELF_HANDLE *LogHandle)
|
PIELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
UNICODE_STRING BackupFileNameW;
|
UNICODE_STRING BackupFileNameW;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -774,11 +789,11 @@ NTSTATUS ElfrOpenBELA(
|
||||||
return STATUS_INVALID_PARAMETER;
|
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);
|
&BackupFileNameW);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&BackupFileNameW);
|
RtlFreeUnicodeString(&BackupFileNameW);
|
||||||
|
@ -788,14 +803,15 @@ NTSTATUS ElfrOpenBELA(
|
||||||
|
|
||||||
|
|
||||||
/* Function 17 */
|
/* Function 17 */
|
||||||
NTSTATUS ElfrReadELA(
|
NTSTATUS
|
||||||
|
ElfrReadELA(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD ReadFlags,
|
ULONG ReadFlags,
|
||||||
DWORD RecordOffset,
|
ULONG RecordOffset,
|
||||||
RULONG NumberOfBytesToRead,
|
RULONG NumberOfBytesToRead,
|
||||||
BYTE *Buffer,
|
PBYTE Buffer,
|
||||||
DWORD *NumberOfBytesRead,
|
PULONG NumberOfBytesRead,
|
||||||
DWORD *MinNumberOfBytesNeeded)
|
PULONG MinNumberOfBytesNeeded)
|
||||||
{
|
{
|
||||||
PLOGHANDLE lpLogHandle;
|
PLOGHANDLE lpLogHandle;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
@ -803,9 +819,7 @@ NTSTATUS ElfrReadELA(
|
||||||
|
|
||||||
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!lpLogHandle)
|
if (!lpLogHandle)
|
||||||
{
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
|
||||||
|
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -829,7 +843,7 @@ NTSTATUS ElfrReadELA(
|
||||||
MinNumberOfBytesNeeded,
|
MinNumberOfBytesNeeded,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
/* Update the handles CurrentRecord if success*/
|
/* Update the handle's CurrentRecord if success */
|
||||||
if (dwError == ERROR_SUCCESS)
|
if (dwError == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
lpLogHandle->CurrentRecord = RecordNumber;
|
lpLogHandle->CurrentRecord = RecordNumber;
|
||||||
|
@ -844,21 +858,22 @@ NTSTATUS ElfrReadELA(
|
||||||
|
|
||||||
|
|
||||||
/* Function 18 */
|
/* Function 18 */
|
||||||
NTSTATUS ElfrReportEventA(
|
NTSTATUS
|
||||||
|
ElfrReportEventA(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD Time,
|
ULONG Time,
|
||||||
USHORT EventType,
|
USHORT EventType,
|
||||||
USHORT EventCategory,
|
USHORT EventCategory,
|
||||||
DWORD EventID,
|
ULONG EventID,
|
||||||
USHORT NumStrings,
|
USHORT NumStrings,
|
||||||
DWORD DataSize,
|
ULONG DataSize,
|
||||||
PRPC_STRING ComputerName,
|
PRPC_STRING ComputerName,
|
||||||
PRPC_SID UserSID,
|
PRPC_SID UserSID,
|
||||||
PRPC_STRING Strings[],
|
PRPC_STRING Strings[],
|
||||||
BYTE *Data,
|
PBYTE Data,
|
||||||
USHORT Flags,
|
USHORT Flags,
|
||||||
DWORD *RecordNumber,
|
PULONG RecordNumber,
|
||||||
DWORD *TimeWritten)
|
PULONG TimeWritten)
|
||||||
{
|
{
|
||||||
UNICODE_STRING ComputerNameW;
|
UNICODE_STRING ComputerNameW;
|
||||||
PUNICODE_STRING *StringsArrayW = NULL;
|
PUNICODE_STRING *StringsArrayW = NULL;
|
||||||
|
@ -891,7 +906,7 @@ NTSTATUS ElfrReportEventA(
|
||||||
{
|
{
|
||||||
StringsArrayW = HeapAlloc(MyHeap,
|
StringsArrayW = HeapAlloc(MyHeap,
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
NumStrings * sizeof (PUNICODE_STRING));
|
NumStrings * sizeof(PUNICODE_STRING));
|
||||||
if (StringsArrayW == NULL)
|
if (StringsArrayW == NULL)
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
|
@ -964,7 +979,8 @@ Done:
|
||||||
|
|
||||||
|
|
||||||
/* Function 19 */
|
/* Function 19 */
|
||||||
NTSTATUS ElfrRegisterClusterSvc(
|
NTSTATUS
|
||||||
|
ElfrRegisterClusterSvc(
|
||||||
handle_t BindingHandle)
|
handle_t BindingHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -973,7 +989,8 @@ NTSTATUS ElfrRegisterClusterSvc(
|
||||||
|
|
||||||
|
|
||||||
/* Function 20 */
|
/* Function 20 */
|
||||||
NTSTATUS ElfrDeregisterClusterSvc(
|
NTSTATUS
|
||||||
|
ElfrDeregisterClusterSvc(
|
||||||
handle_t BindingHandle)
|
handle_t BindingHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -982,7 +999,8 @@ NTSTATUS ElfrDeregisterClusterSvc(
|
||||||
|
|
||||||
|
|
||||||
/* Function 21 */
|
/* Function 21 */
|
||||||
NTSTATUS ElfrWriteClusterEvents(
|
NTSTATUS
|
||||||
|
ElfrWriteClusterEvents(
|
||||||
handle_t BindingHandle)
|
handle_t BindingHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -991,16 +1009,20 @@ NTSTATUS ElfrWriteClusterEvents(
|
||||||
|
|
||||||
|
|
||||||
/* Function 22 */
|
/* Function 22 */
|
||||||
NTSTATUS ElfrGetLogInformation(
|
NTSTATUS
|
||||||
|
ElfrGetLogInformation(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD InfoLevel,
|
ULONG InfoLevel,
|
||||||
BYTE *Buffer,
|
PBYTE Buffer,
|
||||||
DWORD cbBufSize,
|
ULONG cbBufSize,
|
||||||
DWORD *pcbBytesNeeded)
|
PULONG pcbBytesNeeded)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PLOGHANDLE lpLogHandle;
|
||||||
|
|
||||||
/* FIXME: check handle first */
|
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
|
if (!lpLogHandle)
|
||||||
|
return STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
switch (InfoLevel)
|
switch (InfoLevel)
|
||||||
{
|
{
|
||||||
|
@ -1011,10 +1033,16 @@ NTSTATUS ElfrGetLogInformation(
|
||||||
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
|
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
|
||||||
if (cbBufSize < 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;
|
break;
|
||||||
|
|
||||||
|
@ -1028,7 +1056,8 @@ NTSTATUS ElfrGetLogInformation(
|
||||||
|
|
||||||
|
|
||||||
/* Function 23 */
|
/* Function 23 */
|
||||||
NTSTATUS ElfrFlushEL(
|
NTSTATUS
|
||||||
|
ElfrFlushEL(
|
||||||
IELF_HANDLE LogHandle)
|
IELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -1037,22 +1066,23 @@ NTSTATUS ElfrFlushEL(
|
||||||
|
|
||||||
|
|
||||||
/* Function 24 */
|
/* Function 24 */
|
||||||
NTSTATUS ElfrReportEventAndSourceW(
|
NTSTATUS
|
||||||
|
ElfrReportEventAndSourceW(
|
||||||
IELF_HANDLE LogHandle,
|
IELF_HANDLE LogHandle,
|
||||||
DWORD Time,
|
ULONG Time,
|
||||||
USHORT EventType,
|
USHORT EventType,
|
||||||
USHORT EventCategory,
|
USHORT EventCategory,
|
||||||
ULONG EventID,
|
ULONG EventID,
|
||||||
PRPC_UNICODE_STRING SourceName,
|
PRPC_UNICODE_STRING SourceName,
|
||||||
USHORT NumStrings,
|
USHORT NumStrings,
|
||||||
DWORD DataSize,
|
ULONG DataSize,
|
||||||
PRPC_UNICODE_STRING ComputerName,
|
PRPC_UNICODE_STRING ComputerName,
|
||||||
PRPC_SID UserSID,
|
PRPC_SID UserSID,
|
||||||
PRPC_UNICODE_STRING Strings[],
|
PRPC_UNICODE_STRING Strings[],
|
||||||
BYTE *Data,
|
PBYTE Data,
|
||||||
USHORT Flags,
|
USHORT Flags,
|
||||||
DWORD *RecordNumber,
|
PULONG RecordNumber,
|
||||||
DWORD *TimeWritten)
|
PULONG TimeWritten)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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)
|
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