吾爱专用:今天怀着疲惫的身体继续 深层次研究 底层开发
大神勿喷:太累了 今天就简单学习一个 创建设备的API吧
代码如下:
#include
NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject)
{
NTSTATUS Status;
PDEVICE_OBJECT pdevobj;
UNICODE_STRING usdevname;
UNICODE_STRING usSyvname;
RtlInitUnicodeString(&usdevname,L"\\Device\\FirstDevice"); //函数 2个参数
///驱动中调用此函数来创建设备对象。
Status=IoCreateDevice(pDriverObject,\ //参数1 句柄
0,\ //2 0
&usdevname,\ // 指针地址
FILE_DEVICE_UNKNOWN,\ // 默认常量
FILE_DEVICE_SECURE_OPEN,\ // 默认常量
TRUE,\ // 默认
&pdevobj); // 输出的地址
if (!NT_SUCCESS(Status)) //判断宏
{
return Status; //返回 格式
}
pdevobj->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&usSyvname, L"\\??\\FirstDevice");
Status=IoCreateSymbolicLink(&usSyvname,&usdevname); //IO参数 自己 百度下
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(pdevobj);
return Status;
}
return STATUS_SUCCESS;
}
VOID MyUnload(PDRIVER_OBJECT pDriverObject) //卸载驱动 格式 都是死的
{
UNICODE_STRING usSyvname;
RtlInitUnicodeString(&usSyvname, L"\\??\\FirstDevice");
if (pDriverObject->DeviceObject!= NULL)
{
IoDeleteDevice(pDriverObject->DeviceObject);
IoDeleteSymbolicLink(&usSyvname);
KdPrint(("驱动卸载成功"));
}
///卸载历程
/*DbgPrint("1111111");*/
KdPrint(("驱动卸载成功"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING Reg_Path) //加载 驱动格式 都是死的
{
NTSTATUS status;
///主程序
KdPrint(("驱动加载成功"));
/*DbgPrint("quit success");*/
status = CreateDevice(pDriverObject);
if(!NT_SUCCESS(status))
{
KdPrint(("创建成功"));
}else{
KdPrint(("创建失败"));
KdPrint(("%wZ", Reg_Path));
}
pDriverObject->DriverUnload = MyUnload;
return STATUS_SUCCESS;
}
--------------------------------------------------------
函数说明:1:
例如: RtlInitUnicodeString(&ntName, L"\\Device\\CallDevice");
lkd> u RtlInitUnicodeString l 30
ntdll!RtlInitUnicodeString:
7c9212d6 57 push edi
7c9212d7 8b7c240c mov edi,dword ptr [esp+0Ch] ;参数L"\\Device\\CallDevice"
7c9212db 8b542408 mov edx,dword ptr [esp+8] ;参数&ntName
7c9212df c70200000000 mov dword ptr [edx],0 ;ntName.Length = 0,ntName.MaximumLength = 0;
7c9212e5 897a04 mov dword ptr [edx+4],edi;ntName.Buffer 指向 L"\\Device\\CallDevice"
7c9212e8 0bff or edi,edi; 判断参数2,L"\\Device\\CallDevice"是否为空
7c9212ea 7422 je ntdll!RtlInitUnicodeString+0x38 (7c92130e); = 0,退出
7c9212ec 83c9ff or ecx,0FFFFFFFFh ;开始计算长度
7c9212ef 33c0 xor eax,eax
7c9212f1 f266af repne scas word ptr es:[edi]
7c9212f4 f7d1 not ecx
7c9212f6 d1e1 shl ecx,1 ;ecx保存长度
7c9212f8 81f9feff0000 cmp ecx,0FFFEh
7c9212fe 7605 jbe ntdll!RtlInitUnicodeString+0x2f (7c921305)
7c921300 b9feff0000 mov ecx,0FFFEh
7c921305 66894a02 mov word ptr [edx+2],cx ;ntName.MaximumLength = cx
7c921309 49 dec ecx
7c92130a 49 dec ecx
7c92130b 66890a mov word ptr [edx],cx ;ntName.Length = cx
7c92130e 5f pop edi
7c92130f c20800 ret 8
---------------------------------------------
2.例如:CreateDevice
HRESULT CreateDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInte
参数:Adapter:
序数所指示的显示器适配器。D3DADAPTER_DEFAULT始终是主要的显示器适配器。
DeviceType:
在D3DDEVTYPE列举的成员,表示预设类型的驱动器类型,在HAL(Hardware Accelerator,硬件加速)和REF(Reference Rasterizer,一调试工具)之间选择。这里有第三个选项,软件渲染,作用是设计能支持自定义渲染的插件。DirectX DDK(驱动程序开发工具包)就能做到,但如果你能自己写出3D渲染器的话,是不太可能使用VB的J……请指定参数D3DDEVTYPE_HAL(硬件加速)或D3DDEVTYPE_REF(软件模拟) 。,如果预设的设备类型是无效的,即如果不支持硬件加速,调用此函数就会失败,你就不能创建设备。
hFocusWindow:
与设备相关的窗口句柄,你想在哪个窗口绘制就写那个窗口的句柄
BehaviorFlags:
设定为D3DCREATE_SOFTWARE_VERTEXPROCESSING(软件顶点处理) 或者D3DCREATE_HARDWARE_VERTEXPROCESSING(硬件顶点处理) ,使用前应该用d3dcaps来检测用户计算机是否支持硬件顶点处理功能。
PresentationParameters:
一个D3DPRESENT_PARAMETERS 类型的变量,用于指定将要创建设备的各种信息
ppReturnedDeviceInterface:
一个DIRECT3DDEVICE9类型的指针用来返回创建的设备
--------------------------------------------------------------------------------------------------------------------
3.IoCreateDevic()
NTSTATUS IoCreateDevice
(
IN PDRIVER_OBJECT DriverObject,
IN ULONG DeviceExtensionSize,
IN PUNICODE_STRING DeviceNameOPTIONAL,
IN DEVICE_TYPE DeviceType,
IN ULONG DeviceCharacteristics,
IN BOOLEAN Exclusive,
OUT PDEVICE_OBJECT *DeviceObject
);
DriverObject
一个指向调用该函数的驱动程序对象.每一个驱动程序在它的DriverEntry过程里接收一个指向它的驱动程序对象.
WDM功能和过滤驱动程序也在他们的AddDevice过程接受一个驱动程序对象的指针.
DeviceExtensionSize
指定驱动程序为设备扩展对象而定义的结构体的大小.
DeviceName
(可选的参数)指向一个以零结尾的包含Unicode字符串的缓冲区,那是这个设备的名称,该字符串必须是一个完整的设备路径名.
WDM功能驱动程序和过滤驱动程序它们的设备对象没有名字.
注意:如果设备名未提供(即这个参数是NULL),IoCreateDevice创建的设备对象将不会有一个DACL与之相关联.
DeviceType
指定一个由一个系统定义的FILE_DEVICE_XXX常量,表明了这个设备的类型
(如FILE_DEVICE_DISK,FILE_DEVICE_KEYBOARD等),或供应商定义的一种新型设备的类型.
DeviceCharacteristics
指定一个或多个系统定义的常量,连接在一起,提供有关驱动程序的设备其他信息.对于可能的设备特征信息,
见DEVICE_OBJECT结构体.
Exclusive
如果指定设备是独占的,大部分驱动程序设置这个值为FALSE,如果是独占的话设置为TRUE,非独占设置为FALSE.
DeviceObject
一个指向DEVICE_OBJECT结构体指针的指针,这是一个指针的指针,指向的指针用来接收DEVICE_OBJECT结构体的指针.
返回值编辑
IoCreateDevice函数成功时返回STATUS_SUCCESS,失败时返回适当的NTSTATUS错误代码.这时这个函
返回值 STATUS_INSUFFICIENT_RESOURCES
STATUS_OBJECT_NAME_EXISTS
STATUS_OBJECT_NAME_COLLISION
调用要求编辑
包含文件:wdm.h,ntddk.h
--------------------------------------------------------------------------
4. IoCreateSymbolicLink函数的作用以及符号链接、设备名称之间的关系
oCreateSymbolicLink这个函数的功能是创建符号链接,通常在DriverEntry中调用。
wdk文档中对这个函数介绍如下:
The IoCreateSymbolicLink routine sets up a symbolic link between a device object name and a user-visible name for the device.
这句话的意思就是IoCreateSymbolicLink在设备名和用户可见名字之间创建链接。
通常在调用IoCreateDevice创建设备对象的时候会传入设备名称。这个设备名称只能在内核层使用,只能被内核层的函数识别。如果IoCreateDevice中没有指定设备名称,那么I/O管理器会自动分配一个数字作为设备的名称。例如"\Device\00000001"。
如果想要在用户层的应用程序中访问(比如调用CreateFile函数打开),就需要创建符号链接,相当于为设备对象创建一个别名,供应用程序访问。应用层是无法直接通过设备名字来打开对象的,必须建立一个暴露给应用程序的符号链接。
比如:c盘的符号链接名称是"C:",对应的设备名称是"\Device\HarddiskVolume1”
---------------------------------------------------------
4. IoDeleteDevice
作用: 此函数用于删除已建立的设备
VOID IoDeleteDevice(
IN PDEVICE_OBJECT DeviceObject );
参数:
DeviceObject
PDEVICE_OBJECT类型的指针,指向需要删除的设备对象
无返回值
-----------------------------------
5. IoDeleteSymbolicLink
作用: 此函数用于从系统中删除一个符号链接。
NTSTATUS IoDeleteSymbolicLink(
IN PUNICODE_STRING SymbolicLinkName );
参数:
SymbolicLinkName
PUNICODE_STRING类型的指针,指向一个缓冲 Unicode 字符串的用户可见链接符号名称
返回值:
如果符号链接删除成功 返回 STATUS_SUCCESS
----------------------------------------
驱动入口和C++的main 一样
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
){
}
------------------------------------------------
KdPrint DebugPrint
使用方法类似printf,注意KdPrint((" ", ));使用的是双括号。
--------------------------------------------------------------
吾爱专用 累了
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |