static VOID TestAllInformation(VOID) { NTSTATUS Status; UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntoskrnl.exe"); UNICODE_STRING Ntoskrnl = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; IO_STATUS_BLOCK IoStatus; PFILE_ALL_INFORMATION FileAllInfo; SIZE_T Length; ULONG NameLength; PWCHAR Name = NULL; UNICODE_STRING NamePart; InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&FileHandle, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &ObjectAttributes, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE); if (Status == STATUS_PENDING) { Status = ZwWaitForSingleObject(FileHandle, FALSE, NULL); ok_eq_hex(Status, STATUS_SUCCESS); Status = IoStatus.Status; } ok_eq_hex(Status, STATUS_SUCCESS); if (skip(NT_SUCCESS(Status), "No file handle, %lx\n", Status)) return; /* NtQueryInformationFile doesn't do length checks for kernel callers in a free build */ if (KmtIsCheckedBuild) { /* Zero length */ Length = 0; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH); ok_eq_size(Length, (ULONG_PTR)0x5555555555555555); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One less than the minimum */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) - 1; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH); ok_eq_size(Length, (ULONG_PTR)0x5555555555555555); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); } /* The minimum allowed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName)); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* Plenty of space -- determine NameLength and copy the name */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + MAX_PATH * sizeof(WCHAR); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status) && FileAllInfo != NULL, "No info\n")) { NameLength = FileAllInfo->NameInformation.FileNameLength; ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); Name = ExAllocatePoolWithTag(PagedPool, NameLength + sizeof(UNICODE_NULL), 'sFmK'); if (!skip(Name != NULL, "Could not allocate %lu bytes\n", NameLength + (ULONG)sizeof(UNICODE_NULL))) { RtlCopyMemory(Name, FileAllInfo->NameInformation.FileName, NameLength); Name[NameLength / sizeof(WCHAR)] = UNICODE_NULL; ok(Name[0] == L'\\', "Name is %ls, expected first char to be \\\n", Name); ok(NameLength >= Ntoskrnl.Length + sizeof(WCHAR), "NameLength %lu too short\n", NameLength); if (NameLength >= Ntoskrnl.Length) { NamePart.Buffer = Name + (NameLength - Ntoskrnl.Length) / sizeof(WCHAR); NamePart.Length = Ntoskrnl.Length; NamePart.MaximumLength = NamePart.Length; ok(RtlEqualUnicodeString(&NamePart, &Ntoskrnl, TRUE), "Name ends in '%wZ', expected %wZ\n", &NamePart, &Ntoskrnl); } } ok(FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)] == 0xdddd, "Char past FileName is %x\n", FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)]); } if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One char less than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR)); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One byte less than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* Exactly the required size */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One byte more than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + 1; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One char more than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + sizeof(WCHAR); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); ExFreePoolWithTag(Name, 'sFmK'); Status = ObCloseHandle(FileHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); }
static VOID Test_IoSetDeviceInterface(VOID) { NTSTATUS Status; UNICODE_STRING SymbolicLinkName; PWCHAR Buffer; ULONG BufferSize; /* Invalid prefix or GUID */ KmtStartSeh() Status = IoSetDeviceInterfaceState(NULL, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); RtlInitEmptyUnicodeString(&SymbolicLinkName, NULL, 0); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); RtlInitUnicodeString(&SymbolicLinkName, L"\\??"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\\\"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); /* Valid prefix & GUID, invalid device node */ RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); RtlInitUnicodeString(&SymbolicLinkName, L"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); /* Must not read past the buffer */ RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); BufferSize = SymbolicLinkName.Length; Buffer = KmtAllocateGuarded(BufferSize); if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize)) { RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); SymbolicLinkName.Buffer = Buffer; SymbolicLinkName.MaximumLength = BufferSize; KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); KmtFreeGuarded(Buffer); } RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#aaaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); BufferSize = SymbolicLinkName.Length; Buffer = KmtAllocateGuarded(BufferSize); if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize)) { RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); SymbolicLinkName.Buffer = Buffer; SymbolicLinkName.MaximumLength = BufferSize; KmtStartSeh() Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); KmtEndSeh(STATUS_SUCCESS) ok_eq_hex(Status, STATUS_INVALID_PARAMETER); KmtFreeGuarded(Buffer); } }