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

📄 driver.cpp

📁 开发驱动的“hello world" 用来入门不错。
💻 CPP
字号:
// Driver.cpp -- Driver object management for STUPID.SYS (DFW version)
// Copyright (C) 2003 by Walter Oney
// All rights reserved

// STUPID.SYS is the simplest possible framework-based driver. It creates
// a DFWDRIVER object and relies on the framework to handle all aspects of
// interfacing with the PnP and Power Managers -- including creating a
// DFWDEVICE object in the AddDevice function. You should be able to install,
// disable, enable, and uninstall one or more STUPID devices and to put the
// computer through power cycles with them installed.

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

DFWSTATUS EvtDriverDeviceAdd(DFWDRIVER hDriver, DFWDEVICE hDevice);
VOID EvtDriverUnload(DFWDRIVER hDriver);

////////////////////////////////////////////////////////////////////////////////
// DriverEntry creates and initializes a framework driver object. This function
// is called at PASSIVE_LEVEL without any presentation lock and can therefore be
// kept in paged memory.

#pragma PAGEDCODE

extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
	{							// DriverEntry
	PAGED_CODE();

	// This driver uses DfwTraceDbgPrint to print a few debugging messages,
	// but best practice would be to use WPP tracing instead. Next best 
	// would be to call DfwTraceMessage (which goes only to the trace log)
	// and DfwTraceError (which goes both to the trace log and to the
	// debugger if the DbgVerifierDbgPrintOn option is set).

	DfwTraceDbgPrint(DRIVERNAME " - Version %d.%2.2d.%3.3d, %s %s\n",
		VERMAJOR, VERMINOR, BUILD, __DATE__, __TIME__);

	// Setup a driver configuration structure for use as a parameter to a
	// call to DfwDriverCreate. We could use the DFW_DRIVER_CONFIG_INIT
	// macro to help us do this, but (frankly) it doesn't add much value
	// over and above a C-standard initializer. For expository purposes,
	// I'm using explicit assignment statements here to do the initialization.
	// Note that the compiler would generate basically the same code for
	// the DFW_DRIVER_CONFIG_INIT macro, a complete declaration with
	// initializer, and the following. Note also that the presence of any
	// initializer causes the compiler to zero-initialize the remainder of
	// the structure.

	DFW_DRIVER_CONFIG config = {sizeof(DFW_DRIVER_CONFIG)};	// Size -- the size of the structure

	// DeviceExtensionSize is the size of the device extension structure
	// that the framework will allocate for each DFWDEVICE created by this
	// driver. More complex drivers would have a non-empty extension. Still
	// more complex drivers might be creating different types of
	// device object by calling DfwDeviceCreateChild or DfwDeviceCreateControlObject,
	// either of which has an extension-size argument.

	config.DeviceExtensionSize = 0;

	// RequestContextSize is the size of an optional context structure that
	// the framework will create for each DFWREQUEST (i.e., IRP). This
	// driver doesn't explicitly handle any IRPs, so this might as well be zero.

	config.RequestContextSize = 0;

	// Events contains pointers to "event" callback routines. A driver object
	// has two events: DeviceAdd (formerly known as AddDevice) and Unload
	// (formerly known as DriverUnload). The DeviceAdd callback is required,
	// even if it doesn't do anything except initialize a DFWDEVICE object with
	// default parameters.

	config.Events.EvtDriverDeviceAdd = EvtDriverDeviceAdd;

	// An Unload event callback would be needed only to undo any side effects
	// of this DriverEntry routine. There are none in this driver, so we could
	// leave out this callback. I like to see a debug message to tell me that
	// a driver has really unloaded, however, so I'm specifying that callback:

	config.Events.EvtDriverUnload = EvtDriverUnload;

	// No bits had been defined in DriverInitFlags at the time I wrote this
	// sample...

	config.DriverInitFlags = 0;

	// The LockingConfig specifies the synchronization behavior for the
	// whole driver. Since this driver doesn't actually do anything, it
	// hardly matters what we specify here. A plausible choice when you're
	// just starting out is DfwLockingDevice, in which the framework
	// serializes calls to all callbacks related to a particular device
	// object by using a per-device "presentation" lock.

	config.LockingConfig = DfwLockingDevice;

	// The ThreadingConfig specifies whether event callbacks to this driver
	// should be allowed to block their calling thread (synchronous) or
	// not (asynchronous). The preferred choice is asynchronous, which implies
	// use of a spin lock to synchronize event callbacks at DISPATCH_LEVEL.
	// Note that this behavior is quite a bit different than the regular WDM
	// model, in which driver routines can be called at several different IRQLs
	// and must synchronize using IRQL-appropriate locks.

	config.ThreadingConfig = DfwThreadingAsynchronous;

	// SynchronizationConfig is intended to specify how this driver synchronizes
	// hardware access. There is currently just one choice (None), which implies
	// that the driver has to do it's own interrupt synchronization. There may 
	// someday be another choice for DIRQL-level synchronization as with a WDM interrupt object.

	config.SynchronizationConfig = DfwSynchronizationNone;

	// Invoke DfwDriverCreate to create a framework driver object. The
	// third parameter to this function -- NULL in this example -- is
	// the address of an optional DFW_OBJECT_ATTRIBUTES structure that
	// could be used to specify a context-structure size and a destruction
	// callback. These things would be useful, perhaps, in a single-device
	// driver that kept all of its state information in a "driver extension"
	// structure that needed cleanup. I'm hard pressed to think of a situation
	// when I'd want to use them, though, given that there is an Unload callback.

	DFWDRIVER Driver;
	DFWSTATUS status = DfwDriverCreate(DriverObject, RegistryPath, NULL, 
		&config, &Driver);

	if (!NT_SUCCESS(status))
		DfwTraceError(DRIVERNAME " - DfwDriverCreate failed - %X\n", status);

	// Return the status code from DfwDriverCreate.

	return status;
	}							// DriverEntry

////////////////////////////////////////////////////////////////////////////////
// The framework calls EvtDriverDeviceAdd to initialize a new device object.

#pragma LOCKEDCODE

DFWSTATUS EvtDriverDeviceAdd(DFWDRIVER hDriver, DFWDEVICE hDevice)
	{							// EvtDriverDeviceAdd
	DfwTraceDbgPrint(DRIVERNAME " - EvtDriverDeviceAdd entered - IRQL is %d\n", KeGetCurrentIrql());
	DFWSTATUS status;

	// In a more complex driver, we would do many things in this function. For example,
	// prior to calling DfwDeviceInitialize, we might:
	//	.Call DfwDeviceSetDeviceName to establish the name for the DEVICE_OBJECT
	//	.Call DfwDeviceSetDeviceType to establish the type for the DEVICE_OBJECT
	//	.Call DfwDeviceSetDeviceCharacteristics to establish the characteristics flags for the DEVICE_OBJECT
	//	.Call DfwDeviceSetExclusive to establish the Exclusive flag to be used in the eventual call to IoCreateDevice.

	// DfwDeviceInitialize will, among other things, call IoCreateDevice.

	status = DfwDeviceInitialize(hDevice);
	if (!NT_SUCCESS(status))
		{
		DfwTraceError(DRIVERNAME " - DfwDeviceInitialize failed - %X\n", status);
		return status;
		}

	// In a more complex driver, we might now do these additional things:
	//	.Call DfwDeviceCreateDeviceInterface to register a device interface GUID.
	//	.Call one or more functions like DfwDeviceRegisterCallbacks to establish
	//	 event callbacks for various types of IRP.
	//	.Create one or more DFWQUEUE request queues.

	// Even though we don't want to do anything special with PnP IRPs, the WinHEC 2003
	// version of the DFW library requires us to call DfwDeviceRegisterFdoCallbacks, or else
	// it crashes when we unload the driver.

	DFW_FDO_EVENT_CALLBACKS callbacks;
	DFW_FDO_EVENT_CALLBACKS_INIT(&callbacks);

	status = DfwDeviceRegisterFdoCallbacks(hDevice, &callbacks);
	if (!NT_SUCCESS(status))
		{
		DfwTraceError(DRIVERNAME " - DfwDeviceRegisterFdoCallbacks failed - %X\n", status);
		return status;
		}

	return status;
	}							// EvtDriverDeviceAdd

////////////////////////////////////////////////////////////////////////////////
// The framework calls EvtDriverUnload to do any required cleanup of global
// variables in preparation for unloading the driver. This driver has no
// cleanup to perform, so this routine is here just to print a reassuring
// debug message.

#pragma PAGEDCODE

VOID EvtDriverUnload(DFWDRIVER Driver)
	{							// EvtDriverUnload
	PAGED_CODE();
	DfwTraceDbgPrint(DRIVERNAME " - Unloading driver - IRQL is %d\n", KeGetCurrentIrql());
	}							// EvtDriverUnload

⌨️ 快捷键说明

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