Есть ли "программный" способ определить, вращается диск или нет (вращение, не обязательно чтение / запись)?
1 ответ
Вращается ли диск, зависит от его режима питания; обычно двигатель шпинделя работает в режимах «Активный» и «Холостой» и останавливается в режимах «Ожидание» и «Спящий режим». (С накопителями с управлением питанием кеша NV это немного усложняется, о чем я пока не знаю.)
Если диск спит, он определенно не вращается (или делает что-то еще, включая общение с хостом); в противном случае вы можете опросить его о его текущем режиме.
Для привода ATA команда «Проверить режим питания» сделает это. Отправьте значение E5
в регистр команд, и оно вернет FF
в регистр подсчета секторов, если привод активен или находится в режиме ожидания.
Делать это программно - рискнуть на территорию Stack Overflow, но вот фрагмент C, который сделает это в Windows:
int isSpinning = -1;
HANDLE hDevice = CreateFile(TEXT("\\\\.\\PHYSICALDRIVE0"), GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hDevice != INVALID_HANDLE_VALUE)
{
DWORD cb = 0;
ATA_PASS_THROUGH_EX cmd = {sizeof(ATA_PASS_THROUGH_EX)};
cmd.AtaFlags = ATA_FLAGS_DRDY_REQUIRED; /* Require drive to be ready */
cmd.TimeOutValue = 3; /* Arbitrary timeout (seconds) */
cmd.CurrentTaskFile[6] = 0xE5; /* "Check Power Mode" in command register */
if (DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, &cmd, sizeof(cmd), &cmd, sizeof(cmd), &cb, 0))
{
/* FF in sector count register means the drive is
active or idle (and therefore spinning) */
isSpinning = cmd.CurrentTaskFile[1] == 0xFF;
}
}