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

📄 driverentry.cpp

📁 Microsoft Windows驱动程序模型设计 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
	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);
	IoSkipCurrentIrpStackLocation(Irp);
	status = PoCallDriver(pdx->LowerDeviceObject, Irp);
	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return status;
	}							// DispatchPower

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

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

	KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));

	BOOLEAN backend = FALSE;
	
	if (fcn == IRP_MN_START_DEVICE)
		{
		ReportAssignedResources(stack->Parameters.StartDevice.AllocatedResources,
			stack->Parameters.StartDevice.AllocatedResourcesTranslated);
		}
	else if (fcn == IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
		{
		PIO_RESOURCE_REQUIREMENTS_LIST list = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->IoStatus.Information;
		if (!list)
			list = stack->Parameters.FilterResourceRequirements.IoResourceRequirementList;
		ReportRequiredResources(list);
		backend = TRUE;
		}
	else if (fcn == IRP_MN_QUERY_RESOURCE_REQUIREMENTS || fcn == IRP_MN_QUERY_RESOURCES)
		backend = TRUE;

	// Install a completion routine for diagnostic purposes. Note that using a completion
	// routine is not something that filter drivers necessarily have to do here -- I'm 
	// only doing it so this driver can print some interesting information about
	// resource requirements

	if (backend)
		{						// pass down with completion routine
		ASSERT(fcn != IRP_MN_REMOVE_DEVICE);
		IoCopyCurrentIrpStackLocationToNext(Irp);
		IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnPnpComplete, (PVOID) pdx, TRUE, TRUE, TRUE);
		return IoCallDriver(pdx->LowerDeviceObject, Irp);
		}						// pass down with completion routine
	else
		{						// pass down without completion routine
		IoSkipCurrentIrpStackLocation(Irp);
		status = IoCallDriver(pdx->LowerDeviceObject, Irp);

		if (fcn == IRP_MN_REMOVE_DEVICE)
			{
			IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
			RemoveDevice(fido);
			}
		else
			IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

		return status;
		}						// pass down without completion routine

#else // not DBG

	IoSkipCurrentIrpStackLocation(Irp);
	status = IoCallDriver(pdx->LowerDeviceObject, Irp);

	if (fcn == IRP_MN_REMOVE_DEVICE)
		{
		IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
		RemoveDevice(fido);
		}
	else
		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

	return status;

#endif // not DBG
	}							// DispatchPnp

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

NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp)
	{							// DispatchWmi
#if DBG
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG fcn = stack->MinorFunction;

	static char* fcnname[] = {
		"IRP_MN_QUERY_ALL_DATA",
		"IRP_MN_QUERY_SINGLE_INSTANCE",
		"IRP_MN_CHANGE_SINGLE_INSTANCE",
		"IRP_MN_CHANGE_SINGLE_ITEM",
		"IRP_MN_ENABLE_EVENTS",
		"IRP_MN_DISABLE_EVENTS",
		"IRP_MN_ENABLE_COLLECTION",
		"IRP_MN_DISABLE_COLLECTION",
		"IRP_MN_REGINFO",
		"IRP_MN_EXECUTE_METHOD",
		};

	KdPrint((DRIVERNAME " - IRP_MJ_SYSTEM_CONTROL (%s)\n", fcnname[fcn]));
#endif // DBG

	NTSTATUS status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
	status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
	if (!NT_SUCCESS(status))
		return CompleteRequest(Irp, status, 0);
	IoSkipCurrentIrpStackLocation(Irp);
	status = IoCallDriver(pdx->LowerDeviceObject, Irp);
	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return status;
	}							// DispatchWmi

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

#pragma PAGEDCODE

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

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

	IoDeleteDevice(fido);
	}							// RemoveDevice

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

#pragma INITCODE

BOOLEAN IsWin98()
	{							// IsWin98
#ifdef _X86_
	return !IoIsWdmVersionAvailable(1, 0x10);
#else // not _X86_
	return FALSE;
#endif // not _X86_
	}							// IsWin98

#if DBG

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

#ifdef _X86_

#pragma LOCKEDCODE

extern "C" void __declspec(naked) __cdecl _chkesp()
	{
	_asm je okay
	ASSERT(!DRIVERNAME " - Stack pointer mismatch!");
okay:
	_asm ret
	}

#endif // _X86_

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

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

	if (Irp->PendingReturned)
		IoMarkIrpPending(Irp);

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG fcn = stack->MinorFunction;
	DbgPrint(DRIVERNAME " - IRP_MN_PNP (%s) complete\n", pnpname[fcn]);

	switch (fcn)
		{						// select on subfunction

	case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
	case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 
		ReportRequiredResources((PIO_RESOURCE_REQUIREMENTS_LIST) Irp->IoStatus.Information);
		break;

	case IRP_MN_QUERY_RESOURCES:
		ReportAssignedResources((PCM_RESOURCE_LIST) Irp->IoStatus.Information, NULL);
		break;
		}						// select on subfunction

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

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

VOID ReportAssignedResources(PCM_RESOURCE_LIST raw, PCM_RESOURCE_LIST translated)
	{							// ReportAssignedResources
	if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
		return;					// resource lists are in paged memory

	if (raw)
		{						// show untranslated resources
		DbgPrint(DRIVERNAME " - Resources:\n");
		ShowResources(&raw->List[0].PartialResourceList);
		}						// show untranslated resources

	if (translated)
		{						// show translated resources
		DbgPrint(DRIVERNAME " - Translated Resources:\n");
		ShowResources(&translated->List[0].PartialResourceList);
		}						// show translated resources

	}							// ReportAssignedResources

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

VOID ReportRequiredResources(PIO_RESOURCE_REQUIREMENTS_LIST list)
	{							// ReportRequiredResources
	if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
		return;					// resource lists are in paged memory

	if (!list)
		return;					// nothing to do

	ULONG numlists = list->AlternativeLists;
	PIO_RESOURCE_LIST reslist = list->List;
	while (numlists--)
		{						// for each list
		DbgPrint("  Requirements list:\n");
		PIO_RESOURCE_DESCRIPTOR resource = reslist->Descriptors;
		ULONG nres = reslist->Count;
		for (; nres; --nres, ++resource)
			{					// for each resource
			ULONG type = resource->Type;
			DbgPrint("    Type %s", type < arraysize(restypes) ? restypes[type] : "unknown");
			switch (type)
				{				// switch on resource type

			case CmResourceTypePort:
			case CmResourceTypeMemory:
				DbgPrint(" Length %d, Alignment %X, MinimumAddress %8X%8.8lX, MaximumAddress %8X%8.8lX\n",
					resource->u.Port.Length, resource->u.Port.Alignment,
					resource->u.Port.MinimumAddress, resource->u.Port.MaximumAddress);
				break;

			case CmResourceTypeInterrupt:
				DbgPrint(" MinimumVector %X, MaximumVector %X, shared %d\n",
					resource->u.Interrupt.MinimumVector, resource->u.Interrupt.MaximumVector,
					resource->ShareDisposition == CmResourceShareShared);
				break;

			case CmResourceTypeDma:
				DbgPrint(" MinimumChannel %d, MaximumChannel %d\n",
					resource->u.Dma.MinimumChannel, resource->u.Dma.MaximumChannel);
				break;

			default:
				DbgPrint(" %X %X %X\n", resource->u.DevicePrivate.Data[0],
					resource->u.DevicePrivate.Data[1], resource->u.DevicePrivate.Data[2]);
				break;
				}				// switch on resource type
			}					// for each resource

		reslist = (PIO_RESOURCE_LIST) resource;
		}						// for each list
	}							// ReportRequiredResources

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

VOID ShowResources(IN PCM_PARTIAL_RESOURCE_LIST list)
	{							// ShowResources
	PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = list->PartialDescriptors;
	ULONG nres = list->Count;
	ULONG i;

	for (i = 0; i < nres; ++i, ++resource)
		{						// for each resource
		ULONG type = resource->Type;

		KdPrint(("    Type %s", type < arraysize(restypes) ? restypes[type] : "unknown"));

		switch (type)
			{					// select on resource type
		case CmResourceTypePort:
		case CmResourceTypeMemory:
			KdPrint((" start %8X%8.8lX length %X\n",
				resource->u.Port.Start.HighPart, resource->u.Port.Start.LowPart,
				resource->u.Port.Length));
			break;
		
		case CmResourceTypeInterrupt:
			KdPrint(("  level %X, vector %X, affinity %X, shared %d\n",
				resource->u.Interrupt.Level, resource->u.Interrupt.Vector,
				resource->u.Interrupt.Affinity, resource->ShareDisposition == CmResourceShareShared));
			break;
	
		case CmResourceTypeDma:
			KdPrint(("  channel %d, port %X\n",
				resource->u.Dma.Channel, resource->u.Dma.Port));
			break;

		default:
			KdPrint(("\n"));
			break;
			}					// select on resource type
		}						// for each resource
	}							// ShowResources

#endif // DBG

⌨️ 快捷键说明

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