Why access is denied?
Because the I/O control code SMART_RCV_DRIVE_DATA is defined in the winioctl.h header file as
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
Note that RequiredAccess parameter in the CTL_CODE macro is FILE_READ_ACCESS | FILE_WRITE_ACCESS.
How to fix it?
In order to fix the problem, you should call CreateFile() function specifying dwDesiredAccess as FILE_READ_DATA | FILE_WRITE_DATA, not just GENERIC_READ.
Like that:
HANDLE hDrive = CreateFile(drivePath.c_str(), FILE_READ_DATA | FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
GENERIC_READ | GENERIC_WRITE also will work:
HANDLE hDrive = CreateFile(drivePath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
Running it as Administrator is unnecessary.