windows-nt/Source/XPSP1/NT/drivers/parallel/parclass/debug.c
2020-09-26 16:20:57 +08:00

505 lines
18 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: debug.c
//
//--------------------------------------------------------------------------
//
// This file contains functions that are only used for debugging the ParClass driver.
//
#include "pch.h"
#if (1 == DVRH_PAR_LOGFILE)
#include "stdarg.h"
#include "stdio.h"
#endif
static STRUCTUREOFFSETSTABLE gsotDEVICE_EXTENSION [] = {
{"ExtensionSignature", FIELD_OFFSET(DEVICE_EXTENSION, ExtensionSignature)},
{"DeviceType", FIELD_OFFSET(DEVICE_EXTENSION, DeviceType)},
{"DeviceStateFlags", FIELD_OFFSET(DEVICE_EXTENSION, DeviceStateFlags)},
{"Ieee1284_3DeviceId", FIELD_OFFSET(DEVICE_EXTENSION, Ieee1284_3DeviceId)},
{"IsPdo", FIELD_OFFSET(DEVICE_EXTENSION, IsPdo)},
{"EndOfChain", FIELD_OFFSET(DEVICE_EXTENSION, EndOfChain)},
{"PodoRegForWMI", FIELD_OFFSET(DEVICE_EXTENSION, PodoRegForWMI)},
{"ParClassFdo", FIELD_OFFSET(DEVICE_EXTENSION, ParClassFdo)},
{"ParClassPdo", FIELD_OFFSET(DEVICE_EXTENSION, ParClassPdo)},
{"Next", FIELD_OFFSET(DEVICE_EXTENSION, Next)},
{"DeviceObject", FIELD_OFFSET(DEVICE_EXTENSION, DeviceObject)},
{"PortDeviceObject", FIELD_OFFSET(DEVICE_EXTENSION, PortDeviceObject)},
{"PortDeviceFileObject", FIELD_OFFSET(DEVICE_EXTENSION, PortDeviceFileObject)},
{"PortSymbolicLinkName", FIELD_OFFSET(DEVICE_EXTENSION, PortSymbolicLinkName)},
{"PhysicalDeviceObject", FIELD_OFFSET(DEVICE_EXTENSION, PhysicalDeviceObject)},
{"ParentDeviceObject", FIELD_OFFSET(DEVICE_EXTENSION, ParentDeviceObject)},
{"CurrentOpIrp", FIELD_OFFSET(DEVICE_EXTENSION, CurrentOpIrp)},
{"NotificationHandle", FIELD_OFFSET(DEVICE_EXTENSION, NotificationHandle)},
{"ClassName", FIELD_OFFSET(DEVICE_EXTENSION, ClassName)},
{"SymbolicLinkName", FIELD_OFFSET(DEVICE_EXTENSION, SymbolicLinkName)},
{"TimerStart", FIELD_OFFSET(DEVICE_EXTENSION, TimerStart)},
{"CreatedSymbolicLink", FIELD_OFFSET(DEVICE_EXTENSION, CreatedSymbolicLink)},
{"UsePIWriteLoop", FIELD_OFFSET(DEVICE_EXTENSION, UsePIWriteLoop)},
{"Initialized", FIELD_OFFSET(DEVICE_EXTENSION, Initialized)},
{"Initializing", FIELD_OFFSET(DEVICE_EXTENSION, Initializing)},
{"OpenCloseRefCount", FIELD_OFFSET(DEVICE_EXTENSION, OpenCloseRefCount)},
{"ParPortDeviceGone", FIELD_OFFSET(DEVICE_EXTENSION, ParPortDeviceGone)},
{"RegForPptRemovalRelations", FIELD_OFFSET(DEVICE_EXTENSION, RegForPptRemovalRelations)},
{"spare1", FIELD_OFFSET(DEVICE_EXTENSION, spare1)},
{"IdxForwardProtocol", FIELD_OFFSET(DEVICE_EXTENSION, IdxForwardProtocol)},
{"IdxReverseProtocol", FIELD_OFFSET(DEVICE_EXTENSION, IdxReverseProtocol)},
{"CurrentEvent", FIELD_OFFSET(DEVICE_EXTENSION, CurrentEvent)},
{"CurrentPhase", FIELD_OFFSET(DEVICE_EXTENSION, CurrentPhase)},
{"PortHWMode", FIELD_OFFSET(DEVICE_EXTENSION, PortHWMode)},
{"OpenCloseMutex", FIELD_OFFSET(DEVICE_EXTENSION, OpenCloseMutex)},
{"DevObjListMutex", FIELD_OFFSET(DEVICE_EXTENSION, DevObjListMutex)},
{"WorkQueue", FIELD_OFFSET(DEVICE_EXTENSION, WorkQueue)},
{"ThreadObjectPointer", FIELD_OFFSET(DEVICE_EXTENSION, ThreadObjectPointer)},
{"RequestSemaphore", FIELD_OFFSET(DEVICE_EXTENSION, RequestSemaphore)},
{"OriginalController", FIELD_OFFSET(DEVICE_EXTENSION, OriginalController)},
{"Controller", FIELD_OFFSET(DEVICE_EXTENSION, Controller)},
{"EcrController", FIELD_OFFSET(DEVICE_EXTENSION, EcrController)},
{"SpanOfController", FIELD_OFFSET(DEVICE_EXTENSION, SpanOfController)},
{"TryAllocatePort", FIELD_OFFSET(DEVICE_EXTENSION, TryAllocatePort)},
{"FreePort", FIELD_OFFSET(DEVICE_EXTENSION, FreePort)},
{"QueryNumWaiters", FIELD_OFFSET(DEVICE_EXTENSION, QueryNumWaiters)},
{"PortContext", FIELD_OFFSET(DEVICE_EXTENSION, PortContext)},
{"HardwareCapabilities", FIELD_OFFSET(DEVICE_EXTENSION, HardwareCapabilities)},
{"TrySetChipMode", FIELD_OFFSET(DEVICE_EXTENSION, TrySetChipMode)},
{"ClearChipMode", FIELD_OFFSET(DEVICE_EXTENSION, ClearChipMode)},
{"TrySelectDevice", FIELD_OFFSET(DEVICE_EXTENSION, TrySelectDevice)},
{"DeselectDevice", FIELD_OFFSET(DEVICE_EXTENSION, DeselectDevice)},
{"FifoDepth", FIELD_OFFSET(DEVICE_EXTENSION, FifoDepth)},
{"FifoWidth", FIELD_OFFSET(DEVICE_EXTENSION, FifoWidth)},
{"bAllocated", FIELD_OFFSET(DEVICE_EXTENSION, bAllocated)},
{"BusyDelay", FIELD_OFFSET(DEVICE_EXTENSION, BusyDelay)},
{"BusyDelayDetermined", FIELD_OFFSET(DEVICE_EXTENSION, BusyDelayDetermined)},
{"DeferredWorkItem", FIELD_OFFSET(DEVICE_EXTENSION, DeferredWorkItem)},
{"TimeToTerminateThread", FIELD_OFFSET(DEVICE_EXTENSION, TimeToTerminateThread)},
{"UseNT35Priority", FIELD_OFFSET(DEVICE_EXTENSION, UseNT35Priority)},
{"InitializationTimeout", FIELD_OFFSET(DEVICE_EXTENSION, InitializationTimeout)},
{"AbsoluteOneSecond", FIELD_OFFSET(DEVICE_EXTENSION, AbsoluteOneSecond)},
{"OneSecond", FIELD_OFFSET(DEVICE_EXTENSION, OneSecond)},
{"Connected", FIELD_OFFSET(DEVICE_EXTENSION, Connected)},
{"AllocatedByLockPort", FIELD_OFFSET(DEVICE_EXTENSION, AllocatedByLockPort)},
{"spare4", FIELD_OFFSET(DEVICE_EXTENSION, spare4)},
{"fnRead", FIELD_OFFSET(DEVICE_EXTENSION, fnRead)},
{"fnWrite", FIELD_OFFSET(DEVICE_EXTENSION, fnWrite)},
{"IdleTimeout", FIELD_OFFSET(DEVICE_EXTENSION, IdleTimeout)},
{"ProtocolData", FIELD_OFFSET(DEVICE_EXTENSION, ProtocolData)},
{"ForwardInterfaceAddress", FIELD_OFFSET(DEVICE_EXTENSION, ForwardInterfaceAddress)},
{"ReverseInterfaceAddress", FIELD_OFFSET(DEVICE_EXTENSION, ReverseInterfaceAddress)},
{"SetForwardAddress", FIELD_OFFSET(DEVICE_EXTENSION, SetForwardAddress)},
{"SetReverseAddress", FIELD_OFFSET(DEVICE_EXTENSION, SetReverseAddress)},
{"LockPortMutex", FIELD_OFFSET(DEVICE_EXTENSION, LockPortMutex)},
{"DeviceState", FIELD_OFFSET(DEVICE_EXTENSION, DeviceState)},
{"SystemState", FIELD_OFFSET(DEVICE_EXTENSION, SystemState)},
{"spare2", FIELD_OFFSET(DEVICE_EXTENSION, spare2)},
{"bShadowBuffer", FIELD_OFFSET(DEVICE_EXTENSION, bShadowBuffer)},
{"ShadowBuffer", FIELD_OFFSET(DEVICE_EXTENSION, ShadowBuffer)},
{"spare3", FIELD_OFFSET(DEVICE_EXTENSION, spare3)},
{"bSynchWrites", FIELD_OFFSET(DEVICE_EXTENSION, bSynchWrites)},
{"bFirstByteTimeout", FIELD_OFFSET(DEVICE_EXTENSION, bFirstByteTimeout)},
{"bIsHostRecoverSupported", FIELD_OFFSET(DEVICE_EXTENSION, bIsHostRecoverSupported)},
{"PauseEvent", FIELD_OFFSET(DEVICE_EXTENSION, PauseEvent)},
{"ProtocolModesSupported", FIELD_OFFSET(DEVICE_EXTENSION, ProtocolModesSupported)},
{"BadProtocolModes", FIELD_OFFSET(DEVICE_EXTENSION, BadProtocolModes)},
{"ModeSafety", FIELD_OFFSET(DEVICE_EXTENSION, ModeSafety)},
{"IsIeeeTerminateOk", FIELD_OFFSET(DEVICE_EXTENSION, IsIeeeTerminateOk)},
{"IsCritical", FIELD_OFFSET(DEVICE_EXTENSION, IsCritical)},
{"P12843DL", FIELD_OFFSET(DEVICE_EXTENSION, P12843DL)},
{"log", FIELD_OFFSET(DEVICE_EXTENSION, log)},
{"WmiLibContext", FIELD_OFFSET(DEVICE_EXTENSION, WmiLibContext)},
{"WmiRegistrationCount", FIELD_OFFSET(DEVICE_EXTENSION, WmiRegistrationCount)},
{"DeviceIdString", FIELD_OFFSET(DEVICE_EXTENSION, DeviceIdString)},
{"DeviceDescription", FIELD_OFFSET(DEVICE_EXTENSION, DeviceDescription)},
{"dummy", FIELD_OFFSET(DEVICE_EXTENSION, dummy)},
{"RemoveLock", FIELD_OFFSET(DEVICE_EXTENSION, RemoveLock)},
{"HwProfileChangeNotificationHandle", FIELD_OFFSET(DEVICE_EXTENSION, HwProfileChangeNotificationHandle)},
{"ExtensionSignatureEnd", FIELD_OFFSET(DEVICE_EXTENSION, ExtensionSignatureEnd)},
{NULL, sizeof(DEVICE_EXTENSION)}
};
#if DBG
#if (1 == DVRH_PAR_LOGFILE)
/**************************************************************************
Function: DVRH_LogMessage()
Description:Logs message to configured output
Inputs: Parameter indicated message log level and
Format string and parameters
Outputs: Boolean value indicating success or failure
***************************************************************************/
BOOLEAN DVRH_LogMessage(PCHAR szFormat, ...)
{
ULONG Length;
char messagebuf[256];
va_list va;
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES objectAttributes;
NTSTATUS status;
HANDLE FileHandle;
UNICODE_STRING fileName;
//format the string
va_start(va,szFormat);
vsprintf(messagebuf,szFormat,va);
va_end(va);
//get a handle to the log file object
fileName.Buffer = NULL;
fileName.Length = 0;
fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL);
fileName.Buffer = ExAllocatePool(PagedPool,
fileName.MaximumLength);
if (!fileName.Buffer)
{
ParDump2(PARERRORS, ("LogMessage: FAIL. ExAllocatePool Failed.\n") );
return FALSE;
}
RtlZeroMemory(fileName.Buffer, fileName.MaximumLength);
status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME);
InitializeObjectAttributes (&objectAttributes,
(PUNICODE_STRING)&fileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
status = ZwCreateFile(&FileHandle,
FILE_APPEND_DATA,
&objectAttributes,
&IoStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if(NT_SUCCESS(status))
{
CHAR buf[300];
LARGE_INTEGER time;
KeQuerySystemTime(&time);
//put a time stamp on the output message
sprintf(buf,"%10u-%10u %s",time.HighPart,time.LowPart,messagebuf);
//format the string to make sure it appends a newline carrage-return to the
//end of the string.
Length=strlen(buf);
if(buf[Length-1]=='\n')
{
buf[Length-1]='\r';
strcat(buf,"\n");
Length++;
}
else
{
strcat(buf,"\r\n");
Length+=2;
}
ZwWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatus,
buf,
Length,
NULL,
NULL );
ZwClose(FileHandle);
}
if (fileName.Buffer)
ExFreePool (fileName.Buffer);
return STATUS_SUCCESS;
}
/**************************************************************************
Function: DVRH_LogByteData()
Description:Formats byte data to be displayed in the configured output
Inputs: Log level, Whether this is input or output data, a pointer to
the byte data buffer and the size of the buffer
Outputs: Boolean indicated success or failure
***************************************************************************/
#if 0
BOOLEAN DVRH_LogByteData(BOOLEAN READ,PCHAR szBuff,ULONG dwTransferred)
{
CString cStr;
ULONG MAX_SIZE=80;
UNICODE_STRING UniStr;
ANSI_STRING AnsiStr;
WCHAR wStr[8];
PCHAR szTemp=szBuff;
UCHAR bTemp;
ULONG dwDisplaySize;
UniStr.Length=0;
UniStr.MaximumLength=8;
UniStr.Buffer=wStr;
AnsiStr.Length=0;
AnsiStr.MaximumLength=0;
AnsiStr.Buffer=NULL;
if(READ)
cStr=L"<RCV";
else
cStr=L"SND>";
//make sure the size of the requested string is within the set range
dwDisplaySize=(((dwTransferred*3)+10) > MAX_SIZE)?((MAX_SIZE-10)/3):dwTransferred;
//format byte data
while(dwDisplaySize)
{
bTemp=szTemp[0];
if(bTemp > 0xF)
cStr+=L" ";
else
cStr+=L" 0";
RtlIntegerToUnicodeString(bTemp,16,&UniStr);
cStr+=UniStr.Buffer;
szTemp++;
dwDisplaySize--;
}
cStr.StringToAnsiString(&AnsiStr);
LogMessage("%5u %s",dwTransferred,AnsiStr.Buffer);
RtlFreeAnsiString(&AnsiStr);
return (TRUE);
}
#endif
#endif // (1 == DVRH_PAR_LOGFILE)
VOID
ParInitDebugLevel (
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Checked Build Only!
Initialize debugging variables from registry; set to default values
if anything fails.
Arguments:
RegistryPath - Root path in registry where we should look
Return Value:
None
--*/
{
NTSTATUS Status;
RTL_QUERY_REGISTRY_TABLE paramTable[4];
PWSTR path;
ULONG defaultDebugLevel = PARDUMP_SILENT;
ULONG defaultBreakOn = PAR_BREAK_ON_NOTHING;
ULONG defaultUseAsserts = 0; // don't use asserts
//
// We were given a counted string, but we need a null terminated string
//
path = ExAllocatePool(PagedPool, RegistryPath->Length+sizeof(WCHAR));
if (!path) {
// can't get a buffer, use defaults and return
ParDebugLevel = defaultDebugLevel;
ParBreakOn = defaultBreakOn;
ParUseAsserts = defaultUseAsserts;
return;
}
RtlMoveMemory(path, RegistryPath->Buffer, RegistryPath->Length);
path[ (RegistryPath->Length) / 2 ] = UNICODE_NULL;
//
// set up table entries for call to RtlQueryRegistryValues
//
RtlZeroMemory(&paramTable[0], sizeof(paramTable));
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[0].Name = (PWSTR)L"ParDebugLevel";
paramTable[0].EntryContext = &ParDebugLevel;
paramTable[0].DefaultType = REG_DWORD;
paramTable[0].DefaultData = &defaultDebugLevel;
paramTable[0].DefaultLength = sizeof(ULONG);
paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[1].Name = (PWSTR)L"ParBreakOn";
paramTable[1].EntryContext = &ParBreakOn;
paramTable[1].DefaultType = REG_DWORD;
paramTable[1].DefaultData = &defaultBreakOn;
paramTable[1].DefaultLength = sizeof(ULONG);
paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[2].Name = (PWSTR)L"ParUseAsserts";
paramTable[2].EntryContext = &defaultUseAsserts;
paramTable[2].DefaultType = REG_DWORD;
paramTable[2].DefaultData = &defaultBreakOn;
paramTable[2].DefaultLength = sizeof(ULONG);
//
// leave paramTable[3] as all zeros - this terminates the table
//
Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
path,
&paramTable[0],
NULL,
NULL);
if (!NT_SUCCESS(Status)) {
// registry read failed, use defaults
ParDebugLevel = defaultDebugLevel;
ParBreakOn = defaultBreakOn;
ParUseAsserts = defaultUseAsserts;
}
ExFreePool( path );
ParDumpV( ("ParDebugLevel = %08x , ParBreakOn = %08x\n", ParDebugLevel, ParBreakOn) );
}
#endif // DBG
#if DBG
VOID
ParDumpDeviceObjectList(
PDEVICE_OBJECT ParClassFdo
)
/*++
Routine Description:
This function is a diagnostic routine that is only
available in Checked builds
Dump the list of ParClass ejected Device Objects
Arguments:
FdoDeviceObject - The ParClass Function Device Object
Return Value:
NONE
--*/
{
PDEVICE_EXTENSION FdoExtension = ParClassFdo ->DeviceExtension;
PDEVICE_OBJECT currentDO = FdoExtension->ParClassPdo;
ParDump(PARDUMP_VERBOSE_MAX,
("PARALLEL: ParDumpDeviceObjectList(...):\n") );
while( currentDO ) {
PDEVICE_EXTENSION currentExt = currentDO->DeviceExtension;
ParDump(PARDUMP_VERBOSE_MAX,
("PARALLEL: - %x %wZ %wZ\n",
currentDO, &currentExt->ClassName, &currentExt->SymbolicLinkName) );
currentDO = ( (PDEVICE_EXTENSION)(currentDO->DeviceExtension) )->Next;
}
}
#endif
NTSTATUS
ParAcquireRemoveLock(
IN PIO_REMOVE_LOCK RemoveLock,
IN PVOID Tag OPTIONAL
)
{
NTSTATUS status;
ParDump2(PARREMLOCK, ("debug::ParAcquireRemoveLock: RemoveLock= %x , Tag= %x\n", RemoveLock, Tag) );
ParDump2(PARREMLOCK, ("debug::ParAcquireRemoveLock: Count [%x] Removed[%x] - calling IoAcquireRemoveLock\n",
RemoveLock->Common.IoCount, RemoveLock->Common.Removed));
status = IoAcquireRemoveLock(RemoveLock, Tag);
return status;
}
VOID
ParReleaseRemoveLock(
IN PIO_REMOVE_LOCK RemoveLock,
IN PVOID Tag OPTIONAL
)
{
ParDump2(PARREMLOCK, ("debug::ParReleaseRemoveLock: RemoveLock= %x , Tag= %x\n", RemoveLock, Tag) );
ParDump2(PARREMLOCK, ("debug::ParReleaseRemoveLock: Count [%x] Removed[%x] - calling IoReleaseRemoveLock\n",
RemoveLock->Common.IoCount, RemoveLock->Common.Removed));
IoReleaseRemoveLock(RemoveLock, Tag);
}
VOID
ParReleaseRemoveLockAndWait(
IN PIO_REMOVE_LOCK RemoveLock,
IN PVOID Tag
)
{
ParDump2(PARREMLOCK, ("debug::ParReleaseRemoveLockAndWait: RemoveLock= %x , Tag= %x\n", RemoveLock, Tag) );
ParDump2(PARREMLOCK, ("debug::ParReleaseRemoveLock: Count [%x] Removed[%x] - calling IoReleaseRemoveLockAndWait\n",
RemoveLock->Common.IoCount, RemoveLock->Common.Removed));
IoReleaseRemoveLockAndWait(RemoveLock, Tag);
ParDump2(PARREMLOCK, ("debug::ParReleaseRemoveLock: Count [%x] Removed[%x] - post IoReleaseRemoveLockAndWait\n",
RemoveLock->Common.IoCount, RemoveLock->Common.Removed));
}
VOID ParDumpDevObjStructList(
IN PPAR_DEVOBJ_STRUCT DevObjStructHead
)
{
PPAR_DEVOBJ_STRUCT current = DevObjStructHead;
if( DevObjStructHead ) {
ParDump2(PARPNP1, ("debug::ParDumpDevObjStructList - Enter\n") );
} else {
ParDump2(PARPNP1, ("debug::ParDumpDevObjStructList - Enter - Empty list - returning\n") );
return;
}
while( current ) {
ParDump2(PARPNP1, (" Controller = %x\n", current->Controller) );
ParDump2(PARPNP1, (" LegacyPodo = %x\n", current->LegacyPodo) );
ParDump2(PARPNP1, (" EndOfChainPdo = %x\n", current->EndOfChainPdo) );
ParDump2(PARPNP1, (" Dot3Id0Pdo = %x\n", current->Dot3Id0Pdo) );
ParDump2(PARPNP1, (" Dot3Id1Pdo = %x\n", current->Dot3Id1Pdo) );
ParDump2(PARPNP1, (" Dot3Id2Pdo = %x\n", current->Dot3Id2Pdo) );
ParDump2(PARPNP1, (" Dot3Id3Pdo = %x\n", current->Dot3Id3Pdo) );
ParDump2(PARPNP1, (" LegacyZipPdo = %x\n", current->LegacyZipPdo) );
current = current->Next;
}
return;
}
VOID
ParDumpDevExtTable()
{
ULONG i = 0;
while( gsotDEVICE_EXTENSION[i].pszField ) {
DbgPrint("%3x - %s\n", gsotDEVICE_EXTENSION[i].dwOffset, gsotDEVICE_EXTENSION[i].pszField);
++i;
}
DbgPrint("sizeof(DEVICE_EXTENSION) = %08x\n", gsotDEVICE_EXTENSION[i].dwOffset);
}