[try 3] [7/7] ntoskrnl.exe/tests: Add tests for IoInitializeIrp and IoAllocateIrp

Alexander Morozov amorozov at etersoft.ru
Wed Jul 30 03:25:32 CDT 2008


Tests for IoInitializeIrp and IoAllocateIrp.
-------------- next part --------------
From 034bf437bd9de53f4c87319d5ba8f067076b2d56 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov at etersoft.ru>
Date: Tue, 29 Jul 2008 16:28:49 +0400
Subject: [PATCH] ntoskrnl.exe/tests: Add tests for IoInitializeIrp and IoAllocateIrp

---
 dlls/ntoskrnl.exe/tests/driver.c        |  144 +++++++++++++++++++++++++++++++
 dlls/ntoskrnl.exe/tests/ntoskrnl.c      |   27 ++++++
 dlls/ntoskrnl.exe/tests/ntoskrnl_test.h |   22 +++++
 3 files changed, 193 insertions(+), 0 deletions(-)
 create mode 100644 dlls/ntoskrnl.exe/tests/ntoskrnl_test.h

diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 278c8f7..5159556 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -18,20 +18,164 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#ifndef WIN32
+#include "config.h"
+#endif
+
 #include <stdarg.h>
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "winternl.h"
+#include "winioctl.h"
 #include "ddk/ntddk.h"
+#include "ntoskrnl_test.h"
+
+void WINAPI fIoCompleteRequest(IRP *irp, UCHAR priority_boost)
+{
+    #ifdef __i386__
+    __asm__("movl %1,%%edx\n\t"
+            "movl %0,%%ecx\n\t"
+    #ifndef WIN32
+            "call " __ASM_NAME("IofCompleteRequest")
+    #else
+            "call _IofCompleteRequest at 8"
+    #endif
+            : : "g" (irp), "g" (priority_boost));
+    #else
+    IofCompleteRequest(irp, priority_boost);
+    #endif
+}
+
+typedef struct
+{
+    UNICODE_STRING slinkname;
+} devext;
 
 void WINAPI unload(DRIVER_OBJECT *driver)
 {
+    DEVICE_OBJECT *device = driver->DeviceObject;
+
+    if (device)
+    {
+        devext *dx = device->DeviceExtension;
+
+        IoDeleteSymbolicLink(&dx->slinkname);
+        IoDeleteDevice(device);
+    }
+}
+
+NTSTATUS WINAPI complete_request(DEVICE_OBJECT *device, IRP *irp)
+{
+    irp->IoStatus.u.Status = STATUS_SUCCESS;
+    irp->IoStatus.Information = 0;
+    fIoCompleteRequest(irp, IO_NO_INCREMENT);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI device_control(DEVICE_OBJECT *device, IRP *irp)
+{
+    NTSTATUS status = STATUS_UNSUCCESSFUL;
+    ULONG info = 0;
+    IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+    ULONG ioctl_code = irpsp->Parameters.DeviceIoControl.IoControlCode;
+
+    switch (ioctl_code)
+    {
+    case IOCTL_IRPTEST(1):
+    {
+        USHORT size = sizeof(IRP) + 5 * sizeof(IO_STACK_LOCATION);
+        IRP *iorp = ExAllocatePool(NonPagedPool, size);
+
+        if (NULL != iorp)
+        {
+            IoInitializeIrp(iorp, size, 5);
+            if (6 == iorp->Type && iorp->Size == size &&
+                    5 == iorp->StackCount && 6 == iorp->CurrentLocation &&
+                    IsListEmpty(&iorp->ThreadListEntry) &&
+                    (PIO_STACK_LOCATION)(iorp + 1) + 5 ==
+                    iorp->Tail.Overlay.s.u.CurrentStackLocation)
+                status = STATUS_SUCCESS;
+            ExFreePool(iorp);
+        }
+        break;
+    }
+    case IOCTL_IRPTEST(2):
+    {
+        USHORT size = sizeof(IRP) + 2 * sizeof(IO_STACK_LOCATION);
+        IRP *iorp = IoAllocateIrp(2, FALSE);
+
+        if (NULL != iorp)
+        {
+            if (6 == iorp->Type && iorp->Size >= size &&
+                    2 == iorp->StackCount && 3 == iorp->CurrentLocation &&
+                    IsListEmpty(&iorp->ThreadListEntry) &&
+                    (PIO_STACK_LOCATION)(iorp + 1) + 2 ==
+                    iorp->Tail.Overlay.s.u.CurrentStackLocation &&
+                    (IRP_ALLOCATED_FIXED_SIZE & iorp->AllocationFlags) &&
+                    !(IRP_LOOKASIDE_ALLOCATION & iorp->AllocationFlags))
+                status = STATUS_SUCCESS;
+            IoFreeIrp(iorp);
+        }
+        break;
+    }
+    case IOCTL_IRPTEST(3):
+    {
+        USHORT size = sizeof(IRP) + 2 * sizeof(IO_STACK_LOCATION);
+        IRP *iorp = IoAllocateIrp(2, TRUE);
+
+        if (NULL != iorp)
+        {
+            if (6 == iorp->Type && iorp->Size >= size &&
+                    2 == iorp->StackCount && 3 == iorp->CurrentLocation &&
+                    IsListEmpty(&iorp->ThreadListEntry) &&
+                    (PIO_STACK_LOCATION)(iorp + 1) + 2 ==
+                    iorp->Tail.Overlay.s.u.CurrentStackLocation &&
+                    (IRP_ALLOCATED_FIXED_SIZE & iorp->AllocationFlags) &&
+                    (IRP_LOOKASIDE_ALLOCATION & iorp->AllocationFlags))
+                status = STATUS_SUCCESS;
+            IoFreeIrp(iorp);
+        }
+    }
+    }
+
+    irp->IoStatus.u.Status = status;
+    irp->IoStatus.Information = info;
+    fIoCompleteRequest(irp, IO_NO_INCREMENT);
+
+    return status;
 }
 
 NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *regpath)
 {
+    static const WCHAR devnameW[] = {'\\','D','e','v','i','c','e','\\',
+                                     'w','i','n','e','t','e','s','t',0};
+    static const WCHAR slinknameW[] = {'\\','D','o','s','D','e','v','i','c','e','s',
+                                       '\\','w','i','n','e','t','e','s','t',0};
+    UNICODE_STRING devname;
+    NTSTATUS status;
+    DEVICE_OBJECT *device;
+    devext *dx;
+
     driver->DriverUnload = unload;
+    driver->MajorFunction[IRP_MJ_CREATE] = complete_request;
+    driver->MajorFunction[IRP_MJ_CLOSE] = complete_request;
+    driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = device_control;
+    driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = device_control;
+
+    RtlInitUnicodeString(&devname, devnameW);
+    status = IoCreateDevice(driver, sizeof(devext), &devname,
+            FILE_DEVICE_UNKNOWN, 0, FALSE, &device);
+    if (STATUS_SUCCESS != status)
+        return status;
+    dx = device->DeviceExtension;
+    RtlInitUnicodeString(&dx->slinkname, slinknameW);
+    IoCreateSymbolicLink(&dx->slinkname, &devname);
+    device->Flags &= ~DO_DEVICE_INITIALIZING;
 
     return STATUS_SUCCESS;
 }
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 808b2cd..8ba3a29 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -19,7 +19,9 @@
  */
 
 #include "windows.h"
+#include "winioctl.h"
 #include "wine/test.h"
+#include "ntoskrnl_test.h"
 #include "rc.h"
 
 #define DRVNAME "winetest"
@@ -118,6 +120,30 @@ static void stop_service(SC_HANDLE scm)
     CloseServiceHandle(service);
 }
 
+static void irp_test(void)
+{
+    HANDLE hfile;
+    BOOL ret;
+    ULONG k;
+    DWORD bytes;
+
+    SetLastError(0xdeadbeef);
+    hfile = CreateFileA("\\\\.\\" DRVNAME, GENERIC_READ | GENERIC_WRITE,
+            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+            FILE_ATTRIBUTE_NORMAL, NULL);
+    ok(INVALID_HANDLE_VALUE != hfile, "CreateFileA failed: %u\n", GetLastError());
+
+    for (k = 1; k <= 3; ++k)
+    {
+        SetLastError(0xdeadbeef);
+        ret = DeviceIoControl(hfile, IOCTL_IRPTEST(k), NULL, 0, NULL, 0, &bytes, NULL);
+        todo_wine
+        ok(ret, "IRP test %u failed\n", k);
+    }
+
+    CloseHandle(hfile);
+}
+
 START_TEST(ntoskrnl)
 {
     CHAR destpath[MAX_PATH + 1];
@@ -139,6 +165,7 @@ START_TEST(ntoskrnl)
 
     create_service(scm);
     start_service(scm);
+    irp_test();
     stop_service(scm);
     delete_service(scm);
 
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl_test.h b/dlls/ntoskrnl.exe/tests/ntoskrnl_test.h
new file mode 100644
index 0000000..ff427ee
--- /dev/null
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl_test.h
@@ -0,0 +1,22 @@
+/*
+ * Tests for ntoskrnl.exe
+ *
+ * Copyright 2008 Etersoft (Alexander Morozov)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define IOCTL_IRPTEST(n) CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80f + n, \
+        METHOD_NEITHER, FILE_ANY_ACCESS)
-- 
1.5.4.5.GIT



More information about the wine-patches mailing list