none
DeciceIoControl SMART_SEND_DRIVECOMMAND get empty output RRS feed

  • Question

  • Dear all ,

    I write a simple program use DeviceIOControl to send smart command let drive run short self offline test,

    the return value of deviceIoControl is success , but I did not get any result of drive self test. 

    Here is my code, I always get NULL in driver error.

    Could anyone tell what I was wrong? Thanks a lot.

    #include "stdafx.h"

    #include <Windows.h>
    #include <devioctl.h>
    #include <Ntdddisk.h>

    #define DRIVE_HEAD_REG 0xA0

    int _tmain(int argc, _TCHAR* argv[])
    {
    HANDLE hDevice=NULL;
    char szT1[MAX_PATH]={0};
    BOOL bRet=FALSE;
    DWORD dwRet=0;

    //wsprintf(szT1,"\\\\.\\PHYSICALDRIVE%d",ucDriveIndex);
    hDevice=CreateFile(L"\\\\.\\PhysicalDrive0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,NULL);
    if(hDevice!=INVALID_HANDLE_VALUE)
    {
    SENDCMDINPARAMS stCIP={0};
    SENDCMDOUTPARAMS stCOP={0};
    DWORD dwRet=0;
    BOOL bRet=FALSE;

    stCIP.cBufferSize=0;
    stCIP.bDriveNumber =0;
    stCIP.irDriveRegs.bFeaturesReg = EXECUTE_OFFLINE_DIAGS;
    stCIP.irDriveRegs.bSectorCountReg = 1;
    stCIP.irDriveRegs.bSectorNumberReg=SMART_SHORT_SELFTEST_OFFLINE;
    stCIP.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
    stCIP.irDriveRegs.bCylHighReg = SMART_CYL_HI;
    stCIP.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
    stCIP.irDriveRegs.bCommandReg = SMART_CMD;

    bRet=DeviceIoControl(hDevice,SMART_SEND_DRIVE_COMMAND,&stCIP,sizeof(stCIP)-1,&stCOP,sizeof(stCOP)-1,&dwRet,NULL);
    if(bRet)
    {

    printf("smart enable success\n");

    printf("driver error = %s\n",stCOP.DriverStatus.bDriverError);

    }
    else
    {
    dwRet=GetLastError();
    printf("smart enable error : %d\n", dwRet);
    //m_stDrivesInfo[ucDriveIndex].m_csErrorString.Format("Error %d in reading SMART Enabled flag",dwRet);
    }

    }else
    {
    int error = GetLastError();
    printf("get drive faile , error = %d\n",error);
    }
    system("Pause");
    return 0;
    }

    Friday, May 10, 2013 8:17 AM

All replies

  • If you check the definition of DriverStatus http://msdn.microsoft.com/en-us/library/windows/hardware/ff552658(v=vs.85).aspx you will see that bDriverError is a byte, not a string and zero represents no error.


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com Blog: http://msmvps.com/blogs/WinDrvr

    Friday, May 10, 2013 11:12 AM
  • But I got bDriverError is always null, not 0.

    And it seems that the disk did not run any self test.

    Is there any way that I can call disk to run drive self test (dst) ?

    Thanks a lot.

    Monday, May 13, 2013 11:24 AM
  • NULL is 0 they are the same value.  As I stated, this is a BYTE, so trying to display as a string with %s is wrong.  %s takes a pointer, and you have a single byte of data!!!!!


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com Blog: http://msmvps.com/blogs/WinDrvr

    • Marked as answer by Doron Holan [MSFT] Monday, May 13, 2013 2:18 PM
    • Unmarked as answer by Gary1123 Thursday, May 16, 2013 6:06 AM
    Monday, May 13, 2013 11:53 AM
  • Gary1123,

        Since I noticed you again unmarked the answer, I am wondering if you can say what you think is wrong with the data we are giving you? 

        Looking at your code, I would recommend:

    #include "stdafx.h"

    #include <Windows.h>
    #include <devioctl.h>
    #include <Ntdddisk.h>

    #define DRIVE_HEAD_REG 0xA0

    int _tmain(int argc, _TCHAR* argv[])
    {
    HANDLE hDevice=NULL;
    char szT1[MAX_PATH]={0};
    BOOL bRet=FALSE;
    DWORD dwRet=0;

    //wsprintf(szT1,"\\\\.\\PHYSICALDRIVE%d",ucDriveIndex);
    hDevice=CreateFile(L"\\\\.\\PhysicalDrive0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,NULL);
    if(hDevice!=INVALID_HANDLE_VALUE)
    {
    SENDCMDINPARAMS stCIP={0};
    SENDCMDOUTPARAMS stCOP={0};
    DWORD dwRet=0;
    BOOL bRet=FALSE;

    stCIP.cBufferSize=0;
    stCIP.bDriveNumber =0;
    stCIP.irDriveRegs.bFeaturesReg = EXECUTE_OFFLINE_DIAGS;
    stCIP.irDriveRegs.bSectorCountReg = 1;
    stCIP.irDriveRegs.bSectorNumberReg=SMART_SHORT_SELFTEST_OFFLINE;
    stCIP.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
    stCIP.irDriveRegs.bCylHighReg = SMART_CYL_HI;
    stCIP.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
    stCIP.irDriveRegs.bCommandReg = SMART_CMD;

    bRet=DeviceIoControl(hDevice,SMART_SEND_DRIVE_COMMAND,&stCIP,sizeof(stCIP)-1,&stCOP,sizeof(stCOP)-1,&dwRet,NULL);
    if(bRet)
    {
          if ( stCOP.DriverStatus.bDriverError == 0 )

          {

                printf("smart enable success\n");

          }

          else

          {

               printf("disk error = %s\n",stCOP.DriverStatus.bDriverError);

           }
    }
    else
    {
         dwRet=GetLastError();
         printf("smart enable error : %d\n", dwRet);
    }

    }else
    {
    int error = GetLastError();
    printf("get drive faile , error = %d\n",error);
    }
    system("Pause");
    return 0;
    }


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com Blog: http://msmvps.com/blogs/WinDrvr

    • Marked as answer by Doron Holan [MSFT] Thursday, May 16, 2013 2:12 PM
    • Unmarked as answer by Gary1123 Friday, May 17, 2013 6:58 AM
    Thursday, May 16, 2013 2:05 PM
  • I unmarked because I still can not make sure the disk has run self - test after the DeviceIOControl has been called immediately.

    The self -test need run more than 1 min as I know, but I got output form deviceIOcontrol so fast.

    So my question is how to tell hard disk to run dst program and how to get the test result?

    Thanks a lot. 

    Friday, May 17, 2013 5:58 AM
  • There is nothing that says the disk has to issue the offline test once the drive is active.  I suspect your hardware is just ignoring the call and returning success.


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com Blog: http://msmvps.com/blogs/WinDrvr

    Friday, May 17, 2013 1:06 PM