Beispiel #1
0
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);
}
Beispiel #2
0
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);
    }
}