环境配置
STL中有很多很好用的数据结构和算法,因此被广泛使用。不用造轮子直接用是懒程序员的直接想法。目前刚学Windows驱动,就想看看能不能直接在驱动中使用STL和BOOST。很多时候这样是不安全的,因为用到了应用层的DLL,可能引起冲突。这里我也是牛刀小试,觉得还是有法可解的。驱动环境安装和VS自动调试环境细节的就不说了:
- WDK=7600
- HOSTOS=Win7 x64
- CLIENTOS=XP Win7 x86
- VS=2005
- Debugger=VisualDDK
安装好以后,来建立一个空的exe工程testsys,设置vs的include和lib目录 - include:
-
- E:\WinDDK\7600.16385.1\inc\api\crt\stl60
-
- E:\WinDDK\7600.16385.1\inc\ddk
-
- E:\WinDDK\7600.16385.1\inc\crt
-
- E:\WinDDK\7600.16385.1\inc\api
- lib:
-
- E:\WinDDK\7600.16385.1\lib\win7\i386
打开testsys工程属性对话框,如下设置(比网上那些设置要更严格一些):
- E:\WinDDK\7600.16385.1\lib\win7\i386
C/C++
General:
Configuration Type:如果能则设为.sys
Use of MFC:Use MFC in a Static Library
Optimization:
Disabled
Preprocessor:
WIN32=100;_X86_=1;DBG=1
Code Generation:
Enable C++ Exception:Yes
Basic Runtime Checkefault
RuntimeLibrary:Multi-threaded Debug(/MTd)
Buffer Security Check:No
Precompiled Headers:Not Using..
Advanced
Calling Convention:_stdcall
Linker
General
Output Fle:后缀改sys
Enable Incremental Linking:No
Input
Additional Dependencies:ntoskrnl
Ignore All Default Libraries:Yes
Manifest File:No
System
SubSystem:Native
Heap Reserve Size:40000
Heap Commit Size:1000
Driverriver
Advanced
Entry PointriverEntry
Base Address:0x10000
Target Machine:MachineX86
编写测试用例
testdriver.cpp
#include <ntddk.h>
#include "ntmem.h"
#include <string>
#include <vector>
#include <numeric>
#include <map>
using namespace std;
::_Lockit::_Lockit(){};
::_Lockit::~_Lockit(){};
void _cdecl std::_Xlen(void){};
void _cdecl std::_Xran(void){};
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING)
{
//如何保证用stl等c++库不会出问题,我觉得有下面几点:
//1 不使用带有io操作的,尽量使用内存操作的
//2 使用静态链接,不要使用导入库,那样会引入应用层dll
vector<int> vec;
for(int i=1;i<=100;i++)
{
vec.push_back(i);
}
int result1 = accumulate(vec.begin(),vec.end(),0);
KdPrint(("1-100 sum=%d\n",result1));
string result2="lichao";
result2 += "890427";
KdPrint(("name=%s\n",result2.c_str()));
map<string,string> result3;
result3["telphone"]="18392635617";
KdPrint(("tel=%s\n",result3["telphone"].c_str()));
NTSTATUS status = STATUS_SUCCESS;
return status;
}
ntmem.h
#pragma once
#ifndef _LCNTDEFS_
#define _LCNTDEFS_
#ifdef new
#undef new
#endif
#ifdef delete
#undef delete
#endif
//common new
void* __cdecl operator new(size_t _Size)
{
return ExAllocatePool(NonPagedPool,_Size);
}
//array new
void* _cdecl operator new[](size_t _Size)
{
return ExAllocatePool(NonPagedPool,_Size);
}
//common delete
inline void _cdecl operator delete(void* _P)
{
if(_P)
ExFreePool(_P);
}
//array delete
inline void _cdecl operator delete[](void* _P)
{
if(_P)
ExFreePool(_P);
}
#endif/*_LCNTDEFS_*/
extern "C"
{
void _cdecl __CxxFrameHandler3()
{
}
int _cdecl memcmp(const void* buf1,const void* buf2,size_t count)
{
return RtlCompareMemory(buf1,buf2,count);
}
int __security_cookie=0;
}
编译结果:
1>------ Build started: Project: testsys, Configuration: Debug Win32 ------
1>Compiling...
1>cl : Command line warning D9007 : '/Gm' requires '/Zi or /ZI'; option ignored
1>cl : Command line warning D9002 : ignoring unknown option '/verbose'
1>testdriver.cpp
1>c:\users\lichao26\desktop\testdriver\testsys\ntmem.h(48) : warning C4244: 'return' : conversion from 'SIZE_T' to 'int', possible loss of data
1>Linking...
1>Starting pass 1
1>LINK : warning LNK4075: ignoring '/DELAYLOAD' due to '/DRIVER' specification
1>Searching libraries
1> Searching E:\WinDDK\7600.16385.1\lib\win7\i386\ntoskrnl.lib:
1> Found __imp__ExAllocatePool@8
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found __imp__ExFreePoolWithTag@8
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found __imp__RtlCompareMemory@12
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found _DbgPrint
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found _strlen
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found _memcpy
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found _memmove
1> Referenced in testdriver.obj
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found __IMPORT_DESCRIPTOR_ntoskrnl
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found __NULL_IMPORT_DESCRIPTOR
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Found ntoskrnl_NULL_THUNK_DATA
1> Referenced in ntoskrnl.lib(ntoskrnl.exe)
1> Loaded ntoskrnl.lib(ntoskrnl.exe)
1> Searching E:\WinDDK\7600.16385.1\lib\Crt\i386\\DelayImp.lib:
1>Finished searching libraries
1>Finished pass 1
1>Searching libraries
1> Searching E:\WinDDK\7600.16385.1\lib\win7\i386\ntoskrnl.lib:
1> Found __load_config_used
1> Loaded ntoskrnl.lib(loadcfg.obj)
1> Searching E:\WinDDK\7600.16385.1\lib\Crt\i386\\DelayImp.lib:
1>Finished searching libraries
1>Starting pass 2
1> testdriver.obj
1> ntoskrnl.lib(loadcfg.obj)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1> ntoskrnl.lib(ntoskrnl.exe)
1>Finished pass 2
1>roject : warning PRJ0018 : The following environment variables were not found:
1>$(WindowsSdkDir)
1>Build log was saved at "file://c:\Users\lichao26\Desktop\testdriver\testsys\Debug\BuildLog.htm"
1>testsys - 0 error(s), 4 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
注意,ntmem.h重载了new和delete操作符,并且处理了unresolved symbols错误(__CxxFrameHandler3,memcmp,__security_cookie),如果今后有找不到链接符号的时候,在头文件里写相应的实现即可
输出结果:
1-100 sum=5050
name=l
tel=18392635617
总结
此次测试,对string类,vector类及map类做了简单测试,未发生蓝屏,说明其实驱动里,还是可以用stl的,因为stl基本上是内存操作。