Exemplo n.º 1
0
PPH_STRING DiskDriveQueryDosMountPoints(
    _In_ ULONG DeviceNumber
    )
{
    ULONG driveMask;
    WCHAR deviceNameBuffer[7] = L"\\\\.\\?:";
    PH_STRING_BUILDER stringBuilder;

    PhInitializeStringBuilder(&stringBuilder, MAX_PATH);

    driveMask = DiskDriveQueryDeviceMap();

    // NOTE: This isn't the best way of doing this but it works.
    for (INT i = 0; i < 0x1A; i++)
    {
        if (driveMask & (0x1 << i))
        {
            HANDLE deviceHandle;

            deviceNameBuffer[4] = (WCHAR)('A' + i);

            if (NT_SUCCESS(PhCreateFileWin32(
                &deviceHandle,
                deviceNameBuffer,
                FILE_READ_ATTRIBUTES | SYNCHRONIZE,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                FILE_OPEN,
                FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
                )))
            {
                ULONG deviceNumber = ULONG_MAX; // Note: Do not initialize to zero.
                DEVICE_TYPE deviceType = 0;

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(
                    deviceHandle,
                    &deviceNumber,
                    &deviceType
                    )))
                {
                    // BUG: Device numbers are re-used on seperate device controllers and this
                    // causes drive letters to be assigned to disks at those same indexes.
                    // For now, just filter CD_ROM devices but we may need to be a lot more strict and
                    // only allow devices of type FILE_DEVICE_DISK to be scanned for mount points.
                    if (deviceNumber == DeviceNumber && deviceType != FILE_DEVICE_CD_ROM)
                    {
                        PhAppendFormatStringBuilder(&stringBuilder, L"%c: ", deviceNameBuffer[4]);
                    }
                }

                NtClose(deviceHandle);
            }
        }
    }

    if (stringBuilder.String->Length != 0)
        PhRemoveEndStringBuilder(&stringBuilder, 1);

    return PhFinalStringBuilderString(&stringBuilder);
}
Exemplo n.º 2
0
PPH_LIST DiskDriveQueryMountPointHandles(
    _In_ ULONG DeviceNumber
    )
{
    ULONG driveMask;
    PPH_LIST deviceList;
    WCHAR deviceNameBuffer[7] = L"\\\\.\\?:";

    driveMask = DiskDriveQueryDeviceMap();
    deviceList = PhCreateList(2);

    // NOTE: This isn't the best way of doing this but it works.
    for (INT i = 0; i < 0x1A; i++)
    {
        if (driveMask & (0x1 << i))
        {
            HANDLE deviceHandle;

            deviceNameBuffer[4] = (WCHAR)('A' + i);

            if (NT_SUCCESS(PhCreateFileWin32(
                &deviceHandle,
                deviceNameBuffer,
                PhGetOwnTokenAttributes().Elevated ? FILE_GENERIC_READ : FILE_READ_ATTRIBUTES | FILE_TRAVERSE | SYNCHRONIZE,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                FILE_OPEN,
                FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
                )))
            {
                ULONG deviceNumber = ULONG_MAX; // Note: Do not initialize to zero.
                DEVICE_TYPE deviceType = 0;

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(
                    deviceHandle,
                    &deviceNumber,
                    &deviceType
                    )))
                {
                    // BUG: Device numbers are re-used on seperate device controllers and this
                    // causes drive letters to be assigned to disks at those same indexes.
                    // For now, just filter CD_ROM devices but we may need to be a lot more strict and
                    // only allow devices of type FILE_DEVICE_DISK to be scanned for mount points.
                    if (deviceNumber == DeviceNumber && deviceType != FILE_DEVICE_CD_ROM)
                    {
                        PDISK_HANDLE_ENTRY entry = PhAllocate(sizeof(DISK_HANDLE_ENTRY));
                        memset(entry, 0, sizeof(DISK_HANDLE_ENTRY));

                        entry->DeviceLetter = deviceNameBuffer[4];
                        entry->DeviceHandle = deviceHandle;

                        PhAddItemList(deviceList, entry);
                    }
                }
            }
        }
    }

    return deviceList;
}
Exemplo n.º 3
0
PPH_STRING DiskDriveQueryDosMountPoints(
    _In_ ULONG DeviceNumber
    )
{
    ULONG driveMask;
    PH_STRING_BUILDER stringBuilder;
    WCHAR devicePath[] = L"\\\\.\\?:";

    PhInitializeStringBuilder(&stringBuilder, MAX_PATH);

    driveMask = DiskDriveQueryDeviceMap();

    // NOTE: This isn't the best way of doing this but it works (It's also what Task Manager does).
    for (INT i = 0; i < 0x1A; i++)
    {
        if (driveMask & (0x1 << i))
        {
            HANDLE deviceHandle;

            devicePath[4] = 'A' + i;
            
            if (NT_SUCCESS(PhCreateFileWin32(
                &deviceHandle,
                devicePath,
                FILE_READ_ATTRIBUTES | SYNCHRONIZE,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                FILE_OPEN,
                FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
                )))
            {
                ULONG deviceNumber = ULONG_MAX; // Note: Do not initialize to zero.

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(
                    deviceHandle, 
                    &deviceNumber, 
                    NULL
                    )));
                {
                    if (deviceNumber == DeviceNumber)
                    {
                        PhAppendFormatStringBuilder(&stringBuilder, L"%c: ", devicePath[4]);
                    }
                }

                NtClose(deviceHandle);
            }
        }
    }

    if (stringBuilder.String->Length != 0)
        PhRemoveEndStringBuilder(&stringBuilder, 1);

    return PhFinalStringBuilderString(&stringBuilder);
}
Exemplo n.º 4
0
VOID DiskDriveUpdateDeviceInfo(
    _In_opt_ HANDLE DeviceHandle,
    _In_ PDV_DISK_ENTRY DiskEntry
    )
{
    if (!DiskEntry->DiskName || DiskEntry->DiskIndex == ULONG_MAX)
    {
        HANDLE deviceHandle = NULL;

        if (!DeviceHandle)
        {
            DiskDriveCreateHandle(&deviceHandle, DiskEntry->Id.DevicePath);
        }
        else
        {
            deviceHandle = DeviceHandle;
        }

        if (deviceHandle)
        {
            if (!DiskEntry->DiskName)
            {
                PPH_STRING diskName = NULL;

                if (NT_SUCCESS(DiskDriveQueryDeviceInformation(deviceHandle, NULL, &diskName, NULL, NULL)))
                {
                    DiskEntry->DiskName = diskName;
                }
            }

            if (DiskEntry->DiskIndex == ULONG_MAX)
            {
                ULONG diskIndex = ULONG_MAX; // Note: Do not initialize to zero.

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(deviceHandle, &diskIndex, NULL)))
                {
                    DiskEntry->DiskIndex = diskIndex;
                }
            }

            if (!DeviceHandle)
            {
                NtClose(deviceHandle);
            }
        }
    }
}
Exemplo n.º 5
0
VOID FindDiskDrives(
    _In_ PDV_DISK_OPTIONS_CONTEXT Context
    )
{
    PPH_LIST deviceList;
    HDEVINFO deviceInfoHandle;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
    SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail;
    ULONG deviceInfoLength = 0;

    if ((deviceInfoHandle = SetupDiGetClassDevs(
        &GUID_DEVINTERFACE_DISK,
        NULL,
        NULL,
        DIGCF_DEVICEINTERFACE
        )) == INVALID_HANDLE_VALUE)
    {
        return;
    }

    deviceList = PH_AUTO(PhCreateList(1));

    for (ULONG i = 0; SetupDiEnumDeviceInterfaces(deviceInfoHandle, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++)
    {
        if (SetupDiGetDeviceInterfaceDetail(
            deviceInfoHandle,
            &deviceInterfaceData,
            0,
            0,
            &deviceInfoLength,
            &deviceInfoData
            ) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            continue;
        }

        deviceInterfaceDetail = PhAllocate(deviceInfoLength);
        deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        if (SetupDiGetDeviceInterfaceDetail(
            deviceInfoHandle,
            &deviceInterfaceData,
            deviceInterfaceDetail,
            deviceInfoLength,
            &deviceInfoLength,
            &deviceInfoData
            ))
        {
            HANDLE deviceHandle;
            PDISK_ENUM_ENTRY diskEntry;
            WCHAR diskFriendlyName[MAX_PATH] = L"";

            // This crashes on XP with error 0xC06D007F
            //SetupDiGetDeviceProperty(
            //    deviceInfoHandle,
            //    &deviceInfoData,
            //    &DEVPKEY_Device_FriendlyName,
            //    &devicePropertyType,
            //    (PBYTE)diskFriendlyName,
            //    ARRAYSIZE(diskFriendlyName),
            //    NULL,
            //    0
            //    );

            if (!SetupDiGetDeviceRegistryProperty(
                deviceInfoHandle,
                &deviceInfoData,
                SPDRP_FRIENDLYNAME,
                NULL,
                (PBYTE)diskFriendlyName,
                ARRAYSIZE(diskFriendlyName),
                NULL
                ))
            {
                continue;
            }

            diskEntry = PhAllocate(sizeof(DISK_ENUM_ENTRY));
            memset(diskEntry, 0, sizeof(DISK_ENUM_ENTRY));

            diskEntry->DeviceIndex = ULONG_MAX; // Note: Do not initialize to zero.
            diskEntry->DeviceName = PhCreateString(diskFriendlyName);
            diskEntry->DevicePath = PhCreateString(deviceInterfaceDetail->DevicePath);

            if (NT_SUCCESS(DiskDriveCreateHandle(
                &deviceHandle,
                diskEntry->DevicePath
                )))
            {
                ULONG diskIndex = ULONG_MAX; // Note: Do not initialize to zero

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(
                    deviceHandle,
                    &diskIndex,
                    NULL
                    )))
                {
                    PPH_STRING diskMountPoints = PH_AUTO_T(PH_STRING, DiskDriveQueryDosMountPoints(diskIndex));

                    diskEntry->DeviceIndex = diskIndex;
                    diskEntry->DevicePresent = TRUE;

                    if (!PhIsNullOrEmptyString(diskMountPoints))
                    {
                        diskEntry->DeviceMountPoints = PhFormatString(
                            L"Disk %lu (%s) [%s]",
                            diskIndex,
                            diskMountPoints->Buffer,
                            diskFriendlyName
                            );
                    }
                    else
                    {
                        diskEntry->DeviceMountPoints = PhFormatString(
                            L"Disk %lu [%s]",
                            diskIndex,
                            diskFriendlyName
                            );
                    }
                }

                NtClose(deviceHandle);
            }

            PhAddItemList(deviceList, diskEntry);
        }

        PhFree(deviceInterfaceDetail);
    }

    SetupDiDestroyDeviceInfoList(deviceInfoHandle);

    // Sort the entries
    qsort(deviceList->Items, deviceList->Count, sizeof(PVOID), DiskEntryCompareFunction);

    Context->EnumeratingDisks = TRUE;
    PhAcquireQueuedLockShared(&DiskDrivesListLock);

    for (ULONG i = 0; i < deviceList->Count; i++)
    {
        PDISK_ENUM_ENTRY entry = deviceList->Items[i];

        AddDiskDriveToListView(
            Context,
            entry->DevicePresent,
            entry->DevicePath,
            entry->DeviceMountPoints ? entry->DeviceMountPoints : entry->DeviceName
            );

        if (entry->DeviceMountPoints)
            PhDereferenceObject(entry->DeviceMountPoints);
        if (entry->DeviceName)
            PhDereferenceObject(entry->DeviceName);
        // Note: DevicePath is disposed by WM_DESTROY.

        PhFree(entry);
    }

    PhReleaseQueuedLockShared(&DiskDrivesListLock);
    Context->EnumeratingDisks = FALSE;


    // HACK: Show all unknown devices.
    Context->EnumeratingDisks = TRUE;
    PhAcquireQueuedLockShared(&DiskDrivesListLock);

    for (ULONG i = 0; i < DiskDrivesList->Count; i++)
    {
        ULONG index = -1;
        BOOLEAN found = FALSE;
        PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);

        if (!entry)
            continue;

        while ((index = PhFindListViewItemByFlags(
            Context->ListViewHandle,
            index,
            LVNI_ALL
            )) != -1)
        {
            PDV_DISK_ID param;

            if (PhGetListViewItemParam(Context->ListViewHandle, index, &param))
            {
                if (EquivalentDiskId(param, &entry->Id))
                {
                    found = TRUE;
                }
            }
        }

        if (!found)
        {
            PPH_STRING description;

            if (description = PhCreateString(L"Unknown disk"))
            {
                AddDiskDriveToListView(
                    Context,
                    FALSE,
                    entry->Id.DevicePath,
                    description
                    );

                PhDereferenceObject(description);
            }
        }

        PhDereferenceObjectDeferDelete(entry);
    }

    PhReleaseQueuedLockShared(&DiskDrivesListLock);
    Context->EnumeratingDisks = FALSE;
}
Exemplo n.º 6
0
VOID DiskDrivesUpdate(
    VOID
    )
{
    static ULONG runCount = 0; // MUST keep in sync with runCount in process provider

    PhAcquireQueuedLockShared(&DiskDrivesListLock);

    for (ULONG i = 0; i < DiskDrivesList->Count; i++)
    {
        HANDLE deviceHandle = NULL;
        PDV_DISK_ENTRY entry;

        entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);

        if (!entry)
            continue;

        if (NT_SUCCESS(DiskDriveCreateHandle(
            &deviceHandle, 
            entry->Id.DevicePath
            )))
        {
            DISK_PERFORMANCE diskPerformance;

            if (NT_SUCCESS(DiskDriveQueryStatistics(
                deviceHandle,
                &diskPerformance
                )))
            {
                ULONG64 readTime;
                ULONG64 writeTime;
                ULONG64 idleTime;
                ULONG readCount;
                ULONG writeCount;
                ULONG64 queryTime;

                PhUpdateDelta(&entry->BytesReadDelta, diskPerformance.BytesRead.QuadPart);
                PhUpdateDelta(&entry->BytesWrittenDelta, diskPerformance.BytesWritten.QuadPart);
                PhUpdateDelta(&entry->ReadTimeDelta, diskPerformance.ReadTime.QuadPart);
                PhUpdateDelta(&entry->WriteTimeDelta, diskPerformance.WriteTime.QuadPart);
                PhUpdateDelta(&entry->IdleTimeDelta, diskPerformance.IdleTime.QuadPart);
                PhUpdateDelta(&entry->ReadCountDelta, diskPerformance.ReadCount);
                PhUpdateDelta(&entry->WriteCountDelta, diskPerformance.WriteCount);
                PhUpdateDelta(&entry->QueryTimeDelta, diskPerformance.QueryTime.QuadPart);

                readTime = entry->ReadTimeDelta.Delta;
                writeTime = entry->WriteTimeDelta.Delta;
                idleTime = entry->IdleTimeDelta.Delta;
                readCount = entry->ReadCountDelta.Delta;
                writeCount = entry->WriteCountDelta.Delta;
                queryTime = entry->QueryTimeDelta.Delta;

                if (readCount + writeCount != 0)
                    entry->ResponseTime = ((FLOAT)readTime + (FLOAT)writeTime) / (readCount + writeCount);
                else
                    entry->ResponseTime = 0;

                if (queryTime != 0)
                    entry->ActiveTime = (FLOAT)(queryTime - idleTime) / queryTime * 100;
                else
                    entry->ActiveTime = 0.0f;

                if (entry->ActiveTime > 100.f)
                    entry->ActiveTime = 0.f;
                if (entry->ActiveTime < 0.f)
                    entry->ActiveTime = 0.f;

                entry->QueueDepth = diskPerformance.QueueDepth;
                entry->SplitCount = diskPerformance.SplitCount;
            }
            else
            {
                // Disk has been disconnected or dismounted.
                PhInitializeDelta(&entry->BytesReadDelta);
                PhInitializeDelta(&entry->BytesWrittenDelta);
                PhInitializeDelta(&entry->ReadTimeDelta);
                PhInitializeDelta(&entry->WriteTimeDelta);
                PhInitializeDelta(&entry->IdleTimeDelta);
                PhInitializeDelta(&entry->ReadCountDelta);
                PhInitializeDelta(&entry->WriteCountDelta);
                PhInitializeDelta(&entry->QueryTimeDelta);

                entry->ResponseTime = 0;
                entry->ActiveTime = 0.0f;
                entry->QueueDepth = 0;
                entry->SplitCount = 0;
            }

            // HACK: Pull the Disk name from the current query.
            if (!entry->DiskName)
            {
                DiskDriveQueryDeviceInformation(deviceHandle, NULL, &entry->DiskName, NULL, NULL);
            }

            // HACK: Pull the Disk index from the current query.
            if (entry->DiskIndex == ULONG_MAX)
            {
                ULONG diskIndex = ULONG_MAX; // Note: Do not initialize to zero.

                if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(deviceHandle, &diskIndex, NULL)))
                {
                    entry->DiskIndex = diskIndex;
                }
            }

            NtClose(deviceHandle);
        }
        else
        {
            // Disk has been disconnected or dismounted.
            PhInitializeDelta(&entry->BytesReadDelta);
            PhInitializeDelta(&entry->BytesWrittenDelta);
            PhInitializeDelta(&entry->ReadTimeDelta);
            PhInitializeDelta(&entry->WriteTimeDelta);
            PhInitializeDelta(&entry->IdleTimeDelta);
            PhInitializeDelta(&entry->ReadCountDelta);
            PhInitializeDelta(&entry->WriteCountDelta);
            PhInitializeDelta(&entry->QueryTimeDelta);

            entry->ResponseTime = 0;
            entry->ActiveTime = 0.0f;
            entry->QueueDepth = 0;
            entry->SplitCount = 0;
        }

        if (!entry->HaveFirstSample)
        {
            // The first sample must be zero.
            entry->BytesReadDelta.Delta = 0;
            entry->BytesWrittenDelta.Delta = 0;
            entry->HaveFirstSample = TRUE;
        }

        if (runCount != 0)
        {
            PhAddItemCircularBuffer_ULONG64(&entry->ReadBuffer, entry->BytesReadDelta.Delta);
            PhAddItemCircularBuffer_ULONG64(&entry->WriteBuffer, entry->BytesWrittenDelta.Delta);
        }

        PhDereferenceObjectDeferDelete(entry);
    }

    PhReleaseQueuedLockShared(&DiskDrivesListLock);

    runCount++;
}