Ceci est une ancienne révision du document !
SMART_RCV_DRIVE_DATA
Je compte sur vous pour améliorer la qualité des informations contenue sur cette page…
DeviceIOControl
SMART_RCV_DRIVE_DATA est un code de controle (dwIoControlCode
) utilisé dans l'appel a l'API DeviceIoControl
Déclaration
BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped );
Exemple d'appel
Exemple d'appel en Pascal (parce que moi j'aime bien le Pascal)
var vSCIP: TSendCmdInParams; vSCOP: TSendCmdOutParams; vOutSize: dword; begin ... DeviceIoControl(AHandle, SMART_RCV_DRIVE_DATA, @vSCIP, sizeof(TSendCmdInParams), @vSCOP, sizeof(TSendCmdOutParams)+BufferSize, vOutSize, nil);
Structures
SENDCMDOUTPARAMS
Source : SENDCMDOUTPARAMS chez Microsoft
La Structure SENDCMDOUTPARAMS contient la réponse fournie par l'API.
Cette structure est remplie par l'API pas besoin de la pré-remplir.
typedef struct _SENDCMDOUTPARAMS { ULONG cBufferSize; DRIVERSTATUS DriverStatus; UCHAR bBuffer[1]; } SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
Structure SENDCMDINPARAMS
Source : SENDCMDINPARAMS chez Microsoft
typedef struct _SENDCMDINPARAMS { ULONG cBufferSize; // Taille du buffer de sortie BufferSize dans le tableau ci-dessous IDEREGS irDriveRegs; // Strucutre IDEREGS contenant les paramètres d'appel (voir ci-dessous) UCHAR bDriveNumber; // Numero du disk (exemple: avec \\.\PhysicalDrive5, le numéro du disque est 5) UCHAR bReserved[3]; ULONG dwReserved[4]; UCHAR bBuffer[1]; } SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
Structure IDEREGS
Source : IDEREGS chez Microsoft
La Structure IDEREGS est une sous structure de SENDCMDINPARAMS (voir ci-dessus) contenant les paramètres utiles a l'appel de l'API.
typedef struct _IDEREGS { UCHAR bFeaturesReg; // La fonction qu'on appel, Features dans le tableau ci-dessous UCHAR bSectorCountReg; // SectorCount dans tableau : Nombre de secteur (je pense...) UCHAR bSectorNumberReg; // Sectornumber dans tableau : Numéro du premier secteur (je pense...) UCHAR bCylLowReg; // CylLow dans tableau : Cylindre Bas ??? UCHAR bCylHighReg; // CylHigh dans tableau : Cylindre Haut ??? UCHAR bDriveHeadReg; // $A0 or ((DriveNumber and 1) shl 4); en Pascal. Pourquoi ??? je ne sais pas.. UCHAR bCommandReg; // toujours SMART_CMD ( $B0) avec SMART_RVC_DRIVE_DATA UCHAR bReserved; } IDEREGS, *PIDEREGS, *LPIDEREGS;
Features
IDEREGS Features | Rôle | SENDCMDINPARAMS BufferSize | IDEREGS SectorCount | IDEREGS SectorNumber | IDEREGS CylLow | IDEREGS CylHigh | ||
---|---|---|---|---|---|---|---|---|
READ_ATTRIBUTES $D0 | Récupérer les attributs SMART | READ_ATTRIBUTE_BUFFER_SIZE (512) | 1 | 1 | SMART_CYL_LOW ($4F) | SMART_CYL_HI ($C2) | ||
READ_THRESHOLDS $D1 | Récupérer les valeurs de seuil qui indiquent quand un disque est sur le point de tomber en panne. | READ_THRESHOLD_BUFFER_SIZE (512) | 1 | 1 | SMART_CYL_LOW ($4F) | SMART_CYL_HI ($C2) | ||
ENABLE_DISABLE_AUTOSAVE $D2 | Active l'attribut optionnel autosave du périphérique lorsqu'il est défini à 1. Désactive cette fonction lorsqu'elle est définie à 0… | |||||||
SAVE_ATTRIBUTE_VALUES $D3 | Demande à l'appareil de sauvegarder ses valeurs d'attribut dans la mémoire non volatile de l'appareil. | |||||||
EXECUTE_OFFLINE_DIAGS $D4 | Permet à l'appareil de commencer à collecter des données SMART en mode hors ligne ou d'exécuter une routine de test d'autodiagnostic en mode captif ou hors ligne. | |||||||
SMART_READ_LOG $D5 | Récupère les Logs. | |||||||
SMART_WRITE_LOG $D6 | Écrit le nombre indiqué de secteurs de données de 512 octets dans les logs | |||||||
ENABLE_SMART $D8 | Active SMART | |||||||
DISABLE_SMART $D9 | Désactive SMART | |||||||
RETURN_SMART_STATUS $DA | Récupère l'état de fiabilité de l'appareil. | |||||||
ENABLE_DISABLE_AUTO_OFFLINE $DB | Active ou Désactive le mode hors ligne |
Types communs pour les Features
TTicSendCmdOutParams = packed record cBufferSize: DWORD; // Size of bBuffer in bytes DriverStatus: TDriverStatus; // Driver status structure. end;
READ_ATTRIBUTES
le SCOP (SendCmdOutParams) est suivi de deux Byte A et B dont je ne connais pas l'utilité.
Puis un tableau de 30 attributs SMART (TSmartAttrs)
Et de quelques byte, ici pour combler l'espace.
TSCOP_SmartAttrs = packed record SCOP: TTicSendCmdOutParams; A, B: byte; // ??? Results: TSmartAttrs; //array[0..29] of TSmartAttr; Reserved: array[1..150] of byte; // pour arriver a 512 end;
Avec les types suivants
TTicSendCmdOutParams = packed record cBufferSize: DWORD; // Size of bBuffer in bytes DriverStatus: TDriverStatus; // Driver status structure. end; TSmartAttr = packed record ID: byte; Flags: word; Current, Worst: byte; Raw: array[0..5] of byte; //[01 23 45 67 89 AB] correspond a $AB8967452301 Reserved: byte; end; TSmartAttrs = array[0..29] of TSmartAttr; // max of 30 attributes
Les Attributs
D’après ce que je constate il peut y avoir au maximum 30 attributs
ID
Flag
Current
Worst
Raw
READ_THRESHOLDS
le SCOP (SendCmdOutParams)
suivi d'un Word (2oct) indiquant la numéro de révision.
Puis un tableau de 30 Thresholds SMART (TSmartThresholds
)
Et de quelques byte, ici pour combler l'espace.
TSCOP_SmartThresholds = packed record SCOP : TTicSendCmdOutParams; RevNumber : word; // 2 oct Results : TSmartThresholds; // 360 oct Reserved : array[0..148] of byte; // 149 oct Chksum: byte; // 1 oct // total 512 = READ_THRESHOLD_BUFFER_SIZE end;
Avec les types suivants
TSmartThreshold = packed record ID: byte; //1 oct Threshold : byte; //1 oct Reserved : array[0..9] of byte; //10 oct // Total = 12 oct end; TSmartThresholds = array[0..C_SMART_MAX_ATTRS] of TSmartThreshold; //12x30 = 360 oct