NTSTATUS SpPagingPathNotificationCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP LowerIrp, IN PDEVICE_OBJECT Fdo ) { PIRP upperIrp = LowerIrp->AssociatedIrp.MasterIrp; PIO_STACK_LOCATION lowerStack = IoGetCurrentIrpStackLocation(LowerIrp); PIO_STACK_LOCATION upperStack = IoGetCurrentIrpStackLocation(upperIrp); PDEVICE_OBJECT pdo = upperStack->DeviceObject; PADAPTER_EXTENSION lowerExtension; PLOGICAL_UNIT_EXTENSION upperExtension; ASSERT(Fdo != NULL); ASSERT(pdo != NULL); DebugPrint((1, "Completion - IRP_MN_DEVICE_USAGE_NOTIFICATION: Completion of " "paging notification irp %#p sent due to irp %#p\n", LowerIrp, upperIrp)); lowerExtension = (PADAPTER_EXTENSION) Fdo->DeviceExtension; upperExtension = (PLOGICAL_UNIT_EXTENSION) pdo->DeviceExtension; ASSERT_FDO(lowerExtension->DeviceObject); ASSERT_PDO(upperExtension->DeviceObject); DebugPrint((1, "Completion - IRP_MN_DEVICE_USAGE_NOTIFICATION: irp status %#08lx\n", LowerIrp->IoStatus.Status)); if(NT_SUCCESS(LowerIrp->IoStatus.Status)) { PUCHAR typeName = "INSERT TYPE HERE"; PULONG lowerCount; PULONG upperCount; // // The parameters have already been erased from the lower irp stack // location - use the parameters from the upper once since they're // just a copy. // switch(upperStack->Parameters.UsageNotification.Type) { case DeviceUsageTypePaging: { lowerCount = &(lowerExtension->CommonExtension.PagingPathCount); upperCount = &(upperExtension->CommonExtension.PagingPathCount); typeName = "PagingPathCount"; break; } case DeviceUsageTypeHibernation: { lowerCount = &(lowerExtension->CommonExtension.HibernatePathCount); upperCount = &(upperExtension->CommonExtension.HibernatePathCount); typeName = "HibernatePathCount"; break; } case DeviceUsageTypeDumpFile: { lowerCount = &(lowerExtension->CommonExtension.DumpPathCount); upperCount = &(upperExtension->CommonExtension.DumpPathCount); typeName = "DumpPathCount"; break; } default: { typeName = "unknown type"; lowerCount = upperCount = NULL; break; } } if(lowerCount != NULL) { IoAdjustPagingPathCount( lowerCount, upperStack->Parameters.UsageNotification.InPath ); DebugPrint((1, "Completion - IRP_MN_DEVICE_USAGE_NOTIFICATION: " "Fdo %s count - %d\n", typeName, *lowerCount)); IoInvalidateDeviceState(lowerExtension->LowerPdo); } if(upperCount != NULL) { IoAdjustPagingPathCount( upperCount, upperStack->Parameters.UsageNotification.InPath ); DebugPrint((1, "Completion - IRP_MN_DEVICE_USAGE_NOTIFICATION: " "Pdo %s count - %d\n", typeName, *upperCount)); IoInvalidateDeviceState(upperExtension->DeviceObject); } } upperIrp->IoStatus = LowerIrp->IoStatus; SpReleaseRemoveLock(lowerExtension->CommonExtension.DeviceObject, LowerIrp); SpReleaseRemoveLock(upperExtension->CommonExtension.DeviceObject, upperIrp); IoMarkIrpPending(upperIrp); SpCompleteRequest(upperExtension->CommonExtension.DeviceObject, upperIrp, NULL, IO_NO_INCREMENT); IoFreeIrp(LowerIrp); return STATUS_MORE_PROCESSING_REQUIRED; }
NTSTATUS bus_unplug_dev ( int addr, PFDO_DEVICE_DATA fdodata ) { PLIST_ENTRY entry; PPDO_DEVICE_DATA pdodata; int found=0, all; PAGED_CODE (); if(addr<0||addr>127) return STATUS_INVALID_PARAMETER; all = (0 == addr); ExAcquireFastMutex (&fdodata->Mutex); if (all) { Bus_KdPrint (fdodata, BUS_DBG_IOCTL_NOISE, ("Plugging out all the devices!\n")); } else { Bus_KdPrint (fdodata, BUS_DBG_IOCTL_NOISE, ("Plugging out %d\n", addr)); } if (fdodata->NumPDOs == 0) { // // We got a 2nd plugout...somebody in user space isn't playing nice!!! // Bus_KdPrint (fdodata, BUS_DBG_IOCTL_ERROR, ("BAD BAD BAD...2 removes!!! Send only one!\n")); ExReleaseFastMutex (&fdodata->Mutex); return STATUS_NO_SUCH_DEVICE; } for (entry = fdodata->ListOfPDOs.Flink; entry != &fdodata->ListOfPDOs; entry = entry->Flink) { pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); Bus_KdPrint (fdodata, BUS_DBG_IOCTL_NOISE, ("found device %d\n", pdodata->SerialNo)); if (all || addr == pdodata->SerialNo) { Bus_KdPrint (fdodata, BUS_DBG_IOCTL_INFO, ("Plugging out %d\n", pdodata->SerialNo)); pdodata->Present = FALSE; complete_pending_read_irp(pdodata); found = 1; if (!all) { break; } } } ExReleaseFastMutex (&fdodata->Mutex); if (found) { IoInvalidateDeviceRelations (fdodata->UnderlyingPDO, BusRelations); ExAcquireFastMutex (&fdodata->Mutex); for (entry = fdodata->ListOfPDOs.Flink; entry != &fdodata->ListOfPDOs; entry = entry->Flink) { pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); if( pdodata->Present ==FALSE){ complete_pending_irp(pdodata); SET_NEW_PNP_STATE(pdodata,PNP_DEVICE_REMOVED); IoInvalidateDeviceState(pdodata->Self); } } ExReleaseFastMutex (&fdodata->Mutex); Bus_KdPrint (fdodata, BUS_DBG_IOCTL_ERROR, ("Device %d plug out finished\n", addr)); return STATUS_SUCCESS; } return STATUS_INVALID_PARAMETER; }