Exemple #1
0
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;
}