遍历本驱动设备链 (附加)设备栈上的设备 信息

来源:互联网 发布:淘宝销售属性怎么添加 编辑:程序博客网 时间:2024/05/22 10:31
#include <windows.h>#include <stdio.h>//使用CTL_CODE必须加入winioctl.h#include <winioctl.h>#include "..\驱动A\Ioctls.h"int main(){HANDLE hDevice = CreateFile(L"\\\\.\\HelloDDK",GENERIC_READ | GENERIC_WRITE,0,// share mode noneNULL,// no securityOPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );// no templateif (hDevice == INVALID_HANDLE_VALUE){printf("Failed to obtain file handle to device: ""%s with Win32 error code: %d\n","MyWDMDevice", GetLastError() );return 1;}WCHAR* InputBuffer = L"\\Driver\\ACPI";DWORD dwOutput;//输入缓冲区作为输入,输出缓冲区作为输出BOOL bRet;bRet = DeviceIoControl(hDevice, IOCTL_DUMP_DEVICE_STACK, InputBuffer, wcslen(InputBuffer)*2+2, NULL, 0, &dwOutput, NULL);system("pause");CloseHandle(hDevice);return 0;}
// IOCTLS.H -- IOCTL code definitions for fileio driver// Copyright (C) 1999 by Walter Oney// All rights reserved#ifndef IOCTLS_H#define IOCTLS_H#ifndef CTL_CODE#pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")#endif#define IOCTL_DUMP_DEVICE_STACK CTL_CODE(\FILE_DEVICE_UNKNOWN, \0x800, \METHOD_BUFFERED, \FILE_ANY_ACCESS)#endif
/************************************************************************* 文件名称:Driver.h                                                 * 作    者:张帆* 完成日期:2007-11-1*************************************************************************/#pragma once#ifdef __cplusplusextern "C"{#endif#include <NTDDK.h>NTKERNELAPINTSTATUSObReferenceObjectByName(    IN PUNICODE_STRING ObjectName,    IN ULONG Attributes,    IN PACCESS_STATE PassedAccessState OPTIONAL,    IN ACCESS_MASK DesiredAccess OPTIONAL,    IN POBJECT_TYPE ObjectType,    IN KPROCESSOR_MODE AccessMode,    IN OUT PVOID ParseContext OPTIONAL,    OUT PVOID *Object    );NTKERNELAPIPDEVICE_OBJECTNTAPIIoGetBaseFileSystemDeviceObject (    IN PFILE_OBJECT FileObject);extern POBJECT_TYPE IoDeviceObjectType;extern POBJECT_TYPE *IoDriverObjectType;#ifdef __cplusplus}#endif #include "ioctls.h"#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]))#define MAX_FILE_LENGTH 1024typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice;UNICODE_STRING ustrDeviceName;//设备名称UNICODE_STRING ustrSymLinkName;//符号链接名PUCHAR buffer;//缓冲区ULONG file_length;//模拟的文件长度,必须小于MAX_FILE_LENGTH} DEVICE_EXTENSION, *PDEVICE_EXTENSION;// 函数声明NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);typedef struct _OBJECT_CREATE_INFORMATION{    ULONG Attributes;    HANDLE RootDirectory;    PVOID ParseContext;    KPROCESSOR_MODE ProbeMode;    ULONG PagedPoolCharge;    ULONG NonPagedPoolCharge;    ULONG SecurityDescriptorCharge;    PSECURITY_DESCRIPTOR SecurityDescriptor;    PSECURITY_QUALITY_OF_SERVICE SecurityQos;    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;typedef struct _OBJECT_HEADER{    LONG PointerCount;    union    {        LONG HandleCount;        PSINGLE_LIST_ENTRY SEntry;    };    POBJECT_TYPE Type;    UCHAR NameInfoOffset;    UCHAR HandleInfoOffset;    UCHAR QuotaInfoOffset;    UCHAR Flags;    union    {        POBJECT_CREATE_INFORMATION ObjectCreateInfo;        PVOID QuotaBlockCharged;    };    PSECURITY_DESCRIPTOR SecurityDescriptor;    QUAD Body;} OBJECT_HEADER, * POBJECT_HEADER;#define NUMBER_HASH_BUCKETS 37typedef struct _OBJECT_DIRECTORY{    struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];    struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;    BOOLEAN LookupFound;    USHORT SymbolicLinkUsageCount;    struct _DEVICE_MAP* DeviceMap;} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;typedef struct _OBJECT_HEADER_NAME_INFO{    POBJECT_DIRECTORY Directory;    UNICODE_STRING Name;    ULONG Reserved;#if DBG    ULONG Reserved2 ;    LONG DbgDereferenceCount ;#endif} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;#define OBJECT_TO_OBJECT_HEADER( o ) \    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
#include "Driver.h"/************************************************************************* 函数名称:DriverEntry* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象      pRegistryPath:驱动程序在注册表的中的路径* 返回 值:返回初始化驱动状态*************************************************************************/#pragma INITCODEextern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) {NTSTATUS status;KdPrint(("Enter DriverEntry\n"));//设置卸载函数pDriverObject->DriverUnload = HelloDDKUnload;//设置派遣函数for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDeviceIOControl;//创建驱动设备对象status = CreateDevice(pDriverObject);KdPrint(("Leave DriverEntry\n"));return status;}/************************************************************************* 函数名称:CreateDevice* 功能描述:初始化设备对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象* 返回 值:返回初始化状态*************************************************************************/#pragma INITCODENTSTATUS CreateDevice (IN PDRIVER_OBJECTpDriverObject) {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_DIRECT_IO;pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;pDevExt->pDevice = pDevObj;pDevExt->ustrDeviceName = devName;//申请模拟文件的缓冲区pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool,MAX_FILE_LENGTH);//设置模拟文件大小pDevExt->file_length = 0;//创建符号链接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 PAGEDCODEVOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) {PDEVICE_OBJECTpNextObj;KdPrint(("Enter DriverUnload\n"));pNextObj = pDriverObject->DeviceObject;//while (pNextObj != NULL) //{//PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)//pNextObj->DeviceExtension;//if (pDevExt->buffer)//{//ExFreePool(pDevExt->buffer);//pDevExt->buffer = NULL;//}////删除符号链接//UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;//IoDeleteSymbolicLink(&pLinkName);//pNextObj = pNextObj->NextDevice;//IoDeleteDevice( pDevExt->pDevice );//}UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");pNextObj = pDriverObject->DeviceObject;//我的第一个设备                      IoDeleteSymbolicLink(&symLinkName);//删除符号连接                      IoDeleteDevice(pDriverObject->DeviceObject);//删除设备    KdPrint(("DriverB:Enter B DriverUnload\n"));}/************************************************************************* 函数名称:HelloDDKDispatchRoutin* 功能描述:对读IRP进行处理* 参数列表:      pDevObj:功能设备对象      pIrp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) {KdPrint(("Enter HelloDDKDispatchRoutin\n"));PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);//建立一个字符串数组与IRP类型对应起来static char* irpname[] = {"IRP_MJ_CREATE","IRP_MJ_CREATE_NAMED_PIPE","IRP_MJ_CLOSE","IRP_MJ_READ","IRP_MJ_WRITE","IRP_MJ_QUERY_INFORMATION","IRP_MJ_SET_INFORMATION","IRP_MJ_QUERY_EA","IRP_MJ_SET_EA","IRP_MJ_FLUSH_BUFFERS","IRP_MJ_QUERY_VOLUME_INFORMATION","IRP_MJ_SET_VOLUME_INFORMATION","IRP_MJ_DIRECTORY_CONTROL","IRP_MJ_FILE_SYSTEM_CONTROL","IRP_MJ_DEVICE_CONTROL","IRP_MJ_INTERNAL_DEVICE_CONTROL","IRP_MJ_SHUTDOWN","IRP_MJ_LOCK_CONTROL","IRP_MJ_CLEANUP","IRP_MJ_CREATE_MAILSLOT","IRP_MJ_QUERY_SECURITY","IRP_MJ_SET_SECURITY","IRP_MJ_POWER","IRP_MJ_SYSTEM_CONTROL","IRP_MJ_DEVICE_CHANGE","IRP_MJ_QUERY_QUOTA","IRP_MJ_SET_QUOTA","IRP_MJ_PNP",};UCHAR type = stack->MajorFunction;if (type >= arraysize(irpname))KdPrint((" - Unknown IRP, major type %X\n", type));elseKdPrint(("\t%s\n", irpname[type]));NTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDispatchRoutin\n"));return status;}VOID GetDeviceObjectInfo( PDEVICE_OBJECT DevObj )//设备对象{  POBJECT_HEADER ObjectHeader;  POBJECT_HEADER_NAME_INFO ObjectNameInfo;   if ( DevObj == NULL )//判断设备对象是否为空  {    DbgPrint( "DevObj is NULL!\n" );    return;  }  // 得到对象头  ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );  if ( ObjectHeader )  {    // 查询设备名称并打印    ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );    if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )//如果有名字    {      DbgPrint( "驱动名:%wZ - 设备名:%wZ - 驱动地址:0x%x - 设备地址:0x%x\n",                &DevObj->DriverObject->DriverName,                &ObjectNameInfo->Name,                DevObj->DriverObject,                DevObj );    }    // 对于没有名称的设备,则打印 NULL    else if ( DevObj->DriverObject )    {      DbgPrint( "驱动名:%wZ - 设备名:%S - 驱动地址:0x%x - 设备地址:0x%x  设备无名\n",                &DevObj->DriverObject->DriverName,                L"NULL",                DevObj->DriverObject,                DevObj );    }  }}VOID GetAttachedDeviceInfo( PDEVICE_OBJECT DevObj )//设备的附加设备{  PDEVICE_OBJECT DeviceObject;  if ( DevObj == NULL )  {    DbgPrint( "DevObj is NULL!\n" );    return;  }  DeviceObject = DevObj->AttachedDevice;  while ( DeviceObject )//循环到栈顶  {  DbgPrint("附加驱动名:%wZ,附加驱动地址:0x%x,附加设备地址:0x%x\n",//附加驱动名 都不相同&DeviceObject->DriverObject->DriverName,DeviceObject->DriverObject,DeviceObject);    DeviceObject = DeviceObject->AttachedDevice;  }}PDRIVER_OBJECT EnumDeviceStack( PWSTR pwszDeviceName ){  UNICODE_STRING DriverName;  PDRIVER_OBJECT DriverObject = NULL;  PDEVICE_OBJECT DeviceObject = NULL;  RtlInitUnicodeString( &DriverName, pwszDeviceName );// L"\\Driver\\ACPI";  ObReferenceObjectByName( &DriverName,OBJ_CASE_INSENSITIVE,NULL,0,(POBJECT_TYPE)IoDriverObjectType,KernelMode,NULL,(PVOID*)&DriverObject);  if ( DriverObject == NULL )//得到驱动对象  {    return NULL;  }  DeviceObject = DriverObject->DeviceObject;//设备对象  while ( DeviceObject )//本驱动的设备  {    GetDeviceObjectInfo( DeviceObject );//遍历设备对象    // 判断当前设备上是否有过滤驱动(Filter Driver)    if ( DeviceObject->AttachedDevice )    {      GetAttachedDeviceInfo( DeviceObject );//遍历驱动对象    }    // 进一步判断当前设备上 VPB 中的设备    if ( DeviceObject->Vpb && DeviceObject->Vpb->DeviceObject )    {      GetDeviceObjectInfo( DeviceObject->Vpb->DeviceObject );      if ( DeviceObject->Vpb->DeviceObject->AttachedDevice )      {        GetAttachedDeviceInfo( DeviceObject->Vpb->DeviceObject );      }    }    // 得到建立在此驱动上的下一个设备 DEVICE_OBJECT     DeviceObject = DeviceObject->NextDevice;  }  return DriverObject;}#pragma PAGEDCODENTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp){NTSTATUS status = STATUS_SUCCESS;KdPrint(("Enter HelloDDKDeviceIOControl\n"));//得到当前堆栈PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);//得到IO堆栈//得到输入缓冲区大小ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;//得到输出缓冲区大小ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;//得到IOCTL码ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;ULONG info = 0;switch (code){// process requestcase IOCTL_DUMP_DEVICE_STACK:{KdPrint(("IOCTL_DUMP_DEVICE_STACK\n"));//缓冲区方式IOCTL//显示输入缓冲区数据 WCHAR* InputBuffer = (WCHAR*)pIrp->AssociatedIrp.SystemBuffer;KdPrint(("%ws\n",InputBuffer));EnumDeviceStack( InputBuffer );// L"\\Driver\\ACPI";break;}default:status = STATUS_INVALID_VARIANT;}// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = info;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDeviceIOControl\n"));return status;}