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

📄 driverentry.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	if (fcn == IRP_MN_QUERY_CAPABILITIES && !pdx->CapabilitiesDumped)
		{						// capabilities query
		pdx->CapabilitiesDumped = TRUE;	// only do this once
		IoCopyCurrentIrpStackLocationToNext(Irp);
		IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) CapabilitiesQueryCompletionRoutine,
			(PVOID) pdx, TRUE, TRUE, TRUE);
		return IoCallDriver(pdx->LowerDeviceObject, Irp);
		}						// capabilities query

	// Simply forward any other type of PnP request

	IoSkipCurrentIrpStackLocation(Irp);
	status = IoCallDriver(pdx->LowerDeviceObject, Irp);
	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return status;
	}							// DispatchPnp

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

NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
	{							// DispatchPower
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG fcn = stack->MinorFunction;

	if (fcn == IRP_MN_SET_POWER || fcn == IRP_MN_QUERY_POWER)
		{
		POWER_STATE_TYPE type = stack->Parameters.Power.Type;

		if (type == SystemPowerState)
			PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%s), SystemPowerState = %s\n", powminor[fcn], sysnames[stack->Parameters.Power.State.SystemState]);
		else
			PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%s), DevicePowerState = %s\n", powminor[fcn], devnames[stack->Parameters.Power.State.DeviceState]);
		}
	else if (fcn == IRP_MN_WAIT_WAKE)
		{
		SYSTEM_POWER_STATE sysstate = stack->Parameters.WaitWake.PowerState;
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (IRP_MN_WAIT_WAKE), PowerState = %s\n", sysnames[sysstate]);
		}
	else if (fcn < arraysize(powminor))
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%s)\n", powminor[fcn]);
	else
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%X)\n", fcn);

	PoStartNextPowerIrp(Irp);	// must be done while we own the IRP
	NTSTATUS status;
	status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
	if (!NT_SUCCESS(status))
		return CompleteRequest(Irp, status, 0);

	IoCopyCurrentIrpStackLocationToNext(Irp);
	IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) PowerCompletionRoutine, (PVOID) pdx, TRUE, TRUE, TRUE);
	status = PoCallDriver(pdx->LowerDeviceObject, Irp);

	if (fcn < arraysize(powminor))
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%s) dispatch routine returns %X\n", powminor[fcn], status);
	else
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%X) dispatch routine returns %X\n", fcn, status);

	return status;
	}							// DispatchPower

///////////////////////////////////////////////////////////////////////////////
// GetDeviceTypeToUse returns the device object type of the next lower device
// object. This helps overcome a bug in some Win2K file systems which expect the
// topmost FiDO in a storage stack to have a VPB and, hence, to have been created
// with a type such as FILE_DEVICE_DISK.

#pragma PAGEDCODE

ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo)
	{							// GetDeviceTypeToUse
	PDEVICE_OBJECT ldo = IoGetAttachedDeviceReference(pdo);
	if (!ldo)
		return FILE_DEVICE_UNKNOWN;
	ULONG devtype = ldo->DeviceType;
	ObDereferenceObject(ldo);
	return devtype;
	}							// GetDeviceTypeToUse

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

#pragma LOCKEDCODE

NTSTATUS PowerCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
	{							// PowerCompletionRoutine

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG fcn = stack->MinorFunction;
	NTSTATUS status = Irp->IoStatus.Status;

	if (fcn < arraysize(powminor))
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%s) completes with %X\n", powminor[fcn], status);
	else
		PowerTrace(pdx, DRIVERNAME " - IRP_MJ_POWER (%X) completes with %X\n", fcn, status);

	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return STATUS_SUCCESS;
	}							// PowerCompletionRoutine

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

#pragma PAGEDCODE

VOID PowerTraceMessage(char* msg)
	{							// PowerTraceMessage

	// Serialize access to the output file

	KeEnterCriticalRegion();
	ExAcquireFastMutexUnsafe(&filelock);

	// Open logging file. We want output flushed through to disk each time.

	UNICODE_STRING filename;
	RtlInitUnicodeString(&filename, L"\\SystemRoot\\powtrace.log");
	OBJECT_ATTRIBUTES oa;
	InitializeObjectAttributes(&oa, &filename, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
		NULL, NULL);
	HANDLE hfile;
	IO_STATUS_BLOCK iosb;
	NTSTATUS status = ZwCreateFile(&hfile, FILE_APPEND_DATA, &oa, &iosb, NULL, FILE_ATTRIBUTE_NORMAL,
		0, FILE_OPEN_IF, FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
	if (!NT_SUCCESS(status))
		{
		KdPrint((DRIVERNAME " - ZwCreateFile failed - %X\n", status));
		}

	// Write line to file, then cleanup and exit

	else
		{
		ZwWriteFile(hfile, NULL, NULL, NULL, &iosb, msg, strlen(msg), NULL, NULL);
		ZwClose(hfile);
		}

	ExReleaseFastMutexUnsafe(&filelock);
	KeLeaveCriticalRegion();
	}							// PowerTraceMessage

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

#pragma PAGEDCODE

VOID PowerTraceWorkitem(PDEVICE_OBJECT fdo, PPOWTRACE_CONTEXT ctx)
	{							// PowerTraceWorkitem
	PowerTraceMessage(ctx->msg);
	IoFreeWorkItem(ctx->item);
	ExFreePool(ctx);
	}							// PowerTraceWorkitem

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

#pragma LOCKEDCODE

VOID PowerTrace(PDEVICE_EXTENSION pdx, char* ctl, ...)
	{							// PowerTrace
	char msgbuf[256];
	_vsnprintf(msgbuf, arraysize(msgbuf), ctl, (va_list) (&ctl + 1));
	DbgPrint("%s", msgbuf);

	if (!pdx || !pdx->filetrace)
		return;

	if (KeGetCurrentIrql() < DISPATCH_LEVEL)
		PowerTraceMessage(msgbuf);
	else
		{
		PPOWTRACE_CONTEXT ctx = (PPOWTRACE_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(POWTRACE_CONTEXT) + strlen(msgbuf));
		if (!ctx)
			return;
		strcpy(ctx->msg, msgbuf);
		ctx->item = IoAllocateWorkItem(pdx->DeviceObject);
		if (!ctx->item)
			{
			ExFreePool(ctx);
			return;
			}
		IoQueueWorkItem(ctx->item,	(PIO_WORKITEM_ROUTINE) PowerTraceWorkitem, CriticalWorkQueue, ctx);
		}
	}							// PowerTrace

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

#pragma PAGEDCODE

VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
	{							// RemoveDevice
	PAGED_CODE();
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	NTSTATUS status;

	if (pdx->LowerDeviceObject)
		IoDetachDevice(pdx->LowerDeviceObject);

	IoDeleteDevice(fdo);
	}							// RemoveDevice

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

#pragma LOCKEDCODE

VOID ShowCapabilities(PDEVICE_EXTENSION pdx, PDEVICE_CAPABILITIES pdc)
	{							// ShowCapabilities
	PowerTrace(pdx, DRIVERNAME " - Results of IRP_MN_QUERY_CAPABILITIES\n");
	PowerTrace(pdx, DRIVERNAME " - Size = %X\n", pdc->Size);
	PowerTrace(pdx, DRIVERNAME " - Version = %X\n", pdc->Version);
	PowerTrace(pdx, DRIVERNAME " - DeviceD1 = %X\n", pdc->DeviceD1);
	PowerTrace(pdx, DRIVERNAME " - DeviceD2 = %X\n", pdc->DeviceD2);
	PowerTrace(pdx, DRIVERNAME " - LockSupported = %X\n", pdc->LockSupported);
	PowerTrace(pdx, DRIVERNAME " - EjectSupported = %X\n", pdc->EjectSupported);
	PowerTrace(pdx, DRIVERNAME " - Removable = %X\n", pdc->Removable);
	PowerTrace(pdx, DRIVERNAME " - DockDevice = %X\n", pdc->DockDevice);
	PowerTrace(pdx, DRIVERNAME " - UniqueID = %X\n", pdc->UniqueID);
	PowerTrace(pdx, DRIVERNAME " - SilentInstall = %X\n", pdc->SilentInstall);
	PowerTrace(pdx, DRIVERNAME " - RawDeviceOK = %X\n", pdc->RawDeviceOK);
	PowerTrace(pdx, DRIVERNAME " - SurpriseRemovalOK = %X\n", pdc->SurpriseRemovalOK);
	PowerTrace(pdx, DRIVERNAME " - WakeFromD0 = %X\n", pdc->WakeFromD0);
	PowerTrace(pdx, DRIVERNAME " - WakeFromD1 = %X\n", pdc->WakeFromD1);
	PowerTrace(pdx, DRIVERNAME " - WakeFromD2 = %X\n", pdc->WakeFromD2);
	PowerTrace(pdx, DRIVERNAME " - WakeFromD3 = %X\n", pdc->WakeFromD3);
	PowerTrace(pdx, DRIVERNAME " - HardwareDisabled = %X\n", pdc->HardwareDisabled);
	PowerTrace(pdx, DRIVERNAME " - NonDynamic = %X\n", pdc->NonDynamic);
	PowerTrace(pdx, DRIVERNAME " - WarmEjectSupported = %X\n", pdc->WarmEjectSupported);
	PowerTrace(pdx, DRIVERNAME " - NoDisplayInUI = %X\n", pdc->NoDisplayInUI);

	PowerTrace(pdx, DRIVERNAME " - Address = %X\n", pdc->Address);
	PowerTrace(pdx, DRIVERNAME " - UINumber = %X\n", pdc->UINumber);

	for (int i = 0; i < (int) POWER_SYSTEM_MAXIMUM; ++i)
		PowerTrace(pdx, DRIVERNAME " - DeviceState[%s] = %s\n", sysnames[i], devnames[pdc->DeviceState[i]]);

	PowerTrace(pdx, DRIVERNAME " - SystemWake = %s\n", sysnames[pdc->SystemWake]);
	PowerTrace(pdx, DRIVERNAME " - DeviceWake = %s\n", devnames[pdc->DeviceWake]);
	PowerTrace(pdx, DRIVERNAME " - D1Latency = %X\n", pdc->D1Latency);
	PowerTrace(pdx, DRIVERNAME " - D2Latency = %X\n", pdc->D2Latency);
	PowerTrace(pdx, DRIVERNAME " - D3Latency = %X\n", pdc->D3Latency);
	}							// ShowCapabilities

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

#pragma LOCKEDCODE

NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
	{							// StartDeviceCompletionRoutine
	if (Irp->PendingReturned)
		IoMarkIrpPending(Irp);

	// Inherit FILE_REMOVABLE_MEDIA flag from lower object. This is necessary
	// for a disk filter, but it isn't available until start-device time. Drivers
	// above us may examine the flag as part of their own start-device processing, too.

	if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
		fido->Characteristics |= FILE_REMOVABLE_MEDIA;

	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return STATUS_SUCCESS;
	}							// StartDeviceCompletionRoutine

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

#pragma LOCKEDCODE

NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
	{							// UsageNotificationCompletionRoutine
	if (Irp->PendingReturned)
		IoMarkIrpPending(Irp);

	// If lower driver cleared pageable flag, we must do the same

	if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
		fido->Flags &= ~DO_POWER_PAGABLE;

	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return STATUS_SUCCESS;
	}							// UsageNotificationCompletionRoutine

#pragma LOCKEDCODE				// force inline functions into nonpaged code

⌨️ 快捷键说明

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