renxianfu
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2016-01-09
  • 粉丝2
  • 关注2
  • 积分48分
  • 威望365点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分1分
阅读:1516回复:6

请教一个回调函数的问题

楼主#
更多 发布于:2003-09-17 18:09
平台是win2000,是TDI网络过滤驱动,我在驱动里面设置了回调函数,等待网络上的数据返回后,经过我的函数,对数据进行一些处理,这些都没问题,问题是:当网络上的数据还没有到达,而这个时候我的驱动程序已经被卸载了,我设置的回调函数地址出现非法操作,蓝屏! :(
那位大哥知道怎么处理卸载例程中的清除工作,并且替换为原来处理函数,不胜感激
谢谢关注!
yangmin26
驱动小牛
驱动小牛
  • 注册日期2003-02-22
  • 最后登录2012-11-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-09-17 18:27
当(Irp->CurrentLocation == 1)时候强行结束~
YM KILL YOU
renxianfu
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2016-01-09
  • 粉丝2
  • 关注2
  • 积分48分
  • 威望365点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分1分
板凳#
发布于:2003-09-18 13:14
当发出的请求没有回复处理的时候,强行结束后肯定蓝屏,我看了下:IoAcquireRemoveLock,IoReleaseRemoveLockAndWait等相关函数,但是也不能满足我的要求,我目前最笨的办法是:卸载时候先恢复原来系统的处理函数,然后等待,直到回复处理结束,不过现在才开始处理,有新的结果我会贴出来,以供大家指正
谢谢关注!
tanky
驱动牛犊
驱动牛犊
  • 注册日期2002-03-04
  • 最后登录2007-06-08
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-09-19 09:34
卸载之前调用IoCancelIrp
renxianfu
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2016-01-09
  • 粉丝2
  • 关注2
  • 积分48分
  • 威望365点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分1分
地下室#
发布于:2003-09-22 09:30
我这断代码由两个疑问:1,不能使用IoSetCompletionRoutine,否则第一次局域网访问不成功,2,不能使用DriverUnload例程,否则有正在连接的程序时候蓝屏
//////////////////////////////////////////////////////
BOOLEAN fSymbolicLink;
PDEVICE_OBJECT g_devcontrol;

PDEVICE_OBJECT g_tcpfltobj = NULL; // \\Device\\Tcp
PDEVICE_OBJECT g_tcpoldobj;

static VOID DriverUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS PassThrough(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
static NTSTATUS c_n_a_device(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT *fltobj, PDEVICE_OBJECT *oldobj,
wchar_t *devname);
static void d_n_d_device(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT oldobj, PDEVICE_OBJECT fltobj);

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS ntStatus;
UNICODE_STRING strDeviceName;
UNICODE_STRING strwin32DeviceName;

int i = 0;

    PAGED_CODE();

    UNREFERENCED_PARAMETER(RegistryPath);

for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction = Far_MajorDispatch;

// register UnLoad procedure
DriverObject->DriverUnload = Far_DriverUnload;

//Creat Control Device
RtlInitUnicodeString(&strDeviceName, L\"\\\\Device\\\\TestTdi1\");
ntStatus = IoCreateDevice(DriverObject,
0,
&strDeviceName,
0,
0,
TRUE,
&g_devcontrol);
if (! NT_SUCCESS(ntStatus))
{
ObDereferenceObject(g_devcontrol);
g_devcontrol = NULL;
goto DoEnd;
}
else
{
RtlInitUnicodeString(&strwin32DeviceName, L\"\\\\Device\\\\TestTdi1\");

//创建符号连接
ntStatus = IoCreateSymbolicLink( &strwin32DeviceName, &strDeviceName );
if (ntStatus != STATUS_SUCCESS)
{
DbgPrint( \"FAR_TDI: IoCreateSymbolicLink() faild ! \\n\" );
goto DoEnd;
}
else
{
//DbgPrint( \"TWDM: IoCreateSymbolicLink() ok ! \\n\" );
fSymbolicLink = TRUE;
}
}
ntStatus = c_n_a_device(DriverObject, &g_tcpfltobj, &g_tcpoldobj, L\"\\\\Device\\\\Tcp\");
if (ntStatus != STATUS_SUCCESS) {
KdPrint((\"[Far_tdi] DriverEntry: c_n_a_device: 0x%x\\n\", ntStatus));
goto DoEnd;
}

DoEnd:
if (ntStatus != STATUS_SUCCESS) {
// cleanup
Far_DriverUnload(DriverObject);
}

    return ntStatus;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING win32DeviceName;
int i;

d_n_d_device(DriverObject, g_tcpoldobj, g_tcpfltobj);

if (g_devcontrol != NULL) {
UNICODE_STRING linkname;

RtlInitUnicodeString(&linkname, L\"\\\\Device\\\\TestTdi1\");
IoDeleteSymbolicLink(&linkname);

IoDeleteDevice(g_devcontrol);
}
}

NTSTATUS MajorDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irps;
NTSTATUS status;

// sanity check
if (Irp == NULL) {
KdPrint((\"[Far_tdi] Far_MajorDispatch: !irp\\n\"));
return STATUS_SUCCESS;
}

irps = IoGetCurrentIrpStackLocation(Irp);

if (DeviceObject == g_tcpfltobj )
{//Tcp Filter
// send IRP to original driver
status = Far_PassThrough(g_tcpoldobj, Irp);
}
else if (DeviceObject == g_devcontrol)
{// control object
status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else
{//I have know nothing
status = Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}

return status;
}

//直接传递IRP包到下层
NTSTATUS Far_PassThrough(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

if (Irp->CurrentLocation <= 1)
{
// stay on this location after IoCallDriver
IoSkipCurrentIrpStackLocation(Irp);
}
else
{
IoCopyCurrentIrpStackLocationToNext( Irp );
}
// IoSetCompletionRoutine( Irp,
// Far_GenericCompletion,
// NULL,
// TRUE,
// TRUE,
// TRUE);
return IoCallDriver(DeviceObject,Irp);
}

NTSTATUS
c_n_a_device(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT *fltobj, PDEVICE_OBJECT *oldobj,
wchar_t *devname)
{
NTSTATUS status;
UNICODE_STRING str;

/* create filter device */

status = IoCreateDevice(DriverObject,
0,
NULL,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
fltobj);
if (status != STATUS_SUCCESS) {
KdPrint((\"[Far_tdi] c_n_a_device: IoCreateDevice(%S): 0x%x\\n\", devname, status));
return status;
}

(*fltobj)->Flags |= DO_DIRECT_IO;

RtlInitUnicodeString(&str, devname);

status = IoAttachDevice(*fltobj, &str, oldobj);
if (status != STATUS_SUCCESS) {
KdPrint((\"[Far_tdi] DriverEntry: IoAttachDevice(%S): 0x%x\\n\", devname, status));
return status;
}

KdPrint((\"[Far_tdi] DriverEntry: %S fileobj: 0x%x\\n\", devname, *fltobj));

return STATUS_SUCCESS;
}

void
d_n_d_device(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT oldobj, PDEVICE_OBJECT fltobj)
{
/*
* Detaching of a filter driver at runtime is a high-risk deal
*/

#if 1
// for extremal guys only!
if (oldobj != NULL && fltobj != NULL) {
int i;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction = g_tcpoldobj->DriverObject->MajorFunction;
}
#endif

if (oldobj != NULL)
IoDetachDevice(oldobj);

if (fltobj != NULL)
IoDeleteDevice(fltobj);
}
谢谢关注!
renxianfu
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2016-01-09
  • 粉丝2
  • 关注2
  • 积分48分
  • 威望365点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分1分
5楼#
发布于:2003-09-22 09:32
这两个问题郁闷了我很多天,那位前辈由经验的指点一下
谢谢关注!
renxianfu
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2016-01-09
  • 粉丝2
  • 关注2
  • 积分48分
  • 威望365点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分1分
6楼#
发布于:2003-09-22 18:06
等待ing
谢谢关注!
游客

返回顶部