windows-nt/Source/XPSP1/NT/base/tools/kdexts2/portclsd.cpp

1699 lines
74 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*****************************************************************************
* portclsd.cpp - Portcls WinDbg/KD Debugger Extensions
*****************************************************************************
* Copyright (c) 1998 Microsoft Corporation
*/
#include "precomp.h"
#define PC_KDEXT
typedef enum _PCKD_PORTTYPE
{
Topology = 0,
WaveCyclic,
WavePci,
Midi,
UnknownPort
} PCKD_PORTTYPE;
#define MAPPED_QUEUE 0
#define LOCKED_QUEUE 1
#define PRELOCK_QUEUE 2
#define MAX_QUEUES 3
typedef union _PORTCLS_FLAGS
{
struct
{
ULONG PortDump : 1;
ULONG FilterDump : 1;
ULONG PinDump : 1;
ULONG DeviceContext : 1;
ULONG PowerInfo : 1;
ULONG Reserved1 : 3;
ULONG Verbose : 1;
ULONG ReallyVerbose : 1;
ULONG Reserved : 22;
};
ULONG Flags;
} PORTCLS_FLAGS;
typedef struct _PCKD_IRPSTREAM_ENTRY
{
LIST_ENTRY ListEntry;
PVOID Irp;
ULONG QueueType;
} PCKD_IRP_ENTRY;
typedef struct _PCKD_PIN_ENTRY
{
LIST_ENTRY ListEntry;
LIST_ENTRY IrpList;
PVOID PinData;
PVOID IrpStreamData;
ULONG PinInstanceId;
} PCKD_PIN_ENTRY;
typedef struct _PCKD_FILTER_ENTRY
{
LIST_ENTRY ListEntry;
LIST_ENTRY PinList;
PVOID FilterData;
ULONG FilterInstanceId;
} PCKD_FILTER_ENTRY;
typedef struct _PCKD_PORT
{
LIST_ENTRY FilterList;
PCKD_PORTTYPE PortType;
PVOID PortData;
} PCKD_PORT;
typedef struct {
ULONG64 Create;
ULONG64 Context;
UNICODE_STRING ObjectClass;
ULONG64 ObjectClassBuffer;
ULONG64 SecurityDescriptor;
ULONG Flags;
} KSOBJECT_CREATE_ITEM_READ, *PKSOBJECT_CREATE_ITEM_READ;
typedef struct _PCKD_SUBDEVICE_ENTRY
{
LIST_ENTRY ListEntry;
PCKD_PORT Port;
ULONG64 CreateItemAddr;
KSOBJECT_CREATE_ITEM_READ CreateItem;
} PCKD_SUBDEVICE_ENTRY;
#define TranslateDevicePower( x ) \
( x == PowerDeviceD0 ? "PowerDeviceD0" : \
x == PowerDeviceD1 ? "PowerDeviceD1" : \
x == PowerDeviceD2 ? "PowerDeviceD2" : \
x == PowerDeviceD3 ? "PowerDeviceD3" : "Unknown" )
#define TranslateSystemPower( x ) \
( x == PowerSystemWorking ? "PowerSystemWorking" : \
x == PowerSystemSleeping1 ? "PowerSystemSleeping1" : \
x == PowerSystemSleeping2 ? "PowerSystemSleeping2" : \
x == PowerSystemSleeping3 ? "PowerSystemSleeping3" : \
x == PowerSystemHibernate ? "PowerSystemHibernate" : \
x == PowerSystemShutdown ? "PowerSystemShutdown" : "Unknown" )
#define TranslateKsState( x ) \
( x == KSSTATE_STOP ? "KSSTATE_STOP" : \
x == KSSTATE_ACQUIRE ? "KSSTATE_ACQUIRE" : \
x == KSSTATE_PAUSE ? "KSSTATE_PAUSE" : \
x == KSSTATE_RUN ? "KSSTATE_RUN" : "Unknown" )
#define TranslateKsDataFlow( x ) \
( x == KSPIN_DATAFLOW_IN ? "KSPIN_DATAFLOW_IN" : \
x == KSPIN_DATAFLOW_OUT ? "KSPIN_DATAFLOW_OUT" : "Unknown" )
#define TranslateQueueType( x ) \
( x == PRELOCK_QUEUE ? "P" : \
x == LOCKED_QUEUE ? "L" : \
x == MAPPED_QUEUE ? "M" : "U" )
/**********************************************************************
* Forward References
**********************************************************************
*/
BOOL
PCKD_ValidateDevObj
(
PDEVICE_CONTEXT DeviceContext
);
VOID
PCKD_AcquireDeviceData
(
PDEVICE_CONTEXT DeviceContext,
PLIST_ENTRY SubdeviceList,
ULONG Flags
);
VOID
PCKD_DisplayDeviceData
(
PDEVICE_CONTEXT DeviceContext,
PLIST_ENTRY SubdeviceList,
ULONG Flags
);
VOID
PCKD_FreeDeviceData
(
PLIST_ENTRY SubdeviceList
);
VOID
PCKD_AcquireIrpStreamData
(
PVOID PinEntry,
CIrpStream *RemoteIrpStream,
CIrpStream *LocalIrpStream
);
/**********************************************************************
* DECLARE_API( portcls )
**********************************************************************
* Description:
* Dumps PortCls data given the device object (FDO) of a PortCls
* bound DevObj.
*
* Arguments:
* args - address flags
*
* Return Value:
* None
*/
extern "C"
DECLARE_API( portcls )
{
ULONG64 memLoc;
ULONG result;
CHAR buffer[256];
PORTCLS_FLAGS flags;
LIST_ENTRY SubdeviceList;
ULONG64 DeviceExtension;
buffer[0] = '\0';
flags.Flags = 0;
//
// get the arguments
//
if( !*args )
{
memLoc = EXPRLastDump;
} else
{
if (GetExpressionEx(args, &memLoc, &args)) {
strcpy(buffer, args);
}
}
flags.Flags = 0;
if ('\0' != buffer[0]) {
flags.Flags = GetExpression(buffer);
}
//
// print out info
//
dprintf("Dump Portcls DevObj Info %p %x \n", memLoc, flags.Flags );
//
// get the DevObj data
//
if( memLoc )
{
if( GetFieldValue( memLoc, "DEVICE_OBJECT", "DeviceExtension", DeviceExtension ) )
{
dprintf("Could not read DevObj data\n");
return E_INVALIDARG;
}
} else
{
dprintf("\nSYNTAX: !portcls <devobj> [flags]\n");
}
//
// check for device extension
//
if( !DeviceExtension )
{
dprintf("DevObj has no device extension\n");
return E_INVALIDARG;
}
//
// get the device context
//
if( InitTypeRead( DeviceExtension, "DEVICE_CONTEXT" ) )
{
dprintf("Could not read DevObj device extension\n");
return E_INVALIDARG;
}
//
// validate the DevObj
//
if( !PCKD_ValidateDevObj( DeviceExtension ) )
{
dprintf("DevObj not valid or not bound to PortCls\n");
return E_INVALIDARG;
}
//
// initialize the subdevice list
//
InitializeListHead( &SubdeviceList );
//
// acquire the device data
//
PCKD_AcquireDeviceData( DeviceExtension, &SubdeviceList, flags.Flags );
//
// display the requested info
//
PCKD_DisplayDeviceData( DeviceExtension, &SubdeviceList, flags.Flags );
//
// release the device data
//
PCKD_FreeDeviceData( &SubdeviceList );
return S_OK;
}
/**********************************************************************
* PCKD_ValidateDevObj
**********************************************************************
* Description:
* This routine attempts to validate whether or not a given device
* extension is from a PortCls bound DevObj.
*
* Arguments:
* PDEVICE_CONTEXT DeviceContext
* PORTCLS_FLAGS Flags
*
* Return Value:
* BOOL TRUE = Valid, FALSE = Invalid
*/
BOOL
PCKD_ValidateDevObj
(
ULONG64 DeviceContext
)
{
UNREFERENCED_PARAMETER( DeviceContext );
// TODO - Validate device extension
return TRUE;
}
/**********************************************************************
* PCKD_AcquireDeviceData
**********************************************************************
* Description:
* This routine acquires device data given a validated device
* context and builds a subdevice list contain all of the data.
*
* Arguments:
* PDEVICE_CONTEXT DeviceContext
* PLIST_ENTRY SubdeviceList
* PORTCLS_FLAGS Flags
*
* Return Value:
* None
*/
VOID
PCKD_AcquireDeviceData
(
ULONG64 DeviceContext,
PLIST_ENTRY SubdeviceList,
ULONG flags
)
{
ULONG SubdeviceIndex;
PCKD_SUBDEVICE_ENTRY *SubdeviceEntry;
ULONG64 CreateItems;
ULONG64 CurrentCreateItemAddr;
PKSOBJECT_CREATE_ITEM_READ ReadCreateItems;
PKSOBJECT_CREATE_ITEM_READ CurrentCreateItem;
PWSTR Buffer;
ULONG Size;
ULONG Result;
ANSI_STRING AnsiString;
PLIST_ENTRY ListEntry;
PORTCLS_FLAGS Flags;
ULONG ItemSz, MaxObjects;
ULONG i;
Flags.Flags = flags;
ItemSz = GetTypeSize("KSOBJECT_CREATE_ITEM");
InitTypeRead(DeviceContext, DEVICE_CONTEXT);
// allocate local memory for the create items table
Size = (MaxObjects = (ULONG) ReadField(MaxObjects)) * sizeof(KSOBJECT_CREATE_ITEM_READ);
ReadCreateItems = (PKSOBJECT_CREATE_ITEM_READ)LocalAlloc( LPTR, Size );
if( !ReadCreateItems )
{
dprintf("** Unable to allocate create item table memory\n");
return;
}
CreateItems = ReadField(CreateItems);
// copy the create items table to local memory
for (i=0, CurrentCreateItemAddr=CreateItems;
i<MaxObjects, CurrentCreateItemAddr+=IteSz;
i++) {
InitTypeRead(CurrentCreateItemAddr, KSOBJECT_CREATE_ITEM);
ReadCreateItems[i].Context = ReadField(Context);
ReadCreateItems[i].Create = ReadField(Create);
ReadCreateItems[i].Flags = ReadField(Flags);
ReadCreateItems[i].ObjectClassBuffer = ReadField(ObjectClass.Buffer);
ReadCreateItems[i].ObjectClass.MaximumLength = ReadField(ObjectClass.MaximumLength);
ReadCreateItems[i].ObjectClass.Length = ReadField(ObjectClass.Length);
ReadCreateItems[i].SecurityDescriptor = ReadField(SecurityDescriptor);
}
// check out each potential subdevice
for( SubdeviceIndex = 0, CurrentCreateItem = ReadCreateItems;
SubdeviceIndex < MaxObjects;
SubdeviceIndex++, CurrentCreateItem++ )
{
if( CurrentCreateItem->Create) )
{
// allocate a subdevice list entry
SubdeviceEntry = (PCKD_SUBDEVICE_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_SUBDEVICE_ENTRY) );
if( SubdeviceEntry )
{
// initialize the port filter list
InitializeListHead( &(SubdeviceEntry->Port.FilterList) );
// copy the create item data
memcpy( &(SubdeviceEntry->CreateItem), CurrentCreateItem, sizeof(KSOBJECT_CREATE_ITEM_READ) );
// allocate memory for the unicode string buffer
Buffer = (PWSTR)LocalAlloc( LPTR, CurrentCreateItem->ObjectClass.MaximumLength );
if( !Buffer )
{
dprintf("** Unable to allocate unicode string buffer\n");
LocalFree( SubdeviceEntry );
break;
}
// read unicode string data
if( !ReadMemory( CurrentCreateItem->ObjectClassBuffer,
Buffer,
CurrentCreateItem->ObjectClass.MaximumLength,
&Result ) )
{
dprintf("** Unable to read unicode string buffer (0x%p)\n",CurrentCreateItem->ObjectClassBuffer);
LocalFree( Buffer );
LocalFree( SubdeviceEntry );
break;
}
// point the create item string to the local buffer
// ?????
SubdeviceEntry->CreateItem.ObjectClass.Buffer = Buffer;
// determine port type by checking string
// TODO: this should be done by the GUID
//
// convert to ansi
RtlUnicodeStringToAnsiString( &AnsiString,
&(SubdeviceEntry->CreateItem.ObjectClass),
TRUE );
if( 0 == _stricmp( AnsiString.Buffer, "topology" ) )
{
SubdeviceEntry->Port.PortType = Topology;
SubdeviceEntry->Port.PortData = NULL;
} else if( 0 == _stricmp( AnsiString.Buffer, "wave" ) )
{
SubdeviceEntry->Port.PortType = WaveCyclic;
SubdeviceEntry->Port.PortData = NULL;
} else if( (0 == _stricmp( AnsiString.Buffer, "uart") ) ||
(0 == _stricmp( AnsiString.Buffer, "fmsynth") ) )
{
SubdeviceEntry->Port.PortType = Midi;
SubdeviceEntry->Port.PortData = NULL;
} else
{
SubdeviceEntry->Port.PortType = UnknownPort;
SubdeviceEntry->Port.PortData = NULL;
}
// free the ansi string
RtlFreeAnsiString( &AnsiString );
// add the subdevice entry to the subdevice list
InsertTailList( SubdeviceList, &(SubdeviceEntry->ListEntry) );
} else
{
dprintf("** Unable to allocate subdevice memory\n");
}
}
}
// free the create item table local storage
LocalFree( ReadCreateItems );
// acquire the port, filter, and pin data
if( (!IsListEmpty(SubdeviceList)) && (Flags.PortDump || Flags.FilterDump || Flags.PinDump) )
{
for( ListEntry = SubdeviceList->Flink; ListEntry != SubdeviceList; ListEntry = ListEntry->Flink )
{
SubdeviceEntry = (PCKD_SUBDEVICE_ENTRY *) ListEntry;
// read basic port data
PVOID Port;
ULONG PortSize;
switch( SubdeviceEntry->Port.PortType)
{
case Topology:
Port = LocalAlloc( LPTR, sizeof(CPortTopology) );
if( !Port )
{
dprintf("** Unable to allocate port memory\n");
break;
}
if( !ReadMemory( (ULONG)((CPortTopology *)((ISubdevice *)(SubdeviceEntry->CreateItem.Context))),
Port,
sizeof(CPortTopology),
&Result ) )
{
dprintf("** Unable to read port data\n");
LocalFree( Port );
Port = NULL;
break;
}
break;
case WaveCyclic:
Port = LocalAlloc( LPTR, sizeof(CPortWaveCyclic) );
if( !Port )
{
dprintf("** Unable to allocate port memory\n");
break;
}
if( !ReadMemory( (ULONG)((CPortWaveCyclic *)((ISubdevice *)(SubdeviceEntry->CreateItem.Context))),
Port,
sizeof(CPortWaveCyclic),
&Result ) )
{
dprintf("** Unable to read port data\n");
LocalFree( Port );
Port = NULL;
break;
}
break;
case WavePci:
Port = LocalAlloc( LPTR, sizeof(CPortWavePci) );
if( !Port )
{
dprintf("** Unable to allocate port memory\n");
break;
}
if( !ReadMemory( (ULONG)((CPortWavePci *)((ISubdevice *)(SubdeviceEntry->CreateItem.Context))),
Port,
sizeof(CPortWavePci),
&Result ) )
{
dprintf("** Unable to read port data\n");
LocalFree( Port );
Port = NULL;
break;
}
break;
case Midi:
Port = LocalAlloc( LPTR, sizeof(CPortMidi) );
if( !Port )
{
dprintf("** Unable to allocate port memory\n");
break;
}
if( !ReadMemory( (ULONG)((CPortMidi *)((ISubdevice *)(SubdeviceEntry->CreateItem.Context))),
Port,
sizeof(CPortMidi),
&Result ) )
{
dprintf("** Unable to read port data\n");
LocalFree( Port );
Port = NULL;
break;
}
break;
default:
break;
}
// attach the port data to the subdevice entry
SubdeviceEntry->Port.PortData = Port;
switch( SubdeviceEntry->Port.PortType )
{
case Topology:
break;
case WaveCyclic:
{
CPortWaveCyclic *PortWaveCyclic = (CPortWaveCyclic *)Port;
// get the filter and pin data
if( Flags.FilterDump || Flags.PinDump )
{
ULONG Offset;
ULONG PortBase;
PLIST_ENTRY Flink;
PLIST_ENTRY TempListEntry;
ULONG PinNumber = 0;
CPortPinWaveCyclic *PortPinWaveCyclic;
CIrpStream *IrpStream;
PCKD_PIN_ENTRY *CurrentPinEntry;
BOOL NeedNewFilter;
// get the offsets needed to walk the list
Offset = FIELD_OFFSET(CPortWaveCyclic,m_PinList);
PortBase = (ULONG)((CPortWaveCyclic *)((ISubdevice *)(SubdeviceEntry->CreateItem.Context)));
// get the first pin pointer
Flink = PortWaveCyclic->m_PinList.Flink;
while (Flink != PLIST_ENTRY(PortBase + Offset))
{
// allocate a pin list entry
CurrentPinEntry = (PCKD_PIN_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_PIN_ENTRY) );
if( !CurrentPinEntry )
{
dprintf("** Unable to allocate pin list entry\n");
break;
}
// initialize the pin entry
InitializeListHead( &(CurrentPinEntry->IrpList) );
CurrentPinEntry->PinData = NULL;
CurrentPinEntry->IrpStreamData = NULL;
CurrentPinEntry->PinInstanceId = PinNumber++;
// allocate local storage for the pin data
PortPinWaveCyclic = (CPortPinWaveCyclic *)LocalAlloc( LPTR, sizeof(CPortPinWaveCyclic) );
if( !PortPinWaveCyclic )
{
dprintf("** Unable to allocate pin data storage\n");
LocalFree( CurrentPinEntry );
break;
}
// read the pin data
if( !ReadMemory( (ULONG)CONTAINING_RECORD(Flink,
CPortPinWaveCyclic,
m_PinListEntry),
PortPinWaveCyclic,
sizeof(CPortPinWaveCyclic),
&Result ) )
{
dprintf("** Unable to read pin data\n");
LocalFree( PortPinWaveCyclic );
LocalFree( CurrentPinEntry );
break;
}
// is there an irp stream
if( PortPinWaveCyclic->m_IrpStream )
{
// allocate local storage for the irp stream data
IrpStream = (CIrpStream *)LocalAlloc( LPTR, sizeof(CIrpStream) );
if( IrpStream )
{
// read the irp stream data
if( !ReadMemory( (ULONG)((CIrpStream *)(PortPinWaveCyclic->m_IrpStream)),
IrpStream,
sizeof(CIrpStream),
&Result ) )
{
dprintf("** Unable to read irp stream data\n");
LocalFree( IrpStream );
} else
{
PCKD_AcquireIrpStreamData( CurrentPinEntry,
(CIrpStream *)(PortPinWaveCyclic->m_IrpStream),
IrpStream );
}
} else
{
dprintf("** Unable to allocate irp stream storage\n");
}
}
// we need a new filter unless we find it in the filter list
NeedNewFilter = TRUE;
// is the filter list empty?
if( !IsListEmpty( &(SubdeviceEntry->Port.FilterList) ) )
{
PLIST_ENTRY FilterListEntry;
for( FilterListEntry = SubdeviceEntry->Port.FilterList.Flink;
FilterListEntry != &(SubdeviceEntry->Port.FilterList);
FilterListEntry = FilterListEntry->Flink )
{
PCKD_FILTER_ENTRY *CurrentFilterEntry = (PCKD_FILTER_ENTRY *) FilterListEntry;
if( CurrentFilterEntry->FilterInstanceId == (ULONG)(PortPinWaveCyclic->m_Filter) )
{
// found our filter
NeedNewFilter = FALSE;
// add the pin data to the pin entry
CurrentPinEntry->PinData = (PVOID)PortPinWaveCyclic;
// add the pin entry to the filter's pin list
InsertTailList( &(CurrentFilterEntry->PinList),
&(CurrentPinEntry->ListEntry) );
}
}
}
// do we need a new filter entry?
if( NeedNewFilter )
{
PCKD_FILTER_ENTRY *CurrentFilterEntry;
// allocate a new filter entry
CurrentFilterEntry = (PCKD_FILTER_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_FILTER_ENTRY) );
if(!CurrentFilterEntry)
{
dprintf("** Unable to allocate filter entry\n");
LocalFree( PortPinWaveCyclic );
if( CurrentPinEntry->IrpStreamData )
{
LocalFree( CurrentPinEntry->IrpStreamData );
}
// free up any irps in the irp list
while(!IsListEmpty( &(CurrentPinEntry->IrpList)))
{
PCKD_IRP_ENTRY *IrpEntry = (PCKD_IRP_ENTRY *)RemoveTailList(&(CurrentPinEntry->IrpList));
LocalFree( IrpEntry );
}
LocalFree( CurrentPinEntry );
break;
}
//initialize the new filter entry
InitializeListHead( &(CurrentFilterEntry->PinList) );
CurrentFilterEntry->FilterData = NULL;
CurrentFilterEntry->FilterInstanceId = (ULONG)(PortPinWaveCyclic->m_Filter);
// add the pin data to the pin entry
CurrentPinEntry->PinData = (PVOID)PortPinWaveCyclic;
// add the pin entry to the filter's pin list
InsertTailList( &(CurrentFilterEntry->PinList),
&(CurrentPinEntry->ListEntry) );
/// add the filter entry to the port's filter list
InsertTailList( &(SubdeviceEntry->Port.FilterList),
&(CurrentFilterEntry->ListEntry) );
}
// allocate list entry storage
TempListEntry = (PLIST_ENTRY)LocalAlloc( LPTR, sizeof(LIST_ENTRY) );
if( TempListEntry )
{
// read in the next list entry
if( !ReadMemory( (ULONG)Flink,
TempListEntry,
sizeof(LIST_ENTRY),
&Result ) )
{
dprintf("** Unable to read temp list entry\n");
LocalFree(TempListEntry);
break;
}
// update FLINK
Flink = TempListEntry->Flink;
// free the temp list entry
LocalFree( TempListEntry );
} else
{
dprintf("** Unable to allocate temp list entry\n");
break;
}
}
}
}
break;
case WavePci:
{
CPortWavePci *PortWavePci = (CPortWavePci *)Port;
// get the filter and pin data
if( Flags.FilterDump || Flags.PinDump )
{
ULONG Offset;
ULONG PortBase;
PLIST_ENTRY Flink;
PLIST_ENTRY TempListEntry;
ULONG PinNumber = 0;
CPortPinWavePci *PortPinWavePci;
CIrpStream *IrpStream;
PCKD_PIN_ENTRY *CurrentPinEntry;
BOOL NeedNewFilter;
// get the offsets needed to walk the list
Offset = FIELD_OFFSET(CPortWavePci,m_PinList);
PortBase = (ULONG)((CPortWavePci *)((ISubdevice *)(SubdeviceEntry->CreateItem.Context)));
// get the first pin pointer
Flink = PortWavePci->m_PinList.Flink;
while (Flink != PLIST_ENTRY(PortBase + Offset))
{
// allocate a pin list entry
CurrentPinEntry = (PCKD_PIN_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_PIN_ENTRY) );
if( !CurrentPinEntry )
{
dprintf("** Unable to allocate pin list entry\n");
break;
}
// initialize the pin entry
InitializeListHead( &(CurrentPinEntry->IrpList) );
CurrentPinEntry->PinData = NULL;
CurrentPinEntry->IrpStreamData = NULL;
CurrentPinEntry->PinInstanceId = PinNumber++;
// allocate local storage for the pin data
PortPinWavePci = (CPortPinWavePci *)LocalAlloc( LPTR, sizeof(CPortPinWavePci) );
if( !PortPinWavePci )
{
dprintf("** Unable to allocate pin data storage\n");
LocalFree( CurrentPinEntry );
break;
}
// read the pin data
if( !ReadMemory( (ULONG)CONTAINING_RECORD(Flink,
CPortPinWavePci,
m_PinListEntry),
PortPinWavePci,
sizeof(CPortPinWavePci),
&Result ) )
{
dprintf("** Unable to read pin data\n");
LocalFree( PortPinWavePci );
LocalFree( CurrentPinEntry );
break;
}
// is there an irp stream
if( PortPinWavePci->m_IrpStream )
{
// allocate local storage for the irp stream data
IrpStream = (CIrpStream *)LocalAlloc( LPTR, sizeof(CIrpStream) );
if( IrpStream )
{
// read the irp stream data
if( !ReadMemory( (ULONG)((CIrpStream *)(PortPinWavePci->m_IrpStream)),
IrpStream,
sizeof(CIrpStream),
&Result ) )
{
dprintf("** Unable to read irp stream data\n");
LocalFree( IrpStream );
} else
{
PCKD_AcquireIrpStreamData( CurrentPinEntry,
(CIrpStream *)(PortPinWavePci->m_IrpStream),
IrpStream );
}
} else
{
dprintf("** Unable to allocate irp stream storage\n");
}
}
// we need a new filter unless we find it in the filter list
NeedNewFilter = TRUE;
// is the filter list empty?
if( !IsListEmpty( &(SubdeviceEntry->Port.FilterList) ) )
{
PLIST_ENTRY FilterListEntry;
for( FilterListEntry = SubdeviceEntry->Port.FilterList.Flink;
FilterListEntry != &(SubdeviceEntry->Port.FilterList);
FilterListEntry = FilterListEntry->Flink )
{
PCKD_FILTER_ENTRY *CurrentFilterEntry = (PCKD_FILTER_ENTRY *) FilterListEntry;
if( CurrentFilterEntry->FilterInstanceId == (ULONG)(PortPinWavePci->Filter) )
{
// found our filter
NeedNewFilter = FALSE;
// add the pin data to the pin entry
CurrentPinEntry->PinData = (PVOID)PortPinWavePci;
// add the pin entry to the filter's pin list
InsertTailList( &(CurrentFilterEntry->PinList),
&(CurrentPinEntry->ListEntry) );
}
}
}
// do we need a new filter entry?
if( NeedNewFilter )
{
PCKD_FILTER_ENTRY *CurrentFilterEntry;
// allocate a new filter entry
CurrentFilterEntry = (PCKD_FILTER_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_FILTER_ENTRY) );
if(!CurrentFilterEntry)
{
dprintf("** Unable to allocate filter entry\n");
LocalFree( PortPinWavePci );
if( CurrentPinEntry->IrpStreamData )
{
LocalFree( CurrentPinEntry->IrpStreamData );
}
// free up any irps in the irp list
while(!IsListEmpty( &(CurrentPinEntry->IrpList)))
{
PCKD_IRP_ENTRY *IrpEntry = (PCKD_IRP_ENTRY *)RemoveTailList(&(CurrentPinEntry->IrpList));
LocalFree( IrpEntry );
}
LocalFree( CurrentPinEntry );
break;
}
//initialize the new filter entry
InitializeListHead( &(CurrentFilterEntry->PinList) );
CurrentFilterEntry->FilterData = NULL;
CurrentFilterEntry->FilterInstanceId = (ULONG)(PortPinWavePci->Filter);
// add the pin data to the pin entry
CurrentPinEntry->PinData = (PVOID)PortPinWavePci;
// add the pin entry to the filter's pin list
InsertTailList( &(CurrentFilterEntry->PinList),
&(CurrentPinEntry->ListEntry) );
/// add the filter entry to the port's filter list
InsertTailList( &(SubdeviceEntry->Port.FilterList),
&(CurrentFilterEntry->ListEntry) );
}
// allocate list entry storage
TempListEntry = (PLIST_ENTRY)LocalAlloc( LPTR, sizeof(LIST_ENTRY) );
if( TempListEntry )
{
// read in the next list entry
if( !ReadMemory( (ULONG)Flink,
TempListEntry,
sizeof(LIST_ENTRY),
&Result ) )
{
dprintf("** Unable to read temp list entry\n");
LocalFree(TempListEntry);
break;
}
// update FLINK
Flink = TempListEntry->Flink;
// free the temp list entry
LocalFree( TempListEntry );
} else
{
dprintf("** Unable to allocate temp list entry\n");
break;
}
}
}
}
break;
case Midi:
{
CPortMidi *PortMidi = (CPortMidi *)Port;
// get the filter and pin data
if( Flags.FilterDump || Flags.PinDump )
{
ULONG PinIndex;
CPortPinMidi *PortPinMidi;
CIrpStream *IrpStream;
PCKD_PIN_ENTRY *CurrentPinEntry;
BOOL NeedNewFilter;
for( PinIndex = 0; PinIndex < PortMidi->m_PinEntriesUsed; PinIndex++ )
{
if( PortMidi->m_Pins[ PinIndex] )
{
// allocate a pin list entry
CurrentPinEntry = (PCKD_PIN_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_PIN_ENTRY) );
if( !CurrentPinEntry )
{
dprintf("** Unable to allocate pin list entry\n");
break;
}
// initialize the pin entry
InitializeListHead( &(CurrentPinEntry->IrpList) );
CurrentPinEntry->PinData = NULL;
CurrentPinEntry->PinInstanceId = (ULONG)(PortMidi->m_Pins[ PinIndex ]);
// allocate local storage for the pin data
PortPinMidi = (CPortPinMidi *)LocalAlloc( LPTR, sizeof(CPortPinMidi) );
if( !PortPinMidi )
{
dprintf("** Unable to allocate pin data storage\n");
LocalFree( CurrentPinEntry );
break;
}
// read the pin data
if( !ReadMemory( (ULONG)(PortMidi->m_Pins[ PinIndex ]),
PortPinMidi,
sizeof(CPortPinMidi),
&Result ) )
{
dprintf("** Unable to read pin data\n");
LocalFree( PortPinMidi );
LocalFree( CurrentPinEntry );
break;
}
// is there an irp stream
if( PortPinMidi->m_IrpStream )
{
// allocate local storage for the irp stream data
IrpStream = (CIrpStream *)LocalAlloc( LPTR, sizeof(CIrpStream) );
if( IrpStream )
{
// read the irp stream data
if( !ReadMemory( (ULONG)(PortPinMidi->m_IrpStream),
IrpStream,
sizeof(CIrpStream),
&Result ) )
{
dprintf("** Unable to read irp stream data\n");
LocalFree( IrpStream );
} else
{
PCKD_AcquireIrpStreamData( CurrentPinEntry,
(CIrpStream *)(PortPinMidi->m_IrpStream),
IrpStream );
}
} else
{
dprintf("** Unable to allocate irp stream storage\n");
}
}
// we need a new filter unless we find it in the filter list
NeedNewFilter = TRUE;
// is the filter list empty?
if( !IsListEmpty( &(SubdeviceEntry->Port.FilterList) ) )
{
PLIST_ENTRY FilterListEntry;
for( FilterListEntry = SubdeviceEntry->Port.FilterList.Flink;
FilterListEntry != &(SubdeviceEntry->Port.FilterList);
FilterListEntry = FilterListEntry->Flink )
{
PCKD_FILTER_ENTRY *CurrentFilterEntry = (PCKD_FILTER_ENTRY *) FilterListEntry;
if( CurrentFilterEntry->FilterInstanceId == (ULONG)(PortPinMidi->m_Filter) )
{
// found our filter
NeedNewFilter = FALSE;
// add the pin data to the pin entry
CurrentPinEntry->PinData = (PVOID)PortPinMidi;
// add the pin entry to the filter's pin list
InsertTailList( &(CurrentFilterEntry->PinList),
&(CurrentPinEntry->ListEntry) );
}
}
}
// do we need a new filter entry?
if( NeedNewFilter )
{
PCKD_FILTER_ENTRY *CurrentFilterEntry;
// allocate a new filter entry
CurrentFilterEntry = (PCKD_FILTER_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_FILTER_ENTRY) );
if(!CurrentFilterEntry)
{
dprintf("** Unable to allocate filter entry\n");
LocalFree( PortPinMidi );
if( CurrentPinEntry->IrpStreamData )
{
LocalFree( CurrentPinEntry->IrpStreamData );
}
// free up any irps in the irp list
while(!IsListEmpty( &(CurrentPinEntry->IrpList)))
{
PCKD_IRP_ENTRY *IrpEntry = (PCKD_IRP_ENTRY *)RemoveTailList(&(CurrentPinEntry->IrpList));
LocalFree( IrpEntry );
}
LocalFree( CurrentPinEntry );
break;
}
//initialize the new filter entry
InitializeListHead( &(CurrentFilterEntry->PinList) );
CurrentFilterEntry->FilterData = NULL;
CurrentFilterEntry->FilterInstanceId = (ULONG)(PortPinMidi->m_Filter);
// add the pin data to the pin entry
CurrentPinEntry->PinData = (PVOID)PortPinMidi;
// add the pin entry to the filter's pin list
InsertTailList( &(CurrentFilterEntry->PinList),
&(CurrentPinEntry->ListEntry) );
/// add the filter entry to the port's filter list
InsertTailList( &(SubdeviceEntry->Port.FilterList),
&(CurrentFilterEntry->ListEntry) );
}
}
}
}
}
break;
default:
break;
}
}
}
}
/**********************************************************************
* PCKD_DisplayDeviceData
**********************************************************************
* Description:
* This routine displays the requested device data on the debugger
* given a valid device context and a subdevice list built with
* PCKD_AcquireDeviceData.
* Arguments:
* PDEVICE_CONTEXT DeviceContext
* PLIST_ENTRY SubdeviceList
* PORTCLS_FLAGS Flags
*
* Return Value:
* None
*/
VOID
PCKD_DisplayDeviceData
(
PDEVICE_CONTEXT DeviceContext,
PLIST_ENTRY SubdeviceList,
ULONG flags
)
{
PLIST_ENTRY SubdeviceListEntry;
PCKD_SUBDEVICE_ENTRY *SubdeviceEntry;
ANSI_STRING AnsiNameString;
PORTCLS_FLAGS Flags;
Flags.Flags = flags;
dprintf("\n");
// dump misc device context information
if( Flags.DeviceContext )
{
dprintf("\n DEVICE INFO:\n");
dprintf(" PDO: 0x%x\n",DeviceContext->PhysicalDeviceObject);
if( Flags.Verbose )
{
if( Flags.ReallyVerbose )
{
dprintf(" Max Objects: 0x%x\n",DeviceContext->MaxObjects);
}
dprintf(" Existing Objects: 0x%x\n",DeviceContext->ExistingObjectCount);
dprintf(" Active Pin Count: 0x%x\n",DeviceContext->ActivePinCount);
dprintf(" Pending IRP Count: 0x%x\n",DeviceContext->PendingIrpCount);
}
}
// dump power management information
if( Flags.PowerInfo )
{
dprintf("\n POWER INFO:\n");
dprintf(" DeviceState: %s\n", TranslateDevicePower( DeviceContext->CurrentDeviceState ) );
dprintf(" SystemState: %s\n", TranslateSystemPower( DeviceContext->CurrentSystemState ) );
dprintf(" AdapterPower: 0x%x\n", DeviceContext->pAdapterPower );
if( Flags.Verbose && Flags.ReallyVerbose )
{
ULONG index;
dprintf(" Idle Timer: 0x%x\n", DeviceContext->IdleTimer );
dprintf(" Cons Idle Time: 0x%x\n", DeviceContext->ConservationIdleTime );
dprintf(" Perf Idle Time: 0x%x\n", DeviceContext->PerformanceIdleTime );
dprintf(" Idle Device State: %s\n", TranslateDevicePower( DeviceContext->IdleDeviceState ) );
dprintf(" State Mappings:\n");
for( index = 0; index < (ULONG)PowerSystemMaximum; index++ )
{
dprintf(" %20s ==> %14s\n", TranslateSystemPower( index ),
TranslateDevicePower( DeviceContext->DeviceStateMap[ index ] ) );
}
}
}
// dump port/filter/pin information
if( Flags.PortDump || Flags.FilterDump || Flags.PinDump )
{
if( !IsListEmpty( SubdeviceList ) )
{
// go through the subdevice list
for( SubdeviceListEntry = SubdeviceList->Flink;
SubdeviceListEntry != SubdeviceList;
SubdeviceListEntry = SubdeviceListEntry->Flink )
{
SubdeviceEntry = (PCKD_SUBDEVICE_ENTRY *)SubdeviceListEntry;
switch( SubdeviceEntry->Port.PortType )
{
case Topology:
// dump port name
dprintf("\n TOPOLOGY PORT:\n");
break;
case WaveCyclic:
// dump port name
dprintf("\n WAVECYCLIC PORT:\n");
break;
case WavePci:
// dump port name
dprintf("\n WAVEPCI PORT:\n");
break;
case Midi:
// dump port name
dprintf("\n MIDI PORT:\n");
break;
default:
// dump port name
dprintf("\n UNKNOWN PORT:\n");
break;
}
// print out the real name
RtlUnicodeStringToAnsiString( &AnsiNameString,
&(SubdeviceEntry->CreateItem.ObjectClass),
TRUE );
dprintf(" Name: %s\n",AnsiNameString.Buffer);
RtlFreeAnsiString( &AnsiNameString );
// dump the port instance
dprintf(" Port Instance: 0x%x\n",SubdeviceEntry->CreateItem.Context);
if( Flags.Verbose && Flags.ReallyVerbose )
{
// dump generic port data
dprintf(" Create: 0x%x\n",SubdeviceEntry->CreateItem.Create);
dprintf(" Security: 0x%x\n",SubdeviceEntry->CreateItem.SecurityDescriptor);
dprintf(" Flags: 0x%x\n",SubdeviceEntry->CreateItem.Flags);
}
// dump port type specific port data
switch( SubdeviceEntry->Port.PortType )
{
case Topology:
{
CPortTopology *port = (CPortTopology *)(SubdeviceEntry->Port.PortData);
dprintf(" Miniport: 0x%x\n",port->Miniport);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Subdevice Desc: 0x%x\n",port->m_pSubdeviceDescriptor);
dprintf(" Filter Desc: 0x%x\n",port->m_pPcFilterDescriptor);
}
}
break;
case WaveCyclic:
{
CPortWaveCyclic *port = (CPortWaveCyclic *)(SubdeviceEntry->Port.PortData);
dprintf(" Miniport: 0x%x\n",port->Miniport);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Subdevice Desc: 0x%x\n",port->m_pSubdeviceDescriptor);
dprintf(" Filter Desc: 0x%x\n",port->m_pPcFilterDescriptor);
}
}
break;
case WavePci:
{
CPortWavePci *port = (CPortWavePci *)(SubdeviceEntry->Port.PortData);
dprintf(" Miniport: 0x%x\n",port->Miniport);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Subdevice Desc: 0x%x\n",port->m_pSubdeviceDescriptor);
dprintf(" Filter Desc: 0x%x\n",port->m_pPcFilterDescriptor);
}
}
break;
case Midi:
{
CPortMidi *port = (CPortMidi *)(SubdeviceEntry->Port.PortData);
dprintf(" Miniport: 0x%x\n",port->m_Miniport);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Subdevice Desc: 0x%x\n",port->m_pSubdeviceDescriptor);
dprintf(" Filter Desc: 0x%x\n",port->m_pPcFilterDescriptor);
}
dprintf(" Pin Count: 0x%x\n",port->m_PinEntriesUsed);
}
break;
default:
break;
}
if( Flags.FilterDump || Flags.PinDump )
{
// dump the filters
if( !IsListEmpty( &(SubdeviceEntry->Port.FilterList) ) )
{
PLIST_ENTRY FilterListEntry;
PCKD_FILTER_ENTRY *FilterEntry;
// run through the filter list
for( FilterListEntry = SubdeviceEntry->Port.FilterList.Flink;
FilterListEntry != &(SubdeviceEntry->Port.FilterList);
FilterListEntry = FilterListEntry->Flink )
{
FilterEntry = (PCKD_FILTER_ENTRY *)FilterListEntry;
dprintf(" Filter Instance: 0x%x\n",FilterEntry->FilterInstanceId);
if( Flags.PinDump )
{
// dump the pins
if( !IsListEmpty( &(FilterEntry->PinList) ) )
{
PLIST_ENTRY PinListEntry;
PCKD_PIN_ENTRY *PinEntry;
// run through the pin list
for( PinListEntry = FilterEntry->PinList.Flink;
PinListEntry != &(FilterEntry->PinList);
PinListEntry = PinListEntry->Flink )
{
PinEntry = (PCKD_PIN_ENTRY *)PinListEntry;
dprintf(" Pin Instance: 0x%x\n",PinEntry->PinInstanceId);
// dump the pin data
switch( SubdeviceEntry->Port.PortType )
{
case WaveCyclic:
{
CPortPinWaveCyclic *pin = (CPortPinWaveCyclic *)(PinEntry->PinData);
if( pin )
{
dprintf(" Miniport Stream: 0x%x\n",pin->m_Stream);
dprintf(" Stream State: %s\n", TranslateKsState(pin->m_DeviceState));
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Pin ID: 0x%x\n",pin->m_Id);
dprintf(" Commanded State: %s\n", TranslateKsState(pin->m_CommandedState));
dprintf(" Suspended: %s\n", pin->m_Suspended ? "TRUE" : "FALSE");
}
dprintf(" Dataflow: %s\n",TranslateKsDataFlow( pin->m_DataFlow ) );
dprintf(" Data Format: 0x%x\n",pin->m_DataFormat);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Pin Desc: 0x%x\n",pin->m_Descriptor);
}
if( Flags.Verbose )
{
dprintf(" Service Group: 0x%x\n",pin->m_ServiceGroup);
dprintf(" Dma Channel: 0x%x\n",pin->m_DmaChannel);
dprintf(" Irp Stream: 0x%x\n",pin->m_IrpStream);
if( !IsListEmpty( &(PinEntry->IrpList) ) )
{
PLIST_ENTRY IrpListEntry;
PCKD_IRP_ENTRY *IrpEntry;
// run through the irp list
for( IrpListEntry = PinEntry->IrpList.Flink;
IrpListEntry != &(PinEntry->IrpList);
IrpListEntry = IrpListEntry->Flink )
{
IrpEntry = (PCKD_IRP_ENTRY *)IrpListEntry;
dprintf(" Irp: 0x%x (%s)\n",IrpEntry->Irp,
TranslateQueueType(IrpEntry->QueueType));
}
}
}
}
}
break;
case WavePci:
{
CPortPinWavePci *pin = (CPortPinWavePci *)(PinEntry->PinData);
if( pin )
{
dprintf(" Miniport Stream: 0x%x\n",pin->Stream);
dprintf(" Stream State: %s\n", TranslateKsState(pin->m_DeviceState));
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Pin ID: 0x%x\n",pin->Id);
dprintf(" Commanded State: %s\n", TranslateKsState(pin->CommandedState));
dprintf(" Suspended: %s\n", pin->m_Suspended ? "TRUE" : "FALSE");
}
//dprintf(" Dataflow: %s\n",TranslateKsDataFlow( pin->DataFlow ) );
dprintf(" Data Format: 0x%x\n",pin->DataFormat);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Pin Desc: 0x%x\n",pin->Descriptor);
}
if( Flags.Verbose )
{
dprintf(" Service Group: 0x%x\n",pin->ServiceGroup);
dprintf(" Dma Channel: 0x%x\n",pin->DmaChannel);
dprintf(" Irp Stream: 0x%x\n",pin->m_IrpStream);
}
}
}
break;
case Midi:
{
CPortPinMidi *pin = (CPortPinMidi *)(PinEntry->PinData);
if( pin )
{
dprintf(" Miniport Stream: 0x%x\n",pin->m_Stream);
dprintf(" Stream State: %s\n", TranslateKsState(pin->m_DeviceState));
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Pin ID: 0x%x\n",pin->m_Id);
dprintf(" Commanded State: %s\n", TranslateKsState(pin->m_CommandedState));
dprintf(" Suspended: %s\n", pin->m_Suspended ? "TRUE" : "FALSE");
}
dprintf(" Dataflow: %s\n",TranslateKsDataFlow( pin->m_DataFlow ) );
dprintf(" Data Format: 0x%x\n",pin->m_DataFormat);
if( Flags.Verbose && Flags.ReallyVerbose )
{
dprintf(" Pin Desc: 0x%x\n",pin->m_Descriptor);
}
if( Flags.Verbose )
{
dprintf(" Service Group: 0x%x\n",pin->m_ServiceGroup);
dprintf(" Irp Stream: 0x%x\n",pin->m_IrpStream);
}
}
}
break;
default:
break;
}
}
} else
{
dprintf(" No Pin Instances:\n");
}
}
}
}
}
}
}
}
return;
}
/**********************************************************************
* PCKD_FreeDeviceData
**********************************************************************
* Description:
* This routine cleans up and frees the subdevice list.
* Arguments:
* PLIST_ENTRY SubdeviceList
*
* Return Value:
* None
*/
VOID
PCKD_FreeDeviceData
(
PLIST_ENTRY SubdeviceList
)
{
PLIST_ENTRY SubdeviceListEntry;
PLIST_ENTRY FilterListEntry;
PLIST_ENTRY PinListEntry;
PCKD_SUBDEVICE_ENTRY *SubdeviceEntry;
PCKD_FILTER_ENTRY *FilterEntry;
PCKD_PIN_ENTRY *PinEntry;
if( !IsListEmpty( SubdeviceList ) )
{
SubdeviceListEntry = RemoveHeadList( SubdeviceList );
while( SubdeviceListEntry )
{
SubdeviceEntry = (PCKD_SUBDEVICE_ENTRY *) SubdeviceListEntry;
// see if we have filters in the filter list
if( !IsListEmpty( &(SubdeviceEntry->Port.FilterList) ) )
{
FilterListEntry = RemoveHeadList( &(SubdeviceEntry->Port.FilterList) );
while( FilterListEntry )
{
FilterEntry = (PCKD_FILTER_ENTRY *)FilterListEntry;
// see if we have pins in the pin list
if( !IsListEmpty( &(FilterEntry->PinList) ) )
{
PinListEntry = RemoveHeadList( &(FilterEntry->PinList) );
while( PinListEntry )
{
PinEntry = (PCKD_PIN_ENTRY *)PinListEntry;
// free the pin data
if( PinEntry->PinData )
{
LocalFree( PinEntry->PinData );
}
// free the irp stream data
if( PinEntry->IrpStreamData )
{
LocalFree( PinEntry->IrpStreamData );
}
// free up any irps in the irp list
while( !IsListEmpty( &(PinEntry->IrpList) ) )
{
PCKD_IRP_ENTRY *IrpEntry = (PCKD_IRP_ENTRY *)RemoveTailList(&(PinEntry->IrpList));
LocalFree( IrpEntry );
}
// free the pin entry
LocalFree( PinEntry );
// get the next pin
if( !IsListEmpty( &(FilterEntry->PinList) ) )
{
PinListEntry = RemoveTailList( &(FilterEntry->PinList) );
} else
{
PinListEntry = NULL;
}
}
}
// free the filter data
if( FilterEntry->FilterData )
{
LocalFree( FilterEntry->FilterData );
}
// free the filter entry
LocalFree( FilterEntry );
// get the next filter
if( !IsListEmpty( &(SubdeviceEntry->Port.FilterList) ) )
{
FilterListEntry = RemoveTailList( &(SubdeviceEntry->Port.FilterList) );
} else
{
FilterListEntry = NULL;
}
}
}
// free the port data
if( SubdeviceEntry->Port.PortData )
{
LocalFree( SubdeviceEntry->Port.PortData );
}
// free the unicode string buffer
LocalFree( SubdeviceEntry->CreateItem.ObjectClass.Buffer );
// free the subdevice entry
LocalFree( SubdeviceEntry );
// on to the next subdevice
if( !IsListEmpty( SubdeviceList ) )
{
SubdeviceListEntry = RemoveTailList( SubdeviceList );
} else
{
SubdeviceListEntry = NULL;
}
}
}
return;
}
/**********************************************************************
* PCKD_AcquireIrpStreamData
**********************************************************************
* Description:
* This routine acquires irp stream irp queue data.
* Arguments:
* PCKD_PIN_ENTRY *CurrentPinEntry
* CIrpStream *RemoteIrpStream,
* CIrpStream *LocalIrpStream
*
* Return Value:
* None
*/
VOID
PCKD_AcquireIrpStreamData
(
PVOID PinEntry,
CIrpStream *RemoteIrpStream,
CIrpStream *LocalIrpStream
)
{
ULONG QueueType;
PLIST_ENTRY Flink;
PLIST_ENTRY TempListEntry;
PIRP pIrp;
PCKD_IRP_ENTRY *IrpEntry;
ULONG Offset;
ULONG Result;
PCKD_PIN_ENTRY *CurrentPinEntry;
CurrentPinEntry = (PCKD_PIN_ENTRY *)PinEntry;
// processs the queues
for( QueueType = MAPPED_QUEUE; QueueType < MAX_QUEUES; QueueType++ )
{
switch( QueueType )
{
case PRELOCK_QUEUE:
Offset = FIELD_OFFSET(CIrpStream,PreLockQueue);
Flink = LocalIrpStream->PreLockQueue.Flink;
break;
case LOCKED_QUEUE:
Offset = FIELD_OFFSET(CIrpStream,LockedQueue);
Flink = LocalIrpStream->LockedQueue.Flink;
break;
case MAPPED_QUEUE:
Offset = FIELD_OFFSET(CIrpStream,MappedQueue);
Flink = LocalIrpStream->MappedQueue.Flink;
break;
default:
Flink = 0;
break;
}
// walk the list (note we can't use IsListEmpty)
while( (Flink) && (Flink != (PLIST_ENTRY)((PBYTE)RemoteIrpStream + Offset)))
{
// get the irp pointer
pIrp = CONTAINING_RECORD( Flink, IRP, Tail.Overlay.ListEntry );
// allocate an irp entry
IrpEntry = (PCKD_IRP_ENTRY *)LocalAlloc( LPTR, sizeof(PCKD_IRP_ENTRY) );
if( IrpEntry )
{
// initialize the irp entry
IrpEntry->QueueType = QueueType;
IrpEntry->Irp = pIrp;
// add the irp entry to the pin entry
InsertTailList( &(CurrentPinEntry->IrpList),
&(IrpEntry->ListEntry) );
} else
{
dprintf("** Unable to allocate irp entry\n");
}
// allocate list entry storage
TempListEntry = (PLIST_ENTRY)LocalAlloc( LPTR, sizeof(LIST_ENTRY) );
if( TempListEntry )
{
// read in the next list entry
if( !ReadMemory( (ULONG)Flink,
TempListEntry,
sizeof(LIST_ENTRY),
&Result ) )
{
dprintf("** Unable to read temp list entry\n");
LocalFree(TempListEntry);
break;
}
// update FLINK
Flink = TempListEntry->Flink;
// free the temp list entry
LocalFree( TempListEntry );
} else
{
dprintf("** Unable to allocate temp list entry\n");
break;
}
}
}
}