WDM에서 driver name을 통해 Driver Object를 가져오고 Driver에서 생성된 Device Object를 반복합니다.

5319 단어
공개되지 않은 (undocumented) API가 필요합니다.
ObReferenceObjectByName
함수는 대상 이름을 통해 장치 대상을 포함한 각종 핵 대상의 바늘을 얻을 수 있습니다. 예를 들어 핵 이벤트, 상호 배척체 대상 등입니다. 그는 핵 대상의 인용 계수를 증가합니다. 핵 대상을 사용한 후 ObDereference Object 핵 함수로 인용 계수를 1.
참조 정의:
4
NTKERNELAPI NTSTATUS ObReferenceObjectByName  ( __in PUNICODE_STRING  ObjectName,  
  __in ULONG  Attributes,  
  __in_opt PACCESS_STATE  AccessState,  
  __in_opt ACCESS_MASK  DesiredAccess,  
  __in POBJECT_TYPE  ObjectType,  
  __in KPROCESSOR_MODE  AccessMode,  
  __inout_opt PVOID  ParseContext,  
  __out PVOID *  Object   
 ) 
driver name에서 DRIVER 가져오기 지원OBJECT, device name에서 DEVICE 가져오기OBJECT
Driver name에서 DRIVER 가져오기OBJECT:
// API define
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
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 ParseContext OPTIONAL,
    OUT PVOID *Object
    );
extern POBJECT_TYPE *IoDriverObjectType;
#ifdef __cplusplus
}
#endif

// use such API
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING DriverName;
PDRIVER_OBJECT pDriverObj = NULL;
RtlInitUnicodeString(&DriverName, L"\\Driver\\usbhub");    // usbhub as an example
status = ObReferenceObjectByName(
		&DriverName,
		OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
		NULL,
		0,
		*IoDriverObjectType,
		KernelMode,
		NULL,
		(PVOID*)&pDriverObj);

Device name에서 Device Object를 가져오는 방법은 비슷합니다. ObjectType을 구분하기만 하면 됩니다.
저희는 DRIVER를 통해서...OBJECT->DeviceObject에서 이 드라이브에서 생성된 DEVICE를 가져옵니다.OBJECT 및 DEVICE를 통해OBJECT->NextDevice로 모든 DEVICEOBJECT.
typedef struct _DRIVER_OBJECT {
    CSHORT Type;
    CSHORT Size;

    //
    // The following links all of the devices created by a single driver
    // together on a list, and the Flags word provides an extensible flag
    // location for driver objects.
    //

    PDEVICE_OBJECT DeviceObject;
    ULONG Flags;

    //
    // The following section describes where the driver is loaded.  The count
    // field is used to count the number of times the driver has had its
    // registered reinitialization routine invoked.
    //

    PVOID DriverStart;
    ULONG DriverSize;
    PVOID DriverSection;
    PDRIVER_EXTENSION DriverExtension;

    //
    // The driver name field is used by the error log thread
    // determine the name of the driver that an I/O request is/was bound.
    //

    UNICODE_STRING DriverName;

    //
    // The following section is for registry support.  Thise is a pointer
    // to the path to the hardware information in the registry
    //

    PUNICODE_STRING HardwareDatabase;

    //
    // The following section contains the optional pointer to an array of
    // alternate entry points to a driver for "fast I/O" support.  Fast I/O
    // is performed by invoking the driver routine directly with separate
    // parameters, rather than using the standard IRP call mechanism.  Note
    // that these functions may only be used for synchronous I/O, and when
    // the file is cached.
    //

    PFAST_IO_DISPATCH FastIoDispatch;

    //
    // The following section describes the entry points to this particular
    // driver.  Note that the major function dispatch table must be the last
    // field in the object so that it remains extensible.
    //

    PDRIVER_INITIALIZE DriverInit;
    PDRIVER_STARTIO DriverStartIo;
    PDRIVER_UNLOAD DriverUnload;
    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

} DRIVER_OBJECT;

누적되는 동안 PDO의 Device Name을 에 추출할 수 있습니다. 참조:
if (STATUS_SUCCESS == status 
    && NULL != pDriverObj)
{
    PDEVICE_OBJECT pDevObj = pDriverObj->DeviceObject;
    ULONG resultLength = 0;
    PWCHAR pResultBuffer = NULL;
    while(NULL != pDevObj)
    {
        if (pDevObj->Flags & DO_BUS_ENUMERATED_DEVICE )     // PDO
        {
            resultLength = 0;
            status = IoGetDeviceProperty(                   // get PDO device name
                pDevObj,
                DevicePropertyPhysicalDeviceObjectName,
                0,
                NULL,
                &resultLength);
            if (STATUS_BUFFER_TOO_SMALL == status
                && resultLength>0)
            {
                pResultBuffer = ExAllocatePoolWithTag(
                    NonPagedPool,
                    resultLength+1,
                    'NCSP');
                if (pResultBuffer)
                {
                    RtlZeroMemory(pResultBuffer, resultLength+1);
                    status = IoGetDeviceProperty(
                        pDevObj,
                        DevicePropertyPhysicalDeviceObjectName,
                        resultLength,
                        pResultBuffer,
                        &resultLength);
                }
            }
            if (pResultBuffer)
            {
                ExFreePool(pResultBuffer);
            }
        }
        pDevObj = pDevObj->NextDevice;
    }
    ObDereferenceObject(pPciDriverObj);
}

좋은 웹페이지 즐겨찾기