Участник клуба
Регистрация: 03.06.2009
Сообщений: 1,869
|
Код:
TIdSector=_IDSECTOR;
IDSECTOR=_IDSECTOR;
PSendCMDOutParams=^TSendCMDOutParams;
_SENDCMDOUTPARAMS=packed record
cBufferSize:DWORD;
DriverStatus:DRIVERSTATUS;
bBuffer:array[0..0] of BYTE; // drive.
end;
TSendCMDOutParams=_SENDCMDOUTPARAMS;
SENDCMDOUTPARAMS=_SENDCMDOUTPARAMS;
PDriveAttribute=^TDriveAttribute;
_DRIVEATTRIBUTE=packed record
bAttrID:BYTE;
wStatusFlags:WORD;
bAttrValue:BYTE;
bWorstValue:BYTE;
bRawValue:array[0..5]of BYTE;
bReserved:BYTE;
end;
TDriveAttribute=_DRIVEATTRIBUTE;
DRIVEATTRIBUTE=_DRIVEATTRIBUTE;
PAttrThreshold=^TAttrThreshold;
_ATTRTHRESHOLD=packed record
bAttrID:BYTE;
bWarrantyThreshold:BYTE;
bReserved:array[0..9]of BYTE;
end;
TAttrThreshold=_ATTRTHRESHOLD;
ATTRTHRESHOLD=_ATTRTHRESHOLD;
SMARTAttributes=packed array[0..NUM_ATTRIBUTE_STRUCTS-1] of TDriveAttribute;
PSMARTAttributes=^SMARTAttributes;
SMARTThresholds=packed array[0..NUM_ATTRIBUTE_STRUCTS-1]of TAttrThreshold;
PSMARTThresholds=^SMARTThresholds;
function OpenSMART:THandle;
var ver:TOSVERSIONINFO;
begin
result:=0;
ver.dwOSVersionInfoSize:=Sizeof(ver);
GetVersionEx(ver);
if(ver.dwPlatformId=VER_PLATFORM_WIN32_NT)then result:=CreateFile('\\.\PhysicalDrive0',GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
end;
function DoIdentify(hSMARTIOCtl:THandle;SCIP:PSendCMDInParams;SCOP:PSendCMDOutParams;IDCmd:byte;DriveNum:byte;lpcbBytesReturned:DWORD):boolean;
begin
SCIP^.cBufferSize:=IDENTIFY_BUFFER_SIZE;
SCIP^.irDriveRegs.bFeaturesReg:=0;
SCIP^.irDriveRegs.bSectorCountReg:=1;
SCIP^.irDriveRegs.bSectorNumberReg:=1;
SCIP^.irDriveRegs.bCylLowReg:=0;
SCIP^.irDriveRegs.bCylHighReg:=0;
SCIP^.irDriveRegs.bDriveHeadReg:=$A0 or((DriveNum and 1)shl 4);
SCIP^.irDriveRegs.bCommandReg:=IDCmd;
SCIP^.bDriveNumber:=DriveNum;
SCIP^.cBufferSize:=IDENTIFY_BUFFER_SIZE;
result:=DeviceIoControl(hSMARTIOCtl,DFP_RECEIVE_DRIVE_DATA,@SCIP^,SizeOf(SENDCMDINPARAMS)-1,@SCOP^,SizeOf(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE-1,lpcbBytesReturned,nil);
end;
function DoEnableSMART(hSMARTIOCtl:THandle;SCIP:PSendCMDInParams;SCOP:PSendCMDOutParams;DriveNum:byte;lpcbBytesReturned:DWORD):boolean;
begin
SCIP^.cBufferSize:=0;
SCIP^.irDriveRegs.bFeaturesReg:=SMART_ENABLE_SMART_OPERATIONS;
SCIP^.irDriveRegs.bSectorCountReg:=1;
SCIP^.irDriveRegs.bSectorNumberReg:=1;
SCIP^.irDriveRegs.bCylLowReg:=SMART_CYL_LOW;
SCIP^.irDriveRegs.bCylHighReg:=SMART_CYL_HI;
SCIP^.irDriveRegs.bDriveHeadReg:=$A0 or((DriveNum and 1)shl 4);
SCIP^.irDriveRegs.bCommandReg:=IDE_EXECUTE_SMART_FUNCTION;
SCIP^.bDriveNumber:=DriveNum;
result:=DeviceIoControl(hSMARTIOCtl,DFP_SEND_DRIVE_COMMAND,@SCIP^,SizeOf(SENDCMDINPARAMS)-1,@SCOP^,SizeOf(SENDCMDOUTPARAMS)-1,lpcbBytesReturned,nil);
end;
function DoReadAttributesCmd(hSMARTIOCtl:THandle;SCIP:PSendCMDInParams;SCOP:PSendCMDOutParams;DriveNum:byte):boolean;
var cbBytesReturned:DWORD;
begin
SCIP^.cBufferSize:=READ_ATTRIBUTE_BUFFER_SIZE;
SCIP^.irDriveRegs.bFeaturesReg:=SMART_READ_ATTRIBUTE_VALUES;
SCIP^.irDriveRegs.bSectorCountReg:=1;
SCIP^.irDriveRegs.bSectorNumberReg:=1;
SCIP^.irDriveRegs.bCylLowReg:=SMART_CYL_LOW;
SCIP^.irDriveRegs.bCylHighReg:=SMART_CYL_HI;
SCIP^.irDriveRegs.bDriveHeadReg:=$A0 or((DriveNum and 1)shl 4);
SCIP^.irDriveRegs.bCommandReg:=IDE_EXECUTE_SMART_FUNCTION;
SCIP^.bDriveNumber:=DriveNum;
result:=DeviceIoControl(hSMARTIOCtl,DFP_RECEIVE_DRIVE_DATA,@SCIP^,SizeOf(SENDCMDINPARAMS)-1,@SCOP^,SizeOf(SENDCMDOUTPARAMS)+READ_ATTRIBUTE_BUFFER_SIZE-1,cbBytesReturned,nil);
end;
function StrMove(Dest:PChar;const Source:PChar;Count:Cardinal):PChar;assembler;
asm
PUSH ESI
PUSH EDI
MOV ESI,EDX
MOV EDI,EAX
MOV EDX,ECX
CMP EDI,ESI
JA @@1
JE @@2
SHR ECX,2
REP MOVSD
MOV ECX,EDX
AND ECX,3
REP MOVSB
JMP @@2
@@1: LEA ESI,[ESI+ECX-1]
LEA EDI,[EDI+ECX-1]
AND ECX,3
STD
REP MOVSB
SUB ESI,3
SUB EDI,3
MOV ECX,EDX
SHR ECX,2
REP MOVSD
CLD
@@2: POP EDI
POP ESI
end;
var HSmart:THandle;
VersionParams:TGetVersionOutParams;
i:integer;
cbBytesReturned:DWORD;
SN,MN:string;//серийный номер, номер модели
procedure ChangeByteOrder(szString:PChar;StrSize:Integer);
var i:Integer;
Temp:Char;
begin
for i:=0 to(StrSize-1)div 2 do
begin
Temp:=szString[i*2];
szString[i*2]:=szString[i*2+1];
szString[i*2+1]:=Temp;
end;
end;
function DisplayIdInfo(Ids:PIdSector;DriveNum:byte):string;
var szOutBuffer:array[0..40]of Char;
begin
//----- номер модели --------------------------------------------------------
MN:='';
ChangeByteOrder(Ids^.sModelNumber,SizeOf(Ids^.sModelNumber));
StrMove(szOutBuffer,Ids^.sModelNumber,SizeOf(Ids^.sModelNumber));
MN:=szOutBuffer;
while(Pos(' ',MN)<>0)do Delete(MN,Pos(' ',MN),1);//убираем лишние прбелы
if(MN<>'')then WriteLn('HDD '+'Nomer Modeli: '+MN);
//----- серийный номер ------------------------------------------------------
SN:='';
ChangeByteOrder(Ids^.sSerialNumber,SizeOf(Ids^.sSerialNumber));
StrMove(szOutBuffer,Ids^.sSerialNumber,SizeOf(Ids^.sSerialNumber));
SN:=szOutBuffer;
while(Pos(' ',SN)<>0)do Delete(SN,Pos(' ',SN),1);//убираем лишние прбелы
if(SN<>'')then WriteLn(' Nomer Serial: '+SN);
end;
function PrintDriveInfo(DriveNum:byte):string;
var IdOutCmd:pointer;
bIDCmd:byte;
Scip:PSendCMDInParams;
begin
result:='';
if((VersionParams.bIDEDeviceMap shr DriveNum and 1)>0)then
begin
if((VersionParams.bIDEDeviceMap shr DriveNum and $10)>0)then bIDCmd:=IDE_ATAPI_ID
else bIDCmd:=IDE_ID_FUNCTION;
New(Scip);
GetMem(IdOutCmd,sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE-1);
try
cbBytesReturned:=0;
if(DoIDENTIFY(HSmart,Scip,IdOutCmd,bIDCmd,DriveNum,cbBytesReturned))then result:=DisplayIdInfo(Pointer(longint(IdOutCmd)+sizeof(SENDCMDOUTPARAMS)-1),DriveNum);
finally
FreeMem(IdOutCmd);
FreeMem(Scip);
end;
end;
end;
begin
HSmart:=OpenSMART;
if(HSmart<>INVALID_HANDLE_VALUE)and(DeviceIoControl(HSmart,DFP_GET_VERSION,nil,0,@VersionParams,sizeof(VersionParams),cbBytesReturned,nil))then
for i:=0 to MAX_IDE_DRIVES-1 do PrintDriveInfo(i);
CloseHandle(HSmart);
ReadLn;
end.
Программирование - это единственный способ заставить компьютер делать то, что тебе хочется, а не то, что приходится.
|