//+------------------------------------------------------------------------- // // 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""; //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(¶mTable[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, ¶mTable[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, ¤tExt->ClassName, ¤tExt->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); }