[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