6432fdf6e706aaafc73ef4fca78c8ee2854e70be
[reactos.git] / rostests / kmtests / kernel32 / kernel32_drv.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test driver for kernel32 filesystem tests
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #include "kernel32_test.h"
14
15 static KMT_MESSAGE_HANDLER TestMessageHandler;
16 static KMT_IRP_HANDLER TestDirectoryControl;
17 static KMT_IRP_HANDLER TestQueryInformation;
18 static KMT_IRP_HANDLER TestSetInformation;
19
20 static UNICODE_STRING ExpectedExpression = RTL_CONSTANT_STRING(L"<not set>");
21 static WCHAR ExpressionBuffer[MAX_PATH];
22 static ULONG ExpectedSetAttributes = -1;
23 static ULONG ReturnQueryAttributes = -1;
24
25 NTSTATUS
26 TestEntry(
27 IN PDRIVER_OBJECT DriverObject,
28 IN PCUNICODE_STRING RegistryPath,
29 OUT PCWSTR *DeviceName,
30 IN OUT INT *Flags)
31 {
32 NTSTATUS Status = STATUS_SUCCESS;
33
34 PAGED_CODE();
35
36 UNREFERENCED_PARAMETER(RegistryPath);
37
38 *DeviceName = L"kernel32";
39 *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE;
40
41 KmtRegisterIrpHandler(IRP_MJ_DIRECTORY_CONTROL, NULL, TestDirectoryControl);
42 KmtRegisterIrpHandler(IRP_MJ_QUERY_INFORMATION, NULL, TestQueryInformation);
43 KmtRegisterIrpHandler(IRP_MJ_SET_INFORMATION, NULL, TestSetInformation);
44 KmtRegisterMessageHandler(0, NULL, TestMessageHandler);
45
46 return Status;
47 }
48
49 VOID
50 TestUnload(
51 IN PDRIVER_OBJECT DriverObject)
52 {
53 PAGED_CODE();
54 }
55
56 static
57 NTSTATUS
58 TestMessageHandler(
59 IN PDEVICE_OBJECT DeviceObject,
60 IN ULONG ControlCode,
61 IN PVOID Buffer OPTIONAL,
62 IN SIZE_T InLength,
63 IN OUT PSIZE_T OutLength)
64 {
65 NTSTATUS Status = STATUS_SUCCESS;
66
67 PAGED_CODE();
68
69 switch (ControlCode)
70 {
71 case IOCTL_EXPECT_EXPRESSION:
72 {
73 C_ASSERT(sizeof(ExpressionBuffer) <= UNICODE_STRING_MAX_BYTES);
74 DPRINT("IOCTL_EXPECT_EXPRESSION, InLength = %lu\n", InLength);
75 if (InLength > sizeof(ExpressionBuffer))
76 return STATUS_BUFFER_OVERFLOW;
77
78 if (InLength % sizeof(WCHAR) != 0)
79 return STATUS_INVALID_PARAMETER;
80
81 RtlInitEmptyUnicodeString(&ExpectedExpression, ExpressionBuffer, sizeof(ExpressionBuffer));
82 RtlCopyMemory(ExpressionBuffer, Buffer, InLength);
83 ExpectedExpression.Length = (USHORT)InLength;
84 DPRINT("IOCTL_EXPECT_EXPRESSION: %wZ\n", &ExpectedExpression);
85
86 break;
87 }
88 case IOCTL_RETURN_QUERY_ATTRIBUTES:
89 {
90 DPRINT("IOCTL_RETURN_QUERY_ATTRIBUTES, InLength = %lu\n", InLength);
91 if (InLength != sizeof(ULONG))
92 return STATUS_INVALID_PARAMETER;
93
94 ReturnQueryAttributes = *(PULONG)Buffer;
95 DPRINT("IOCTL_RETURN_QUERY_ATTRIBUTES: %lu\n", ReturnQueryAttributes);
96 break;
97 }
98 case IOCTL_EXPECT_SET_ATTRIBUTES:
99 {
100 DPRINT("IOCTL_EXPECT_SET_ATTRIBUTES, InLength = %lu\n", InLength);
101 if (InLength != sizeof(ULONG))
102 return STATUS_INVALID_PARAMETER;
103
104 ExpectedSetAttributes = *(PULONG)Buffer;
105 DPRINT("IOCTL_EXPECT_SET_ATTRIBUTES: %lu\n", ExpectedSetAttributes);
106 break;
107 }
108 default:
109 return STATUS_NOT_SUPPORTED;
110 }
111
112 return Status;
113 }
114
115 static
116 NTSTATUS
117 TestDirectoryControl(
118 IN PDEVICE_OBJECT DeviceObject,
119 IN PIRP Irp,
120 IN PIO_STACK_LOCATION IoStackLocation)
121 {
122 NTSTATUS Status = STATUS_NOT_SUPPORTED;
123
124 PAGED_CODE();
125
126 DPRINT("IRP %x/%x\n", IoStackLocation->MajorFunction, IoStackLocation->MinorFunction);
127 ASSERT(IoStackLocation->MajorFunction == IRP_MJ_DIRECTORY_CONTROL);
128
129 ok(IoStackLocation->MinorFunction == IRP_MN_QUERY_DIRECTORY, "Minor function: %u\n", IoStackLocation->MinorFunction);
130 if (IoStackLocation->MinorFunction == IRP_MN_QUERY_DIRECTORY)
131 {
132 ok(IoStackLocation->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation,
133 "FileInformationClass: %d\n", IoStackLocation->Parameters.QueryDirectory.FileInformationClass);
134 if (IoStackLocation->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation)
135 {
136 ok(RtlEqualUnicodeString(IoStackLocation->Parameters.QueryDirectory.FileName, &ExpectedExpression, FALSE),
137 "Expression is '%wZ', expected '%wZ'\n", IoStackLocation->Parameters.QueryDirectory.FileName, &ExpectedExpression);
138 RtlZeroMemory(Irp->UserBuffer, IoStackLocation->Parameters.QueryDirectory.Length);
139 Status = STATUS_SUCCESS;
140 }
141 }
142
143 Irp->IoStatus.Status = Status;
144 Irp->IoStatus.Information = 0;
145
146 IoCompleteRequest(Irp, IO_NO_INCREMENT);
147
148 return Status;
149 }
150
151 static
152 NTSTATUS
153 TestQueryInformation(
154 IN PDEVICE_OBJECT DeviceObject,
155 IN PIRP Irp,
156 IN PIO_STACK_LOCATION IoStackLocation)
157 {
158 NTSTATUS Status = STATUS_NOT_SUPPORTED;
159 PFILE_BASIC_INFORMATION BasicInfo;
160
161 PAGED_CODE();
162
163 DPRINT("IRP %x/%x\n", IoStackLocation->MajorFunction, IoStackLocation->MinorFunction);
164 ASSERT(IoStackLocation->MajorFunction == IRP_MJ_QUERY_INFORMATION);
165
166 Irp->IoStatus.Information = 0;
167
168 ok_eq_ulong(IoStackLocation->Parameters.QueryFile.FileInformationClass, FileBasicInformation);
169 if (IoStackLocation->Parameters.QueryFile.FileInformationClass == FileBasicInformation)
170 {
171 ok(ReturnQueryAttributes != (ULONG)-1, "Unexpected QUERY_INFORMATION call\n");
172 BasicInfo = Irp->AssociatedIrp.SystemBuffer;
173 BasicInfo->CreationTime.QuadPart = 126011664000000000;
174 BasicInfo->LastAccessTime.QuadPart = 130899112800000000;
175 BasicInfo->LastWriteTime.QuadPart = 130899112800000000;
176 BasicInfo->ChangeTime.QuadPart = 130899112800000000;
177 BasicInfo->FileAttributes = ReturnQueryAttributes;
178 ReturnQueryAttributes = -1;
179 Status = STATUS_SUCCESS;
180 Irp->IoStatus.Information = sizeof(*BasicInfo);
181 }
182
183 Irp->IoStatus.Status = Status;
184
185 IoCompleteRequest(Irp, IO_NO_INCREMENT);
186
187 return Status;
188 }
189
190 static
191 NTSTATUS
192 TestSetInformation(
193 IN PDEVICE_OBJECT DeviceObject,
194 IN PIRP Irp,
195 IN PIO_STACK_LOCATION IoStackLocation)
196 {
197 NTSTATUS Status = STATUS_NOT_SUPPORTED;
198 PFILE_BASIC_INFORMATION BasicInfo;
199
200 PAGED_CODE();
201
202 DPRINT("IRP %x/%x\n", IoStackLocation->MajorFunction, IoStackLocation->MinorFunction);
203 ASSERT(IoStackLocation->MajorFunction == IRP_MJ_SET_INFORMATION);
204
205 ok_eq_ulong(IoStackLocation->Parameters.SetFile.FileInformationClass, FileBasicInformation);
206 if (IoStackLocation->Parameters.SetFile.FileInformationClass == FileBasicInformation)
207 {
208 ok(ExpectedSetAttributes != (ULONG)-1, "Unexpected SET_INFORMATION call\n");
209 BasicInfo = Irp->AssociatedIrp.SystemBuffer;
210 ok_eq_longlong(BasicInfo->CreationTime.QuadPart, 0LL);
211 ok_eq_longlong(BasicInfo->LastAccessTime.QuadPart, 0LL);
212 ok_eq_longlong(BasicInfo->LastWriteTime.QuadPart, 0LL);
213 ok_eq_longlong(BasicInfo->ChangeTime.QuadPart, 0LL);
214 ok_eq_ulong(BasicInfo->FileAttributes, ExpectedSetAttributes);
215 ExpectedSetAttributes = -1;
216 Status = STATUS_SUCCESS;
217 }
218
219 Irp->IoStatus.Status = Status;
220 Irp->IoStatus.Information = 0;
221
222 IoCompleteRequest(Irp, IO_NO_INCREMENT);
223
224 return Status;
225 }