⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugplay.cpp

📁 智能卡的读写程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// (We can now be stopped or working)

	pdx->prevstate = pdx->state;
	pdx->state = PENDINGREMOVE;
	return DefaultPnpHandler(fdo, Irp);
	}							// HandleQueryRemove

///////////////////////////////////////////////////////////////////////////////

NTSTATUS HandleQueryStop(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
	{							// HandleQueryStop
	ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_QUERY_STOP_DEVICE);
	Irp->IoStatus.Status = STATUS_SUCCESS;	// flag that we handled this IRP
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	
	// Boot devices may get this query before they even start, so check to see
	// if we're in the WORKING state before doing anything.

	if (pdx->state != WORKING)
		return DefaultPnpHandler(fdo, Irp);

	KdPrint((DRIVERNAME " - To PENDINGSTOP from %s\n", statenames[pdx->state]));
	pdx->state = PENDINGSTOP;
	return DefaultPnpHandler(fdo, Irp);
	}							// HandleQueryStop

///////////////////////////////////////////////////////////////////////////////

NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
	{							// HandleRemoveDevice
	ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_REMOVE_DEVICE);
	Irp->IoStatus.Status = STATUS_SUCCESS;	// flag that we handled this IRP
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	// Cancel any queued IRPs and start rejecting new ones

	// Disable all device interfaces. This triggers PnP notifications that will 
	// allow apps to close their handles.

	DeregisterAllInterfaces(pdx);

	// Release our I/O resources

	StopDevice(fdo, pdx->state == WORKING);

	KdPrint((DRIVERNAME " - To REMOVED from %s\n", statenames[pdx->state]));
	pdx->state = REMOVED;

	// Let lower-level drivers handle this request. Ignore whatever
	// result eventuates.

	NTSTATUS status = DefaultPnpHandler(fdo, Irp);

	// Wait for all claims against this device to vanish before removing
	// the device object.

	IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);

	// Remove the device object

	RemoveDevice(fdo);

	return status;				// lower-level completed IoStatus already
	}							// HandleRemoveDevice

///////////////////////////////////////////////////////////////////////////////

NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
	{							// HandleStartDevice
	ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_START_DEVICE);
	Irp->IoStatus.Status = STATUS_SUCCESS;	// flag that we handled this IRP
	NTSTATUS status = ForwardAndWait(fdo, Irp);
	if (!NT_SUCCESS(status))
		return CompleteRequest(Irp, status);

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	status = StartDevice(fdo);

	// While we were in the stopped state, we were stalling incoming requests.
	// Now we can release any pending IRPs and start processing new ones

	if (NT_SUCCESS(status))
		{						// started okay

		// Enable all registered device interfaces.

		EnableAllInterfaces(pdx, TRUE);

		KdPrint((DRIVERNAME " - To WORKING from %s\n", statenames[pdx->state]));
		pdx->state = WORKING;
		}						// started okay

	return CompleteRequest(Irp, status);
	}							// HandleStartDevice

///////////////////////////////////////////////////////////////////////////////	

NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
	{							// HandleStopDevice
	ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_STOP_DEVICE);
	Irp->IoStatus.Status = STATUS_SUCCESS;	// flag that we handled this IRP
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	// We're supposed to always get a query before we're stopped, so
	// we should already be in the PENDINGSTOP state. There's a Win98 bug that
	// can sometimes cause us to get a STOP instead of a REMOVE, in which case
	// we should start rejecting IRPs

	if (pdx->state != PENDINGSTOP)
		{						// no previous query
		KdPrint((DRIVERNAME " - STOP with no previous QUERY_STOP!\n"));
		}						// no previous query
	StopDevice(fdo, pdx->state == WORKING);
	KdPrint((DRIVERNAME " - To STOPPED from %s\n", statenames[pdx->state]));
	pdx->state = STOPPED;
	return DefaultPnpHandler(fdo, Irp);
	}							// HandleStopDevice

///////////////////////////////////////////////////////////////////////////////

NTSTATUS HandleSurpriseRemoval(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
	{							// HandleSurpriseRemoval
	ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_SURPRISE_REMOVAL);
	Irp->IoStatus.Status = STATUS_SUCCESS;	// flag that we handled this IRP
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	// Cancel any queued IRPs and start rejecting new ones
	EnableAllInterfaces(pdx, FALSE);
	KdPrint((DRIVERNAME " - To SURPRISEREMOVED from %s\n", statenames[pdx->state]));

	BOOLEAN oktouch = pdx->state == WORKING;
	pdx->state = SURPRISEREMOVED;
	StopDevice(fdo, oktouch);

	return DefaultPnpHandler(fdo, Irp);
	}							// HandleSurpriseRemoval
	
///////////////////////////////////////////////////////////////////////////////
// AdjustDeviceCapabilities corrects the reported device capabilities to
// workaround the fact that many back-level bus drivers simply don't report
// them correctly. Cf. toaster.sys sample in the DDK and talk given by
// Adrian Oney (no relation) at WinHEC 2002.

#pragma PAGEDCODE

__inline SYSTEM_POWER_STATE& operator++(SYSTEM_POWER_STATE& ss) {ss = (SYSTEM_POWER_STATE) (ss + 1); return ss;}
__inline SYSTEM_POWER_STATE& operator--(SYSTEM_POWER_STATE& ss) {ss = (SYSTEM_POWER_STATE) (ss - 1); return ss;}

VOID AdjustDeviceCapabilities(PDEVICE_EXTENSION pdx, PDEVICE_CAPABILITIES pdc)
	{							// AdjustDeviceCapabilities

	// Adjust power capabilities to compensate for bus driver written to
	// WDM 1.0 spec. First infer D1 and D2 capabilities from S->D state map.

	for (SYSTEM_POWER_STATE sstate = PowerSystemSleeping1; sstate <= PowerSystemHibernate; ++sstate)
		{					// for each S-state
		if (pdc->DeviceState[sstate] == PowerDeviceD1)
			pdc->DeviceD1 = TRUE;
		if (pdc->DeviceState[sstate] == PowerDeviceD2)
			pdc->DeviceD2 = TRUE;
		}					// for each S-state

	// Set the WakeFromDx flags based on the reported DeviceWake state and
	// on the D-state corresponding to the reported SystemWake state

	AdjustWakeCapabilities(pdc, pdc->DeviceWake);
	if (pdc->SystemWake != PowerSystemUnspecified)
		AdjustWakeCapabilities(pdc, pdc->DeviceState[pdc->SystemWake]);

	// Find the deepest D-state from which this device can wake the system

	DEVICE_POWER_STATE wakestate = PowerDeviceD0;	// assume no wakeup capability

	if (pdc->WakeFromD3)
		wakestate = PowerDeviceD3;
	else if (pdc->WakeFromD2)
		wakestate = PowerDeviceD2;
	else if (pdc->WakeFromD1)
		wakestate = PowerDeviceD1;
	else if (pdc->WakeFromD0)
		wakestate = PowerDeviceD0;

	// If SystemWake is specified, the corresponding D-state had better be at
	// least as powered as the state we just discovered, or else there's a bug
	// in our bus driver...

	if (pdc->SystemWake != PowerSystemUnspecified)
		{
		ASSERT(pdc->DeviceState[pdc->SystemWake] <= wakestate);
		}

	// If SystemWake wasn't specified, infer it from the S->D state map by
	// finding the lowest S-state whose D-state is at least as powered as the
	// lowest D-state from which wakeup is possible (I think I got that right...)

	else if (wakestate != PowerDeviceD0 && wakestate != PowerDeviceUnspecified)
		{						// infer system wake state
		for (sstate = PowerSystemSleeping3; sstate >= PowerSystemWorking; --sstate)
			{					// for each S-state
			if (pdc->DeviceState[sstate] != PowerDeviceUnspecified
				&& pdc->DeviceState[sstate] <= wakestate)
				{				// found the S-state
				KdPrint((DRIVERNAME " - Inferring that wakeup from S%d state possible\n", sstate - 1));
				pdc->SystemWake = sstate;
				break;
				}				// found the S-state
			}					// for each S-state
		}						// infer system wake state
	}							// AdjustDeviceCapabilities

///////////////////////////////////////////////////////////////////////////////
// AdjustWakeCapabilities adjusts the wakeup capabilities for a device.	

VOID AdjustWakeCapabilities(PDEVICE_CAPABILITIES pdc, DEVICE_POWER_STATE dstate)
	{							// AdjustWakeCapabilities
	switch (dstate)
		{						// select on D-state
	case PowerDeviceUnspecified:
		break;
	case PowerDeviceD0:
		pdc->WakeFromD0 = TRUE;
		break;
	case PowerDeviceD1:
		pdc->DeviceD1 = TRUE;
		pdc->WakeFromD1 = TRUE;
		break;
	case PowerDeviceD2:
		pdc->DeviceD2 = TRUE;
		pdc->WakeFromD2 = TRUE;
		break;
	case PowerDeviceD3:
		pdc->WakeFromD3 = TRUE;
		break;
	default:
		ASSERT(FALSE);
		}						// select on D-state
	}							// AdjustWakeCapabilities

///////////////////////////////////////////////////////////////////////////////	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -