第9章底层开发

合集下载

《实用软件工程》第9章 面向对象设计

《实用软件工程》第9章 面向对象设计

• 信息隐藏:对于类而言,其内部信息如属性的表示方法和操作的实现算法,对 外界是隐藏的。外界通过有限的接口来访问类的内部信息。
17
9.3.2 面向对象设计的原则
• 低耦合:在面向对象设计中,耦合主要指对象之间相互关联的紧密程度,低耦 合有利于降低一个模块改变对其他模块的影响。
• 高内聚:内聚与耦合密切相关,低耦合往往意味着高内聚,高内聚有助于提高 系统独立性。
但随着需求理解的加深,以及对系统认识程度的逐步 提高,设计人员还要对模型进行修正和完善。 • 设计任务管理子系统包括确定任务,分配任务,还包 括权衡一致性、成本、性能等因素以及未来可扩充性。 • 设计数据管理子系统,需要设计数据格式以及相应的 服务,设计数据格式的方法与所用的数据存储管理模 式密切相关,不同数据存储管理模式时,属性和服务 的设计方法是不同的。
9.2 面向对象设计与面向对象分析的关系
• 设计阶段的任务是及时把分析阶段得到的需求转变成符合各项要求的 系统实现方案。与传统的软件工程方法不同的是,面向对象的方法不强调 需求分析和软件设计的严格区分。实际上,面向对象的需求分析和面向对 象的设计活动是一个反复迭代的过程,从分析到设计的过渡,是一个逐渐 扩充、细化和完善分析阶段所得到的各种模型的过程。严格的意义上来讲, 从面向对象分析到面向对象设计不存在转换问题,而是同一种表示方法在 不同范围的运用。面向对象设计也不仅仅是对面向对象分析模型进行细化。
• (2)人机交互子系统包括有效的人机交互所需的显示和输入,这些类在很大程度上 依赖于所用的图形用户界面环境,例如Windows、Delphi、C++,而且可能包括“窗 口”、“菜单”、“滚动条”、“按钮”等针对项目的特殊类。
25
9.5.1 系统分解

第9章-ARM汇编语言程序设计基础(87)

第9章-ARM汇编语言程序设计基础(87)
12:30
A Free sample background from
4
Slide 5
9.1.1 ADS工具包的组成
ADS是ARM公司推出的集成开发工具包,专用于ARM应用开发 和调试的综合性软件。目前常用的版本是1.2,在功能和易用性 上比早期的SDT都有提高,是一款功能强大又易于使用的开发工 具。ARM ADS包含有编译器、链接器、CodeWarrior IDE、调试 器、指令集模拟器、ARM开发包和应用库等部分,可以用ADS开 发、编译、调试采用包括C、C++和ARM汇编语言编写的程序。 1.编译器
12:30
A Free sample background from
2
Slide 3
第9章 ARM汇编语言程序设计基础
9.1 ADS集成开发环境 9.2 ARM汇编伪指令
4-32 33-49
9.3 ARM的汇编语言结构
9.4 ARM汇编语言程序调试
在命令控制台环境下,输人命令“C:>armcc-help”可以查看armcc的语法 格式以及最常用的一些操作选项。
( 2 ) armcpp: armcpp 是 ARM C++ 编译器 。它将 ISO C++ 或 EC++ 源码编译 成 32 位ARM指令代码; (3)tcc: tcc是Thumb C编译器。编译器通过了Plum Hall C Validation Suite为ANSI一致性测试。tcc将ANSIC源代码编译成16位的Thumb指令代码。
12:30
A Free sample background from
11
Slide 12
命令行开发工具
(4)tcpp: tcpp是Thumb C++编译器。它将ISO C++或EC++源码编译成16位 Thumb指令代码; armcpp、tcc和tcpp的命令行格式与armcc相同。 (5)armsm: armsm是ARM和Thumb的汇编器.它对用ARM汇编语言和Thumb汇编 语言写的源代码进行汇编; (6)armlink: armlink是ARM连接器。该命令即可以将编译得到的一个或多 个目标文件和相关的一个或多个库文件进行链接,生成一个可执行文件,也 可以将多个目标文件部分链接成一个目标文件,以供进一步的链接。ARM链 接器生成的是ELF格式的可执行映像文件; (7)armsd: armsd是ARM和Thumb的符号调试器。它能够进行源码级的程序 调试。用户可以在用C语言或汇编语言写的代码中进行单步调试,设臵断点 ,查看变量值和内存单元的内容。

云计算导论 第9章-云计算导论(第2版)-吕云翔-清华大学出版社

云计算导论 第9章-云计算导论(第2版)-吕云翔-清华大学出版社

3、阿里云的主要产品
➢ 弹性计算
云服务器ECS。一种简单高效,处理能力可弹性伸缩的计算服务;
云引擎ACE。一种弹性、分布式的应用托管环境,支持Java、PHP、 Python、Node.js等多种语言环境。帮助开发者快速开发和部署服务 端应用程序,并简化系统维护工作。搭载了丰富的分布式扩展服务, 为应用程序提供强大助力;
第3节 亚马逊的弹性计算云
弹性计算云(Elastic Compute Cloud,EC2) ➢开放的服务 与Google公司提供的云计算服务不同,Google公司仅为自己在互 联网上的应用提供云计算平台,独立开发商或者开发人员无法在这 个平台上工作,因此只 能转而通过开源的Hadoop软件支持来开发 云计算应用。 亚马逊公司将自己的弹性计算云建立在公司内部的大规模集群计 算的平台之上,而用户可以通过弹性计算云的网络界面去操作在云 计算平台上运行的各个实例(Instance),而付费方式则由用户的使 用状况决定,即用户仅需要为自己所使用的计算平台实例付费,运 行结束后计费也随之结束。 ➢灵活的工作模式
1、蓝云云计算平台中的虚拟化
➢在每一个节点上运行的软件栈与传统的软件栈一个很大的不同在 于蓝云云计算平台内部使用了虚拟化技术。 ➢通过将虚拟化的技术应用到云计算的平台,可以获得如下一些良 好的特性:
云计算的管理平台能够动态地将计算平台定位到所需要的物理平台上; 能够更加有效率地使用主机资源; 通过动态迁移,能够获得与应用无关的负载平衡性能; 在部署上也更加灵活。
在弹性计算云中的每一个计算实例都具有一个内部的IP地址,用 户程序可以使用内部IP地址进行数据通信,以获得数据通信的最好 性能。
第4节 IBM蓝云云计算平台
➢IBM公司在2007年11月15日推出了蓝云计算平台,为用户提供“即 买即用”的云计算平台。 ➢它包括一系列的云计算产品,使得计算不仅仅局限在本地机器或 远程服务器农场(即服务器集群),通过架构一个分布式、可全球 访问的资源结构,使得数据中心在类似于互联网的环境下运行计算。

云计算导论:概念架构与应用_PPT课件第9章 超融合架构介绍

云计算导论:概念架构与应用_PPT课件第9章 超融合架构介绍

Pool和PG分布情况
Pool是Ceph存储数据时的逻辑分区, 它起到Namespace的作用
每个Pool包含一定数量(可配置)的PG, 不随着物理节点的增减而变化
PG里的对象被映射到不同的Object上 Pool是分布到整个集群的 Pool可以做故障隔离域,根据不同的
用户场景不一进行隔离
04 竞争优势---对传统数据中心价值提升
传统IT架构 上一代云计算架构
数据安全性 01

业务可靠性 02

系统扩展性 03

总体建设成本 04

资源利用率 05

运行效率 06

业务交付周期 07

中 高 高 中 中 中 分钟级
超融合架构
高 高 高 低 高 高 分钟级
2
Ceph分布式文件系统介绍
VM1
Attachment
VM2 …
VMMS
以快照为基础进行Volume创建
逻辑卷可以以某个时间点的快照为基础进行创建,这样可以很容易 的创建多个相同的逻辑卷,使得多个虚拟机实例可以执行相同的计 算任务
Snapshots LV1
/lost+found /etc /var …
LV2
EBS
Attachment Attachment
Ceph概述
什么是Ceph
➢ Ceph是一个统一的分布式存储系统,提供较好的性能、可靠性和可扩展性 ➢ 统一的:Ceph同时提供对象存储、块存储、文件系统存储三种功能 ➢ 分布式:真正的无中心结构和没有理论上限的系统规模可扩展性
传统
Ceph
Ceph概述
编程访问
应用程序
虚拟机、iSCSI

《计算机组成与系统结构》课件第9章

《计算机组成与系统结构》课件第9章

2) 多级互连网络 另一种组织与控制更为有效的交换网络是基于a×b交换 开关构造而成的。2×2交换开关是一种最常用的二元开关, 如图9.13(a)所示,它有两个输入和两个输出,从任意输入 线到达的消息都可以交换到任意的输出线上。
图 9.13 2×2的交换开关
图 9.14 Omega网络
多级互连网络设计的关键是: (1) 选择何种交换开关; (2) 交换开关之间采用何种拓扑连接; (3) 对交换开关采用何种控制方式。
图 9.3 计算机分类
9.3 阵列处理机和向量处理机
9.3.1 阵列处理机 阵列处理机属于分布式内存SIMD(DM-SIMD)系统,它
由许多在不同数据集合上执行同样指令序列、完成同样功能 的完全相同的处理器组成。阵列处理机中的处理器共享一 个控制器(所以它不是通常意义上的独立CPU),控制器发布 指令,指令由处理器阵列中的处理器执行。因为阵列机中的 所有处理器是以步调一致的方式工作的,所以处理器之间不 需要同步,这就大大简化了这种系统的设计。
向量-寄存器处理器的基本组成如图9.5所示,它是以 Cray-1为基础的一个模型,标量部分是MIPS,向量部分是 MIPS的逻辑向量扩展,其主要模块功能如下:
(1) 向量寄存器组。 (2) 向量功能单元。 (3) 向量Load-Store部件。 (4) 标量寄存器组。
图 9.5 基本的向量-寄存器体系结构
9.4 互 连 网 络
9.4.1 基本概念 互连网络(Interconnection Network)是一种由开关元件按
照一定的拓扑结构和控制方式构成的网络,用于实现计算机 系统中部件之间、处理器之间、部件与处理器之间甚至计 算机之间的相互连接,
根据连接的设备数和设备的接近程度,可以将互连网络 分为以下四类:

第9章 层次式设计(hierarchy design)

第9章  层次式设计(hierarchy  design)

第9章 层次式设计(Hierarchy Design)在一般的设计方法中可分为top down或bottom up两种,以VHDL来做设计自然也不例外。

每个设计者都有自己的设计风格,有些设计者的设计是从头到尾只有一个程序,即使三五千行的程序仍是一个程序通到底。

有些设计者的设计则固定会分成十来个小的方块,即使最小的设计是一个flip-flop也无所谓。

我个人认为较好的方式是先将整个设计依功能上的需要划分成数个小的区块,再从每个小区块中进行底层模块详细设计。

也就是说在功能划分上采用top down的方式,而在底层模块设计上采取bottom up的方式。

就如同图9-1中,先将整个设计A划分成B及C两个设计,之后再将设计B及设计C各划分成D、E、F及G四个设计。

在划分阶段并没有考虑底层模块具体实现,只以功能相似与否做参考。

等到划分完成后做底层模块详细设计时,再由D、E、F及G四个设计先开始。

9-1Component Instantiation到第9章才开始介绍这个标题似乎有些晚了,因为它并不一定是在层次结构的设计中才看得到。

小到一个反相器也是可以用component instantiation的方式将其放在设计中。

然而以VHDL从事设计,号称是高级语言的设计方式,若是每个小的基本器件都还要把component instantiation的方式放在设计中,那还不如以schematics(绘制电路原理图的方式)设计来得更容易接受,因此在这里是将整个设计分成功能相近的几个方块,再以component instantiation的方式将这几个依功能区分的方块相连接,成为一个完整的设计。

在使用component instantiation前要先声明component,声明的位置有两种:一是声明在package中,一是直接在source文档中声明。

要是在source文档中声明,就要将其位置在architecture与begin之间的声明部分中。

精品PPT课件--第9章软件体系结构与设计模式

精品PPT课件--第9章软件体系结构与设计模式
在组织形式上,框架是一个待实例化的完整系统,定义 了软件系统的元素和关系,创建了基本的模块,定义了涉 及功能更改和扩充的插件位置。典型的框架例子有MFC框 架和Struts框架。
9.1 软件体系结构的基本概念
• 体系结构的重要作用
体系结构的重要作用体现在以下三个方面 : (1)体系结构的表示有助于风险承担者(项目干系
层次结构具有以下优点: (1)支持基于抽象程度递增的系统设计,使设计者可以把
一个复杂系统按递增的步骤进行分解。 (2)支持功能增强,因为每一层至多和相邻的上下层交
互,因此,功能的改变最多影响相邻的内外层。
9.2 典型的体系结构风格
(3)支持复用。只要提供的服务接口定义不变,同一层的 不同实现可以交换使用。这样,就可以定义一组标准 的接口,从而允许各种不同的实现方法。
9.1 软件体系结构的基本概念
2.风格
风格是带有一种倾向性的模式。同一个问题可以有不同 的解决问题的方案或模式,但我们根据经验,通常会强烈 倾向于采用特定的模式,这就是风格。
每种风格描述一种系统范畴,该范畴包括: (1)一组构件(如数据库、计算模块)完成系统需要的某
种功能; (2)一组连接件,它们能使构件间实现“通信”、“合作”
个对象的表示,而不影响其他对象。 (2)设计者可将一些数据存取操作的问题分解成一些交互
的代理程序的集合。
9.2 典型的体系结构风格
其缺点如下: (1)为了使一个对象和另一个对象通过过程调用等进行
交互,必须知道对象的标识。只要一个对象的标识 改变了,就必须修改所有其他明确调用它的对象。 (2)必须修改所有显式调用它的其他对象,并消除由此 带来的一些副作用。例如,如果A使用了对象B,C 也使用了对象B,那么,C对B的使用所造成的对A 的影响可能是料想不到的。

《大数据技术原理与操作应用》第9章习题答案

《大数据技术原理与操作应用》第9章习题答案

第9章课后习题答案一、选择题1.下列语句中,描述错误的是( ) 。

A.可以通过 CLI 方式、Java Api 方式调用 Sqoop。

B.Sqoop 底层会将 Sqoop 命令转换为 MapReduce 任务,并通过 Sqoop 连接器进行数据的导入导出操作。

C.Sqoop 是独立的数据迁移工具,可以在任何系统上执行。

D.如果在Hadoop 分布式集群环境下,连接MySQL 服务器参数不能是“ localhost” 或“127. 0. 0. 1” 。

参考答案:C2.下列选项中,属于 Sqoop 命令的参数有() 。

A. importB. outputC. inputD. export参考答案:AD二、判断题1.Sqoop 工具的使用,依赖 Java 环境和 Hadoop 环境。

( )参考答案:对2.Sqoop 从 Hive 表导出 MySQL 表时,首先需要在 MySQL 中创建表结构。

( )参考答案:对3.如果没有指定“ --num-mappers 1”( 或“ -m 1”,即 Map 任务个数为“1”),那么在命令中必须还要添加“ --split-by” 参数。

( )参考答案:对4.如果指定了“ \n” 为 Sqoop 导入的换行符,当 MySQL 的某个 string 字段的值如果包含了“ \n”, 则会导致 Sqoop 导入多出一行记录。

( )参考答案:对5.在导入开始之前,Sqoop 使用 JDBC 来检查将要导入的表,检索出表中所有的列以及列的SQL 数据类型。

( )参考答案:对6.merge 是将两个数据集合并的工具,对于相同的 value 会覆盖新值。

( )参考答案:错7.metastore 文件的存储位置可以通过“conf / sqoop-site. xml” 配置文件修改。

()参考答案:对8.$CONDITIONS相当于一个动态占位符,动态的接收传过滤后的子集数据,然后让每个Map 任务执行查询的结果并进行数据导入。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第9章底层开发很多程序往往需要实现和硬件打交道的功能,这种功能特别是对于那些不能开发驱动程序的语言来说,显得特别重要。

这时可以采用C或者汇编语言开发一个驱动程序,通过这些程序和驱动程序通信,实现硬件的驱动。

9.1 基于WindowsNT操作系统的端口直接读写WindowsNT/2000是一个非常出色的操作系统,凭借其安全性、可靠性、稳定性以及良好的人机交互界面,在商业高端操作系统中占据一席之地,成为工业控制计算机首选的操作系统。

然而,Windows NT并不是一个实时的操作系统,出于安全稳定性考虑,它禁止用户态的应用程序直接操纵硬件,所有涉及物理内存、磁盘、中断、端口读写的操作,必须通过一个内核态的WDM驱动程序完成,否则就会出现一个特权指令异常的消息,系统提示用户要么终止、要么调试这个出现异常的应用程序。

即便用户在WindowsNT的控制台窗口进行端口读写,IO操作要么被忽略,要么被一个叫做VDD 的虚拟设备驱动程序实现,尽管没有出现任何例外,但是用户并没有获得真正的IO口直接读写。

通过编写WDM驱动程序,用户态应用程序可以借助与WDM程序的通信(利用CreateFile、CloseHandle、DeviceIOControl),实现IO读写,直接存取硬件。

然而,一个CPUIO指令大约只需要30多个指令周期,然而调用驱动程序再要花费6000到12000个时钟周期,这将使系统的实时性和灵敏度大打折扣。

端口指令允许所有的80X86CPU与系统中的其他硬件设备通信,从而实现对硬件设备的直接低层次控制。

在C语言中提供了类似于汇编语言的端口操作指令,允许用户实现端口的读写。

然而在WindowsNT/2000环境下,直接运行这些操作函数,将导致特权指令异常,并给出终止或者调试出错应用程序的选择。

如果在WindowsNT/2000控制台窗口中运行16位的DOS应用程序进行端口操作,这时这些IO操作要么被忽略,要么通过WindowsNT/2000虚拟设备驱动程序仿真实现。

尽管没有任何异常,但是用户得不到真正的IO操作。

这是因为WindowsNT/2000的安全机制不允许用户态的应用程序直接访问硬件,从而摧毁和搞垮WindowsNT/2000无懈可击的稳定性。

WindowsNT/2000规定用户态程序所有的IO操作必须借助于DeviceIOControl函数和内核驱动程序进行通信实现,然而和内核的通信势必会造成大量的时钟周期浪费和开销。

WindowsNT/2000只允许内核态的应用程序存取所有端口,对于用户态的程序,它通过设置IOPL实现了对IO操作的屏蔽。

为了实现在用户态的直接IO操作,用户必须通过编写驱动程序去掉对读写端口的屏蔽。

我们知道WindowsNT实现IO读写保护是有原因的,一方面它使系统异常的稳定,用户再也不必为Windows9x下的蓝屏和异常而苦恼了。

用户可以放心大胆地调试应用程序,即便程序出现死锁,系统也会干脆利落地把它杀死,而不会波及到整个系统。

IO读写保护与Windows98保护8253定时器端口是一样道理,它的目的就是防止用户使用简单的in/out指令,从而把系统搞垮。

但是,对于大量的信号采集的系统而言,应用程序开发人员会更关心系统的实时性,更习惯于在程序中直接使用in/out指令实现信号采集。

因此必须打破WindowsNT环境下的IO瓶颈,使得用户态的应用程序拥有IO读写权限,实现实时控制。

弄清楚如何把IO存取权授权给用户态的应用程序,用户必须了解WindowsNT环境下IO保护是如何实现的。

WindowsNT本身并不能实现IO保护,由于CPU能够捕捉尝试的IO存取,WindowsNT利用了80x86这一特征。

80x86采用了特权级别系统,它总共定义了0、1、2、3四个级别,即我们所说的Ring环。

出于对ALPHA平台的兼容性,80x86仅使用了权限最高的Ring0和最低的ring3,CPU的当前运行权限级(CPL)保存在CS代码段寄存器的两位中。

IO权限并不是由CPU静态定义的。

CPU在处理器的标志寄存器Eflags的某两位定义了当前的IO权限级别(IOPL),通过比较当前的IO权限级和CPU的当前运行权限级,来决定IO指令能否自由使用。

由于当前的IO权限级总是大于等于0,因此运行在Ring0环的内核模式的设备驱动程序,总是可以直接对IO端口进行存取。

而运行在用户态的应用程序,工作在Ring3环,WindowsNT 把当前的IO权限级设置为0,因此,用户态的程序尝试端口存取时,必须经过保护机制。

判断CPL>IOPL,仅仅是保护机制的第一步,I/O保护要么全有,要么全无。

处理器采用了更为灵活的机制,使得操作系统能够根据任务的不同,对端口的任何子集进行授权。

CPU是采用了一个位屏蔽矩阵(IOPM)实现这一步的。

这个矩阵由0,1组成,每一个二进制位对应一个输入输出端口。

这样,65536个端口共需要8192个字节,如果某一二进制位值为0,那么程序对该端口的读写就会不加阻拦。

当然用户不能对一个只读端口进行写操作,只能对端口进行读操作。

位屏蔽矩阵(IOPM)保存在主存的任务状态段结构中,我们可以通过NTOSKRNL库提供的一些内核模式设备驱动例程,实现对该位屏蔽矩阵进行读写,以便对某些端口进行授权。

注意这些服务例程,在DDK帮助文档中并没有说明,并不能保证下个版本是否支持。

我们可以通过VisualStudio提供的ViewDependcy工具打开windows/system32/driver/videoprt.sys,发现它调用了ntoskrnl.exe中的几个未见文档的服务例程。

尽管没有说明,但顾名思义,我们也可以看出这些函数要干什么。

extern"C"{void Ke386SetIoAccessMap(int,NTPORT*);//复制位图影像到NTPORT结构指针中//int:1复制缓冲区,0用0xff填充voidKe386QueryIoAccessMap(int,NTPORT*);//查询当前IOPMvoid Ke386IoSetAccessProcess(PEPROCESS,int);}}//int:1允许I/O,0禁止I/OPsGetCurrentProcess() //获得当前进程设备驱动程序的加载是一个非常麻烦的事情。

对于一个不是硬件的虚拟设备,用户不得不创建一个安装程序,或者编写一个.inf文件,利用控制面板中的添加新硬件功能,加入一个其它设备,或者直接编辑注册编辑表,把驱动程序复制到WINNT系统目录的Drivers32子目录中,有时还需要用户重新启动计算机。

而用户需要的功能仅仅是一次(也许是最后一次)辅助驱动用户的小程序。

正因为这个原因,本程序提供了一个设备驱动程序加载工具,实现设备驱动程序的动态加载,用户不用做任何添加新硬件的操作,也不用编辑注册表和重新启动计算机。

驱动程序不一定位于系统目录中,但要求和程序提供的NTPORT.dll文件位于同一目录。

本程序参考了NumegaDriveStudio提供的loaddrv例子程序。

下面简要介绍一下程序调用的有关API函数。

(1)首先使用OpenSCManager函数与指定服务控制管理器建立联系,打开指定的服务控制管理数据库。

schSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);(2)利用CreateService函数创建一个服务对象,并把它加入到指定的服务控制管理数据库中。

SC_HANDLEschService=CreateService(SchSCManager,DriverName,DriverName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,ServiceExe,NULL,NULL,NULL,NULL,NULL);具体参数请参考MSDN。

(3)用函数StartService启动一个服务,启动前用OpenService打开服务。

BOOL StartService(SC_HANDLE hService,DWORD dwNumServiceArgs,LPCTSTR *lpServiceArgVectors);(4)用CreateFile打开设备,设备名为驱动程序中用IoCreateSymbolicLink服务创建的符号连接名。

如果执行成功,用户就可以利用DeviceIOControl函数接口与驱动程序进行通信了。

例9-1DirectIO实现。

#include<ntddk.h>#define DEVICE_NAME_STRINGL"ZNtPort"#define IOPM_VERSION 110#define IOPM_TEST 00123#define IOPM_TEST 11234#define IOPM_TEST 22345#define IOPMD_TYPE 0xF100#define IOCTL_IOPMD_READ_TESTCTL_CODE (IOPMD_TYPE,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_READ_VERSIONCTL_CODE (IOPMD_TYPE,0x901,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_CLEAR_LIOPMCTL_CODE (IOPMD_TYPE,0x910,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_SET_LIOPMCTL_CODE (IOPMD_TYPE,0x911,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_GET_LIOPMBCTL_CODE (IOPMD_TYPE,0x912,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_GET_LIOPMACTL_CODE (IOPMD_TYPE,0x913,METHOD_BUFFERED,FILE_ANY_ACCESS) //Interact with kernel#define IOCTL_IOPMD_ACTIVATE_KIOPMCTL_CODE (IOPMD_TYPE,0x920,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_DEACTIVATE_KIOPMCTL_CODE (IOPMD_TYPE,0x921,METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_IOPMD_QUERY_KIOPMCTL_CODE (IOPMD_TYPE,0x922,METHOD_BUFFERED,FILE_ANY_ACCESS) #define ZNtPort_PARAMCOUNT 3#define ZNtPort_PARAMCOUNT _BYTESZNtPort_PARAMCOUNT*4#define IOPM_SIZE0x2000typedef UCHARIOPM[IOPM_SIZE];IOPM *IOPM_local=0;Void Ke386SetIoAccessMap(int,IOPM*);Void Ke386QueryIoAccessMap(int,IOPM*);Void Ke386IoSetAccessProcess(PEPROCESS,int);Void disp_ACTIVATE_KIOPM(void){Ke386IoSetAccessProcess(PsGetCurrentProcess(),1); Ke386SetIoAccessMap(1,IOPM_local);}Void disp_DEACTIVATE_KIOPM(void) { Ke386IoSetAccessProcess(PsGetCurrentProcess(),0);}Void disp_QUERY_KIOPM(void) { Ke386QueryIoAccessMap(1,IOPM_local);}Void disp_CLEAR_LIOPM(void){int n;for(n=0;n<IOPM_SIZE;n++)(*IOPM_local)[n]=0xFF;}NTSTATUSZNt Port_Dispatch(INPDEVICE_OBJECTDeviceObject,INPIRPpIrp){int Ix,B;PIO_STACK_LOCATION pIrpStack;NTSTATUS Status;PULONG pIOBuffer;ULONG InBufferSize;ULONG OutBufferSize;ULONG OutByteCount;ULONG IoControlCode;pIrpStack=IoGetCurrentIrpStackLocation(pIrp);Status=STATUS_NOT_IMPLEMENTED;OutByteCount=0;switch(pIrpStack->MajorFunction){case IRP_MJ_CREATE: Status=STATUS_SUCCESS; break;case IRP_MJ_CLOSE: Status=STATUS_SUCCESS; break;case IRP_MJ_DEVICE_CONTROL:InBufferSize=pIrpStack->Parameters.DeviceIoControl.InputBufferLength;OutBufferSize=pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;pIOBuffer=(PULONG)pIrp->AssociatedIrp.SystemBuffer;IoControlCode=pIrpStack->Parameters.DeviceIoControl.IoControlCode;switch(IoControlCode){case IOCTL_IOPMD_READ_TEST: pIOBuffer[0]=IOPM_TEST0;pIOBuffer[1]=IOPM_TEST1;pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_SUCCESS;break;Case IOCTL_IOPMD_READ_VERSION:pIOBuffer[0]=IOPM_VERSION;pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_SUCCESS;break;Case IOCTL_IOPMD_CLEAR_LIOPM: disp_CLEAR_LIOPM();pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES; Status=STATUS_SUCCESS; break;Case IOCTL_IOPMD_SET_LIOPM:Ix=pIOBuffer[0]&0x1FFF;B=pIOBuffer[1]&0xFF;(*IOPM_local)[Ix]=B;disp_ACTIVATE_KIOPM();pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_SUCCESS;break;Case IOCTL_IOPMD_GET_LIOPMB: disp_QUERY_KIOPM();Ix=pIOBuffer[0]&0x1FFF;B=(*IOPM_local)[Ix];pIOBuffer[1]=B&0x000000FF;pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_SUCCESS;break;Case IOCTL_IOPMD_GET_LIOPMA:disp_QUERY_KIOPM();if(OutBufferSize<IOPM_SIZE){ Status=STATUS_INVALID_PARAMETER;}else{ for(Ix=0;Ix<IOPM_SIZE;Ix++) ((PUCHAR)pIOBuffer)[Ix]=(*IOPM_local)[Ix];} OutByteCount=IOPM_SIZE;Status=STATUS_SUCCESS;} break;Case IOCTL_IOPMD_ACTIVATE_KIOPM: disp_ACTIVATE_KIOPM();pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES; Status=STATUS_SUCCESS;break;Case IOCTL_IOPMD_DEACTIVATE_KIOPM: disp_DEACTIVATE_KIOPM();pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_SUCCESS;break;Case IOCTL_IOPMD_QUERY_KIOPM: disp_QUERY_KIOPM();pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_SUCCESS;break;default:pIOBuffer[2]=IoControlCode;OutByteCount=ZNtPort_PARAMCOUNT_BYTES;Status=STATUS_INVALID_DEVICE_REQUEST;break;}break;}pIrp->IoStatus.Status=Status;pIrp->rmation=OutByteCount; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return Status;}VOID ZNtPort_Unload(INPDR IVER_OBJECTDriverObject){ WCHARD OSNameBuffer[]=L"\\DosDevices\\"DEVICE_NAME_STRING;UNICODE_STRING uniDOSString;if(IOPM_local)MmFreeNonCachedMemory(IOPM_local,sizeof(IOPM));RtlInitUnicodeString(&uniDOSString,DOSNameBuffer);IoDeleteSymbolicLink(&uniDOSString);IoDeleteDevice(DriverObject->DeviceObject);}NTSTATUS DriverEntry(INPDRIVER_OBJECT DriverObject,INPUNICODE_STRING RegistryPath){PDEVICE_OBJECTdeviceObject;NTSTATUS status;WCHARNameBuffer[]=L"\\Device\\"DEVICE_NAME_STRING;WCHARDOSNameBuffer[]=L"\\DosDevices\\"DEVICE_NAME_STRING;UNICODE_STRING uniNameString,uniDOSString;Int n; IOPM_local=MmAllocateNonCachedMemory(sizeof(IOPM));if(IOPM_local==0) return STATUS_INSUFFICIENT_RESOURCES;disp_CLEAR_LIOPM();RtlInitUnicodeString(&uniNameString,NameBuffer);RtlInitUnicodeString(&uniDOSString,DOSNameBuffer);status=IoCreateDevice(DriverObject,0,&uniNameString,IOPMD_TYPE,0,FALSE,&deviceObject);if(!NT_SUCCESS(status)) return status;status=IoCreateSymbolicLink(&uniDOSString,&uniNameString);if(!NT_SUCCESS(status)) return status;DriverObject->MajorFunction[IRP_MJ_CREATE]=ZNtPort_Dispatch;DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=ZNtPort_Dispatch;DriverObject->DriverUnload=ZNtPort_Unload; return STATUS_SUCCESS;}为了方便使用,这里把通信代码封装到一个COM组件中,提供了简单的接口。

相关文档
最新文档