You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
5.8 KiB
281 lines
5.8 KiB
/*++
|
|
|
|
Copyright (c) 1998-2000 Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
shmisc.cpp
|
|
|
|
Abstract:
|
|
|
|
This module contains miscellaneous functions for the kernel streaming
|
|
filter shell.
|
|
|
|
Author:
|
|
|
|
Dale Sather (DaleSat) 31-Jul-1998
|
|
|
|
--*/
|
|
|
|
#include "private.h"
|
|
#include "ksshellp.h"
|
|
#include <kcom.h>
|
|
|
|
#pragma code_seg("PAGE")
|
|
|
|
|
|
void
|
|
KsWorkSinkItemWorker(
|
|
IN PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine calls a worker function on a work sink interface.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
_DbgPrintF(DEBUGLVL_BLAB,("KsWorkSinkItemWorker"));
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT(Context);
|
|
|
|
PIKSWORKSINK(Context)->Work();
|
|
}
|
|
|
|
|
|
void
|
|
KspShellStandardConnect(
|
|
IN PIKSSHELLTRANSPORT NewTransport OPTIONAL,
|
|
OUT PIKSSHELLTRANSPORT *OldTransport OPTIONAL,
|
|
IN KSPIN_DATAFLOW DataFlow,
|
|
IN PIKSSHELLTRANSPORT ThisTransport,
|
|
IN PIKSSHELLTRANSPORT* SourceTransport,
|
|
IN PIKSSHELLTRANSPORT* SinkTransport
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine establishes a transport connection.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
_DbgPrintF(DEBUGLVL_BLAB,("KspShellStandardConnect"));
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT(ThisTransport);
|
|
ASSERT(SourceTransport);
|
|
ASSERT(SinkTransport);
|
|
|
|
//
|
|
// Make sure this object sticks around until we are done.
|
|
//
|
|
ThisTransport->AddRef();
|
|
|
|
PIKSSHELLTRANSPORT* transport =
|
|
(DataFlow & KSPIN_DATAFLOW_IN) ?
|
|
SourceTransport :
|
|
SinkTransport;
|
|
|
|
//
|
|
// Release the current source/sink.
|
|
//
|
|
if (*transport) {
|
|
//
|
|
// First disconnect the old back link. If we are connecting a back
|
|
// link for a new connection, we need to do this too. If we are
|
|
// clearing a back link (disconnecting), this request came from the
|
|
// component we're connected to, so we don't bounce back again.
|
|
//
|
|
switch (DataFlow) {
|
|
case KSPIN_DATAFLOW_IN:
|
|
(*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_OUT);
|
|
break;
|
|
|
|
case KSPIN_DATAFLOW_OUT:
|
|
(*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_IN);
|
|
break;
|
|
|
|
case KSPSHELL_BACKCONNECT_IN:
|
|
if (NewTransport) {
|
|
(*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_OUT);
|
|
}
|
|
break;
|
|
|
|
case KSPSHELL_BACKCONNECT_OUT:
|
|
if (NewTransport) {
|
|
(*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_IN);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Now release the old neighbor or hand it off to the caller.
|
|
//
|
|
if (OldTransport) {
|
|
*OldTransport = *transport;
|
|
} else {
|
|
(*transport)->Release();
|
|
}
|
|
} else if (OldTransport) {
|
|
*OldTransport = NULL;
|
|
}
|
|
|
|
//
|
|
// Copy the new source/sink.
|
|
//
|
|
*transport = NewTransport;
|
|
|
|
if (NewTransport) {
|
|
//
|
|
// Add a reference if necessary.
|
|
//
|
|
NewTransport->AddRef();
|
|
|
|
//
|
|
// Do the back connect if necessary.
|
|
//
|
|
switch (DataFlow) {
|
|
case KSPIN_DATAFLOW_IN:
|
|
NewTransport->Connect(ThisTransport,NULL,KSPSHELL_BACKCONNECT_OUT);
|
|
break;
|
|
|
|
case KSPIN_DATAFLOW_OUT:
|
|
NewTransport->Connect(ThisTransport,NULL,KSPSHELL_BACKCONNECT_IN);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now this object may die if it has no references.
|
|
//
|
|
ThisTransport->Release();
|
|
}
|
|
|
|
#pragma code_seg()
|
|
|
|
|
|
NTSTATUS
|
|
KspShellTransferKsIrp(
|
|
IN PIKSSHELLTRANSPORT NewTransport,
|
|
IN PIRP Irp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine transfers a streaming IRP using the kernel streaming shell
|
|
transport.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
_DbgPrintF(DEBUGLVL_BLAB,("KspShellTransferKsIrp"));
|
|
|
|
ASSERT(NewTransport);
|
|
ASSERT(Irp);
|
|
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
|
while (NewTransport) {
|
|
PIKSSHELLTRANSPORT nextTransport;
|
|
status = NewTransport->TransferKsIrp(Irp,&nextTransport);
|
|
|
|
ASSERT(NT_SUCCESS(status) || ! nextTransport);
|
|
|
|
NewTransport = nextTransport;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
#pragma code_seg("PAGE")
|
|
|
|
#if DBG
|
|
|
|
void
|
|
DbgPrintCircuit(
|
|
IN PIKSSHELLTRANSPORT Transport
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine spews a transport circuit.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
_DbgPrintF(DEBUGLVL_BLAB,("DbgPrintCircuit"));
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT(Transport);
|
|
|
|
#define MAX_NAME_SIZE 64
|
|
|
|
PIKSSHELLTRANSPORT transport = Transport;
|
|
while (transport) {
|
|
CHAR name[MAX_NAME_SIZE + 1];
|
|
PIKSSHELLTRANSPORT next;
|
|
PIKSSHELLTRANSPORT prev;
|
|
|
|
transport->DbgRollCall(MAX_NAME_SIZE,name,&next,&prev);
|
|
DbgPrint(" %s",name);
|
|
|
|
if (prev) {
|
|
PIKSSHELLTRANSPORT next2;
|
|
PIKSSHELLTRANSPORT prev2;
|
|
prev->DbgRollCall(MAX_NAME_SIZE,name,&next2,&prev2);
|
|
if (next2 != transport) {
|
|
DbgPrint(" SOURCE'S(0x%08x) SINK(0x%08x) != THIS(%08x)",prev,next2,transport);
|
|
}
|
|
} else {
|
|
DbgPrint(" NO SOURCE");
|
|
}
|
|
|
|
if (next) {
|
|
PIKSSHELLTRANSPORT next2;
|
|
PIKSSHELLTRANSPORT prev2;
|
|
next->DbgRollCall(MAX_NAME_SIZE,name,&next2,&prev2);
|
|
if (prev2 != transport) {
|
|
DbgPrint(" SINK'S(0x%08x) SOURCE(0x%08x) != THIS(%08x)",next,prev2,transport);
|
|
}
|
|
} else {
|
|
DbgPrint(" NO SINK");
|
|
}
|
|
|
|
DbgPrint("\n");
|
|
|
|
transport = next;
|
|
if (transport == Transport) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|