Reputation: 23
I run my program that gets HDD SMART attributes as admin, but get this error: Failed to get S.M.A.R.T. data. Error code: 5 Error message: Access is denied.
Why access is denied?How to fix it?Program seems to be correct,if not,please help to correct it.
void GetSMART()
{
// Открытие физического диска
int driveNumber = 0; // № диска
wstring drivePath = L"\\\\.\\PhysicalDrive" + std::to_wstring(driveNumber);
HANDLE hDrive = CreateFile(drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (hDrive == INVALID_HANDLE_VALUE) {
return;
}
// Получение S.M.A.R.T.
bool isGetData;
DWORD bytesReturned;
const int inParamsSize = sizeof(SENDCMDINPARAMS) - 1;
SENDCMDINPARAMS inParams = { 0 };
inParams.cBufferSize = READ_ATTRIBUTE_BUFFER_SIZE;
inParams.irDriveRegs.bFeaturesReg = READ_ATTRIBUTES;
inParams.irDriveRegs.bSectorCountReg = 1;
inParams.irDriveRegs.bSectorNumberReg = 1;
inParams.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
inParams.irDriveRegs.bCylHighReg = SMART_CYL_HI;
inParams.irDriveRegs.bDriveHeadReg = 0xA0 | ((static_cast<BYTE>(driveNumber) & 1) << 4);
inParams.irDriveRegs.bCommandReg = SMART_CMD;
const int outParamsSize = sizeof(SENDCMDOUTPARAMS) - 1 + READ_ATTRIBUTE_BUFFER_SIZE;
SENDCMDOUTPARAMS outParamsAttributes[outParamsSize] = { 0 };
isGetData = DeviceIoControl(hDrive, SMART_RCV_DRIVE_DATA,
&inParams, inParamsSize, &outParamsAttributes, outParamsSize, &bytesReturned, NULL);
if (!isGetData) {
DWORD errorCode = GetLastError();
LPSTR errorMessage = nullptr;
DWORD result = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPSTR>(&errorMessage),
0,
nullptr
);
if (result != 0) {
std::cout << "Failed to get S.M.A.R.T. data. Error code: " << errorCode << std::endl;
std::cout << "Error message: " << errorMessage << std::endl;
}
else {
std::cout << "Failed to retrieve error message." << std::endl;
}
LocalFree(errorMessage);
CloseHandle(hDrive);
return;
}
}
Upvotes: 1
Views: 425
Reputation: 51
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.
Upvotes: 0