[4/9] ntoskrnl.exe: Implement some functions.
Alexander Morozov
amorozov at etersoft.ru
Mon Oct 6 02:20:31 CDT 2008
-------------- next part --------------
From 890bad8c0aeaaf789add06085048ee0b1dfc8830 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov at etersoft.ru>
Date: Fri, 3 Oct 2008 17:51:26 +0400
Subject: [PATCH] ntoskrnl.exe: Implement some functions.
---
dlls/ntoskrnl.exe/ntoskrnl.c | 179 ++++++++++++++++++++++++++++++++++-
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 6 +-
2 files changed, 177 insertions(+), 8 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 1751233..9af2f16 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -34,6 +34,7 @@
#include "ddk/ntddk.h"
#include "wine/unicode.h"
#include "wine/server.h"
+#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
@@ -54,6 +55,14 @@ KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4] = { { 0 } };
typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
+static struct list Irps = LIST_INIT(Irps);
+
+struct IrpInstance
+{
+ struct list entry;
+ IRP *irp;
+};
+
#ifdef __i386__
#define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
__ASM_GLOBAL_FUNC( name, \
@@ -253,7 +262,17 @@ NTSTATUS wine_ntoskrnl_main_loop( HANDLE stop_event )
*/
void WINAPI IoInitializeIrp( IRP *irp, USHORT size, CCHAR stack_size )
{
- FIXME( "%p, %u, %d\n", irp, size, stack_size );
+ TRACE( "%p, %u, %d\n", irp, size, stack_size );
+
+ RtlZeroMemory( irp, size );
+
+ irp->Type = IO_TYPE_IRP;
+ irp->Size = size;
+ InitializeListHead( &irp->ThreadListEntry );
+ irp->StackCount = stack_size;
+ irp->CurrentLocation = stack_size + 1;
+ irp->Tail.Overlay.s.u.CurrentStackLocation =
+ (PIO_STACK_LOCATION)(irp + 1) + stack_size;
}
@@ -262,8 +281,20 @@ void WINAPI IoInitializeIrp( IRP *irp, USHORT size, CCHAR stack_size )
*/
PIRP WINAPI IoAllocateIrp( CCHAR stack_size, BOOLEAN charge_quota )
{
- FIXME( "%d, %d\n", stack_size, charge_quota );
- return NULL;
+ SIZE_T size;
+ PIRP irp;
+
+ TRACE( "%d, %d\n", stack_size, charge_quota );
+
+ size = sizeof(IRP) + stack_size * sizeof(IO_STACK_LOCATION);
+ irp = ExAllocatePool( NonPagedPool, size );
+ if (irp != NULL)
+ IoInitializeIrp( irp, size, stack_size );
+ irp->AllocationFlags = IRP_ALLOCATED_FIXED_SIZE;
+ if (charge_quota)
+ irp->AllocationFlags |= IRP_LOOKASIDE_ALLOCATION;
+
+ return irp;
}
@@ -272,7 +303,9 @@ PIRP WINAPI IoAllocateIrp( CCHAR stack_size, BOOLEAN charge_quota )
*/
void WINAPI IoFreeIrp( IRP *irp )
{
- FIXME( "%p\n", irp );
+ TRACE( "%p\n", irp );
+
+ ExFreePool( irp );
}
@@ -297,6 +330,68 @@ PIO_WORKITEM WINAPI IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject )
/***********************************************************************
+ * IoAttachDeviceToDeviceStack (NTOSKRNL.EXE.@)
+ */
+PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
+ DEVICE_OBJECT *target )
+{
+ TRACE( "%p, %p\n", source, target );
+ target->AttachedDevice = source;
+ source->StackSize = target->StackSize + 1;
+ return target;
+}
+
+
+/***********************************************************************
+ * IoBuildDeviceIoControlRequest (NTOSKRNL.EXE.@)
+ */
+PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
+ PDEVICE_OBJECT DeviceObject,
+ PVOID InputBuffer,
+ ULONG InputBufferLength,
+ PVOID OutputBuffer,
+ ULONG OutputBufferLength,
+ BOOLEAN InternalDeviceIoControl,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK IoStatusBlock )
+{
+ PIRP irp;
+ PIO_STACK_LOCATION irpsp;
+ struct IrpInstance *instance;
+
+ TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
+ IoControlCode, DeviceObject, InputBuffer, InputBufferLength,
+ OutputBuffer, OutputBufferLength, InternalDeviceIoControl,
+ Event, IoStatusBlock );
+
+ if (DeviceObject == NULL)
+ return NULL;
+
+ irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
+ if (irp == NULL)
+ return NULL;
+
+ instance = HeapAlloc( GetProcessHeap(), 0, sizeof(struct IrpInstance) );
+ if (instance == NULL)
+ {
+ IoFreeIrp( irp );
+ return NULL;
+ }
+ instance->irp = irp;
+ list_add_tail( &Irps, &instance->entry );
+
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation - 1;
+ irpsp->MajorFunction = InternalDeviceIoControl ?
+ IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
+ irpsp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+ irp->UserIosb = IoStatusBlock;
+ irp->UserEvent = Event;
+
+ return irp;
+}
+
+
+/***********************************************************************
* IoCreateDriver (NTOSKRNL.EXE.@)
*/
NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
@@ -462,6 +557,31 @@ NTSTATUS WINAPI IoGetDeviceObjectPointer( UNICODE_STRING *name, ACCESS_MASK acc
/***********************************************************************
+ * IofCallDriver (NTOSKRNL.EXE.@)
+ */
+#ifdef DEFINE_FASTCALL2_ENTRYPOINT
+DEFINE_FASTCALL2_ENTRYPOINT( IofCallDriver )
+NTSTATUS WINAPI __regs_IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
+#else
+NTSTATUS WINAPI IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
+#endif
+{
+ PDRIVER_DISPATCH dispatch;
+ IO_STACK_LOCATION *irpsp;
+ NTSTATUS status;
+
+ TRACE( "%p %p\n", device, irp );
+
+ --irp->CurrentLocation;
+ irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
+ dispatch = device->DriverObject->MajorFunction[irpsp->MajorFunction];
+ status = dispatch( device, irp );
+
+ return status;
+}
+
+
+/***********************************************************************
* IoGetRelatedDeviceObject (NTOSKRNL.EXE.@)
*/
PDEVICE_OBJECT WINAPI IoGetRelatedDeviceObject( PFILE_OBJECT obj )
@@ -512,8 +632,57 @@ void WINAPI __regs_IofCompleteRequest( IRP *irp, UCHAR priority_boost )
void WINAPI IofCompleteRequest( IRP *irp, UCHAR priority_boost )
#endif
{
+ 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 );
- /* nothing to do for now */
+
+ iosb = irp->UserIosb;
+ status = irp->IoStatus.u.Status;
+ while (irp->CurrentLocation <= irp->StackCount)
+ {
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+ routine = irpsp->CompletionRoutine;
+ call_flag = 0;
+ /* FIXME: add SL_INVOKE_ON_CANCEL support */
+ if (routine)
+ {
+ if ((irpsp->Control & SL_INVOKE_ON_SUCCESS) && STATUS_SUCCESS == status)
+ call_flag = 1;
+ 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 );
+ stat = routine( irpsp->DeviceObject, irp, irpsp->Context );
+ TRACE( "CompletionRoutine returned %x\n", status );
+ 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;
+ }
+ }
}
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index bdd1537..7d543d4 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -39,7 +39,7 @@
@ stub IoReadPartitionTable
@ stub IoSetPartitionInformation
@ stub IoWritePartitionTable
-@ stub IofCallDriver
+@ stdcall -norelay IofCallDriver(ptr ptr)
@ stdcall -norelay IofCompleteRequest(ptr long)
@ stub KeAcquireInStackQueuedSpinLockAtDpcLevel
@ stub KeReleaseInStackQueuedSpinLockFromDpcLevel
@@ -317,10 +317,10 @@
@ stub IoAssignResources
@ stub IoAttachDevice
@ stub IoAttachDeviceByPointer
-@ stub IoAttachDeviceToDeviceStack
+@ stdcall IoAttachDeviceToDeviceStack(ptr ptr)
@ stub IoAttachDeviceToDeviceStackSafe
@ stub IoBuildAsynchronousFsdRequest
-@ stub IoBuildDeviceIoControlRequest
+@ stdcall IoBuildDeviceIoControlRequest(long ptr ptr long ptr long long ptr ptr)
@ stub IoBuildPartialMdl
@ stub IoBuildSynchronousFsdRequest
@ stub IoCallDriver
--
1.5.6.5.GIT
More information about the wine-patches
mailing list