Source code of Windows XP (NT5)
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.

419 lines
8.7 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. #ifndef DEBUG // Only free the name in retail; allows .s to display name
  120. delete pPhysicalConnection;
  121. pPhysicalConnection = NULL;
  122. #endif
  123. }
  124. Status = STATUS_CONTINUE;
  125. exit:
  126. return(Status);
  127. }
  128. NTSTATUS CPinInfo::GetPinInstances(
  129. PFILE_OBJECT pFileObject,
  130. PKSPIN_CINSTANCES pcInstances
  131. )
  132. {
  133. NTSTATUS Status;
  134. Status = GetPinProperty(
  135. pFileObject,
  136. KSPROPERTY_PIN_CINSTANCES,
  137. PinId,
  138. sizeof(KSPIN_CINSTANCES),
  139. (PVOID) pcInstances);
  140. return Status;
  141. } // GetPinInstances
  142. NTSTATUS
  143. CPinInfo::Create(
  144. PFILE_OBJECT pFileObject
  145. )
  146. {
  147. NTSTATUS Status = STATUS_SUCCESS;
  148. PDATARANGES pDataRanges;
  149. PIDENTIFIERS pInterfaces;
  150. PIDENTIFIERS pMediums;
  151. Assert(this);
  152. Assert(pFilterNode);
  153. Status = GetPinInstances(pFileObject, &cPinInstances);
  154. if(!NT_SUCCESS(Status)) {
  155. Trap();
  156. goto exit;
  157. }
  158. Status = GetPinProperty(
  159. pFileObject,
  160. KSPROPERTY_PIN_DATAFLOW,
  161. PinId,
  162. sizeof(KSPIN_DATAFLOW),
  163. (PVOID)&DataFlow);
  164. if(!NT_SUCCESS(Status)) {
  165. Trap();
  166. goto exit;
  167. }
  168. Status = GetPinProperty(
  169. pFileObject,
  170. KSPROPERTY_PIN_COMMUNICATION,
  171. PinId,
  172. sizeof(KSPIN_COMMUNICATION),
  173. (PVOID)&Communication);
  174. if(!NT_SUCCESS(Status)) {
  175. Trap();
  176. goto exit;
  177. }
  178. pguidCategory = new GUID;
  179. if(pguidCategory == NULL) {
  180. Trap();
  181. Status = STATUS_INSUFFICIENT_RESOURCES;
  182. goto exit;
  183. }
  184. Status = GetPinProperty(
  185. pFileObject,
  186. KSPROPERTY_PIN_CATEGORY,
  187. PinId,
  188. sizeof(GUID),
  189. (PVOID)pguidCategory);
  190. if(NT_SUCCESS(Status)) {
  191. Status = pFilterNode->lstFreeMem.AddList(pguidCategory);
  192. if(!NT_SUCCESS(Status)) {
  193. Trap();
  194. delete pguidCategory;
  195. pguidCategory = NULL;
  196. goto exit;
  197. }
  198. }
  199. else {
  200. delete pguidCategory;
  201. pguidCategory = NULL;
  202. if(Status != STATUS_NOT_FOUND) {
  203. Trap();
  204. goto exit;
  205. }
  206. }
  207. Status = GetPinPropertyEx(
  208. pFileObject,
  209. KSPROPERTY_PIN_NAME,
  210. PinId,
  211. (PVOID*)&pwstrName);
  212. if(!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) {
  213. Trap();
  214. goto exit;
  215. }
  216. Status = GetPinPropertyEx(
  217. pFileObject,
  218. KSPROPERTY_PIN_PHYSICALCONNECTION,
  219. PinId,
  220. (PVOID*)&pPhysicalConnection);
  221. if(!NT_SUCCESS(Status)) {
  222. Trap();
  223. goto exit;
  224. }
  225. Status = GetPinPropertyEx(
  226. pFileObject,
  227. KSPROPERTY_PIN_INTERFACES,
  228. PinId,
  229. (PVOID*)&pInterfaces);
  230. if(!NT_SUCCESS(Status)) {
  231. Trap();
  232. goto exit;
  233. }
  234. if(pInterfaces == NULL || pInterfaces->MultipleItem.Count == 0) {
  235. delete pInterfaces;
  236. pInterfaces = &IdentifiersNull;
  237. }
  238. else {
  239. Status = pFilterNode->lstFreeMem.AddList(pInterfaces);
  240. if(!NT_SUCCESS(Status)) {
  241. Trap();
  242. delete pInterfaces;
  243. goto exit;
  244. }
  245. }
  246. Status = GetPinPropertyEx(
  247. pFileObject,
  248. KSPROPERTY_PIN_MEDIUMS,
  249. PinId,
  250. (PVOID*)&pMediums);
  251. if(!NT_SUCCESS(Status)) {
  252. Trap();
  253. goto exit;
  254. }
  255. if(pMediums == NULL || pMediums->MultipleItem.Count == 0) {
  256. delete pMediums;
  257. pMediums = &IdentifiersNull;
  258. }
  259. else {
  260. Status = pFilterNode->lstFreeMem.AddList(pMediums);
  261. if(!NT_SUCCESS(Status)) {
  262. Trap();
  263. delete pMediums;
  264. goto exit;
  265. }
  266. }
  267. Status = GetPinPropertyEx(
  268. pFileObject,
  269. KSPROPERTY_PIN_DATARANGES,
  270. PinId,
  271. (PVOID*)&pDataRanges);
  272. if(!NT_SUCCESS(Status)) {
  273. Trap();
  274. goto exit;
  275. }
  276. if(pDataRanges == NULL || pDataRanges->MultipleItem.Count == 0) {
  277. Trap();
  278. delete pDataRanges;
  279. pDataRanges = &DataRangesNull;
  280. }
  281. else {
  282. Status = pFilterNode->lstFreeMem.AddList(pDataRanges);
  283. if(!NT_SUCCESS(Status)) {
  284. Trap();
  285. delete pDataRanges;
  286. goto exit;
  287. }
  288. }
  289. Status = CPinNode::CreateAll(
  290. this,
  291. pDataRanges,
  292. pInterfaces,
  293. pMediums);
  294. if(!NT_SUCCESS(Status)) {
  295. Trap();
  296. goto exit;
  297. }
  298. // ISSUE-2001/05/15-alpers
  299. // This is a temporary low risk solution to reverse DataRange problem.
  300. // This needs to be implemented properly in the future.
  301. //
  302. if (pFilterNode->GetType() & FILTER_TYPE_AEC) {
  303. DPF(10, "AEC Filter Pin : Reversing Data Ranges");
  304. lstPinNode.ReverseList();
  305. }
  306. if (pFilterNode->GetType() & FILTER_TYPE_GFX) {
  307. DPF(10, "GFX Filter Pin : Reversing Data Ranges");
  308. lstPinNode.ReverseList();
  309. }
  310. exit:
  311. return(Status);
  312. }
  313. #ifdef DEBUG
  314. PSZ apszDataFlow[] = { "??", "IN", "OUT" };
  315. PSZ apszCommunication[] = { "NONE", "SINK", "SOURCE", "BOTH", "BRIDGE" };
  316. ENUMFUNC
  317. CPinInfo::Dump(
  318. )
  319. {
  320. Assert(this);
  321. if(ulDebugFlags & (DEBUG_FLAGS_VERBOSE | DEBUG_FLAGS_OBJECT)) {
  322. dprintf("PI: %08x FN %08x PinId %d DataFlow %08x %s Comm %08x %s\n",
  323. this,
  324. pFilterNode,
  325. PinId,
  326. DataFlow,
  327. apszDataFlow[DataFlow],
  328. Communication,
  329. apszCommunication[Communication]);
  330. dprintf(" cPossible %d cCurrent %d %s\n",
  331. cPinInstances.PossibleCount,
  332. cPinInstances.CurrentCount,
  333. pFilterNode->DumpName());
  334. dprintf(" guidCategory: %s\n", DbgGuid2Sz(pguidCategory));
  335. dprintf(" guidName: %s\n", DbgGuid2Sz(pguidName));
  336. if(pwstrName != NULL) {
  337. dprintf(" pwstrName: %s\n", DbgUnicode2Sz(pwstrName));
  338. }
  339. if(pPhysicalConnection != NULL) {
  340. dprintf(" pPhysicalConnection: PinId %d\n %s\n",
  341. pPhysicalConnection->Pin,
  342. DbgUnicode2Sz(pPhysicalConnection->SymbolicLinkName));
  343. }
  344. dprintf(" lstTopologyConnection:");
  345. lstTopologyConnection.DumpAddress();
  346. dprintf("\n");
  347. if(ulDebugFlags & DEBUG_FLAGS_DETAILS) {
  348. dprintf(" lshPinNode:\n");
  349. lstPinNode.Dump();
  350. }
  351. }
  352. else {
  353. dprintf("PI: %08x FN %08x #%-2d %-3s %-6s\n",
  354. this,
  355. pFilterNode,
  356. PinId,
  357. apszDataFlow[DataFlow],
  358. apszCommunication[Communication]);
  359. }
  360. return(STATUS_CONTINUE);
  361. }
  362. #endif