|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
logging.c
Abstract:
This module contains routines for trace logging.
Author:
Stephen Hsiao (shsiao) 01-Jan-2000
Revision History:
--*/
#include "perfp.h"
#ifndef NTPERF
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGEWMI, PerfInfoReserveBytes)
#pragma alloc_text(PAGEWMI, PerfInfoLogBytes)
#endif //ALLOC_PRAGMA
#endif // !NTPERF
NTSTATUS PerfInfoReserveBytes( PPERFINFO_HOOK_HANDLE Hook, USHORT HookId, ULONG BytesToReserve ) /*++
Routine Description:
Reserves memory for the hook via WMI and initializes the header.
Arguments:
Hook - pointer to hook handle (used for reference decrement) HookId - Id for the hook BytesToLog - size of data in bytes
Return Value:
STATUS_SUCCESS on success STATUS_UNSUCCESSFUL if the buffer memory couldn't be allocated. --*/ { NTSTATUS Status = STATUS_UNSUCCESSFUL; PPERFINFO_TRACE_HEADER PPerfTraceHeader = NULL; PWMI_BUFFER_HEADER PWmiBufferHeader = NULL;
PERF_ASSERT((BytesToReserve + FIELD_OFFSET(PERFINFO_TRACE_HEADER, Data)) <= MAXUSHORT); PERF_ASSERT(Hook != NULL);
PPerfTraceHeader = WmiReserveWithPerfHeader(BytesToReserve, &PWmiBufferHeader);
if (PPerfTraceHeader != NULL) { PPerfTraceHeader->Packet.HookId = HookId; Hook->PerfTraceHeader = PPerfTraceHeader; Hook->WmiBufferHeader = PWmiBufferHeader;
Status = STATUS_SUCCESS; } else { *Hook = PERF_NULL_HOOK_HANDLE; }
return Status; }
NTSTATUS PerfInfoLogBytes( USHORT HookId, PVOID Data, ULONG BytesToLog ) /*++
Routine Description:
Reserves memory for the hook, copies the data, and unref's the hook entry.
Arguments:
HookId - Id for the hook Data - pointer to the data to be logged BytesToLog - size of data in bytes
Return Value:
STATUS_SUCCESS on success --*/ { PERFINFO_HOOK_HANDLE Hook; NTSTATUS Status;
Status = PerfInfoReserveBytes(&Hook, HookId, BytesToLog); if (!NT_SUCCESS(Status)) { return Status; }
RtlCopyMemory(PERFINFO_HOOK_HANDLE_TO_DATA(Hook, PPERF_BYTE), Data, BytesToLog); PERF_FINISH_HOOK(Hook);
return STATUS_SUCCESS; }
#ifdef NTPERF
PVOID FASTCALL PerfInfoReserveBytesFromPerfMem( ULONG BytesToReserve ) /*++
Routine Description:
Reserves memory for the hook from the buffer, initializes the header, and the hook handle.
Arguments:
Hook - pointer to hook handle (used for reference decrement) HookId - Id for the hook BytesToLog - size of data in bytes
Return Value:
STATUS_SUCCESS on success STATUS_UNSUCCESSFUL if the buffer memory couldn't be allocated. --*/ { PPERFINFO_TRACEBUF_HEADER pPerfBufHdr; PPERF_BYTE CurrentPtr; PPERF_BYTE NewPtr; PPERF_BYTE OriginalPtr; BOOLEAN Done = FALSE; ULONG AlignedTotBytes;
pPerfBufHdr = PerfBufHdr();
AlignedTotBytes = ALIGN_TO_POWER2(BytesToReserve, DEFAULT_TRACE_ALIGNMENT);
OriginalPtr = pPerfBufHdr->Current.Ptr; while (!Done) { NewPtr = OriginalPtr + AlignedTotBytes; if (NewPtr <= pPerfBufHdr->Max.Ptr) { //
// If the buffer pointer has not changed, returned value will be == to the comparand,
// OriginalPointer, and the Destenation will be updated with the new end of buffer.
//
// If it did change, the Destination will not change and the a new end of buffer will
// be returned. We loop until we get it in or the buffer is full.
//
CurrentPtr = (PPERF_BYTE) InterlockedCompareExchangePointer( (PVOID *)&(pPerfBufHdr->Current.Ptr), (PVOID)NewPtr, (PVOID)OriginalPtr ); if (OriginalPtr == CurrentPtr) { Done = TRUE; } else { OriginalPtr = CurrentPtr; } } else { //
// Buffer overflow
//
Done = TRUE; CurrentPtr = NULL; } }
return CurrentPtr; } #endif //NTPERF
|