/*++ 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 #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