Windows 驱动加载程序代码
#include <windows.h>
#include <winsvc.h>
#include <conio.h>
#include <stdio.h>
#define DRIVER_NAME "MySYS"
#define DRIVER_PATH "./MySYS.sys" BOOL LoadNTDriver(char* lpszDriverName,char* lpszDriverPath)
{
char szDriverImagePath[256];
//得到完整的驱动路径
GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
BOOL bRet = FALSE;
SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
//打开服务控制管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hServiceMgr == NULL )
{
//OpenSCManager失败
printf( "OpenSCManager() Faild %d ! /n", GetLastError() );
bRet = FALSE;
goto BeforeLeave;
}
else
{
////OpenSCManager成功
printf( "OpenSCManager() ok ! /n" );
}
//创建驱动所对应的服务
hServiceDDK = CreateService( hServiceMgr,
lpszDriverName, //驱动程序的在注册表中的名字
lpszDriverName, // 注册表驱动程序的 DisplayName 值
SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序
SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值
SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值
szDriverImagePath, // 注册表驱动程序的 ImagePath 值
NULL,
NULL,
NULL,
NULL,
NULL);
DWORD dwRtn;
//判断服务是否失败
if( hServiceDDK == NULL )
{
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )
{
//由于其他原因创建服务失败
printf( "CrateService() Faild %d ! /n", dwRtn );
bRet = FALSE;
goto BeforeLeave;
}
else
{
//服务创建失败,是由于服务已经创立过
printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! /n" );
}
// 驱动程序已经加载,只需要打开
hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );
if( hServiceDDK == NULL )
{
//如果打开服务也失败,则意味错误
dwRtn = GetLastError();
printf( "OpenService() Faild %d ! /n", dwRtn );
bRet = FALSE;
goto BeforeLeave;
}
else
{
printf( "OpenService() ok ! /n" );
}
}
else
{
printf( "CrateService() ok ! /n" );
}
//开启此项服务
bRet= StartService( hServiceDDK, NULL, NULL );
if( !bRet )
{
DWORD dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
{
printf( "StartService() Faild %d ! /n", dwRtn );
bRet = FALSE;
goto BeforeLeave;
}
else
{
if( dwRtn == ERROR_IO_PENDING )
{
//设备被挂住
printf( "StartService() Faild ERROR_IO_PENDING ! /n");
bRet = FALSE;
goto BeforeLeave;
}
else
{
//服务已经开启
printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! /n");
bRet = TRUE;
goto BeforeLeave;
}
}
}
bRet = TRUE;
//离开前关闭句柄
BeforeLeave:
if(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
return bRet;
} //卸载驱动程序
BOOL UnloadNTDriver( char * szSvrName )
{
BOOL bRet = FALSE;
SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
SERVICE_STATUS SvrSta;
//打开SCM管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hServiceMgr == NULL )
{
//带开SCM管理器失败
printf( "OpenSCManager() Faild %d ! /n", GetLastError() );
bRet = FALSE;
goto BeforeLeave;
}
else
{
//带开SCM管理器失败成功
printf( "OpenSCManager() ok ! /n" );
}
//打开驱动所对应的服务
hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );
if( hServiceDDK == NULL )
{
//打开驱动所对应的服务失败
printf( "OpenService() Faild %d ! /n", GetLastError() );
bRet = FALSE;
goto BeforeLeave;
}
else
{
printf( "OpenService() ok ! /n" );
}
//停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。
if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )
{
printf( "ControlService() Faild %d !/n", GetLastError() );
}
else
{
//打开驱动所对应的失败
printf( "ControlService() ok !/n" );
}
//动态卸载驱动程序。
if( !DeleteService( hServiceDDK ) )
{
//卸载失败
printf( "DeleteSrevice() Faild %d !/n", GetLastError() );
}
else
{
//卸载成功
printf( "DelServer:eleteSrevice() ok !/n" );
}
bRet = TRUE;
BeforeLeave:
//离开前关闭打开的句柄
if(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
return bRet;
}
void TestDriver()
{
//测试驱动程序
HANDLE hDevice = CreateFile("////.//HelloDDK",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hDevice != INVALID_HANDLE_VALUE )
{
printf( "Create Device ok ! /n" );
}
else
{
printf( "Create Device faild %d ! /n", GetLastError() );
}
CloseHandle( hDevice );
} int main(int argc, char* argv[])
{
//加载驱动
BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);
if (!bRet)
{
printf("LoadNTDriver error/n");
return 0;
}
//加载成功
printf( "press any to create device!/n" );
getch();
TestDriver();
//这时候你可以通过注册表,或其他查看符号连接的软件验证。
printf( "press any to unload the driver!/n" );
getch();
//卸载驱动
UnloadNTDriver(DRIVER_NAME);
if (!bRet)
{
printf("UnloadNTDriver error/n");
return 0;
}
return 0;
}
Windows 驱动加载程序代码的更多相关文章
- 引导加载程序之争: LILO 和 GRUB
在不考虑他们的工作或专业情况下,所有 Linux 用户都会使用的是哪个工具?引导加载程序.通过本文了解引导加载程序的工作原理,认识两个流行的引导加载程序 LILO(LInux LOader)和 GNU ...
- 微信小程序开发——模板中加载html代码
最新方法可以使用微信小程序提供的 rich-text (富文本)组件直接写解析html,详见 rich-text: <rich-text class='f13 c_9' nodes=" ...
- 老调重弹:JDBC系列之<驱动加载原理全面解析) ----转
最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读者 ...
- linux设备和驱动加载的先后顺序
点击打开链接 Linux驱动先注册总线,总线上可以先挂device,也可以先挂driver,那么究竟怎么控制先后的顺序呢. Linux系统使用两种方式去加载系统中的模块:动态和静态. 静态加载:将所有 ...
- insmod模块加载过程代码分析1【转】
转自:http://blog.chinaunix.net/uid-27717694-id-3966290.html 一.概述模块是作为ELF对象文件存放在文件系统中的,并通过执行insmod程序链接到 ...
- (DT系列四)驱动加载中, 如何取得device tree中的属性
本文以At91rm9200平台为例,从源码实现的角度来分析驱动加载时,Device tree的属性是如何取得的.一:系统级初始化DT_MACHINE_START 主要是定义"struct m ...
- 【转】(DT系列四)驱动加载中, 如何取得device tree中的属性
原文网址:http://www.cnblogs.com/biglucky/p/4057488.html 本文以At91rm9200平台为例,从源码实现的角度来分析驱动加载时,Device tree的属 ...
- 引导加载程序:GRUB
计算机在启动的时候,首先由BIOS中的程序执行自检,自检通过后,就根据CMOS的配置找到第一个可启动磁盘的MBR中的Boot Loader程序(一般在启动盘的第一个物理扇区,占446字节),并把控制权 ...
- golang动态加载原生代码思路
golang动态加载原生代码思路(非plugin,非so文件.使用mmap形式运行机器码,可释放) 1.用go tool objdump,可以看到任意函数的机器码.汇编指令.偏移.(go源码下面有一个 ...
随机推荐
- 简述Python垃圾回收机制和常量池的验证
目录 通过代码验证python解释器内部使用了常量池 Python的引入 变量的引入 为什么要有变量 定义变量 常量引入 常量池引入 Python解释器 Python变量存储机制 Python垃圾回收 ...
- Hi3559AV100 NNIE开发(3)RuyiStudio软件 .wk文件生成过程-mobilefacenet.cfg的参数配置
之后随笔将更多笔墨着重于NNIE开发系列,下文是关于Hi3559AV100 NNIE开发(3)RuyiStudio软件 .wk文件生成过程-mobilefacenet.cfg的参数配置,目前项目需要对 ...
- WPF 基础 - DataTemplate
如果把控件的功能视为内容,则可以使用控件模板 ControlTemplate 来控制它的展现: 如果把数据视为内容,则可以使用数据模板 DataTemplate 把数据展示出来: ControlTem ...
- H5 简单实现打砖块游戏
实现效果如图所示: 1.布局 在html中,声明 div1 作为作为带有边框的父物体,一切行为都要在 div1 中进行.创建小球ball.左右可滑动的板子bat,以及存放要销毁的砖块的父物体 bri ...
- ACM常用的C++ && STL
内容 c++输入输出 c++ string vector:不定长数组 map:映射 queue:队列 sort:排序 priority_queue:优先队列 c++输入输出 1 #include &l ...
- XML数据持久化学习笔记
一.XML基础语法 1.XML结构:XML是一种树结构的文本 2.XML注释:格式:<!--在其中书写注释-->,在注释中可以单行注释也可以多行注释 3.固定内容:<?xml ver ...
- Starting Tomcat v9.0 Server at localhost' has encountered a problem
•问题描述 在通过 Eclipse 打开 Tomcat 时报错: •解决方案 找到 Tomcat 的安装位置,打开 tomcat\bin 目录,找到 shutdown.bat,手动关闭 tomcat: ...
- 清明节特辑 |记忆存储、声音还原、性格模仿……AI可以让人类永生吗?
摘要:如果能用AI "复活"逝去的亲人 你愿意吗? 清明节,很少有人会去特地想这样一个问题:我们为什么要给过世的人修墓,然后每年固定的时间去扫墓?当农耕文化的色彩褪去,清明节的祭祀 ...
- Windows下C++/Fortran调用.exe可执行文件
目录 软件环境 Windows下CMake编译配置 设置项目的generator Command Line CMake GUI PreLoad.cmake 设置make 示例程序 CMake 设置Fo ...
- [树形DP]二叉苹果树
二 叉 苹 果 树 二叉苹果树 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定 ...