SMART_RCV_DRIVE_DATA & SMART_SEND_DRIVE_COMMAND
Je compte sur vous pour améliorer la qualité des informations contenue sur cette page…
DeviceIOControl
SMART_RCV_DRIVE_DATA
et SMART_SEND_DRIVE_COMMAND
sont des un codes de contrôle (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); // Ou... DeviceIoControl(AHandle, SMART_SEND_DRIVE_COMMAND, @vSCIP, sizeof(TSendCmdInParams), @vSCOP, sizeof(TSendCmdOutParams), 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
SMART_RCV_DRIVE_DATA | ||||||||
---|---|---|---|---|---|---|---|---|
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 | |||||||
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 | |||||||
SMART_SEND_DRIVE_COMMAND | ||||||||
IDEREGS Features | Rôle | SENDCMDINPARAMS BufferSize | IDEREGS SectorCount | IDEREGS SectorNumber | IDEREGS CylLow | IDEREGS CylHigh | ||
ENABLE_SMART $D8 | Active SMART | 0 | 1 | 1 | SMART_CYL_LOW ($4F) | SMART_CYL_HI ($C2) | ||
DISABLE_SMART $D9 | Désactive SMART |
Types communs pour les Features
TicSendCmdOutParams
Le type TicSendCmdOutParams
est une variante du type TSendCmdOutParams
présent dans l'unité jwaWinIoCtl.pas
(Ici on parle Pascal et Lazarus plus précisément)
auquel j'ai enlevé le dernier membre (bBuffer: array [0..0] of BYTE
) pour qu'il puisse être inclus dans un type TSCOP_XXXXXXX.
Bon, je ne sais pas si c'est une bonne idée, mais c'est la mienne a l'instant T.
Et ça fonctionne en plus !
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; (voir ci-dessus) 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
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 Membre d'un Attribut
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
Les Membres de Threshold
30 max comme le nombre d'attributs
ID
ID de l'attribut auquel correspond ce Threshold
Threshold
Valeur sur 1 octet, seuil indiquant quand un disque est sur le point de tomber en panne.
Interpretation du Threshold
Pour l'instant, je ne sais pas trop.
Dés que j'ai plus d'infos je les mettrai ici !
ENABLE_DISABLE_AUTOSAVE
SAVE_ATTRIBUTE_VALUES
EXECUTE_OFFLINE_DIAGS
SMART_READ_LOG
SMART_WRITE_LOG
ENABLE_SMART
On peut estimer que si la commande DeviceIOControl renvoi True
alors le SMART est activé.