• 遍历驱动设备栈


    参考:https://blog.csdn.net/hjxyshell/article/details/39106609

    参考 《windows 驱动开发技术详解》,部分关于对象的结构,请看上节windbg命令 中介绍

    公用头文件:

    1.  
      // IOCTLS.H -- IOCTL code definitions for fileio driver
    2.  
      // Copyright (C) 1999 by Walter Oney
    3.  
      // All rights reserved
    4.  
       
    5.  
      #ifndef IOCTLS_H
    6.  
      #define IOCTLS_H
    7.  
       
    8.  
      #ifndef CTL_CODE
    9.  
      #pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")
    10.  
      #endif
    11.  
       
    12.  
      #define IOCTL_DUMP_DEVICE_STACK CTL_CODE(
    13.  
      FILE_DEVICE_UNKNOWN,
    14.  
      0x800,
    15.  
      METHOD_BUFFERED,
    16.  
      FILE_ANY_ACCESS)
    17.  
       
    18.  
      #endif


    ring3级代码

    1.  
      #include <stdio.h>
    2.  
      #include <windows.h>
    3.  
      #include <winioctl.h>
    4.  
      #include "..Ioctls.h"
    5.  
       
    6.  
      int main()
    7.  
      {
    8.  
      HANDLE hDevice = CreateFile("\\.\KeListDeviceSL",
    9.  
      GENERIC_READ | GENERIC_WRITE,
    10.  
      0,
    11.  
      NULL,
    12.  
      OPEN_EXISTING,
    13.  
      FILE_ATTRIBUTE_NORMAL,
    14.  
      NULL);
    15.  
      if(hDevice == INVALID_HANDLE_VALUE)
    16.  
      {
    17.  
      printf("Failed to obtain file handle to device: "
    18.  
      "%s with Win32 error code: %d ",
    19.  
      "MyWDMDevice", GetLastError() );
    20.  
      return 0;
    21.  
      }
    22.  
      WCHAR* InputBuffer = L"\Driver\ACPI";
    23.  
      DWORD dwOutput;
    24.  
      BOOL bRet;
    25.  
      bRet = DeviceIoControl(hDevice,
    26.  
      IOCTL_DUMP_DEVICE_STACK,
    27.  
      InputBuffer,
    28.  
      wcslen(InputBuffer)*2+2,
    29.  
      NULL,
    30.  
      0,
    31.  
      &dwOutput,
    32.  
      NULL);
    33.  
      CloseHandle(hDevice);
    34.  
      return 1;
    35.  
      }

    ring0级代码

    ListDevice.h

    1.  
      #pragma once
    2.  
      #ifdef __cplusplus
    3.  
      extern "C"
    4.  
      {
    5.  
      #endif
    6.  
      #include <ntddk.h>
    7.  
      NTKERNELAPI
    8.  
      NTSTATUS
    9.  
      ObReferenceObjectByName(
    10.  
      IN PUNICODE_STRING ObjectName,
    11.  
      IN ULONG Attributes,
    12.  
      IN PACCESS_STATE PassedAccessState OPTIONAL,
    13.  
      IN ACCESS_MASK DesiredAccess OPTIONAL,
    14.  
      IN POBJECT_TYPE ObjectType,
    15.  
      IN KPROCESSOR_MODE AccessMode,
    16.  
      IN OUT PVOID ParseContext OPTIONAL,
    17.  
      OUT PVOID *Object
    18.  
      );
    19.  
      NTKERNELAPI
    20.  
      PDEVICE_OBJECT
    21.  
      NTAPI
    22.  
      IoGetBaseFileSystemDeviceObject(
    23.  
      IN PFILE_OBJECT FileObject
    24.  
      );
    25.  
      extern POBJECT_TYPE IoDeviceObjectType;
    26.  
      extern POBJECT_TYPE *IoDriverObjectType;
    27.  
      #ifdef __cplusplus
    28.  
      }
    29.  
      #endif
    30.  
       
    31.  
      #include "..Ioctls.h"
    32.  
       
    33.  
      #define MAX_FILE_LENGTH 1024
    34.  
       
    35.  
      typedef struct _DEVICE_EXTENSION{
    36.  
      PDEVICE_OBJECT pDevice;
    37.  
      UNICODE_STRING ustrDeviceName;
    38.  
      UNICODE_STRING ustrSymLinkName;
    39.  
       
    40.  
      PUCHAR buffer; //缓冲区
    41.  
      ULONG file_length; //模拟文件长度,必须小于MAX_FILE_LENGTH
    42.  
      }DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    43.  
       
    44.  
      //函数声明
    45.  
      //创建设备
    46.  
      NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject, UNICODE_STRING devname, UNICODE_STRING symLinkName);
    47.  
      //卸载驱动
    48.  
      VOID DriverUnload(PDRIVER_OBJECT pDriverObject);
    49.  
      //IRP请求处理函数
    50.  
      NTSTATUS MyDispatchFunction(PDEVICE_OBJECT device, PIRP pIrp);
    51.  
      //处理消息
    52.  
      NTSTATUS DeviceIoControlDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    53.  
       
    54.  
      //枚举设备栈
    55.  
      PDRIVER_OBJECT EnumDeviceStack(PWSTR pwszDeviceName);
    56.  
       
    57.  
      typedef struct _OBJECT_CREATE_INFORMATION
    58.  
      {
    59.  
      ULONG Attributes;
    60.  
      HANDLE RootDirectory;
    61.  
      PVOID ParseContext;
    62.  
      KPROCESSOR_MODE ProbeMode;
    63.  
      ULONG PagedPoolCharge;
    64.  
      ULONG NonPagedPoolCharge;
    65.  
      ULONG SecurityDescriptorCharge;
    66.  
      PSECURITY_DESCRIPTOR SecurityDescriptor;
    67.  
      PSECURITY_QUALITY_OF_SERVICE SecurityQos;
    68.  
      SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
    69.  
      }OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
    70.  
       
    71.  
      typedef struct _OBJECT_HEADER
    72.  
      {
    73.  
      LONG PointerCount;
    74.  
      union
    75.  
      {
    76.  
      LONG HandleCount;
    77.  
      PSINGLE_LIST_ENTRY SEntry;
    78.  
      };
    79.  
      POBJECT_TYPE Type;
    80.  
      UCHAR NameInfoOffset;
    81.  
      UCHAR HandleInfoOffset;
    82.  
      UCHAR QuotaInfoOffset;
    83.  
      UCHAR Flags;
    84.  
      union
    85.  
      {
    86.  
      POBJECT_CREATE_INFORMATION ObjectCreateInfo;
    87.  
      PVOID QuotaBlockCharged;
    88.  
      };
    89.  
      PSECURITY_DESCRIPTOR SecurityDescriptor;
    90.  
      QUAD Body;
    91.  
      }OBJECT_HEADER, * POBJECT_HEADER;
    92.  
       
    93.  
      #define NUMBER_HASH_BUCKETS 37
    94.  
       
    95.  
      typedef struct _OBJECT_DIRECTORY
    96.  
      {
    97.  
      struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
    98.  
      struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
    99.  
      BOOLEAN LookupFound;
    100.  
      USHORT SymbolicLinkUsageCount;
    101.  
      struct _DEVICE_MAP* DeviceMap;
    102.  
      } OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
    103.  
       
    104.  
      typedef struct _OBJECT_HEADER_NAME_INFO
    105.  
      {
    106.  
      POBJECT_DIRECTORY Directory;
    107.  
      UNICODE_STRING Name;
    108.  
      ULONG QueryReferences;
    109.  
      #if DBG
    110.  
      ULONG QueryReferences2 ;
    111.  
      LONG DbgDereferenceCount ;
    112.  
      #endif
    113.  
      } OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
    114.  
      //////////////////////////////////////////////////////////////////////////
    115.  
      // ----OBJECT----
    116.  
      // ----------------------------
    117.  
      // | Object_Header |
    118.  
      // ----------------------------
    119.  
      // | Object_Body(QUAD Body) |
    120.  
      // ----------------------------
    121.  
      //example(device object):
    122.  
      //
    123.  
      //dt nt!_object_header
    124.  
      // +0x000 PointerCount : Int4B
    125.  
      // +0x004 HandleCount : Int4B
    126.  
      // +0x004 NextToFree : Ptr32 Void
    127.  
      // +0x008 Type : Ptr32 _OBJECT_TYPE
    128.  
      // +0x00c NameInfoOffset : UChar
    129.  
      // +0x00d HandleInfoOffset : UChar
    130.  
      // +0x00e QuotaInfoOffset : UChar
    131.  
      // +0x00f Flags : UChar
    132.  
      // +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
    133.  
      // +0x010 QuotaBlockCharged : Ptr32 Void
    134.  
      // +0x014 SecurityDescriptor : Ptr32 Void
    135.  
      // +0x018 Body : _QUAD //此处内容即下面的对象
    136.  
      //
    137.  
      //dt nt!_DEVICE_OBJECT
    138.  
      // +0x000 Type : Int2B
    139.  
      // +0x002 Size : Uint2B
    140.  
      // +0x004 ReferenceCount : Int4B
    141.  
      // +0x008 DriverObject : Ptr32 _DRIVER_OBJECT
    142.  
      // +0x00c NextDevice : Ptr32 _DEVICE_OBJECT
    143.  
      // +0x010 AttachedDevice : Ptr32 _DEVICE_OBJECT
    144.  
      // +0x014 CurrentIrp : Ptr32 _IRP
    145.  
      // +0x018 Timer : Ptr32 _IO_TIMER
    146.  
      // +0x01c Flags : Uint4B
    147.  
      // +0x020 Characteristics : Uint4B
    148.  
      // +0x024 Vpb : Ptr32 _VPB
    149.  
      // +0x028 DeviceExtension : Ptr32 Void
    150.  
      // +0x02c DeviceType : Uint4B
    151.  
      // +0x030 StackSize : Char
    152.  
      // +0x034 Queue : <unnamed-tag>
    153.  
      // +0x05c AlignmentRequirement : Uint4B
    154.  
      // +0x060 DeviceQueue : _KDEVICE_QUEUE
    155.  
      // +0x074 Dpc : _KDPC
    156.  
      // +0x094 ActiveThreadCount : Uint4B
    157.  
      // +0x098 SecurityDescriptor : Ptr32 Void
    158.  
      // +0x09c DeviceLock : _KEVENT
    159.  
      // +0x0ac SectorSize : Uint2B
    160.  
      // +0x0ae Spare1 : Uint2B
    161.  
      // +0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION
    162.  
      // +0x0b4 Reserved : Ptr32 Void
    163.  
      //
    164.  
      //////////////////////////////////////////////////////////////////////////
    165.  
       
    166.  
      #define OBJECT_TO_OBJECT_HEADER( o )
    167.  
      CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
    168.  
       
    169.  
      #define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO)
    170.  
      ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))


    ListDevice.cpp

    1.  
      // _ooOoo_
    2.  
      // o8888888o
    3.  
      // 88" . "88
    4.  
      // (| -_- |)
    5.  
      // O = /O
    6.  
      // ____/`---'\____
    7.  
      // . ' \| |// `.
    8.  
      // / \||| : |||//
    9.  
      // / _||||| -:- |||||-
    10.  
      // | | \ - /// | |
    11.  
      // | \_| ''---/'' | |
    12.  
      // .-\__ `-` ___/-. /
    13.  
      // ___`. .' /--.-- `. . __
    14.  
      // ."" '< `.___\_<|>_/___.' >'"".
    15.  
      // | | : `- \`.;` _ /`;.`/ - ` : | |
    16.  
      // `-. \_ __ /__ _/ .-` / /
    17.  
      // ======`-.____`-.___\_____/___.-`____.-'======
    18.  
      // `=---='
    19.  
      //
    20.  
      // .............................................
    21.  
      // 佛祖镇楼 BUG辟易
    22.  
      // 佛曰:
    23.  
      // 写字楼里写字间,写字间里程序员;
    24.  
      // 程序人员写程序,又拿程序换酒钱。
    25.  
      // 酒醒只在网上坐,酒醉还来网下眠;
    26.  
      // 酒醉酒醒日复日,网上网下年复年。
    27.  
      // 但愿老死电脑间,不愿鞠躬老板前;
    28.  
      // 奔驰宝马贵者趣,公交自行程序员。
    29.  
      // 别人笑我忒疯癫,我笑自己命太贱;
    30.  
      // 不见满街漂亮妹,哪个归得程序员?
    31.  
       
    32.  
      #include "ListDevice.h"
    33.  
       
    34.  
      NTSTATUS
    35.  
      DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
    36.  
      {
    37.  
      DbgPrint("Enter DriverEntry ");
    38.  
       
    39.  
      NTSTATUS status;
    40.  
      pDriverObject->DriverUnload = DriverUnload;
    41.  
      for (int i = 0; i< IRP_MJ_MAXIMUM_FUNCTION; i++)
    42.  
      {
    43.  
      pDriverObject->MajorFunction[i] = MyDispatchFunction;
    44.  
      }
    45.  
       
    46.  
      pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControlDispatch;
    47.  
      //准备创建设备
    48.  
      UNICODE_STRING ustrDevName, ustrSymbolicName;
    49.  
      RtlInitUnicodeString(&ustrDevName, L"\Device\KeListDevice");
    50.  
      RtlInitUnicodeString(&ustrSymbolicName, L"\DosDevices\KeListDeviceSL");
    51.  
      status = CreateDevice(pDriverObject, ustrDevName, ustrSymbolicName);
    52.  
      if(!NT_SUCCESS(status))
    53.  
      {
    54.  
      KdPrint(("Failed to Create Device ... "));
    55.  
      return STATUS_UNSUCCESSFUL;
    56.  
      }
    57.  
      KdPrint(("Exit DriverEntry "));
    58.  
      return STATUS_SUCCESS;
    59.  
      }
    60.  
       
    61.  
      NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject, UNICODE_STRING devname, UNICODE_STRING symLinkName)
    62.  
      {
    63.  
      NTSTATUS status;
    64.  
      PDEVICE_OBJECT pDevObj;
    65.  
      PDEVICE_EXTENSION pDevExt;
    66.  
      //创建设备
    67.  
      status = IoCreateDevice(pDriverObject,
    68.  
      sizeof(DEVICE_EXTENSION),
    69.  
      &devname,
    70.  
      FILE_DEVICE_UNKNOWN,
    71.  
      0,
    72.  
      TRUE,
    73.  
      &pDevObj);
    74.  
      if(!NT_SUCCESS(status))
    75.  
      return status;
    76.  
       
    77.  
      pDevObj->Flags |= DO_BUFFERED_IO;
    78.  
      pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
    79.  
      pDevExt->pDevice = pDevObj;
    80.  
      pDevExt->ustrDeviceName = devname;
    81.  
      pDevExt->ustrSymLinkName = symLinkName;
    82.  
       
    83.  
      //创建设备连接
    84.  
      status = IoCreateSymbolicLink(&symLinkName, &devname);
    85.  
      if(!NT_SUCCESS(status))
    86.  
      {
    87.  
      KdPrint(("Failed to IoCreateSymbolicLink and delete DeviceObject --- errorcode = %d ... ",status));
    88.  
      IoDeleteDevice(pDevObj);
    89.  
      return status;
    90.  
      }
    91.  
      return status;
    92.  
      }
    93.  
      //卸载驱动
    94.  
      VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
    95.  
      {
    96.  
      PDEVICE_OBJECT pNextObj;
    97.  
      KdPrint(("Enter DriverUnload... "));
    98.  
      pNextObj = pDriverObject->DeviceObject;
    99.  
      //循环遍历删除所有该驱动上的设备
    100.  
      while(pNextObj != NULL)
    101.  
      {
    102.  
      //设备的名称和链接名称均在扩展结构中存储
    103.  
      PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
    104.  
      //删除符号链接
    105.  
      UNICODE_STRING LinkName = pDevExt->ustrSymLinkName;
    106.  
      IoDeleteSymbolicLink(&LinkName);
    107.  
      pNextObj = pNextObj->NextDevice;
    108.  
      IoDeleteDevice(pDevExt->pDevice);
    109.  
      }
    110.  
      }
    111.  
      //IRP请求处理函数
    112.  
      NTSTATUS MyDispatchFunction(PDEVICE_OBJECT device, PIRP pIrp)
    113.  
      {
    114.  
      NTSTATUS status = STATUS_SUCCESS;
    115.  
      //完成IRP,此处不做任何特殊处理
    116.  
      pIrp->IoStatus.Status = status;
    117.  
      pIrp->IoStatus.Information = 0;
    118.  
      IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    119.  
      KdPrint(("Leave MyDispatchFunction "));
    120.  
      return status;
    121.  
      }
    122.  
      //处理消息
    123.  
      NTSTATUS DeviceIoControlDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    124.  
      {
    125.  
       
    126.  
      NTSTATUS status = STATUS_SUCCESS;
    127.  
       
    128.  
      KdPrint(("Enter DeviceIoControlDispatch... "));
    129.  
      PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    130.  
      ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
    131.  
      ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
    132.  
      //得到IOCTL码
    133.  
      ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
    134.  
      ULONG info = 0;
    135.  
      switch(code)
    136.  
      {
    137.  
      case IOCTL_DUMP_DEVICE_STACK:
    138.  
      {
    139.  
      KdPrint(("IOCTL_DUMP_DEVICE_STACK "));
    140.  
      WCHAR* InputBuffer = (WCHAR*)pIrp->AssociatedIrp.SystemBuffer; //ring3级传入的是WCHAR类型的字符串
    141.  
      EnumDeviceStack(InputBuffer);
    142.  
      }
    143.  
      default:
    144.  
      status = STATUS_INVALID_VARIANT;
    145.  
      }
    146.  
      //完成IRP,此处不做任何特殊处理
    147.  
      pIrp->IoStatus.Status = status;
    148.  
      pIrp->IoStatus.Information = info;
    149.  
      IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    150.  
      KdPrint(("Leave MyDispatchFunction "));
    151.  
      return status;
    152.  
      }
    153.  
       
    154.  
      //获取设备对象的信息
    155.  
      VOID GetDeviceObjectInfo(PDEVICE_OBJECT DevObj)
    156.  
      {
    157.  
      POBJECT_HEADER ObjectHeader;
    158.  
      POBJECT_HEADER_NAME_INFO ObjectNameInfo;
    159.  
       
    160.  
      if(DevObj == NULL)
    161.  
      {
    162.  
      DbgPrint("DevObj is NULL! ");
    163.  
      return;
    164.  
      }
    165.  
      ObjectHeader = OBJECT_TO_OBJECT_HEADER(DevObj); //由对象得到对象头
    166.  
      if(ObjectHeader)
    167.  
      {
    168.  
      //查询设备对象名称并打印
    169.  
      ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
    170.  
      if(ObjectNameInfo && ObjectNameInfo->Name.Buffer)
    171.  
      {
    172.  
      //打印设备相关信息
    173.  
      DbgPrint(" Driver Name : %wZ - Device Name :%wZ -Driver Address :0x%x - Device Address: 0x%x ",
    174.  
      &(DevObj->DriverObject->DriverName),
    175.  
      &(ObjectNameInfo->Name),
    176.  
      DevObj->DriverObject,
    177.  
      DevObj);
    178.  
      }
    179.  
      //无名子设备处理
    180.  
      else if (DevObj->DriverObject)
    181.  
      {
    182.  
      //打印设备相关信息
    183.  
      DbgPrint(" Driver Name : %wZ - Device Name :%wZ -Driver Address :0x%x - Device Address: 0x%x ",
    184.  
      &(DevObj->DriverObject->DriverName),
    185.  
      L"NULL",
    186.  
      DevObj->DriverObject,
    187.  
      DevObj);
    188.  
      }
    189.  
      }
    190.  
      }
    191.  
       
    192.  
      //遍历一个设备上所有的附加设备
    193.  
      VOID GetAttachedDeviceInfo(PDEVICE_OBJECT DevObj)
    194.  
      {
    195.  
      PDEVICE_OBJECT AtDeviceObject; //附加的设备
    196.  
      if(DevObj == NULL)
    197.  
      {
    198.  
      DbgPrint("DevObj is NULL! ");
    199.  
      return;
    200.  
      }
    201.  
       
    202.  
      AtDeviceObject = DevObj->AttachedDevice;
    203.  
       
    204.  
      while(AtDeviceObject)
    205.  
      {
    206.  
      DbgPrint( "Attached Driver Name:%wZ,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x ",
    207.  
      &(AtDeviceObject->DriverObject->DriverName),
    208.  
      AtDeviceObject->DriverObject,
    209.  
      AtDeviceObject );
    210.  
      AtDeviceObject = AtDeviceObject->AttachedDevice;
    211.  
      }
    212.  
      }
    213.  
      //枚举设备栈
    214.  
      PDRIVER_OBJECT EnumDeviceStack(PWSTR pwszDeviceName)
    215.  
      {
    216.  
      UNICODE_STRING DriverName;
    217.  
      PDRIVER_OBJECT DriverObject = NULL;
    218.  
      PDEVICE_OBJECT DeviceObject = NULL;
    219.  
       
    220.  
      RtlInitUnicodeString(&DriverName, pwszDeviceName); //本例是获得 高级电源管理驱动的设备栈
    221.  
       
    222.  
      ObReferenceObjectByName(&DriverName,
    223.  
      OBJ_CASE_INSENSITIVE,
    224.  
      NULL,
    225.  
      0,
    226.  
      (POBJECT_TYPE)IoDriverObjectType,
    227.  
      KernelMode,
    228.  
      NULL,
    229.  
      (PVOID*)&DriverObject);
    230.  
       
    231.  
      if(DriverObject == NULL)
    232.  
      return NULL;
    233.  
       
    234.  
      DeviceObject = DriverObject->DeviceObject;
    235.  
      while(DeviceObject)
    236.  
      {
    237.  
      GetDeviceObjectInfo(DeviceObject);
    238.  
      //判断是否有过滤驱动(附加驱动)
    239.  
      if(DeviceObject->AttachedDevice)
    240.  
      GetAttachedDeviceInfo(DeviceObject);
    241.  
       
    242.  
      //进一步判断设备上的VPB 中设备
    243.  
      if(DeviceObject->Vpb && DeviceObject->Vpb->DeviceObject)
    244.  
      {
    245.  
      GetDeviceObjectInfo(DeviceObject->Vpb->DeviceObject);
    246.  
      if(DeviceObject->Vpb->DeviceObject->AttachedDevice)
    247.  
      GetAttachedDeviceInfo(DeviceObject->Vpb->DeviceObject);
    248.  
      }
    249.  
      //得到驱动上的下一个设备DEVICE_OBJECT
    250.  
      DeviceObject = DeviceObject->NextDevice;
    251.  
      }
    252.  
      return DriverObject;
    253.  
      }
  • 相关阅读:
    解决:transform-decorators-legacy 报错
    leetcode刷题笔记 232题 用栈实现队列
    leetcode刷题笔记 231题 2的幂
    leetcode刷题笔记 230题 二叉搜索树中第K小的元素
    leetcode刷题笔记 229题 求众数II
    leetcode刷题笔记 228题 汇总区间
    leetcode刷题笔记 227题 基本计算器II
    leetcode刷题笔记 225题 用队列实现栈
    leetcode刷题笔记 224题 基本计算器
    leetcode刷题笔记 223题 矩形面积
  • 原文地址:https://www.cnblogs.com/kuangke/p/12390513.html
Copyright © 2020-2023  润新知