// eventlog.c // // Requires DDK Only // File created on 11/30/2005 // #include "pch.h" #ifdef CPR_WMI_TRACE #include "eventlog.tmh" #endif CPR_SESSION_QUEUE gSessionQueue; PNPAGED_LOOKASIDE_LIST pEventLog_LookasideList = NULL; volatile ULONG CprNumEventLogsAllocated = 0; PCPR_EVENT_LOG_BUFFER pEventLogBuffer = NULL; /////////////////////////////////////////////////////////////////////////////////////////////////// // CprInitializeEventLog // Sets up a Event Log System. // Lookaside List is allocated out of Non Paged Memory. // // Arguments: // // Return Value: // none // VOID CprInitializeEventLog() { CprDebugPrint(NULL, DBG_PNP, DBG_TRACE, __FUNCTION__"++"); if (pEventLog_LookasideList) { CprCloseDownEventLog(); } pEventLog_LookasideList = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, sizeof(NPAGED_LOOKASIDE_LIST), CPR_POOL_TAG_LOOKASIDE ); if (pEventLog_LookasideList != NULL) { ExInitializeNPagedLookasideList( pEventLog_LookasideList, _CprEventLogAllocate, _CprEventLogFree, 0, sizeof(CPR_EVENT_LOG_KERNEL), CPR_POOL_TAG_EVENT, 0 ); } InitializeListHead(&gSessionQueue.ListHead); KeInitializeSpinLock(&gSessionQueue.QueueLock); CprDebugPrint(NULL, DBG_PNP, DBG_TRACE, __FUNCTION__"--"); } /////////////////////////////////////////////////////////////////////////////////////////////////// // CprCloseDownEventLog // Delete Event Log Lookaside List // // Arguments: // // Return Value: // none // VOID CprCloseDownEventLog() { if (pEventLog_LookasideList != NULL) { //if (g_Data.BackdoorDevice != NULL) //{ // PBACKDOOR_DEVICE_EXTENSION bdExt; // bdExt = (PBACKDOOR_DEVICE_EXTENSION)g_Data.BackdoorDevice->DeviceExtension; CprCleanUpSessions(); ExDeleteNPagedLookasideList(pEventLog_LookasideList); ExFreePool(pEventLog_LookasideList); pEventLog_LookasideList = NULL; //} } } /////////////////////////////////////////////////////////////////////////////////////////////////// // CprGetNewEventLog // Grabs the next available CPR_EVENT_LOG_KERNEL out of the Event Log Lookaside List // // Arguments: // // Return Value: // none // PCPR_EVENT_LOG_KERNEL CprGetNewEventLog() { if (pEventLog_LookasideList != NULL) return ExAllocateFromNPagedLookasideList(pEventLog_LookasideList); return NULL; } /////////////////////////////////////////////////////////////////////////////////////////////////// // CprReleaseEventLog // Returns the CPR_EVENT_LOG_KERNEL back to the Event Log Lookaside List // // Arguments: // // Return Value: // none // VOID CprReleaseEventLog( PCPR_EVENT_LOG_KERNEL pEventLog ) { if (pEventLog && pEventLog_LookasideList) { ExFreeToNPagedLookasideList(pEventLog_LookasideList, (PVOID)pEventLog); } } /////////////////////////////////////////////////////////////////////////////////////////////////// // _CprEventLogAllocate // Allocates Memory. // // Arguments: // // Return Value: // none // PVOID _CprEventLogAllocate( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag ) { PVOID buf = NULL; if (CprNumEventLogsAllocated < CPR_EVENT_LOG_MAX) { buf = ExAllocatePoolWithTag( PoolType, NumberOfBytes, Tag ); if (buf != NULL) { RtlFillMemory(buf, NumberOfBytes, '\0'); CprNumEventLogsAllocated++; } } return buf; } /////////////////////////////////////////////////////////////////////////////////////////////////// // _CprEventLogFree // Free Memory // // Arguments: // // Return Value: // none // VOID _CprEventLogFree( PVOID Buffer ) { CprNumEventLogsAllocated--; ExFreePool(Buffer); } //CprGetNextEventLog(PCPR_EVENT_LOG_HEADER hdr) //{ // PCPR_EVENT_LOG eventLog = NULL; // // hdr = &pEventLogBuffer->header; // // if (!EventLogFull(hdr)) // { // eventLog = hdr->pWrite; // } // // return eventLog; //} char _tmpBuf[256]; /////////////////////////////////////////////////////////////////////////////////////////////////// // _CprLogEvent // // Log Events Per Session // // Arguments: // ULONG type, // ULONG subType, // ULONG flags, // PCPR_DEVICE_EXTENSION devExt, // NTSTATUS status, // char *msg, // // Return Value: // NT status code // NTSTATUS _CprLogEvent ( ULONG type, ULONG subType, PCPR_DEVICE_EXTENSION devExt, NTSTATUS status, char *msg ) { short comPort = 0; short tcpPort = 0; ULONG ipAddr = 0; NTSTATUS Status = STATUS_SUCCESS; PLIST_ENTRY entry; PCPR_SESSION pSession; KIRQL oldIrql; BOOLEAN passUp; BOOLEAN printed = FALSE; if (devExt) { comPort = (short)devExt->portNumber; tcpPort = (short)devExt->Services[devExt->CurService].Port; ipAddr = UnicodeToULong(devExt->Services[devExt->CurService].Address); } KeAcquireSpinLock(&gSessionQueue.QueueLock, &oldIrql); // // Loop through each registered session. // for (entry = gSessionQueue.ListHead.Flink; entry != &gSessionQueue.ListHead; entry = entry->Flink) { // Get the Session from the entry pSession = CONTAINING_RECORD(entry, CPR_SESSION, ListEntry); if (pSession && pSession->EventLogActive && (pSession->FilterData.CprEventFlags & CPR_EVENT_FLAG_PASS_UP)) { unsigned int comNdx = (comPort - 1) >> 5; unsigned int comMask = (1 << ((comPort - 1) % 32)); if ((comNdx < 8) && ((pSession->FilterData.CprComPorts[comNdx] & comMask) == comMask)) { passUp = type && ((pSession->FilterData.CprEventLogFilter & type) == type); passUp |= subType && ((pSession->FilterData.CprELIoctlFilter & subType) == subType); // Has this session registered for this event? if (passUp) { PCPR_EVENT_LOG_KERNEL elogKernel; int i; elogKernel = CprGetNewEventLog(); if (elogKernel != NULL) { PCPR_EVENT_LOG elog = &elogKernel->eventLog; char *msgDst; char *msgSrc; // Populate it elog->ticks = KeQueryPerformanceCounter(NULL); elog->type = type; elog->subType = subType; elog->flags = pSession->FilterData.CprEventFlags; elog->comPort = comPort; elog->tcpPort = tcpPort; elog->ipAddr = ipAddr; elog->status = status; elog->sessionId = devExt->sessionId; elog->msg[0] = '\0'; if (msg != NULL) { if ((type == CPR_EVENT_TYPE_READ) || (type == CPR_EVENT_TYPE_WRITE) || (type == CPR_EVENT_TYPE_DATA_RECEIVE) || (type == CPR_EVENT_TYPE_DATA_TRANSMIT) || (type == CPR_EVENT_TYPE_PENDED_READ_RELEASED)) { RtlMoveMemory(elog->msg, msg, sizeof(elog->msg)); } else { RtlStringCchCopyA(elog->msg, sizeof(elog->msg), msg); } } Status = CprQueueEventLog(pSession, elogKernel); } } } } if (printed == FALSE) { if (pSession->FilterData.CprEventFlags & CPR_EVENT_FLAG_DBGPRINT) { char *GetEventStr(ULONG type, ULONG subType); printed = TRUE; // Only print once. if (msg == NULL) msg = ""; RtlStringCchPrintfA(_tmpBuf, 256, "CPR_EVENT: %s Com%d TcpPort %d IpAddress %x Status 0x%08x (%s)\n", GetEventStr(type, subType), comPort, tcpPort, ipAddr, status, msg); DbgPrint((_tmpBuf)); } } } KeReleaseSpinLock(&gSessionQueue.QueueLock, oldIrql); return Status; } char *GetEventStr(ULONG type, ULONG subType) { switch(type) { case CPR_EVENT_TYPE_OPEN: return "Open"; case CPR_EVENT_TYPE_CLOSE: return "Close"; case CPR_EVENT_TYPE_READ: return "Read"; case CPR_EVENT_TYPE_WRITE: return "Write"; case CPR_EVENT_TYPE_DEBUG: return "Debug"; case CPR_EVENT_TYPE_XON: return "Xon"; case CPR_EVENT_TYPE_XOFF: return "Xoff"; case CPR_EVENT_TYPE_RFC2217: return "RFC2217"; case CPR_EVENT_TYPE_CONNECT: return "Connect"; case CPR_EVENT_TYPE_DISCONNECT: return "Reconnecting"; case CPR_EVENT_TYPE_RECONNECTING: return "Reconnected"; case CPR_EVENT_TYPE_RECONNECTED: return "Reconnected"; case CPR_EVENT_TYPE_WRITE_TIMEOUT: return "Write Timeout"; case CPR_EVENT_TYPE_WAIT_RXCHAR: return "Wait RxChar"; case CPR_EVENT_TYPE_WAIT_RXFLAG: return "Wait RxFlag"; case CPR_EVENT_TYPE_WAIT_TXEMPTY: return "Wait TxEmpty"; case CPR_EVENT_TYPE_WAIT_CTS: return "Wait CTS"; case CPR_EVENT_TYPE_WAIT_DSR: return "Wait DSR"; case CPR_EVENT_TYPE_WAIT_RLSD: return "Wait RLSD"; case CPR_EVENT_TYPE_WAIT_BREAK: return "Wait Break"; case CPR_EVENT_TYPE_WAIT_ERR: return "Wait Err"; case CPR_EVENT_TYPE_WAIT_RING: return "Wait Ring"; case CPR_EVENT_TYPE_WAIT_RX80FULL: return "Wait Rx80Full"; case CPR_EVENT_TYPE_DATA_RECEIVE: return "Data Receive"; case CPR_EVENT_TYPE_DATA_TRANSMIT: return "Data Transmit"; case CPR_EVENT_TYPE_READ_TIMEOUT: return "Read Timeout"; case CPR_EVENT_TYPE_PENDED_READ_RELEASED: return "Pended Read Released"; case CPR_EVENT_TYPE_READ_OVERFLOW: return "Read Overflow"; default: case CPR_EVENT_TYPE_NONE: switch(subType) { case CPR_ET_IOCTL_PURGE: return "Purge"; case CPR_ET_IOCTL_GET_HANDFLOW: return "GetHandflow"; case CPR_ET_IOCTL_SET_HANDFLOW: return "SetHandflow"; case CPR_ET_IOCTL_GET_MODEM_STATUS: return "GetModemStatus"; case CPR_ET_IOCTL_GET_DTRRTS: return "GetDTR_RST"; case CPR_ET_IOCTL_GET_COMM_STATUS: return "GetCommStatus"; case CPR_ET_IOCTL_GET_PROPERTIES: return "GetProperties"; case CPR_ET_IOCTL_SET_BAUDRATE: return "SetBaudrate"; case CPR_ET_IOCTL_GET_BAUDRATE: return "Get_Baudrate"; case CPR_ET_IOCTL_SET_MODEM_CONTROL: return "GetModemControl"; case CPR_ET_IOCTL_GET_MODEM_CONTROL: return "SetModemControl"; case CPR_ET_IOCTL_SET_LINE_CONTROL: return "SetLineControl"; case CPR_ET_IOCTL_XOFF_COUNTER: return "XoffCounter"; case CPR_ET_IOCTL_GET_STATS: return "GetStats"; case CPR_ET_IOCTL_SET_TIMEOUTS: return "SetTimeouts"; case CPR_ET_IOCTL_GET_TIMEOUTS: return "GetTimeouts"; case CPR_ET_IOCTL_SET_CHARS: return "SetChars"; case CPR_ET_IOCTL_GET_CHARS: return "GetChars"; case CPR_ET_IOCTL_SET_DTR: return "SetDTR"; case CPR_ET_IOCTL_CLEAR_DTR: return "ClearDTR"; case CPR_ET_IOCTL_SET_RTS: return "SetRTS"; case CPR_ET_IOCTL_CLEAR_RTS: return "ClearRTS"; case CPR_ET_IOCTL_SET_XON: return "SetXOn"; case CPR_ET_IOCTL_SET_XOFF: return "SetXOff"; case CPR_ET_IOCTL_SET_BREAK_ON: return "SetBreakOn"; case CPR_ET_IOCTL_SET_QUEUE_SIZE: return "SetQueueSize"; case CPR_ET_IOCTL_GET_WAIT_MASK: return "GetWaitMask"; case CPR_ET_IOCTL_SET_WAIT_MASK: return "SetWaitMask"; case CPR_ET_IOCTL_WAIT_ON_MASK: return "WaitOnMask"; case CPR_ET_IOCTL_IMMEDIATE_CHAR: return "ImmediateChar"; case CPR_ET_IOCTL_GET_LINE_CONTROL: return "GetLineControl"; default: return "Unknown"; } } }