[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 }
};
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
HANDLE MyHeap = NULL;
/* 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
ServiceControlHandler(DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext)
{
/* FIXME */
DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
return ERROR_SUCCESS;
DPRINT("ServiceControlHandler() called\n");
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,
LPWSTR *argv)
{
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
DWORD dwError;
UNREFERENCED_PARAMETER(argc);
@ -102,31 +156,20 @@ ServiceMain(DWORD argc,
return;
}
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 2000;
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
UpdateServiceStatus(SERVICE_START_PENDING);
dwError = ServiceInit();
if (dwError != ERROR_SUCCESS)
{
DPRINT1("Service stopped\n");
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
DPRINT("Service stopped (dwError: %lu\n", dwError);
UpdateServiceStatus(SERVICE_START_PENDING);
}
else
{
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
DPRINT("Service started\n");
UpdateServiceStatus(SERVICE_RUNNING);
}
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
DPRINT("ServiceMain() done\n");
}

View file

@ -44,7 +44,8 @@ typedef struct _IO_ERROR_LPC
#define ELF_LOGFILE_ARCHIVE_SET 8
/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
typedef struct _EVENTLOGHEADER {
typedef struct _EVENTLOGHEADER
{
ULONG HeaderSize;
ULONG Signature;
ULONG MajorVersion;
@ -59,7 +60,8 @@ typedef struct _EVENTLOGHEADER {
ULONG EndHeaderSize;
} EVENTLOGHEADER, *PEVENTLOGHEADER;
typedef struct _EVENTLOGEOF {
typedef struct _EVENTLOGEOF
{
ULONG RecordSizeBeginning;
ULONG Ones;
ULONG Twos;
@ -72,13 +74,13 @@ typedef struct _EVENTLOGEOF {
ULONG RecordSizeEnd;
} EVENTLOGEOF, *PEVENTLOGEOF;
typedef struct
typedef struct _EVENT_OFFSET_INFO
{
ULONG EventNumber;
ULONG EventOffset;
} EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
typedef struct
typedef struct _LOGFILE
{
HANDLE hFile;
EVENTLOGHEADER Header;

View file

@ -480,45 +480,29 @@ NTSTATUS ElfrOpenELA(
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
UNICODE_STRING ModuleNameW = { 0, 0, NULL };
UNICODE_STRING RegModuleNameW = { 0, 0, NULL };
NTSTATUS Status;
UNICODE_STRING ModuleNameW;
if (UNCServerName &&
!RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
{
return STATUS_NO_MEMORY;
}
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
if (ModuleName &&
!RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
return STATUS_NO_MEMORY;
}
/* RegModuleName must be an empty string */
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
if (RegModuleName &&
!RtlAnsiStringToUnicodeString(&RegModuleNameW, (PANSI_STRING)RegModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_NO_MEMORY;
}
RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
Status = ElfrOpenELW(
UNCServerName ? UNCServerNameW.Buffer : NULL,
ModuleName ? (PRPC_UNICODE_STRING)&ModuleNameW : NULL,
RegModuleName ? (PRPC_UNICODE_STRING)&RegModuleNameW : NULL,
MajorVersion,
MinorVersion,
LogHandle);
/* FIXME: Must verify that caller has read access */
*LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, FALSE);
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
RtlFreeUnicodeString(&RegModuleNameW);
return Status;
if (*LogHandle == NULL)
{
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}
@ -531,45 +515,32 @@ NTSTATUS ElfrRegisterEventSourceA(
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
UNICODE_STRING ModuleNameW = { 0, 0, NULL };
if (UNCServerName &&
!RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
{
return STATUS_NO_MEMORY;
}
if (ModuleName &&
!RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
return STATUS_NO_MEMORY;
}
/* RegModuleName must be an empty string */
if (RegModuleName->Length > 0)
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_INVALID_PARAMETER;
}
if ((MajorVersion != 1) || (MinorVersion != 1))
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
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,
TRUE);
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_SUCCESS;
@ -661,8 +632,32 @@ NTSTATUS ElfrGetLogInformation(
DWORD cbBufSize,
DWORD *pcbBytesNeeded)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status = STATUS_SUCCESS;
/* 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,
(UCHAR *)"ncacn_np",
(UCHAR *)UNCServerName,
(UCHAR *)"\\pipe\\ntsvcs",
(UCHAR *)"\\pipe\\EventLog",
NULL,
(UCHAR **)&pszStringBinding);
if (status)
@ -147,20 +147,17 @@ BOOL WINAPI
BackupEventLogA(IN HANDLE hEventLog,
IN LPCSTR lpBackupFileName)
{
RPC_STRING BackupFileName;
ANSI_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, lpBackupFileName);
BackupFileName.Buffer = (LPSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? strlen(lpBackupFileName) : 0;
BackupFileName.MaximumLength += sizeof(CHAR);
RtlInitAnsiString(&BackupFileName, lpBackupFileName);
RpcTryExcept
{
Status = ElfrBackupELFA(hEventLog,
&BackupFileName);
(PRPC_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@ -188,20 +185,17 @@ BOOL WINAPI
BackupEventLogW(IN HANDLE hEventLog,
IN LPCWSTR lpBackupFileName)
{
RPC_UNICODE_STRING BackupFileName;
UNICODE_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
BackupFileName.Buffer = (LPWSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
BackupFileName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&BackupFileName, lpBackupFileName);
RpcTryExcept
{
Status = ElfrBackupELFW(hEventLog,
&BackupFileName);
(PRPC_UNICODE_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@ -226,20 +220,17 @@ BOOL WINAPI
ClearEventLogA(IN HANDLE hEventLog,
IN LPCSTR lpBackupFileName)
{
RPC_STRING BackupFileName;
ANSI_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, lpBackupFileName);
BackupFileName.Buffer = (LPSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? strlen(lpBackupFileName) : 0;
BackupFileName.MaximumLength += sizeof(CHAR);
RtlInitAnsiString(&BackupFileName, lpBackupFileName);
RpcTryExcept
{
Status = ElfrClearELFA(hEventLog,
&BackupFileName);
(PRPC_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@ -264,20 +255,17 @@ BOOL WINAPI
ClearEventLogW(IN HANDLE hEventLog,
IN LPCWSTR lpBackupFileName)
{
RPC_UNICODE_STRING BackupFileName;
UNICODE_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
BackupFileName.Buffer = (LPWSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
BackupFileName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&BackupFileName,lpBackupFileName);
RpcTryExcept
{
Status = ElfrClearELFW(hEventLog,
&BackupFileName);
(PRPC_UNICODE_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@ -380,6 +368,12 @@ GetEventLogInformation(IN HANDLE hEventLog,
{
NTSTATUS Status;
if (dwInfoLevel != EVENTLOG_FULL_INFO)
{
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
RpcTryExcept
{
Status = ElfrGetLogInformation(hEventLog,
@ -562,21 +556,18 @@ HANDLE WINAPI
OpenBackupEventLogW(IN LPCWSTR lpUNCServerName,
IN LPCWSTR lpFileName)
{
RPC_UNICODE_STRING FileName;
UNICODE_STRING FileName;
IELF_HANDLE LogHandle;
NTSTATUS Status;
TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));
FileName.Buffer = (LPWSTR)lpFileName;
FileName.Length = FileName.MaximumLength =
lpFileName ? wcslen(lpFileName) * sizeof(WCHAR) : 0;
FileName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&FileName, lpFileName);
RpcTryExcept
{
Status = ElfrOpenBELW((LPWSTR)lpUNCServerName,
&FileName,
(PRPC_UNICODE_STRING)&FileName,
1,
1,
&LogHandle);
@ -903,21 +894,18 @@ HANDLE WINAPI
RegisterEventSourceW(IN LPCWSTR lpUNCServerName,
IN LPCWSTR lpSourceName)
{
RPC_UNICODE_STRING SourceName;
UNICODE_STRING SourceName;
IELF_HANDLE LogHandle;
NTSTATUS Status;
TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
SourceName.Buffer = (LPWSTR)lpSourceName;
SourceName.Length = SourceName.MaximumLength =
lpSourceName ? wcslen(lpSourceName) * sizeof(WCHAR) : 0;
SourceName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&SourceName, lpSourceName);
RpcTryExcept
{
Status = ElfrRegisterEventSourceW((LPWSTR)lpUNCServerName,
&SourceName,
(PRPC_UNICODE_STRING)&SourceName,
&EmptyStringU,
1,
1,