Beispiel #1
0
static DECLSPEC_NOINLINE NTSTATUS
PdoRemoveDevice(
    IN  PXENFILT_PDO    Pdo,
    IN  PIRP            Irp
    )
{
    PXENFILT_FDO        Fdo = __PdoGetFdo(Pdo);
    POWER_STATE         PowerState;
    NTSTATUS            status;

    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
    if (!NT_SUCCESS(status))
        goto fail1;

    if (__PdoGetDevicePowerState(Pdo) != PowerDeviceD0)
        goto done;

    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);

    PowerState.DeviceState = PowerDeviceD3;
    PoSetPowerState(Pdo->Dx->DeviceObject,
                    DevicePowerState,
                    PowerState);

done:
    if (__PdoIsMissing(Pdo)) {
        __PdoSetDevicePnpState(Pdo, Deleted);
        IoReleaseRemoveLockAndWait(&Pdo->Dx->RemoveLock, Irp);
    } else {
        __PdoSetDevicePnpState(Pdo, Enumerated);
        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
    }

    status = PdoForwardIrpSynchronously(Pdo, Irp);
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    if (__PdoIsMissing(Pdo)) {
        FdoAcquireMutex(Fdo);
        PdoDestroy(Pdo);
        FdoReleaseMutex(Fdo);
    }

    return status;

fail1:
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}
Beispiel #2
0
NTSTATUS VBoxDrvAddDevice(IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO)
{
    NTSTATUS rc;
    PDEVICE_OBJECT pDO, pDOParent;
    PVBOXMOUSE_DEVEXT pDevExt;

    PAGED_CODE();
    LOGF_ENTER();

    rc = IoCreateDevice(Driver, sizeof(VBOXMOUSE_DEVEXT), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &pDO);
    if (!NT_SUCCESS(rc))
    {
        WARN(("IoCreateDevice failed with %#x", rc));
        return rc;
    }

    pDevExt = (PVBOXMOUSE_DEVEXT) pDO->DeviceExtension;
    RtlZeroMemory(pDevExt, sizeof(VBOXMOUSE_DEVEXT));

    IoInitializeRemoveLock(&pDevExt->RemoveLock, VBOXUSB_RLTAG, 1, 100);

    rc = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
    if (!NT_SUCCESS(rc))
    {
        WARN(("IoAcquireRemoveLock failed with %#x", rc));
        IoDeleteDevice(pDO);
        return rc;
    }

    pDOParent = IoAttachDeviceToDeviceStack(pDO, PDO);
    if (!pDOParent)
    {
        IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);

        WARN(("IoAttachDeviceToDeviceStack failed"));
        IoDeleteDevice(pDO);
        return STATUS_DEVICE_NOT_CONNECTED;
    }

    pDevExt->pdoMain   = PDO;
    pDevExt->pdoSelf   = pDO;
    pDevExt->pdoParent = pDOParent;

    VBoxDeviceAdded(pDevExt);

    pDO->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    pDO->Flags &= ~DO_DEVICE_INITIALIZING;

    LOGF_LEAVE();
    return rc;
}
Beispiel #3
0
static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp)
{
	NTSTATUS status;

	status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp);
	if (!NT_SUCCESS (status))
		return TCCompleteIrp (Irp, status, 0);

	switch (irpSp->MinorFunction)
	{
	case IRP_MN_START_DEVICE:
		Dump ("IRP_MN_START_DEVICE volume pdo=%p\n", Extension->Pdo);
		return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnStartDeviceCompleted, Extension);

	case IRP_MN_DEVICE_USAGE_NOTIFICATION:
		{
			PDEVICE_OBJECT attachedDevice = IoGetAttachedDeviceReference (DeviceObject);

			if (attachedDevice == DeviceObject || (attachedDevice->Flags & DO_POWER_PAGABLE))
				DeviceObject->Flags |= DO_POWER_PAGABLE;

			ObDereferenceObject (attachedDevice);
		}

		return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnDeviceUsageNotificationCompleted, Extension);


	case IRP_MN_REMOVE_DEVICE:
		Dump ("IRP_MN_REMOVE_DEVICE volume pdo=%p\n", Extension->Pdo);

		IoReleaseRemoveLockAndWait (&Extension->Queue.RemoveLock, Irp);
		status = PassIrp (Extension->LowerDeviceObject, Irp);

		IoDetachDevice (Extension->LowerDeviceObject);

		IoDeleteDevice (DeviceObject);
		return status;

	default:
		status = PassIrp (Extension->LowerDeviceObject, Irp);
		IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp);
	}

	return status;
}
Beispiel #4
0
NTSTATUS VBoxIrpPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION pStack;
    PVBOXMOUSE_DEVEXT pDevExt;
    NTSTATUS rc;
    LOGF_ENTER();

    pStack = IoGetCurrentIrpStackLocation(Irp);
    pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;

    switch (pStack->MinorFunction)
    {
        case IRP_MN_REMOVE_DEVICE:
        {
            LOGF(("IRP_MN_REMOVE_DEVICE"));

            IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);

            VBoxDeviceRemoved(pDevExt);

            Irp->IoStatus.Status = STATUS_SUCCESS;
            rc = VBoxIrpPassthrough(DeviceObject, Irp);

            IoDetachDevice(pDevExt->pdoParent);
            IoDeleteDevice(DeviceObject);
            break;
        }
        default:
        {
            rc = VBoxIrpPassthrough(DeviceObject, Irp);
            break;
        }
    }

    if (!NT_SUCCESS(rc) && rc != STATUS_NOT_SUPPORTED)
    {
        WARN(("rc=%#x", rc));
    }

    LOGF_LEAVE();
    return rc;
}
Beispiel #5
0
VOID USBPcapDeleteRootHubControlDevice(IN PDEVICE_OBJECT controlDevice)
{
    UNICODE_STRING     symbolicLinkName;
    PWCHAR             symbolicNameBuffer[MAX_SYMBOLIC_LEN];
    USHORT             id;
    PDEVICE_EXTENSION  pDevExt;
    NTSTATUS           status;

    pDevExt = ((PDEVICE_EXTENSION)controlDevice->DeviceExtension);

    ASSERT(pDevExt->deviceMagic == USBPCAP_MAGIC_CONTROL);

    id = pDevExt->context.control.id;

    symbolicLinkName.Length = 0;
    symbolicLinkName.MaximumLength = MAX_SYMBOLIC_LEN;
    symbolicLinkName.Buffer = (PWSTR)symbolicNameBuffer;

    status = RtlUnicodeStringPrintf(&symbolicLinkName,
                                    SYMBOLIC_PREFIX L"%hu", id);

    IoAcquireRemoveLock(&pDevExt->removeLock, NULL);
    IoReleaseRemoveLockAndWait(&pDevExt->removeLock, NULL);

    IoReleaseRemoveLock(pDevExt->parentRemoveLock, NULL);

    ASSERT(NT_SUCCESS(status));
    if (NT_SUCCESS(status))
    {
        IoDeleteSymbolicLink(&symbolicLinkName);
        IoDeleteDevice(controlDevice);
    }
    else
    {
        /* Very bad */
        KdPrint(("Failed to init symbolic link name\n"));

        pDevExt->context.control.pRootHubObject = NULL;
    }
}
Beispiel #6
0
NTSTATUS DkHubFltPnP(PDEVICE_EXTENSION pDevExt, PIO_STACK_LOCATION pStack, PIRP pIrp)
{
    NTSTATUS  ntStat = STATUS_SUCCESS;

    ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error lock!", ntStat);
        DkCompleteRequest(pIrp, ntStat, 0);
        return ntStat;
    }

    switch (pStack->MinorFunction)
    {
        case IRP_MN_START_DEVICE:
            DkDbgStr("IRP_MN_START_DEVICE");

            ntStat = DkForwardAndWait(pDevExt->pNextDevObj, pIrp);
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);
            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

            return ntStat;

        case IRP_MN_REMOVE_DEVICE:
        {
            PUSBPCAP_DEVICE_DATA pDeviceData = pDevExt->context.usb.pDeviceData;
            DkDbgStr("IRP_MN_REMOVE_DEVICE");

            IoSkipCurrentIrpStackLocation(pIrp);
            ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

            if (pDeviceData != NULL &&
                pDeviceData->pRootData != NULL &&
                pDeviceData->pRootData->controlDevice != NULL)
            {
                USBPcapDeleteRootHubControlDevice(pDeviceData->pRootData->controlDevice);
            }

            IoReleaseRemoveLockAndWait(&pDevExt->removeLock, (PVOID) pIrp);

            DkDetachAndDeleteHubFilt(pDevExt);

            return ntStat;
        }

        case IRP_MN_QUERY_DEVICE_RELATIONS:
            DkDbgStr("IRP_MN_QUERY_DEVICE_RELATIONS");
            ntStat = DkHubFltPnpHandleQryDevRels(pDevExt, pStack, pIrp);

            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
            return ntStat;

        default:
            DkDbgVal("", pStack->MinorFunction);
            break;

    }

    IoSkipCurrentIrpStackLocation(pIrp);
    ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

    IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

    return ntStat;
}
Beispiel #7
0
NTSTATUS DkTgtPnP(PDEVICE_EXTENSION pDevExt, PIO_STACK_LOCATION pStack, PIRP pIrp)
{
    NTSTATUS             ntStat = STATUS_SUCCESS;
    PUSBPCAP_DEVICE_DATA  pDeviceData = pDevExt->context.usb.pDeviceData;

    ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error lock!", ntStat);
        DkCompleteRequest(pIrp, ntStat, 0);
        return ntStat;
    }

    switch (pStack->MinorFunction)
    {
        case IRP_MN_START_DEVICE:
            /* IRP_MN_START_DEVICE is sent at PASSIVE_LEVEL */
            DkDbgStr("IRP_MN_START_DEVICE");

            ntStat = DkForwardAndWait(pDevExt->pNextDevObj, pIrp);
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);

            if (NT_SUCCESS(USBPcapGetDeviceUSBInfo(pDevExt)))
            {
                DkDbgVal("Started device", pDeviceData->deviceAddress);
            }
            else
            {
                DkDbgStr("Failed to get info of started device");
            }
            IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
            return ntStat;

        case IRP_MN_QUERY_DEVICE_RELATIONS:
            /* Keep track of, and create child devices only for hubs.
             * Do not create child filters for composite devices.
             */
            if (pDeviceData->isHub == TRUE)
            {
                DkDbgStr("IRP_MN_QUERY_DEVICE_RELATIONS");
                ntStat = DkHubFltPnpHandleQryDevRels(pDevExt, pStack, pIrp);

                IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);
                return ntStat;
            }
            else
            {
                break;
            }

        case IRP_MN_REMOVE_DEVICE:
            DkDbgStr("IRP_MN_REMOVE_DEVICE");

            IoSkipCurrentIrpStackLocation(pIrp);
            ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

            IoReleaseRemoveLockAndWait(&pDevExt->removeLock, (PVOID) pIrp);

            DkDetachAndDeleteTgt(pDevExt);

            return ntStat;


        default:
            DkDbgVal("", pStack->MinorFunction);
            break;

    }

    IoSkipCurrentIrpStackLocation(pIrp);
    ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp);

    IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp);

    return ntStat;
}
//========================================================================================
// Function:	DispatchPnp
// Purpose:		
// Return Value:
//				NT status code
//========================================================================================
NTSTATUS
DispatchPnp (
	IN PDEVICE_OBJECT fido,		// fido - pointer to a device object.
	IN PIRP irp					// Irp - pointer to an I/O Request Packet.
	)
{
	PDEVICE_EXTENSION dx;
	PIO_STACK_LOCATION irpStack;
	NTSTATUS ntStatus = STATUS_SUCCESS;

	PAGED_CODE();

	dx = (PDEVICE_EXTENSION)fido->DeviceExtension;
	irpStack = IoGetCurrentIrpStackLocation(irp);

	//acquire remove lock
	ntStatus = IoAcquireRemoveLock(&dx->rmLock, irp);
	if (!NT_SUCCESS(ntStatus))
	{
		//complete irp if cannot acquire remove lock
		irp->IoStatus.Status=ntStatus;
		irp->IoStatus.Information=0;
		IoCompleteRequest(irp, IO_NO_INCREMENT);
		return ntStatus;
	}

	PnPMinorFunctionString(irpStack->MinorFunction);

	switch (irpStack->MinorFunction)
	{
	case IRP_MN_START_DEVICE:
		//The device is starting.
		//We cannot touch the device (send it any non pnp irps) until a
		//start device has been passed down to the lower drivers.
		IoCopyCurrentIrpStackLocationToNext(irp);
		IoSetCompletionRoutine(irp,
			(PIO_COMPLETION_ROUTINE)CompletionRoutineStartDevice,
			NULL,
			TRUE,
			TRUE,
			TRUE);

		return IoCallDriver(dx->lowerdo, irp);

	case IRP_MN_REMOVE_DEVICE:
		IoSkipCurrentIrpStackLocation(irp);
		ntStatus = IoCallDriver(dx->lowerdo, irp);
		IoReleaseRemoveLockAndWait(&dx->rmLock, irp);

		SET_NEW_PNP_STATE(dx, Deleted);
		IoDetachDevice(dx->lowerdo);
		IoDeleteDevice(fido);
		return ntStatus;

	case IRP_MN_QUERY_STOP_DEVICE:
		SET_NEW_PNP_STATE(dx, StopPending);
		break;

	case IRP_MN_CANCEL_STOP_DEVICE:
		//Check to see whether you have received cancel-stop
		//without first receiving a query-stop. This could happen if someone
		//above us fails a query-stop and passes down the subsequent
		//cancel-stop.
		if(dx->DevicePnPState == StopPending)
		{
			//We did receive a query-stop, so restore.
			RESTORE_PREVIOUS_PNP_STATE(dx);
		}
		//We must not fail this IRP.
		break;

	case IRP_MN_STOP_DEVICE:
		SET_NEW_PNP_STATE(dx, Stopped);
		break;

	case IRP_MN_QUERY_REMOVE_DEVICE:
		SET_NEW_PNP_STATE(dx, RemovePending);
		break;

	case IRP_MN_SURPRISE_REMOVAL:
		SET_NEW_PNP_STATE(dx, SurpriseRemovePending);
		break;

	case IRP_MN_CANCEL_REMOVE_DEVICE:
		//Check to see whether you have received cancel-remove
		//without first receiving a query-remove. This could happen if
		//someone above us fails a query-remove and passes down the
		//subsequent cancel-remove.
		if(dx->DevicePnPState == RemovePending)
		{
			//We did receive a query-remove, so restore.
			RESTORE_PREVIOUS_PNP_STATE(dx);
		}
		//We must not fail this IRP.
		break;

	case IRP_MN_DEVICE_USAGE_NOTIFICATION:
		//On the way down, pagable might become set. Mimic the driver
		//above us. If no one is above us, just set pagable.
		if ((fido->AttachedDevice == NULL) ||
			(fido->AttachedDevice->Flags & DO_POWER_PAGABLE))
		{
			fido->Flags |= DO_POWER_PAGABLE;
		}

		IoCopyCurrentIrpStackLocationToNext(irp);
		IoSetCompletionRoutine(irp,
			CompletionRoutineDevUsgNotify,
			NULL,
			TRUE,
			TRUE,
			TRUE);

		return IoCallDriver(dx->lowerdo, irp);

	default:
		break;
	}

	IoSkipCurrentIrpStackLocation(irp);
	ntStatus = IoCallDriver(dx->lowerdo, irp);

	IoReleaseRemoveLock(&dx->rmLock, irp);
	return ntStatus;
}
Beispiel #9
0
// IRP_MJ_CREATE/IRP_MJ_CLOSE处理函数
NTSTATUS DispatchCreateClose(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
{
    PIO_STACK_LOCATION irpStack;
    NTSTATUS            status;
    PFILE_CONTEXT       fileContext;

    UNREFERENCED_PARAMETER(DeviceObject);

    PAGED_CODE();

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    ASSERT(irpStack->FileObject != NULL);    

    switch (irpStack->MajorFunction)
    {
	case IRP_MJ_CREATE:
		{
			DebugPrint(("IRP_MJ_CREATE\n"));

			fileContext = (PFILE_CONTEXT)ExAllocatePoolWithQuotaTag(
				NonPagedPool, 
				sizeof(FILE_CONTEXT),
				TAG);

			if (NULL == fileContext) 
			{
				status =  STATUS_INSUFFICIENT_RESOURCES;
				break;
			}

			IoInitializeRemoveLock(&fileContext->FileRundownLock, TAG, 0, 0);

			ASSERT(irpStack->FileObject->FsContext == NULL);
			irpStack->FileObject->FsContext = (PVOID) fileContext;

			status = STATUS_SUCCESS;
			break;
		}

	case IRP_MJ_CLOSE:
		{
			DebugPrint(("IRP_MJ_CLOSE\n"));

			fileContext = irpStack->FileObject->FsContext;
			IoAcquireRemoveLock(&fileContext->FileRundownLock, 0);
			IoReleaseRemoveLockAndWait(&fileContext->FileRundownLock, 0);

			ExFreePoolWithTag(fileContext, TAG);

			status = STATUS_SUCCESS;
			break;
		}

	default:
		ASSERT(FALSE);  // should never hit this
		status = STATUS_NOT_IMPLEMENTED;
		break;
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}
Beispiel #10
0
NTSTATUS
FPFilterDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PIO_STACK_LOCATION  irpSp = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS            status;
    PDEVICE_EXTENSION   pDevExt = DeviceObject->DeviceExtension;
    BOOLEAN				lockHeld;

    KdPrint(("LPCFILTER: FPFilterDispatchPnp: Device %X Irp %X\n", DeviceObject, Irp));

    //
    // Acquire the remove lock so that device will not be removed while
    // processing this irp.
    //
    status = IoAcquireRemoveLock(&pDevExt->RemoveLock, Irp);

    if (!NT_SUCCESS(status))
    {
        KdPrint(("LPCFILTER: FPFilterDispatchPnp: Remove lock failed PNP Irp type [%#02x]\n", irpSp->MinorFunction));
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    lockHeld		= TRUE;


    switch(irpSp->MinorFunction) 
	{
		case IRP_MN_QUERY_INTERFACE:
		{
            KdPrint(("LPCFILTER: FPFilterDispatchPnp: Schedule completion for QUERY_INTERFACE\n"));

			status = FPFilterForwardIrpSynchronous(DeviceObject, Irp);
			status = Irp->IoStatus.Status;
			IoCompleteRequest(Irp,IO_NO_INCREMENT);
			break;
		}
		case IRP_MN_QUERY_CAPABILITIES:
		{
            KdPrint(("LPCFILTER: FPFilterDispatchPnp: Sending on QUERY_CAPABILITIES\n"));
			status = FPFilterSendToNextDriver(DeviceObject, Irp);

			break;
		}

        case IRP_MN_START_DEVICE:
        {
			KdPrint(("LPCFILTER: FPFilterDispatchPnp: Sending on START_DEVICE\n"));
            status = FPFilterSendToNextDriver(DeviceObject, Irp);
	
            break;
        }

		case IRP_MN_STOP_DEVICE:
        {
			KdPrint(("LPCFILTER: FPFilterDispatchPnp: Sending on  STOP_DEVICE\n"));
            status = FPFilterSendToNextDriver(DeviceObject, Irp);

			// if this filter device is the one with an associated control device then stop the thread and tidy up
			if(pDevExt->pOtherExt != NULL)
			{
				pDevExt->pOtherExt->ThreadGo = FALSE;

				// wait for the thread to end
				if(pDevExt->pOtherExt->DispatcherThreadObject)
				{
					KeWaitForSingleObject(pDevExt->pOtherExt->DispatcherThreadObject, Executive, KernelMode, FALSE, NULL);
					ObDereferenceObject(pDevExt->pOtherExt->DispatcherThreadObject);
					pDevExt->pOtherExt->DispatcherThreadObject = NULL;
				}

				if(pDevExt->pOtherExt->pStats)
				{
					ExFreePool(pDevExt->pOtherExt->pStats);
					pDevExt->pOtherExt->pStats = NULL;
					pDevExt->pOtherExt->StatsDataSize = 0;
				}

				if(pDevExt->pOtherExt->pPCTData)
				{
					ExFreePool(pDevExt->pOtherExt->pPCTData);
					pDevExt->pOtherExt->pPCTData = NULL;
				}
	
				if(pDevExt->pOtherExt->pPSSData)
				{
					ExFreePool(pDevExt->pOtherExt->pPSSData);
					pDevExt->pOtherExt->pPSSData = NULL;
				}

				if(pDevExt->pOtherExt->pChildEnumData)
				{
					ExFreePool(pDevExt->pOtherExt->pChildEnumData);
					pDevExt->pOtherExt->pChildEnumData = NULL;
				}
				
				if(pDevExt->pOtherExt->pCPUDB)
				{
					ExFreePool(pDevExt->pOtherExt->pCPUDB);
					pDevExt->pOtherExt->pCPUDB = NULL;
				}

				pDevExt->pOtherExt->IsDataObtained = FALSE;
			}
            break;
        }

	    case IRP_MN_REMOVE_DEVICE:
        {
            //
            // Delete our device object(s) 
            //
            KdPrint(( "FPFilterDispatchPnp: Sending on  REMOVE_DEVICE\n"));
            status = FPFilterSendToNextDriver(DeviceObject, Irp);

			IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, Irp);

			IoDetachDevice(pDevExt->TargetDeviceObject);

			// if this filter device is the one with an associated control device then tidy up
			// stop the thread and delete that too device too
			if(pDevExt->pOtherExt != NULL)
			{
				pDevExt->pOtherExt->ThreadGo = FALSE;

				// wait for the thread to end
				if(pDevExt->pOtherExt->DispatcherThreadObject)
				{
					KeWaitForSingleObject(pDevExt->pOtherExt->DispatcherThreadObject, Executive, KernelMode, FALSE, NULL);
					ObDereferenceObject(pDevExt->pOtherExt->DispatcherThreadObject);
					pDevExt->pOtherExt->DispatcherThreadObject = NULL;
				}

				if(pDevExt->pOtherExt->pStats)
				{
					ExFreePool(pDevExt->pOtherExt->pStats);
					pDevExt->pOtherExt->pStats = NULL;
					pDevExt->pOtherExt->StatsDataSize = 0;
				}

				if(pDevExt->pOtherExt->pPCTData)
				{
					ExFreePool(pDevExt->pOtherExt->pPCTData);
					pDevExt->pOtherExt->pPCTData = NULL;
				}
	
				if(pDevExt->pOtherExt->pPSSData)
				{
					ExFreePool(pDevExt->pOtherExt->pPSSData);
					pDevExt->pOtherExt->pPSSData = NULL;
				}

				if(pDevExt->pOtherExt->pChildEnumData)
				{
					ExFreePool(pDevExt->pOtherExt->pChildEnumData);
					pDevExt->pOtherExt->pChildEnumData = NULL;
				}
				
				if(pDevExt->pOtherExt->pCPUDB)
				{
					ExFreePool(pDevExt->pOtherExt->pCPUDB);
					pDevExt->pOtherExt->pCPUDB = NULL;
				}

				IoDeleteSymbolicLink(&pDevExt->pOtherExt->linkName);

				IoDeleteDevice(pDevExt->pOtherExt->DeviceObject);

				gCtlDevNum = 0;
			}
		
			IoDeleteDevice(pDevExt->DeviceObject);

			lockHeld = FALSE;

            break;
        }
        
        case IRP_MN_DEVICE_USAGE_NOTIFICATION:
        {
            KdPrint(("LPCFILTER: FPFilterDispatchPnp: Sending on DEVICE_USAGE_NOTIFICATION\n"));
            status = FPFilterSendToNextDriver(DeviceObject, Irp);
            break; 
        }
        default:
        {
            KdPrint(("LPCFILTER: FPFilterDispatchPnp: Forwarding irp\n"));
	        status = FPFilterSendToNextDriver(DeviceObject, Irp);
        }
    }

    if (lockHeld)
    {
        IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp);
    }

    return status;
} 
Beispiel #11
0
NTSTATUS
mvolRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	NTSTATUS		status;
	PVOLUME_EXTENSION	VolumeExtension = DeviceObject->DeviceExtension;

	// we should call acuire removelock before pass down irp.
	// if acuire-removelock fail, we should return fail(STATUS_DELETE_PENDING).
	if (KeGetCurrentIrql() <= DISPATCH_LEVEL) {
		status = IoAcquireRemoveLock(&VolumeExtension->RemoveLock, NULL);
		if(!NT_SUCCESS(status)) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = 0;

			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return status;
		}
	}
	
	status = mvolRunIrpSynchronous(DeviceObject, Irp);
	if (!NT_SUCCESS(status))
	{
		WDRBD_ERROR("cannot remove device, status=0x%x\n", status);
	}

	IoReleaseRemoveLockAndWait(&VolumeExtension->RemoveLock, NULL); //wait remove lock
	IoDetachDevice(VolumeExtension->TargetDeviceObject);
	IoDeleteDevice(DeviceObject);

#ifdef MULTI_WRITE_HOOKER_THREADS
	{
		int i = 0;
		for (i = 0; i < 5; i++) 
		{
			if (deviceExtension->WorkThreadInfo[i].Active)
			{
				mvolTerminateThread(&deviceExtension->WorkThreadInfo);
				WDRBD_TRACE("[%ws]: WorkThread Terminate Completely\n",
					deviceExtension->PhysicalDeviceName);
			}
		}
	}
#else
	if (VolumeExtension->WorkThreadInfo.Active)
	{
		mvolTerminateThread(&VolumeExtension->WorkThreadInfo);
		WDRBD_TRACE("[%ws]: WorkThread Terminate Completely\n",	VolumeExtension->PhysicalDeviceName);
	}
#endif

	if (VolumeExtension->dev) {
		struct drbd_device *device = minor_to_device(VolumeExtension->VolIndex);
		if (device) {

			// DRBD-UPGRADE: if primary, check umount first? maybe umounted already?
			struct drbd_resource *resource = device->resource;
			int ret;

			// DW-876: The function 'drbd_adm_down_from_engine' performs down operation with specified resource, it does clean up all it needs(including disconnecting connections..)
			// It should be called per resource. Do not call with the resource which is already down.
			ret = drbd_adm_down_from_engine(resource);
			if (ret != NO_ERROR) {
				WDRBD_ERROR("drbd_adm_down_from_engine failed. ret=%d\n", ret); // EVENTLOG!
				// error ignored.
			}
		}
	}

	FreeUnicodeString(&VolumeExtension->MountPoint);
	FreeUnicodeString(&VolumeExtension->VolumeGuid);

	MVOL_LOCK();
	mvolDeleteDeviceList(VolumeExtension);
	MVOL_UNLOCK();
	
	Irp->IoStatus.Status = status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}
Beispiel #12
0
NTSTATUS
FilterDispatchPnp (
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp
    )
/*++

Routine Description:

    The plug and play dispatch routines.

    Most of these the driver will completely ignore.
    In all cases it must pass on the IRP to the lower driver.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

      NT status code

--*/
{
    PDEVICE_EXTENSION           deviceExtension;
    PIO_STACK_LOCATION         irpStack;
    NTSTATUS                            status;
    KEVENT                               event;

    PAGED_CODE();

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    DebugPrint(("FilterDO %s IRP:0x%p \n",
                PnPMinorFunctionString(irpStack->MinorFunction), Irp));

   status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
    if (!NT_SUCCESS (status)) {
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }
    

    switch (irpStack->MinorFunction) {
    case IRP_MN_START_DEVICE:

        //
        // The device is starting.
        // We cannot touch the device (send it any non pnp irps) until a
        // start device has been passed down to the lower drivers.
        //
        KeInitializeEvent(&event, NotificationEvent, FALSE);
        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(Irp,
                               FilterStartCompletionRoutine,
                               &event,
                               TRUE,
                               TRUE,
                               TRUE);

        status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
        
        //
        // Wait for lower drivers to be done with the Irp. Important thing to
        // note here is when you allocate memory for an event in the stack  
        // you must do a KernelMode wait instead of UserMode to prevent 
        // the stack from getting paged out.
        //
        if (status == STATUS_PENDING) {

           KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);          
           status = Irp->IoStatus.Status;
        }

        if (NT_SUCCESS (status)) {

            //
            // As we are successfully now back, we will
            // first set our state to Started.
            //

            SET_NEW_PNP_STATE(deviceExtension, Started);

            //
            // On the way up inherit FILE_REMOVABLE_MEDIA during Start.
            // This characteristic is available only after the driver stack is started!.
            //
            if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA) {

                DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
            }

#ifdef IOCTL_INTERFACE
            //
            // If the PreviousPnPState is stopped then we are being stopped temporarily
            // and restarted for resource rebalance. 
            //
            if (Stopped != deviceExtension->PreviousPnPState) {
                //
                // Device is started for the first time.
                //
                FilterCreateControlObject(DeviceObject);
            }
#endif   
        }
        
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); 
        return status;

    case IRP_MN_REMOVE_DEVICE:

        //
        // Wait for all outstanding requests to complete
        //
        DebugPrint(("Waiting for outstanding requests\n"));
        IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp);

        IoSkipCurrentIrpStackLocation(Irp);

        status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);

        SET_NEW_PNP_STATE(deviceExtension, Deleted);
        
#ifdef IOCTL_INTERFACE
        FilterDeleteControlObject();
#endif 
        IoDetachDevice(deviceExtension->NextLowerDriver);
        IoDeleteDevice(DeviceObject);
        return status;


    case IRP_MN_QUERY_STOP_DEVICE:
        SET_NEW_PNP_STATE(deviceExtension, StopPending);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_STOP_DEVICE:

        //
        // Check to see whether you have received cancel-stop
        // without first receiving a query-stop. This could happen if someone
        // above us fails a query-stop and passes down the subsequent
        // cancel-stop.
        //

        if (StopPending == deviceExtension->DevicePnPState)
        {
            //
            // We did receive a query-stop, so restore.
            //
            RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
        }
        status = STATUS_SUCCESS; // We must not fail this IRP.
        break;

    case IRP_MN_STOP_DEVICE:
        SET_NEW_PNP_STATE(deviceExtension, Stopped);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_REMOVE_DEVICE:

        SET_NEW_PNP_STATE(deviceExtension, RemovePending);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending);
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_REMOVE_DEVICE:

        //
        // Check to see whether you have received cancel-remove
        // without first receiving a query-remove. This could happen if
        // someone above us fails a query-remove and passes down the
        // subsequent cancel-remove.
        //

        if (RemovePending == deviceExtension->DevicePnPState)
        {
            //
            // We did receive a query-remove, so restore.
            //
            RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
        }

        status = STATUS_SUCCESS; // We must not fail this IRP.
        break;

    case IRP_MN_DEVICE_USAGE_NOTIFICATION:

        //
        // On the way down, pagable might become set. Mimic the driver
        // above us. If no one is above us, just set pagable.
        //
        #pragma prefast(suppress:__WARNING_INACCESSIBLE_MEMBER)
        if ((DeviceObject->AttachedDevice == NULL) ||
            (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) {

            DeviceObject->Flags |= DO_POWER_PAGABLE;
        }

        IoCopyCurrentIrpStackLocationToNext(Irp);

        IoSetCompletionRoutine(
            Irp,
            FilterDeviceUsageNotificationCompletionRoutine,
            NULL,
            TRUE,
            TRUE,
            TRUE
            );

        return IoCallDriver(deviceExtension->NextLowerDriver, Irp);

    default:
        //
        // If you don't handle any IRP you must leave the
        // status as is.
        //
        status = Irp->IoStatus.Status;

        break;
    }

    //
    // Pass the IRP down and forget it.
    //
    Irp->IoStatus.Status = status;
    IoSkipCurrentIrpStackLocation (Irp);
    status = IoCallDriver (deviceExtension->NextLowerDriver, Irp);
    IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); 
    return status;
}
Beispiel #13
0
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{							// DispatchPnp
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG fcn = stack->MinorFunction;
	NTSTATUS status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
	status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
	if (!NT_SUCCESS(status))
		return CompleteRequest(Irp, status, 0);
#if DBG 
	static char* pnpname[] = 
	{
		"IRP_MN_START_DEVICE",
		"IRP_MN_QUERY_REMOVE_DEVICE",
		"IRP_MN_REMOVE_DEVICE",
		"IRP_MN_CANCEL_REMOVE_DEVICE",
		"IRP_MN_STOP_DEVICE",
		"IRP_MN_QUERY_STOP_DEVICE",
		"IRP_MN_CANCEL_STOP_DEVICE",
		"IRP_MN_QUERY_DEVICE_RELATIONS",
		"IRP_MN_QUERY_INTERFACE",
		"IRP_MN_QUERY_CAPABILITIES",
		"IRP_MN_QUERY_RESOURCES",
		"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
		"IRP_MN_QUERY_DEVICE_TEXT",
		"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
		"",
		"IRP_MN_READ_CONFIG",
		"IRP_MN_WRITE_CONFIG",
		"IRP_MN_EJECT",
		"IRP_MN_SET_LOCK",
		"IRP_MN_QUERY_ID",
		"IRP_MN_QUERY_PNP_DEVICE_STATE",
		"IRP_MN_QUERY_BUS_INFORMATION",
		"IRP_MN_DEVICE_USAGE_NOTIFICATION",
		"IRP_MN_SURPRISE_REMOVAL",
		"IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
	};

	if (fcn < arraysize(pnpname))
		KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));
	else
		KdPrint((DRIVERNAME " - IRP_MJ_PNP (%2.2X)\n", fcn));
#endif // DBG

	// Handle usage notification specially in order to track power pageable
	// flag correctly. We need to avoid allowing a non-pageable handler to be
	// layered on top of a pageable handler.
	if (fcn == IRP_MN_DEVICE_USAGE_NOTIFICATION)
	{						// usage notification
		if (!fido->AttachedDevice || (fido->AttachedDevice->Flags & DO_POWER_PAGABLE))
			fido->Flags |= DO_POWER_PAGABLE;
		IoCopyCurrentIrpStackLocationToNext(Irp);
		IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) UsageNotificationCompletionRoutine,
			(PVOID) pdx, TRUE, TRUE, TRUE);
		return IoCallDriver(pdx->LowerDeviceObject, Irp);
	}						// usage notification

	// Handle start device specially in order to correctly inherit
	// FILE_REMOVABLE_MEDIA
	if (fcn == IRP_MN_START_DEVICE)
	{						// device start
		IoCopyCurrentIrpStackLocationToNext(Irp);
		IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) StartDeviceCompletionRoutine,
			(PVOID) pdx, TRUE, TRUE, TRUE);
		return IoCallDriver(pdx->LowerDeviceObject, Irp);
	}						// device start

	// Handle remove device specially in order to cleanup device stack
	if (fcn == IRP_MN_REMOVE_DEVICE)
	{						// remove device
		IoSkipCurrentIrpStackLocation(Irp);
		status = IoCallDriver(pdx->LowerDeviceObject, Irp);
		IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
		RemoveDevice(fido);
		return status;
	}						// remove device

	// Simply forward any other type of PnP request
	IoSkipCurrentIrpStackLocation(Irp);
	status = IoCallDriver(pdx->LowerDeviceObject, Irp);
	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return status;
}							// DispatchPnp
Beispiel #14
0
NTSTATUS
CsampCleanup(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
)
/*++

Routine Description:
    This dispatch routine is called when the last handle (in
    the whole system) to a file object is closed. In other words, the open
    handle count for the file object goes to 0. A driver that holds pending
    IRPs internally must implement a routine for IRP_MJ_CLEANUP. When the
    routine is called, the driver should cancel all the pending IRPs that
    belong to the file object identified by the IRP_MJ_CLEANUP call. In other
    words, it should cancel all the IRPs that have the same file-object pointer
    as the one supplied in the current I/O stack location of the IRP for the
    IRP_MJ_CLEANUP call. Of course, IRPs belonging to other file objects should
    not be canceled. Also, if an outstanding IRP is completed immediately, the
    driver does not have to cancel it.

Arguments:

    DeviceObject     -- pointer to the device object
    Irp             -- pointer to the requesing Irp

Return Value:

    STATUS_SUCCESS   -- if the poll succeeded,
--*/
{

    PDEVICE_EXTENSION   devExtension;
    PIRP                pendingIrp;
    PIO_STACK_LOCATION  irpStack;
    PFILE_CONTEXT       fileContext;
    NTSTATUS            status;

    CSAMP_KDPRINT(("CsampCleanupIrp enter\n"));

    devExtension = DeviceObject->DeviceExtension;

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    ASSERT(irpStack->FileObject != NULL);    

    fileContext = irpStack->FileObject->FsContext;    

    //
    // This acquire cannot fail because you cannot get more than one
    // cleanup for the same handle.
    //
    status = IoAcquireRemoveLock(&fileContext->FileRundownLock, Irp);
    ASSERT(NT_SUCCESS(status));

    //
    // Wait for all the threads that are currently dispatching to exit and 
    // prevent any threads dispatching I/O on the same handle beyond this point.
    //
    IoReleaseRemoveLockAndWait(&fileContext->FileRundownLock, Irp);

    pendingIrp = IoCsqRemoveNextIrp(&devExtension->CancelSafeQueue,
                                    irpStack->FileObject);

    while(pendingIrp) 
    {
        //
        // Cancel the IRP
        //
        pendingIrp->IoStatus.Information = 0;
        pendingIrp->IoStatus.Status = STATUS_CANCELLED;
        CSAMP_KDPRINT(("Cleanup cancelled irp\n"));
        IoCompleteRequest(pendingIrp, IO_NO_INCREMENT);

        pendingIrp = IoCsqRemoveNextIrp(&devExtension->CancelSafeQueue,
                                        irpStack->FileObject);
    }

    //
    // Finally complete the cleanup IRP
    //
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    CSAMP_KDPRINT(("CsampCleanupIrp exit\n"));

    return STATUS_SUCCESS;

}
Beispiel #15
0
static NTSTATUS NTAPI
V4vDispatchPnP(PDEVICE_OBJECT fdo, PIRP irp)
{
    NTSTATUS           status = STATUS_SUCCESS;
    PIO_STACK_LOCATION isl = IoGetCurrentIrpStackLocation(irp);
    PXENV4V_EXTENSION  pde = V4vGetDeviceExtension(fdo);
    KEVENT             kev;

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    TraceVerbose((" =PnP= 0x%x\n", isl->MinorFunction));

    status = IoAcquireRemoveLock(&pde->removeLock, irp);
    if (!NT_SUCCESS(status)) {
        TraceError(("failed to acquire IO lock - error: 0x%x\n", status));
        return V4vSimpleCompleteIrp(irp, status);
    }

    switch (isl->MinorFunction) {
    case IRP_MN_START_DEVICE:
        KeInitializeEvent(&kev, NotificationEvent, FALSE);
        // Send the start down and wait for it to complete
        IoCopyCurrentIrpStackLocationToNext(irp);
        IoSetCompletionRoutine(irp, V4vStartDeviceIoCompletion, &kev, TRUE, TRUE, TRUE);
        status = IoCallDriver(pde->ldo, irp);
        if (status == STATUS_PENDING) {
            // Wait for everything underneath us to complete
            TraceVerbose(("Device start waiting for lower device.\n"));
            KeWaitForSingleObject(&kev, Executive, KernelMode, FALSE, NULL);
            TraceVerbose(("Device start wait finished.\n"));
        }

        status = irp->IoStatus.Status;
        if (!NT_SUCCESS(status)) {
            TraceError(("Failed to start lower drivers: %x.\n", status));
            IoCompleteRequest(irp, IO_NO_INCREMENT);
            break;
        }

        status = STATUS_SUCCESS;

        // Connect our interrupt (ec).
        status = V4vInitializeEventChannel(fdo);
        if (NT_SUCCESS(status)) {
            InterlockedExchange(&pde->state, XENV4V_DEV_STARTED);
        }
        else {
            TraceError(("failed to initialize event channel - error: 0x%x\n", status));
        }

        irp->IoStatus.Status = status;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        break;
    case IRP_MN_STOP_DEVICE:
        // Stop our device's IO processing
        V4vStopDevice(fdo, pde);

        // Pass it down
        irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation(irp);
        status = IoCallDriver(pde->ldo, irp);
        break;        
    case IRP_MN_REMOVE_DEVICE:
        // Stop our device's IO processing
        V4vStopDevice(fdo, pde);

        // Cleanup anything here that locks for IO
        IoReleaseRemoveLockAndWait(&pde->removeLock, irp);

        // Pass it down first
        IoSkipCurrentIrpStackLocation(irp);
        status = IoCallDriver(pde->ldo, irp);

        // Then detach and cleanup our device
        xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CLOSED);
        IoDetachDevice(pde->ldo);
        ExDeleteNPagedLookasideList(&pde->destLookasideList);
        XmFreeMemory(pde->frontendPath);
        IoDeleteSymbolicLink(&pde->symbolicLink);
        IoDeleteDevice(fdo);
        InterlockedAnd(&g_deviceCreated, 0);
        return status;
    default:
        // Pass it down
        TraceVerbose(("IRP_MJ_PNP MinorFunction %d passed down\n", isl->MinorFunction));
        IoSkipCurrentIrpStackLocation(irp);
        status = IoCallDriver(pde->ldo, irp);
    };

    // Everybody but REMOVE
    IoReleaseRemoveLock(&pde->removeLock, irp); 

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));

    return status;
}