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.

363 lines
8.5 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Module: pi.cpp
  4. //
  5. // Description:
  6. //
  7. //
  8. //@@BEGIN_MSINTERNAL
  9. // Development Team:
  10. // Mike McLaughlin
  11. //
  12. // History: Date Author Comment
  13. //
  14. // To Do: Date Author Comment
  15. //
  16. //@@END_MSINTERNAL
  17. //
  18. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  19. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  20. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  21. // PURPOSE.
  22. //
  23. // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
  24. //
  25. //---------------------------------------------------------------------------
  26. #include "common.h"
  27. //---------------------------------------------------------------------------
  28. //---------------------------------------------------------------------------
  29. DATARANGES DataRangesNull = {
  30. {
  31. sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATARANGE),
  32. 1
  33. },
  34. {
  35. sizeof(KSDATARANGE),
  36. 0,
  37. STATICGUIDOF(GUID_NULL),
  38. STATICGUIDOF(GUID_NULL),
  39. STATICGUIDOF(GUID_NULL),
  40. }
  41. };
  42. IDENTIFIERS IdentifiersNull = {
  43. {
  44. sizeof(KSMULTIPLE_ITEM) + sizeof(KSIDENTIFIER),
  45. 1
  46. },
  47. {
  48. STATICGUIDOF(GUID_NULL),
  49. 0,
  50. 0
  51. }
  52. };
  53. //---------------------------------------------------------------------------
  54. //---------------------------------------------------------------------------
  55. CPinInfo::CPinInfo(
  56. PFILTER_NODE pFilterNode,
  57. ULONG PinId
  58. )
  59. {
  60. Assert(pFilterNode);
  61. this->pFilterNode = pFilterNode;
  62. this->PinId = PinId;
  63. AddList(&pFilterNode->lstPinInfo);
  64. }
  65. CPinInfo::~CPinInfo()
  66. {
  67. Assert(this);
  68. // Free physical connection data
  69. delete pPhysicalConnection;
  70. delete pwstrName;
  71. }
  72. ENUMFUNC
  73. CPinInfo::CreatePhysicalConnection(
  74. )
  75. {
  76. NTSTATUS Status;
  77. Assert(this);
  78. if(pPhysicalConnection != NULL) {
  79. PFILTER_NODE pFilterNodeConnect;
  80. PPIN_INFO pPinInfoConnect;
  81. ASSERT(pPhysicalConnection->Size != 0);
  82. Status = AddFilter(
  83. pPhysicalConnection->SymbolicLinkName,
  84. &pFilterNodeConnect);
  85. if(!NT_SUCCESS(Status)) {
  86. DPF1(10,
  87. "CreatePhysicalConnection: AddFilter FAILED: %08x", Status);
  88. goto exit;
  89. }
  90. Assert(pFilterNodeConnect);
  91. FOR_EACH_LIST_ITEM(&pFilterNodeConnect->lstPinInfo, pPinInfoConnect) {
  92. if(pPhysicalConnection->Pin == pPinInfoConnect->PinId) {
  93. DPF2(50, "CreatePhysicalConnection: From %d %s",
  94. PinId,
  95. pFilterNode->DumpName());
  96. DPF2(50, "CreatePhysicalConnection: To %d %s",
  97. pPinInfoConnect->PinId,
  98. pPinInfoConnect->pFilterNode->DumpName());
  99. if(DataFlow == KSPIN_DATAFLOW_OUT &&
  100. pPinInfoConnect->DataFlow == KSPIN_DATAFLOW_IN) {
  101. PTOPOLOGY_CONNECTION pTopologyConnection;
  102. Status = CreatePinInfoConnection(
  103. &pTopologyConnection,
  104. pFilterNode,
  105. NULL,
  106. this,
  107. pPinInfoConnect);
  108. if(!NT_SUCCESS(Status)) {
  109. Trap();
  110. goto exit;
  111. }
  112. }
  113. else {
  114. DPF(50, "CreatePhysicalConnection: rejected");
  115. }
  116. break;
  117. }
  118. } END_EACH_LIST_ITEM
  119. delete pPhysicalConnection;
  120. pPhysicalConnection = NULL;
  121. }
  122. Status = STATUS_CONTINUE;
  123. exit:
  124. return(Status);
  125. }
  126. NTSTATUS CPinInfo::GetPinInstances(
  127. PFILE_OBJECT pFileObject,
  128. PKSPIN_CINSTANCES pcInstances
  129. )
  130. {
  131. NTSTATUS Status;
  132. Status = GetPinProperty(
  133. pFileObject,
  134. KSPROPERTY_PIN_CINSTANCES,
  135. PinId,
  136. sizeof(KSPIN_CINSTANCES),
  137. (PVOID) pcInstances);
  138. return Status;
  139. } // GetPinInstances
  140. NTSTATUS
  141. CPinInfo::Create(
  142. PFILE_OBJECT pFileObject
  143. )
  144. {
  145. NTSTATUS Status = STATUS_SUCCESS;
  146. PDATARANGES pDataRanges;
  147. PIDENTIFIERS pInterfaces;
  148. PIDENTIFIERS pMediums;
  149. Assert(this);
  150. Assert(pFilterNode);
  151. Status = GetPinInstances(pFileObject, &cPinInstances);
  152. if(!NT_SUCCESS(Status)) {
  153. Trap();
  154. goto exit;
  155. }
  156. Status = GetPinProperty(
  157. pFileObject,
  158. KSPROPERTY_PIN_DATAFLOW,
  159. PinId,
  160. sizeof(KSPIN_DATAFLOW),
  161. (PVOID)&DataFlow);
  162. if(!NT_SUCCESS(Status)) {
  163. Trap();
  164. goto exit;
  165. }
  166. Status = GetPinProperty(
  167. pFileObject,
  168. KSPROPERTY_PIN_COMMUNICATION,
  169. PinId,
  170. sizeof(KSPIN_COMMUNICATION),
  171. (PVOID)&Communication);
  172. if(!NT_SUCCESS(Status)) {
  173. Trap();
  174. goto exit;
  175. }
  176. pguidCategory = new GUID;
  177. if(pguidCategory == NULL) {
  178. Trap();
  179. Status = STATUS_INSUFFICIENT_RESOURCES;
  180. goto exit;
  181. }
  182. Status = GetPinProperty(
  183. pFileObject,
  184. KSPROPERTY_PIN_CATEGORY,
  185. PinId,
  186. sizeof(GUID),
  187. (PVOID)pguidCategory);
  188. if(NT_SUCCESS(Status)) {
  189. Status = pFilterNode->lstFreeMem.AddList(pguidCategory);
  190. if(!NT_SUCCESS(Status)) {
  191. Trap();
  192. delete pguidCategory;
  193. pguidCategory = NULL;
  194. goto exit;
  195. }
  196. }
  197. else {
  198. delete pguidCategory;
  199. pguidCategory = NULL;
  200. if(Status != STATUS_NOT_FOUND) {
  201. Trap();
  202. goto exit;
  203. }
  204. }
  205. Status = GetPinPropertyEx(
  206. pFileObject,
  207. KSPROPERTY_PIN_NAME,
  208. PinId,
  209. (PVOID*)&pwstrName);
  210. if(!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) {
  211. Trap();
  212. goto exit;
  213. }
  214. Status = GetPinPropertyEx(
  215. pFileObject,
  216. KSPROPERTY_PIN_PHYSICALCONNECTION,
  217. PinId,
  218. (PVOID*)&pPhysicalConnection);
  219. if(!NT_SUCCESS(Status)) {
  220. Trap();
  221. goto exit;
  222. }
  223. Status = GetPinPropertyEx(
  224. pFileObject,
  225. KSPROPERTY_PIN_INTERFACES,
  226. PinId,
  227. (PVOID*)&pInterfaces);
  228. if(!NT_SUCCESS(Status)) {
  229. Trap();
  230. goto exit;
  231. }
  232. if(pInterfaces == NULL || pInterfaces->MultipleItem.Count == 0) {
  233. delete pInterfaces;
  234. pInterfaces = &IdentifiersNull;
  235. }
  236. else {
  237. Status = pFilterNode->lstFreeMem.AddList(pInterfaces);
  238. if(!NT_SUCCESS(Status)) {
  239. Trap();
  240. delete pInterfaces;
  241. goto exit;
  242. }
  243. }
  244. Status = GetPinPropertyEx(
  245. pFileObject,
  246. KSPROPERTY_PIN_MEDIUMS,
  247. PinId,
  248. (PVOID*)&pMediums);
  249. if(!NT_SUCCESS(Status)) {
  250. Trap();
  251. goto exit;
  252. }
  253. if(pMediums == NULL || pMediums->MultipleItem.Count == 0) {
  254. delete pMediums;
  255. pMediums = &IdentifiersNull;
  256. }
  257. else {
  258. Status = pFilterNode->lstFreeMem.AddList(pMediums);
  259. if(!NT_SUCCESS(Status)) {
  260. Trap();
  261. delete pMediums;
  262. goto exit;
  263. }
  264. }
  265. Status = GetPinPropertyEx(
  266. pFileObject,
  267. KSPROPERTY_PIN_DATARANGES,
  268. PinId,
  269. (PVOID*)&pDataRanges);
  270. if(!NT_SUCCESS(Status)) {
  271. Trap();
  272. goto exit;
  273. }
  274. if(pDataRanges == NULL || pDataRanges->MultipleItem.Count == 0) {
  275. Trap();
  276. delete pDataRanges;
  277. pDataRanges = &DataRangesNull;
  278. }
  279. else {
  280. Status = pFilterNode->lstFreeMem.AddList(pDataRanges);
  281. if(!NT_SUCCESS(Status)) {
  282. Trap();
  283. delete pDataRanges;
  284. goto exit;
  285. }
  286. }
  287. Status = CPinNode::CreateAll(
  288. this,
  289. pDataRanges,
  290. pInterfaces,
  291. pMediums);
  292. if(!NT_SUCCESS(Status)) {
  293. Trap();
  294. goto exit;
  295. }
  296. // ISSUE-2001/05/15-alpers
  297. // This is a temporary low risk solution to reverse DataRange problem.
  298. // This needs to be implemented properly in the future.
  299. //
  300. if (pFilterNode->GetType() & FILTER_TYPE_AEC) {
  301. DPF(10, "AEC Filter Pin : Reversing Data Ranges");
  302. lstPinNode.ReverseList();
  303. }
  304. if (pFilterNode->GetType() & FILTER_TYPE_GFX) {
  305. DPF(10, "GFX Filter Pin : Reversing Data Ranges");
  306. lstPinNode.ReverseList();
  307. }
  308. exit:
  309. return(Status);
  310. }