Initializing a Callout Driver

来源:互联网 发布:juniper networks mac 编辑:程序博客网 时间:2024/06/01 16:05

A callout driver initializes itself within its DriverEntry function. The main initialization tasks are as follows:

callout driver在DriverEntry函数中初始化自己,主要的初始化功能如下:

  • Specifying an Unload Function
  • Creating a Device Object
  • Registering Callouts with the Filter Engine
Specifying an Unload Function

A callout driver must provide an unload function. The operating system calls this function when the callout driver is unloaded from the system. A callout driver's unload function must guarantee that the callout driver's callouts are unregistered from the filter engine before the callout driver is unloaded from system memory. A callout driver cannot be unloaded from the system if it does not provide an unload function.
callout driver必须提供卸载函数,否则无法卸载callout driver。另外必须在卸载函数中保证从过滤引擎反注册callouts。

How a callout driver specifies an unload function depends on whether the callout driver is based on the Windows Driver Model (WDM) or the Windows Driver Foundation (WDF).

WDM-Based Callout Drivers
If a callout driver is based on WDM, it specifies an Unload function in its DriverEntry function. For example:

VOID
  Unload(
    IN PDRIVER_OBJECT DriverObject
    );

NTSTATUS
  DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
  ...

  // Specify the callout driver's Unload function
  DriverObject->DriverUnload = Unload;

  ...
}


Creating a Device Object

A callout driver must create a device object before it can register its callouts with the filter engine. How a callout driver creates a device object depends on whether the callout driver is based on the Windows Driver Model (WDM) or the Windows Driver Foundation (WDF).
callout driver在注册它的callouts之前必须创建设备对象。

WDM-Based Callout Drivers
If a callout driver is based on WDM, it creates a device object by calling the IoCreateDevice function. For example:

PDEVICE_OBJECT deviceObject;

NTSTATUS
  DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
  NTSTATUS status;

  ...

  // Create a device object
  status =
    IoCreateDevice(
      DriverObject,
      0,
      NULL,
      FILE_DEVICE_UNKNOWN,
      FILE_DEVICE_SECURE_OPEN,
      FALSE,
      &deviceObject
      );

  ...

  return status;
}


Registering Callouts with the Filter Engine

After a callout driver has created a device object, it can then register its callouts with the filter engine. A callout driver can register its callouts with the filter engine at any time, even if the filter engine is currently not running. To register a callout with the filter engine, a callout driver calls the FwpsCalloutRegister0 function. For example:

callout driver在创建完设备对象后,就可以注册它的callouts了。callout driver可以在任意时候注册callouts,甚至在过滤引擎没有运行时。为了注册callout,驱动调用FwpsCalloutRegister0函数。

// Prototypes for the callout's callout functions
VOID NTAPI
  ClassifyFn(
    IN const FWPS_INCOMING_VALUES0  *inFixedValues,
    IN const FWPS_INCOMING_METADATA_VALUES0  *inMetaValues,
    IN OUT VOID  *layerData,
    IN const FWPS_FILTER0  *filter,
    IN UINT64  flowContext,
    OUT FWPS_CLASSIFY_OUT0  *classifyOut
    );

NTSTATUS NTAPI
  NotifyFn(
    IN FWPS_CALLOUT_NOTIFY_TYPE  notifyType,
    IN const GUID  *filterKey,
    IN const FWPS_FILTER0  *filter
    );

VOID NTAPI
  FlowDeleteFn(
    IN UINT16  layerId,
    IN UINT32  calloutId,
    IN UINT64  flowContext
    );

// Callout registration structure
const FWPS_CALLOUT0 Callout =
{
  { ... }, // GUID key identifying the callout
  0,       // Callout-specific flags (none set here)
  ClassifyFn,
  NotifyFn,
  FlowDeleteFn
};

// Variable for the run-time callout identifier
UINT32 CalloutId;

NTSTATUS
  DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
  PDEVICE_OBJECT deviceObject;
  NTSTATUS status;

  ...

  status =
    FwpsCalloutRegister0(
      deviceObject,
      &Callout,
      &CalloutId
      );

  ...

  return status;
}

If the call to the FwpsCalloutRegister0 function is successful, the variable pointed to by the last parameter contains the run-time identifier for the callout. This run-time identifier corresponds to the GUID that was specified for the callout key.

调用FwpsCalloutRegister0成功后,最后一个参数包含一个运行时标识符,这个运行时标识符于callout key对应。

A single callout driver can implement more than one callout. If a callout driver implements more than one callout, it calls theFwpsCalloutRegister0 function one time for each callout that it supports to register each callout with the filter engine.












0 0