[EVENTLOG]

- Set the current service status from the service control handler.
- Fix type declarations.
- ElfrOpenELA/ElfrRegisterEventSourceA: Do not call the Unicode functions because in this case it is easier to do things yourself.
- Implement ElfrGetLogInformation partially.
- Bind client to the EventLog Pipe.
- Use RtlInitAnsiString and RtlInitUnicodeString instead of building strings manually.
- GetEventLogInformation: Check for valid dwInfoLevel.

svn path=/trunk/; revision=46199
This commit is contained in:
Eric Kohl 2010-03-14 12:26:49 +00:00
parent c39812d1b6
commit ee46cddad7
4 changed files with 138 additions and 110 deletions

View file

@ -21,20 +21,76 @@ static SERVICE_TABLE_ENTRYW ServiceTable[2] =
{ NULL, NULL } { NULL, NULL }
}; };
SERVICE_STATUS ServiceStatus;
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;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static VOID
UpdateServiceStatus(DWORD dwState)
{
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = dwState;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
if (dwState == SERVICE_START_PENDING ||
dwState == SERVICE_STOP_PENDING ||
dwState == SERVICE_PAUSE_PENDING ||
dwState == SERVICE_CONTINUE_PENDING)
ServiceStatus.dwWaitHint = 10000;
else
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
}
static DWORD WINAPI static DWORD WINAPI
ServiceControlHandler(DWORD dwControl, ServiceControlHandler(DWORD dwControl,
DWORD dwEventType, DWORD dwEventType,
LPVOID lpEventData, LPVOID lpEventData,
LPVOID lpContext) LPVOID lpContext)
{ {
/* FIXME */ DPRINT("ServiceControlHandler() called\n");
DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
return ERROR_SUCCESS; switch (dwControl)
{
case SERVICE_CONTROL_STOP:
DPRINT(" SERVICE_CONTROL_STOP received\n");
UpdateServiceStatus(SERVICE_STOPPED);
return ERROR_SUCCESS;
case SERVICE_CONTROL_PAUSE:
DPRINT(" SERVICE_CONTROL_PAUSE received\n");
UpdateServiceStatus(SERVICE_PAUSED);
return ERROR_SUCCESS;
case SERVICE_CONTROL_CONTINUE:
DPRINT(" SERVICE_CONTROL_CONTINUE received\n");
UpdateServiceStatus(SERVICE_RUNNING);
return ERROR_SUCCESS;
case SERVICE_CONTROL_INTERROGATE:
DPRINT(" SERVICE_CONTROL_INTERROGATE received\n");
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
return ERROR_SUCCESS;
case SERVICE_CONTROL_SHUTDOWN:
DPRINT(" SERVICE_CONTROL_SHUTDOWN received\n");
UpdateServiceStatus(SERVICE_STOPPED);
return ERROR_SUCCESS;
default :
DPRINT1(" Control %lu received\n");
return ERROR_CALL_NOT_IMPLEMENTED;
}
} }
@ -83,8 +139,6 @@ static VOID CALLBACK
ServiceMain(DWORD argc, ServiceMain(DWORD argc,
LPWSTR *argv) LPWSTR *argv)
{ {
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
DWORD dwError; DWORD dwError;
UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argc);
@ -102,31 +156,20 @@ ServiceMain(DWORD argc,
return; return;
} }
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; UpdateServiceStatus(SERVICE_START_PENDING);
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 2000;
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
dwError = ServiceInit(); dwError = ServiceInit();
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
{ {
DPRINT1("Service stopped\n"); DPRINT("Service stopped (dwError: %lu\n", dwError);
ServiceStatus.dwCurrentState = SERVICE_STOPPED; UpdateServiceStatus(SERVICE_START_PENDING);
} }
else else
{ {
ServiceStatus.dwCurrentState = SERVICE_RUNNING; DPRINT("Service started\n");
UpdateServiceStatus(SERVICE_RUNNING);
} }
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
DPRINT("ServiceMain() done\n"); DPRINT("ServiceMain() done\n");
} }

View file

@ -44,7 +44,8 @@ typedef struct _IO_ERROR_LPC
#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
{
ULONG HeaderSize; ULONG HeaderSize;
ULONG Signature; ULONG Signature;
ULONG MajorVersion; ULONG MajorVersion;
@ -59,7 +60,8 @@ typedef struct _EVENTLOGHEADER {
ULONG EndHeaderSize; ULONG EndHeaderSize;
} EVENTLOGHEADER, *PEVENTLOGHEADER; } EVENTLOGHEADER, *PEVENTLOGHEADER;
typedef struct _EVENTLOGEOF { typedef struct _EVENTLOGEOF
{
ULONG RecordSizeBeginning; ULONG RecordSizeBeginning;
ULONG Ones; ULONG Ones;
ULONG Twos; ULONG Twos;
@ -72,13 +74,13 @@ typedef struct _EVENTLOGEOF {
ULONG RecordSizeEnd; ULONG RecordSizeEnd;
} EVENTLOGEOF, *PEVENTLOGEOF; } EVENTLOGEOF, *PEVENTLOGEOF;
typedef struct typedef struct _EVENT_OFFSET_INFO
{ {
ULONG EventNumber; ULONG EventNumber;
ULONG EventOffset; ULONG EventOffset;
} EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO; } EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
typedef struct typedef struct _LOGFILE
{ {
HANDLE hFile; HANDLE hFile;
EVENTLOGHEADER Header; EVENTLOGHEADER Header;

View file

@ -480,45 +480,29 @@ NTSTATUS ElfrOpenELA(
DWORD MinorVersion, DWORD MinorVersion,
IELF_HANDLE *LogHandle) IELF_HANDLE *LogHandle)
{ {
UNICODE_STRING UNCServerNameW = { 0, 0, NULL }; UNICODE_STRING ModuleNameW;
UNICODE_STRING ModuleNameW = { 0, 0, NULL };
UNICODE_STRING RegModuleNameW = { 0, 0, NULL };
NTSTATUS Status;
if (UNCServerName && if ((MajorVersion != 1) || (MinorVersion != 1))
!RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName)) return STATUS_INVALID_PARAMETER;
{
return STATUS_NO_MEMORY;
}
if (ModuleName && /* RegModuleName must be an empty string */
!RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE)) if (RegModuleName->Length > 0)
{ return STATUS_INVALID_PARAMETER;
RtlFreeUnicodeString(&UNCServerNameW);
return STATUS_NO_MEMORY;
}
if (RegModuleName && RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
!RtlAnsiStringToUnicodeString(&RegModuleNameW, (PANSI_STRING)RegModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_NO_MEMORY;
}
Status = ElfrOpenELW( /* FIXME: Must verify that caller has read access */
UNCServerName ? UNCServerNameW.Buffer : NULL,
ModuleName ? (PRPC_UNICODE_STRING)&ModuleNameW : NULL, *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, FALSE);
RegModuleName ? (PRPC_UNICODE_STRING)&RegModuleNameW : NULL,
MajorVersion,
MinorVersion,
LogHandle);
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW); RtlFreeUnicodeString(&ModuleNameW);
RtlFreeUnicodeString(&RegModuleNameW);
return Status; if (*LogHandle == NULL)
{
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
} }
@ -531,45 +515,32 @@ NTSTATUS ElfrRegisterEventSourceA(
DWORD MinorVersion, DWORD MinorVersion,
IELF_HANDLE *LogHandle) IELF_HANDLE *LogHandle)
{ {
UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
UNICODE_STRING ModuleNameW = { 0, 0, NULL }; UNICODE_STRING ModuleNameW = { 0, 0, NULL };
if (UNCServerName &&
!RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
{
return STATUS_NO_MEMORY;
}
if (ModuleName && if (ModuleName &&
!RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE)) !RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
{ {
RtlFreeUnicodeString(&UNCServerNameW);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
/* RegModuleName must be an empty string */ /* RegModuleName must be an empty string */
if (RegModuleName->Length > 0) if (RegModuleName->Length > 0)
{ {
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW); RtlFreeUnicodeString(&ModuleNameW);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if ((MajorVersion != 1) || (MinorVersion != 1)) if ((MajorVersion != 1) || (MinorVersion != 1))
{ {
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW); RtlFreeUnicodeString(&ModuleNameW);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/*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 */
*LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer,
TRUE); TRUE);
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW); RtlFreeUnicodeString(&ModuleNameW);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -661,8 +632,32 @@ NTSTATUS ElfrGetLogInformation(
DWORD cbBufSize, DWORD cbBufSize,
DWORD *pcbBytesNeeded) DWORD *pcbBytesNeeded)
{ {
UNIMPLEMENTED; NTSTATUS Status = STATUS_SUCCESS;
return STATUS_NOT_IMPLEMENTED;
/* FIXME: check handle first */
switch (InfoLevel)
{
case EVENTLOG_FULL_INFO:
{
LPEVENTLOG_FULL_INFORMATION efi = (LPEVENTLOG_FULL_INFORMATION)Buffer;
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))
{
return STATUS_BUFFER_TOO_SMALL;
}
efi->dwFull = 0; /* FIXME */
}
break;
default:
Status = STATUS_INVALID_LEVEL;
break;
}
return Status;
} }

View file

@ -42,7 +42,7 @@ EVENTLOG_HANDLE_A_bind(EVENTLOG_HANDLE_A UNCServerName)
status = RpcStringBindingComposeA(NULL, status = RpcStringBindingComposeA(NULL,
(UCHAR *)"ncacn_np", (UCHAR *)"ncacn_np",
(UCHAR *)UNCServerName, (UCHAR *)UNCServerName,
(UCHAR *)"\\pipe\\ntsvcs", (UCHAR *)"\\pipe\\EventLog",
NULL, NULL,
(UCHAR **)&pszStringBinding); (UCHAR **)&pszStringBinding);
if (status) if (status)
@ -147,20 +147,17 @@ BOOL WINAPI
BackupEventLogA(IN HANDLE hEventLog, BackupEventLogA(IN HANDLE hEventLog,
IN LPCSTR lpBackupFileName) IN LPCSTR lpBackupFileName)
{ {
RPC_STRING BackupFileName; ANSI_STRING BackupFileName;
NTSTATUS Status; NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, lpBackupFileName); TRACE("%p, %s\n", hEventLog, lpBackupFileName);
BackupFileName.Buffer = (LPSTR)lpBackupFileName; RtlInitAnsiString(&BackupFileName, lpBackupFileName);
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? strlen(lpBackupFileName) : 0;
BackupFileName.MaximumLength += sizeof(CHAR);
RpcTryExcept RpcTryExcept
{ {
Status = ElfrBackupELFA(hEventLog, Status = ElfrBackupELFA(hEventLog,
&BackupFileName); (PRPC_STRING)&BackupFileName);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -188,20 +185,17 @@ BOOL WINAPI
BackupEventLogW(IN HANDLE hEventLog, BackupEventLogW(IN HANDLE hEventLog,
IN LPCWSTR lpBackupFileName) IN LPCWSTR lpBackupFileName)
{ {
RPC_UNICODE_STRING BackupFileName; UNICODE_STRING BackupFileName;
NTSTATUS Status; NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName)); TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
BackupFileName.Buffer = (LPWSTR)lpBackupFileName; RtlInitUnicodeString(&BackupFileName, lpBackupFileName);
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
BackupFileName.MaximumLength += sizeof(WCHAR);
RpcTryExcept RpcTryExcept
{ {
Status = ElfrBackupELFW(hEventLog, Status = ElfrBackupELFW(hEventLog,
&BackupFileName); (PRPC_UNICODE_STRING)&BackupFileName);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -226,20 +220,17 @@ BOOL WINAPI
ClearEventLogA(IN HANDLE hEventLog, ClearEventLogA(IN HANDLE hEventLog,
IN LPCSTR lpBackupFileName) IN LPCSTR lpBackupFileName)
{ {
RPC_STRING BackupFileName; ANSI_STRING BackupFileName;
NTSTATUS Status; NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, lpBackupFileName); TRACE("%p, %s\n", hEventLog, lpBackupFileName);
BackupFileName.Buffer = (LPSTR)lpBackupFileName; RtlInitAnsiString(&BackupFileName, lpBackupFileName);
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? strlen(lpBackupFileName) : 0;
BackupFileName.MaximumLength += sizeof(CHAR);
RpcTryExcept RpcTryExcept
{ {
Status = ElfrClearELFA(hEventLog, Status = ElfrClearELFA(hEventLog,
&BackupFileName); (PRPC_STRING)&BackupFileName);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -264,20 +255,17 @@ BOOL WINAPI
ClearEventLogW(IN HANDLE hEventLog, ClearEventLogW(IN HANDLE hEventLog,
IN LPCWSTR lpBackupFileName) IN LPCWSTR lpBackupFileName)
{ {
RPC_UNICODE_STRING BackupFileName; UNICODE_STRING BackupFileName;
NTSTATUS Status; NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName)); TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
BackupFileName.Buffer = (LPWSTR)lpBackupFileName; RtlInitUnicodeString(&BackupFileName,lpBackupFileName);
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
BackupFileName.MaximumLength += sizeof(WCHAR);
RpcTryExcept RpcTryExcept
{ {
Status = ElfrClearELFW(hEventLog, Status = ElfrClearELFW(hEventLog,
&BackupFileName); (PRPC_UNICODE_STRING)&BackupFileName);
} }
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -380,6 +368,12 @@ GetEventLogInformation(IN HANDLE hEventLog,
{ {
NTSTATUS Status; NTSTATUS Status;
if (dwInfoLevel != EVENTLOG_FULL_INFO)
{
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
RpcTryExcept RpcTryExcept
{ {
Status = ElfrGetLogInformation(hEventLog, Status = ElfrGetLogInformation(hEventLog,
@ -562,21 +556,18 @@ HANDLE WINAPI
OpenBackupEventLogW(IN LPCWSTR lpUNCServerName, OpenBackupEventLogW(IN LPCWSTR lpUNCServerName,
IN LPCWSTR lpFileName) IN LPCWSTR lpFileName)
{ {
RPC_UNICODE_STRING FileName; UNICODE_STRING FileName;
IELF_HANDLE LogHandle; IELF_HANDLE LogHandle;
NTSTATUS Status; NTSTATUS Status;
TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName)); TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));
FileName.Buffer = (LPWSTR)lpFileName; RtlInitUnicodeString(&FileName, lpFileName);
FileName.Length = FileName.MaximumLength =
lpFileName ? wcslen(lpFileName) * sizeof(WCHAR) : 0;
FileName.MaximumLength += sizeof(WCHAR);
RpcTryExcept RpcTryExcept
{ {
Status = ElfrOpenBELW((LPWSTR)lpUNCServerName, Status = ElfrOpenBELW((LPWSTR)lpUNCServerName,
&FileName, (PRPC_UNICODE_STRING)&FileName,
1, 1,
1, 1,
&LogHandle); &LogHandle);
@ -903,21 +894,18 @@ HANDLE WINAPI
RegisterEventSourceW(IN LPCWSTR lpUNCServerName, RegisterEventSourceW(IN LPCWSTR lpUNCServerName,
IN LPCWSTR lpSourceName) IN LPCWSTR lpSourceName)
{ {
RPC_UNICODE_STRING SourceName; UNICODE_STRING SourceName;
IELF_HANDLE LogHandle; IELF_HANDLE LogHandle;
NTSTATUS Status; NTSTATUS Status;
TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName)); TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
SourceName.Buffer = (LPWSTR)lpSourceName; RtlInitUnicodeString(&SourceName, lpSourceName);
SourceName.Length = SourceName.MaximumLength =
lpSourceName ? wcslen(lpSourceName) * sizeof(WCHAR) : 0;
SourceName.MaximumLength += sizeof(WCHAR);
RpcTryExcept RpcTryExcept
{ {
Status = ElfrRegisterEventSourceW((LPWSTR)lpUNCServerName, Status = ElfrRegisterEventSourceW((LPWSTR)lpUNCServerName,
&SourceName, (PRPC_UNICODE_STRING)&SourceName,
&EmptyStringU, &EmptyStringU,
1, 1,
1, 1,