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

📄 driverentry.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 CPP
字号:
// Main program for hidfake driver
// Copyright (C) 2001 by Walter Oney
// All rights reserved

#include "stddcls.h"
#include "driver.h"

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT fdo);
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS PowerUpCompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx);

struct INIT_STRUCT : public _GENERIC_INIT_STRUCT {
//	QSIO morequeues[1];			// additional devqueue/sio pointers
	};

BOOLEAN win98 = FALSE;
BOOLEAN winXP = FALSE;

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

#pragma PAGEDCODE

extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
	IN PUNICODE_STRING RegistryPath)
	{							// DriverEntry
	KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject));

	if (GenericGetVersion() < 0x00010003)
		{
		KdPrint((DRIVERNAME " - Required version (1.3) of GENERIC.SYS not installed\n"));
		return STATUS_UNSUCCESSFUL;
		}

	// See if we're running under Win98 or NT:

	win98 = IsWin98();

#if DBG
	if (win98)
		KdPrint((DRIVERNAME " - Running under Windows 98\n"));
	else
		KdPrint((DRIVERNAME " - Running under NT\n"));
#endif

	// We need to handle IRP_MN_QUERY_ID specially in systems prior to XP, so determine
	// now whether we're in XP or not

	winXP = IoIsWdmVersionAvailable(1, 0x20);

	// In other of my sample drivers, I copy the RegistryPath key here. There's no point in
	// a HID minidriver because HIDCLASS will be handling any WMI requests that occur (and none
	// will, because there are no Microsoft standard classes for HID devices).

	// Initialize function pointers

	DriverObject->DriverUnload = DriverUnload;
	DriverObject->DriverExtension->AddDevice = AddDevice;

	DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalControl;
	DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
	DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;

	// This is a HID minidriver, so register with HIDCLASS. To make it easier
	// for the test application to give us dummy report data, we claim to be
	// polled. Most real HID devices are not polled, actually.

	HID_MINIDRIVER_REGISTRATION reg;
	RtlZeroMemory(&reg, sizeof(reg));
	reg.Revision = HID_REVISION;
	reg.DriverObject = DriverObject;
	reg.RegistryPath = RegistryPath;
	reg.DeviceExtensionSize = sizeof(DEVICE_EXTENSION) + GetSizeofGenericExtension();
	reg.DevicesArePolled = TRUE;
	
	return HidRegisterMinidriver(&reg);
	}							// DriverEntry

///////////////////////////////////////////////////////////////////////////////
// The DriverUnload callback for a HID minidriver releases resources allocated
// in DriverEntry. This driver doesn't need any cleanup, however, so this is
// a nearly empty function.

#pragma PAGEDCODE

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
	{							// DriverUnload
	PAGED_CODE();
	KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject));
	}							// DriverUnload

///////////////////////////////////////////////////////////////////////////////
// AddDevice callback. Note that we do *not* create a device object in this
// callback. HIDCLASS has already done that. Our job is simply to initialize
// our device extension.

#pragma PAGEDCODE

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT fdo)
	{							// AddDevice
	PAGED_CODE();
	KdPrint((DRIVERNAME " - Entering AddDevice: DriverObject %8.8lX, fdo %8.8lX\n", DriverObject, fdo));

	NTSTATUS status = STATUS_SUCCESS;
	
	PDEVICE_EXTENSION pdx = PDX(fdo);
	BOOLEAN ginit = FALSE;

	// From this point forward, any error will have side effects that need to
	// be cleaned up. Using a do-once block allows us to modify the program
	// easily without losing track of the side effects.

	do
		{						// finish initialization

		// Initialize to use the GENERIC.SYS library

		pdx->pgx = (PGENERIC_EXTENSION) ((PUCHAR) pdx + sizeof(DEVICE_EXTENSION));

		INIT_STRUCT gis;
		RtlZeroMemory(&gis, sizeof(gis));
		gis.Size = sizeof(gis);
		gis.DeviceObject = fdo;
		gis.Pdo = PDO(fdo);
		gis.Ldo = LDO(fdo);
		gis.RemoveLock = &pdx->RemoveLock;
		gis.StartDevice = StartDevice;
		gis.StopDevice = StopDevice;
		gis.RemoveDevice = RemoveDevice;
		RtlInitUnicodeString(&gis.DebugName, LDRIVERNAME);

		status = InitializeGenericExtension(pdx->pgx, &gis);
		if (!NT_SUCCESS(status))
			{
			KdPrint((DRIVERNAME " - InitializeGenericExtension failed - %X\n", status));
			break;
			}
		ginit = TRUE;

		// Indicate that the device is initially in the D0 power state

		pdx->devpower = PowerDeviceD0;

		}						// finish initialization
	while (FALSE);

	if (!NT_SUCCESS(status))
		{					// need to cleanup
		if (ginit)
			CleanupGenericExtension(pdx->pgx);
		}					// need to cleanup

	// HIDCLASS ignores our return code, so save the status code in the
	// device extension for use by StartDevice

	pdx->AddDeviceStatus = status;
	return STATUS_SUCCESS;
	}							// AddDevice

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

#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(PIRP Irp, NTSTATUS status)
	{							// CompleteRequest
	Irp->IoStatus.Status = status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
	}							// CompleteRequest

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

///////////////////////////////////////////////////////////////////////////////
// The DispatchPnp callback for a HID minidriver does pretty much what any
// function driver would do. We delegate the IRPs to GENERIC, which calls
// back to StartDevice, StopDevice, and RemoveDevice functions.

#pragma PAGEDCODE

NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp)
	{							// DispatchPnp
	PDEVICE_EXTENSION pdx = PDX(fdo);	
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	// Handle IRP_MN_QUERY_ID separately prior to XP because the root enumerator
	// will succeed the request and give back a NULL id

	if (!winXP 
		&& stack->MinorFunction == IRP_MN_QUERY_ID 
		&& !NT_SUCCESS(Irp->IoStatus.Status))
		{						// handle QUERY_ID
		ASSERT(!Irp->IoStatus.Information);	// should be NULL if no-one has handled this IRP
		PWCHAR idstring;

#if DBG
		static char* names[] = {
			"BusQueryDeviceID",
			"BusQueryHardwareIDs",
			"BusQueryCompatibleIDs",
			"BusQueryInstanceID",
			"BusQueryDeviceSerialNumber",
			};

		ULONG type = stack->Parameters.QueryId.IdType;
		if (type < arraysize(names))
			KdPrint((DRIVERNAME " - IRP_MN_QUERY_ID(%s)\n", names[type]));
		else
			KdPrint((DRIVERNAME " - IRP_MN_QUERY_ID(%d)\n", type));
#endif

		switch (stack->Parameters.QueryId.IdType)
			{					// select on query type

		case BusQueryInstanceID:
			idstring = L"0000";
			break;

		case BusQueryDeviceID:
			idstring = L"ROOT\\*WCO0D01";
			break;

		case BusQueryHardwareIDs:
			idstring = L"*WCO0D01";
			break;

		default:
			return CompleteRequest(Irp);
			}					// select on query type

		ULONG nchars = wcslen(idstring);
		ULONG size = (nchars + 2) * sizeof(WCHAR);	// room for 2 null terminators
		PWCHAR id = (PWCHAR) ExAllocatePool(PagedPool, size);
		if (!id)
			return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES);
		wcscpy(id, idstring);
		id[nchars + 1] = 0;		// in case someone is expecting MULTI_SZ
		return CompleteRequest(Irp, STATUS_SUCCESS, (ULONG_PTR) id);
		}						// handle QUERY_ID

	return GenericDispatchPnp(PDX(fdo)->pgx, Irp);
	}							// DispatchPnp

///////////////////////////////////////////////////////////////////////////////
// The DispatchPower callback for a HID minidriver need only worry about saving and
// restoring device context. The framework provided by HIDCLASS might force you
// to block the system thread while doing this, which is not ideal but won't cause
// deadlocks as long as you don't issue any power IRPs.

#pragma PAGEDCODE

NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp)
	{							// DispatchPower
	PDEVICE_EXTENSION pdx = PDX(fdo);	
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	IoCopyCurrentIrpStackLocationToNext(Irp);

	// Check for D-set operation. Note that we needn't call PoStartNextPowerIrp
	// because HIDCLASS has already done so.

	if (stack->MinorFunction == IRP_MN_SET_POWER && stack->Parameters.Power.Type == DevicePowerState)
		{						// device set-power
		DEVICE_POWER_STATE newstate = stack->Parameters.Power.State.DeviceState;
		KdPrint((DRIVERNAME " - Setting power state D%d\n", newstate - 1));
		if (newstate == PowerDeviceD0)
			{					// restoring power
			IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) PowerUpCompletionRoutine, (PVOID) pdx,
				TRUE, TRUE, TRUE);
			}					// restoring power
		else if (pdx->devpower == PowerDeviceD0)
			{					// powering down
			// TODO save context information, if any
			pdx->devpower = newstate;
			}					// powering down
		}						// device set-power

	// Forward all other IRPs (and D-sets that lower power below D0)

	return PoCallDriver(LDO(fdo), Irp);
	}							// DispatchPower

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

#pragma LOCKEDCODE

NTSTATUS PowerUpCompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx)
	{							// PowerUpCompletionRoutine
	// TODO restore device context without blocking this thread
	pdx->devpower = PowerDeviceD0;
	return STATUS_SUCCESS;		// allow IRP to continue completing
	}							// PowerUpCompletionRoutine

///////////////////////////////////////////////////////////////////////////////
// The RemoveDevice function for a HID minidriver merely cleans up resources
// allocated in the AddDevice callback. It does not delete the device object
// (HIDCLASS does that).

#pragma PAGEDCODE

VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
	{							// RemoveDevice
	PAGED_CODE();
	}							// RemoveDevice

#pragma LOCKEDCODE				// force inline functions into nonpaged code

⌨️ 快捷键说明

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