通过驱动名称枚举驱动下设备和挂载设备的信息

说明:

exe程序通过打开驱动的设备,然后使用DeviceIOCtrl发送一个IOCtrl码,并将将要显示的驱动程序的名称传递给驱动程序,驱动程序受到IOCtrl码并接收到驱动程序的名称,调用枚举设备信息函数。


应用程序代码:

// ShowDeviceInfo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "ShowDeviceInfo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一的应用程序对象

CWinApp theApp;

using namespace std;
#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
	((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
	)
const ULONG IOCTL_ENUMDEV_DEVNAME = CTL_CODE(0x8000, 0x01, 0, 0x0001 | 0x0002);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// 初始化 MFC 并在失败时显示错误
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: 更改错误代码以符合您的需要
		_tprintf(_T("错误: MFC 初始化失败\n"));
		nRetCode = 1;
	}
	else
	{
		// TODO: 在此处为应用程序的行为编写代码。
	}


	HANDLE hdl = CreateFile(L"\\\\.\\ENUMDEV_DeviceName",
		GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL ,NULL);
	if (hdl == INVALID_HANDLE_VALUE)
	{
		CString csLog;
		csLog.Format(L"CreateFile Error:%d",GetLastError());
		AfxMessageBox(csLog);
		return -1;
	}

	WCHAR *DriName = L"\\Driver\\ACPI";
	DWORD dwInLen = wcslen(DriName)*2+2;

	DWORD dwRetLen;
	BOOL bRetRead = DeviceIoControl(hdl,IOCTL_ENUMDEV_DEVNAME,DriName,dwInLen,NULL,0,&dwRetLen,NULL);
	if (bRetRead)
	{
		cout<<"DeviceIoControl OK!"<<endl;
	}


	CloseHandle(hdl);

	system("PAUSE");


	return nRetCode;
}

驱动程序代码:

///
///
/// Copyright (c) 2014 - <company name here>
///
/// Original filename: EnumDev.cpp
/// Project          : EnumDev
/// Date of creation : 2014-06-26
/// Author(s)        : <author name(s)>
///
/// Purpose          : <description>
///
/// Revisions:
///  0000 [2014-06-26] Initial revision.
///
///

// $Id$

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <string.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "EnumDev.h"

#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif


#define DEVICE_NAME			"\\Device\\ENUMDEV_DeviceName"
#define SYMLINK_NAME		"\\DosDevices\\ENUMDEV_DeviceName"
PRESET_UNICODE_STRING(usDeviceName, DEVICE_NAME);
PRESET_UNICODE_STRING(usSymlinkName, SYMLINK_NAME);

#ifndef FILE_DEVICE_ENUMDEV
#define FILE_DEVICE_ENUMDEV 0x8000
#endif



const ULONG IOCTL_ENUMDEV_DEVNAME = CTL_CODE(FILE_DEVICE_ENUMDEV, 0x01, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA);



#if __cplusplus
extern "C"
{
#endif

#include <ntddk.h>
#pragma  comment(lib"ntoskrnl.lib")

	NTKERNELAPI NTSTATUS ObReferenceObjectByName(
		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 ParseContent OPTIONAL,
		OUT PVOID *Object);

	NTKERNELAPI NTAPI IoGetBaseFileSystemDeviceObject(
		IN PFILE_OBJECT FileObject);

	extern POBJECT_TYPE *IoDriverObjectType;
	//extern POBJECT_TYPE *IoDeviceObjectType;
#if __cplusplus
};
#endif

typedef struct _DEVICE_EXTENSION 
{
	PDEVICE_OBJECT pDevObj;
	UNICODE_STRING usDevName;
	UNICODE_STRING usLinkName;

	PUCHAR buffer;
	ULONG fileLen;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;


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 37

typedef 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)))


NTSTATUS ENUMDEV_DispatchCreateClose(
    IN PDEVICE_OBJECT		DeviceObject,
    IN PIRP					Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}


VOID ENUMDEV_DriverUnload(
    IN PDRIVER_OBJECT		DriverObject
    )
{
    PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
    IoDeleteSymbolicLink(&usSymlinkName);

    // Delete all the device objects
    while(pdoNextDeviceObj)
    {
        PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
        pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
        IoDeleteDevice(pdoThisDeviceObj);
    }
}


VOID GetDeviceObjectInfo(PDEVICE_OBJECT pDevObj)
{

	POBJECT_HEADER pObjectHeader;
	POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo;

	if (pDevObj == NULL)
	{
		KdPrint(("GetDeviceObjectInfo::pDevObj is NULL...\n"));
		return;
	}

	pObjectHeader = OBJECT_TO_OBJECT_HEADER(pDevObj);//得到对象头

	if (pObjectHeader)
	{
		//查询设备名称并打印
		pObjectHeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(pObjectHeader);
		if (pObjectHeaderNameInfo && pObjectHeaderNameInfo->Name.Buffer)
		{
			KdPrint(("Driver Name:%wZ - Device Name:%wZ - Driver Address:0x%x - Device Address:0x%x\n",
				&pDevObj->DriverObject->DriverName,
				&pObjectHeaderNameInfo->Name,
				pDevObj->DriverObject,
				pDevObj ));
		}else if (pDevObj->DriverObject) //没有设备名称
		{
			KdPrint(("Driver Name:%wZ - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
				&pDevObj->DriverObject->DriverName,
				L"NULL",
				pDevObj->DriverObject,
				pDevObj));

		}
	}

}

VOID getAttachedDevInfo(PDEVICE_OBJECT pDevObj)
{
	PDEVICE_OBJECT pDeviceObject;
	if (pDevObj == NULL)
	{
		return ;
	}

	pDeviceObject = pDevObj->AttachedDevice;//获取设备上的挂载设备

	while(pDeviceObject)
	{
		KdPrint(( "Attached Driver Name:%wZ,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
			&pDeviceObject->DriverObject->DriverName,
			pDeviceObject->DriverObject,
			pDeviceObject ));

		pDeviceObject  = pDeviceObject->AttachedDevice;//获取挂载设备上的挂载设备
	}
}

PDRIVER_OBJECT EnumDeviceStack(PWSTR pwsDriverName)
{
	//通过设备名获取所在驱动的驱动的对象指针

	NTSTATUS status = STATUS_SUCCESS;

	PDRIVER_OBJECT pDriverObj = NULL;
	UNICODE_STRING usDriName;
	RtlInitUnicodeString(&usDriName,pwsDriverName);


	KdPrint(("usDevName:%wZ\n",&usDriName));

	status = ObReferenceObjectByName(&usDriName,
		OBJ_CASE_INSENSITIVE,
		NULL,0,(POBJECT_TYPE)*IoDriverObjectType,
		KernelMode,
		NULL,
		(PVOID*)&pDriverObj);//通过驱动名称获取驱动的对象指针

	if (pDriverObj == NULL)
	{
		KdPrint(("ObReferenceObjectByName Error.status:0x%x",status));
		return NULL;
	}

	PDEVICE_OBJECT pDevObj = pDriverObj->DeviceObject;//获取驱动下创建的设备

	while(pDevObj)
	{
		GetDeviceObjectInfo(pDevObj);//获取设备信息并打印	

		//判断设备上是否有过滤设备
		if (pDevObj->AttachedDevice)
		{
			getAttachedDevInfo(pDevObj);//获取设备上的挂载设备的信息
		}


		//判断设备上的VPB设备
		if (pDevObj->Vpb && pDevObj->Vpb->DeviceObject)
		{
			GetDeviceObjectInfo(pDevObj->Vpb->DeviceObject);

			if (pDevObj->Vpb->DeviceObject->AttachedDevice)
			{
				getAttachedDevInfo(pDevObj->Vpb->DeviceObject);
			}
		}

		//得到在此驱动上建立的下一个设备
		pDevObj = pDevObj->NextDevice;


	}


	return pDriverObj ;

}


NTSTATUS ENUMDEV_DispatchDeviceControl(
									   IN PDEVICE_OBJECT		DeviceObject,
									   IN PIRP					Irp
									   )
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG uIn=0,uOut=0;
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);

	uIn = irpSp->Parameters.DeviceIoControl.InputBufferLength;
	uOut = irpSp->Parameters.DeviceIoControl.OutputBufferLength;


	switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
	{
	case IOCTL_ENUMDEV_DEVNAME:
		{
			KdPrint(("IOCTL_ENUMDEV_DEVNAME...."));
			WCHAR* inputBuffer = (WCHAR*)Irp->AssociatedIrp.SystemBuffer;

			KdPrint(("inputBuffer:%S",inputBuffer));

			EnumDeviceStack(inputBuffer);
			// status = SomeHandlerFunction(irpSp);

		}

	
		break;
	default:
		Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
		Irp->IoStatus.Information = 0;
		break;
	}

	status = Irp->IoStatus.Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}


#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )
{
    PDEVICE_OBJECT pdoDeviceObj = 0;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    pdoGlobalDrvObj = DriverObject;

    // Create the device object.
    if(!NT_SUCCESS(status = IoCreateDevice(
        DriverObject,
        0,
        &usDeviceName,
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &pdoDeviceObj
        )))
    {
        // Bail out (implicitly forces the driver to unload).
        return status;
    };

    // Now create the respective symbolic link object
    if(!NT_SUCCESS(status = IoCreateSymbolicLink(
        &usSymlinkName,
        &usDeviceName
        )))
    {
        IoDeleteDevice(pdoDeviceObj);
        return status;
    }

    // NOTE: You need not provide your own implementation for any major function that
    //       you do not want to handle. I have seen code using DDKWizard that left the
    //       *empty* dispatch routines intact. This is not necessary at all!
    DriverObject->MajorFunction[IRP_MJ_CREATE] =
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = ENUMDEV_DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ENUMDEV_DispatchDeviceControl;
    DriverObject->DriverUnload = ENUMDEV_DriverUnload;

    return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif

下面是另一个版本的驱动代码:使用IoGetdeviceProperty函数 有设备对象指针获得设备名称-效果是一样的

///
///
/// Copyright (c) 2014 - <company name here>
///
/// Original filename: EnumDev.cpp
/// Project          : EnumDev
/// Date of creation : 2014-06-26
/// Author(s)        : <author name(s)>
///
/// Purpose          : <description>
///
/// Revisions:
///  0000 [2014-06-26] Initial revision.
///
///

// $Id$

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <string.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "EnumDev.h"

#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif


#define DEVICE_NAME			"\\Device\\ENUMDEV_DeviceName"
#define SYMLINK_NAME		"\\DosDevices\\ENUMDEV_DeviceName"
PRESET_UNICODE_STRING(usDeviceName, DEVICE_NAME);
PRESET_UNICODE_STRING(usSymlinkName, SYMLINK_NAME);

#ifndef FILE_DEVICE_ENUMDEV
#define FILE_DEVICE_ENUMDEV 0x8000
#endif



const ULONG IOCTL_ENUMDEV_DEVNAME = CTL_CODE(FILE_DEVICE_ENUMDEV, 0x01, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA);



#if __cplusplus
extern "C"
{
#endif

#include <ntddk.h>
#pragma  comment(lib"ntoskrnl.lib")

	NTKERNELAPI NTSTATUS ObReferenceObjectByName(
		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 ParseContent OPTIONAL,
		OUT PVOID *Object);

	NTKERNELAPI NTAPI IoGetBaseFileSystemDeviceObject(
		IN PFILE_OBJECT FileObject);

	extern POBJECT_TYPE *IoDriverObjectType;
	//extern POBJECT_TYPE *IoDeviceObjectType;
#if __cplusplus
};
#endif

typedef struct _DEVICE_EXTENSION 
{
	PDEVICE_OBJECT pDevObj;
	UNICODE_STRING usDevName;
	UNICODE_STRING usLinkName;

	PUCHAR buffer;
	ULONG fileLen;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;

/*

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 37

typedef 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)))

*/

NTSTATUS ENUMDEV_DispatchCreateClose(
    IN PDEVICE_OBJECT		DeviceObject,
    IN PIRP					Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}


VOID ENUMDEV_DriverUnload(
    IN PDRIVER_OBJECT		DriverObject
    )
{
    PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
    IoDeleteSymbolicLink(&usSymlinkName);

    // Delete all the device objects
    while(pdoNextDeviceObj)
    {
        PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
        pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
        IoDeleteDevice(pdoThisDeviceObj);
    }
}


VOID GetDeviceObjectInfo(PDEVICE_OBJECT pDevObj)
{

	//POBJECT_HEADER pObjectHeader;
	//POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo;

	if (pDevObj == NULL)
	{
		KdPrint(("GetDeviceObjectInfo::pDevObj is NULL...\n"));
		return;
	}

	
	PWCHAR pResutlt = NULL;
	ULONG uNeedSize =0;
	NTSTATUS status  = IoGetDeviceProperty(pDevObj,
		DevicePropertyPhysicalDeviceObjectName,0,NULL,&uNeedSize);
	if (status == STATUS_BUFFER_TOO_SMALL && uNeedSize > 0)
	{
		pResutlt = (PWCHAR)ExAllocatePool(PagedPool,uNeedSize+1);
		if (pResutlt)
		{
			RtlZeroMemory(pResutlt,uNeedSize+1);
			status = IoGetDeviceProperty(pDevObj,DevicePropertyPhysicalDeviceObjectName,uNeedSize+1,pResutlt,&uNeedSize);
			if (NT_SUCCESS(status))
			{

				if (pResutlt)
				{					
					KdPrint(("Driver Name:%wZ - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
						&pDevObj->DriverObject->DriverName,
						pResutlt,
						pDevObj->DriverObject,
						pDevObj));
				}else
				{
					KdPrint(("Driver Name:%wZ - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
						&pDevObj->DriverObject->DriverName,
						L"NULL",
						pDevObj->DriverObject,
						pDevObj));
				}
			}

		}

	}else
	{
		return ;
	}


	if (pResutlt)
	{
		ExFreePool(pResutlt);
		pResutlt = NULL;
	}



	/*
	pObjectHeader = OBJECT_TO_OBJECT_HEADER(pDevObj);//得到对象头
	
		if (pObjectHeader)
		{
			//查询设备名称并打印
			pObjectHeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(pObjectHeader);
			if (pObjectHeaderNameInfo && pObjectHeaderNameInfo->Name.Buffer)
			{
				KdPrint(("Driver Name:%wZ - Device Name:%wZ - Driver Address:0x%x - Device Address:0x%x\n",
					&pDevObj->DriverObject->DriverName,
					&pObjectHeaderNameInfo->Name,
					pDevObj->DriverObject,
					pDevObj ));
			}else if (pDevObj->DriverObject) //没有设备名称
			{
				KdPrint(("Driver Name:%wZ - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
					&pDevObj->DriverObject->DriverName,
					L"NULL",
					pDevObj->DriverObject,
					pDevObj));
	
			}
		}*/
	

}

VOID getAttachedDevInfo(PDEVICE_OBJECT pDevObj)
{
	PDEVICE_OBJECT pDeviceObject;
	if (pDevObj == NULL)
	{
		return ;
	}

	pDeviceObject = pDevObj->AttachedDevice;//获取设备上的挂载设备

	while(pDeviceObject)
	{
		KdPrint(( "Attached Driver Name:%wZ,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
			&pDeviceObject->DriverObject->DriverName,
			pDeviceObject->DriverObject,
			pDeviceObject ));

		pDeviceObject  = pDeviceObject->AttachedDevice;//获取挂载设备上的挂载设备
	}
}

PDRIVER_OBJECT EnumDeviceStack(PWSTR pwsDriverName)
{
	//通过设备名获取所在驱动的驱动的对象指针

	NTSTATUS status = STATUS_SUCCESS;

	PDRIVER_OBJECT pDriverObj = NULL;
	UNICODE_STRING usDriName;
	RtlInitUnicodeString(&usDriName,pwsDriverName);


	KdPrint(("usDevName:%wZ\n",&usDriName));

	status = ObReferenceObjectByName(&usDriName,
		OBJ_CASE_INSENSITIVE,
		NULL,0,(POBJECT_TYPE)*IoDriverObjectType,
		KernelMode,
		NULL,
		(PVOID*)&pDriverObj);//通过驱动名称获取驱动的对象指针

	if (pDriverObj == NULL)
	{
		KdPrint(("ObReferenceObjectByName Error.status:0x%x",status));
		return NULL;
	}

	PDEVICE_OBJECT pDevObj = pDriverObj->DeviceObject;//获取驱动下创建的设备

	while(pDevObj)
	{
		GetDeviceObjectInfo(pDevObj);//获取设备信息并打印	

		//判断设备上是否有过滤设备
		if (pDevObj->AttachedDevice)
		{
			getAttachedDevInfo(pDevObj);//获取设备上的挂载设备的信息
		}


		//判断设备上的VPB设备
		if (pDevObj->Vpb && pDevObj->Vpb->DeviceObject)
		{
			GetDeviceObjectInfo(pDevObj->Vpb->DeviceObject);

			if (pDevObj->Vpb->DeviceObject->AttachedDevice)
			{
				getAttachedDevInfo(pDevObj->Vpb->DeviceObject);
			}
		}

		//得到在此驱动上建立的下一个设备
		pDevObj = pDevObj->NextDevice;


	}


	return pDriverObj ;

}


NTSTATUS ENUMDEV_DispatchDeviceControl(
									   IN PDEVICE_OBJECT		DeviceObject,
									   IN PIRP					Irp
									   )
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG uIn=0,uOut=0;
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);

	uIn = irpSp->Parameters.DeviceIoControl.InputBufferLength;
	uOut = irpSp->Parameters.DeviceIoControl.OutputBufferLength;


	switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
	{
	case IOCTL_ENUMDEV_DEVNAME:
		{
			KdPrint(("IOCTL_ENUMDEV_DEVNAME...."));
			WCHAR* inputBuffer = (WCHAR*)Irp->AssociatedIrp.SystemBuffer;

			KdPrint(("inputBuffer:%S",inputBuffer));

			EnumDeviceStack(inputBuffer);
			// status = SomeHandlerFunction(irpSp);

		}

	
		break;
	default:
		Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
		Irp->IoStatus.Information = 0;
		break;
	}

	status = Irp->IoStatus.Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}


#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )
{
    PDEVICE_OBJECT pdoDeviceObj = 0;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    pdoGlobalDrvObj = DriverObject;

    // Create the device object.
    if(!NT_SUCCESS(status = IoCreateDevice(
        DriverObject,
        0,
        &usDeviceName,
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &pdoDeviceObj
        )))
    {
        // Bail out (implicitly forces the driver to unload).
        return status;
    };

    // Now create the respective symbolic link object
    if(!NT_SUCCESS(status = IoCreateSymbolicLink(
        &usSymlinkName,
        &usDeviceName
        )))
    {
        IoDeleteDevice(pdoDeviceObj);
        return status;
    }

    // NOTE: You need not provide your own implementation for any major function that
    //       you do not want to handle. I have seen code using DDKWizard that left the
    //       *empty* dispatch routines intact. This is not necessary at all!
    DriverObject->MajorFunction[IRP_MJ_CREATE] =
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = ENUMDEV_DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ENUMDEV_DispatchDeviceControl;
    DriverObject->DriverUnload = ENUMDEV_DriverUnload;

    return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值