diff options
Diffstat (limited to '')
-rw-r--r-- | private/eventlog/elfclnt/apistub.c | 1577 | ||||
-rw-r--r-- | private/eventlog/elfclnt/elfclntp.h | 44 | ||||
-rw-r--r-- | private/eventlog/elfclnt/getconfg.c | 110 | ||||
-rw-r--r-- | private/eventlog/elfclnt/makefile | 6 | ||||
-rw-r--r-- | private/eventlog/elfclnt/rpcbind.c | 205 | ||||
-rw-r--r-- | private/eventlog/elfclnt/sources | 59 |
6 files changed, 2001 insertions, 0 deletions
diff --git a/private/eventlog/elfclnt/apistub.c b/private/eventlog/elfclnt/apistub.c new file mode 100644 index 000000000..da62f55bf --- /dev/null +++ b/private/eventlog/elfclnt/apistub.c @@ -0,0 +1,1577 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + APISTUB.C + +Abstract: + + This module contains the client ends of the Elf APIs. + + +Author: + + Rajen Shah (rajens) 29-Jul-1991 + + +Revision History: + + 29-Jul-1991 RajenS + Created + +--*/ + +#include <elfclntp.h> +#include <lmerr.h> +#include <stdlib.h> +#include <string.h> + +// +// Global data +// +PUNICODE_STRING pGlobalComputerNameU; +PANSI_STRING pGlobalComputerNameA; + + + +VOID +w_GetComputerName ( ) + +/*++ + +Routine Description: + + This routine gets the name of the computer. It checks the global + variable to see if the computer name has already been determined. + If not, it updates that variable with the name. + It does this for the UNICODE and the ANSI versions. + +Arguments: + + NONE + +Return Value: + + NONE + + +--*/ +{ + PUNICODE_STRING pNameU; + PANSI_STRING pNameA; + LPSTR pName; + NTSTATUS Error; + NTSTATUS status; + + + pNameU = MIDL_user_allocate (sizeof (UNICODE_STRING)); + pNameA = MIDL_user_allocate (sizeof (ANSI_STRING)); + + if ((pNameU != NULL) && (pNameA != NULL)) { + + if ((Error = ElfpGetComputerName (&pName)) == NERR_Success) { + + // + // ElfpComputerName has allocated a buffer to contain the + // ASCII name of the computer. We use that for the ANSI + // string structure. + // + RtlInitAnsiString ( pNameA, pName ); + + } else { + // + // We could not get the computer name for some reason. Set up + // the golbal pointer to point to the NULL string. + // + RtlInitAnsiString ( pNameA, "\0"); + } + + // + // Set up the UNICODE_STRING structure. + // + status = RtlAnsiStringToUnicodeString ( + pNameU, + pNameA, + TRUE + ); + + // + // If there was no error, set the global variables. + // Otherwise, free the buffer allocated by ElfpGetComputerName + // and leave the global variables unchanged. + // + if (NT_SUCCESS(status)) { + + pGlobalComputerNameU = pNameU; // Set global variable if no error + pGlobalComputerNameA = pNameA; // Set global ANSI variable + + } else { + + DbgPrint("[ELFCLNT] GetComputerName - Error 0x%lx\n", status); + LocalFree(pName); + MIDL_user_free (pNameU); // Free the buffers + MIDL_user_free (pNameA); + } + + } +} + + + + +PUNICODE_STRING +TmpGetComputerNameW ( ) + +/*++ + +Routine Description: + + This routine gets the UNICODE name of the computer. It checks the global + variable to see if the computer name has already been determined. + If not, it calls the worker routine to do that. + +Arguments: + + NONE + +Return Value: + + Returns a pointer to the computer name, or a NULL. + + +--*/ +{ + if (pGlobalComputerNameU == NULL) { + w_GetComputerName(); + } + return (pGlobalComputerNameU); +} + + + +PANSI_STRING +TmpGetComputerNameA ( ) + +/*++ + +Routine Description: + + This routine gets the ANSI name of the computer. It checks the global + variable to see if the computer name has already been determined. + If not, it calls the worker routine to do that. + +Arguments: + + NONE + +Return Value: + + Returns a pointer to the computer name, or a NULL. + + +--*/ +{ + + if (pGlobalComputerNameA == NULL) { + w_GetComputerName(); + } + return (pGlobalComputerNameA); +} + +// +// These APIs only have one interface, since they don't take or return strings +// + +NTSTATUS +ElfNumberOfRecords( + IN HANDLE LogHandle, + OUT PULONG NumberOfRecords + ) +{ + NTSTATUS status; + + // + // Make sure the output pointer is valid + // + + if (!NumberOfRecords) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service entry point + + status = ElfrNumberOfRecords ( + (IELF_HANDLE) LogHandle, + NumberOfRecords + ); + + } + RpcExcept (1) { + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + +NTSTATUS +ElfOldestRecord( + IN HANDLE LogHandle, + OUT PULONG OldestRecordNumber + ) +{ + NTSTATUS status; + + // + // + // Make sure the output pointer is valid + // + + if (!OldestRecordNumber) { + return(STATUS_INVALID_PARAMETER); + } + + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service entry point + + status = ElfrOldestRecord ( + (IELF_HANDLE) LogHandle, + OldestRecordNumber + ); + + } + RpcExcept (1) { + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + +NTSTATUS +ElfChangeNotify( + IN HANDLE LogHandle, + IN HANDLE Event + ) +{ + + NTSTATUS status; + RPC_CLIENT_ID RpcClientId; + CLIENT_ID ClientId; + + // + // Map the handles to something that RPC can understand + // + + ClientId = NtCurrentTeb()->ClientId; + RpcClientId.UniqueProcess = (ULONG) ClientId.UniqueProcess; + RpcClientId.UniqueThread = (ULONG) ClientId.UniqueThread; + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + + RpcTryExcept { + + // Call service entry point + + status = ElfrChangeNotify ( + (IELF_HANDLE) LogHandle, + RpcClientId, + (DWORD) Event + ); + + } + RpcExcept (1) { + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + +// +// UNICODE APIs +// + +NTSTATUS +ElfOpenEventLogW ( + IN PUNICODE_STRING UNCServerName, + IN PUNICODE_STRING LogName, + OUT PHANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfOpenEventLog API. + + It creates an RPC binding for the server specified, and stores that + and additional data away. It returns a handle to the caller that can + be used to later on access the handle-specific information. + +Arguments: + + UNCServerName - Server with which to bind for subsequent operations. + + LogName - Supplies the name of the module for the logfile + to associate with this handle. + + LogHandle - Location where log handle is to be returned. + + +Return Value: + + Returns an NTSTATUS code and, if no error, a handle that can be used + for subsequent Elf API calls. + + +--*/ +{ + NTSTATUS status = STATUS_SUCCESS; + UNICODE_STRING RegModuleName; + EVENTLOG_HANDLE_W ServerNameString; + + // + // Make sure input & output pointers are valid + // + + if (!LogHandle || !LogName || LogName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) { + ServerNameString = UNCServerName->Buffer; + } else { + ServerNameString = NULL; + } + + RtlInitUnicodeString( &RegModuleName, UNICODE_NULL); + + // Call service via RPC. Pass in major and minor version numbers. + + *LogHandle = NULL; // Must be NULL so RPC fills it in + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + status = ElfrOpenELW( + ServerNameString, + (PRPC_UNICODE_STRING) LogName, + (PRPC_UNICODE_STRING) &RegModuleName, + ELF_VERSION_MAJOR, + ELF_VERSION_MINOR, + (PIELF_HANDLE) LogHandle + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + + return (status); +} + + +NTSTATUS +ElfRegisterEventSourceW ( + IN PUNICODE_STRING UNCServerName, + IN PUNICODE_STRING ModuleName, + OUT PHANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfRegisterEventSource API. + + It creates an RPC binding for the server specified, and stores that + and additional data away. It returns a handle to the caller that can + be used to later on access the handle-specific information. + +Arguments: + + UNCServerName - Server with which to bind for subsequent operations. + + ModuleName - Supplies the name of the module to associate with + this handle. + + LogHandle - Location where log handle is to be returned. + + +Return Value: + + Returns an NTSTATUS code and, if no error, a handle that can be used + for subsequent Elf API calls. + + +--*/ +{ + NTSTATUS status = STATUS_SUCCESS; + UNICODE_STRING RegModuleName; + EVENTLOG_HANDLE_W ServerNameString; + + // + // Make sure input & output pointers are valid + // + + if (!LogHandle || !ModuleName || ModuleName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) { + ServerNameString = UNCServerName->Buffer; + } else { + ServerNameString = NULL; + } + + RtlInitUnicodeString( &RegModuleName, UNICODE_NULL); + + // Call service via RPC. Pass in major and minor version numbers. + + *LogHandle = NULL; // Must be NULL so RPC fills it in + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + status = ElfrRegisterEventSourceW( + ServerNameString, + (PRPC_UNICODE_STRING)ModuleName, + (PRPC_UNICODE_STRING)&RegModuleName, + ELF_VERSION_MAJOR, + ELF_VERSION_MINOR, + (PIELF_HANDLE) LogHandle + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + + return (status); +} + + +NTSTATUS +ElfOpenBackupEventLogW ( + IN PUNICODE_STRING UNCServerName, + IN PUNICODE_STRING BackupFileName, + OUT PHANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfOpenBackupEventLog API. + + It creates an RPC binding for the server specified, and stores that + and additional data away. It returns a handle to the caller that can + be used to later on access the handle-specific information. + +Arguments: + + UNCServerName - Server with which to bind for subsequent operations. + + BackupFileName - Supplies the filename of the module to associate with + this handle. + + LogHandle - Location where log handle is to be returned. + + +Return Value: + + Returns an NTSTATUS code and, if no error, a handle that can be used + for subsequent Elf API calls. + + +--*/ +{ + NTSTATUS status = STATUS_SUCCESS; + EVENTLOG_HANDLE_W ServerNameString; + + // + // Make sure input & output pointers are valid + // + + if (!LogHandle || !BackupFileName || BackupFileName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) { + ServerNameString = UNCServerName->Buffer; + } else { + ServerNameString = NULL; + } + + // Call service via RPC. Pass in major and minor version numbers. + + *LogHandle = NULL; // Must be NULL so RPC fills it in + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + + RpcTryExcept { + + status = ElfrOpenBELW( + ServerNameString, + (PRPC_UNICODE_STRING)BackupFileName, + ELF_VERSION_MAJOR, + ELF_VERSION_MINOR, + (PIELF_HANDLE) LogHandle + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); +} + + + +NTSTATUS +ElfClearEventLogFileW ( + IN HANDLE LogHandle, + IN PUNICODE_STRING BackupFileName + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfClearEventLogFile API. + The call is passed to the eventlog service on the appropriate server + identified by LogHandle. + + +Arguments: + + LogHandle - Handle returned from a previous "Open" call. This is + used to identify the module and the server. + + BackupFileName - Name of the file to back up the current log file. + NULL implies not to back up the file. + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service entry point + + status = ElfrClearELFW ( + (IELF_HANDLE) LogHandle, + (PRPC_UNICODE_STRING)BackupFileName + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + +NTSTATUS +ElfBackupEventLogFileW ( + IN HANDLE LogHandle, + IN PUNICODE_STRING BackupFileName + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfBackupEventLogFile API. + The call is passed to the eventlog service on the appropriate server + identified by LogHandle. + + +Arguments: + + LogHandle - Handle returned from a previous "Open" call. This is + used to identify the module and the server. + + BackupFileName - Name of the file to back up the current log file. + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + + // + // Make sure input pointers are valid + // + + if (!BackupFileName || BackupFileName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service entry point + + status = ElfrBackupELFW ( + (IELF_HANDLE) LogHandle, + (PRPC_UNICODE_STRING)BackupFileName + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + +NTSTATUS +ElfCloseEventLog ( + IN HANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfCloseEventLog API. + It closes the RPC binding, and frees any memory allocated for the + handle. + + +Arguments: + + LogHandle - Handle returned from a previous "Open" call. + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call server + + status = ElfrCloseEL ( + (PIELF_HANDLE) &LogHandle + ); + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + +NTSTATUS +ElfDeregisterEventSource ( + IN HANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfDeregisterEventSource API. + It closes the RPC binding, and frees any memory allocated for the + handle. + + +Arguments: + + LogHandle - Handle returned from a previous "Open" call. + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call server + + status = ElfrDeregisterEventSource ( + (PIELF_HANDLE) &LogHandle + ); + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + + +NTSTATUS +ElfReadEventLogW ( + IN HANDLE LogHandle, + IN ULONG ReadFlags, + IN ULONG RecordNumber, + OUT PVOID Buffer, + IN ULONG NumberOfBytesToRead, + OUT PULONG NumberOfBytesRead, + OUT PULONG MinNumberOfBytesNeeded + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfReadEventLog API. + +Arguments: + + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + ULONG FlagBits; + + // + // Make sure the output pointers are valid + // + + if (!Buffer || !NumberOfBytesRead || !MinNumberOfBytesNeeded) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Ensure that the ReadFlags we got are valid. + // Make sure that one of each type of bit is set. + // + FlagBits = ReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ); + + if ((FlagBits > 2) || (FlagBits == 0)) { + return(STATUS_INVALID_PARAMETER); + } + + FlagBits = ReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ); + + if ((FlagBits > 8) || (FlagBits == 0)) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service + + status = ElfrReadELW ( + (IELF_HANDLE) LogHandle, + ReadFlags, + RecordNumber, + NumberOfBytesToRead, + Buffer, + NumberOfBytesRead, + MinNumberOfBytesNeeded + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + // Return status and bytes read/required. + + return (status); + +} + + + +NTSTATUS +ElfReportEventW ( + IN HANDLE LogHandle, + IN USHORT EventType, + IN USHORT EventCategory OPTIONAL, + IN ULONG EventID, + IN PSID UserSid, + IN USHORT NumStrings, + IN ULONG DataSize, + IN PUNICODE_STRING *Strings, + IN PVOID Data, + IN USHORT Flags, + IN OUT PULONG RecordNumber OPTIONAL, + IN OUT PULONG TimeWritten OPTIONAL + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfReportEvent API. + +Arguments: + + +Return Value: + + Returns an NTSTATUS code. + +Note: + + The last three parameters (Flags, RecordNumber and TimeWritten) are + designed to be used by Security Auditing for the implementation of + paired events (associating a file open event with the subsequent file + close). This will not be implemented in Product 1, but the API is + defined to allow easier support of this in a later release. + + +--*/ +{ + NTSTATUS status; + PUNICODE_STRING pComputerNameU; + LARGE_INTEGER Time; + ULONG EventTime; + + // + // Generate the time of the event. This is done on the client side + // since that is where the event occurred. + // + NtQuerySystemTime(&Time); + RtlTimeToSecondsSince1970(&Time, + &EventTime + ); + + // + // Generate the ComputerName of the client. + // We have to do this in the client side since this call may be + // remoted to another server and we would not necessarily have + // the computer name there. + // + pComputerNameU = TmpGetComputerNameW(); + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service + + status = ElfrReportEventW ( + (IELF_HANDLE) LogHandle, + EventTime, + EventType, + EventCategory, + EventID, + NumStrings, + DataSize, + (PRPC_UNICODE_STRING)pComputerNameU, + UserSid, + (PRPC_UNICODE_STRING *)Strings, + Data, + Flags, + RecordNumber, + TimeWritten + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + +// +// ANSI APIs +// + +NTSTATUS +ElfOpenEventLogA ( + IN PANSI_STRING UNCServerName, + IN PANSI_STRING LogName, + OUT PHANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfOpenEventLog API. + + It creates an RPC binding for the server specified, and stores that + and additional data away. It returns a handle to the caller that can + be used to later on access the handle-specific information. + +Arguments: + + UNCServerName - Server with which to bind for subsequent operations. + + LogName - Supplies the name of the module for the logfile to + associate with this handle. + + LogHandle - Location where log handle is to be returned. + + +Return Value: + + Returns an NTSTATUS code and, if no error, a handle that can be used + for subsequent Elf API calls. + + +--*/ +{ + NTSTATUS status = STATUS_SUCCESS; + ANSI_STRING RegModuleName; + EVENTLOG_HANDLE_A ServerNameString; + + // + // Make sure input & output pointers are valid + // + + if (!LogHandle || !LogName || LogName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) { + ServerNameString = UNCServerName->Buffer; + } else { + ServerNameString = NULL; + } + + RtlInitAnsiString( &RegModuleName, ELF_APPLICATION_MODULE_NAME_ASCII ); + + if ( NT_SUCCESS (status) ) { + + // Call service via RPC. Pass in major and minor version numbers. + + *LogHandle = NULL; // Must be NULL so RPC fills it in + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + status = ElfrOpenELA ( + ServerNameString, + (PRPC_STRING) LogName, + (PRPC_STRING) &RegModuleName, + ELF_VERSION_MAJOR, + ELF_VERSION_MINOR, + (PIELF_HANDLE) LogHandle + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + + } + + return (status); +} + + +NTSTATUS +ElfRegisterEventSourceA ( + IN PANSI_STRING UNCServerName, + IN PANSI_STRING ModuleName, + OUT PHANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfOpenEventLog API. + + It creates an RPC binding for the server specified, and stores that + and additional data away. It returns a handle to the caller that can + be used to later on access the handle-specific information. + +Arguments: + + UNCServerName - Server with which to bind for subsequent operations. + + ModuleName - Supplies the name of the module to associate with + this handle. + + LogHandle - Location where log handle is to be returned. + + +Return Value: + + Returns an NTSTATUS code and, if no error, a handle that can be used + for subsequent Elf API calls. + + +--*/ +{ + NTSTATUS status = STATUS_SUCCESS; + ANSI_STRING RegModuleName; + EVENTLOG_HANDLE_A ServerNameString; + + // + // Make sure input & output pointers are valid + // + + if (!LogHandle || !ModuleName || ModuleName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) { + ServerNameString = UNCServerName->Buffer; + } else { + ServerNameString = NULL; + } + + RtlInitAnsiString( &RegModuleName, ELF_APPLICATION_MODULE_NAME_ASCII ); + + if ( NT_SUCCESS (status) ) { + + // Call service via RPC. Pass in major and minor version numbers. + + *LogHandle = NULL; // Must be NULL so RPC fills it in + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + status = ElfrRegisterEventSourceA ( + ServerNameString, + (PRPC_STRING)ModuleName, + (PRPC_STRING)&RegModuleName, + ELF_VERSION_MAJOR, + ELF_VERSION_MINOR, + (PIELF_HANDLE) LogHandle + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + + } + + return (status); +} + + + +NTSTATUS +ElfOpenBackupEventLogA ( + IN PANSI_STRING UNCServerName, + IN PANSI_STRING FileName, + OUT PHANDLE LogHandle + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfOpenBackupEventLog API. + + It creates an RPC binding for the server specified, and stores that + and additional data away. It returns a handle to the caller that can + be used to later on access the handle-specific information. + +Arguments: + + UNCServerName - Server with which to bind for subsequent operations. + + FileName - Supplies the filename of the logfile to associate with + this handle. + + LogHandle - Location where log handle is to be returned. + + +Return Value: + + Returns an NTSTATUS code and, if no error, a handle that can be used + for subsequent Elf API calls. + + +--*/ +{ + EVENTLOG_HANDLE_A ServerNameString; + NTSTATUS status; + + // + // Make sure input & output pointers are valid + // + + if (!LogHandle || !FileName || FileName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) { + ServerNameString = UNCServerName->Buffer; + } else { + ServerNameString = NULL; + } + + // Call service via RPC. Pass in major and minor version numbers. + + *LogHandle = NULL; // Must be NULL so RPC fills it in + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + + RpcTryExcept { + + status = ElfrOpenBELA ( + ServerNameString, + (PRPC_STRING)FileName, + ELF_VERSION_MAJOR, + ELF_VERSION_MINOR, + (PIELF_HANDLE) LogHandle + ); + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); +} + + + +NTSTATUS +ElfClearEventLogFileA ( + IN HANDLE LogHandle, + IN PANSI_STRING BackupFileName + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfClearEventLogFile API. + The call is passed to the eventlog service on the appropriate server + identified by LogHandle. + + +Arguments: + + LogHandle - Handle returned from a previous "Open" call. This is + used to identify the module and the server. + + BackupFileName - Name of the file to back up the current log file. + NULL implies not to back up the file. + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service entry point + + status = ElfrClearELFA ( + (IELF_HANDLE) LogHandle, + (PRPC_STRING)BackupFileName + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + +NTSTATUS +ElfBackupEventLogFileA ( + IN HANDLE LogHandle, + IN PANSI_STRING BackupFileName + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfBackupEventLogFile API. + The call is passed to the eventlog service on the appropriate server + identified by LogHandle. + + +Arguments: + + LogHandle - Handle returned from a previous "Open" call. This is + used to identify the module and the server. + + BackupFileName - Name of the file to back up the current log file. + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + + // + // Make sure input pointers are valid + // + + if (!BackupFileName || BackupFileName->Length == 0) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service entry point + + status = ElfrBackupELFA ( + (IELF_HANDLE) LogHandle, + (PRPC_STRING)BackupFileName + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} + + + +NTSTATUS +ElfReadEventLogA ( + IN HANDLE LogHandle, + IN ULONG ReadFlags, + IN ULONG RecordNumber, + OUT PVOID Buffer, + IN ULONG NumberOfBytesToRead, + OUT PULONG NumberOfBytesRead, + OUT PULONG MinNumberOfBytesNeeded + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfReadEventLog API. + +Arguments: + + + +Return Value: + + Returns an NTSTATUS code. + + +--*/ +{ + NTSTATUS status; + ULONG FlagBits; + + // + // Make sure the output pointers are valid + // + + if (!Buffer || !NumberOfBytesRead || !MinNumberOfBytesNeeded) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Ensure that the ReadFlags we got are valid. + // Make sure that one of each type of bit is set. + // + FlagBits = ReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ); + + if ( (FlagBits == (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ)) + || (FlagBits == 0)) { + return(STATUS_INVALID_PARAMETER); + } + + FlagBits = ReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ); + + if ( (FlagBits == (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ)) + || (FlagBits == 0)) { + return(STATUS_INVALID_PARAMETER); + } + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service + + status = ElfrReadELA ( + (IELF_HANDLE) LogHandle, + ReadFlags, + RecordNumber, + NumberOfBytesToRead, + Buffer, + NumberOfBytesRead, + MinNumberOfBytesNeeded + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + // Return status and bytes read/required. + + return (status); + +} + + + +NTSTATUS +ElfReportEventA ( + IN HANDLE LogHandle, + IN USHORT EventType, + IN USHORT EventCategory OPTIONAL, + IN ULONG EventID, + IN PSID UserSid, + IN USHORT NumStrings, + IN ULONG DataSize, + IN PANSI_STRING *Strings, + IN PVOID Data, + IN USHORT Flags, + IN OUT PULONG RecordNumber OPTIONAL, + IN OUT PULONG TimeWritten OPTIONAL + ) + +/*++ + +Routine Description: + + This is the client DLL entry point for the ElfReportEvent API. + +Arguments: + + +Return Value: + + Returns an NTSTATUS code. + +Note: + + The last three parameters (Flags, RecordNumber and TimeWritten) are + designed to be used by Security Auditing for the implementation of + paired events (associating a file open event with the subsequent file + close). This will not be implemented in Product 1, but the API is + defined to allow easier support of this in a later release. + + +--*/ +{ + NTSTATUS status; + PANSI_STRING pComputerNameA; + LARGE_INTEGER Time; + ULONG EventTime; + + // + // Generate the time of the event. This is done on the client side + // since that is where the event occurred. + // + NtQuerySystemTime(&Time); + RtlTimeToSecondsSince1970(&Time, + &EventTime + ); + + // + // Generate the ComputerName of the client. + // We have to do this in the client side since this call may be + // remoted to another server and we would not necessarily have + // the computer name there. + // + pComputerNameA = TmpGetComputerNameA(); + + // + // Do the RPC call with an exception handler since RPC will raise an + // exception if anything fails. It is up to us to figure out what + // to do once the exception is raised. + // + RpcTryExcept { + + // Call service + + status = ElfrReportEventA ( + (IELF_HANDLE) LogHandle, + EventTime, + EventType, + EventCategory, + EventID, + NumStrings, + DataSize, + (PRPC_STRING)pComputerNameA, + UserSid, + (PRPC_STRING*)Strings, + Data, + Flags, + RecordNumber, + TimeWritten + ); + + } + RpcExcept (1) { + + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept + + return (status); + +} diff --git a/private/eventlog/elfclnt/elfclntp.h b/private/eventlog/elfclnt/elfclntp.h new file mode 100644 index 000000000..ec0de3a67 --- /dev/null +++ b/private/eventlog/elfclnt/elfclntp.h @@ -0,0 +1,44 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + elfclntp.h + +Abstract: + + Common include file for all the client-side modules for the + event logging facility. + +Author: + + Rajen Shah (rajens) 29-Jul-1991 + + +Revision History: + + 29-Jul-1991 RajenS + Created + +--*/ + +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +#include <windef.h> +#include <winbase.h> +#include <rpc.h> +#include <ntrpcp.h> +#include <lmcons.h> +#include <lmerr.h> +//#include <netlib.h> + +#include <elf.h> +#include <elfcommn.h> + + +NTSTATUS +ElfpGetComputerName ( + IN LPSTR *ComputerNamePtr); diff --git a/private/eventlog/elfclnt/getconfg.c b/private/eventlog/elfclnt/getconfg.c new file mode 100644 index 000000000..a947af787 --- /dev/null +++ b/private/eventlog/elfclnt/getconfg.c @@ -0,0 +1,110 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + getconfg.c + +Abstract: + + This is a Hacked up version of getconfg.c stolen from + c:\nt\private\net\netlib. We need to make an rtl routine out + of this - something that is more globally available. + -Danl 9-3-91 + + + This module contains routines for manipulating configuration + information. The following functions available are: + + NetpGetComputerName + + Currently configuration information is kept in NT.CFG. + Later it will be kept by the configuration manager. + +Author: + + Dan Lafferty (danl) 09-Apr-1991 + +Environment: + + User Mode -Win32 (also uses nt RTL routines) + +Revision History: + + 09-Apr-1991 danl + created + +--*/ + +//#include <stdlib.h> // atol +#include <nt.h> // DbgPrint prototype +#include <ntrtl.h> // DbgPrint prototype +#include <ntdef.h> +#include <ntstatus.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +//#include <ntlsa.h> // +#include <windef.h> +#include <winbase.h> // LocalAlloc +#include <lmcons.h> +#include <string.h> +#include <lmerr.h> + + + +NTSTATUS +ElfpGetComputerName ( + IN LPSTR *ComputerNamePtr) + +/*++ + +Routine Description: + + This routine obtains the computer name from a persistent database, + by calling the GetcomputerNameA Win32 Base API + + This routine assumes the length of the computername is no greater + than MAX_COMPUTERNAME_LENGTH, space for which it allocates using + LocalAlloc. It is necessary for the user to free that space using + LocalFree when finished. + +Arguments: + + ComputerNamePtr - This is a pointer to the location where the pointer + to the computer name is to be placed. + +Return Value: + + NERR_Success - If the operation was successful. + + It will return assorted Net or Win32 or NT error messages if not. + +--*/ +{ + DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1; + + // + // Allocate a buffer to hold the largest possible computer name. + // + + *ComputerNamePtr = LocalAlloc(LMEM_ZEROINIT, nSize); + + if (*ComputerNamePtr == NULL) { + return (GetLastError()); + } + + // + // Get the computer name string into the locally allocated buffer + // by calling the Win32 GetComputerNameA API. + // + + if (!GetComputerNameA(*ComputerNamePtr, &nSize)) { + LocalFree(*ComputerNamePtr); + *ComputerNamePtr = NULL; + return (GetLastError()); + } + + return (NERR_Success); +} diff --git a/private/eventlog/elfclnt/makefile b/private/eventlog/elfclnt/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/eventlog/elfclnt/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/eventlog/elfclnt/rpcbind.c b/private/eventlog/elfclnt/rpcbind.c new file mode 100644 index 000000000..2cf13c1eb --- /dev/null +++ b/private/eventlog/elfclnt/rpcbind.c @@ -0,0 +1,205 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + rpcbind.c + +Abstract: + + Contains the RPC bind and un-bind routines for the Eventlog + client-side APIs. + +Author: + + Rajen Shah (rajens) 30-Jul-1991 + +Revision History: + + 30-Jul-1991 RajenS + created + +--*/ + +// +// INCLUDES +// +#include <elfclntp.h> +#include <lmsvc.h> + +#define SERVICE_EVENTLOG L"EVENTLOG" + + +/****************************************************************************/ +handle_t +EVENTLOG_HANDLE_W_bind ( + EVENTLOG_HANDLE_W ServerName) + +/*++ + +Routine Description: + This routine calls a common bind routine that is shared by all services. + This routine is called from the ElfOpenEventLog API client stub when + it is necessary to bind to a server. + The binding is done to allow impersonation by the server since that is + necessary for the API calls. + +Arguments: + + ServerName - A pointer to a string containing the name of the server + to bind with. + +Return Value: + + The binding handle is returned to the stub routine. If the + binding is unsuccessful, a NULL will be returned. + +--*/ +{ + handle_t bindingHandle; + RPC_STATUS status; + + status = RpcpBindRpc ( + ServerName, + SERVICE_EVENTLOG, + NULL, + &bindingHandle); + + // DbgPrint("EVENTLOG_bind: handle=%d\n",bindingHandle); + return( bindingHandle); +} + + + +/****************************************************************************/ +void +EVENTLOG_HANDLE_W_unbind ( + EVENTLOG_HANDLE_W ServerName, + handle_t BindingHandle) + +/*++ + +Routine Description: + + This routine calls a common unbind routine that is shared by + all services. + +Arguments: + + ServerName - This is the name of the server from which to unbind. + + BindingHandle - This is the binding handle that is to be closed. + +Return Value: + + none. + +--*/ +{ + RPC_STATUS status; + + // DbgPrint("EVENTLOG_HANDLE_unbind: handle=%d\n",BindingHandle); + status = RpcpUnbindRpc ( BindingHandle); + return; + + UNREFERENCED_PARAMETER(ServerName); + +} + + +handle_t +EVENTLOG_HANDLE_A_bind ( + EVENTLOG_HANDLE_A ServerName) + +/*++ + +Routine Description: + + This routine calls EVENTLOG_HANDLE_W_bind to do the work. + +Arguments: + + ServerName - A pointer to a UNICODE string containing the name of + the server to bind with. + +Return Value: + + The binding handle is returned to the stub routine. If the + binding is unsuccessful, a NULL will be returned. + +--*/ +{ + UNICODE_STRING ServerNameU; + ANSI_STRING ServerNameA; + handle_t bindingHandle; + + // + // Convert the ANSI string to a UNICODE string before calling the + // UNICODE routine. + // + RtlInitAnsiString (&ServerNameA, (PSTR)ServerName); + + RtlAnsiStringToUnicodeString ( + &ServerNameU, + &ServerNameA, + TRUE + ); + + bindingHandle = EVENTLOG_HANDLE_W_bind( + (EVENTLOG_HANDLE_W)ServerNameU.Buffer + ); + + RtlFreeUnicodeString (&ServerNameU); + + return( bindingHandle); +} + + + +/****************************************************************************/ +void +EVENTLOG_HANDLE_A_unbind ( + EVENTLOG_HANDLE_A ServerName, + handle_t BindingHandle) + +/*++ + +Routine Description: + + This routine calls EVENTLOG_HANDLE_W_unbind. + +Arguments: + + ServerName - This is the ANSI name of the server from which to unbind. + + BindingHandle - This is the binding handle that is to be closed. + +Return Value: + + none. + +--*/ +{ + UNICODE_STRING ServerNameU; + ANSI_STRING ServerNameA; + + // + // Convert the ANSI string to a UNICODE string before calling the + // UNICODE routine. + // + RtlInitAnsiString (&ServerNameA, (PSTR)ServerName); + + RtlAnsiStringToUnicodeString ( + &ServerNameU, + &ServerNameA, + TRUE + ); + + EVENTLOG_HANDLE_W_unbind( (EVENTLOG_HANDLE_W)ServerNameU.Buffer, + BindingHandle ); + + RtlFreeUnicodeString (&ServerNameU); + + return; +} diff --git a/private/eventlog/elfclnt/sources b/private/eventlog/elfclnt/sources new file mode 100644 index 000000000..457c34587 --- /dev/null +++ b/private/eventlog/elfclnt/sources @@ -0,0 +1,59 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Rajen Shah (rajens) 2-Jul-1991 + + +Revision History: + +!ENDIF + +# +# The TARGETNAME variable is defined by the developer. It is the name of +# the target (component) that is being built by this makefile. It +# should NOT include any path or file extension information. +# + +MAJORCOMP=eventlog +MINORCOMP=client +TARGETNAME=elfapi +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=LIBRARY + +# +# The INCLUDES variable specifies any include paths that are specific to +# this source directory. Separate multiple directory paths with single +# semicolons. Relative path specifications are okay. +# + +INCLUDES=.;..;$(BASEDIR)\private\inc + +# +# The SOURCES variable is defined by the developer. It is a list of all the +# source files for this component. Each source file should be on a separate +# line using the line continuation character. This will minimize merge +# conflicts if two developers adding source files to the same component. +# + +SOURCES= \ + elf_c.c \ + apistub.c \ + rpcbind.c \ + getconfg.c + +C_DEFINES=$(C_DEFINES) -DRPC_NO_WINDOWS_H -D_ADVAPI32_ |