|
|
/*++
Copyright (c) 2000-2000 Microsoft Corporation
Module Name:
Utils.c
Abstract:
This module implements various Utility routines used by the PGM Transport
Author:
Mohammad Shabbir Alam (MAlam) 3-30-2000
Revision History:
--*/
#include "precomp.h"
#include <stdio.h>
//******************* Pageable Routine Declarations ****************
#ifdef ALLOC_PRAGMA
#endif
//******************* Pageable Routine Declarations ****************
//----------------------------------------------------------------------------
ULONG GetRandomInteger( IN ULONG StartRange, IN ULONG EndRange ) /*++
Routine Description:
This routine returns a random integer calculated using the help of SystemTime
Arguments:
IN StartRange -- Lower bound for range IN EndRange -- upper bound for range
Return Value:
Random integer between StartRange and EndRange (inclusive) If StartRange >= EndRange, then StartRange is returned
--*/ { ULONG Range = (EndRange - StartRange) + 1; LARGE_INTEGER TimeValue;
if (StartRange >= EndRange) { return (StartRange); }
KeQuerySystemTime (&TimeValue); // the lower 4 bits appear to be zero always...!!
return (StartRange + ((TimeValue.LowTime >> 8) % Range)); }
//----------------------------------------------------------------------------
VOID PgmExecuteWorker( IN PVOID pContextInfo ) /*++
Routine Description:
This routine handles executing delayed requests at non-Dpc level. If the Driver is currently being unloaded, we let the Unload Handler complete the request.
Arguments: pContext - the Context data for this Worker thread
Return Value:
none
--*/
{ PGM_WORKER_CONTEXT *pContext = (PGM_WORKER_CONTEXT *) pContextInfo; PPGM_WORKER_ROUTINE pDelayedWorkerRoutine = (PPGM_WORKER_ROUTINE) pContext->WorkerRoutine; PGMLockHandle OldIrq;
(*pDelayedWorkerRoutine) (pContext->Context1, pContext->Context2, pContext->Context3);
PgmFreeMem ((PVOID) pContext);
PgmLock (&PgmDynamicConfig, OldIrq); if ((!--PgmDynamicConfig.NumWorkerThreadsQueued) && (PgmDynamicConfig.GlobalFlags & PGM_CONFIG_FLAG_UNLOADING)) { PgmUnlock (&PgmDynamicConfig, OldIrq); KeSetEvent(&PgmDynamicConfig.LastWorkerItemEvent, 0, FALSE); } else { PgmUnlock (&PgmDynamicConfig, OldIrq); } }
//----------------------------------------------------------------------------
NTSTATUS PgmQueueForDelayedExecution( IN PVOID DelayedWorkerRoutine, IN PVOID Context1, IN PVOID Context2, IN PVOID Context3, IN BOOLEAN fConfigLockHeld ) /*++
Routine Description:
This routine simply queues a request on an excutive worker thread for later execution.
Arguments: DelayedWorkerRoutine- the routine for the Workerthread to call Context1 - Context Context2 Context3
Return Value:
NTSTATUS -- Final status of the Queue request
--*/ { NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; PGM_WORKER_CONTEXT *pContext; PGMLockHandle OldIrq;
if (!fConfigLockHeld) { PgmLock (&PgmDynamicConfig, OldIrq); }
if (pContext = (PGM_WORKER_CONTEXT *) PgmAllocMem (sizeof(PGM_WORKER_CONTEXT), PGM_TAG('2'))) { PgmZeroMemory (pContext, sizeof(PGM_WORKER_CONTEXT)); InitializeListHead(&pContext->PgmConfigLinkage);
pContext->Context1 = Context1; pContext->Context2 = Context2; pContext->Context3 = Context3; pContext->WorkerRoutine = DelayedWorkerRoutine;
//
// Don't Queue this request onto the Worker Queue if we have
// already started unloading
//
if (PgmDynamicConfig.GlobalFlags & PGM_CONFIG_FLAG_UNLOADING) { InsertTailList (&PgmDynamicConfig.WorkerQList, &pContext->PgmConfigLinkage); } else { ++PgmDynamicConfig.NumWorkerThreadsQueued; ExInitializeWorkItem (&pContext->Item, PgmExecuteWorker, pContext); ExQueueWorkItem (&pContext->Item, DelayedWorkQueue); }
status = STATUS_SUCCESS; }
if (!fConfigLockHeld) { PgmUnlock (&PgmDynamicConfig, OldIrq); }
return (status); }
//----------------------------------------------------------------------------
//
// The following routines are temporary and will be replaced by WMI logging
// in the near future
//
//----------------------------------------------------------------------------
NTSTATUS _PgmLog( IN enum eSEVERITY_LEVEL Severity, IN ULONG Path, IN PUCHAR pszFunctionName, IN PUCHAR Format, IN va_list Marker ) /*++
Routine Description:
This routine
Arguments:
IN
Return Value:
NTSTATUS - Final status of the set event operation
--*/ { PUCHAR pLogBuffer = NULL;
if ((Path & PgmLogFilePath) && (Severity <= PgmLogFileSeverity)) { ASSERT (0); // Not implemented yet!
}
if ((Path & PgmDebuggerPath) && (Severity <= PgmDebuggerSeverity)) { if (MAX_DEBUG_MESSAGE_LENGTH <= (sizeof ("RMCast.") + sizeof (": ") + sizeof ("ERROR -- ") + strlen (pszFunctionName) + 1)) { DbgPrint ("PgmLog: FunctionName=<%s> too big to print!\n", pszFunctionName); return (STATUS_UNSUCCESSFUL); }
if (!(pLogBuffer = ExAllocateFromNPagedLookasideList (&PgmStaticConfig.DebugMessagesLookasideList))) { DbgPrint ("PgmLog: STATUS_INSUFFICIENT_RESOURCES Logging %sMessage from Function=<%s>\n", ((Severity == PGM_LOG_ERROR || Severity == PGM_LOG_CRITICAL_ERROR) ? "ERROR " : ""), pszFunctionName); return (STATUS_INSUFFICIENT_RESOURCES); }
strcpy(pLogBuffer, "RMCast."); strcat(pLogBuffer, pszFunctionName); strcat(pLogBuffer, ": ");
if ((Severity == PGM_LOG_ERROR) || (Severity == PGM_LOG_CRITICAL_ERROR)) { strcat(pLogBuffer, "ERROR -- "); }
_vsnprintf (pLogBuffer+strlen(pLogBuffer), MAX_DEBUG_MESSAGE_LENGTH-strlen(pLogBuffer), Format, Marker); pLogBuffer[MAX_DEBUG_MESSAGE_LENGTH] = '\0';
DbgPrint ("%s", pLogBuffer);
ExFreeToNPagedLookasideList (&PgmStaticConfig.DebugMessagesLookasideList, pLogBuffer); }
return (STATUS_SUCCESS); }
//----------------------------------------------------------------------------
NTSTATUS PgmLog( IN enum eSEVERITY_LEVEL Severity, IN ULONG Path, IN PUCHAR pszFunctionName, IN PUCHAR Format, ... ) /*++
Routine Description:
This routine
Arguments:
IN
Return Value:
NTSTATUS - Final status of the set event operation
--*/ { NTSTATUS status = STATUS_SUCCESS; va_list Marker;
//
// Based on our Path and the Flags, see if this Event qualifies
// for being logged
//
if (((Path & PgmDebuggerPath) && (Severity <= PgmDebuggerSeverity)) || ((Path & PgmLogFilePath) && (Severity <= PgmLogFileSeverity))) { va_start (Marker, Format);
status =_PgmLog (Severity, Path, pszFunctionName, Format, Marker);
va_end (Marker); }
return (status); }
//----------------------------------------------------------------------------
|