user2320492
user2320492

Reputation: 151

Get Harddrrive performance under windows using C++

I have a question divided into several parts and hope you can help me solving it. I'm trying to writ some code to help me get the hard disk performance in interval period of time.

It would be basically like using performance under Task manager in windows like the following pic: enter image description here

but instead of the read speed the actual read/write number of bytes.

I followed some guides in order to do so and end up with the following code:

HANDLE OpenTarget(PCWSTR lpName)
{
    HANDLE hTarget;
    hTarget = CreateFile(lpName,
        0,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);

    return hTarget;
}

long total_disk_read() noexcept {
    HANDLE hTarget = OpenTarget(wszDrive);

    if (hTarget == INVALID_HANDLE_VALUE)
    {
        LOG(error) << "Failed to get Disk info, code: " << GetLastError();
        return 0 ;
    }

    DISK_PERFORMANCE dp = { 0 };
    DWORD cbOutBufferSize = sizeof(DISK_PERFORMANCE);
    DWORD cbBytesReturned = 0;
    LPVOID lpOutBuffer = (LPVOID)&dp;

    if (!DeviceIoControl(hTarget, IOCTL_DISK_PERFORMANCE, NULL, 0, lpOutBuffer, cbOutBufferSize, &cbBytesReturned, NULL))
    {
        LOG(error) << "Failed to get Disk Performance info, code: " << GetLastError();
        CloseHandle(hTarget);
        return 0 ;
    }
    else {
        CloseHandle(hTarget);
        return dp.BytesRead.QuadPart;
    }
}

Now I have two questions:

1- I understand that dp.BytesRead returns long_integer defined in windows.h lib. I 'm using long it to reserve the results. Is there a better format to use. 2- I noticed that each time the return read is increasing which mean that the read counter is not reset on each read. Is this correct? and how to solve it ?

Thanks in advance.

Upvotes: 2

Views: 389

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

The safest would be to let your function return a LARGE_INTEGER or a int64_t (since a LARGE_INTEGER is a signed 64 bit integer).

Save the value of the previous read and reduce the returned value by that value.

int64_t disk_read_since_last_check() noexcept {
    static int64_t previous_read=0;
    //...
    int64_t rv = dp.BytesRead.QuadPart - previous_read;
    previous_read = dp.BytesRead.QuadPart;
    return rv;
}

Upvotes: 1

Related Questions