1 /* 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> 6 */ 7 8 /* TODO: what's with the prototypes at the top, what's with the if-ed out part? Doesn't process most results */ 9 10 #include <kmt_test.h> 11 #include <poclass.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 #if 0 17 NTSTATUS 18 (NTAPI *IoGetDeviceInterfaces_Func)( 19 IN CONST GUID *InterfaceClassGuid, 20 IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, 21 IN ULONG Flags, 22 OUT PWSTR *SymbolicLinkList); 23 24 NTSTATUS NTAPI 25 ReactOS_IoGetDeviceInterfaces( 26 IN CONST GUID *InterfaceClassGuid, 27 IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, 28 IN ULONG Flags, 29 OUT PWSTR *SymbolicLinkList); 30 #endif /* 0 */ 31 32 static VOID DeviceInterfaceTest_Func() 33 { 34 NTSTATUS Status; 35 PWSTR SymbolicLinkList; 36 PWSTR SymbolicLinkListPtr; 37 GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; 38 39 Status = IoGetDeviceInterfaces( 40 &Guid, 41 NULL, 42 0, 43 &SymbolicLinkList); 44 45 ok(NT_SUCCESS(Status), 46 "IoGetDeviceInterfaces failed with status 0x%X\n", 47 (unsigned int)Status); 48 if (!NT_SUCCESS(Status)) 49 { 50 return; 51 } 52 53 DPRINT("IoGetDeviceInterfaces results:\n"); 54 for (SymbolicLinkListPtr = SymbolicLinkList; 55 SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; 56 SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) 57 { 58 DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr); 59 } 60 61 #if 0 62 DPRINT("[PnP Test] Trying to get aliases\n"); 63 64 for (SymbolicLinkListPtr = SymbolicLinkList; 65 SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; 66 SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) 67 { 68 UNICODE_STRING SymbolicLink; 69 UNICODE_STRING AliasSymbolicLink; 70 71 SymbolicLink.Buffer = SymbolicLinkListPtr; 72 SymbolicLink.Length = SymbolicLink.MaximumLength = wcslen(SymbolicLinkListPtr); 73 RtlInitUnicodeString(&AliasSymbolicLink, NULL); 74 IoGetDeviceInterfaceAlias( 75 &SymbolicLink, 76 &AliasGuid, 77 &AliasSymbolicLink); 78 if (AliasSymbolicLink.Buffer != NULL) 79 { 80 DPRINT("[PnP Test] Original: %S\n", SymbolicLinkListPtr); 81 DPRINT("[PnP Test] Alias: %S\n", AliasSymbolicLink.Buffer); 82 } 83 } 84 #endif 85 86 ExFreePool(SymbolicLinkList); 87 } 88 89 static 90 VOID 91 Test_IoRegisterDeviceInterface(VOID) 92 { 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; 98 NTSTATUS Status; 99 100 RtlInitUnicodeString(&SymbolicLinkName, L""); 101 102 // Prepare our surrogate of a Device Object 103 DeviceObject.DeviceObjectExtension = (PDEVOBJ_EXTENSION)&DeviceObjectExtension; 104 105 // 1. DeviceNode = NULL 106 DeviceObjectExtension.DeviceNode = NULL; 107 Status = IoRegisterDeviceInterface(&DeviceObject, &Guid, NULL, 108 &SymbolicLinkName); 109 110 ok(Status == STATUS_INVALID_DEVICE_REQUEST, 111 "IoRegisterDeviceInterface returned 0x%08lX\n", Status); 112 113 // 2. DeviceNode->InstancePath is of a null length 114 DeviceObjectExtension.DeviceNode = &DeviceNode; 115 DeviceNode.InstancePath.Length = 0; 116 Status = IoRegisterDeviceInterface(&DeviceObject, &Guid, NULL, 117 &SymbolicLinkName); 118 119 ok(Status == STATUS_INVALID_DEVICE_REQUEST, 120 "IoRegisterDeviceInterface returned 0x%08lX\n", Status); 121 122 DeviceInterfaceTest_Func(); 123 } 124 125 static UCHAR NotificationContext; 126 127 static DRIVER_NOTIFICATION_CALLBACK_ROUTINE NotificationCallback; 128 static 129 NTSTATUS 130 NTAPI 131 NotificationCallback( 132 _In_ PVOID NotificationStructure, 133 _Inout_opt_ PVOID Context) 134 { 135 PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification = NotificationStructure; 136 NTSTATUS Status; 137 OBJECT_ATTRIBUTES ObjectAttributes; 138 HANDLE Handle; 139 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)); 144 145 /* symbolic link must exist */ 146 trace("Interface change: %wZ\n", Notification->SymbolicLinkName); 147 InitializeObjectAttributes(&ObjectAttributes, 148 Notification->SymbolicLinkName, 149 OBJ_KERNEL_HANDLE, 150 NULL, 151 NULL); 152 Status = ZwOpenSymbolicLinkObject(&Handle, GENERIC_READ, &ObjectAttributes); 153 ok_eq_hex(Status, STATUS_SUCCESS); 154 if (!skip(NT_SUCCESS(Status), "No symbolic link\n")) 155 { 156 Status = ObCloseHandle(Handle, KernelMode); 157 ok_eq_hex(Status, STATUS_SUCCESS); 158 } 159 return STATUS_SUCCESS; 160 } 161 162 static 163 VOID 164 Test_IoRegisterPlugPlayNotification(VOID) 165 { 166 NTSTATUS Status; 167 PVOID NotificationEntry; 168 169 Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, 170 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, 171 (PVOID)&GUID_DEVICE_SYS_BUTTON, 172 KmtDriverObject, 173 NotificationCallback, 174 &NotificationContext, 175 &NotificationEntry); 176 ok_eq_hex(Status, STATUS_SUCCESS); 177 if (!skip(NT_SUCCESS(Status), "PlugPlayNotification not registered\n")) 178 { 179 Status = IoUnregisterPlugPlayNotification(NotificationEntry); 180 ok_eq_hex(Status, STATUS_SUCCESS); 181 } 182 } 183 184 static 185 VOID 186 Test_IoSetDeviceInterface(VOID) 187 { 188 NTSTATUS Status; 189 UNICODE_STRING SymbolicLinkName; 190 PWCHAR Buffer; 191 ULONG BufferSize; 192 193 /* Invalid prefix or GUID */ 194 KmtStartSeh() 195 Status = IoSetDeviceInterfaceState(NULL, TRUE); 196 KmtEndSeh(STATUS_SUCCESS) 197 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 198 199 RtlInitEmptyUnicodeString(&SymbolicLinkName, NULL, 0); 200 KmtStartSeh() 201 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 202 KmtEndSeh(STATUS_SUCCESS) 203 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 204 205 RtlInitUnicodeString(&SymbolicLinkName, L"\\??"); 206 KmtStartSeh() 207 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 208 KmtEndSeh(STATUS_SUCCESS) 209 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 210 211 RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\"); 212 KmtStartSeh() 213 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 214 KmtEndSeh(STATUS_SUCCESS) 215 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 216 217 RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\\\"); 218 KmtStartSeh() 219 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 220 KmtEndSeh(STATUS_SUCCESS) 221 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 222 223 RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); 224 KmtStartSeh() 225 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 226 KmtEndSeh(STATUS_SUCCESS) 227 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 228 229 /* Valid prefix & GUID, invalid device node */ 230 RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); 231 KmtStartSeh() 232 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 233 KmtEndSeh(STATUS_SUCCESS) 234 ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); 235 236 RtlInitUnicodeString(&SymbolicLinkName, L"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); 237 KmtStartSeh() 238 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 239 KmtEndSeh(STATUS_SUCCESS) 240 ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); 241 242 RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\"); 243 KmtStartSeh() 244 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 245 KmtEndSeh(STATUS_SUCCESS) 246 ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); 247 248 RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); 249 KmtStartSeh() 250 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 251 KmtEndSeh(STATUS_SUCCESS) 252 ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); 253 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)) 259 { 260 RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); 261 SymbolicLinkName.Buffer = Buffer; 262 SymbolicLinkName.MaximumLength = BufferSize; 263 KmtStartSeh() 264 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 265 KmtEndSeh(STATUS_SUCCESS) 266 ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); 267 KmtFreeGuarded(Buffer); 268 } 269 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)) 274 { 275 RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); 276 SymbolicLinkName.Buffer = Buffer; 277 SymbolicLinkName.MaximumLength = BufferSize; 278 KmtStartSeh() 279 Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 280 KmtEndSeh(STATUS_SUCCESS) 281 ok_eq_hex(Status, STATUS_INVALID_PARAMETER); 282 KmtFreeGuarded(Buffer); 283 } 284 } 285 286 START_TEST(IoDeviceInterface) 287 { 288 // FIXME: This test crashes in Windows 289 (void)Test_IoRegisterDeviceInterface; 290 Test_IoRegisterPlugPlayNotification(); 291 Test_IoSetDeviceInterface(); 292 }