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

📄 driverentry.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						result = FALSE;
						}		// found higher version
					else
						KdPrint((DRIVERNAME " - Overriding WDMSTUB clone version %d.%2.2d\n", version >> 16, version & 0xFFFF));
					}			// check version #
				else
					KdPrint((DRIVERNAME " - IOCTL_INTERNAL_WDMSTUB_GET_VERSION failed to %ws - %X\n", devname, status));
				}				// send IRP

			// Dereference the file object to release our hold on the clone device object

			ObDereferenceObject(fop);
			}					// found a clone

		// If there's no device object by this name, remember the index for when we need to create our own
		// device object

		else if (avail == 0xFFFFFFFF)
			avail = index;
		}						// for each possible driver index

	// Check the result of the version comparisons

	if (!result)
		return FALSE;

	// We have decided to stub some functions. Create a dummy device object so
	// other clones can find us. Also take an extra reference to the driver object
	// to pin us into memory -- some other WDM driver may end up using one of our
	// stubs

	if (avail == 0xFFFFFFFF)
		{
		KdPrint((DRIVERNAME " - More than 100 WDMSTUB clones are loaded in this system!\n"));
		return FALSE;
		}

	_snwprintf(namebuf, arraysize(namebuf), L"\\Device\\WDMSTUB%d", avail);
	RtlInitUnicodeString(&devname, namebuf);

	status = IoCreateDevice(DriverObject, sizeof(DUMMY_DEVICE_EXTENSION), &devname, FILE_DEVICE_UNKNOWN, 0, FALSE, &DummyDeviceObject);
	if (!NT_SUCCESS(status))
		{
		KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
		return FALSE;
		}

	ObReferenceObject(DriverObject);	// pin this driver into memory forever

	// Initialize the dummy device extension so IRP dispatch functions can distinguish between this
	// and a layered device object

	PDUMMY_DEVICE_EXTENSION ddx = (PDUMMY_DEVICE_EXTENSION) DummyDeviceObject->DeviceExtension;
	ddx->flags |= DUMMY_DEVICE_FLAG;

	return TRUE;
	}							// CheckCloneVersions

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

#pragma LOCKEDCODE

NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
	{							// CompleteRequest
	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = info;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
	}							// CompleteRequest

NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status)
	{							// CompleteRequest
	Irp->IoStatus.Status = status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
	}							// CompleteRequest

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

#pragma LOCKEDCODE				// make no assumptions about pageability of dispatch fcns

NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
	{							// DispatchAny
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
	
	// Fail any IRPs addressed to the dummy device object other than CREATE and CLOSE

	if (pdx->flags & DUMMY_DEVICE_FLAG)
		{						// IRP for dummy device
		PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
		NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
		if (stack->MajorFunction == IRP_MJ_CREATE || stack->MajorFunction == IRP_MJ_CLOSE)
			status = STATUS_SUCCESS;
		return CompleteRequest(Irp, status);
		}						// IRP for dummy device

	// Pass down IRPs addressed to the FiDO

	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pdx->LowerDeviceObject, Irp);
	}							// DispatchAny

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

NTSTATUS DispatchInternalControl(PDEVICE_OBJECT dummy, PIRP Irp)
	{							// DispatchInternalControl
	PDUMMY_DEVICE_EXTENSION ddx = (PDUMMY_DEVICE_EXTENSION) dummy->DeviceExtension;
	if (!(ddx->flags & DUMMY_DEVICE_FLAG))
		{						// not for us
		IoSkipCurrentIrpStackLocation(Irp);
		return IoCallDriver(((PDEVICE_EXTENSION)(ddx))->LowerDeviceObject, Irp);
		}						// not for us

	NTSTATUS status;
	ULONG info = 0;
	
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
	ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
	ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;

	switch (code)
		{						// process internal control operation

	// Version query: return the version number of this driver

	case IOCTL_INTERNAL_WDMSTUB_GET_VERSION:
		if (cbout < sizeof(ULONG))
			{					// wrong output buffer length
			status = STATUS_INVALID_PARAMETER;
			break;
			}					// wrong output buffer length
		*(PULONG)(Irp->UserBuffer) = (VERMAJOR << 16) | VERMINOR;
		info = sizeof(ULONG);
		status = STATUS_SUCCESS;
		break;

	default:
		status = STATUS_INVALID_DEVICE_REQUEST;
		break;
		}						// process internal control operation

	return CompleteRequest(Irp, status, info);
	}							// DispatchInternalControl

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

#pragma LOCKEDCODE

NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
	{							// DispatchPower
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
	PoStartNextPowerIrp(Irp);	// must be done while we own the IRP

	if (pdx->flags & DUMMY_DEVICE_FLAG)
		return CompleteRequest(Irp, STATUS_SUCCESS);	// shouldn't happen in the 1st place

	IoSkipCurrentIrpStackLocation(Irp);
	return PoCallDriver(pdx->LowerDeviceObject, Irp);
	}							// DispatchPower

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

#pragma LOCKEDCODE

NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
	{							// DispatchPnp
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

	// The dummy device shouldn't get any PnP IRPs

	if (pdx->flags & DUMMY_DEVICE_FLAG)
		return CompleteRequest(Irp, STATUS_SUCCESS);	// don't change Information field

	// Pass down PnP request 

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	ULONG fcn = stack->MinorFunction;

	NTSTATUS status;

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

	if (fcn == IRP_MN_REMOVE_DEVICE)
		RemoveDevice(fido);

	return status;
	}							// DispatchPnp

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

#pragma PAGEDCODE

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
	{							// DriverUnload
	PAGED_CODE();

	// Delete our dummy device object

	if (DummyDeviceObject)
		IoDeleteDevice(DummyDeviceObject);

	// It should not be possible for this driver to be unloaded if we defined
	// any stubs. Don't preclude this, though, because there may be some future
	// mechanism that would make this safe.

	if (StubsDefined)
		UndefineStubs();
	}							// DriverUnload

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

#pragma PAGEDCODE

VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
	{							// RemoveDevice
	PAGED_CODE();
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	ASSERT(!(pdx->flags & DUMMY_DEVICE_FLAG));	// shouldn't be possible
	NTSTATUS status;

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

	IoDeleteDevice(fdo);
	}							// RemoveDevice

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

#pragma INITCODE

BOOLEAN IsWin98()
	{							// IsWin98
#ifdef _X86_

	// Windows 98 (including 2d ed) supports WDM version 1.0, whereas Win2K
	// supports 1.10.

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

#pragma LOCKEDCODE				// force inline functions into locked code

⌨️ 快捷键说明

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