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

📄 plugplayfdo.cpp

📁 Programming the Microsoft Windows driver model.2nd 随书光盘。内有很多作者送的实用工具和随书源码。WDM编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:


	if (pdx->sarefcnt)

		return CompleteRequest(Irp, STATUS_UNSUCCESSFUL);	// have referenced suballoc interface



	if (pdx->state == WORKING)

		{						// currently working



	#ifdef _X86_



		// Win98 doesn't check for open handles before allowing a remove to proceed,

		// and it may deadlock in IoReleaseRemoveLockAndWait if handles are still

		// open.



		if (win98 && pdx->DeviceObject->ReferenceCount)

			{

			KdPrint((DRIVERNAME " - Failing removal query due to open handles\n"));

			return CompleteRequest(Irp, STATUS_DEVICE_BUSY, 0);

			}



	#endif

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

		}						// currently working



	// Save current state for restoration if the query gets cancelled.

	// (We can now be stopped or working)



	pdx->prevstate = pdx->state;

	pdx->state = PENDINGREMOVE;

	return DefaultPnpHandler(fdo, Irp);

	}							// HandleQueryRemove



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



static NTSTATUS HandleQueryStop(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleQueryStop

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	if (pdx->sarefcnt)

		return CompleteRequest(Irp, STATUS_UNSUCCESSFUL);	// have referenced suballoc interface

	

	// 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



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



static NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleRemoveDevice

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	// Win98 doesn't send a SURPRISE_REMOVE, so now is the first time we'll

	// know that the device was removed.



	if (pdx->state != PENDINGREMOVE && pdx->state != SURPRISEREMOVED)

		{						// Win98 surprise removal

		KdPrint((DRIVERNAME " - IRP_MN_REMOVE_DEVICE received by surprise\n"));

		StopDevice(fdo, FALSE);

		}						// Win98 surprise removal



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

	pdx->state = REMOVED;

	IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);



	// Do any processing required for *us* to remove the device. This

	// would include completing any outstanding requests, etc. In general,

	// the routine we call here should not touch the hardware because it

	// may already be gone.



	StopDevice(fdo, FALSE);



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

	// result eventuates.



	NTSTATUS status = DefaultPnpHandler(fdo, Irp);



	// Remove the device object



	RemoveDevice(fdo);



	return status;				// lower-level completed IoStatus already

	}							// HandleRemoveDevice



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



static NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleStartDevice

	NTSTATUS status = ForwardAndWait(fdo, Irp);

	if (!NT_SUCCESS(status))

		return CompleteRequest(Irp, status, Irp->IoStatus.Information);



	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



	PCM_PARTIAL_RESOURCE_LIST raw;

	if (stack->Parameters.StartDevice.AllocatedResources)

		raw = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;

	else

		raw = NULL;



	PCM_PARTIAL_RESOURCE_LIST translated;

	if (stack->Parameters.StartDevice.AllocatedResourcesTranslated)

		translated = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;

	else

		translated = NULL;



#if DBG

	if (raw)

		{

		KdPrint((DRIVERNAME " - Resources:\n"));

		ShowResources(raw);

		}

	if (translated)

		{

		KdPrint((DRIVERNAME " - Translated Resources:\n"));

		ShowResources(translated);

		}

#endif // DBG



	status = StartDevice(fdo, raw, translated);



	// 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

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

		pdx->state = WORKING;

		}						// started okay



	return CompleteRequest(Irp, status, 0);

	}							// HandleStartDevice



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



static NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleStopDevice

	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



	if (pdx->state != PENDINGSTOP)

		return DefaultPnpHandler(fdo, Irp);



	StopDevice(fdo, TRUE);		// TRUE means okay to touch hardware

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

	pdx->state = STOPPED;

	return DefaultPnpHandler(fdo, Irp);

	}							// HandleStopDevice



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



static NTSTATUS HandleSurpriseRemoval(IN PDEVICE_OBJECT fdo, IN PIRP Irp)

	{							// HandleSurpriseRemoval

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;



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

	pdx->state = SURPRISEREMOVED;



	// Release I/O resources without touching the hardware



	StopDevice(fdo, FALSE);

	

	// Set status field as a signal to PDO that we've handled this IRP



	Irp->IoStatus.Status = STATUS_SUCCESS;



	return DefaultPnpHandler(fdo, Irp);

	}							// HandleSurpriseRemoval



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



#if DBG



static 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;



		static char* name[] = {

			"CmResourceTypeNull",

			"CmResourceTypePort",

			"CmResourceTypeInterrupt",

			"CmResourceTypeMemory",

			"CmResourceTypeDma",

			"CmResourceTypeDeviceSpecific",

			"CmResourceTypeBusNumber",

			"CmResourceTypeDevicePrivate",

			"CmResourceTypeAssignedResource",

			"CmResourceTypeSubAllocateFrom",

			};



		KdPrint(("    type %s", type < arraysize(name) ? name[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\n",

				resource->u.Interrupt.Level, resource->u.Interrupt.Vector,

				resource->u.Interrupt.Affinity));

			break;

	

		case CmResourceTypeDma:

			KdPrint(("  channel %d, port %X\n",

				resource->u.Dma.Channel, resource->u.Dma.Port));

			}					// select on resource type

		}						// for each resource

	}							// ShowResources



#endif // DBG



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



static NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated)

	{							// StartDevice

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	NTSTATUS status = STATUS_SUCCESS;



	// Scan raw and translated resource descriptor lists to save description of the

	// two port resources we expect to find. The 1-port resource is for child A,

	// the 2-port resource is for child B.



	BOOLEAN gotportAraw = FALSE;

	BOOLEAN gotportBraw = FALSE;

	BOOLEAN gotportAtranslated = FALSE;

	BOOLEAN gotportBtranslated = FALSE;



	if (!raw || !translated)

		return STATUS_DEVICE_CONFIGURATION_ERROR;



	PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = raw->PartialDescriptors;

	ULONG nres = raw->Count;

	for (ULONG i = 0; i < nres; ++i, ++resource)

		{						// scan raw resources

		if (resource->Type != CmResourceTypePort)

			continue;			// ignore unexpected resource

		if (resource->u.Port.Length == 1)

			pdx->PortARaw = *resource, gotportAraw = TRUE;

		else

			pdx->PortBRaw = *resource, gotportBraw = TRUE;

		}						// scan raw resources



	resource = translated->PartialDescriptors;

	nres = raw->Count;

	for (i = 0; i < nres; ++i, ++resource)

		{						// scan raw resources

		if (resource->Type != CmResourceTypePort)

			continue;			// ignore unexpected resource

		if (resource->u.Port.Length == 1)

			pdx->PortATranslated = *resource, gotportAtranslated = TRUE;

		else

			pdx->PortBTranslated = *resource, gotportBtranslated = TRUE;

		}						// scan raw resources



	if (!(gotportAraw && gotportBraw && gotportAtranslated && gotportBtranslated))

		return STATUS_DEVICE_CONFIGURATION_ERROR;



	// Create device objects (PDOs) for the two child devices this sample has.

	// Real multifunction or controller devices might have more elaborate

	// ways of detecting their children, of course.



	if (!pdx->ChildA)

		status = CreateChild(pdx, CHILDTYPEA, &pdx->ChildA);

	if (!pdx->ChildB && NT_SUCCESS(status))

		{

		status = CreateChild(pdx, CHILDTYPEB, &pdx->ChildB);

		if (!NT_SUCCESS(status))

			{

			IoDeleteDevice(pdx->ChildA);

			pdx->ChildA = NULL;

			}

		}



	return status;

	}							// StartDevice



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



static VOID StopDevice(PDEVICE_OBJECT fdo, BOOLEAN oktouch)

	{							// StopDevice

	}							// StopDevice

⌨️ 快捷键说明

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