/*++
*******************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved				*
* 																										*
* This software contains proprietary and confidential information of Digi		*
* International Inc.  By accepting transfer of this copy, Recipient agrees		*
* to retain this software in confidence, to prevent disclosure to others,		*
* and to make no use of this software other than that for which it was			*
* delivered.  This is an unpublished copyrighted work of Digi International	*
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly	*
* prohibited.																						*
* 																										*
* Restricted Rights Legend																		*
*																										*
* Use, duplication, or disclosure by the Government is subject to					*
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in			*
* Technical Data and Computer Software clause at DFARS 252.227-7031 or			*
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -				*
* Restricted Rights at 48 CFR 52.227-19, as applicable.								*
*																										*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343				*
*																										*
*******************************************************************************

Module Name:

   digilog.c

Abstract:

   Routines to log errors as well as print out debug messages.

Author:

   Michael Zarns

--*/

#include "digilib.h"


VOID 
DigiLogError( 
	IN PVOID    pObject,
	IN NTSTATUS ErrorCode,
	IN ULONG    ErrorIndex,
	IN PVOID    pData OPTIONAL,
	IN ULONG    cbData,
	IN PWCHAR   pString1 OPTIONAL,
	IN ULONG    cbString1,
	IN PWCHAR   pString2 OPTIONAL,
	IN ULONG    cbString2 )
/*++

Routine Description:

    This routine allocates an error log entry, copies the supplied data
    to it, and attempts to write it to the system error log.

Arguments:

	pObject
		Driver or Device object associated with the error

	ErrorCode
		An IO_ERR_XXX style error value.

	ErrorIndex
		Unique value that identifies the particular call to this routine.

	pData
		Dump data to be displayed in the event log.  If NULL, no dump data used.

	cbData
		Length of data to include.

	pString1
		Insertion string.  If NULL, no insertion string used.  Typically this is the 
		adapter name.  This string is referred to as %2 in event error messages.

	cbString1
		Length of insertion string, including terminating NULL.

	pString2
		Another insertion string.  pString must be present if pString2 is used.  This
		string is referred to as %3 in event error message.

	cbString2
		Length of insertion string 2, including terminating NULL.

Return Value:

    None.

--*/
{
   PIO_ERROR_LOG_PACKET pLog;
	ULONG cbLog;
	ULONG InsertOffset;
	USHORT cbDataAligned = (USHORT)( (cbData + 0x03) & ~0x03 );

	ASSERT( pString1 != NULL || pString2 == NULL );

	cbLog = MAX(FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + cbDataAligned + cbString1 + cbString2, sizeof(IO_ERROR_LOG_PACKET));
	if ( cbLog > ERROR_LOG_MAXIMUM_SIZE )
	{
		DigiDump( DEBUG_ERROR, ( "DigiLogError: ErrorLogEntry size (0x%x) exceeds maximum allowed size (0x%x)!\n",
		          cbLog, ERROR_LOG_MAXIMUM_SIZE ) );
		goto Exit;
	}

   pLog = IoAllocateErrorLogEntry( pObject, (UCHAR)cbLog );
	if ( pLog == NULL )
		goto Exit;

	RtlZeroMemory( pLog, cbLog );
   pLog->ErrorCode        = ErrorCode;
   pLog->UniqueErrorValue = ErrorIndex;
   pLog->DumpDataSize     = cbDataAligned;
	InsertOffset = FIELD_OFFSET( IO_ERROR_LOG_PACKET, DumpData );

   if( cbData && pData )
   {
		RtlCopyMemory( (PCHAR)pLog + InsertOffset, pData, cbData );
		InsertOffset += cbDataAligned;
   }

	if ( cbString1 && pString1 )
	{
		pLog->NumberOfStrings++;
		pLog->StringOffset = (USHORT)InsertOffset;
		RtlCopyMemory( (PCHAR)pLog + InsertOffset, pString1, cbString1 );
		InsertOffset += cbString1;
	}

	if ( cbString2 && pString2 )
	{
		pLog->NumberOfStrings++;
		RtlCopyMemory( (PCHAR)pLog + InsertOffset, pString2, cbString2 );
		InsertOffset += cbString2;
	}

	ASSERT( InsertOffset == cbLog || sizeof(IO_ERROR_LOG_PACKET) == cbLog);

   IoWriteErrorLogEntry( pLog );

Exit:
	return ;
}
