Exemplo n.º 1
0
static
VOID
NTAPI
KernelModeTest(IN PVOID Context)
{
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE ParentHandle, SystemRootHandle, TargetHandle;
    PFILE_OBJECT ParentFileObject, TargetFileObject, SystemRootFileObject;

    UNREFERENCED_PARAMETER(Context);

    /* Kernelmode mandatory for IoCreateFile */
    ok(ExGetPreviousMode() == KernelMode, "UserMode returned!\n");

    /* First of all, open \\SystemRoot
     * We're interested in 3 pieces of information about it:
     * -> Its target (it's a symlink): \Windows or \ReactOS
     * -> Its associated File Object
     * -> Its associated FCB
     */
    TargetFileObject = NULL;
    IoStatusBlock.Status = 0xFFFFFFFF;
    TargetHandle = INVALID_HANDLE_VALUE;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&TargetHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        Status = ObReferenceObjectByHandle(TargetHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           KernelMode,
                                           (PVOID *)&TargetFileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
    }

    ok(TargetFileObject != NULL, "Not target to continue!\n");
    if (TargetFileObject == NULL)
    {
        if (TargetHandle != INVALID_HANDLE_VALUE)
        {
            ObCloseHandle(TargetHandle, KernelMode);
        }
        return;
    }

    /* Open target directory of \SystemRoot\Regedit.exe
     * This must lead to \SystemRoot opening
     */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootRegedit,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        Status = ObReferenceObjectByHandle(ParentHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           KernelMode,
                                           (PVOID *)&ParentFileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            /* At that point, file object must point to \SystemRoot
             * But must not be the same FO than target (diverted file object)
             * This means FCB & FileName are equal
             * But CCB & FO are different
             * CCB must be != NULL, otherwise it means open failed
             */
            ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
            ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL);
            ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
            ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
            ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
            ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
            ObDereferenceObject(ParentFileObject);
        }
        /* Because target exists FSD must signal it */
        ok_eq_long(IoStatusBlock.Information, FILE_EXISTS);
        ObCloseHandle(ParentHandle, KernelMode);
    }

    /* Do the same with relative open */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &Regedit,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            Status = ObReferenceObjectByHandle(ParentHandle,
                                               FILE_READ_DATA,
                                               *IoFileObjectType,
                                               KernelMode,
                                               (PVOID *)&ParentFileObject,
                                               NULL);
            ok_eq_hex(Status, STATUS_SUCCESS);
            if (Status == STATUS_SUCCESS)
            {
                ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
                ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
                ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
                ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
                ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
                Status = ObReferenceObjectByHandle(SystemRootHandle,
                                                   FILE_READ_DATA,
                                                   *IoFileObjectType,
                                                   KernelMode,
                                                   (PVOID *)&SystemRootFileObject,
                                                   NULL);
                ok_eq_hex(Status, STATUS_SUCCESS);
                if (Status == STATUS_SUCCESS)
                {
                    ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject);
                    ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n");
                    ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n");
                    ObDereferenceObject(SystemRootFileObject);
                }
                ObDereferenceObject(ParentFileObject);
            }
            ok_eq_long(IoStatusBlock.Information, FILE_EXISTS);
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }

    /* *** */

    /* Now redo the same scheme, but using a target that doesn't exist
     * The difference will be in IoStatusBlock.Information, the FSD will
     * inform that the target doesn't exist.
     * Clear for rename :-)
     */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootFoobar,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        Status = ObReferenceObjectByHandle(ParentHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           KernelMode,
                                           (PVOID *)&ParentFileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
            ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL);
            ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
            ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
            ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
            ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
            ObDereferenceObject(ParentFileObject);
        }
        ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST);
        ObCloseHandle(ParentHandle, KernelMode);
    }

    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &Foobar,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            Status = ObReferenceObjectByHandle(ParentHandle,
                                               FILE_READ_DATA,
                                               *IoFileObjectType,
                                               KernelMode,
                                               (PVOID *)&ParentFileObject,
                                               NULL);
            ok_eq_hex(Status, STATUS_SUCCESS);
            if (Status == STATUS_SUCCESS)
            {
                ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
                ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
                ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
                ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
                ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
                Status = ObReferenceObjectByHandle(SystemRootHandle,
                                                   FILE_READ_DATA,
                                                   *IoFileObjectType,
                                                   KernelMode,
                                                   (PVOID *)&SystemRootFileObject,
                                                   NULL);
                ok_eq_hex(Status, STATUS_SUCCESS);
                if (Status == STATUS_SUCCESS)
                {
                    ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject);
                    ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n");
                    ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n");
                    ObDereferenceObject(SystemRootFileObject);
                }
                ObDereferenceObject(ParentFileObject);
            }
            ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST);
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }

    ObDereferenceObject(TargetFileObject);
    ObCloseHandle(TargetHandle, KernelMode);

    /* *** */

    /* Direct target open of something that doesn't exist */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootFoobarFoobar,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND);
    ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
    if (Status == STATUS_SUCCESS)
    {
        ObCloseHandle(ParentHandle, KernelMode);
    }

    /* Relative target open of something that doesn't exist */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &FoobarFoobar,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND);
        ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
        if (Status == STATUS_SUCCESS)
        {
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }
}
Exemplo n.º 2
0
static
VOID
TestVolumeInfo(
    IN HANDLE ServerHandle)
{
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_FS_SIZE_INFORMATION FileFsSizeInfo;
    FILE_FS_DEVICE_INFORMATION FileFsDeviceInfo;
    FILE_FS_FULL_SIZE_INFORMATION FileFsFullSizeInfo;

    struct {
        FILE_FS_VOLUME_INFORMATION;
        WCHAR PartialName[10];
    } VolumeInfo;

    struct {
        FILE_FS_ATTRIBUTE_INFORMATION;
        WCHAR PartialName[6];
    } AttributeInfo;

    RtlFillMemory(&VolumeInfo, sizeof(VolumeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &VolumeInfo,
                                          sizeof(VolumeInfo),
                                          FileFsVolumeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_long(VolumeInfo.VolumeCreationTime.LowPart, 0);
    ok_eq_long(VolumeInfo.VolumeCreationTime.HighPart, 0);
    ok_eq_ulong(VolumeInfo.VolumeSerialNumber, 0);
    ok_bool_false(VolumeInfo.SupportsObjects, "VolumeInfo.SupportsObjects");
    ok_eq_ulong(VolumeInfo.VolumeLabelLength, 18);
    ok_eq_size(RtlCompareMemory(VolumeInfo.VolumeLabel, L"NamedPipe", 18), 18);
    ok_eq_wchar(VolumeInfo.VolumeLabel[9], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + 9 * sizeof(WCHAR)));

    RtlFillMemory(&VolumeInfo, sizeof(VolumeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &VolumeInfo,
                                          sizeof(FILE_FS_VOLUME_INFORMATION) + 2 * sizeof(WCHAR),
                                          FileFsVolumeInformation);
    ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_hex(IoStatusBlock.Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_long(VolumeInfo.VolumeCreationTime.LowPart, 0);
    ok_eq_long(VolumeInfo.VolumeCreationTime.HighPart, 0);
    ok_eq_ulong(VolumeInfo.VolumeSerialNumber, 0);
    ok_bool_false(VolumeInfo.SupportsObjects, "VolumeInfo.SupportsObjects");
    ok_eq_ulong(VolumeInfo.VolumeLabelLength, 18);
    ok_eq_size(RtlCompareMemory(VolumeInfo.VolumeLabel, L"NamedP", 10), 10);
    ok_eq_wchar(VolumeInfo.VolumeLabel[5], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + 5 * sizeof(WCHAR)));

    RtlFillMemory(&FileFsSizeInfo, sizeof(FileFsSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsSizeInfo,
                                          sizeof(FileFsSizeInfo),
                                          FileFsSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsSizeInfo.AvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsSizeInfo.SectorsPerAllocationUnit, 1);
    ok_eq_ulong(FileFsSizeInfo.BytesPerSector, 1);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsSizeInfo));

    RtlFillMemory(&FileFsSizeInfo, sizeof(FileFsSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsSizeInfo,
                                          sizeof(FileFsSizeInfo) - 4,
                                          FileFsSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsSizeInfo.AvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsSizeInfo.SectorsPerAllocationUnit, 1);
    ok_eq_ulong(FileFsSizeInfo.BytesPerSector, 1);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsSizeInfo));

    RtlFillMemory(&FileFsDeviceInfo, sizeof(FileFsDeviceInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsDeviceInfo,
                                          sizeof(FileFsDeviceInfo),
                                          FileFsDeviceInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(FileFsDeviceInfo.Characteristics, 0);
    ok_eq_ulong(FileFsDeviceInfo.DeviceType, FILE_DEVICE_NAMED_PIPE);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsDeviceInfo));

    RtlFillMemory(&FileFsDeviceInfo, sizeof(FileFsDeviceInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsDeviceInfo,
                                          sizeof(FileFsDeviceInfo) - 4,
                                          FileFsDeviceInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(FileFsDeviceInfo.Characteristics, 0);
    ok_eq_ulong(FileFsDeviceInfo.DeviceType, FILE_DEVICE_NAMED_PIPE);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsDeviceInfo));

    RtlFillMemory(&AttributeInfo, sizeof(AttributeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &AttributeInfo,
                                          sizeof(AttributeInfo),
                                          FileFsAttributeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(AttributeInfo.FileSystemAttributes, FILE_CASE_PRESERVED_NAMES);
    ok_eq_long(AttributeInfo.MaximumComponentNameLength, 0xFFFFFFFF);
    ok_eq_ulong(AttributeInfo.FileSystemNameLength, 8);
    ok_eq_size(RtlCompareMemory(AttributeInfo.FileSystemName, L"NPFS", 8), 8);
    ok_eq_wchar(AttributeInfo.FileSystemName[4], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, 20);

    RtlFillMemory(&AttributeInfo, sizeof(AttributeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &AttributeInfo,
                                          sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 2 * sizeof(WCHAR),
                                          FileFsAttributeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(AttributeInfo.FileSystemAttributes, FILE_CASE_PRESERVED_NAMES);
    ok_eq_long(AttributeInfo.MaximumComponentNameLength, 0xFFFFFFFF);
    ok_eq_ulong(AttributeInfo.FileSystemNameLength, 8);
    ok_eq_size(RtlCompareMemory(AttributeInfo.FileSystemName, L"NPFS", 8), 8);
    ok_eq_wchar(AttributeInfo.FileSystemName[4], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, 20);

    RtlFillMemory(&FileFsFullSizeInfo, sizeof(FileFsFullSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsFullSizeInfo,
                                          sizeof(FileFsFullSizeInfo),
                                          FileFsFullSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsFullSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.CallerAvailableAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.ActualAvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsFullSizeInfo.SectorsPerAllocationUnit, 0);
    ok_eq_ulong(FileFsFullSizeInfo.BytesPerSector, 0);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsFullSizeInfo));

    RtlFillMemory(&FileFsFullSizeInfo, sizeof(FileFsFullSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsFullSizeInfo,
                                          sizeof(FileFsFullSizeInfo) - 4,
                                          FileFsFullSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsFullSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.CallerAvailableAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.ActualAvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsFullSizeInfo.SectorsPerAllocationUnit, 0);
    ok_eq_ulong(FileFsFullSizeInfo.BytesPerSector, 0);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsFullSizeInfo));
}
Exemplo n.º 3
0
static
VOID
TestEventConcurrent(
    IN PKEVENT Event,
    IN EVENT_TYPE Type,
    IN KIRQL OriginalIrql,
    PSET_EVENT_FUNCTION SetEvent,
    KPRIORITY PriorityIncrement,
    LONG ExpectedState,
    BOOLEAN SatisfiesAll)
{
    NTSTATUS Status;
    THREAD_DATA Threads[5];
    const INT ThreadCount = sizeof Threads / sizeof Threads[0];
    KPRIORITY Priority;
    LARGE_INTEGER LongTimeout, ShortTimeout;
    INT i;
    KWAIT_BLOCK WaitBlock[MAXIMUM_WAIT_OBJECTS];
    PVOID ThreadObjects[MAXIMUM_WAIT_OBJECTS];
    LONG State;
    PKTHREAD Thread = KeGetCurrentThread();

    LongTimeout.QuadPart = -100 * MILLISECOND;
    ShortTimeout.QuadPart = -1 * MILLISECOND;

    KeInitializeEvent(Event, Type, FALSE);

    for (i = 0; i < ThreadCount; ++i)
    {
        Threads[i].Event = Event;
        Threads[i].Signal = FALSE;
        Status = PsCreateSystemThread(&Threads[i].Handle, GENERIC_ALL, NULL, NULL, NULL, WaitForEventThread, &Threads[i]);
        ok_eq_hex(Status, STATUS_SUCCESS);
        Status = ObReferenceObjectByHandle(Threads[i].Handle, SYNCHRONIZE, PsThreadType, KernelMode, (PVOID *)&Threads[i].Thread, NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ThreadObjects[i] = Threads[i].Thread;
        Priority = KeQueryPriorityThread(Threads[i].Thread);
        ok_eq_long(Priority, 8L);
        while (!Threads[i].Signal)
        {
            Status = KeDelayExecutionThread(KernelMode, FALSE, &ShortTimeout);
            ok_eq_hex(Status, STATUS_SUCCESS);
        }
        CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, ThreadObjects, i + 1);
    }

    /* the threads shouldn't wake up on their own */
    Status = KeDelayExecutionThread(KernelMode, FALSE, &ShortTimeout);
    ok_eq_hex(Status, STATUS_SUCCESS);

    for (i = 0; i < ThreadCount; ++i)
    {
        CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, ThreadObjects + i, ThreadCount - i);
        State = SetEvent(Event, PriorityIncrement + i, FALSE);

        ok_eq_long(State, 0L);
        CheckEvent(Event, Type, ExpectedState, FALSE, OriginalIrql, ThreadObjects + i + 1, SatisfiesAll ? 0 : ThreadCount - i - 1);
        Status = KeWaitForMultipleObjects(ThreadCount, ThreadObjects, SatisfiesAll ? WaitAll : WaitAny, Executive, KernelMode, FALSE, &LongTimeout, WaitBlock);
        ok_eq_hex(Status, STATUS_WAIT_0 + i);
        if (SatisfiesAll)
        {
            for (; i < ThreadCount; ++i)
            {
                Priority = KeQueryPriorityThread(Threads[i].Thread);
                ok_eq_long(Priority, max(min(8L + PriorityIncrement, 15L), 8L));
            }
            break;
        }
        Priority = KeQueryPriorityThread(Threads[i].Thread);
        ok_eq_long(Priority, max(min(8L + PriorityIncrement + i, 15L), 8L));
        /* replace the thread with the current thread - which will never signal */
        if (!skip((Status & 0x3F) < ThreadCount, "Index out of bounds"))
            ThreadObjects[Status & 0x3F] = Thread;
        Status = KeWaitForMultipleObjects(ThreadCount, ThreadObjects, WaitAny, Executive, KernelMode, FALSE, &ShortTimeout, WaitBlock);
        ok_eq_hex(Status, STATUS_TIMEOUT);
    }

    for (i = 0; i < ThreadCount; ++i)
    {
        ObDereferenceObject(Threads[i].Thread);
        Status = ZwClose(Threads[i].Handle);
        ok_eq_hex(Status, STATUS_SUCCESS);
    }
}
Exemplo n.º 4
0
static
VOID
TestEventFunctional(
    IN PKEVENT Event,
    IN EVENT_TYPE Type,
    IN KIRQL OriginalIrql)
{
    LONG State;
    PKTHREAD Thread = KeGetCurrentThread();

    memset(Event, 0x55, sizeof *Event);
    KeInitializeEvent(Event, Type, FALSE);
    CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0);

    memset(Event, 0x55, sizeof *Event);
    KeInitializeEvent(Event, Type, TRUE);
    CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0);

    Event->Header.SignalState = 0x12345678L;
    CheckEvent(Event, Type, 0x12345678L, FALSE, OriginalIrql, (PVOID *)NULL, 0);

    State = KePulseEvent(Event, 0, FALSE);
    CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0);
    ok_eq_long(State, 0x12345678L);

    Event->Header.SignalState = 0x12345678L;
    KeClearEvent(Event);
    CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0);

    State = KeSetEvent(Event, 0, FALSE);
    CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0);
    ok_eq_long(State, 0L);

    State = KeResetEvent(Event);
    CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0);
    ok_eq_long(State, 1L);

    Event->Header.SignalState = 0x23456789L;
    State = KeSetEvent(Event, 0, FALSE);
    CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0);
    ok_eq_long(State, 0x23456789L);

    Event->Header.SignalState = 0x3456789AL;
    State = KeResetEvent(Event);
    CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0);
    ok_eq_long(State, 0x3456789AL);

    /* Irql is raised to DISPATCH_LEVEL here, which kills checked build,
     * a spinlock is acquired and never released, which kills MP build */
    if ((OriginalIrql <= DISPATCH_LEVEL || !KmtIsCheckedBuild) &&
        !KmtIsMultiProcessorBuild)
    {
        Event->Header.SignalState = 0x456789ABL;
        State = KeSetEvent(Event, 0, TRUE);
        CheckEvent(Event, Type, 1L, TRUE, DISPATCH_LEVEL, (PVOID *)NULL, 0);
        ok_eq_long(State, 0x456789ABL);
        ok_eq_uint(Thread->WaitIrql, OriginalIrql);
        /* repair the "damage" */
        Thread->WaitNext = FALSE;
        KmtSetIrql(OriginalIrql);

        Event->Header.SignalState = 0x56789ABCL;
        State = KePulseEvent(Event, 0, TRUE);
        CheckEvent(Event, Type, 0L, TRUE, DISPATCH_LEVEL, (PVOID *)NULL, 0);
        ok_eq_long(State, 0x56789ABCL);
        ok_eq_uint(Thread->WaitIrql, OriginalIrql);
        /* repair the "damage" */
        Thread->WaitNext = FALSE;
        KmtSetIrql(OriginalIrql);
    }

    ok_irql(OriginalIrql);
    KmtSetIrql(OriginalIrql);
}
Exemplo n.º 5
0
static
VOID
TestFastMutex(
    PFAST_MUTEX Mutex,
    KIRQL OriginalIrql)
{
    PKTHREAD Thread = KeGetCurrentThread();

    ok_irql(OriginalIrql);

    /* acquire/release normally */
    ExAcquireFastMutex(Mutex);
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ok_bool_false(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned");
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ExReleaseFastMutex(Mutex);
    CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

#ifdef _M_IX86
    /* ntoskrnl's fastcall version */
    ExiAcquireFastMutex(Mutex);
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ok_bool_false(ExiTryToAcquireFastMutex(Mutex), "ExiTryToAcquireFastMutex returned");
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ExiReleaseFastMutex(Mutex);
    CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);
#endif

    /* try to acquire */
    ok_bool_true(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned");
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ExReleaseFastMutex(Mutex);
    CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

    /* shortcut functions with critical region */
    ExEnterCriticalRegionAndAcquireFastMutexUnsafe(Mutex);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(Mutex);

    /* acquire/release unsafe */
    if (!KmtIsCheckedBuild || OriginalIrql == APC_LEVEL)
    {
        ExAcquireFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, OriginalIrql);
        ExReleaseFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

        /* mismatched acquire/release */
        ExAcquireFastMutex(Mutex);
        CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
        ExReleaseFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, APC_LEVEL);
        KmtSetIrql(OriginalIrql);
        CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

        Mutex->OldIrql = 0x55555555LU;
        ExAcquireFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 0L, Thread, 0LU, 0x55555555LU, OriginalIrql);
        Mutex->OldIrql = PASSIVE_LEVEL;
        ExReleaseFastMutex(Mutex);
        CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, PASSIVE_LEVEL);
        KmtSetIrql(OriginalIrql);
        CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql);
    }

    if (!KmtIsCheckedBuild)
    {
        /* release without acquire */
        ExReleaseFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 2L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql);
        --Mutex->Count;
        Mutex->OldIrql = OriginalIrql;
        ExReleaseFastMutex(Mutex);
        CheckMutex(Mutex, 2L, NULL, 0LU, OriginalIrql, OriginalIrql);
        ExReleaseFastMutex(Mutex);
        CheckMutex(Mutex, 3L, NULL, 0LU, OriginalIrql, OriginalIrql);
        Mutex->Count -= 2;
    }

    /* make sure we survive this in case of error */
    ok_eq_long(Mutex->Count, 1L);
    Mutex->Count = 1;
    ok_irql(OriginalIrql);
    KmtSetIrql(OriginalIrql);
}