目录
1 生成控制设备
1.1DriverEntry函数原型
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath
);
/*
Routine Description:
Called on loading. We create a device object to handle user-mode requests
on, and register ourselves as a protocol with NDIS.
Arguments:
pDriverObject - Pointer to driver object created by system.
pRegistryPath - Pointer to the Unicode name of the registry path
for this driver.
Return Value:
NT Status code*/
1.2.注册一个协议
1.2.1 定义需要用到的变量
//协议驱动的协议特征
NDIS_PROTOCOL_CHARACTERISTICS protocolChar;
//状态变量,当返回值用
NTSTATUS status = STATUS_SUCCESS;
//NDIS_STRING其实就是UNICODE_STRING
NDIS_STRING protoName = NDIS_STRING_CONST("NdisProt");
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;
BOOLEAN fSymbolicLink = FALSE;
PDEVICE_OBJECT deviceObject = NULL;
//用宏避免出现参数未使用警告 这个语句非常重要,因为我们经常不会用到pRegistryPath
UNREFERENCED_PARAMETER(pRegistryPath);
DEBUGP(DL_LOUD, ("DriverEntry\n"));
//在全局变量中记录驱动对象指针,也就是DriverEntry用到的本驱动对象指针
Globals.pDriverObject = pDriverObject;
//初始化一个事件
NPROT_INIT_EVENT(&Globals.BindsComplete);
1.2.2 生成控制设备和该设备的符号链接
do
{
//
// Create our device object using which an application can
// access NDIS devices.
//
//初始化控制设备名 #define NT_DEVICE_NAME L"\\Device\\NdisProt"
RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
//不同系统下创建新的设备对象
#ifndef WIN9X
status = IoCreateDeviceSecure(pDriverObject,
0,
&ntDeviceName,
FILE_DEVICE_NETWORK,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
NULL,
&deviceObject);
#else
status = IoCreateDevice(pDriverObject,
0,
&ntDeviceName,
FILE_DEVICE_NETWORK,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&deviceObject);
#endif
if (!NT_SUCCESS (status))
{
//
// Either not enough memory to create a deviceobject or another
// deviceobject with the same name exits. This could happen
// if you install another instance of this device.
//
break;
}
//初始化符号链接 #define DOS_DEVICE_NAME L"\\DosDevices\\NdisProt"
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
//生成符号链接
status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
if (!NT_SUCCESS(status))
{
break;
}
fSymbolicLink = TRUE;
//设备采用直接IO通信方式
deviceObject->Flags |= DO_DIRECT_IO;
//在全局变量中记下控制设备对象指针
Globals.ControlDeviceObject = deviceObject;
NPROT_INIT_LIST_HEAD(&Globals.OpenList);
NPROT_INIT_LOCK(&Globals.GlobalLock);
1.2.3.注册协议 填写协议特征(回调函数)
很简单 只要将协议特征与我们所要填写的API函数名对应起来就行了,和一般的过滤设备绑定是一个套路
//填写协议特征
NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
protocolChar.MajorNdisVersion = 5;
protocolChar.MinorNdisVersion = 0;
protocolChar.Name = protoName;
protocolChar.OpenAdapterCompleteHandler = NdisProtOpenAdapterComplete;
protocolChar.CloseAdapterCompleteHandler = NdisProtCloseAdapterComplete;
protocolChar.SendCompleteHandler = NdisProtSendComplete;
protocolChar.TransferDataCompleteHandler = NdisProtTransferDataComplete;
protocolChar.ResetCompleteHandler = NdisProtResetComplete;
protocolChar.RequestCompleteHandler = NdisProtRequestComplete;
protocolChar.ReceiveHandler = NdisProtReceive;
protocolChar.ReceiveCompleteHandler = NdisProtReceiveComplete;
protocolChar.StatusHandler = NdisProtStatus;
protocolChar.StatusCompleteHandler = NdisProtStatusComplete;
protocolChar.BindAdapterHandler = NdisProtBindAdapter;
protocolChar.UnbindAdapterHandler = NdisProtUnbindAdapter;
protocolChar.UnloadHandler = NULL;
protocolChar.ReceivePacketHandler = NdisProtReceivePacket;
protocolChar.PnPEventHandler = NdisProtPnPEventHandler;
//
// 注册协议
//
NdisRegisterProtocol(
(PNDIS_STATUS)&status,
&Globals.NdisProtocolHandle,
&protocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
status = STATUS_UNSUCCESSFUL;
break;
}
#ifdef NDIS51
Globals.PartialCancelId = NdisGeneratePartialCancelId();
Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));
#endif
//
// 填写本驱动所需要的分发函数(仅仅用于控制设备)
//
pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisProtOpen;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisProtClose;
pDriverObject->MajorFunction[IRP_MJ_READ] = NdisProtRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = NdisProtWrite;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = NdisProtCleanup;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisProtIoControl;
pDriverObject->DriverUnload = NdisProtUnload;
status = STATUS_SUCCESS;
}
while (FALSE);
1.2.4 DriverEntry收尾工作
收尾无非就是如果status状态不为success就释放掉上文创建的资源;如果成功则返回status结束DriverEntry
if (!NT_SUCCESS(status))
{
if (deviceObject)
{
IoDeleteDevice(deviceObject);
Globals.ControlDeviceObject = NULL;
}
if (fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}
return status;
版权声明:本文为weixin_42709632原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。