枚举所有句柄的方法

由于windows并没有给出枚举所有句柄所用到的API,和进程所拥有的句柄相关的只有GetProcessHandleCount这个函数,然而这个函数只能获取到和进程相关的句柄数,不能获取到实际的句柄,要获得句柄,我们必须使用未公开的Native API才可以。
 
PS:网上有很多关于这类的方法,但几乎都是抄来抄去,很多连编译都过不了就直接放上去了(囧)。我整理了一下方法,实测在win10和win7都可以用。
NTSTATUS WINAPI NtQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
枚举的关键是使用NtQuerySystemInformation(旧版本是ZwQuerySystemInformation)这个方法
 
但MSDN上并没有把这个函数的第一个参数的枚举值给全,而且Windows API所定义的枚举值也是MSDN上面列的几个而已,如下:
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation = ,
SystemPerformanceInformation = ,
SystemTimeOfDayInformation = ,
SystemProcessInformation = ,
SystemProcessorPerformanceInformation = ,
SystemInterruptInformation = ,
SystemExceptionInformation = ,
SystemRegistryQuotaInformation = ,
SystemLookasideInformation = ,
SystemPolicyInformation = ,
} SYSTEM_INFORMATION_CLASS;
这几个值的定义在MSDN上都有,具体可以在上面给的链接的文档查到,这里就不列了。这些枚举值都是可以拿来指定NtQuerySystemInformation所查询的内容
 
然而所给到的枚举值并没有我们想要的枚举句柄的功能,这个时候只能求助于强大的搜索引擎了,我们可以查到比较完整的SYSTEM_INFORMATION_CLASS的定义是下面的列表
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemMirrorMemoryInformation,
SystemPerformanceTraceInformation,
SystemObsolete0,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemVerifierAddDriverInformation,
SystemVerifierRemoveDriverInformation,
SystemProcessorIdleInformation,
SystemLegacyDriverInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation,
SystemTimeSlipNotification,
SystemSessionCreate,
SystemSessionDetach,
SystemSessionInformation,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemVerifierThunkExtend,
SystemSessionProcessInformation,
SystemLoadGdiDriverInSystemSpace,
SystemNumaProcessorMap,
SystemPrefetcherInformation,
SystemExtendedProcessInformation,
SystemRecommendedSharedDataAlignment,
SystemComPlusPackage,
SystemNumaAvailableMemory,
SystemProcessorPowerInformation,
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHandleInformation,
SystemLostDelayedWriteInformation,
SystemBigPoolInformation,
SystemSessionPoolTagInformation,
SystemSessionMappedViewInformation,
SystemHotpatchInformation,
SystemObjectSecurityMode,
SystemWatchdogTimerHandler,
SystemWatchdogTimerInformation,
SystemLogicalProcessorInformation,
SystemWow64SharedInformation,
SystemRegisterFirmwareTableInformationHandler,
SystemFirmwareTableInformation,
SystemModuleInformationEx,
SystemVerifierTriageInformation,
SystemSuperfetchInformation,
SystemMemoryListInformation,
SystemFileCacheInformationEx,
MaxSystemInfoClass // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;
注意看到第17项(枚举值16)的SystemHandleInformation,这就是我们想要的东西,通过这个值传入NtQuerySystemInformation,然后在NtQuerySystemInformation的函数的第二项放入缓存空间长度,第三项放入缓存空间的指针即可。
 
现在我们要确定缓存区的类型了。如果我们传入SystemHandleInformation,那么NtQuerySystemInformation将会返回下面这个结构
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_INFORMATION Information[];//注意655360这个值是我自己定义的,你们可以自己定义其他的常量值
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
 
其中,SYSTEM_HANDLE_INFORMATION的定义是:
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;//进程标识符
UCHAR ObjectTypeNumber;//打开的对象的类型
UCHAR Flags;//句柄属性标志
USHORT Handle;//句柄数值,在进程打开的句柄中唯一标识某个句柄
PVOID Object;//这个就是句柄对应的EPROCESS的地址
ACCESS_MASK GrantedAccess;//句柄对象的访问权限
}SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
注意到这里有个很奇怪的地方,就是Handle值的类型是USHORT的,然而HANDLE的定义是void *,在32位上是4个字节,在64位上是8个字节。这就告诉我们,我们只能枚举到一个进程的0~65535个句柄值, 但是我们从Windows Internals这本书里面可以知道,现在Windows每个进程的句柄值已经可以到16000000以上了(虽然不会用到那么多)。
 
这样我们就可以根据ProcessId来获取我们感兴趣的进程的句柄值了,但是这里也有一个问题,虽然ProcessId的类型是ULONG,但是也只能枚举到16位以下的ProcessId的值,也就是枚举到的最大ProcessId值是65535,如果我们的程序的ProcessId大于65535,我们就不能枚举到这些进程所创建的句柄了。(这就是Undocument的函数不可靠的体现了)。
 
ObjectTypeNumber是我们想要的句柄值的类型,但是我暂时还无法找到关于这个值的详细资料,只是在windows driver里面查到了这个东西ObReferenceObjectByHandle,但是我现在想在ring3层把问题解决,暂时先不考虑驱动。事实上我们可以在Process Explorer里面根据把句柄值一个一个对应然后找到相应类型,比如下图:
我们可以看到获知句柄值为0x4时,对应的值是Type是Key

我们再来看下我们取到的Info的ObjectType是7,也就是说,我们的Key的类型值就是7

同理我们也可以找到File类型的ObjectType是35
 
 
 
我无法确定这个值是否会跟着系统不同而改变,如果要使用这个方法,请一定要先测试一下。
 
接下来的事情就很好办了,我们只要把NtQuerySystemInformation从NtDll.dll里面拉出来就可以了,我们可以写出这样的代码:
//头文件引#include <winternl.h>
#define SystemHandleInformation 0x10
typedef DWORD(WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
HMODULE hNtDll = LoadLibrary(L"ntdll.dll");
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
(NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "NtQuerySystemInformation");
ULONG cbBuffer = sizeof(SYSTEM_HANDLE_INFORMATION_EX);
LPVOID pBuffer = (LPVOID)malloc(cbBuffer);
if (pBuffer)
{
NtQuerySystemInformation(SystemHandleInformation, pBuffer, cbBuffer, NULL);
PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;
for (ULONG r = ; r < pInfo->NumberOfHandles; r++)
{
//dosomething
} free(pBuffer);
}
FreeModule(hNtDll);
 
Native API其他用法举例:查找文件句柄文件名的方法

有时候我们想查找句柄的所对应的信息,比如我之前就遇到了一个需要查找文件句柄所对应文件名的方法,这个时候也需要Native API来完成,需要用到ZwQueryInformationFile这个方法
NTSTATUS ZwQueryInformationFile(
_In_ HANDLE FileHandle,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_Out_ PVOID FileInformation,
_In_ ULONG Length,
_In_ FILE_INFORMATION_CLASS FileInformationClass
);
其中第一个参数是我们要查询的文件句柄,信息可以存放在FileInformation指向的内存中,这个内存的长度由Length指定。
 
现在我们来看下第二个参数IoStatusBlock的类型IO_STATUS_BLOCK
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
 
Pointer是个保留项,第一项就是指定IRP's I/O的返回值,这个值我们可以不用
 
最后一个参数是FILE_INFORMATION_CLASS类型的一个数,这个数可以拿来指定ZwQueryInformationFile所查询的内容(就像NtQuerySystemInformation的那一堆枚举值也是用来指定NtQuerySystemInformation所查询的内容一样),这个值在MSDN有完整的定义,但在VS自带的SDK里面却没有。
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = ,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileIoCompletionNotificationInformation,
FileIoStatusBlockRangeInformation,
FileIoPriorityHintInformation,
FileSfioReserveInformation,
FileSfioVolumeInformation,
FileHardLinkInformation,
FileProcessIdsUsingFileInformation,
FileNormalizedNameInformation,
FileNetworkPhysicalNameInformation,
FileIdGlobalTxDirectoryInformation,
FileIsRemoteDeviceInformation,
FileUnusedInformation,
FileNumaNodeInformation,
FileStandardLinkInformation,
FileRemoteProtocolInformation,
FileRenameInformationBypassAccessCheck,
FileLinkInformationBypassAccessCheck,
FileVolumeNameInformation,
FileIdInformation,
FileIdExtdDirectoryInformation,
FileReplaceCompletionInformation,
FileHardLinkFullIdInformation,
FileIdExtdBothDirectoryInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
 
在我们的例子中,我们需要用到的枚举值是FileNameInformation(枚举值9)
 
具体使用也像 一样,先从ntdll.dll里面导出来,然后把参数往里面填就好了,在这里我先定义一个缓冲区:
typedef struct _NM_INFO
{
HANDLE hFile;
FILE_NAME_INFORMATION Info;
} NM_INFO, *PNM_INFO;
 
FILE_NAME_INFORMATION结构:
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[];//256我自己定的,可以改成其他的,只要够放位置就行
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
 
调用API:
NM_INFO nmInfo = {  };
nmInfo.hFile = hFile;
PNM_INFO NmInfo = (PNM_INFO)lpParameter;
IO_STATUS_BLOCK IoStatus;
ZWQUERYINFORMATIONFILE ZwQueryInformationFile =
(ZWQUERYINFORMATIONFILE)GetProcAddress(hNtDll, "ZwQueryInformationFile");
ZwQueryInformationFile(NmInfo->hFile, &IoStatus, &NmInfo->Info, , FILE_INFORMATION_CLASS::FileNameInformation);
 
注意查询出来的FileNameLength是字节数,而不是WCHAR数组的最大偏移值,在这里WCHAR的最大偏移值应该是512,因为WCHAR是两个字节的
 
 
例子:找出所有文件句柄,并且把对应文件名含有ABC的句柄关掉

注意我把FILE_INFORMATION_CLASS改了个名字,改成了RFILE_INFORMATION_CLASS,这是因为SDK里面已经有了一个FILE_INFORMATION_CLASS了,而且我还把第一个枚举值给改了个名字,如果用以前的那个不知道为啥VS不给编译通过。
 
#include <afx.h>
#include <winternl.h>
typedef DWORD(WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
}SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
#define STATUS_INFO_LENGTH_MISMATCH 0x004
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_INFORMATION Information[];
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
#define SystemHandleInformation 0x10 //
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _NM_INFO
{
HANDLE hFile;
FILE_NAME_INFORMATION Info;
} NM_INFO, *PNM_INFO;
typedef enum _RFILE_INFORMATION_CLASS {
FileDirectoryInformation1 = ,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileIoCompletionNotificationInformation,
FileIoStatusBlockRangeInformation,
FileIoPriorityHintInformation,
FileSfioReserveInformation,
FileSfioVolumeInformation,
FileHardLinkInformation,
FileProcessIdsUsingFileInformation,
FileNormalizedNameInformation,
FileNetworkPhysicalNameInformation,
FileIdGlobalTxDirectoryInformation,
FileIsRemoteDeviceInformation,
FileUnusedInformation,
FileNumaNodeInformation,
FileStandardLinkInformation,
FileRemoteProtocolInformation,
FileRenameInformationBypassAccessCheck,
FileLinkInformationBypassAccessCheck,
FileVolumeNameInformation,
FileIdInformation,
FileIdExtdDirectoryInformation,
FileReplaceCompletionInformation,
FileHardLinkFullIdInformation,
FileIdExtdBothDirectoryInformation,
FileMaximumInformation
} RFILE_INFORMATION_CLASS, *PRFILE_INFORMATION_CLASS;
typedef NTSTATUS(WINAPI *ZWQUERYINFORMATIONFILE)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, RFILE_INFORMATION_CLASS);
CString GetFileName(HMODULE hNtDll, PNM_INFO lpParameter)
{
PNM_INFO NmInfo = (PNM_INFO)lpParameter;
IO_STATUS_BLOCK IoStatus;
ZWQUERYINFORMATIONFILE ZwQueryInformationFile =
(ZWQUERYINFORMATIONFILE)GetProcAddress(hNtDll, "ZwQueryInformationFile");
ZwQueryInformationFile(NmInfo->hFile, &IoStatus, &NmInfo->Info, , RFILE_INFORMATION_CLASS::FileNameInformation);
if (NmInfo->Info.FileNameLength != )
{
CString str;
str.Append(NmInfo->Info.FileName, NmInfo->Info.FileNameLength / sizeof(WCHAR));
return str;
}
return CString();
}
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
HMODULE hNtDll = LoadLibrary(L"ntdll.dll");
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
(NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "ZwQuerySystemInformation");
ULONG cbBuffer = sizeof(SYSTEM_HANDLE_INFORMATION_EX);
LPVOID pBuffer = (LPVOID)malloc(cbBuffer);
auto id= GetCurrentProcessId();
if (pBuffer)
{
NtQuerySystemInformation(SystemHandleInformation, pBuffer, cbBuffer, NULL);
PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;
for (ULONG r = ; r < pInfo->NumberOfHandles; r++)
{
if (pInfo->Information[r].ObjectTypeNumber == )
{
NM_INFO nmInfo = { };
nmInfo.hFile = (HANDLE)pInfo->Information[r].Handle;
CString fileName = GetFileName(hNtDll, &nmInfo);
if (!fileName.IsEmpty())
{
if (fileName.Find(L"ABC") != -)
{
CloseHandle(nmInfo.hFile);
}
}
}
} free(pBuffer);
}
FreeModule(hNtDll);
return ;
}
 

用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法的更多相关文章

  1. 掉坑日志:Windows Native API与DPI缩放

    高DPI显示器越来越普及,软件自然也要适应这个变化,最近实习的时候也遇到了一个关于DPI缩放的问题.因为内部框架的一个控件有BUG,会导致内容的显示出问题,后来实在没办法改成了用Windows Nat ...

  2. Windows Native API

    http://en.wikipedia.org/wiki/Native_API Windows 的原生 API 函数通常在系统启动时(这里其他 Windows 组件还不可用).kernel32.dll ...

  3. 不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符

    [源码下载] 不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 结构体 ...

  4. Windows下如何枚举所有进程

    要编写一个类似于 Windows 任务管理器的软件,首先遇到的问题是如何实现枚举所有进程.暂且不考虑进入核心态去查隐藏进程一类的,下面提供几种方法.请注意每种方法的使用局限,比如使用这些 API 所需 ...

  5. 驱动开发:内核枚举PspCidTable句柄表

    在上一篇文章<驱动开发:内核枚举DpcTimer定时器>中我们通过枚举特征码的方式找到了DPC定时器基址并输出了内核中存在的定时器列表,本章将学习如何通过特征码定位的方式寻找Windows ...

  6. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  7. 不可或缺 Windows Native 系列文章索引

    [源码下载] 不可或缺 Windows Native 系列文章索引 作者:webabcd 1.不可或缺 Windows Native (1) - C 语言: hello c 介绍不可或缺 Window ...

  8. node-webkit教程(9)native api 之Tray(托盘)

    node-webkit教程(9)native api 之Tray(托盘) 文/玄魂 目录 node-webkit教程(9)native api 之Tray(托盘) 前言 9.1  Tray简介 9.2 ...

  9. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

随机推荐

  1. jenkins 找不到mvn 命令

    错误如下: /data/jenkins/temp/hudson9132559581388971644.sh: line 4: mvn: command not found 方法如下: 1  修改环境变 ...

  2. C#中的结构体要使用new来实例化吗?

    声明结构的默认(无参数)构造函数是错误的.总是提供默认构造函数以将结构成员初始化为它们的默认值.在结构中初始化实例字段也是错误的. 如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当 ...

  3. Openjudge2729 Blah数集(单调队列)

    2729:Blah数集 总时间限制:  3000ms 内存限制:  65536kB 描述 大数学家高斯小时候偶然间发现一种有趣的自然数集合Blah,对于以a为基的集合Ba定义如下:(1) a是集合Ba ...

  4. 遍历问题 codevs

    1029 遍历问题 1029 遍历问题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 我们都很熟悉二叉树的前序.中序. ...

  5. uoj#351. 新年的叶子(概率期望)

    传送门 数学还是太差了,想了半天都没想出来 首先有一个定理,如果直径(这里考虑经过的点数)为奇数,所有直径有同一个中点,如果直径为偶数,所有直径有同一条最中间的边.这个可以用反证法,假设不成立的话直径 ...

  6. 洛谷P3264 [JLOI2015]管道连接(斯坦纳树)

    传送门 感觉对斯坦纳树还是有很多疑惑啊…… 等到时候noip没有爆零的话再回来填坑好了 //minamoto #include<iostream> #include<cstdio&g ...

  7. SpringMVC 控制器写多个方法(非注解方式)

    Controller类有两种方法 1,implements Controller(实现Controller接口) 2,extends MultiActionController(继承 MultiAct ...

  8. STP-7-RSTP的BPDU格式和处理方式的改变

    RSTP只使用一种BPDU,协议版本字段为2(STP为0). STP标志字段8位只使用了两位:TC(拓扑变化)和TCA(拓扑变化确认). RSTP也使用了其余6位:提议位,端口角色位,学习位,转发位, ...

  9. vue教程6-图表

    引入 cnpm install echarts --save #在vue项目目录下安装echarts 静态折线图 linechart.js import echarts from 'echarts' ...

  10. CF914D Bash and a Tough Math Puzzle 线段树+gcd??奇怪而精妙

    嗯~~,好题... 用线段树维护区间gcd,按如下法则递归:(记题目中猜测的那个数为x,改动次数为tot) 1.若子区间的gcd是x的倍数,不递归: 2.若子区间的gcd是x的倍数,且没有递归到叶子结 ...