zoukankan      html  css  js  c++  java
  • WINDOWS操作驱动学习 带服务加载驱动

    可以用这个工具查看  驱动运行负荷  如果内核模式运行时间陡然上升  则说明驱动程序消耗了大量的内核资源


    windows 2000 通过        int 2eh

    winodws XP    通过         sysenter   进入内核模式

    Native API  通过 软件中断方式进入到内核模式  并调用内核的系统服务

    执行程序组件:

    1对象管理程序   创建 管理 回收 这些对象的组件

    2进程管理程序   创建  终止 进程  依赖其他执行程序组件

    3虚拟内存管理程序 负责对虚拟内存管理的模块  

      通过某种映射将物理内存和虚拟内存关联起来   0-0x7fffffff  用户模式 的地址   0x80000000 - 0xffffffff  内核模式的地址

    WINDOWS规定所有进程内核 模式 下的虚拟内存的映射方式完全一样  这样在每个进程中  顶端2G的内核模式地址数据完全一致

    4I/O管理器   负责发起I/O 请求  并且管理这些请求  无论对端口的读写   键盘的访问  对磁盘文件的操作 都统一为  IRP(I/O Request Packages) 的请求形式

    IRP被传递到具体设备的驱动程序中,驱动程序负责完成 这些ITP , I/O 管理器担当者用户模式代码和设备驱动程序之间的接口

    5配置管理程序   记录所有计算机软件 硬件 的配置信息 使用注册表 保存这些数据

    设备驱动程序根据注册表进行加载



    WINDOWS NT 4.0 (2000之前的版本)后  USER32.DLL  GDI32.DLL 的核心代码放进内核模式下的WIN32K.SYS  同时也保留原来的DLL

    这使得USE32.DKK 和GDI32.DLL变得很小,只负责调用内核模式下的WIN32K.SYS 这样提高了WINDOWS的绘制图形 效率



    驱动程序  可以理解为  操作系统的  “补丁”


    __cdecl  函数体以  ret  

    __stdcall 函数以   ret x返回

    C语言和标准调用的最重要的区别

    extern "C" 修饰   /  VC 设置 __stdcall  / DDK  编译   函数编译成汇编   __Foo@8  的形式  才正确


    C++ 需要包含 NTDDK.H  / WDM.H 会出现错误  错误原因: 按照C++的编译方式  修改为:

    #ifdef __cplusplus //判断是否使用C++的编译方式
    extern "C"
    { //用大括号包含  这样就按照C的方式编译了
    #endif
    #include <ntddk.h>
    #ifdef __cplusplus
    }
    #endif 


    调试语句打印:

    KdPrint(("Enter Hello "));

    char *name = "hello";

    KdPrint(("%s ",name));

    UNICODE_STRING devName;

    ``````

    KdPrint(("%S ",devName.Buffer));    //UNICODE

    KdPrint(("%ws ",devName.Buffer));  //宽字符

    Int number =100;

    KdPrint(("%d ",number));

    KdPrint(("%X ",number));


    手动加载NT驱动:



    下面是提供的自动运行驱动的服务安装  这里的服务是不显示的:   驱动程序源码就没提供了  随便弄个就可以验证了

    #include <windows.h>  
    #include <winsvc.h>  
    #include <conio.h>  
    #include <stdio.h>
    
    #define DRIVER_NAME "HelloDDK"    //这里填写驱动显示名称
    #define DRIVER_PATH "..\MyDriver\MyDriver_Check\HelloDDK.sys" //这里填写驱动
    
    //装载NT驱动程序
    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 ! 
    ", GetLastError() );
    		bRet = FALSE;
    		goto BeforeLeave;
    	}
    	else
    	{
    		////OpenSCManager成功
    		printf( "OpenSCManager() ok ! 
    " );  
    	}
    
    	//创建驱动所对应的服务
    	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 ! 
    ", dwRtn );  
    			bRet = FALSE;
    			goto BeforeLeave;
    		}  
    		else  
    		{
    			//服务创建失败,是由于服务已经创立过
    			printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! 
    " );  
    		}
    
    		// 驱动程序已经加载,只需要打开  
    		hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );  
    		if( hServiceDDK == NULL )  
    		{
    			//如果打开服务也失败,则意味错误
    			dwRtn = GetLastError();  
    			printf( "OpenService() Faild %d ! 
    ", dwRtn );  
    			bRet = FALSE;
    			goto BeforeLeave;
    		}  
    		else 
    		{
    			printf( "OpenService() ok ! 
    " );
    		}
    	}  
    	else  
    	{
    		printf( "CrateService() ok ! 
    " );
    	}
    
    	//开启此项服务   这里意味着  驱动被加载了
    	bRet= StartService( hServiceDDK, NULL, NULL );  
    	if( !bRet )  
    	{  
    		DWORD dwRtn = GetLastError();  
    		if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )  
    		{  
    			printf( "StartService() Faild %d ! 
    ", dwRtn );  
    			bRet = FALSE;
    			goto BeforeLeave;
    		}  
    		else  
    		{  
    			if( dwRtn == ERROR_IO_PENDING )  
    			{  
    				//设备被挂住
    				printf( "StartService() Faild ERROR_IO_PENDING ! 
    ");
    				bRet = FALSE;
    				goto BeforeLeave;
    			}  
    			else  
    			{  
    				//服务已经开启
    				printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! 
    ");
    				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 ! 
    ", GetLastError() );  
    		bRet = FALSE;
    		goto BeforeLeave;
    	}  
    	else  
    	{
    		//带开SCM管理器失败成功
    		printf( "OpenSCManager() ok ! 
    " );  
    	}
    	//打开驱动所对应的服务
    	hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );  
    
    	if( hServiceDDK == NULL )  
    	{
    		//打开驱动所对应的服务失败
    		printf( "OpenService() Faild %d ! 
    ", GetLastError() );  
    		bRet = FALSE;
    		goto BeforeLeave;
    	}  
    	else  
    	{  
    		printf( "OpenService() ok ! 
    " );  
    	}  
    	//停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  
    	if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  
    	{  
    		printf( "ControlService() Faild %d !
    ", GetLastError() );  
    	}  
    	else  
    	{
    		//打开驱动所对应的失败
    		printf( "ControlService() ok !
    " );  
    	}  
    	//动态卸载驱动程序。  
    	if( !DeleteService( hServiceDDK ) )  
    	{
    		//卸载失败
    		printf( "DeleteSrevice() Faild %d !
    ", GetLastError() );  
    	}  
    	else  
    	{  
    		//卸载成功
    		printf( "DelServer:eleteSrevice() ok !
    " );  
    	}  
    	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 ! 
    " );  
    	}
    	else  
    	{
    		printf( "Create Device faild %d ! 
    ", GetLastError() );  
    	}
    	CloseHandle( hDevice );
    } 
    
    int main(int argc, char* argv[])  
    {
    	//加载驱动
    	BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);
    	if (!bRet)
    	{
    		printf("LoadNTDriver error
    ");
    		return 0;
    	}
    	//加载成功
    
    	printf( "press any to create device!
    " );  
    	getch();  
    
    	TestDriver();
    
    	//这时候你可以通过注册表,或其他查看符号连接的软件验证。  
    	printf( "press any to unload the driver!
    " );  
    	getch();  
    
    	//卸载驱动
    	UnloadNTDriver(DRIVER_NAME);
    	if (!bRet)
    	{
    		printf("UnloadNTDriver error
    ");
    		return 0;
    	}
    
    	return 0;  
    }  
    

















  • 相关阅读:
    (双指针 二分) leetcode 167. Two Sum II
    (双指针) leetcode 485. Max Consecutive Ones
    (双指针) leetcode 27. Remove Element
    (String) leetcode 67. Add Binary
    (数组) leetcode 66. Plus One
    (N叉树 BFS) leetcode429. N-ary Tree Level Order Traversal
    (N叉树 递归) leetcode 590. N-ary Tree Postorder Traversal
    (N叉树 递归) leetcode589. N-ary Tree Preorder Traversal
    (N叉树 DFS 递归 BFS) leetcode 559. Maximum Depth of N-ary Tree
    (BST 递归) leetcode98. Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982527.html
Copyright © 2011-2022 走看看