笔记-设备相关知识

news/2024/5/19 1:56:19/文章来源:https://blog.csdn.net/qq_31314583/article/details/126887691

目录

设备类

接口类

Windows 如何安装设备

步骤 1:标识设备

步骤 2:选择设备的驱动程序包

搜索驱动程序包

选择驱动程序

步骤 3:已安装设备的驱动程序包

硬件

为设备创建硬件 ID

根枚举设备的硬件 ID

获取设备的硬件 ID 列表

硬件 ID 示例

设备栈

相关函数

        IoGetAttachedDevice     栈顶获取

        IoGetDeviceAttachmentBaseRef     栈底获取

        IoAttachDeviceToDeviceStack     设备挂靠(接)

        IoDetachDevice    移除设备挂靠(接)



设备类

        为了方便设备安装,相同方式设置和配置的设备将分组到设备安装类中。

         设备设置类可以定义一些常见设置,这些设置适用于该设备安装类中的所有设备,例如应插入该设备 的设备堆栈 中的筛选器驱动程序。

        Microsoft 为大多数类型的设备定义设置类。 IHV 和 OEM 可以定义新的设备安装程序类,但前提是现有类都不适用。 例如,相机供应商不必定义新的设置类,因为相机属于相机设置类。 同样, (UPS) 设备的不间断电源属于电池类。

        每个设备设置类都有一个与 GUID 关联的 GUID。 系统定义的安装程序类 GUID 在 Devguid.h 中定义,通常具有表单GUID_DEVCLASS_Xxx 的符号名称。

接口类

        用户模式代码可以定向到其用户模式客户端的物理、逻辑或虚拟设备的任何驱动程序都必须为其用户模式客户端提供名称。 使用名称,用户模式应用程序 (或其他系统组件) 标识请求 I/O 的设备。

        从 Windows 2000 开始,驱动程序不会命名设备对象。 相反,它们使用按设备接口类分组的设备接口。 设备接口类是将设备和驱动程序功能导出到其他系统组件(包括其他驱动程序)以及用户模式应用程序的一种方式。 驱动程序可以为可能向其发送用户模式 I/O 请求的每个设备对象注册和启用设备接口类的设备接口实例。 每个 设备接口类 都应表示该类中任何 设备接口 应支持或表示(例如特定 I/O 协定)的概念性功能。

        每个设备接口类都与 GUID 相关联。 系统为特定于设备的头文件中的常见设备接口类定义 GUID。 供应商可以创建其他设备接口类。

        例如,三种不同类型的鼠标设备可以注册属于同一设备接口类的成员 的设备接口 ,即使一个设备接口通过 USB 端口连接,另一个通过串行端口进行连接,第三种通过红外端口进行连接。 每个驱动程序将其设备注册为接口类的成员GUID_DEVINTERFACE_MOUSE。 此 GUID 在头文件 Ntddmou.h 中定义。

        驱动程序可以为设备注册和启用设备 接口 ,这些设备可以控制设备和驱动程序支持的任意数量的 设备接口类 。 例如,可以装载的磁盘的驱动程序应注册其磁盘接口类 (GUID_DEVINTERFACE_DISK) 和可装载设备类 (MOUNTDEV_MOUNTED_DEVICE_GUID) 。

        当驱动程序注册设备接口类的设备接口实例时,I/O 管理器会将设备和设备接口类 GUID 与符号链接名称相关联。 驱动程序必须启用设备接口,以使该符号链接可供驱动程序或应用程序用来将 I/O 发送到。 在系统启动时,链接名称的注册会持续存在,但 设备接口 必须由设备的每个枚举上的驱动程序启用。 使用特定 设备接口类 的应用程序可以查询该类中的 设备接口 实例,并接收表示支持接口的设备符号链接名称列表。 然后,应用程序可以使用符号链接名称作为 I/O 请求的目标。

Windows 如何安装设备

        设备和驱动程序安装概述 - Windows drivers | Microsoft Learn

步骤 1:标识设备

        当总线驱动程序向 Windows 操作系统报告新设备时,Windows需要从总线驱动程序查询有关此设备的信息以识别设备。 出于其他原因,需要此信息来标识可能 ( 此) 驱动程序包。

        Windows使用这些 ID 查找设备和驱动程序包之间的最匹配

硬件 ID 或兼容 ID 的格式通常包括以下各项:

  • 特定于总线的前缀,例如 PCI\ 或 USB\。
  • 设备供应商特定的标识符,例如供应商、型号和修订号标识符。 ID 中这些标识符的格式也特定于总线驱动程序。

兼容 ID 通常比硬件 D 更通用,并且可能不包含特定的制造商或型号信息,可能只表示此硬件的设备类型。  

        Windows使用硬件 D 和兼容的 ID 搜索设备的驱动程序包。 它将设备的硬件 ID 和兼容 ID 与包 的 INF 文件中指定的这些 ID 进行比较,找到设备的匹配驱动程序包。

例如,当用户将无线局域网 (WLAN) 适配器插入连接到计算机的 USB 集线器端口时,将执行以下步骤:

  1. USB 集线器驱动程序检测到设备。 中心驱动程序根据从适配器查询的信息,为设备创建硬件 ID。 例如,USB 集线器驱动程序可以创建 WLAN 适配器的硬件 ID USB\VID_1234&PID_5678&REV_0001 。 有关 USB 硬件标识格式的信息,请参阅 USB 设备的标识符。

  2. USB 集线器驱动程序通知 PnP 即插即用 (管理器) 检测到新设备。 PnP 管理器会查询中心驱动程序,以查询设备的所有硬件 ID 和兼容的 ID。 中心驱动程序可以针对同一设备创建多个硬件 ID 和兼容的 ID。

  3. Windows驱动程序存储中开始搜索与设备的硬件 D 之一匹配的驱动程序包。 如果Windows找不到匹配的硬件 ID,它会搜索具有设备匹配兼容 ID 的驱动程序包。

    有关此过程的信息,请参阅 Step 2: A Driver for the Device is Selected

步骤 2:选择设备的驱动程序包

检测到新设备并进行识别后,Windows 及其设备安装组件执行以下步骤:

  1. Windows 搜索设备的匹配驱动程序包。 有关此步骤的详细信息,请参阅 搜索驱动程序包。
  2. Windows 从一个或多个驱动程序包中为设备选择最适合的驱动程序包 (s) 。 有关此步骤的详细信息,请参阅 选择驱动程序。

搜索驱动程序包

使用硬件标识符 (id) 和设备的总线驱动程序报告的兼容 id ,Windows 搜索与该设备相匹配的驱动程序包。 如果设备上的硬件 ID 或兼容 ID 与驱动程序包的inf 文件的 " INF模型" 部分条目中的 id 匹配,则驱动程序包与设备匹配。

例如,在 Windows 8 和更高版本中,如果用户将 WLAN 适配器插入 USB 集线器的端口,则会执行以下步骤:

  • USB 集线器驱动程序创建了 WLAN 适配器的硬件 id 和兼容 id 的列表后,Windows 首先在驱动程序存储区中搜索设备的匹配驱动程序包。 如果在驱动程序存储区中找到了驱动程序包,Windows 会将其安装在设备上。 这允许设备快速开始工作。

  • 在单独的进程中,Windows 搜索与从驱动程序存储区中安装的驱动程序更匹配的驱动程序 Windows 更新和 DevicePath。 如果找到一个,驱动程序将暂存到驱动程序存储区中,然后安装到设备上。

有关驱动程序包搜索过程的详细信息,请参阅Windows 搜索驱动程序的位置。

注意从 Windows Vista 开始,操作系统始终从驱动程序存储区安装驱动程序包。 如果在其他位置找到了匹配的驱动程序包,则 Windows 首先将包安装到驱动程序存储区,然后再将驱动程序包安装到设备上

选择驱动程序

一旦 Windows 找到了设备的一个或多个匹配的驱动程序包,Windows 通过执行以下步骤来选择最佳的驱动程序包:

  1. 如果 Windows 只找到一个匹配的驱动程序包,则它会在设备上安装该驱动程序包。

  2. 如果 Windows 找到多个匹配的驱动程序包,Windows 首先为每个驱动程序包中的每个匹配项分配一个排名值。 如果只有一个驱动程序具有最低排名值,则它会在设备上安装该驱动程序包。

    有关排名过程的详细信息,请参阅如何 Windows 对驱动程序进行排名。

  3. 如果多个驱动程序包具有相同的最低排名值,Windows 将使用驱动程序日期和版本为设备选择最佳驱动程序包。 日期和版本由驱动程序包的inf 文件中包含的inf DriverVer 指令指定。

步骤 3:已安装设备的驱动程序包

选择Windows设备的最佳驱动程序包后,Windows以下步骤安装驱动程序包:

  1. 根据驱动程序包的INF 文件中指令,Windows在设备上安装驱动程序包。 例如,它可以:

    • 根据所有相关 INF CopyFiles 指令的指定,将驱动程序二进制文件和其他关联文件复制到硬盘上的位置。

    • 执行由任何相关的 INF AddReg 指令指定的注册表操作。

    • 从"INF 版本" 部分中的 " 类"和" ClassGuid "条目向设备分配设备 安装程序类。

  2. 在设备上安装驱动程序包后,设备将重新启动。

  3. 在因重启而再次处理设备过程中,即插即用 (PnP) 管理器会为设备标识相应的函数驱动程序和任何可选的筛选器驱动程序,并尝试生成设备堆栈并启动设备。

    PnP 管理器为尚未加载的任何所需驱动程序调用 DriverEntry 例程。 然后,PnP 管理器调用每个驱动程序的 AddDevice 例程,从低筛选器驱动程序开始,然后调用函数驱动程序,最后调用任何上部筛选器驱动程序。 PnP 管理器将资源分配给设备(如果需要)并将IRP_MN_START_DEVICE发送到设备的驱动程序。

此步骤完成后,即可安装设备并准备好使用。

硬件

         硬件 ID 是供应商定义的标识字符串,Windows用于将设备与驱动程序包匹配。

         在大多数情况下,一个设备关联了多个硬件 ID。通常,硬件 ID 列表按与设备的适配程度由高到低的顺序排列。 例如,设备的概念硬件 ID 列表可能如下所示:

<Product X made by company Y with firmware revision Z>
<Product X made by company Y that is a device of type W>

为设备创建硬件 ID

设备枚举 (总线驱动程序) 向 即插即用 Manager (PnP) 报告硬件 ID。 通常,当总线驱动程序的作者需要为设备创建新的硬件 ID 时,它会向 PnP 报告,它将使用以下通用格式之一:

<enumerator>\<enumerator-specific-device-ID>

这是单个枚举器报告给即插即用 (PnP) 管理器的单个 PnP 设备的最常见格式。

\*<generic-device-ID>

星号表示设备受多个枚举器支持,如 ISAPNP 和 BIOS。

<device-class-specific-ID>

有关详细信息,请参阅通用标识符。

已建立自己的命名约定的现有设备类可能会使用自定义格式。 有关其硬件 ID 格式的信息,请参阅此类总线的硬件规范。

硬件 ID 的字符数(不包括 NULL 终止符)必须小于 MAX_DEVICE_ID_LEN。 此约束适用于硬件 ID 中所有字段与任何 \\ 字段分隔符的长度总和。 有关详细信息,请参阅 IRP_MN_QUERY_ID 的“操作”部分。

根枚举设备的硬件 ID

        根枚举设备特别,因此可以使用提供硬件 ID 的 API 创建这些设备。 具有共享泛型命名空间的硬件 ID 的根枚举设备,例如ROOT\SYSTEM,在更新Windows时,设备管理器出现黄色砰错误图标。

        为防止出现这种情况,可为具有根枚举设备的每个驱动程序使用唯一命名空间。 对于 USB 或系统设备,请使用 ROOT\[COMPANYNAME]\[DEVICENAME],而不是使用 ROOT\USB 或 ROOT\SYSTEM"。 然后,在安装之前检查 devnode 是否已存在。

获取设备的硬件 ID 列表

若要查找给定设备的硬件 ID 列表,请执行以下步骤:

  1. 打开“设备管理器”。

  2. 在树中找到该设备。

  3. 右键单击该设备并选择“属性”。

  4. 选择“详细信息”选项卡。

  5. 在“属性”下拉列表中,选择“硬件 ID”或“兼容 ID”。

还可以通过检索设备上的 DEVPKEY_Device_HardwareIds 属性以编程方式获取硬件 ID 列表。 例如,可以使用 API(例如 IoGetDevicePropertyData、 SetupDiGetDeviceProperty 或 CM_Get_DevNode_Property)检索该属性。

此例程检索到的硬件 ID 列表是一个 REG_MULTI_SZ 值。 硬件列表中的字符的最大数目(包括每个硬件 ID 后的 NULL 终止符和最终 NULL 终止符)为 REGSTR_VAL_MAX_HCID_LEN。 硬件 ID 列表中最多可以包含的 ID 数为 64 个。

硬件 ID 示例

下面是 PnP 设备通用标识符的示例:

root\*PNP0F08

下面是 PCI 设备标识符的示例:

PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02

设备栈

        每个驱动程序会创建一个或多个设备对象,组织上类似链表。

        结构与内存中的栈类似,DO即DEVICE_OBJECT中AttachedDevice 指向栈上更高一层的驱动DO,而DeviceExtension->AttachedTo 则指向下层的驱动。

        [转载]设备栈 - Acg!Check - 博客园

相关函数

        IoGetAttachedDevice     栈顶获取

//循环遍历DeviceObject->AttachedDevice,直至为NULL
PDEVICE_OBJECT IoGetAttachedDevice(IN PDEVICE_OBJECT DeviceObject
)
{//// 直到 Top 元素的 AttachedDevice == NULL //while (DeviceObject->AttachedDevice)DeviceObject = DeviceObject->AttachedDevice;return DeviceObject;
} 

        IoGetDeviceAttachmentBaseRef     栈底获取

//调用IopGetDeviceAttachmentBase实现
//而该函数循环遍历DeviceObject->DeviceObjectExtension->AttachedTo;直至为NULL实现
PDEVICE_OBJECT IoGetDeviceAttachmentBaseRef(IN PDEVICE_OBJECT  DeviceObject
)
{KIRQL OldIrql = KeRaiseIrqlToDpcLevel();PDEVICE_OBJECT Bottom = IopGetDeviceAttachmentBase(DeviceObject);ObfReferenceObject(Bottom);KfLowerIrql(OldIrql);return Bottom;
}PDEVICE_OBJECT IopGetDeviceAttachmentBase(IN PDEVICE_OBJECT  DeviceObject
)
{//// 根据 DeviceObjectExtension->AttachedTo 向下查找栈底// while (DeviceObject->DeviceObjectExtension->AttachedTo){DeviceObject = DeviceObject->DeviceObjectExtension->AttachedTo;}return DeviceObject;
} 

        IoAttachDeviceToDeviceStack     设备挂靠(接)

//调用IopGetDeviceAttachmentBase实现,
//而该函数循环遍历DeviceObject->DeviceObjectExtension->AttachedTo;直至为NULL实现
PDEVICE_OBJECT IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice,IN PDEVICE_OBJECT TargetDevice
)
{return IopAttachDeviceToDeviceStackSafe(SourceDevice, TargetDevice, NULL);// AttachedToDeviceObject 参数为 NULL
}PDEVICE_OBJECT IopAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,IN PDEVICE_OBJECT TargetDeviceOUT PDEVICE_OBJECT* AttachedToDeviceObject OPTIONAL
)
{PDEVICE_OBJECT devObj = NULL;// 返回被 attach 的 objectPDEVICE_EXTENSION SourceDeviceExtension = SourceDevice->DeviceObjectExtension;KIRQL OldIrql = KeRaiseIrqToDpcLevel();// 提升到 DISPATCH_LEVELif (IopVerifierOn == TRUE){IovAttachDeviceToDeviceStack(SourceDevice, TargetDevice);}//// 得到 stack top 的 device//devObj = IoGetAttachedDevice(TargetDevice);PDEVICE_EXTENSION DeviceExtension = devObj->DeviceObjectExtension;//// 下面进行 attach 操作//if ((devObj->Flags & DO_DEVICE_INITIALIZING == 0) &&(DeviceExtension->ExtensionFlags & (DOE_UNLOAD_PENDING | DOE_DELETE_PENDING |DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED) == 0)){devObj->Spare1++;devObj->AttachedDevice = SourceDevice;SourceDevice->StackSize = devObj->StackSize + 1;SourceDevice->AlignmentRequirement = devObj->AlignmentRequirement;SourceDevice->SectorSize = devObj->SectorSize;if (DeviceExtension->ExtensionFlags & DOE_START_PENDING){SourceDevice->DeviceObjectExtension->ExtensionFlags |= DOE_START_PENDING;}SourceDeviceExtension->AttachedTo = devObj;}else{devObj = NULL;}if (AttachedToDeviceObject != NULL){*AttachedToDeviceObject = devObj;// 返回被 attach 的 device object}KfLowerIrql(OldIrql);         // 恢复原 IRQL return devObj;
}

        IoAttachDeviceToDeviceStack() 函数的目的是将 SourceDevice 挂接在 TargetDevice 之上。那么 SourceDevice 将变为栈 Top 元素。

        成功挂接后,函数返回原 Top 元素,如图中的 device B object。

        IoDetachDevice    移除设备挂靠(接)

VOID
IoDetachDevice(IN OUT PDEVICE_OBJECT  TargetDevice
)
{KIRQL OldIrql = KeRaiseIrqlToDpcLevel();if (IopVerifierOn == TRUE){IovDetachDevice(TargerDevice);}//// 删除挂接//TargetDevice->AttachedDevice->DeviceObjectExtension->AttachedTo = NULL;TargerDevice->AttachedDevice = NULL;//// 检测是否需要 Unload 或 Delete 操作//if ((TargetDevice->DeviceObjectExtension->ExtensionFlags & (DOE_UNLOAD_PENDING |         DOE_DELETE_PENDING| DOE_REMOVE_PENDING)) && (TargerDevice->ReferenceCount == 0)){IopCompleteUnloadOrDelete(TargetDevice, FALSE, OldIrql);}else{KfLowerIrql(OldIrql);}
}

         IoDetachDevice() 函数接受的参数是由 IoAttachDeviceToDeviceStack() 挂接成功后返回的值。

        将移除 device B 元素。最后调用IopCompleteUnloadOrDelete()做 Unload 或 Delete 操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_12144.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低浓度阿拉特津(ATZ)诱导MCF-7细胞增殖的生物标志物发现及其代谢组学机制探究

低浓度阿拉特津&#xff08;ATZ&#xff09;诱导MCF-7细胞增殖的生物标志物发现及其代谢组学机制探究 文章标题&#xff1a;Integrated metabolomics and transcriptomics analysis reveals new biomarkers and mechanistic insights on atrazine exposures in MCF7 cells 发…

【转】详谈判断点在多边形内的七种方法

原帖地址: https://blog.csdn.net/WilliamSun0122/article/details/77994526 射线法时间复杂度:O(n) 适用范围:任意多边形算法思想:以被测点Q为端点,向任意方向作射线(一般水平向右作射线),统计该射线与多边形的交点数。如果为奇数,Q在多边形内;如果为偶数,Q在多边…

用工具刺探主机通信和用系统ping命令有何区别(新人常犯的错误)

ping是操作系统自带的命令,经常用来刺探对端主机是否在线,通信能否畅通。它的原理是在调用ping命令时驱动TCP/IP协议栈的ICMP模块发送icmp echo request消息,待对方主机的ICMP模块收到后,会自动回复icmp echo response消息。本方收到icmp echo response即可确认对方主机在线…

15天深度复习JavaWeb的详细笔记(十)——Filter、Listener、Ajax

文章目录demo10-Filter、Listener、Ajax1&#xff0c;Filter1.1 Filter概述1.2 Filter快速入门1.2.1 开发步骤1.2.2 代码演示1.3 Filter执行流程1.4 Filter拦截路径配置1.5 过滤器链1.5.1 概述1.5.2 代码演示2&#xff0c;Listener2.1 概述2.2 分类2.3 代码演示3&#xff0c;Aj…

Dev C++中窗口输出中文问题解决

1、window+R+regedit调出注册表 2、点击Dec_Dev-Cpp_ConsolePauser.exe 3、鼠标左键双击“CodePage”,弹出设置页面。选择“十进制”,输入65001 4、右键点击运行窗口的图标,选择属性,取消使用旧版控制台5、重新运行完美!!!

vue后台系统管理项目-角色权限分配管理功能

⭐️⭐️⭐️ 作者&#xff1a;船长在船上 &#x1f6a9;&#x1f6a9;&#x1f6a9; 主页&#xff1a;来访地址船长在船上的博客 &#x1f528;&#x1f528;&#x1f528; 简介&#xff1a;CSDN前端领域优质创作者&#xff0c;资深前端开发工程师&#xff0c;专注前端开发…

Java_面向对象的三大特征之_继承

继承 如何继承一个类&#xff1f; 使用继承有什么好处&#xff1f; super如何使用&#xff1f; 重写的概念使用&#xff1f; 继承的关键字是什么&#xff1f; 抽象的关键字是什么&#xff1f; 抽象类有什么特点&#xff1f; Final关键字都能修饰什么&#xff1f;修饰完…

DolphinScheduler任务调度源码剖析

1.数据表 t_ds_process_definition&#xff1a;工作流定义表 t_ds_process_definition_log t_ds_process_instance&#xff1a;工作流运行实例表 t_ds_task_definition&#xff1a;任务定义表 t_ds_task_definition_log t_ds_process_task_relation&#xff1a;任务关系表 …

Appium入门自动化测试(6)—— Appium 常用方法的自己动手封装

Appium 常用方法的自己动手封装 前言 阅读此文大概需要5分钟&#xff0c;之后需要自己动手实践。 之前我们已经对Appium的一些常用的API有所了解&#xff0c;在实际测试过程中&#xff0c;大多数自动化测试工程师&#xff0c;尤其是UI自动化测试工程师&#xff0c;遇到更多的…

c语言分层理解(枚举和联合体)

文章目录1. 枚举1.1 枚举定义1.2 枚举常量的理解1.3 枚举的优点1.4 枚举大小1.5 枚举变量的使用2.联合体&#xff08;共同体&#xff09;2.1 联合体定义1.2 联合体特点1.2.1 联合体实现判断大小端1.3 联合体的大小1.3.1 实例一1.3.2 实例二1. 枚举 1.1 枚举定义 枚举的意思就是…

第四:Fiddler抓包教程(4)-会话面板和HTTP会话数据操作详解

一.会话列表 (Session list) 概览 1.Fiddler抓取到的每条http请求&#xff08;每一条称为一个session&#xff09;&#xff0c;会话列表 主要是Fiddler所抓取到的每一条http请求都会显示到这里。主要包含了请求的ID编号、状态码、协议、主机名、URL、内容类型、body大小、进程…

基于安卓(Android)的即时实时聊天APP软件

安卓即时聊天软件 实习目的及要求 Android 开发提高&#xff1a; 提供&#xff16;个基础样例代码&#xff0c;发挥想象力和创造力对其中一个进行改进和提高&#xff0c;比如&#xff1a;增加程序的功能&#xff0c;改进程序的人机交互性&#xff0c;以及提高程序运行的性能…

出海非洲新启示?传音控股供应链合作的本土化融合

近日&#xff0c;美媒发表报道称&#xff0c;中国品牌正成为非洲智能手机市场领导者。该报道透露&#xff0c;传音控股的智能机在第二季度市场份额占比为48%&#xff0c;超过三星&#xff0c;进一步夯实非洲智能机市场领导者的地位。 在全球经济疲弱且市场竞争越发激烈的背景下…

CSS中的BFC是什么?

BFC就是符合一些特性的HTML标签 1、什么是BFC? BFC格式化上下文 指一个独立的渲染区域&#xff0c;或者说是一个隔离的独立容器&#xff0c;可以理解为一个独立的封闭空间。无论如何不会影响到它的外面。 2、形成BFC的条件 浮动元素&#xff0c;float除none以外的值&#…

SDN实验一

1、基础版 a) 第1步Mininet运行结果截图b) 第2步的执行结果截图c) 第3步提交修改过的“学号.py”代码、Mininet运行结果 #!/usr/bin/env pythonfrom mininet.net import Mininet from mininet.node import Controller, RemoteController, OVSController from mininet.node impo…

有关anaconda常见指令操作

有关anaconda常见指令操作 查看已安装的包 conda list [PACKAGE]卸载包 conda uninstall PACKAGE更新包 conda update PACKAGE查看虚拟环境及其位置 conda env list创建环境 conda create --name [my_env]激活环境 conda activate my_env退出环境 conda deactivate删除环境 co…

【网络安全】记一次杀猪盘渗透实战

看起来非常假的网站这个网站是没有cdn的用的是thinkphpk框架搭建的。 先打一波poc没有效果&#xff0c; 【一一帮助安全学习&#xff0c;所有资源获取处一一】 ①网络安全学习路线 ②20份渗透测试电子书 ③安全攻防357页笔记 ④50份安全攻防面试指南 ⑤安全红队渗透工具包 ⑥…

不能出门的第10天我焦虑了,为了金三银四决定刷完这千道Java试题

前言: 因为疫情我被困在了家里&#xff0c;我是一个被无聊笼罩的人&#xff0c;呆在家里为国家做贡献&#xff0c;打算年后面试找工作的我决定发奋刷面试题&#xff0c;不打无准备的仗&#xff0c;这么多面试题的收集整理花费了很多的时间和经历&#xff0c;程序员朋友们如果你…

多线程---线程安全

&#x1f389;&#x1f389;&#x1f389;写在前面&#xff1a; 博主主页&#xff1a;&#x1f339;&#x1f339;&#x1f339;戳一戳&#xff0c;欢迎大佬指点&#xff01; 目标梦想&#xff1a;进大厂&#xff0c;立志成为一个牛掰的Java程序猿&#xff0c;虽然现在还是一个…

springboot+基于Java的果蔬产品销售系统 毕业设计-附源码131110

中文摘要 本文首先先引入了在线购物网站系统除了后端内容管理系统的概念外&#xff0c;还介绍了所使用的相关技术&#xff0c;分析了当前的研究现状和发展趋势&#xff0c;研究了与目标系统&#xff0c;系统介绍和二次开发有关的主要技术&#xff1b; 然后重点关注系统的总体体…