------------------------------------------------------------------------------------------------------------------------------
以下是文档
设计说明书
1.引言
1.1编写目的
分析系统要实现的功能,所需要的输入输出项目,为系统的实现做宏观的设计;
1.2背景
a. 系统监控与管理
b. Designer: //设计者 Developer: //开发者 User: SCIENCE //使用者:1.3定义
[列出本文件中用到的专门术语的定义和外文首字母组词的原词组。]
1.4参考资料
[列出有关的参考资料。]
2.总体设计
2.1需求规定
[说明对本系统的主要的输入输出项目、处理的功能性能要求。包括]
2.1.1系统功能
1、服务监控中心(服务端)
(1)服务登记、服务状态的监视
(2)将服务的状态写入数据库,并且提供客户端的查询请求;
(3)服务实时状态信息的监视、查询,向客户端提供实时监视信息;
(4)管理和控制服务;
(5)向告警中心发送告警信息;
2、系统资源监视器(服务端)
(1)硬件系统资源监视;
(2)与日志服务进行实时交互;
(3)接收并向客户端(或者发短信给技术人员)展示告警信息;
3、告警中心(服务端)
(1)接收监控中心发送的告警信息,同时向客户端(或者技术人员发送短信);
(2)将告警信息写入数据库;
(3)告警自动解除;
4、信息查询(客户端)
(1)系统硬件资源的查询;
(2)系统硬件资源历史查询;
(3)各个服务状态的查询;
(4)系统业务状态的查询;
(5)系统业务状态历史查询;
2.1.2系统性能
1、精度
提供能准确反应系统、服务的状态以及运行状况的数据;
2、时间特性要求
实时地监控系统、服务的运行状态,并且即使反馈到客户端;
客户端发出的对系统、服务的调度请求要即可响应;
3、可靠性
4、灵活性
2.1.3输入输出要求
2.1.4数据管理能力要求
2.1.5故障处理要求
2.1.6其他专门要求
2.2运行环境
1、 主要运行于Windows 2000系统;
2、 需要考虑移植到Linux、Unix系统,所以在编码过程中少用C++Builder的组件;
2.2.1设备
[列出运行该软件所需要的硬设备。说明其中的新型设备及其专门功能。]
2.2.2支持软件
[列出支持软件,包括要用到的操作系统、编译(或汇编)程序、测试支持软件等。]
2.2.3接口
[说明该系统同其他系统之间的接口、数据通信协议等]
2.2.4控制
[说明控制该系统的运行的方法和控制信号,并说明这些控制信号的来源。]
2.3基本设计概念和处理流程
[说明本系统的基本设计概念和处理流程,尽量使用图表的形式。]
2.4结构
[给出系统结构总体框图(包括软件、硬件结构框图),说明本系统的各模块的划分,扼要说明每个系统模块的标识符和功能,分层次地给出各模块之间的控制与被控制关系。]
2.5功能需求与系统模块的关系
[本条用一张矩阵图说明各项功能需求的实现同各模块的分配关系。]
| [系统模块1] | [系统模块2] | [……] | [系统模块m] |
[功能需求1] | √ |
|
|
|
[功能需求2] |
| √ |
|
|
[┇] |
|
|
|
|
[功能需求n] |
| √ |
| √ |
2.6人工处理过程
[说明在本系统的工作过程中不得不包含的人工处理过程。]
2.7尚未解决的问题
[说明在概要设计过程中尚未解决而设计者认为在系统完成之前必须解决的各个问题。]
3.接口设计
3.1用户接口
[说明将向用户提供的命令和它们的语法结构,以及相应的回答信息。]
[说明提供给用户操作的硬件控制面板的定义。]
3.2外部接口
[说明本系统同外界的所有接口的安排包括软件与硬件之间的接口、本系统与各支持系统之间的接口关系。]
3.3内部接口
[说明本系统之内的各个系统元素之间的接口的安排。]
4.运行设计
4.1运行模块组合
[说明对系统施加不同的外界运行控制时所引起的各种不同的运行模块组合,说明每种运行所历经的内部模块的支持软件。]
4.2运行控制
[说明每一种外界的运行控制的方式方法和操作步骤。]
4.3运行时间
[说明每种运行模块组合将占用各种资源的时间。]
5.系统数据结构设计
[不涉及软件设计可不包含]
5.1逻辑结构设计要点
[给出本系统内软件所使用的每个数据结构的名称、标识符以及它们之中每个数据项、记录、文卷和系的标识、定义、长度及它们之间的层次的或表格的相互关系。]
5.2物理结构设计要点
[给出本系统内软件所使用的每个数据结构中的每个数据项的存储要求,访问方法、存取单位、存取的物理关系、设计考虑和保密条件。]
5.3数据结构与程序的关系
[说明各个数据结构与访问这些数据结构的各个程序之间的对应关系。]
| [程序1] | [程序2] | [……] | [程序m] |
[数据结构1] | √ |
|
|
|
[数据结构2] | √ | √ |
|
|
┇ |
|
|
|
|
[数据结构n] |
| √ |
| √ |
6.系统出错处理设计
6.1出错信息
[用一览表的方式说明每种可能的出错或故障情况出现时,系统输出信息的形式、含意及处理方法。]
6.2补救措施
[说明故障出现后可能采取的变通措施。包括:]
a.后备技术 [说明准备采用的后备技术,当原始系统数据万一丢失时启用的副本的建立和启动的技术,例如周期性地把磁盘信息记录到磁带上去就是对于磁盘媒体的一种后备技术。]
b.降效技术 [说明准备采用的后备技术,使用另一个效率稍低的系统或方法来求得所需结果的某些部分,例如一个自动系统的降效技术可以是手工操作和数据的人工记录。]
c.恢复及再启动技术 [说明将使用的恢复再启动技术,使软件从故障点恢复执行或使软件从头开始重新运行的方法。]
6.3系统维护设计
[说明为了系统维护的方便而在程序内部设计中作出的安排,包括在程序中专门安排用于系统的检查与维护的检测点和专用模块。]
数据库设计说明书
1.引言
1.1编写目的
1、 为系统的实现提供后台数据库实施方案; DBMS
2、 为系统代码的编写过程中的数据需求提供支持和参考; CODING STAFF
1.2背景
a.[待开发数据库的名称和使用此数据库的软件系统的名称;]
b.[列出本项目的任务提出者、开发者、用户。]
1.3定义
[列出本文件中用到的专门术语的定义和外文首字母组词的原词组。]
1.4参考资料
[列出有关的参考资料。]
2.外部设计
1.1标识符的状态
[联系用途,详细说明用于唯一地标识该数据库的代码、名称或标识符,附加的描述性信息亦要给出。如果该数据库属于尚在实验中、尚在测试中或是暂时使用的,则要说明这一特点及其有效时间范围。]
2.2使用它的程序
[列出将要使用或访问此数据库的所有应用程序,对于这些应用程序的每一个,给出它的名称和版本号。]
2.3约定
[陈述一个程序员或一个系统分析员为了能使用此数据库而需要了解的建立标号、标识的约定。]
2.4专门指导
[向准备从事此数据库的生成、从事此数据库的测试、维护人员提供专门的指导。]
2.5支持软件
[简单介绍同此数据库直接有关的支持软件。说明这些软件的名称、版本号的主要功能特性。列出这些支持软件的技术文件的标题、编号及来源]
3.结构设计
3.1概念结构设计
[说明本数据库将反映的现实世界中的实体、属性和它们之间的关系等的原始数据形式,包括各数据项、记录、系、文卷的标识符、定义、类型、度量单位和值域,建立本数据库的每一幅用户视图。]
3.2逻辑结构设计
[说明把上述原始数据进行分解、合并后重新组织起来的数据库全局逻辑结构。]
3.3物理结构设计
[建立系统程序员视图。]
4.运用设计
4.1数据字典设计
[对数据库设计中涉及到的各种项目一般要建立起数据字典,以说明它们的标识符、同义名及有关信息。]
4.2安全保密设计
[说明在数据库的设计中,将如何通过区分不同的访问者、不同的访问类型和不同的数据对象,进行分别对待而获得的数据库安全保密的设计考虑。]
CD-BCS监控服务API函数说明
1. PRC_GetTelnetInfo();
目的:获取业务服务器Telnet 端口输出信息
实现:获取Socket端口的输出信息,以NMS 消息参数的形式发送到前台
备注:
客户端发起该请求后,只要不主动断开该次请求,输出参数就要不断地发送给客户端
2. GetCPUInfo(),用来获取系统当前CPU利用率
目的:获取系统当前CPU利用率
实现:,调用NtQuerySystemInformation()函数来获取当前CPU时间,计算获取CPU利用率;这部分实现在程序中已经添加了明确的注释,不再赘述,
如果还有疑问,可参考MSDN;
3. GetMemoryInfo(TBCSMemoryInfo &memInfo)获取系统当前内存信息
目的:获取当前系统的内存(物理内存和虚拟内存)的信息,如果需要内存利用率,可以计算得到
实现:调用了GlobalMemoryStatus(&memory)函数获取系统当前内存信息,
返回:结构TBCSMemoryInfo在Unit3.h中定义
如果还有疑问,可参考MSDN;
4. GetDiskInfo(TBCSDiskInfo *diskInfo)获取本机磁盘信息
目的:获取本机磁盘信息(逻辑盘名称、总容量、已用空间、未用空间),如果需要磁盘利用率,可计算得到;
实现:
1) 调用GetProcAddress()装入动态连接库并返回输出函数地址
2) 调用GetLogicalDriveStrings()函数获取逻辑盘名称
3) 调用pGetDiskFreeSpaceEx()函数获取指定逻辑盘空间信息
如果还有疑问,可参考MSDN;
5. GetServiceList(TBCSServiceList *&serviceList)获取本机服务列表
目的:列举指定服务器(这里指本机)系统服务列表,返回服务数
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指本机;返回管理数据库句柄。
2) 调用EnumServicesStatusEx()函数枚举服务列表,并取得服务基本信息;
3) 调用schService()函数获取指定服务句柄;
4) 调用QueryServiceConfig2()获取,指定服务的描述信息;
具体实现参考代码,如还有疑问,可参考MSDN;
6. GetServiceProperty(TBCSServiceProperty &serviceProperty,String ServiceName)获取指定服务的各项属性
目的:获取指定服务的各项信息
实现:代码中每一步都有详细注释,不再赘述;
7. GetProcessList(TBCSProcessInfo &processInfo,int processID)获取进程列表
目的:获取指定进程的
实现:
1) 调用GetProcAddress()函数定义一个函数NtQuerySystemInformation();来调用 ntdll.dll 库中NtQuerySystemInformation()函数;
2) 调用自定义函数NtQuerySystemInformation()获取进程信息,返回结构数组;
3) 枚举进程列表(包括进程简要消息);
欲获取更多关于进程信息,参考获取进程列表实例GetprocessList见附件;
8. GetNetInfo(TBCSNetInfo &NetInfo)获取网络信息
目的:获取本机的网络信息
(模拟在DOS提示符下输入:netstat -a -n显示的网络信息)
实现:
参考:《监测网络流量》和《网络信息实例API.txt》及代码中的注释
9. InstallService(String serviceName,String displayName,String path)安装服务
目的:实现服务安装
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指向本机服务管理数据库;访问方式为SC_MANAGER_CREATE_SERVICE;返回管理数据库句柄。
2) 调用CreateService()函数创建服务,并添加到服务管理数据库;
10. UNInstallService(String serviceName)卸载服务
目的:实现服务卸载
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指向本机服务管理数据库;访问方式为SC_MANAGER_CREATE_SERVICE;返回管理数据库句柄。
2) 调用OpenService()函数获取该服务句柄;
3) 调用ControlService()服务卸载该服务;
11. StartUpService(String serviceName)启动服务
目的:实现服务启动
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指向本机服务管理数据库;访问方式为SC_MANAGER_CREATE_SERVICE;返回管理数据库句柄。
2) 调用OpenService()函数获取该服务句柄;
3) 调用QueryServiceStatus()函数获取该服务状态;
4) 调用StartService()函数启动该服务;
12. StopService(String serviceName)停止服务
目的:实现服务停止
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指向本机服务管理数据库;访问方式为SC_MANAGER_CREATE_SERVICE;返回管理数据库句柄。
2) 调用OpenService()函数获取该服务句柄;
3) 调用QueryServiceStatus()函数获取该服务状态;
4) 调用StartService()函数停止该服务;
13. PauseService(String serviceName)暂停服务
目的:实现服务暂停
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指向本机服务管理数据库;访问方式为SC_MANAGER_CREATE_SERVICE;返回管理数据库句柄。
2) 调用OpenService()函数获取该服务句柄;
3) 调用QueryServiceStatus()函数获取该服务状态;
4) 调用StartService()函数暂停该服务;
14. ContinueService(String serviceName)恢复服务
目的:将服务恢复为启动状态
实现:
1) 调用OpenSCManager()函数,建立连接到指定机器服务管理数据库,pServer 为NULL时或者pServer指向空字符串时,指向本机服务管理数据库;访问方式为SC_MANAGER_CREATE_SERVICE;返回管理数据库句柄。
2) 调用OpenService()函数获取该服务句柄;
3) 调用QueryServiceStatus()函数获取该服务状态;
4) 调用StartService()函数恢复该服务为启动状态;
15. ClosePeocess(int processID)终止进程
目的:终止指定进程
实现:
调用OpenProcess()函数获取指定进程句柄;调用TerminateProcess()函数强行结束该进程;
16. RestartServer()重启服务器
目的:重启服务器
实现:
要用到“user32.dll”库。首先调用OpenProcessToken()函数得到当前进程Token,然后调用LookupPrivilegeValue()函数提升权限,使其拥有shutdown权限。函数AdjustTokenPrivileges()时shutdowm可用。最后调用ExitWindowsEx()函数重启系统。
TsockInfo类的声明及定义:
17. 获取socket资源使用信息
参考:《关联进程与端口》及代码中的注释
系统监控与管理
一、 分类
网络资源:包括socket资源的监视、释放、管理,网络流量的监视、管理
基础资源:包括硬盘、内存、操作系统的监视、管理,系统进程管理
应用:应用系统的运行状态监视、管理
二、 实现
网络资源与基础资源的实现已经有一个雏形,按照原有的方法继续完善,同时需要兼顾目前的系统结构.
应用的监控与管理:在现有的系统结构中添加监控中心、监视器、告警器,并对现有的服务进行适应性修改
监控中心需要完成的功能包括:其他服务的状态监视,与数据库交互进行数据的记录、历史记录的查询,实时数据的查询,系统实时资源管理。监控中心根据实际需要,可以配置一个或者多个。
监视器需要完成的功能包括:本硬件系统资源进行监视,与日志服务进行交互进行实时数据记录。监视器位于系统所有硬件节点上,至少每个节点一个
告警器需要完成的功能包括:对监控中心发送的告警信息进行报警,告警信息登记,告警信息解除。可以采用不同的告警方式,如:软件、短信等。告警器根据实际需要,可以配置一个或者多个。
其他适应性修改:keepalive消息发送。
前台必须实现的功能:系统网络资源、基础资源的实时监视与调度,历史记录查询,具体应用的实时状态监视与调度。
三、 环境
开发、测试环境:
Windows2000 server + Oracle8.1.7 and Oracle 9.0 and Sybase11.5+ Bcb6.0+XML4.0
但必须考虑系统移植到unix的可能:尽量少用BCB、Vcl特有的控件以及类,尽可能的多用标准C++。
四、 消息定义
4.1 监控中心需要处理的消息
l 服务登记:其他服务向监控中心进行注册并发送初始信息,供监控中心以后使用
l 系统业务应用消息:其他BCSS服务处理的消息,在发送给边界网关的同时,发送给监控服务一份,由监控服务进行统计,并对错误信息进行实时的监视,与其他消息的区别用ModelID
l 链路监测消息:其他BCSS服务向监控中心发送的链路维持以及keepalive消息,目的在于:由监控中心随时检测各个业务服务的状态
l 系统业务状态查询:由前台发起,查询当前系统各部分、各个服务的运行状态,监控前台可以设置由后台定时返回当前系统各部分运行状态,如果需要的是实时信息,需要直接发送给监视器,由监视器直接返回,否则从数据库中读取最近的信息
l 告警信息查询:由前台发起,查询给定时间范围内的告警信息
l 系统资源查询:由前台发起,查询当前系统各节点的资源状况,监控前台可以设置由后台定时返回各节点的资源状况,如果需要的是实时信息,需要直接发送给监视器,由监视器直接返回,否则从数据库中读取最近的信息
l 历史纪录查询:由前台发起,查询给定时间范围内系统的业务状态、系统资源状况纪录
l 告警信息登记:由监控中心发起,向告警器发送告警信息
l 告警信息解除:由监控中心发起,向告警器发送告警解除信息
l 系统资源调度:由前台根据系统资源查询的返回信息发起,进行:停止某个服务,重启某台机器,修改某些系统参数等操作,该操作在具体实现的同时,还必须首先记录进数据库。
4.2监视器需要处理的消息
监视器负责采集本地的资源状况,与日志服务进行交互以记录实时状态,需要发送的消息也就是给日志服务发送的写数据库的消息;监控中心需要的实时信息,包括实时资源(网络、硬件等)信息
4.3告警器需要处理的消息
l 告警信息登记:由监控中心发起,向告警器发送告警信息
l 告警信息解除:由监控中心发起,向告警器发送告警解除信息
五、 数据库需要新增的表以及存储过程
5.1 表结构
l 系统节点概要信息表:描述系统各节点的概要信息,如:CPU、内存、硬盘、操作系统
l 系统结构信息表:描述系统软件组成的概要信息,如:服务编号、监听端口、监听地址、调试端口、调试地址、服务说明等
l 系统业务状态表:存储系统当天的业务状态信息,如:服务编号、处理的业务次数、成功次数、失败次数、当前处理的业务信息、当前的失败信息、时间、收到以及发送的字节数等
l 系统业务状态历史表:存储系统业务状态历史信息
l 系统资源状态表:存储系统当天各节点的资源状态信息,如:ip地址、时间、内存信息、硬盘信息、SOCKET连接数等,其中内存信息包括:可用内存、虚拟内存等,硬盘包括:逻辑盘数量,磁盘容量,可用磁盘容量等
l 系统网络状态表:描述当前各节点网络连接数以及各连接信息表,如:时间、本地ip、对端ip、本地端口、对端端口、连接状态等
l 系统资源状态历史表
l 系统网络状态历史表
l 告警信息表:存储需要告警的信息及其状态,包括:类型、告警信息、发送状态、是否解除等
l 系统调度历史记录表:存储系统调度操作历史记录
5.2 存储过程
l 系统业务扫描:用于扫描系统数据库中的告警信息,如果各个表中(包括各业务处理表),存在需要告警的信息,则返回告警信息数量以及告警信息,向告警服务发送警告信息,如果没有则返回0,如果监控中心调用该过程失败,则缩小时间间隔重复调用,连续3次失败,则认为数据库故障
l 其他存储过程主要包括:查询业务状态、资源状态、业务历史、资源历史、系统调度操作记录等
六、 程序结构说明及注意事项
采取类似于以前的服务结构,但监控中心的不同之处在于,需要维护一个所有BCSS对应状态描述的数组,该数组为一个结构数组或者对象数组,一个该结构或对象描述对应的一个BCSS,需要描述的状态变量包括:
服务状态(由KeepAlive消息维护),业务信息(包括业务次数、成功次数、失败次数、连续失败次数、当前提示信息、当前失败信息、发送字节数、收到字节数等)
该对象每天营业前将前一天的累积数据写入数据库,然后清空,断开所有连接,由BCSS重新维护该连接;监控中心需要与数据库建立一个连接,作为服务端需要与所有的监视器建立连接,需要与告警器建立一个连接,需要与所有的BCSS建立连接
监视器作为客户端需要与日志服务建立一个连接,需要与监控中心建立一个连接
告警器作为客户端视告警方式的不同适当建立数据库连接,并需要与监控中心建立连接
------------------------------------------------------------------------------------------------------------------------------
//project.cpp
#include <SysUtils.hpp>
#include <SvcMgr.hpp>
#pragma hdrstop
#define Application Svcmgr::Application
USEFORM("Unit1.cpp", BCSInfoCollect); /* TService: File Type */
USEFORM("Unit2.cpp", DM); /* TDataModule: File Type */
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Title = "BCSInfoCollect";
Application->CreateForm(__classid(TBCSInfoCollect), &BCSInfoCollect);
Application->CreateForm(__classid(TDM), &DM);
Application->Run();
}
catch (Exception &exception)
{
Sysutils::ShowException(&exception, System::ExceptAddr());
}
catch(...)
{
try
{
throw Exception("");
}
catch(Exception &exception)
{
Sysutils::ShowException(&exception, System::ExceptAddr());
}
}
return 0;
}
-----------------------------------------------------------------------------------------------------------------------
//Unit1.cpp
//---------------------------------------------------------------------------
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TTelnetConsole *console=NULL;
TNMSInterfaceForServer NMSServer;
TBCSInfoCollect *BCSInfoCollect;
//---------------------------------------------------------------------------
__fastcall TBCSInfoCollect::TBCSInfoCollect(TComponent* Owner)
: TService(Owner)
{
}
TServiceController __fastcall TBCSInfoCollect::GetServiceController(void)
{
return (TServiceController) ServiceController;
}
void __stdcall ServiceController(unsigned CtrlCode)
{
BCSInfoCollect->Controller(CtrlCode);
}
//---------------------------------------------------------------------------
void __fastcall TBCSInfoCollect::ServiceExecute(TService *Sender)
{
TRegIniFile *pini=new TRegIniFile("NICESOFT//BCS//ServerGuardian");
INT ExecuteContinueFlag =0;
while(!Terminated)
{
try
{
if (ExecuteContinueFlag>20 && pini)
{
pini->WriteInteger(Name,"ActiveFlag",10);
ExecuteContinueFlag=0;
}
ExecuteContinueFlag++;
}
catch(...)
{
}
Sleep(50);
ServiceThread->ProcessRequests(false);
NMSServer.Execute();
}
}
void TBCSInfoCollect::DebugInfo(String info)
{
console->Print(info+"/r/n");
Log2("801::"+info,"bcs.log");
}
//---------------------------------------------------------------------------
void __fastcall TBCSInfoCollect::ServiceStart(TService *Sender, bool &Started)
{
BTRY
int port=10006,srvid=801;
CoInitialize(NULL);
if (NMSServer.Flag()<NMS_INTERFACE_IDLE) //判断服务状态
{
LTRY
NMSServer.OnCommEvent =OnServerAccept;
port=GlobalInfo.RegIni->ReadInteger(APP,"监听端口",10006); //从注册表取值
srvid=GlobalInfo.RegIni->ReadInteger(APP,"服务编号",801);
LTRY
for(int i=0;i<MAX_ACTIVE_CONNECTION;i++) //MAX_ACTIVE_CONNECTION pFTag 61.135.129.15
{
// NMSServer.FClient[i].SetAutoCompress(true);
LTRY
NMSServer.FClient[i].OnGetNMS=OnGetServerClient1Message; //server receive NMS后响应事件
NMSServer.FClient[i].OnCommEvent =OnClientEvent;
LTRY
}
NMSServer.ServiceID(srvid);
try
{
NMSServer.SetAddress("",(WORD)port); //设置连接
DebugInfo("prepare start"+String(port));
LTRY
NMSServer.Initialize();
Started=true; //初始化服务
DebugInfo("服务启动");
}
catch(Exception &E)
{
Started=false;
DebugInfo("服务启动失败:"+E.Message);
}
}
else
{
NMSServer.Final();
Started=false;
}
ETRY
}
//---------------------------------------------------------------------------
void TBCSInfoCollect::OnServerAccept(TNMSInterfaceForPerConnecttion * sendder,TNMSCommEventCode EventCode)
{
try
{
if(EventCode==ceAccept)
{
}
else if(EventCode== ceDisconnect)
{
}
}
catch(...)
{}
}
void TBCSInfoCollect::OnClientEvent(TNMSInterfaceForPerConnecttion * Sender,TNMSCommEventCode EventCode)
{
try
{
if(EventCode==ceDisconnect)
{
}
else
{
}
}
catch(...)
{}
}
void TBCSInfoCollect::OnGetServerClient1Message(TNMSInterfaceForPerConnecttion * sender,TNetMessage &nms)
{
try
{
DebugInfo("From:"+sender->GetRemoteAddress()+" Receive NMS ID:"+String(nms.MessageID));
// if(sender->pFTag!=NULL)
{
DM->ExecuteNMS(nms,*sender);
}
}
catch(...){}
}
void __fastcall TBCSInfoCollect::ServiceStop(TService *Sender,
bool &Stopped)
{
CoUninitialize();
}
//---------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------
//Unit2.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit1.h"
#include "Unit3.h"
#define __SERVICE_USED__
extern TTelnetConsole *console;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#include <inifiles.hpp>
TDM *DM;
extern TGetInfo *GetSerInfo;
TBCSDiskInfo serviceList;
//---------------------------------------------------------------------------
__fastcall TDM::TDM(TComponent* Owner)
: TDataModule(Owner)
{
}
//---------------------------------------------------------------------------
int TDM::ExecuteNMS(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
try
{
ReceiveNMS.MessageType=(ReceiveNMS.MessageType&0xfff9)|0x4;
switch (ReceiveNMS.MessageID)
{
case NMS_LOGIN:
PRC_Login(ReceiveNMS,Sender);
break;
case NMS_GETINITIALINFO:
PRC_Initialize(ReceiveNMS,Sender);
break;
case NMS_GETTELNETINFO:
PRC_GetTelnetInfo(ReceiveNMS,Sender);
break;
case NMS_INITIALINFO:
PRC_Initialize((ReceiveNMS,Sender);
break;
case NMS_GETSERVICELIST:
PRC_GetServiceList(ReceiveNMS,Sender);
break;
case NMS_GETSYSTEMINFO:
PRC_GetSystemInfo(ReceiveNMS,Sender);
break;
case NMS_GETPROCESSINFO:
PRC_GetProcessInfo(ReceiveNMS,Sender);
break;
case NMS_GETNETINFO:
PRC_GetNetInfo(ReceiveNMS,Sender);
break;
case NMS_SERVICECONTROLINFO:
PRC_ServiceCtrl(ReceiveNMS,Sender);
break;
case NMS_OPERATE:
PRC_Operate(ReceiveNMS,Sender);
break;
default:
break;
}
return 0;
}
catch (Exception &E)
{
int err_code=9999;
String err_msg=E.Message;
TVariable tmpjgj(PARA_RESULT_CODE);
tmpjgj=err_code;
ReceiveNMS.Parameters<<tmpjgj;
tmpjgj.ResetAs(PARA_RESULT_MSG);
if (err_msg=="") err_msg="未定义的异常信息!";
tmpjgj=err_msg;
ReceiveNMS.Parameters<<tmpjgj;
Sender<<ReceiveNMS;
return 1;
}
}
void TDM::PRC_Login(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
try
{
int ret_code=0;
String ret_msg="";
TVariable tmpvar;
ReceiveNMS.MessageID=1000;
ReceiveNMS.ModelID=1020;
String gh=ReceiveNMS.Parameters[PARA_STAFF_ID].AsString();
if (gh.Trim()!="")
{
int retcode=0;
if (retcode==0)
{
ret_code=0;
ReceiveNMS.MessageID=1000;
ret_msg=String("您好,")+gh+",欢迎进入BCS服务管理与监控系统./n登录时间:"+TDateTime::CurrentDateTime().FormatString("YYYY/MM/DD hh:nn:ss");
}
else
{
ret_code=100;
ret_msg="登录失败";
}
}
else
{
ret_code=1001;
ret_msg="请在下面输入工号再登录";
}
tmpvar.ResetAs(PARA_RESULT_CODE);
tmpvar=ret_code;
ReceiveNMS.Parameters<<tmpvar;
if (ret_msg.Length())
{
tmpvar.ResetAs(PARA_RESULT_MSG);
tmpvar=ret_msg;
ReceiveNMS.Parameters<<tmpvar;
}
Sender<<ReceiveNMS;
}
catch(Exception &E)
{
int err_code=9999;
String err_msg=E.Message;
TVariable tmpvar(PARA_RESULT_CODE);
tmpvar=err_code;
ReceiveNMS.Parameters<<tmpvar;
tmpvar.ResetAs(PARA_RESULT_MSG);
if (err_msg=="") err_msg="未定义的异常信息!";
tmpvar=err_msg;
ReceiveNMS.Parameters<<tmpvar;
Sender<<ReceiveNMS;
}
void TDM::PRC_Initialize(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
}
void TDM::PRC_GetTelnetInfo(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
TVariable tmpvar;
// String status=ReceiveNMS.Parameters[PARA_LINKSTATE_IN].AsString();
String ServerIP=ReceiveNMS.Parameters[PARA_DESTADDR_IN].AsString();
int ServerPort=ReceiveNMS.Parameters[PARA_DESTPORT_IN].AsInteger();
ClientSocket1->Address=ServerIP;
ClientSocket1->Port=ServerPort;
// for (int i=0;i<2;i++)
// {
if (!ClientSocket1->Active)
{
ClientSocket1->Active=true;
}
if (ClientSocket1->Socket->ReceiveLength() )
{
String TelnetInfo=ClientSocket1->Socket->ReceiveText();
tmpvar.ResetAs(PARA_GETTELNET_INFO);
tmpvar=TelnetInfo;
ReceiveNMS.Parameters<<tmpvar;
}
Sender<<ReceiveNMS;
//可进行判断,如果前台未传回"stop"信息,则将i--,继续循环
}
}
//---------------------------------------------------------------------------
void TDM::PRC_GetSystemInfo(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
}
//---------------------------------------------------------------------------
void TDM::PRC_GetServiceList(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
}
//---------------------------------------------------------------------------
void TDM::PRC_GetProcessInfo(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
}
//---------------------------------------------------------------------------
void TDM::PRC_GetNetInfo(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
}
//---------------------------------------------------------------------------
void TDM::PRC_ServiceCtrl(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
String ServiceName=ReceiveNMS.Parameters[SERVICE_PARA_NAME].AsString();
int Ctrl=ReceiveNMS.Parameters[SERVICE_PARA_CTRL].AsInteger();
switch (Ctrl)
{
case SERVICE_START
Contrl.StartServiceA(ServiceName);
break;
case SERVICE_STOP
Contrl.ContrlService(str,SERVICE_CONTROL_STOP);
break;
case SERVICE_PAUSE
Contrl.ContrlService(str,SERVICE_CONTROL_PAUSE);
break;
case SERVICE_CONTINUE
Contrl.ContrlService(str,SERVICE_CONTROL_CONTINUE);
break;
default:
break;
}
//---------------------------------------------------------------------------
void TDM::PRC_Operate(TNetMessage & ReceiveNMS,TNMSInterfaceForPerConnecttion & Sender)
{
}
-----------------------------------------------------------------------------------------------------------------------------
//Unit3.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit3.h"
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include "Ipexport.h" //NETINFO 所需头文件 ,IP输出
#include "Iptypes.h" //IP类型
#include "Iphlpapi.h" //IP帮助
//---------------------------------------------------------------------------
#pragma package(smart_init)
TGetInfo::TGetInfo()
{
}
TGetInfo::~TGetInfo()
{
}
//---------------------------------------------------------------------------
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;
typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;
typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
PROCNTQSI NtQuerySystemInformation;
//系统cpu利用率
double TGetInfo::GetCPUInfo()
{
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;
static LARGE_INTEGER liOldIdleTime = {0,0};
static LARGE_INTEGER liOldSystemTime = {0,0};
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);
if (!NtQuerySystemInformation)
return S_FALSE;
// 得到系统中处理器数
status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
return S_FALSE;
// 得到新的系统时间
status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return S_FALSE;
// 得到新的CPU空闲时间
status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return S_FALSE;
// 如果第一次调用跳过
if (liOldIdleTime.QuadPart != 0)
{
// 当前值 = 最新值 - 旧值
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
// 当前CPU空闲时间 = 空闲时间 / 系统时间
dbIdleTime = dbIdleTime / dbSystemTime;
// 当前CPU利用率% = 100 - (当前CPU空闲时间 * 100) / 处理器数
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;
}
// 存储新的CPU空闲及系统时间
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;
return dbIdleTime;
}
void TGetInfo::GetMemoryInfo(TBCSMemoryInfo &memInfo)
{
MEMORYSTATUS memory;
memory.dwLength =sizeof(memory); //初始化
GlobalMemoryStatus(&memory);
memInfo.MemTotalPhys = memory.dwTotalPhys/1024/1024;
memInfo.MemAvailPhys = memory.dwAvailPhys/1024;
memInfo.MemTotalVirtual =memory.dwTotalVirtual/1024/1024;
memInfo.MemAvailVirtual= memory.dwAvailVirtual/1024;
}
int TGetInfo::GetDiskInfo(TBCSDiskInfo *diskInfo)
{
int Count=0;
typedef BOOL (WINAPI *PGETDISKFREESPACEEX)(LPCSTR,PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
PGETDISKFREESPACEEX pGetDiskFreeSpaceEx ;
__int64 i64FreeBytesToCaller,i64TotalTypes,i64FreeBytes;
pGetDiskFreeSpaceEx=(PGETDISKFREESPACEEX)GetProcAddress(GetModuleHandle("kernel32.dll"),
"GetDiskFreeSpaceEx");
if (pGetDiskFreeSpaceEx)
{
char str[100];
int n=GetLogicalDriveStrings(100,str);
for (int i=0;i<n/4;i++)
{
String disk=String(str+i*4).SubString(1,2).c_str();
pGetDiskFreeSpaceEx (disk.c_str(),
(PULARGE_INTEGER)&i64FreeBytesToCaller,
(PULARGE_INTEGER)&i64TotalTypes,
(PULARGE_INTEGER)&i64FreeBytes);
diskInfo=diskInfo+i;
diskInfo[i]->DISKSIZE=i64TotalTypes ;
diskInfo[i]->DISKFREESPACE=i64FreeBytes;
Count++;
}
}
return Count;
}
//获取服务列表
void TGetInfo::GetServiceList(TBCSServiceList *serviceList)
{
SC_HANDLE hSC;
char *pServer=NULL;
ENUM_SERVICE_STATUS_PROCESS scstat[100];
DWORD BytesNeed=0,ServiceReturned=0,ResumeHandle=0,ret,i=0;
char *stat[]={"","Stop","Starting","Stopping","Running","Continue pending","Pause pending","Pause"};
hSC=OpenSCManager(pServer,SERVICES_ACTIVE_DATABASE,SC_MANAGER_CONNECT|SC_MANAGER_ENUMERATE_SERVICE);
do //开始枚举服务
{
ret=EnumServicesStatusEx(hSC,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,
(LPBYTE)scstat,
sizeof(scstat),
&BytesNeed,
&ServiceReturned,
&ResumeHandle, //注意这个参数,第一次调用这个函数时应该为0
NULL);
for(int i=0;i<ServiceReturned;i++)
{
TBCSServiceList *p = serviceList+i;
p->ProcessID=scstat[i].ServiceStatusProcess.dwProcessId;
p->ServiceType=scstat[i].ServiceStatusProcess.dwServiceType;
serviceList.ServiceWin32ExitCode=scstat[i].ServiceStatusProcess.dwWin32ExitCode;
strcpy(p->ServiceStatus,stat[scstat[i].ServiceStatusProcess.dwCurrentState]);
strcpy(p->ServiceName,scstat[i].lpServiceName);
strcpy(p->DisplayName,scstat[i].lpDisplayName);
}
}while((ret==0)&&(GetLastError()==ERROR_MORE_DATA));//ERROR_MORE_DATA表示缓存不够大,还有未枚举的服务,这时应该继续
}
//获取进程信息
void TGetInfo::GetProcessInfo(TBCSProcessInfo &processInfo,int processID)
{
PVOID pProcInfo = NULL;
DWORD dwInfoSize = 0x20000;
PPROCESSINFO pProcessInfo;
DWORD dwWorkingSet;
long ( __stdcall *NtQuerySystemInformation )( DWORD, PVOID, DWORD, DWORD );
static __int64 LastTotalProcessCPUUsage = 0;
static __int64 LastCurrentProcessCPUUsage = 0;
int CurrentDelta;
int TotalDelta;
__int64 TotalProcessCPUUsage = 0;
__int64 CurrentProcessCPUUsage = 0;
pProcInfo = (PVOID)(new byte[dwInfoSize]);
NtQuerySystemInformation = (long(__stdcall*)(DWORD,PVOID,DWORD,DWORD))
GetProcAddress( GetModuleHandle( "ntdll.dll" ),"NtQuerySystemInformation" );
NtQuerySystemInformation(5,pProcInfo,dwInfoSize,0);
pProcessInfo = (PPROCESSINFO)pProcInfo;
do
{
TotalProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
if(pProcessInfo->dwProcessID ==processID) // GetCurrentProcessId()取当前进程id
{
dwWorkingSet = pProcessInfo->dwWorkingSet;
CurrentProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
strcpy(processInfo.ProcessName,String(pProcessInfo->ProcessName.Buffer).c_str());
}
if(pProcessInfo->dwOffset == 0)
{
break;
}
pProcessInfo = (PPROCESSINFO)((byte*)pProcessInfo + pProcessInfo->dwOffset);
}
while(true);
TotalDelta = TotalProcessCPUUsage - LastTotalProcessCPUUsage;
CurrentDelta = CurrentProcessCPUUsage - LastCurrentProcessCPUUsage;
if(TotalDelta != 0)
{
processInfo.ProcessID = pProcessInfo->dwProcessID;
// strcpy(processInfo.ProcessName,String(pProcessInfo->ProcessName.Buffer).c_str()); //注意
processInfo.CpuPercent= 100*(CurrentDelta / TotalDelta);
processInfo.ProcessMemory= dwWorkingSet/1024;
}
LastTotalProcessCPUUsage = TotalProcessCPUUsage;
LastCurrentProcessCPUUsage = CurrentProcessCPUUsage;
delete[] pProcInfo;
}
//获取网络信息
void TGetInfo::GetNetInfo(TBCSNetInfo &NetInfo)
{
HINSTANCE hInst=::LoadLibrary("iphlpapi.dll");
DWORD NumberOfInterfaces;
typedef DWORD (__stdcall* pGetNumberOfInterfaces)(DWORD*);
typedef DWORD (__stdcall* pGetInterfaceInfo)(PIP_INTERFACE_INFO,unsigned long*);
typedef DWORD (__stdcall* pGetTcpTable)(PMIB_TCPTABLE,unsigned long*,bool);
typedef DWORD (__stdcall* pGetIfEntry)(PMIB_IFROW);
pGetNumberOfInterfaces pf1=(pGetNumberOfInterfaces)::GetProcAddress(hInst,"GetNumberOfInterfaces");
if(pf1)
{
if(pf1(&NumberOfInterfaces)==NO_ERROR)
{
NetInfo.NumInterfaces= NumberOfInterfaces;
}
}
PIP_INTERFACE_INFO pInterfaceInfo=(PIP_INTERFACE_INFO)malloc(sizeof(PIP_INTERFACE_INFO));
unsigned long InfoSize=sizeof(PIP_INTERFACE_INFO);
pGetInterfaceInfo pf2=(pGetInterfaceInfo)::GetProcAddress(hInst,"GetInterfaceInfo");
if(pf2)
{
if(pf2(pInterfaceInfo,&InfoSize)!=NO_ERROR)
{
pInterfaceInfo=(PIP_INTERFACE_INFO)realloc(pInterfaceInfo,InfoSize);
if(pf2(pInterfaceInfo,&InfoSize)==NO_ERROR)
{
NetInfo.NumAdpaters=pInterfaceInfo->NumAdapters;
for(int i=0;i<pInterfaceInfo->NumAdapters;i++)
{
NetInfo.AdpatersIndex=pInterfaceInfo->Adapter[i].Index;
strcpy(NetInfo.AdpatersName,String(pInterfaceInfo->Adapter[i].Name).c_str());
MIB_IFROW ifrow;
MIB_IFROW mibifrow;
MIB_TCPTABLE tcptable;
unsigned long tcpcount=1000;
ifrow.dwIndex=pInterfaceInfo->Adapter[i].Index; //注意
pGetTcpTable pf4=(pGetTcpTable)::GetProcAddress(hInst,"GetTcpTable");
if(pf4)
{
unsigned long rtn=pf4(&tcptable,&tcpcount,true);
if(rtn==NO_ERROR)
{
for(int i=0;i<tcptable.dwNumEntries;i++)
{
String LocalIP,RemoteIP;
int Localport=0,Remoteport=0,Constate=0;
for (int j=0;j<4;j++)
{
if(j==0)
{
LocalIP=String(((tcptable.table[i].dwLocalAddr)>>(j*8))&0xff);
RemoteIP=String(((tcptable.table[i].dwRemoteAddr)>>(j*8))&0xff);
}
else
{
LocalIP=LocalIP+"."+String(((tcptable.table[i].dwLocalAddr)>>(j*8))&0xff);
RemoteIP=RemoteIP+"."+String(((tcptable.table[i].dwRemoteAddr)>>(j*8))&0xff);
}
}
Localport=((tcptable.table[i].dwLocalPort&0xff00)>>8)|((tcptable.table[i].dwLocalPort&0xff)<<8);
Constate=tcptable.table[i].dwState;
if(Constate==MIB_TCP_STATE_LISTEN)
Remoteport=0 ;
else
Remoteport=((tcptable.table[i].dwRemotePort&0xff00)>>8)|((tcptable.table[i].dwRemotePort&0xff)<<8);
strcpy(NetInfo.links[i].LocalAddr,LocalIP.c_str()); // 本地地址
NetInfo.links[i].LocalPort=Localport; // 本地端口
strcpy(NetInfo.links[i].RemoteAddr,RemoteIP.c_str()); // 远程地址
NetInfo.links[i].RemotePort=Remoteport; // 远程的端口
NetInfo.links[i].ConState=Constate ; //连接状态
}
}
else
{
String lpMsgBuf;
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
rtn,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
lpMsgBuf.c_str(),
0,
NULL ))
{
ShowMessage(lpMsgBuf);
}
}
}
pGetIfEntry pf3=(pGetIfEntry)::GetProcAddress(hInst,"GetIfEntry");
if(pf3)
{
if(pf3(&ifrow)==NO_ERROR)
{
if (ifrow.dwType==6||ifrow.dwType==23)
{
mibifrow.dwIndex=pInterfaceInfo->Adapter[i].Index;
if(pf3(&mibifrow)==NO_ERROR)
{
NetInfo.InterFaceIndex= mibifrow.dwIndex ;
strcpy(NetInfo.InterFaceName,String(mibifrow.wszName).c_str());
strcpy(NetInfo.InterFaceDescr,mibifrow.bDescr);
NetInfo.InterFaceType=mibifrow.dwType;
NetInfo.InterFaceSpeed=mibifrow.dwSpeed;
NetInfo.InterFaceMTU=mibifrow.dwMtu;
strcpy(NetInfo.InterFacePhysAddr,mibifrow.bPhysAddr) ;
NetInfo.InterFaceAdminStatus=mibifrow.dwAdminStatus ;
NetInfo.InterFaceOperStatus=mibifrow.dwOperStatus ;
NetInfo.InterFaceInByte=mibifrow.dwInOctets;
NetInfo.InterFaceInUcastPkts=mibifrow.dwInUcastPkts;
NetInfo.InterFaceInNUcastPkts=mibifrow.dwInNUcastPkts;
NetInfo.InterFaceInDiscards=mibifrow.dwInDiscards;
NetInfo.InterFaceInErrors=mibifrow.dwInErrors;
NetInfo.InterFaceInUnKnownPro=mibifrow.dwInUnknownProtos;
NetInfo.InterFaceOutBytes=mibifrow.dwOutOctets;
NetInfo.InterFaceOutUcastPkts=mibifrow.dwOutUcastPkts;
NetInfo.InterFaceOutNUcastPkts=mibifrow.dwOutNUcastPkts;
NetInfo.InterFaceOutDiscards=mibifrow.dwOutDiscards;
NetInfo.InterFaceOutErrors=mibifrow.dwOutErrors;
NetInfo.InterFaceOutQLen=mibifrow.dwOutQLen ;
NetInfo.InterFaceLastChange=mibifrow.dwLastChange;
}
}
}
}
}
}
}
}
free(pInterfaceInfo);
::FreeLibrary(hInst);
}
//安装服务
void TGetInfo::InstallService(String serviceName,String displayName,String path)
{
SC_HANDLE scm;
SC_HANDLE svc;
scm=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
if (scm!=NULL)
{
svc=CreateService(scm,
serviceName.c_str(),
displayName.c_str(),
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS
|SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START, //自动
SERVICE_ERROR_IGNORE,
path.c_str(), //Service程序路径
NULL,NULL,NULL,NULL,NULL);
if (svc!=NULL)
CloseServiceHandle(svc);
CloseServiceHandle(scm);
}
}
//卸载服务
void TGetInfo::UNInstallService(String serviceName)
{
SC_HANDLE scm;
SC_HANDLE svc;
SERVICE_STATUS ServiceStatus;
scm=OpenSCManager(NULL,NULL,
SC_MANAGER_CONNECT);
if (scm!=NULL)
{
svc=OpenService(scm,
serviceName.c_str(),
SERVICE_ALL_ACCESS);
if (svc!=NULL)
{
QueryServiceStatus(svc,&ServiceStatus);
if (ServiceStatus.dwCurrentState==SERVICE_RUNNING) //删除前,先停止此Service.
ControlService(svc,SERVICE_CONTROL_STOP,&ServiceStatus);
DeleteService(svc);
CloseServiceHandle(svc); //删除Service后,最好再调用CloseServiceHandle
}
CloseServiceHandle(scm); //以便立即从数据库中移走此条目
}
}
//终止进程
void TGetInfo::ClosePeocess(int processID)
{
HANDLE psn = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_TERMINATE,false,processID);
//可用GetExitCodeProcess(HANDLE,LPDWORD)获取 ExitCode
if(psn&&TerminateProcess(psn,-9))
{
MessageBox(HANDLE,"成功结束该进程!",Application->Title.c_str(),MB_OK|MB_ICONINFORMATION);
}
else
MessageBox(HANDLE,"无法终止此进程!",Application->Title.c_str(),MB_OK|MB_ICONERROR);
}
//重启服务器
bool TGetInfo::RestartServer()
{
hToken;
TOKEN_PRIVILEGES tkp;
// Get a token for this process.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return( FALSE );
// Get the LUID for the shutdown privilege.
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); //提高权限
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Get the shutdown privilege for this process.
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0); //使得SE_SHUTDOWN_NAME的privilege为有效
if (GetLastError() != ERROR_SUCCESS)
return FALSE;
//ReBoot the system and force all applications to close.
if (!ExitWindowsEx(EWX_REBOOT|EWX_FORCE, 0))
return FALSE;
}
------------------------------------------------------------------------------------------------------------------------
//Unit4.cpp
#pragma hdrstop
#include "Unit4.h"
#include <Aclapi.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma comment ( lib, "ws2_32.lib" )
#pragma package(smart_init)
//---------------------------------------------------------------------------
TSockInfo::TSockInfo()
{
}
TSockInfo::~TSockInfo()
{
}
// 申明NtQuerySystemInformation()函数
typedef DWORD (CALLBACK* NTQUERYSYSTEMINFORMATION)( DWORD, PDWORD, DWORD, PVOID );
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
// 判断SOCKET类型的数组
char szSockType[6][6] = { "NUL", "TCP", "UDP", "RAW", "RDM", "SEQ" };
// RaisePrivleges()函数用来提升本进程的特权
bool TSockInfo::RaisePrivleges( HANDLE hToken, char *pPriv)
{
TOKEN_PRIVILEGES tkp;
if ( !LookupPrivilegeValue( NULL, pPriv, &tkp.Privileges[0].Luid ) )
{
printf( "LookupPrivilegeValue Error:%d/n", GetLastError() );
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
int iRet = AdjustTokenPrivileges(hToken,false,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
if ( iRet == NULL )//AdjustTokenPrivileges函数调用失败
{
printf( "AdjustTokenPrivileges Error:%d/n", GetLastError() );
return false;
}
else//AdjustTokenPrivileges调用成功
{//使用GetLastError()获得返回值
iRet = GetLastError();
switch ( iRet )
{
case ERROR_NOT_ALL_ASSIGNED://未指派所有的特权
printf( "AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED/n" );
return false;
case ERROR_SUCCESS://成功地指派了所有的特权
return true;
default://不知名的错误
printf( "AdjustTokenPrivileges Unknow Error:%d/n", iRet );
return false;
}
}
}
// AdjustDacl用来调整目标进程的DACL
void TSockInfo::AdjustDacl( HANDLE hProcess )
{
SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 };
LPTSTR ptstrName = (LPTSTR)&world;
EXPLICIT_ACCESS ea ={STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,SET_ACCESS,NO_INHERITANCE,
{0, NO_MULTIPLE_TRUSTEE,TRUSTEE_IS_SID,TRUSTEE_IS_USER,ptstrName}};
ACL * pdacl = 0;
if ( SetEntriesInAcl(1, &ea, 0, &pdacl) != ERROR_SUCCESS )
printf( "SetEntriesInAcl Error:%d", GetLastError() );
if ( SetSecurityInfo(hProcess,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,0,0,pdacl,0)!= ERROR_SUCCESS )
printf( "SetSecurityInfo Error:%d", GetLastError() );
LocalFree(pdacl);
}
int TSockInfo::maininfo(TBCSNetState *netstate)
{
printf( "/t=*= GPort Beta1 (Shotgun@xici.net) =*=/n/n" );
int iRet,icount=0;
WSADATA wsaData;
DWORD (__stdcall *GMFNE)(HANDLE hProcess,HMODULE hModule,LPTSTR lpFilename,DWORD nSize);
iRet = WSAStartup( MAKEWORD(1,1), &wsaData );
if ( iRet )
printf( "WSAStartup Error:%d/n", GetLastError() );
HANDLE hCurrentProc = GetCurrentProcess();
HANDLE hToken;
if(!OpenProcessToken(hCurrentProc,TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken))
printf( "OpenProcessToken Error:%d/n", GetLastError() );
else
{
if ( !RaisePrivleges( hToken, SE_DEBUG_NAME ) )
printf( "SetPrivleges SE_DEBUG_NAME Error:%d/n", GetLastError() );
}
if ( hToken )
CloseHandle( hToken );
HMODULE hNtdll = NULL;
hNtdll = LoadLibrary( "ntdll.dll" );
if ( !hNtdll )
{
printf( "LoadLibrary( NTDLL.DLL ) Error:%d/n", GetLastError() );
return false;
}
NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll,"NtQuerySystemInformation");
if ( !NtQuerySystemInformation )
{
printf( "GetProcess( NtQuerySystemInformation ) Error:%d/n", GetLastError() );
return false;
}
HMODULE hPsapi=LoadLibrary("PSAPI");
if(!hPsapi)
{
printf("Cannot load PSAPI./n");
return 0;
}
GMFNE=(DWORD (__stdcall *) (HANDLE, HMODULE,LPTSTR,DWORD))GetProcAddress(hPsapi,"GetModuleFileNameExA");
if(!GMFNE)
{
printf("Cannot GetProcess(GetModuleFileNameExA) Error:%d/n", GetLastError() );
return 0;
}
DWORD dwNumBytes = MAX_HANDLE_LIST_BUF;
PDWORD pdwHandleList = (PDWORD)malloc( dwNumBytes );
if ( !pdwHandleList )
{
printf( "Malloc for Handle List Error:%d/n", GetLastError() );
return false;
}
DWORD dwNumBytesRet = 0;
iRet = (*NtQuerySystemInformation)(NT_HANDLE_LIST,pdwHandleList,dwNumBytes,&dwNumBytesRet);
DWORD dwNumEntries;
PHANDLEINFO pHandleInfo;
if ( iRet )
{
printf( "NtQuerySystemInformation return %d, Error:%d/n",dwNumBytesRet,GetLastError() );
}
else
{
HANDLE hProc;
dwNumEntries = pdwHandleList[0];
pHandleInfo = (PHANDLEINFO)( pdwHandleList + 1 );
for ( DWORD i = 0; i < dwNumEntries; i++ )
{
if ((pHandleInfo->ObjType == OBJECT_TYPE_SOCKET ) && ( pHandleInfo->dwPid ) )
{
hProc = OpenProcess(WRITE_DAC,false,pHandleInfo->dwPid );
if ( hProc )
{
AdjustDacl(hProc);
CloseHandle( hProc );
}
else
printf( "OpenProcess(WRITE_DAC) %d Error:%d/n",pHandleInfo->dwPid,GetLastError());
HANDLE hMyHandle = NULL;
hProc = OpenProcess(PROCESS_DUP_HANDLE,true,pHandleInfo->dwPid );
if ( hProc )
{
DuplicateHandle(hProc,(HANDLE)pHandleInfo->HndlOffset,hCurrentProc,&hMyHandle,STANDARD_RIGHTS_REQUIRED,false,0);
CloseHandle( hProc );
}
else
printf( "OpenProcess %d Error:%d/n",pHandleInfo->dwPid,GetLastError());
if ( !hMyHandle )
{
Sleep( 0 );
//printf( "DuplicateHandle PID=%4d HANDLE:%4d Error:%d/n",pHandleInfo->dwPid, pHandleInfo->HndlOffset, GetLastError() );
}
else
{
sockaddr_in name = {0};
name.sin_family = AF_INET;
int namelen = sizeof(sockaddr_in);
SOCKET s = (SOCKET)hMyHandle;
iRet = getsockname( s,(sockaddr*)&name,&namelen );
if ( iRet != SOCKET_ERROR )
{
int sockType = 0;
int optlen = 4;
char fn[128];
if(icount!=0) Form1->netstate=(TBCSNetState*)realloc(Form1->netstate, sizeof(TBCSNetState)*(icount+1));
iRet = getsockopt(s,SOL_SOCKET,SO_TYPE,(char*)&sockType,&optlen );
hProc=OpenProcess(PROCESS_ALL_ACCESS,false,pHandleInfo->dwPid);
GMFNE(hProc,NULL,fn,128);
CloseHandle( hProc );
Form1->netstate[icount].ProcessID=pHandleInfo->dwPid;
Form1->netstate[icount].SocketPort=ntohs(name.sin_port );
strncpy(Form1->netstate[icount].SocketType,szSockType[sockType],6);
strcpy(Form1->netstate[icount].ProcessName,fn);
icount++;
}
}
}
pHandleInfo++;
}
}
if ( pdwHandleList )
free( pdwHandleList );
if ( hCurrentProc )
CloseHandle( hCurrentProc );
FreeLibrary(hPsapi);
FreeLibrary(hNtdll);
return icount;
}
--------------------------------------------------------------------------------------------------------------
以上是5各Unit,请问怎们样注释,尽量把要实现的写详细一些。谢谢了!