Leaked source code of windows server 2003
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

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