Beispiel #1
0
void disk_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) {
    PFILE_OBJECT FileObject, mountmgrfo;
    PDEVICE_OBJECT devobj, mountmgr;
    NTSTATUS Status;
    STORAGE_DEVICE_NUMBER sdn;
    ULONG dlisize;
    DRIVE_LAYOUT_INFORMATION_EX* dli = NULL;
    IO_STATUS_BLOCK iosb;
    GET_LENGTH_INFORMATION gli;
    UNICODE_STRING mmdevpath;

    UNUSED(DriverObject);

    Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &FileObject, &devobj);
    if (!NT_SUCCESS(Status)) {
        ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
        return;
    }

    RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME);
    Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
    if (!NT_SUCCESS(Status)) {
        ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
        ObDereferenceObject(FileObject);
        return;
    }

    dlisize = 0;

    do {
        dlisize += 1024;

        if (dli)
            ExFreePool(dli);

        dli = ExAllocatePoolWithTag(PagedPool, dlisize, ALLOC_TAG);
        if (!dli) {
            ERR("out of memory\n");
            goto end;
        }

        Status = dev_ioctl(devobj, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0,
                           dli, dlisize, TRUE, &iosb);
    } while (Status == STATUS_BUFFER_TOO_SMALL);

    // only consider disk as a potential filesystem if it has no partitions
    if (NT_SUCCESS(Status) && dli->PartitionCount > 0) {
        ExFreePool(dli);
        goto end;
    }

    ExFreePool(dli);

    Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0,
                        &gli, sizeof(gli), TRUE, NULL);

    if (!NT_SUCCESS(Status)) {
        ERR("error reading length information: %08x\n", Status);
        goto end;
    }

    Status = dev_ioctl(devobj, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0,
                       &sdn, sizeof(STORAGE_DEVICE_NUMBER), TRUE, NULL);
    if (!NT_SUCCESS(Status)) {
        TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status);
        sdn.DeviceNumber = 0xffffffff;
        sdn.PartitionNumber = 0;
    } else
        TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);

    test_vol(mountmgr, devobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart);

end:
    ObDereferenceObject(FileObject);
    ObDereferenceObject(mountmgrfo);
}
Beispiel #2
0
static NTSTATUS look_in_harddisk_dir(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT mountmgr, PUNICODE_STRING name, LIST_ENTRY* volumes) {
    UNICODE_STRING path;
    OBJECT_ATTRIBUTES attr;
    NTSTATUS Status;
    HANDLE h;
    OBJECT_DIRECTORY_INFORMATION* odi;
    ULONG odisize, context;
    BOOL restart, has_part0 = FALSE, has_parts = FALSE;
    
    static const WCHAR partition[] = L"Partition";
    static WCHAR partition0[] = L"Partition0";
    
    path.Buffer = ExAllocatePoolWithTag(PagedPool, ((wcslen(devpath) + 1) * sizeof(WCHAR)) + name->Length, ALLOC_TAG);
    if (!path.Buffer) {
        ERR("out of memory\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    
    RtlCopyMemory(path.Buffer, devpath, wcslen(devpath) * sizeof(WCHAR));
    path.Buffer[wcslen(devpath)] = '\\';
    RtlCopyMemory(&path.Buffer[wcslen(devpath) + 1], name->Buffer, name->Length);
    path.Length = path.MaximumLength = ((wcslen(devpath) + 1) * sizeof(WCHAR)) + name->Length;

    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.Attributes = OBJ_CASE_INSENSITIVE;
    attr.ObjectName = &path;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;
    
    Status = ZwOpenDirectoryObject(&h, DIRECTORY_TRAVERSE, &attr);

    if (!NT_SUCCESS(Status)) {
        ERR("ZwOpenDirectoryObject returned %08x\n", Status);
        goto end;
    }
    
    odisize = sizeof(OBJECT_DIRECTORY_INFORMATION) * 16;
    odi = ExAllocatePoolWithTag(PagedPool, odisize, ALLOC_TAG);
    if (!odi) {
        ERR("out of memory\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ZwClose(h);
        goto end;
    }
    
    restart = TRUE;
    do {
        Status = ZwQueryDirectoryObject(h, odi, odisize, FALSE, restart, &context, NULL/*&retlen*/);
        restart = FALSE;
        
        if (!NT_SUCCESS(Status)) {
            if (Status != STATUS_NO_MORE_ENTRIES)
                ERR("ZwQueryDirectoryObject returned %08x\n", Status);
        } else {
            OBJECT_DIRECTORY_INFORMATION* odi2 = odi;
            
            while (odi2->Name.Buffer) {
                TRACE("%.*S, %.*S\n", odi2->TypeName.Length / sizeof(WCHAR), odi2->TypeName.Buffer, odi2->Name.Length / sizeof(WCHAR), odi2->Name.Buffer);
                
                if (odi2->Name.Length > wcslen(partition) * sizeof(WCHAR) &&
                    RtlCompareMemory(odi2->Name.Buffer, partition, wcslen(partition) * sizeof(WCHAR)) == wcslen(partition) * sizeof(WCHAR)) {
                    
                    if (odi2->Name.Length == (wcslen(partition) + 1) * sizeof(WCHAR) && odi2->Name.Buffer[(odi2->Name.Length / sizeof(WCHAR)) - 1] == '0') {
                        // Partition0 refers to the whole disk
                        has_part0 = TRUE;
                    } else {
                        has_parts = TRUE;
                        
                        test_vol(DriverObject, mountmgr, &path, &odi2->Name, FALSE, volumes);
                    }
                }
                
                odi2 = &odi2[1];
            }
        }
    } while (NT_SUCCESS(Status));
    
    // If disk had no partitions, test the whole disk
    if (!has_parts && has_part0) {
        UNICODE_STRING part0us;
        
        part0us.Buffer = partition0;
        part0us.Length = part0us.MaximumLength = wcslen(partition0) * sizeof(WCHAR);
        
        test_vol(DriverObject, mountmgr, &path, &part0us, TRUE, volumes);
    }
    
    ZwClose(h);
    
    ExFreePool(odi);
    
    Status = STATUS_SUCCESS;
    
end:
    ExFreePool(path.Buffer);
    
    return Status;
}