Commit 7845c011 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

ntoskrnl.exe/tests: Add some tests for file objects.

parent 2ddb6b66
...@@ -209,6 +209,7 @@ static void *get_proc_address(const char *name) ...@@ -209,6 +209,7 @@ static void *get_proc_address(const char *name)
} }
static FILE_OBJECT *last_created_file; static FILE_OBJECT *last_created_file;
static unsigned int create_count, close_count;
static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device) static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device)
{ {
...@@ -1631,7 +1632,7 @@ static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR * ...@@ -1631,7 +1632,7 @@ static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS get_cancel_count(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) static NTSTATUS get_dword(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info, DWORD value)
{ {
ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength; ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
char *buffer = irp->AssociatedIrp.SystemBuffer; char *buffer = irp->AssociatedIrp.SystemBuffer;
...@@ -1642,7 +1643,24 @@ static NTSTATUS get_cancel_count(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR * ...@@ -1642,7 +1643,24 @@ static NTSTATUS get_cancel_count(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *
if (length < sizeof(DWORD)) if (length < sizeof(DWORD))
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
*(DWORD*)buffer = cancel_cnt; *(DWORD*)buffer = value;
*info = sizeof(DWORD);
return STATUS_SUCCESS;
}
static NTSTATUS get_fscontext(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
{
ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
char *buffer = irp->AssociatedIrp.SystemBuffer;
DWORD *context = stack->FileObject->FsContext;
if (!buffer || !context)
return STATUS_ACCESS_VIOLATION;
if (length < sizeof(DWORD))
return STATUS_BUFFER_TOO_SMALL;
*(DWORD*)buffer = *context;
*info = sizeof(DWORD); *info = sizeof(DWORD);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
...@@ -1667,8 +1685,13 @@ static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG ...@@ -1667,8 +1685,13 @@ static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG
static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp) static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp)
{ {
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
DWORD *context = ExAllocatePool(PagedPool, sizeof(*context));
last_created_file = irpsp->FileObject; last_created_file = irpsp->FileObject;
++create_count;
if (context)
*context = create_count;
irpsp->FileObject->FsContext = context;
create_caller_thread = KeGetCurrentThread(); create_caller_thread = KeGetCurrentThread();
irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Status = STATUS_SUCCESS;
...@@ -1701,7 +1724,16 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp) ...@@ -1701,7 +1724,16 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
IoMarkIrpPending(irp); IoMarkIrpPending(irp);
return STATUS_PENDING; return STATUS_PENDING;
case IOCTL_WINETEST_GET_CANCEL_COUNT: case IOCTL_WINETEST_GET_CANCEL_COUNT:
status = get_cancel_count(irp, stack, &irp->IoStatus.Information); status = get_dword(irp, stack, &irp->IoStatus.Information, cancel_cnt);
break;
case IOCTL_WINETEST_GET_CREATE_COUNT:
status = get_dword(irp, stack, &irp->IoStatus.Information, create_count);
break;
case IOCTL_WINETEST_GET_CLOSE_COUNT:
status = get_dword(irp, stack, &irp->IoStatus.Information, close_count);
break;
case IOCTL_WINETEST_GET_FSCONTEXT:
status = get_fscontext(irp, stack, &irp->IoStatus.Information);
break; break;
case IOCTL_WINETEST_DETACH: case IOCTL_WINETEST_DETACH:
IoDetachDevice(lower_device); IoDetachDevice(lower_device);
...@@ -1733,6 +1765,10 @@ static NTSTATUS WINAPI driver_FlushBuffers(DEVICE_OBJECT *device, IRP *irp) ...@@ -1733,6 +1765,10 @@ static NTSTATUS WINAPI driver_FlushBuffers(DEVICE_OBJECT *device, IRP *irp)
static NTSTATUS WINAPI driver_Close(DEVICE_OBJECT *device, IRP *irp) static NTSTATUS WINAPI driver_Close(DEVICE_OBJECT *device, IRP *irp)
{ {
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
++close_count;
if (stack->FileObject->FsContext)
ExFreePool(stack->FileObject->FsContext);
irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(irp, IO_NO_INCREMENT); IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#define IOCTL_WINETEST_TEST_CANCEL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_TEST_CANCEL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_GET_CANCEL_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_GET_CANCEL_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_DETACH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_DETACH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_GET_CREATE_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_GET_CLOSE_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_GET_FSCONTEXT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
static const char teststr[] = "Wine is not an emulator"; static const char teststr[] = "Wine is not an emulator";
......
...@@ -318,6 +318,76 @@ static void test_load_driver(SC_HANDLE service) ...@@ -318,6 +318,76 @@ static void test_load_driver(SC_HANDLE service)
ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState); ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
} }
static void test_file_handles(void)
{
DWORD count, ret_size;
HANDLE file, dup, file2;
BOOL ret;
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 2, "got %u\n", count);
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 1, "got %u\n", count);
file = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 3, "got %u\n", count);
file2 = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
ok(file2 != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 4, "got %u\n", count);
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
ok(ret, "failed to duplicate handle: %u\n", GetLastError());
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 4, "got %u\n", count);
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 1, "got %u\n", count);
ret = DeviceIoControl(file, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 3, "got %u\n", count);
ret = DeviceIoControl(file2, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 4, "got %u\n", count);
ret = DeviceIoControl(dup, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 3, "got %u\n", count);
CloseHandle(dup);
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 1, "got %u\n", count);
CloseHandle(file2);
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 2, "got %u\n", count);
CloseHandle(file);
ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
ok(ret, "ioctl failed: %u\n", GetLastError());
ok(count == 3, "got %u\n", count);
}
static void test_driver3(void) static void test_driver3(void)
{ {
char filename[MAX_PATH]; char filename[MAX_PATH];
...@@ -369,6 +439,7 @@ START_TEST(ntoskrnl) ...@@ -369,6 +439,7 @@ START_TEST(ntoskrnl)
main_test(); main_test();
test_overlapped(); test_overlapped();
test_load_driver(service2); test_load_driver(service2);
test_file_handles();
/* We need a separate ioctl to call IoDetachDevice(); calling it in the /* We need a separate ioctl to call IoDetachDevice(); calling it in the
* driver unload routine causes a live-lock. */ * driver unload routine causes a live-lock. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment