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

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. shmisc.cpp
  5. Abstract:
  6. This module contains miscellaneous functions for the kernel streaming
  7. filter shell.
  8. Author:
  9. Dale Sather (DaleSat) 31-Jul-1998
  10. --*/
  11. #include "private.h"
  12. #include "ksshellp.h"
  13. #include <kcom.h>
  14. #pragma code_seg("PAGE")
  15. void
  16. KsWorkSinkItemWorker(
  17. IN PVOID Context
  18. )
  19. /*++
  20. Routine Description:
  21. This routine calls a worker function on a work sink interface.
  22. Arguments:
  23. Return Value:
  24. --*/
  25. {
  26. _DbgPrintF(DEBUGLVL_BLAB,("KsWorkSinkItemWorker"));
  27. PAGED_CODE();
  28. ASSERT(Context);
  29. PIKSWORKSINK(Context)->Work();
  30. }
  31. void
  32. KspShellStandardConnect(
  33. IN PIKSSHELLTRANSPORT NewTransport OPTIONAL,
  34. OUT PIKSSHELLTRANSPORT *OldTransport OPTIONAL,
  35. IN KSPIN_DATAFLOW DataFlow,
  36. IN PIKSSHELLTRANSPORT ThisTransport,
  37. IN PIKSSHELLTRANSPORT* SourceTransport,
  38. IN PIKSSHELLTRANSPORT* SinkTransport
  39. )
  40. /*++
  41. Routine Description:
  42. This routine establishes a transport connection.
  43. Arguments:
  44. Return Value:
  45. --*/
  46. {
  47. _DbgPrintF(DEBUGLVL_BLAB,("KspShellStandardConnect"));
  48. PAGED_CODE();
  49. ASSERT(ThisTransport);
  50. ASSERT(SourceTransport);
  51. ASSERT(SinkTransport);
  52. //
  53. // Make sure this object sticks around until we are done.
  54. //
  55. ThisTransport->AddRef();
  56. PIKSSHELLTRANSPORT* transport =
  57. (DataFlow & KSPIN_DATAFLOW_IN) ?
  58. SourceTransport :
  59. SinkTransport;
  60. //
  61. // Release the current source/sink.
  62. //
  63. if (*transport) {
  64. //
  65. // First disconnect the old back link. If we are connecting a back
  66. // link for a new connection, we need to do this too. If we are
  67. // clearing a back link (disconnecting), this request came from the
  68. // component we're connected to, so we don't bounce back again.
  69. //
  70. switch (DataFlow) {
  71. case KSPIN_DATAFLOW_IN:
  72. (*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_OUT);
  73. break;
  74. case KSPIN_DATAFLOW_OUT:
  75. (*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_IN);
  76. break;
  77. case KSPSHELL_BACKCONNECT_IN:
  78. if (NewTransport) {
  79. (*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_OUT);
  80. }
  81. break;
  82. case KSPSHELL_BACKCONNECT_OUT:
  83. if (NewTransport) {
  84. (*transport)->Connect(NULL,NULL,KSPSHELL_BACKCONNECT_IN);
  85. }
  86. break;
  87. }
  88. //
  89. // Now release the old neighbor or hand it off to the caller.
  90. //
  91. if (OldTransport) {
  92. *OldTransport = *transport;
  93. } else {
  94. (*transport)->Release();
  95. }
  96. } else if (OldTransport) {
  97. *OldTransport = NULL;
  98. }
  99. //
  100. // Copy the new source/sink.
  101. //
  102. *transport = NewTransport;
  103. if (NewTransport) {
  104. //
  105. // Add a reference if necessary.
  106. //
  107. NewTransport->AddRef();
  108. //
  109. // Do the back connect if necessary.
  110. //
  111. switch (DataFlow) {
  112. case KSPIN_DATAFLOW_IN:
  113. NewTransport->Connect(ThisTransport,NULL,KSPSHELL_BACKCONNECT_OUT);
  114. break;
  115. case KSPIN_DATAFLOW_OUT:
  116. NewTransport->Connect(ThisTransport,NULL,KSPSHELL_BACKCONNECT_IN);
  117. break;
  118. }
  119. }
  120. //
  121. // Now this object may die if it has no references.
  122. //
  123. ThisTransport->Release();
  124. }
  125. #pragma code_seg()
  126. NTSTATUS
  127. KspShellTransferKsIrp(
  128. IN PIKSSHELLTRANSPORT NewTransport,
  129. IN PIRP Irp
  130. )
  131. /*++
  132. Routine Description:
  133. This routine transfers a streaming IRP using the kernel streaming shell
  134. transport.
  135. Arguments:
  136. Return Value:
  137. --*/
  138. {
  139. _DbgPrintF(DEBUGLVL_BLAB,("KspShellTransferKsIrp"));
  140. ASSERT(NewTransport);
  141. ASSERT(Irp);
  142. NTSTATUS status = STATUS_UNSUCCESSFUL;
  143. while (NewTransport) {
  144. PIKSSHELLTRANSPORT nextTransport;
  145. status = NewTransport->TransferKsIrp(Irp,&nextTransport);
  146. ASSERT(NT_SUCCESS(status) || ! nextTransport);
  147. NewTransport = nextTransport;
  148. }
  149. return status;
  150. }
  151. #pragma code_seg("PAGE")
  152. #if DBG
  153. void
  154. DbgPrintCircuit(
  155. IN PIKSSHELLTRANSPORT Transport
  156. )
  157. /*++
  158. Routine Description:
  159. This routine spews a transport circuit.
  160. Arguments:
  161. Return Value:
  162. --*/
  163. {
  164. _DbgPrintF(DEBUGLVL_BLAB,("DbgPrintCircuit"));
  165. PAGED_CODE();
  166. ASSERT(Transport);
  167. #define MAX_NAME_SIZE 64
  168. PIKSSHELLTRANSPORT transport = Transport;
  169. while (transport) {
  170. CHAR name[MAX_NAME_SIZE + 1];
  171. PIKSSHELLTRANSPORT next;
  172. PIKSSHELLTRANSPORT prev;
  173. transport->DbgRollCall(MAX_NAME_SIZE,name,&next,&prev);
  174. DbgPrint(" %s",name);
  175. if (prev) {
  176. PIKSSHELLTRANSPORT next2;
  177. PIKSSHELLTRANSPORT prev2;
  178. prev->DbgRollCall(MAX_NAME_SIZE,name,&next2,&prev2);
  179. if (next2 != transport) {
  180. DbgPrint(" SOURCE'S(0x%08x) SINK(0x%08x) != THIS(%08x)",prev,next2,transport);
  181. }
  182. } else {
  183. DbgPrint(" NO SOURCE");
  184. }
  185. if (next) {
  186. PIKSSHELLTRANSPORT next2;
  187. PIKSSHELLTRANSPORT prev2;
  188. next->DbgRollCall(MAX_NAME_SIZE,name,&next2,&prev2);
  189. if (prev2 != transport) {
  190. DbgPrint(" SINK'S(0x%08x) SOURCE(0x%08x) != THIS(%08x)",next,prev2,transport);
  191. }
  192. } else {
  193. DbgPrint(" NO SINK");
  194. }
  195. DbgPrint("\n");
  196. transport = next;
  197. if (transport == Transport) {
  198. break;
  199. }
  200. }
  201. }
  202. #endif