生成控制设备
//在DriverEntry之外定义一个全局变量
PDEVICE_OBJECT g_cdo = NULL;
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg_path)
{
//生成一个控制设备,然后生成符号链接
UNICODE_STRING sddl = RTL_CONSTANT_STRING(L"D:P(A;;GA;;;WD)");//允许任何用户访问设备
UNICODE_STRING cdo_name = RTL_CONSTANT_STRING(L"\\Device||slbk_3948d33e");//设备名字
..............................
status = IoCreateDeviceSecure(
driver,
0,
&cdo_name,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&sddl,//安全性设置
(LPCGUID)&SLBKGUID_CLASS_MYCDO,&g_cdo
);
if(!NT_SUCCESS(status))
return status;
..................
}
//生成符号链接
NTSTATUS
IoCreateSymbolicLink(
IN PUNICODE_STRING SymbolicLinkNmae,
IN PUNICODE_STRING DeviceName
);
删除符号链接和控制设备
#define CWK_CDO_SYB_NAME L"\\??\\slbkcdo_3948d33e"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg_path)
{
//在DriverUnload里面,设置了cwkUload就是写在函数
driver->DriverUnload = cwkUnload;
}
void cwkUnload(PDRIVER_OBJECT driver)
{
UNICODE_STRING cdo_syb =RTL_CONSTANT_STRING(SLBKCDO_SYB_NAME);
ASSERT(g_cdo != NULL);
IoDeleteSymbolicLink(&);
IoDeleteDevice(g_cdo);
}
分发函数的原型
NTSTATUS cwkDispatch(
IN PDEVICE_OBJECT dev,
IN PIRP irp
)
分发函数必须首先设置给驱动对象,这个工作在DriverEntry中完成
NTSTATSU DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg_path)
{
ULONG i;
//所有的分发函数都设置成一样的
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
driver->MajorFunction[i] = cwkDispatch;
}
}
请求的处理
获得栈空间,利用当前栈空间获得主功能号码
NTSTATUS cwkDispatch(IN PDEVICE_OBJECT dev,IN PIRP irp)
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);//获得栈空间的方法
//判断请求发给谁
if(dev !=g_cdo)
...
...
//判断请求的种类
if(irpsp->MajorFunction == IRP_MJ_CREATE || irpsp->MajorFunction == IRP_MJ_CLOSE)
{
...
}
if(irpsp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
...
}
...
}
在分发函数里面返回请求,需要下满四个步骤
NTSTATUS cwkDispatch(IN PDEVICE_OBJECT dev,IN PIRP irp)
{
...
irp->IoStatus.Information = ret_len;//记录返回的输出长度(小于等于输出缓冲区的长度)
irp->IoStatus.status = status;//记录请求的完成状态
IoCompleteRequest(irp,IO_NO_INCREMENT);//结束这个请求
return status;
}