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.

1087 lines
25 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. SERVICE.C
  5. Abstract:
  6. Services provided to the DBC port driver
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include <wdm.h>
  13. #include "stdarg.h"
  14. #include "stdio.h"
  15. #include "dbci.h"
  16. #include "dbclass.h"
  17. #include "dbfilter.h"
  18. #define DBCLASS
  19. #include "dbclib.h"
  20. #undef DBCLASS
  21. extern PDBC_CONTEXT DBCLASS_ControllerList;
  22. extern KSPIN_LOCK DBCLASS_ControllerListSpin;
  23. extern LIST_ENTRY DBCLASS_DevicePdoList;
  24. extern LIST_ENTRY DBCLASS_BusFilterMdoList;
  25. NTSTATUS
  26. DBCLASS_Initialize(
  27. )
  28. {
  29. // temp init code.
  30. static init = 0;
  31. if (init)
  32. {
  33. return STATUS_SUCCESS;
  34. }
  35. #if DBG
  36. DBCLASS_GetClassGlobalDebugRegistryParameters();
  37. BRK_ON_TRAP();
  38. #endif
  39. DBCLASS_KdPrint((1, "'Initailize DBC Class Driver\n"));
  40. #ifdef DEBUG_LOG
  41. //
  42. // Initialize our debug trace log
  43. //
  44. DBCLASS_LogInit();
  45. #endif
  46. DBCLASS_ControllerList = NULL;
  47. KeInitializeSpinLock(&DBCLASS_ControllerListSpin);
  48. InitializeListHead(&DBCLASS_DevicePdoList);
  49. InitializeListHead(&DBCLASS_BusFilterMdoList);
  50. init = 1;
  51. return STATUS_SUCCESS;
  52. }
  53. #if 0
  54. __declspec(dllexport)
  55. NTSTATUS
  56. DllInitialize(
  57. IN PUNICODE_STRING RegistryPath
  58. )
  59. {
  60. TEST_TRAP();
  61. return STATUS_SUCCESS;
  62. }
  63. #endif
  64. NTSTATUS
  65. DriverEntry(
  66. IN PDRIVER_OBJECT DriverObject,
  67. IN PUNICODE_STRING RegistryPath
  68. )
  69. /*++
  70. Routine Description:
  71. Installable driver initialization entry point.
  72. This entry point is called directly by the I/O system.
  73. Arguments:
  74. DriverObject - pointer to the driver object
  75. RegistryPath - pointer to a unicode string representing the path
  76. to driver-specific key in the registry
  77. Return Value:
  78. NT status code
  79. --*/
  80. {
  81. TEST_TRAP();
  82. return STATUS_SUCCESS;
  83. }
  84. NTSTATUS
  85. DBCLASS_RegisterController(
  86. IN ULONG DbclassVersion,
  87. IN PDEVICE_OBJECT ControllerFdo,
  88. IN PDEVICE_OBJECT TopOfPdoStack,
  89. IN PDEVICE_OBJECT ControllerPdo,
  90. IN ULONG ControllerSig
  91. )
  92. /*++
  93. Routine Description:
  94. This function registers a DBC with the class driver, the
  95. FDO of the DBC is passed in along with the PDO for the DBC.
  96. The class driver uses this information to locate the
  97. correct instances of the DB Class Driver FDOs.
  98. Arguments:
  99. Return Value:
  100. None
  101. --*/
  102. {
  103. PDBC_CONTEXT dbcContext;
  104. KIRQL irql;
  105. NTSTATUS ntStatus;
  106. #if DBG
  107. DBCLASS_GetClassGlobalDebugRegistryParameters();
  108. #endif
  109. DBCLASS_KdPrint((0, "'Class Registration\n"));
  110. LOGENTRY(LOG_MISC, 'REGc', ControllerFdo, 0, 0);
  111. // initialize here
  112. DBCLASS_Initialize();
  113. // search our list if we find the TopOfStack device
  114. // object then this must be a filter driver, otherwise
  115. // allocate a new context structure for this controller
  116. if (ControllerSig == DBC_OEM_FILTER_SIG)
  117. {
  118. KeAcquireSpinLock(&DBCLASS_ControllerListSpin, &irql);
  119. dbcContext = DBCLASS_ControllerList;
  120. while (dbcContext)
  121. {
  122. if (dbcContext->TopOfStack == TopOfPdoStack)
  123. {
  124. // we have a DBC filter, update our
  125. // TopOfStack DeviceObject so that
  126. // the filter gets called first
  127. DBCLASS_KdPrint((0, "'>Registering Filter\n"));
  128. dbcContext->TopOfStack = ControllerFdo;
  129. KeReleaseSpinLock(&DBCLASS_ControllerListSpin, irql);
  130. return STATUS_SUCCESS;
  131. }
  132. dbcContext = dbcContext->Next;
  133. }
  134. KeReleaseSpinLock(&DBCLASS_ControllerListSpin, irql);
  135. DBCLASS_KdPrint((0, "'>Register Filter, could not find controller?\n"));
  136. }
  137. else
  138. {
  139. // create a context structure for this controller
  140. DBCLASS_KdPrint((0, "'>Registering Controller\n"));
  141. KeAcquireSpinLock(&DBCLASS_ControllerListSpin, &irql);
  142. dbcContext = DbcExAllocatePool(NonPagedPool, sizeof(*dbcContext));
  143. if (dbcContext)
  144. {
  145. RtlZeroMemory(dbcContext, sizeof(*dbcContext));
  146. dbcContext->Sig = DBC_CONTEXT_SIG;
  147. dbcContext->Next = DBCLASS_ControllerList;
  148. DBCLASS_ControllerList = dbcContext;
  149. dbcContext->TopOfStack = ControllerFdo;
  150. dbcContext->ControllerFdo = ControllerFdo;
  151. // consider ourselves initially stopped
  152. dbcContext->Stopped = TRUE;
  153. dbcContext->ControllerSig = ControllerSig;
  154. dbcContext->ControllerPdo = ControllerPdo;
  155. dbcContext->TopOfPdoStack = TopOfPdoStack;
  156. DBCLASS_KdPrint((0, "'ControllerFdo (%08X) ControllerPdo (%08X) TopOfPdoStack (%08X) TopOfStack (%08X) DbcContext (%08X)\n",
  157. dbcContext->ControllerFdo, dbcContext->ControllerPdo, dbcContext->TopOfPdoStack, dbcContext->TopOfStack, dbcContext));
  158. ntStatus = STATUS_SUCCESS;
  159. }
  160. else
  161. {
  162. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  163. }
  164. KeReleaseSpinLock(&DBCLASS_ControllerListSpin, irql);
  165. }
  166. LOGENTRY(LOG_MISC, 'rEGc', ControllerFdo, ntStatus, 0);
  167. return ntStatus;
  168. }
  169. NTSTATUS
  170. DBCLASS_PortQDeviceRelationsComplete(
  171. IN PDEVICE_OBJECT DeviceObject,
  172. IN PIRP Irp,
  173. IN PVOID Context
  174. )
  175. /*++
  176. Routine Description:
  177. Arguments:
  178. DeviceObject - a pointer to the device object
  179. Irp - a pointer to the irp
  180. Context - NULL ptr
  181. Return Value:
  182. STATUS_SUCCESS
  183. --*/
  184. {
  185. PDBC_CONTEXT dbcContext = Context;
  186. PIO_STACK_LOCATION irpStack;
  187. PDEVICE_RELATIONS oldList, newList;
  188. PDEVICE_EXTENSION deviceExtension;
  189. ULONG pdoCount, i;
  190. // we are interested in REMOVAL_RELATIONS
  191. irpStack = IoGetCurrentIrpStackLocation (Irp);
  192. DBCLASS_ASSERT(IRP_MJ_PNP == irpStack->MajorFunction);
  193. DBCLASS_ASSERT(IRP_MN_QUERY_DEVICE_RELATIONS == irpStack->MinorFunction);
  194. switch (irpStack->Parameters.QueryDeviceRelations.Type)
  195. {
  196. case RemovalRelations:
  197. //
  198. // Add the PDOs for the device bay devices to the list
  199. //
  200. oldList = (PDEVICE_RELATIONS) Irp->IoStatus.Information;
  201. newList = NULL;
  202. if (oldList)
  203. {
  204. pdoCount = oldList->Count;
  205. }
  206. else
  207. {
  208. // empty list
  209. pdoCount = 0;
  210. }
  211. //
  212. // count our PDOs
  213. //
  214. for (i=1; i<=NUMBER_OF_BAYS(dbcContext); i++)
  215. {
  216. if (dbcContext->BayInformation[i].DeviceFilterObject)
  217. {
  218. pdoCount++;
  219. }
  220. }
  221. if (pdoCount)
  222. {
  223. newList = ExAllocatePoolWithTag(PagedPool, sizeof(*newList) +
  224. (pdoCount - 1) * sizeof(PDEVICE_OBJECT), DBC_TAG);
  225. }
  226. if (newList)
  227. {
  228. newList->Count = pdoCount = 0;
  229. // add the old list to the new list
  230. if (oldList)
  231. {
  232. for (i=0; i< oldList->Count; i++)
  233. {
  234. newList->Objects[pdoCount] = oldList->Objects[i];
  235. newList->Count++;
  236. pdoCount++;
  237. }
  238. }
  239. // free the old list
  240. ExFreePool(oldList);
  241. // add our PDOs to the list;
  242. for (i=1; i<=NUMBER_OF_BAYS(dbcContext); i++)
  243. {
  244. if (dbcContext->BayInformation[i].DeviceFilterObject)
  245. {
  246. deviceExtension =
  247. dbcContext->BayInformation[i].DeviceFilterObject->DeviceExtension;
  248. newList->Objects[pdoCount] =
  249. deviceExtension->PhysicalDeviceObject;
  250. pdoCount++;
  251. newList->Count++;
  252. }
  253. }
  254. Irp->IoStatus.Information = PtrToUlong(newList);
  255. }
  256. break;
  257. default:
  258. break;
  259. }
  260. return STATUS_SUCCESS;
  261. }
  262. NTSTATUS
  263. DBCLASS_UnRegisterController(
  264. IN PDEVICE_OBJECT ControllerFdo,
  265. IN PDEVICE_OBJECT TopOfStack
  266. )
  267. /*++
  268. Routine Description:
  269. Arguments:
  270. Return Value:
  271. None
  272. --*/
  273. {
  274. // locate which instance of the class driver is associated
  275. // with this DBC.
  276. PDBC_CONTEXT dbcContext = NULL;
  277. PDBC_CONTEXT prev = NULL;
  278. prev = dbcContext = DBCLASS_ControllerList;
  279. while (dbcContext)
  280. {
  281. if (dbcContext->ControllerFdo == ControllerFdo)
  282. {
  283. // remove controller
  284. DBCLASS_KdPrint((0, "'>UnRegister Controller\n"));
  285. DBCLASS_KdPrint((0, "'ControllerFdo (%08X) ControllerPdo (%08X) TopOfPdoStack (%08X) TopOfStack (%08X) FilterMDOUSB (%08X) DbcContext (%08X)\n",
  286. dbcContext->ControllerFdo, dbcContext->ControllerPdo, dbcContext->TopOfPdoStack, dbcContext->TopOfStack, dbcContext->BusFilterMdoUSB, dbcContext));
  287. // unlink
  288. if (DBCLASS_ControllerList == dbcContext)
  289. {
  290. DBCLASS_ControllerList = dbcContext->Next;
  291. }
  292. else
  293. {
  294. DBCLASS_ASSERT(prev->Next == dbcContext);
  295. prev->Next = dbcContext->Next;
  296. }
  297. DBCLASS_RemoveControllerFromMdo(dbcContext);
  298. DbcExFreePool(dbcContext);
  299. break;
  300. }
  301. prev = dbcContext;
  302. dbcContext = dbcContext->Next;
  303. }
  304. LOGENTRY(LOG_MISC, 'UNRc', dbcContext, 0, 0);
  305. #if DBG
  306. if (dbcContext == NULL)
  307. {
  308. DBCLASS_KdPrint((0, "'Controller not Found\n"));
  309. TRAP();
  310. }
  311. #endif
  312. return STATUS_SUCCESS;
  313. }
  314. NTSTATUS
  315. DBCLASS_ClassDispatch(
  316. IN PDEVICE_OBJECT ControllerFdo,
  317. IN PIRP Irp,
  318. IN PBOOLEAN HandledByClass
  319. )
  320. /*++
  321. Routine Description:
  322. Arguments:
  323. Return Value:
  324. None
  325. --*/
  326. {
  327. PIO_STACK_LOCATION irpStack;
  328. NTSTATUS ntStatus;
  329. PDBC_CONTEXT dbcContext;
  330. *HandledByClass = FALSE;
  331. dbcContext = DBCLASS_GetDbcContext(ControllerFdo);
  332. LOGENTRY(LOG_MISC, 'dIRP', ControllerFdo, 0, Irp);
  333. if (dbcContext == NULL)
  334. {
  335. DBCLASS_KdPrint((0, "'Invalid ControllerFdo passed in\n"));
  336. TRAP();
  337. ntStatus = STATUS_INVALID_PARAMETER;
  338. *HandledByClass = TRUE;
  339. goto DBCLASS_Dispatch_Done;
  340. }
  341. ntStatus = Irp->IoStatus.Status;
  342. irpStack = IoGetCurrentIrpStackLocation (Irp);
  343. switch (irpStack->MajorFunction)
  344. {
  345. case IRP_MJ_POWER:
  346. ntStatus = DBCLASS_ClassPower(ControllerFdo,
  347. Irp,
  348. HandledByClass);
  349. goto DBCLASS_Dispatch_Exit;
  350. break; /* IRP_MJ_POWER */
  351. case IRP_MJ_PNP:
  352. switch (irpStack->MinorFunction)
  353. {
  354. case IRP_MN_QUERY_DEVICE_RELATIONS:
  355. // handle Q_BUS_RELATIONS for the port driver
  356. *HandledByClass = TRUE;
  357. // hook the completion and pass on
  358. IoCopyCurrentIrpStackLocationToNext(Irp);
  359. IoSetCompletionRoutine(Irp,
  360. DBCLASS_PortQDeviceRelationsComplete,
  361. dbcContext,
  362. TRUE,
  363. TRUE,
  364. TRUE);
  365. ntStatus = IoCallDriver(dbcContext->TopOfStack, Irp);
  366. // we did the calldown for the port driver so
  367. // all we do now is exit
  368. goto DBCLASS_Dispatch_Exit;
  369. break;
  370. case IRP_MN_START_DEVICE:
  371. DBCLASS_KdPrint((1, "'IRP_MN_START_DEVICE\n"));
  372. ntStatus = DBCLASS_StartController(dbcContext,
  373. Irp,
  374. HandledByClass);
  375. break;
  376. #if 0
  377. case IRP_MN_QUERY_STOP_DEVICE:
  378. case IRP_MN_QUERY_REMOVE_DEVICE:
  379. #if DBG
  380. if (irpStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) {
  381. DBCLASS_KdPrint((1, "'IRP_MN_QUERY_REMOVE_DEVICE\n"));
  382. } else {
  383. DBCLASS_KdPrint((1, "'IRP_MN_QUERY_STOP_DEVICE\n"));
  384. }
  385. #endif
  386. // would like to eject the devices at this
  387. // point -- instead I will fail if we have devices in
  388. // the bays!
  389. {
  390. BOOLEAN empty = TRUE;
  391. USHORT bay;
  392. for (bay=1; bay <=NUMBER_OF_BAYS(dbcContext); bay++)
  393. {
  394. if (dbcContext->BayInformation[bay].DeviceFilterObject !=
  395. NULL)
  396. {
  397. empty = FALSE;
  398. break;
  399. }
  400. }
  401. if (!empty)
  402. {
  403. *HandledByClass = TRUE;
  404. ntStatus = STATUS_UNSUCCESSFUL;
  405. DBCLASS_KdPrint((1, "'Bays not Empty!"));
  406. goto DBCLASS_Dispatch_Done;
  407. }
  408. }
  409. break;
  410. #endif
  411. case IRP_MN_STOP_DEVICE:
  412. DBCLASS_KdPrint((1, "'IRP_MN_STOP_DEVICE\n"));
  413. ntStatus = DBCLASS_StopController(dbcContext,
  414. Irp,
  415. HandledByClass);
  416. if (NT_SUCCESS(ntStatus))
  417. {
  418. // free allocated resources
  419. ntStatus = DBCLASS_CleanupController(dbcContext);
  420. }
  421. dbcContext->Stopped = TRUE;
  422. LOGENTRY(LOG_MISC, 'STPd', dbcContext, 0, ntStatus);
  423. break;
  424. case IRP_MN_REMOVE_DEVICE:
  425. DBCLASS_KdPrint((1, "'IRP_MN_REMOVE_DEVICE\n"));
  426. DBCLASS_KdPrint((1, "'FDO (%08X)\n", ControllerFdo));
  427. if (!dbcContext->Stopped)
  428. {
  429. ntStatus = DBCLASS_StopController(dbcContext,
  430. Irp,
  431. HandledByClass);
  432. if (NT_SUCCESS(ntStatus))
  433. {
  434. // free allocated resources
  435. ntStatus = DBCLASS_CleanupController(dbcContext);
  436. }
  437. }
  438. else
  439. {
  440. ntStatus = STATUS_SUCCESS;
  441. }
  442. LOGENTRY(LOG_MISC, 'RMVd', dbcContext, 0, ntStatus);
  443. break;
  444. }
  445. break;
  446. case IRP_MJ_CREATE:
  447. case IRP_MJ_CLOSE:
  448. ntStatus = STATUS_SUCCESS;
  449. break;
  450. default:
  451. //
  452. // Irp is not interesting to us
  453. LOGENTRY(LOG_MISC, 'pIRP', ControllerFdo, 0, Irp);
  454. break;
  455. }; /* case MJ_FUNCTION */
  456. DBCLASS_Dispatch_Done:
  457. if (*HandledByClass)
  458. {
  459. DBCLASS_KdPrint((2, "'Completing Irp\n"));
  460. Irp->IoStatus.Status = ntStatus;
  461. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  462. }
  463. DBCLASS_Dispatch_Exit:
  464. return ntStatus;
  465. }
  466. NTSTATUS
  467. DBCLASS_FilterDispatch(
  468. PDEVICE_OBJECT DeviceObject,
  469. PIRP Irp
  470. )
  471. /*++
  472. Routine Description:
  473. figure out what type of FDO we are and dispatch to
  474. the appropriate handler
  475. Arguments:
  476. DeviceObject - Device bay Filter FDO
  477. Return Value:
  478. NTSTATUS
  479. --*/
  480. {
  481. PIO_STACK_LOCATION irpStack;
  482. NTSTATUS ntStatus;
  483. PDEVICE_EXTENSION deviceExtension;
  484. BOOLEAN handled = FALSE;
  485. PDEVICE_OBJECT topOfStackDeviceObject;
  486. ULONG MinFunc, MajFunc;
  487. deviceExtension = DeviceObject->DeviceExtension;
  488. topOfStackDeviceObject = deviceExtension->TopOfStackDeviceObject;
  489. LOGENTRY(LOG_MISC, 'FLT>', 0, DeviceObject, Irp);
  490. irpStack = IoGetCurrentIrpStackLocation(Irp);
  491. MinFunc = irpStack->MinorFunction;
  492. MajFunc = irpStack->MajorFunction;
  493. // figure out what kind of PDO this call is bound for
  494. switch(deviceExtension->FdoType)
  495. {
  496. case DB_FDO_BUS_IGNORE:
  497. break;
  498. case DB_FDO_BUS_UNKNOWN:
  499. ntStatus = DBCLASS_BusFilterDispatch(
  500. DeviceObject,
  501. Irp,
  502. &handled);
  503. break;
  504. case DB_FDO_USBHUB_BUS:
  505. ntStatus = DBCLASS_UsbhubBusFilterDispatch(
  506. DeviceObject,
  507. Irp,
  508. &handled);
  509. break;
  510. case DB_FDO_USB_DEVICE:
  511. case DB_FDO_1394_DEVICE:
  512. ntStatus = DBCLASS_PdoFilterDispatch(
  513. DeviceObject,
  514. Irp,
  515. &handled);
  516. break;
  517. case DB_FDO_1394_BUS:
  518. ntStatus = DBCLASS_1394BusFilterDispatch(
  519. DeviceObject,
  520. Irp,
  521. &handled);
  522. break;
  523. default:
  524. DBCLASS_KdPrint((0, "'Invalid Extension Signature"));
  525. TRAP();
  526. }
  527. if (!handled)
  528. {
  529. if(MajFunc == IRP_MJ_POWER)
  530. {
  531. PoStartNextPowerIrp(Irp);
  532. IoSkipCurrentIrpStackLocation(Irp);
  533. ntStatus = PoCallDriver(topOfStackDeviceObject, Irp);
  534. if(ntStatus)
  535. {
  536. DBCLASS_KdPrint((2, "'Filter Power Dispatch Status (%08X)\n", ntStatus));
  537. }
  538. }
  539. else
  540. {
  541. // all filters behave pretty much the same
  542. // if the routine we called did not want to
  543. // handle the IRP we take the default action
  544. // here.
  545. IoSkipCurrentIrpStackLocation(Irp);
  546. ntStatus = IoCallDriver(topOfStackDeviceObject, Irp);
  547. if(ntStatus)
  548. {
  549. DBCLASS_KdPrint((2, "'Filter Dispatch Status (%08X)\n", ntStatus));
  550. }
  551. }
  552. }
  553. LOGENTRY(LOG_MISC, 'PNP<', ntStatus, DeviceObject, 0);
  554. return ntStatus;
  555. }
  556. #if 0
  557. NTSTATUS
  558. DBCLASS_SetD0_Complete(
  559. PDEVICE_OBJECT ControllerFdo,
  560. PIRP Irp
  561. )
  562. /*++
  563. Routine Description:
  564. Called by port driver when the port driver
  565. enters D0.
  566. Arguments:
  567. DeviceObject - Device bay Filter FDO
  568. Return Value:
  569. NTSTATUS
  570. --*/
  571. {
  572. PIO_STACK_LOCATION irpStack;
  573. NTSTATUS ntStatus = STATUS_SUCCESS;
  574. PDBC_CONTEXT dbcContext;
  575. LOGENTRY(LOG_MISC, 'D0cp', 0, ControllerFdo, Irp);
  576. irpStack = IoGetCurrentIrpStackLocation(Irp);
  577. dbcContext = DBCLASS_GetDbcContext(ControllerFdo);
  578. DBCLASS_KdPrint((0, "'Set DevicePowerState = D0\n"));
  579. dbcContext->CurrentDevicePowerState = PowerDeviceD0;
  580. return ntStatus;
  581. }
  582. #endif
  583. NTSTATUS
  584. DBCLASS_RegisterBusFilter(
  585. ULONG DbclassVersion,
  586. PDRIVER_OBJECT FilterDriverObject,
  587. PDEVICE_OBJECT FilterMdo
  588. )
  589. /*++
  590. Routine Description:
  591. find the controller for this PDO and associate the
  592. PDO with the correct bay
  593. Arguments:
  594. Return Value:
  595. NTSTATUS
  596. --*/
  597. {
  598. PDEVICE_EXTENSION deviceExtension;
  599. NTSTATUS ntStatus = STATUS_SUCCESS;
  600. deviceExtension = FilterMdo->DeviceExtension;
  601. // initialize here
  602. DBCLASS_Initialize();
  603. LOGENTRY(LOG_MISC, 'rPDO', 0, FilterMdo, 0);
  604. DBCLASS_KdPrint((0, "'Register Bus Filter FDO(%x)\n", FilterMdo));
  605. // The bus filter handle one instance of the 1394 bus --
  606. // which may have multiple DBCs associated with it.
  607. // therefore we don't use the Context field in the bus filter
  608. // extension
  609. deviceExtension->DbcContext = (PDBC_CONTEXT) -1;
  610. // Put the filter MDO on our list of bus filters
  611. DBCLASS_AddBusFilterMDOToList(FilterMdo);
  612. return ntStatus;
  613. }
  614. NTSTATUS
  615. DBCLASS_AddBusFilterMDOToList(
  616. PDEVICE_OBJECT BusFilterMdo
  617. )
  618. /*++
  619. Routine Description:
  620. Adds a bus filter to our internal list
  621. Arguments:
  622. Return Value:
  623. NTSTATUS
  624. --*/
  625. {
  626. PDBCLASS_PDO_LIST newEntry;
  627. newEntry = ExAllocatePool(NonPagedPool, sizeof(DBCLASS_PDO_LIST));
  628. DBCLASS_ASSERT(newEntry);
  629. if (newEntry == NULL)
  630. {
  631. TRAP();
  632. return STATUS_INSUFFICIENT_RESOURCES;
  633. }
  634. // Fill in fields in new entry
  635. newEntry->FilterDeviceObject = BusFilterMdo;
  636. // Add new entry to end of list
  637. InsertTailList(&DBCLASS_BusFilterMdoList, &newEntry->ListEntry);
  638. DBCLASS_KdPrint((2, "'AddBusFilterMdo (%08X)\n", BusFilterMdo));
  639. return STATUS_SUCCESS;
  640. }
  641. VOID
  642. DBCLASS_RemoveBusFilterMDOFromList(
  643. IN PDEVICE_OBJECT BusFilterMdo
  644. )
  645. /*++
  646. Routine Description:
  647. Removes a bus filter from the internal list
  648. Arguments:
  649. BusFilterMdo - a pointer to the device object to remove.
  650. Return Value:
  651. VOID
  652. --*/
  653. {
  654. PDBCLASS_PDO_LIST entry;
  655. PLIST_ENTRY listEntry;
  656. listEntry = &DBCLASS_BusFilterMdoList;
  657. if (!IsListEmpty(listEntry))
  658. {
  659. listEntry = DBCLASS_BusFilterMdoList.Flink;
  660. }
  661. while (listEntry != &DBCLASS_BusFilterMdoList)
  662. {
  663. entry = CONTAINING_RECORD(listEntry,
  664. DBCLASS_PDO_LIST,
  665. ListEntry);
  666. DBCLASS_ASSERT(entry);
  667. if (entry->FilterDeviceObject == BusFilterMdo)
  668. break;
  669. listEntry = entry->ListEntry.Flink;
  670. }
  671. // we should always find it
  672. DBCLASS_ASSERT(listEntry != &DBCLASS_BusFilterMdoList);
  673. DBCLASS_KdPrint((2, "'RemoveBusFilterMdo (%08X)\n", BusFilterMdo));
  674. RemoveEntryList(listEntry);
  675. ExFreePool(entry);
  676. }
  677. VOID
  678. DBCLASS_Refresh1394(
  679. )
  680. /*++
  681. Routine Description:
  682. Removes a bus filter from the internal list
  683. Arguments:
  684. DeviceObject - a pointer to the device object to remove.
  685. Return Value:
  686. VOID
  687. --*/
  688. {
  689. PDBCLASS_PDO_LIST entry;
  690. PLIST_ENTRY listEntry;
  691. PDEVICE_EXTENSION busFilterDeviceExtension;
  692. PDEVICE_OBJECT FilterDevObj;
  693. listEntry = &DBCLASS_BusFilterMdoList;
  694. if (!IsListEmpty(listEntry)) {
  695. listEntry = DBCLASS_BusFilterMdoList.Flink;
  696. }
  697. while (listEntry != &DBCLASS_BusFilterMdoList)
  698. {
  699. entry = CONTAINING_RECORD(listEntry,
  700. DBCLASS_PDO_LIST,
  701. ListEntry);
  702. DBCLASS_ASSERT(entry);
  703. FilterDevObj = entry->FilterDeviceObject;
  704. DBCLASS_KdPrint((2, "'Refresh1394 Entry (%08X) FilterDevObj (%08X)\n", entry, FilterDevObj));
  705. if(FilterDevObj)
  706. {
  707. busFilterDeviceExtension =
  708. FilterDevObj->DeviceExtension;
  709. if(busFilterDeviceExtension)
  710. {
  711. if (busFilterDeviceExtension->FdoType == DB_FDO_1394_BUS)
  712. {
  713. DBCLASS_KdPrint((0, "'IoInvalidate 1394\n"));
  714. IoInvalidateDeviceRelations(busFilterDeviceExtension->PhysicalDeviceObject,
  715. BusRelations);
  716. }
  717. }
  718. }
  719. listEntry = entry->ListEntry.Flink;
  720. }
  721. }
  722. VOID
  723. DBCLASS_RemoveControllerFromMdo(PDBC_CONTEXT DbcContext)
  724. /*++
  725. Routine Description:
  726. Removes reference to USB controller from a filter
  727. Return Value:
  728. VOID
  729. --*/
  730. {
  731. PDBCLASS_PDO_LIST entry;
  732. PLIST_ENTRY listEntry;
  733. PDEVICE_EXTENSION busFilterDeviceExtension;
  734. PDEVICE_OBJECT FilterDevObj;
  735. listEntry = &DBCLASS_DevicePdoList;
  736. if (!IsListEmpty(listEntry))
  737. {
  738. listEntry = DBCLASS_DevicePdoList.Flink;
  739. }
  740. while (listEntry != &DBCLASS_DevicePdoList)
  741. {
  742. entry = CONTAINING_RECORD(listEntry,
  743. DBCLASS_PDO_LIST,
  744. ListEntry);
  745. DBCLASS_ASSERT(entry);
  746. FilterDevObj = entry->FilterDeviceObject;
  747. if(FilterDevObj)
  748. {
  749. busFilterDeviceExtension =
  750. FilterDevObj->DeviceExtension;
  751. if(busFilterDeviceExtension)
  752. {
  753. if (busFilterDeviceExtension->DbcContext == DbcContext)
  754. {
  755. DBCLASS_KdPrint((2, "'Remove Controller From FilterDevObj (%08X)\n", FilterDevObj));
  756. busFilterDeviceExtension->DbcContext = NULL;
  757. }
  758. }
  759. }
  760. listEntry = entry->ListEntry.Flink;
  761. }
  762. }
  763.