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.

735 lines
20 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Module: property.c
  4. //
  5. // Description:
  6. //
  7. //
  8. //@@BEGIN_MSINTERNAL
  9. // Development Team:
  10. // Andy Nicholson
  11. //
  12. // History: Date Author Comment
  13. //
  14. // To Do: Date Author Comment
  15. //
  16. //@@END_MSINTERNAL
  17. //---------------------------------------------------------------------------
  18. //
  19. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  20. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  21. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  22. // PURPOSE.
  23. //
  24. // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
  25. //
  26. //---------------------------------------------------------------------------
  27. #include "common.h"
  28. //---------------------------------------------------------------------------
  29. //---------------------------------------------------------------------------
  30. NTSTATUS
  31. PropertyReturnString(
  32. IN PIRP pIrp,
  33. IN PWSTR pwstrString,
  34. IN ULONG cbString,
  35. OUT PVOID pData
  36. )
  37. {
  38. NTSTATUS Status = STATUS_SUCCESS;
  39. PIO_STACK_LOCATION pIrpStack;
  40. ULONG cbNameBuffer;
  41. ULONG cbToCopy;
  42. pIrp->IoStatus.Information = 0;
  43. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  44. cbNameBuffer = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
  45. cbNameBuffer &= ~(sizeof(WCHAR) - 1); // round down to whole wchar's
  46. // If the size of the passed buffer is 0, then the
  47. // requestor wants to know the length of the string.
  48. if(cbNameBuffer == 0) {
  49. pIrp->IoStatus.Information = cbString;
  50. Status = STATUS_BUFFER_OVERFLOW;
  51. }
  52. // If the size of the passed buffer is a ULONG, then infer the
  53. // requestor wants to know the length of the string.
  54. else if(cbNameBuffer == sizeof(ULONG)) {
  55. *((PULONG)pData) = cbString;
  56. pIrp->IoStatus.Information = sizeof(ULONG);
  57. ASSERT(NT_SUCCESS(Status));
  58. }
  59. else {
  60. // Note that we don't check for zero-length buffer because ks handler
  61. // function should have done that already.
  62. // Even though we are getting back the length of the string (as though
  63. // it were a unicode string) it is being handed up as a double-byte
  64. // string, so this code assumes there is a null at the end. There
  65. // will be a bug here if there is no null.
  66. cbToCopy = min(cbString, cbNameBuffer);
  67. RtlCopyMemory(pData, pwstrString, cbToCopy);
  68. // Ensure there is a null at the end
  69. ((PWCHAR)pData)[cbToCopy/sizeof(WCHAR) - 1] = (WCHAR)0;
  70. pIrp->IoStatus.Information = cbToCopy;
  71. ASSERT(NT_SUCCESS(Status));
  72. }
  73. return(Status);
  74. }
  75. //---------------------------------------------------------------------------
  76. NTSTATUS
  77. SetPreferredDevice(
  78. IN PIRP pIrp,
  79. IN PSYSAUDIO_PREFERRED_DEVICE pPreferred,
  80. IN PULONG pulDevice
  81. )
  82. {
  83. PFILTER_INSTANCE pFilterInstance;
  84. NTSTATUS Status = STATUS_SUCCESS;
  85. PIO_STACK_LOCATION pIrpStack;
  86. PDEVICE_NODE pDeviceNode,OldDeviceNode;
  87. ULONG PinId = MAXULONG;
  88. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  89. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  90. Assert(pFilterInstance);
  91. if(pPreferred->Flags & ~SYSAUDIO_FLAGS_CLEAR_PREFERRED) {
  92. Status = STATUS_INVALID_PARAMETER;
  93. goto exit;
  94. }
  95. if(pPreferred->Index >= MAX_SYSAUDIO_DEFAULT_TYPE) {
  96. Trap();
  97. Status = STATUS_INVALID_PARAMETER;
  98. goto exit;
  99. }
  100. if(pPreferred->Flags & SYSAUDIO_FLAGS_CLEAR_PREFERRED) {
  101. OldDeviceNode = apShingleInstance[pPreferred->Index]->GetDeviceNode();
  102. if (OldDeviceNode) {
  103. OldDeviceNode->SetPreferredStatus((KSPROPERTY_SYSAUDIO_DEFAULT_TYPE)pPreferred->Index, FALSE);
  104. }
  105. apShingleInstance[pPreferred->Index]->SetDeviceNode(NULL);
  106. DPF1(60, "SetPreferredDevice: CLEAR %d", pPreferred->Index);
  107. }
  108. else {
  109. if(*pulDevice == MAXULONG) {
  110. pDeviceNode = pFilterInstance->GetDeviceNode();
  111. if(pDeviceNode == NULL) {
  112. Trap();
  113. Status = STATUS_INVALID_DEVICE_REQUEST;
  114. goto exit;
  115. }
  116. }
  117. else {
  118. Status = GetDeviceByIndex(
  119. *pulDevice,
  120. &pDeviceNode);
  121. if(!NT_SUCCESS(Status)) {
  122. goto exit;
  123. }
  124. }
  125. Assert(pDeviceNode);
  126. if(pIrpStack->Parameters.DeviceIoControl.OutputBufferLength ==
  127. (sizeof(ULONG) * 2)) {
  128. PinId = pulDevice[1];
  129. }
  130. OldDeviceNode = apShingleInstance[pPreferred->Index]->GetDeviceNode();
  131. if (OldDeviceNode) {
  132. OldDeviceNode->SetPreferredStatus((KSPROPERTY_SYSAUDIO_DEFAULT_TYPE)pPreferred->Index, FALSE);
  133. }
  134. apShingleInstance[pPreferred->Index]->SetDeviceNode(pDeviceNode);
  135. pDeviceNode->SetPreferredStatus((KSPROPERTY_SYSAUDIO_DEFAULT_TYPE)pPreferred->Index, TRUE);
  136. DPF4(60, "SetPreferredDevice: %d SAD %d #%d %s",
  137. pPreferred->Index,
  138. *pulDevice,
  139. PinId,
  140. pDeviceNode->DumpName());
  141. }
  142. exit:
  143. return(Status);
  144. }
  145. NTSTATUS
  146. GetComponentIdProperty(
  147. IN PIRP pIrp,
  148. IN PKSPROPERTY pRequest,
  149. IN OUT PVOID pData
  150. )
  151. {
  152. NTSTATUS Status = STATUS_SUCCESS;
  153. PFILTER_INSTANCE pFilterInstance;
  154. PIO_STACK_LOCATION pIrpStack;
  155. PDEVICE_NODE pDeviceNode;
  156. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  157. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  158. Assert(pFilterInstance);
  159. if(*(PULONG)(pRequest + 1) == MAXULONG) {
  160. pDeviceNode = pFilterInstance->GetDeviceNode();
  161. if(pDeviceNode == NULL) {
  162. Trap();
  163. Status = STATUS_INVALID_PARAMETER;
  164. goto exit;
  165. }
  166. }
  167. else {
  168. Status = GetDeviceByIndex(
  169. *(PULONG)(pRequest + 1),
  170. &pDeviceNode);
  171. if(!NT_SUCCESS(Status)) {
  172. goto exit;
  173. }
  174. }
  175. Assert(pDeviceNode);
  176. if(pDeviceNode->GetComponentId() == NULL) {
  177. Status = STATUS_INVALID_DEVICE_REQUEST; // This should be STATUS_NOT_FOUND but
  178. goto exit; // returning this causes FilterDispatchIoControl
  179. // call ForwardIrpNode which asserts that this is
  180. // not a KSPROPSETID_Sysaudio property.
  181. }
  182. RtlCopyMemory(
  183. pData,
  184. pDeviceNode->GetComponentId(),
  185. sizeof(KSCOMPONENTID));
  186. Status = STATUS_SUCCESS;
  187. if(!NT_SUCCESS(Status)) {
  188. goto exit;
  189. }
  190. exit:
  191. return(Status);
  192. }
  193. NTSTATUS
  194. GetFriendlyNameProperty(
  195. IN PIRP pIrp,
  196. IN PKSPROPERTY pRequest,
  197. IN OUT PVOID pData
  198. )
  199. {
  200. NTSTATUS Status = STATUS_SUCCESS;
  201. PFILTER_INSTANCE pFilterInstance;
  202. PIO_STACK_LOCATION pIrpStack;
  203. PDEVICE_NODE pDeviceNode;
  204. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  205. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  206. Assert(pFilterInstance);
  207. if(*(PULONG)(pRequest + 1) == MAXULONG) {
  208. pDeviceNode = pFilterInstance->GetDeviceNode();
  209. if(pDeviceNode == NULL) {
  210. Trap();
  211. Status = STATUS_INVALID_PARAMETER;
  212. goto exit;
  213. }
  214. }
  215. else {
  216. Status = GetDeviceByIndex(
  217. *(PULONG)(pRequest + 1),
  218. &pDeviceNode);
  219. if(!NT_SUCCESS(Status)) {
  220. goto exit;
  221. }
  222. }
  223. Assert(pDeviceNode);
  224. if(pDeviceNode->GetFriendlyName() == NULL) {
  225. Status = STATUS_INVALID_DEVICE_REQUEST;
  226. goto exit;
  227. }
  228. Status = PropertyReturnString(
  229. pIrp,
  230. pDeviceNode->GetFriendlyName(),
  231. (wcslen(pDeviceNode->GetFriendlyName()) *
  232. sizeof(WCHAR)) + sizeof(UNICODE_NULL),
  233. pData);
  234. if(!NT_SUCCESS(Status)) {
  235. goto exit;
  236. }
  237. exit:
  238. return(Status);
  239. }
  240. NTSTATUS
  241. GetDeviceCount(
  242. IN PIRP pIrp,
  243. IN PKSPROPERTY pRequest,
  244. IN OUT PVOID pData
  245. )
  246. {
  247. if(gplstDeviceNode == NULL) {
  248. *(PULONG)pData = 0;
  249. }
  250. else {
  251. *(PULONG)pData = gplstDeviceNode->CountList();
  252. }
  253. pIrp->IoStatus.Information = sizeof(ULONG);
  254. return(STATUS_SUCCESS);
  255. }
  256. NTSTATUS
  257. GetInstanceDevice(
  258. IN PIRP pIrp,
  259. IN PKSPROPERTY pRequest,
  260. IN OUT PVOID pData
  261. )
  262. {
  263. NTSTATUS Status = STATUS_SUCCESS;
  264. PIO_STACK_LOCATION pIrpStack;
  265. PFILTER_INSTANCE pFilterInstance;
  266. ULONG Index;
  267. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  268. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  269. Assert(pFilterInstance);
  270. Status = pFilterInstance->GetDeviceNode()->GetIndexByDevice(&Index);
  271. if(NT_SUCCESS(Status)) {
  272. *(PULONG)pData = Index;
  273. pIrp->IoStatus.Information = sizeof(ULONG);
  274. }
  275. return(Status);
  276. }
  277. NTSTATUS
  278. SetInstanceDevice(
  279. IN PIRP Irp,
  280. IN PKSPROPERTY Request,
  281. IN OUT PVOID Data
  282. )
  283. {
  284. NTSTATUS Status = STATUS_SUCCESS;
  285. PFILTER_INSTANCE pFilterInstance;
  286. PIO_STACK_LOCATION pIrpStack;
  287. PDEVICE_NODE pDeviceNode;
  288. pIrpStack = IoGetCurrentIrpStackLocation(Irp);
  289. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  290. Assert(pFilterInstance);
  291. if(!pFilterInstance->IsChildInstance()) {
  292. DPF(5, "SetInstanceDevice: FAILED - open pin instances");
  293. Status = STATUS_INVALID_DEVICE_REQUEST;
  294. goto exit;
  295. }
  296. Status = GetDeviceByIndex(*(PULONG)Data, &pDeviceNode);
  297. if(NT_SUCCESS(Status)) {
  298. Status = pFilterInstance->SetDeviceNode(pDeviceNode);
  299. if(!NT_SUCCESS(Status)) {
  300. goto exit;
  301. }
  302. }
  303. exit:
  304. return(Status);
  305. }
  306. NTSTATUS
  307. SetInstanceInfo(
  308. IN PIRP Irp,
  309. IN PSYSAUDIO_INSTANCE_INFO pInstanceInfo,
  310. IN OUT PVOID Data
  311. )
  312. {
  313. NTSTATUS Status = STATUS_SUCCESS;
  314. PFILTER_INSTANCE pFilterInstance;
  315. PIO_STACK_LOCATION pIrpStack;
  316. PDEVICE_NODE pDeviceNode;
  317. pIrpStack = IoGetCurrentIrpStackLocation(Irp);
  318. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  319. Assert(pFilterInstance);
  320. if(pInstanceInfo->Flags & ~SYSAUDIO_FLAGS_DONT_COMBINE_PINS) {
  321. Status = STATUS_INVALID_PARAMETER;
  322. goto exit;
  323. }
  324. if(!pFilterInstance->IsChildInstance()) {
  325. Trap();
  326. DPF(5, "SetInstanceInfo: FAILED - open pin instances");
  327. Status = STATUS_INVALID_DEVICE_REQUEST;
  328. goto exit;
  329. }
  330. Status = GetDeviceByIndex(pInstanceInfo->DeviceNumber, &pDeviceNode);
  331. if(!NT_SUCCESS(Status)) {
  332. goto exit;
  333. }
  334. Assert(pDeviceNode);
  335. pFilterInstance->ulFlags |= FLAGS_COMBINE_PINS;
  336. if(pInstanceInfo->Flags & SYSAUDIO_FLAGS_DONT_COMBINE_PINS) {
  337. pFilterInstance->ulFlags &= ~FLAGS_COMBINE_PINS;
  338. }
  339. Status = pFilterInstance->SetDeviceNode(pDeviceNode);
  340. if(!NT_SUCCESS(Status)) {
  341. goto exit;
  342. }
  343. exit:
  344. return(Status);
  345. }
  346. NTSTATUS
  347. SetDeviceDefault(
  348. IN PIRP pIrp,
  349. IN PKSPROPERTY pRequest,
  350. IN OUT PULONG pData
  351. )
  352. {
  353. NTSTATUS Status = STATUS_SUCCESS;
  354. PFILTER_INSTANCE pFilterInstance;
  355. PIO_STACK_LOCATION pIrpStack;
  356. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  357. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  358. Assert(pFilterInstance);
  359. if(*pData >= MAX_SYSAUDIO_DEFAULT_TYPE) {
  360. Status = STATUS_INVALID_DEVICE_REQUEST;
  361. goto exit;
  362. }
  363. if(!pFilterInstance->IsChildInstance()) {
  364. Trap();
  365. DPF(5, "SetDeviceDefault: FAILED - open pin instances");
  366. Status = STATUS_INVALID_DEVICE_REQUEST;
  367. goto exit;
  368. }
  369. Status = pFilterInstance->SetShingleInstance(apShingleInstance[*pData]);
  370. if(!NT_SUCCESS(Status)) {
  371. goto exit;
  372. }
  373. exit:
  374. return(Status);
  375. }
  376. NTSTATUS
  377. GetDeviceInterfaceName(
  378. IN PIRP pIrp,
  379. IN PKSPROPERTY pRequest,
  380. IN OUT PVOID pData
  381. )
  382. {
  383. PIO_STACK_LOCATION pIrpStack;
  384. PFILTER_INSTANCE pFilterInstance;
  385. NTSTATUS Status = STATUS_SUCCESS;
  386. PDEVICE_NODE pDeviceNode;
  387. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  388. pFilterInstance = (PFILTER_INSTANCE)pIrpStack->FileObject->FsContext;
  389. Assert(pFilterInstance);
  390. if(*(PULONG)(pRequest + 1) == MAXULONG) {
  391. pDeviceNode = pFilterInstance->GetDeviceNode();
  392. if(pDeviceNode == NULL) {
  393. Trap();
  394. Status = STATUS_INVALID_PARAMETER;
  395. goto exit;
  396. }
  397. }
  398. else {
  399. Status = GetDeviceByIndex(*(PULONG)(pRequest + 1), &pDeviceNode);
  400. if(!NT_SUCCESS(Status)) {
  401. goto exit;
  402. }
  403. }
  404. Assert(pDeviceNode);
  405. if(pDeviceNode->GetDeviceInterface() == NULL) {
  406. Status = STATUS_INVALID_DEVICE_REQUEST;
  407. goto exit;
  408. }
  409. Status = PropertyReturnString(
  410. pIrp,
  411. pDeviceNode->GetDeviceInterface(),
  412. (wcslen(pDeviceNode->GetDeviceInterface()) *
  413. sizeof(WCHAR)) + sizeof(UNICODE_NULL),
  414. pData);
  415. if(!NT_SUCCESS(Status)) {
  416. goto exit;
  417. }
  418. exit:
  419. return(Status);
  420. }
  421. NTSTATUS
  422. SelectGraph(
  423. IN PIRP pIrp,
  424. PSYSAUDIO_SELECT_GRAPH pSelectGraph,
  425. IN OUT PVOID pData
  426. )
  427. {
  428. PGRAPH_NODE_INSTANCE pGraphNodeInstance;
  429. PTOPOLOGY_NODE pTopologyNode2;
  430. PTOPOLOGY_NODE pTopologyNode;
  431. PSTART_NODE pStartNode;
  432. NTSTATUS Status;
  433. Status = ::GetGraphNodeInstance(pIrp, &pGraphNodeInstance);
  434. if(!NT_SUCCESS(Status)) {
  435. goto exit2;
  436. }
  437. Assert(pGraphNodeInstance);
  438. if(pGraphNodeInstance->palstTopologyNodeSelect == NULL ||
  439. pGraphNodeInstance->palstTopologyNodeNotSelect == NULL) {
  440. DPF(5, "SelectGraph: palstTopologyNodeSelect == NULL");
  441. Status = STATUS_INVALID_DEVICE_REQUEST;
  442. goto exit2;
  443. }
  444. if(pSelectGraph->Flags != 0 || pSelectGraph->Reserved != 0) {
  445. DPF(5, "SelectGraph: invalid flags or reserved field");
  446. Status = STATUS_INVALID_PARAMETER;
  447. goto exit2;
  448. }
  449. if(pSelectGraph->PinId >= pGraphNodeInstance->cPins) {
  450. DPF(5, "SelectGraph: invalid pin id");
  451. Status = STATUS_INVALID_PARAMETER;
  452. goto exit2;
  453. }
  454. if(pSelectGraph->NodeId >=
  455. pGraphNodeInstance->Topology.TopologyNodesCount) {
  456. DPF(5, "SelectGraph: invalid node id");
  457. Status = STATUS_INVALID_PARAMETER;
  458. goto exit2;
  459. }
  460. #ifdef BREAKS_INTEL
  461. if(!pGraphNodeInstance->pFilterInstance->IsChildInstance()) {
  462. Trap();
  463. DPF(5, "SelectGraph: open pin instances");
  464. Status = STATUS_INVALID_DEVICE_REQUEST;
  465. goto exit2;
  466. }
  467. #endif
  468. pTopologyNode = pGraphNodeInstance->papTopologyNode[pSelectGraph->NodeId];
  469. Assert(pTopologyNode);
  470. Assert(pGraphNodeInstance->pGraphNode);
  471. Assert(pGraphNodeInstance->pGraphNode->pDeviceNode);
  472. DPF2(90, "SelectGraph GNI %08X TN %08X", pGraphNodeInstance, pTopologyNode);
  473. if(pTopologyNode->pFilterNode->GetType() & FILTER_TYPE_GLOBAL_SELECT &&
  474. pGraphNodeInstance->paPinDescriptors[pSelectGraph->PinId].DataFlow ==
  475. KSPIN_DATAFLOW_IN) {
  476. PSTART_NODE_INSTANCE pStartNodeInstance;
  477. PFILTER_INSTANCE pFilterInstance;
  478. FOR_EACH_LIST_ITEM(
  479. &pGraphNodeInstance->pGraphNode->pDeviceNode->lstFilterInstance,
  480. pFilterInstance) {
  481. if(pFilterInstance->pGraphNodeInstance == NULL) {
  482. continue;
  483. }
  484. Assert(pFilterInstance->pGraphNodeInstance);
  485. FOR_EACH_LIST_ITEM(
  486. &pFilterInstance->pGraphNodeInstance->lstStartNodeInstance,
  487. pStartNodeInstance) {
  488. if(EnumerateGraphTopology(
  489. pStartNodeInstance->pStartNode->GetStartInfo(),
  490. (TOP_PFN)FindTopologyNode,
  491. pTopologyNode) == STATUS_CONTINUE) {
  492. DPF2(5, "SelectGraph: TN %08x not found on SNI %08x",
  493. pTopologyNode,
  494. pStartNodeInstance);
  495. Status = STATUS_INVALID_DEVICE_REQUEST;
  496. goto exit;
  497. }
  498. } END_EACH_LIST_ITEM
  499. } END_EACH_LIST_ITEM
  500. Status = pGraphNodeInstance->
  501. lstTopologyNodeGlobalSelect.AddListDup(pTopologyNode);
  502. if(!NT_SUCCESS(Status)) {
  503. Trap();
  504. goto exit;
  505. }
  506. }
  507. else {
  508. Status = pGraphNodeInstance->
  509. palstTopologyNodeSelect[pSelectGraph->PinId].AddList(pTopologyNode);
  510. if(!NT_SUCCESS(Status)) {
  511. Trap();
  512. goto exit;
  513. }
  514. }
  515. //
  516. // If this is a "not select" type filter like AEC or Mic Array, then all
  517. // the nodes in the filter have to be remove from the not select list,
  518. // otherwise IsGraphValid will never find a valid graph.
  519. //
  520. if(pTopologyNode->pFilterNode->GetType() & FILTER_TYPE_NOT_SELECT) {
  521. FOR_EACH_LIST_ITEM(
  522. &pTopologyNode->pFilterNode->lstTopologyNode,
  523. pTopologyNode2) {
  524. pGraphNodeInstance->palstTopologyNodeNotSelect[
  525. pSelectGraph->PinId].RemoveList(pTopologyNode2);
  526. DPF2(50, " Removing %s NodeId %d",\
  527. pTopologyNode2->pFilterNode->DumpName(),
  528. pTopologyNode2->ulSysaudioNodeNumber);
  529. } END_EACH_LIST_ITEM
  530. }
  531. //
  532. // Validate that there is a valid path though the graph after updating
  533. // the various global, select and not select lists.
  534. //
  535. DPF(90, "SelectGraph: Validating Graph");
  536. FOR_EACH_LIST_ITEM(
  537. pGraphNodeInstance->aplstStartNode[pSelectGraph->PinId],
  538. pStartNode) {
  539. DPF2(90, " SN: %X %s",
  540. pStartNode,
  541. pStartNode->GetStartInfo()->GetPinInfo()->pFilterNode->DumpName());
  542. Assert(pStartNode);
  543. if(pGraphNodeInstance->IsGraphValid(
  544. pStartNode,
  545. pSelectGraph->PinId)) {
  546. Status = STATUS_SUCCESS;
  547. goto exit;
  548. }
  549. else {
  550. DPF(90, " IsGraphValid failed");
  551. }
  552. } END_EACH_LIST_ITEM
  553. //
  554. // The select graph failed so restore the not select list back to normal
  555. //
  556. if(pTopologyNode->pFilterNode->GetType() & FILTER_TYPE_NOT_SELECT) {
  557. FOR_EACH_LIST_ITEM(
  558. &pTopologyNode->pFilterNode->lstTopologyNode,
  559. pTopologyNode2) {
  560. pGraphNodeInstance->palstTopologyNodeNotSelect[
  561. pSelectGraph->PinId].AddList(pTopologyNode2);
  562. } END_EACH_LIST_ITEM
  563. }
  564. Status = STATUS_INVALID_DEVICE_REQUEST;
  565. exit:
  566. if(!NT_SUCCESS(Status)) {
  567. pGraphNodeInstance->
  568. palstTopologyNodeSelect[pSelectGraph->PinId].RemoveList(pTopologyNode);
  569. pGraphNodeInstance->
  570. lstTopologyNodeGlobalSelect.RemoveList(pTopologyNode);
  571. }
  572. exit2:
  573. return(Status);
  574. }
  575. //---------------------------------------------------------------------------
  576. NTSTATUS
  577. GetTopologyConnectionIndex(
  578. IN PIRP pIrp,
  579. IN PKSPROPERTY pProperty,
  580. OUT PULONG pulIndex
  581. )
  582. {
  583. PSTART_NODE_INSTANCE pStartNodeInstance;
  584. NTSTATUS Status = STATUS_SUCCESS;
  585. Status = ::GetStartNodeInstance(pIrp, &pStartNodeInstance);
  586. if(!NT_SUCCESS(Status)) {
  587. Trap();
  588. goto exit;
  589. }
  590. Assert(pStartNodeInstance);
  591. Assert(pStartNodeInstance->pStartNode);
  592. Assert(pStartNodeInstance->pStartNode->GetStartInfo());
  593. *pulIndex = pStartNodeInstance->pStartNode->GetStartInfo()->
  594. ulTopologyConnectionTableIndex;
  595. pIrp->IoStatus.Information = sizeof(ULONG);
  596. exit:
  597. return(Status);
  598. }
  599. NTSTATUS
  600. GetPinVolumeNode(
  601. IN PIRP pIrp,
  602. IN PKSPROPERTY pProperty,
  603. OUT PULONG pulNode
  604. )
  605. {
  606. PIO_STACK_LOCATION pIrpStack;
  607. PPIN_INSTANCE pPinInstance;
  608. NTSTATUS Status;
  609. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  610. pPinInstance = (PPIN_INSTANCE)pIrpStack->FileObject->FsContext;
  611. Assert(pPinInstance);
  612. Status = GetVolumeNodeNumber(pPinInstance, NULL);
  613. if(!NT_SUCCESS(Status)) {
  614. Trap();
  615. goto exit;
  616. }
  617. if(pPinInstance->ulVolumeNodeNumber == MAXULONG) {
  618. DPF(5, "GetPinVolumeNode: no volume node found");
  619. Status = STATUS_INVALID_DEVICE_REQUEST;
  620. goto exit;
  621. }
  622. *pulNode = pPinInstance->ulVolumeNodeNumber;
  623. pIrp->IoStatus.Information = sizeof(ULONG);
  624. exit:
  625. return(Status);
  626. }
  627. NTSTATUS
  628. AddRemoveGfx(
  629. IN PIRP,
  630. IN PKSPROPERTY pProperty,
  631. IN PSYSAUDIO_GFX pSysaudioGfx
  632. )
  633. {
  634. NTSTATUS Status;
  635. if(pSysaudioGfx->Enable) {
  636. Status = AddGfx(pSysaudioGfx);
  637. }
  638. else {
  639. Status = RemoveGfx(pSysaudioGfx);
  640. }
  641. return(Status);
  642. }