DDK中的链表结构

 

// 链表结构
typedef struct _LIST_ENTRY
{
 struct _LIST_ENTRY *Flink;
 struct _LIST_ENTRY *Blink;
}LIST_ENTRY, *PLIST_ENTRY;

// 使用链表时应当初始化使之指向自身
InitializeListHead(&head);

// 判断链表是否为空链
IsListEmpty(&head);


// 使用DDK中的链表扩展自己的数据结构
typedef struct _MYDATASTRUCT
{
 // List Entry 需要作为_MYDATASTRUCT结构体的一部分
 LIST_ENTRY ListEntry;    // 注意:此结构必须放在第一个域中
 
 // 下面是自定义的数据
 UNLONG x;
 UNLONG y;
}MYDATASTRUCT, *PMYDATASTRUCT;


// 从首部插入链表
InsertHeadList(&head, &mydata->ListEntry);


// 从尾部插入链表
InsertTailList(&head, &mydata->ListEntry);


// 从链表中删除
PLIST_ENTRY pEntry = RemoveHeadList(&head);
PLIST_ENTRY pEntry = RemoveTailList(&head);


访问链表中的数据

typedef struct _MYDATASTRUCT
{
 LIST_ENTRY ListEntry;    
 UNLONG x;
 UNLONG y;
}MYDATASTRUCT, *PMYDATASTRUCT;


PLIST_ENTRY pEntry = RemoveHeadList(&head);
PMYDATASTRUCT pMyData = (PMYDATASTRUCT)pEntry;


PLIST_ENTRY pEntry = RemoveHeadList(&head);
PIRP pIrp = CONTAINING_RECOD(pEntry,
       MYDATASTRUCT,
       ListEntry);
参数:
1.指向结点的指针
2.自定义数据结构
3.自定义数据结构中的ListEntry字段

 

实验:

/************************************************************************
* 文件名称:Driver.h                                                
* 作    者:张帆
* 完成日期:2007-11-1
*************************************************************************/
#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

typedef struct _DEVICE_EXTENSION {
 PDEVICE_OBJECT pDevice;
 UNICODE_STRING ustrDeviceName; //设备名称
 UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

// 函数声明

NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
         IN PIRP pIrp);

        
/************************************************************************
* 文件名称:Driver.cpp                                                
* 作    者:张帆
* 完成日期:2007-11-1
*************************************************************************/

#include "Driver.h"

typedef struct _MYDATASTRUCT
{
 ULONG number;
 LIST_ENTRY ListEntry;
} MYDATASTRUCT, *PMYDATASTRUCT;

#pragma INITCODE
VOID LinkListTest()
{
 LIST_ENTRY linkListHead;
 //初始化链表
 InitializeListHead(&linkListHead);

 PMYDATASTRUCT pData;
 ULONG i = 0;
 
 //在链表中插入10个元素
 KdPrint(("Begin insert to link list"));
 for (i=0 ; i<10 ; i++)
 {
  pData = (PMYDATASTRUCT)
   ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT));
  pData->number = i;
  InsertHeadList(&linkListHead,&pData->ListEntry);
 }

 //从链表中取出,并显示
 KdPrint(("Begin remove from link list\n"));
 while(!IsListEmpty(&linkListHead))
 {
  PLIST_ENTRY pEntry = RemoveTailList(&linkListHead);
  pData = CONTAINING_RECORD(pEntry,      // 指向结点的指针
                              MYDATASTRUCT,      // 自定义数据结构
                              ListEntry);      // 自定义数据结构中的ListEntry字段
  KdPrint(("%d\n",pData->number));
  ExFreePool(pData);
 }
 
}

/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
      pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
   IN PDRIVER_OBJECT pDriverObject,
   IN PUNICODE_STRING pRegistryPath )
{
 NTSTATUS status;
 KdPrint(("Enter DriverEntry\n"));

 //注册其他驱动调用函数入口
 pDriverObject->DriverUnload = HelloDDKUnload;
 pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
 pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
 pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
 
 //创建驱动设备对象
 status = CreateDevice(pDriverObject);

 LinkListTest();

 KdPrint(("DriverEntry end\n"));
 return status;
}

/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (
  IN PDRIVER_OBJECT pDriverObject)
{
 NTSTATUS status;
 PDEVICE_OBJECT pDevObj;
 PDEVICE_EXTENSION pDevExt;
 
 //创建设备名称
 UNICODE_STRING devName;
 RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");
 
 //创建设备
 status = IoCreateDevice( pDriverObject,
      sizeof(DEVICE_EXTENSION),
      &(UNICODE_STRING)devName,
      FILE_DEVICE_UNKNOWN,
      0, TRUE,
      &pDevObj );
 if (!NT_SUCCESS(status))
  return status;

 pDevObj->Flags |= DO_BUFFERED_IO;
 pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
 pDevExt->pDevice = pDevObj;
 pDevExt->ustrDeviceName = devName;
 //创建符号链接
 UNICODE_STRING symLinkName;
 RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");
 pDevExt->ustrSymLinkName = symLinkName;
 status = IoCreateSymbolicLink( &symLinkName,&devName );
 if (!NT_SUCCESS(status))
 {
  IoDeleteDevice( pDevObj );
  return status;
 }
 return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
      pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
 PDEVICE_OBJECT pNextObj;
 KdPrint(("Enter DriverUnload\n"));
 pNextObj = pDriverObject->DeviceObject;
 while (pNextObj != NULL)
 {
  PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
   pNextObj->DeviceExtension;

  //删除符号链接
  UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
  IoDeleteSymbolicLink(&pLinkName);
  pNextObj = pNextObj->NextDevice;
  IoDeleteDevice( pDevExt->pDevice );
 }
}

/************************************************************************
* 函数名称:HelloDDKDispatchRoutine
* 功能描述:对读IRP进行处理
* 参数列表:
      pDevObj:功能设备对象
      pIrp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
         IN PIRP pIrp)
{
 KdPrint(("Enter HelloDDKDispatchRoutine\n"));
 NTSTATUS status = STATUS_SUCCESS;
 // 完成IRP
 pIrp->IoStatus.Status = status;
 pIrp->IoStatus.Information = 0; // bytes xfered
 IoCompleteRequest( pIrp, IO_NO_INCREMENT );
 KdPrint(("Leave HelloDDKDispatchRoutine\n"));
 return status;
}

 

你可能感兴趣的:(DDK中的链表结构)