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

📄 plugplayfdo.cpp

📁 programming windows driver mode源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			newrel->Objects[newrel->Count++] = pdx->ChildA;
			}
		
		if (pdx->ChildB)
			{
			ObReferenceObject(pdx->ChildB);
			newrel->Objects[newrel->Count++] = pdx->ChildB;
			}

		Irp->IoStatus.Information = (ULONG_PTR) newrel;
		}						// build new list
	else
		status = STATUS_INSUFFICIENT_RESOURCES;

	Irp->IoStatus.Status = status;
	return DefaultPnpHandler(fdo, Irp);
	}							// HandleQueryRelations

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

static NTSTATUS HandleQueryRemove(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
	{							// HandleQueryRemove
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	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;
	
	// 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;

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