Beispiel #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;
}
Beispiel #2
0
NTSTATUS
BlkMovDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PIO_STACK_LOCATION  irpSp = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS            status;
    PDEVICE_EXTENSION   deviceExtension;

    PAGED_CODE();

    switch(irpSp->MinorFunction)
	{

        case IRP_MN_START_DEVICE:
            //
            // Call the Start Routine handler to schedule a completion routine
            //
            status = BlkMovStartDevice(DeviceObject, Irp);
            break;

        /*case IRP_MN_REMOVE_DEVICE:
        {
            //
            // Call the Remove Routine handler to schedule a completion routine
            //
            status = BlkMovRemoveDevice(DeviceObject, Irp);
            break;
        }*/
        case IRP_MN_DEVICE_USAGE_NOTIFICATION:
        {
            PIO_STACK_LOCATION irpStack;
            ULONG count;
            BOOLEAN setPagable;

            DbgPrint("BlkMovDispatchPnp: Processing DEVICE_USAGE_NOTIFICATION\n");
            irpStack = IoGetCurrentIrpStackLocation(Irp);

            if (irpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging)
			{
                status = BlkMovSendToNextDriver(DeviceObject, Irp);
                break; // out of case statement
            }

            deviceExtension = DeviceObject->DeviceExtension;

            //
            // wait on the paging path event
            //

            status = KeWaitForSingleObject(&deviceExtension->PagingPathCountEvent,
                                           Executive, KernelMode,
                                           FALSE, NULL);
            //
            // if removing last paging device, need to set DO_POWER_PAGABLE
            // bit here, and possible re-set it below on failure.
            //
			setPagable = FALSE;
            if (!irpStack->Parameters.UsageNotification.InPath &&
                deviceExtension->PagingPathCount == 1 )
			{
                //
                // removing the last paging file
                // must have DO_POWER_PAGABLE bits set
                //

                if (DeviceObject->Flags & DO_POWER_INRUSH)
				{
                    DbgPrint("BlkMovDispatchPnp: last paging file "
                                "removed but DO_POWER_INRUSH set, so not "
                                "setting PAGABLE bit "
                                "for DO %p\n", DeviceObject);
                }
				else
				{
                    DbgPrint("BlkMovDispatchPnp: Setting  PAGABLE "
                                "bit for DO %p\n", DeviceObject);
                    DeviceObject->Flags |= DO_POWER_PAGABLE;
                    setPagable = TRUE;
                }

            }

            //
            // send the irp synchronously
            //

            status = BlkMovForwardIrpSynchronous(DeviceObject, Irp);

            //
            // now deal with the failure and success cases.
            // note that we are not allowed to fail the irp
            // once it is sent to the lower drivers.
            //

            if (NT_SUCCESS(status))
			{
                IoAdjustPagingPathCount(
                    &deviceExtension->PagingPathCount,
                    irpStack->Parameters.UsageNotification.InPath);

                if (irpStack->Parameters.UsageNotification.InPath)
				{
                    if (deviceExtension->PagingPathCount == 1)
					{

                        //
                        // first paging file addition
                        //

                        DeviceObject->Flags &= ~DO_POWER_PAGABLE;
                    }
                }

            }
			else
			{

                //
                // cleanup the changes done above
                //

                if (setPagable == TRUE)
				{
                    DeviceObject->Flags &= ~DO_POWER_PAGABLE;
                    setPagable = FALSE;
                }

            }

            //
            // set the event so the next one can occur.
            //

            KeSetEvent(&deviceExtension->PagingPathCountEvent,
                       IO_NO_INCREMENT, FALSE);

            //
            // and complete the irp
            //

            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return status;
            break;

        }
		case IRP_MN_REMOVE_DEVICE:
			return BlkMovSendToNextDriver(DeviceObject, Irp);
		case IRP_MN_STOP_DEVICE:
			return BlkMovSendToNextDriver(DeviceObject, Irp);
        default:
            //
            // Simply forward all other Irps
            //
            return BlkMovSendToNextDriver(DeviceObject, Irp);

    }

    return status;

} // end BlkMovDispatchPnp()
Beispiel #3
0
NTSTATUS
YtDispatchFilterPnP(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
	)
{
	PIO_STACK_LOCATION  irpSp = IoGetCurrentIrpStackLocation(Irp);
	NTSTATUS            status;
	PDEVICE_EXTENSION   deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    //DebugPrint(("YtDispatchPnp: Device %X Irp %X\n", DeviceObject, Irp));

	switch(irpSp->MinorFunction)
	{
	case IRP_MN_REMOVE_DEVICE:
		DebugPrint(("YtDispatchFilterPnP: Schedule completion for REMOVE_DEVICE.\n"));
		status = YtRemoveDevice(DeviceObject, Irp);
		return status;

	case IRP_MN_START_DEVICE:
		DebugPrint(("YtDispatchFilterPnP: Schedule completion for START_DEVICE.\n"));
		status = YtStartDevice(DeviceObject, Irp);

		return status;

	case IRP_MN_STOP_DEVICE:
		DebugPrint(("YtDispatchFilterPnP: Schedule completion for STOP_DEVICE.\n"));
		status = YtStopDevice(DeviceObject, Irp);

		return status;

	case IRP_MN_DEVICE_USAGE_NOTIFICATION:
		PIO_STACK_LOCATION irpStack;
		ULONG count;
		BOOLEAN setPagable;

		DebugPrint(("YtDispatchFilterPnP: Processing DEVICE_USAGE_NOTIFICATION\n"));
		irpStack = IoGetCurrentIrpStackLocation(Irp);

		if (irpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging)
		{
			status = YtSendToNextDriver(DeviceObject, Irp);

			return status;
		}

		deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

		// wait on the paging path event
		status = KeWaitForSingleObject(
			&deviceExtension->PagingPathCountEvent,
			Executive,
			KernelMode,
			FALSE,
			NULL
			);

		// if removing last paging device, need to set DO_POWER_PAGABLE
		// bit here, and possible re-set it below on failure.
		setPagable = FALSE;
		if (!irpStack->Parameters.UsageNotification.InPath &&
			deviceExtension->PagingPathCount == 1 )
		{
			// removing the last paging file
			// must have DO_POWER_PAGABLE bits set

			if (DeviceObject->Flags & DO_POWER_INRUSH)
			{
				DebugPrint(("YtDispatchFilterPnP: last paging file "
				"removed but DO_POWER_INRUSH set, so not "
				"setting PAGABLE bit "
				"for DO %p\n", DeviceObject));
			}
			else
			{
				DebugPrint(("YtDispatchFilterPnP: Setting  PAGABLE "
					"bit for DO %p\n", DeviceObject));
				DeviceObject->Flags |= DO_POWER_PAGABLE;
				setPagable = TRUE;
			}
		}

		//send the irp synchronously

		status = YtForwardIrpSynchronous(DeviceObject, Irp);

		//now deal with the failure and success cases.
		//note that we are not allowed to fail the irp
        //once it is sent to the lower drivers.
		if (NT_SUCCESS(status))
		{
			IoAdjustPagingPathCount(
				&deviceExtension->PagingPathCount,
				irpStack->Parameters.UsageNotification.InPath
				);

			if (irpStack->Parameters.UsageNotification.InPath)
			{
				if (deviceExtension->PagingPathCount == 1)
				{
					DebugPrint(("YtDispatchFilterPnP: Clearing PAGABLE bit "
							"for DO %p\n", DeviceObject));
					DeviceObject->Flags &= ~DO_POWER_PAGABLE;
				}
			}

        } else {

            //
            // cleanup the changes done above
            //

            if (setPagable == TRUE) {
                DeviceObject->Flags &= ~DO_POWER_PAGABLE;
                setPagable = FALSE;
            }

        }

        //
        // set the event so the next one can occur.
        //

        KeSetEvent(&deviceExtension->PagingPathCountEvent,
                    IO_NO_INCREMENT, FALSE);

        //
        // and complete the irp
        //

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
	}

	//DebugPrint(("YtDispatchPnp: Forwarding irp...\n"));
	//Forward all other Irps
	status = YtSendToNextDriver(DeviceObject, Irp);

	return status;
}
Beispiel #4
0
NTSTATUS
DF_DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	NTSTATUS				status;
	PDF_DEVICE_EXTENSION	DevExt;
	PIO_STACK_LOCATION		IrpSp;
	// For handling paging requests.
	BOOLEAN					setPageable;
	BOOLEAN					bAddPageFile;
	PAGED_CODE();

	IrpSp = IoGetCurrentIrpStackLocation(Irp);
	DevExt = (PDF_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
	switch(IrpSp->MinorFunction)
	{
	case IRP_MN_START_DEVICE:
		DBG_PRINT(DBG_TRACE_OPS, ("%s: Start Device...\n", __FUNCTION__));
		status = Irp->IoStatus.Status;
		DevExt->CurrentPnpState = IRP_MN_START_DEVICE;
		break;
	case IRP_MN_DEVICE_USAGE_NOTIFICATION :
		setPageable = FALSE;
		bAddPageFile = IrpSp->Parameters.UsageNotification.InPath;
		DBG_PRINT(DBG_TRACE_OPS, ("%s: Paging file request...\n", __FUNCTION__));
		if (IrpSp->Parameters.UsageNotification.Type == DeviceUsageTypePaging)
		//	Indicated it will create or delete a paging file.
		{
			if(bAddPageFile && !DevExt->CurrentPnpState)
			{
				status = STATUS_DEVICE_NOT_READY;
				break;
			}

			//	Waiting other paging requests.
			KeWaitForSingleObject(&DevExt->PagingCountEvent,
				Executive, KernelMode,
				FALSE, NULL);

			//	Removing last paging device.
			if (!bAddPageFile && DevExt->PagingCount == 1 )
			{
				// The last paging file is no longer active.
				// Set the DO_POWER_PAGABLE bit before
				// forwarding the paging request down the
				// stack.
				if (!(DeviceObject->Flags & DO_POWER_INRUSH))
				{
					DeviceObject->Flags |= DO_POWER_PAGABLE;
					setPageable = TRUE;
				}
			}
			//	Waiting lower device complete.
			IoForwardIrpSynchronously(DevExt->LowerDeviceObject, Irp);

			if (NT_SUCCESS(Irp->IoStatus.Status))
			{
				IoAdjustPagingPathCount(&DevExt->PagingCount, bAddPageFile);
				if (bAddPageFile && DevExt->PagingCount == 1) {
					//	Once the lower device objects have succeeded the addition of the paging
					//	file, it is illegal to fail the request. It is also the time to clear
					//	the Filter DO's DO_POWER_PAGABLE flag.
					DeviceObject->Flags &= ~DO_POWER_PAGABLE;
				}
			}
			else
			{
				if (setPageable == TRUE) {
					DeviceObject->Flags &= ~DO_POWER_PAGABLE;
					setPageable = FALSE;
				}
			}
			KeSetEvent(&DevExt->PagingCountEvent, IO_NO_INCREMENT, FALSE);
			status = Irp->IoStatus.Status;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return status;
		}
		break;
	case IRP_MN_REMOVE_DEVICE:
		DBG_PRINT(DBG_TRACE_OPS, ("%s: Removing Device...\n", __FUNCTION__));
		IoForwardIrpSynchronously(DevExt->LowerDeviceObject, Irp);
		status = Irp->IoStatus.Status;
		if (NT_SUCCESS(status))
		{
			DBG_PRINT(DBG_TRACE_OPS, ("%d-%d: Stopping Device...\n", DevExt->DiskNumber, DevExt->PartitionNumber));
			StopDevice(DeviceObject);
			DBG_PRINT(DBG_TRACE_OPS, ("%d-%d: Device Stopped.\n", DevExt->DiskNumber, DevExt->PartitionNumber));
		}
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return status;
	}
	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(DevExt->LowerDeviceObject, Irp);
}
Beispiel #5
0
NTSTATUS	
DPDispatchPnp(
	IN	PDEVICE_OBJECT	DeviceObject,
	IN	PIRP			Irp
	)
{
	//用来指向过滤设备的设备扩展的指针
	PDP_FILTER_DEV_EXTENSION	DevExt = DeviceObject->DeviceExtension;
	//返回值
	NTSTATUS ntStatus = STATUS_SUCCESS;
	//用来指向irp stack的指针
	PIO_STACK_LOCATION  irpsp = IoGetCurrentIrpStackLocation(Irp);

	switch(irpsp->MinorFunction) 
	{
	case IRP_MN_REMOVE_DEVICE:
		//如果是PnP manager发过来的移除设备的irp,将进入这里
		{
			//这里主要做一些清理工作
			if (DevExt->ThreadTermFlag != TRUE && NULL != DevExt->ThreadHandle)
			{
				//如果线程还在运行的话需要停止它,这里通过设置线程停止运行的标志并且发送事件信息,让线程自己终止运行
				DevExt->ThreadTermFlag = TRUE;
				KeSetEvent(
					&DevExt->ReqEvent,
					(KPRIORITY) 0,
					FALSE
					);
				//等待线程结束
				KeWaitForSingleObject(
					DevExt->ThreadHandle,
					Executive,
					KernelMode,
					FALSE,
					NULL
					);
				//解除引用线程对象
				ObDereferenceObject(DevExt->ThreadHandle);
			}
	 		if (NULL != DevExt->Bitmap)
	 		{
				//如果还有位图,就释放
	 			DPBitmapFree(DevExt->Bitmap);
	 		}
			if (NULL != DevExt->LowerDevObj)
			{
				//如果存在着下层设备,就先去掉挂接
				IoDetachDevice(DevExt->LowerDevObj);
			}
	 		if (NULL != DevExt->FltDevObj)
	 		{
				//如果存在过滤设备,就要删除它
	 			IoDeleteDevice(DevExt->FltDevObj);
	 		}
			break;
		}
	//这个是PnP 管理器用来询问设备能否支持特殊文件的irp,作为卷的过滤驱动,我们必须处理
	case IRP_MN_DEVICE_USAGE_NOTIFICATION:
		{
			BOOLEAN setPagable;
			//如果是询问是否支持休眠文件和dump文件,则直接下发给下层设备去处理
			if (irpsp->Parameters.UsageNotification.Type != DeviceUsageTypePaging) 
			{
				ntStatus = DPSendToNextDriver(
					DevExt->LowerDevObj,
					Irp);
				return ntStatus; 
			}
			//这里等一下分页计数事件
			ntStatus = KeWaitForSingleObject(
				&DevExt->PagingPathCountEvent,
				Executive, 
				KernelMode,
				FALSE, 
				NULL);

			//setPagable初始化为假,是没有设置过DO_POWER_PAGABLE的意思
			setPagable = FALSE;
			if (!irpsp->Parameters.UsageNotification.InPath &&
				DevExt->PagingPathCount == 1 ) 
			{
				//如果是PnP manager通知我们将要删去分页文件,且我们目前只剩下最后一个分页文件的时候会进入这里
				if (DeviceObject->Flags & DO_POWER_INRUSH)
				{} 
				else 
				{
					//到这里说明没有分页文件在这个设备上了,需要设置DO_POWER_PAGABLE这一位了
					DeviceObject->Flags |= DO_POWER_PAGABLE;
					setPagable = TRUE;
				}
			}
			//到这里肯定是关于分页文件的是否可建立查询,或者是删除的通知,我们交给下层设备去做。这里需要用同步的方式给下层设备,也就是说要等待下层设备的返回
			ntStatus = DPForwardIrpSync(DevExt->LowerDevObj,Irp);

			if (NT_SUCCESS(ntStatus)) 
			{
				//如果发给下层设备的请求成功了,说明下层设备支持这个操作,会执行到这里
				//在成功的条件下我们来改变我们自己的计数值,这样就能记录我们现在这个设备上到底有多少个分页文件
				IoAdjustPagingPathCount(
					&DevExt->PagingPathCount,
					irpsp->Parameters.UsageNotification.InPath);
				if (irpsp->Parameters.UsageNotification.InPath) 
				{
					if (DevExt->PagingPathCount == 1) 
					{
						//如果这个请求是一个建立分页文件的查询请求,并且下层设备支持这个请求,而且这是第一个在这个设备上的分页文件,那么我们需要清除DO_POWER_PAGABLE位
						DeviceObject->Flags &= ~DO_POWER_PAGABLE;
					}
				}
			}
			else 
			{
				//到这里说明给下层设备发请求失败了,下层设备不支持这个请求,这时候我们需要把之前做过的操作还原
				if (setPagable == TRUE) 
				{
					//根据setPagable变量的值来判断我们之前是否做过对DO_POWER_PAGABLE的设置,如果有的话就清楚这个设置
					DeviceObject->Flags &= ~DO_POWER_PAGABLE;
					setPagable = FALSE;
				}
			}
			//设置分页计数事件
			KeSetEvent(
				&DevExt->PagingPathCountEvent,
				IO_NO_INCREMENT, 
				FALSE
				);
			//到这里我们就可以完成这个irp请求了
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return ntStatus;
		}		
	default:
		break;
	}
	return DPSendToNextDriver(
		DevExt->LowerDevObj,
		Irp);

}