[Wine-devel] ntoskrnl.exe: Improve IofCompleteRequest and IofCallDriver
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Чт Июл 24 13:16:37 MSD 2008
В результате написания тестов оказалось, что реализованное в eterhack поведение достаточно плохо соответствует поведению Windows. Изменил IofCompleteRequest и IofCallDriver, чтобы они соответствовали тестам.
----------- следующая часть -----------
From 37c5d66d9d83ba5ef96422d95809e83d9e58c641 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 23 Jul 2008 13:32:01 +0400
Subject: [PATCH] ntoskrnl.exe: Improve IofCompleteRequest and IofCallDriver
---
dlls/ntoskrnl.exe/ntoskrnl.c | 74 ++++++++++++++++++++---------------------
1 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 0dc8be3..0d3e360 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -621,8 +621,6 @@ NTSTATUS WINAPI IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
dispatch = device->DriverObject->MajorFunction[irpsp->MajorFunction];
status = dispatch( device, irp );
- ++irp->CurrentLocation;
- ++irp->Tail.Overlay.s.u.CurrentStackLocation;
return status;
}
@@ -640,53 +638,53 @@ void WINAPI IofCompleteRequest( IRP *irp, UCHAR priority_boost )
{
IO_STACK_LOCATION *irpsp;
PIO_COMPLETION_ROUTINE routine;
+ IO_STATUS_BLOCK *iosb;
+ struct IrpInstance *instance;
+ NTSTATUS status, stat;
+ int call_flag = 0;
TRACE( "%p %u\n", irp, priority_boost );
- irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
- routine = irpsp->CompletionRoutine;
- /* FIXME: check other stack locations */
- if (routine)
+ iosb = irp->UserIosb;
+ status = irp->IoStatus.u.Status;
+ while (irp->CurrentLocation <= irp->StackCount)
{
- NTSTATUS status;
- int call_flag = 0;
-
- switch (irp->IoStatus.u.Status)
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+ routine = irpsp->CompletionRoutine;
+ call_flag = 0;
+ /* FIXME: add SL_INVOKE_ON_CANCEL support */
+ if (routine)
{
- case STATUS_SUCCESS:
- if (irpsp->Control & SL_INVOKE_ON_SUCCESS)
+ if ((irpsp->Control & SL_INVOKE_ON_SUCCESS) && STATUS_SUCCESS == status)
call_flag = 1;
- break;
- case STATUS_CANCELLED:
- if (irpsp->Control & SL_INVOKE_ON_CANCEL)
- call_flag = 1;
- break;
- default:
- if (irpsp->Control & SL_INVOKE_ON_ERROR)
+ if ((irpsp->Control & SL_INVOKE_ON_ERROR) && STATUS_SUCCESS != status)
call_flag = 1;
}
-
+ ++irp->CurrentLocation;
+ ++irp->Tail.Overlay.s.u.CurrentStackLocation;
if (call_flag)
{
- TRACE( "calling %p( %p, %p, %p )\n", routine, irpsp->DeviceObject,
- irp, irpsp->Context );
- status = routine( irpsp->DeviceObject, irp, irpsp->Context );
+ TRACE( "calling %p( %p, %p, %p )\n", routine,
+ irpsp->DeviceObject, irp, irpsp->Context );
+ stat = routine( irpsp->DeviceObject, irp, irpsp->Context );
TRACE( "CompletionRoutine returned %x\n", status );
- if (status != STATUS_MORE_PROCESSING_REQUIRED)
- {
- struct IrpInstance *instance;
-
- LIST_FOR_EACH_ENTRY( instance, &Irps, struct IrpInstance, entry )
- {
- if (instance->irp == irp)
- {
- list_remove( &instance->entry );
- HeapFree( GetProcessHeap(), 0, instance );
- IoFreeIrp( irp );
- break;
- }
- }
- }
+ if (STATUS_MORE_PROCESSING_REQUIRED == stat)
+ return;
+ }
+ }
+ if (iosb && STATUS_SUCCESS == status)
+ {
+ iosb->u.Status = irp->IoStatus.u.Status;
+ iosb->Information = irp->IoStatus.Information;
+ }
+ LIST_FOR_EACH_ENTRY( instance, &Irps, struct IrpInstance, entry )
+ {
+ if (instance->irp == irp)
+ {
+ list_remove( &instance->entry );
+ HeapFree( GetProcessHeap(), 0, instance );
+ IoFreeIrp( irp );
+ break;
}
}
}
--
1.5.4.5.GIT
Подробная информация о списке рассылки Wine-devel