2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Device Interface functions test
5 * PROGRAMMER: Filip Navara <xnavara@volny.cz>
8 /* TODO: what's with the prototypes at the top, what's with the if-ed out part? Doesn't process most results */
18 (NTAPI
*IoGetDeviceInterfaces_Func
)(
19 IN CONST GUID
*InterfaceClassGuid
,
20 IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL
,
22 OUT PWSTR
*SymbolicLinkList
);
25 ReactOS_IoGetDeviceInterfaces(
26 IN CONST GUID
*InterfaceClassGuid
,
27 IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL
,
29 OUT PWSTR
*SymbolicLinkList
);
32 static VOID
DeviceInterfaceTest_Func()
35 PWSTR SymbolicLinkList
;
36 PWSTR SymbolicLinkListPtr
;
37 GUID Guid
= {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
39 Status
= IoGetDeviceInterfaces(
45 ok(NT_SUCCESS(Status
),
46 "IoGetDeviceInterfaces failed with status 0x%X\n",
47 (unsigned int)Status
);
48 if (!NT_SUCCESS(Status
))
53 DPRINT("IoGetDeviceInterfaces results:\n");
54 for (SymbolicLinkListPtr
= SymbolicLinkList
;
55 SymbolicLinkListPtr
[0] != 0 && SymbolicLinkListPtr
[1] != 0;
56 SymbolicLinkListPtr
+= wcslen(SymbolicLinkListPtr
) + 1)
58 DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr
);
62 DPRINT("[PnP Test] Trying to get aliases\n");
64 for (SymbolicLinkListPtr
= SymbolicLinkList
;
65 SymbolicLinkListPtr
[0] != 0 && SymbolicLinkListPtr
[1] != 0;
66 SymbolicLinkListPtr
+= wcslen(SymbolicLinkListPtr
) + 1)
68 UNICODE_STRING SymbolicLink
;
69 UNICODE_STRING AliasSymbolicLink
;
71 SymbolicLink
.Buffer
= SymbolicLinkListPtr
;
72 SymbolicLink
.Length
= SymbolicLink
.MaximumLength
= wcslen(SymbolicLinkListPtr
);
73 RtlInitUnicodeString(&AliasSymbolicLink
, NULL
);
74 IoGetDeviceInterfaceAlias(
78 if (AliasSymbolicLink
.Buffer
!= NULL
)
80 DPRINT("[PnP Test] Original: %S\n", SymbolicLinkListPtr
);
81 DPRINT("[PnP Test] Alias: %S\n", AliasSymbolicLink
.Buffer
);
86 ExFreePool(SymbolicLinkList
);
91 Test_IoRegisterDeviceInterface(VOID
)
93 GUID Guid
= {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
94 DEVICE_OBJECT DeviceObject
;
95 EXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension
;
96 DEVICE_NODE DeviceNode
;
97 UNICODE_STRING SymbolicLinkName
;
100 RtlInitUnicodeString(&SymbolicLinkName
, L
"");
102 // Prepare our surrogate of a Device Object
103 DeviceObject
.DeviceObjectExtension
= (PDEVOBJ_EXTENSION
)&DeviceObjectExtension
;
105 // 1. DeviceNode = NULL
106 DeviceObjectExtension
.DeviceNode
= NULL
;
107 Status
= IoRegisterDeviceInterface(&DeviceObject
, &Guid
, NULL
,
110 ok(Status
== STATUS_INVALID_DEVICE_REQUEST
,
111 "IoRegisterDeviceInterface returned 0x%08lX\n", Status
);
113 // 2. DeviceNode->InstancePath is of a null length
114 DeviceObjectExtension
.DeviceNode
= &DeviceNode
;
115 DeviceNode
.InstancePath
.Length
= 0;
116 Status
= IoRegisterDeviceInterface(&DeviceObject
, &Guid
, NULL
,
119 ok(Status
== STATUS_INVALID_DEVICE_REQUEST
,
120 "IoRegisterDeviceInterface returned 0x%08lX\n", Status
);
122 DeviceInterfaceTest_Func();
125 static UCHAR NotificationContext
;
127 static DRIVER_NOTIFICATION_CALLBACK_ROUTINE NotificationCallback
;
131 NotificationCallback(
132 _In_ PVOID NotificationStructure
,
133 _Inout_opt_ PVOID Context
)
135 PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification
= NotificationStructure
;
137 OBJECT_ATTRIBUTES ObjectAttributes
;
140 ok_irql(PASSIVE_LEVEL
);
141 ok_eq_pointer(Context
, &NotificationContext
);
142 ok_eq_uint(Notification
->Version
, 1);
143 ok_eq_uint(Notification
->Size
, sizeof(*Notification
));
145 /* symbolic link must exist */
146 trace("Interface change: %wZ\n", Notification
->SymbolicLinkName
);
147 InitializeObjectAttributes(&ObjectAttributes
,
148 Notification
->SymbolicLinkName
,
152 Status
= ZwOpenSymbolicLinkObject(&Handle
, GENERIC_READ
, &ObjectAttributes
);
153 ok_eq_hex(Status
, STATUS_SUCCESS
);
154 if (!skip(NT_SUCCESS(Status
), "No symbolic link\n"))
156 Status
= ObCloseHandle(Handle
, KernelMode
);
157 ok_eq_hex(Status
, STATUS_SUCCESS
);
159 return STATUS_SUCCESS
;
164 Test_IoRegisterPlugPlayNotification(VOID
)
167 PVOID NotificationEntry
;
169 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
170 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
171 (PVOID
)&GUID_DEVICE_SYS_BUTTON
,
173 NotificationCallback
,
174 &NotificationContext
,
176 ok_eq_hex(Status
, STATUS_SUCCESS
);
177 if (!skip(NT_SUCCESS(Status
), "PlugPlayNotification not registered\n"))
179 Status
= IoUnregisterPlugPlayNotification(NotificationEntry
);
180 ok_eq_hex(Status
, STATUS_SUCCESS
);
186 Test_IoSetDeviceInterface(VOID
)
189 UNICODE_STRING SymbolicLinkName
;
193 /* Invalid prefix or GUID */
195 Status
= IoSetDeviceInterfaceState(NULL
, TRUE
);
196 KmtEndSeh(STATUS_SUCCESS
)
197 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
199 RtlInitEmptyUnicodeString(&SymbolicLinkName
, NULL
, 0);
201 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
202 KmtEndSeh(STATUS_SUCCESS
)
203 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
205 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??");
207 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
208 KmtEndSeh(STATUS_SUCCESS
)
209 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
211 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\");
213 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
214 KmtEndSeh(STATUS_SUCCESS
)
215 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
217 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\\\");
219 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
220 KmtEndSeh(STATUS_SUCCESS
)
221 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
223 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
225 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
226 KmtEndSeh(STATUS_SUCCESS
)
227 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
229 /* Valid prefix & GUID, invalid device node */
230 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
232 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
233 KmtEndSeh(STATUS_SUCCESS
)
234 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
236 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
238 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
239 KmtEndSeh(STATUS_SUCCESS
)
240 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
242 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\");
244 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
245 KmtEndSeh(STATUS_SUCCESS
)
246 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
248 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
250 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
251 KmtEndSeh(STATUS_SUCCESS
)
252 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
254 /* Must not read past the buffer */
255 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
256 BufferSize
= SymbolicLinkName
.Length
;
257 Buffer
= KmtAllocateGuarded(BufferSize
);
258 if (!skip(Buffer
!= NULL
, "Failed to allocate %lu bytes\n", BufferSize
))
260 RtlCopyMemory(Buffer
, SymbolicLinkName
.Buffer
, BufferSize
);
261 SymbolicLinkName
.Buffer
= Buffer
;
262 SymbolicLinkName
.MaximumLength
= BufferSize
;
264 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
265 KmtEndSeh(STATUS_SUCCESS
)
266 ok_eq_hex(Status
, STATUS_OBJECT_NAME_NOT_FOUND
);
267 KmtFreeGuarded(Buffer
);
270 RtlInitUnicodeString(&SymbolicLinkName
, L
"\\??\\#aaaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
271 BufferSize
= SymbolicLinkName
.Length
;
272 Buffer
= KmtAllocateGuarded(BufferSize
);
273 if (!skip(Buffer
!= NULL
, "Failed to allocate %lu bytes\n", BufferSize
))
275 RtlCopyMemory(Buffer
, SymbolicLinkName
.Buffer
, BufferSize
);
276 SymbolicLinkName
.Buffer
= Buffer
;
277 SymbolicLinkName
.MaximumLength
= BufferSize
;
279 Status
= IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
280 KmtEndSeh(STATUS_SUCCESS
)
281 ok_eq_hex(Status
, STATUS_INVALID_PARAMETER
);
282 KmtFreeGuarded(Buffer
);
286 START_TEST(IoDeviceInterface
)
288 // FIXME: This test crashes in Windows
289 (void)Test_IoRegisterDeviceInterface
;
290 Test_IoRegisterPlugPlayNotification();
291 Test_IoSetDeviceInterface();