Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- for displaying the details of hard drives in
- 06/11/2000 Lynn McGuire written with many contributions from others,
- IDE drives only under Windows NT/2K and 9X,
- maybe SCSI drives later
- translated by Wyfinger 14/08/2007, wyfinger@mail.ru
- }
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
- type
- TForm1 = class(TForm)
- Memo1: TMemo;
- Button1: TButton;
- Label1: TLabel;
- procedure Button1Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- type
- // GETVERSIONOUTPARAMS contains the data returned from the
- // Get Driver Version function.
- GETVERSIONOUTPARAMS = record
- bVersion : BYTE; // Binary driver version.
- bRevision : BYTE; // Binary driver revision.
- bReserved : BYTE; // Not used.
- bIDEDeviceMap : BYTE; // Bit map of IDE devices.
- fCapabilities : DWORD; // Bit mask of driver capabilities.
- dwReserved : array[0..3] of DWORD; // For future use.
- end;
- PGETVERSIONOUTPARAMS = ^GETVERSIONOUTPARAMS;
- LPGETVERSIONOUTPARAMS = ^GETVERSIONOUTPARAMS;
- // IDE registers
- IDEREGS = record
- bFeaturesReg : BYTE; // Used for specifying SMART "commands".
- bSectorCountReg : BYTE; // IDE sector count register
- bSectorNumberReg : BYTE; // IDE sector number register
- bCylLowReg : BYTE; // IDE low order cylinder value
- bCylHighReg : BYTE; // IDE high order cylinder value
- bDriveHeadReg : BYTE; // IDE drive/head register
- bCommandReg : BYTE; // Actual IDE command.
- bReserved : BYTE; // reserved for future use. Must be zero.
- end;
- PIDEREGS = ^IDEREGS;
- LPIDEREGS = ^IDEREGS;
- // SENDCMDINPARAMS contains the input parameters for the
- // Send Command to Drive function.
- SENDCMDINPARAMS = record
- cBufferSize : DWORD; // Buffer size in bytes
- irDriveRegs : IDEREGS; // Structure with drive register values.
- bDriveNumber : BYTE; // Physical drive number to send
- // command to (0,1,2,3).
- bReserved : array[0..2] of BYTE; // Reserved for future expansion.
- dwReserved : array[0..3] of DWORD; // For future use.
- bBuffer : array[0..0] of BYTE; // Input buffer.
- end;
- PSENDCMDINPARAMS = ^SENDCMDINPARAMS;
- LPSENDCMDINPARAMS = ^SENDCMDINPARAMS;
- // Status returned from driver
- DRIVERSTATUS = record
- bDriverError : BYTE; // Error code from driver, or 0 if no error.
- bIDEStatus : BYTE; // Contents of IDE Error register.
- // Only valid when bDriverError is SMART_IDE_ERROR.
- bReserved : array[0..1] of BYTE; // Reserved for future expansion.
- dwReserved : array[0..1] of DWORD; // Reserved for future expansion.
- end;
- PDRIVERSTATUS = ^DRIVERSTATUS;
- LPDRIVERSTATUS = ^DRIVERSTATUS;
- // Structure returned by PhysicalDrive IOCTL for several commands
- SENDCMDOUTPARAMS = record
- cBufferSize : DWORD; // Size of bBuffer in bytes
- DriverStatus : DRIVERSTATUS; // Driver status structure.
- bBuffer : array[0..0] of BYTE; // Buffer of arbitrary length in which to store the data read from the // drive.
- end;
- PSENDCMDOUTPARAMS = ^SENDCMDOUTPARAMS;
- LPSENDCMDOUTPARAMS = ^SENDCMDOUTPARAMS;
- USHORT = BYTE;
- // The following struct defines the interesting part of the IDENTIFY
- // buffer:
- IDSECTOR = record
- wGenConfig : USHORT;
- wNumCyls : USHORT;
- wReserved : USHORT;
- wNumHeads : USHORT;
- wBytesPerTrack : USHORT;
- wBytesPerSector : USHORT;
- wSectorsPerTrack : USHORT;
- wVendorUnique : array[0..2] of USHORT;
- sSerialNumber : array[0..19] of CHAR;
- wBufferType : USHORT;
- wBufferSize : USHORT;
- wECCSize : USHORT;
- sFirmwareRev : array[0..7] of CHAR;
- sModelNumber : array[0..39] of CHAR;
- wMoreVendorUnique : USHORT;
- wDoubleWordIO : USHORT;
- wCapabilities : USHORT;
- wReserved1 : USHORT;
- wPIOTiming : USHORT;
- wDMATiming : USHORT;
- wBS : USHORT;
- wNumCurrentCyls : USHORT;
- wNumCurrentHeads : USHORT;
- wNumCurrentSectorsPerTrack : USHORT;
- ulCurrentSectorCapacity : ULONG;
- wMultSectorStuff : USHORT;
- ulTotalAddressableSectors : ULONG;
- wSingleWordDMA : USHORT;
- wMultiWordDMA : USHORT;
- bReserved : array[0..127] of BYTE;
- end;
- PIDSECTOR = ^IDSECTOR;
- SRB_IO_CONTROL = record
- HeaderLength : ULONG;
- Signature : array[0..7] of UCHAR;
- Timeout : ULONG;
- ControlCode : ULONG;
- ReturnCode : ULONG;// ReturnCode;
- Length : ULONG;
- end;
- PSRB_IO_CONTROL = ^SRB_IO_CONTROL;
- TDWArray = array of DWORD;
- const
- // Required to ensure correct PhysicalDrive IOCTL structure setup
- MAX_IDE_DRIVES = 4;
- // Max number of drives assuming primary/secondary, master/slave topology
- IDENTIFY_BUFFER_SIZE = 512;
- // IOCTL commands
- DFP_GET_VERSION = $00074080;
- DFP_SEND_DRIVE_COMMAND = $0007c084;
- DFP_RECEIVE_DRIVE_DATA = $0007c088;
- FILE_DEVICE_SCSI = $0000001b;
- IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI shl 16) + $0501);
- IOCTL_SCSI_MINIPORT = $0004D008; // see NTDDSCSI.H for definition
- // Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
- CAP_IDE_ID_FUNCTION = 1; // ATA ID command supported
- CAP_IDE_ATAPI_ID = 2; // ATAPI ID command supported
- CAP_IDE_EXECUTE_SMART_FUNCTION = 4; // SMART commannds supported
- // Valid values for the bCommandReg member of IDEREGS.
- IDE_ATAPI_IDENTIFY = $0A1; // Returns ID sector for ATAPI.
- IDE_ATA_IDENTIFY = $0EC; // Returns ID sector for ATA.
- var
- // Define global buffers.
- IdOutCmd : Integer = SizeOf(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1;
- function DoIDENTIFY(hPhysicalDriveIOCTL: THandle; pSCIP: PSENDCMDINPARAMS;
- pSCOP: PSENDCMDOUTPARAMS; bIDCmd, bDriveNum: BYTE;
- lpcbBytesReturned: PDWORD): Boolean;
- procedure PrintIdeInfo(drive: Integer; diskdata : array of DWORD);
- implementation
- {$R *.dfm}
- function ReadPhysicalDriveInNT: Boolean;
- var
- done : Boolean;
- drive : Integer;
- driveName : PChar;
- hPhysicalDriveIOCTL : THandle;
- VersionParams : GETVERSIONOUTPARAMS;
- cbBytesReturned : DWORD;
- bIDCmd : BYTE;
- scip : SENDCMDINPARAMS;
- diskdata : array[0..255] of DWORD;
- ijk : Integer;
- pIdSector : USHORT;
- //pOut :
- begin
- done := False;
- drive := 0;
- for drive := 0 to MAX_IDE_DRIVES-1 do
- begin
- hPhysicalDriveIOCTL := 0;
- // Try to get a handle to PhysicalDrive IOCTL, report failure
- // and exit if can't.
- driveName := PChar(Format('\\.\PhysicalDrive%d', [drive]));
- // Windows NT, Windows 2000, must have admin rights
- hPhysicalDriveIOCTL := CreateFile(driveName,
- { dwDesiredAccess } GENERIC_READ or GENERIC_WRITE,
- { dwShareMode } FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
- OPEN_EXISTING, 0, 0);
- if hPhysicalDriveIOCTL <> INVALID_HANDLE_VALUE then
- begin
- // Get the version, etc of PhysicalDrive IOCTL
- FillChar(VersionParams, sizeof(VersionParams), 0);
- if not DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION,
- nil, 0, @VersionParams, sizeof(VersionParams),
- cbBytesReturned, nil) then
- begin
- ShowMessage('DFP_GET_VERSION failed for drive '+ driveName);
- Exit;
- end;
- if VersionParams.bIDEDeviceMap > 0 then
- begin
- // Now, get the ID sector for all IDE devices in the system.
- // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
- // otherwise use the IDE_ATA_IDENTIFY command
- if Boolean(VersionParams.bIDEDeviceMap shr drive and $010) then
- bIDCmd := IDE_ATAPI_IDENTIFY else bIDCmd := IDE_ATA_IDENTIFY;
- FillChar(scip, sizeof(scip), 0);
- FillChar(diskdata, Length(diskdata), 0);
- if DoIDENTIFY(hPhysicalDriveIOCTL, @scip,
- @diskdata, bIDCmd, drive, @cbBytesReturned) then
- begin
- ijk := 0;
- //pIdSector := @PSENDCMDOUTPARAMS(IdOutCmd).bBuffer[0]; // ????
- {for ijk := 0 to 256-1 do
- diskdata[ijk] := PSENDCMDOUTPARAMS(IdOutCmd).bBuffer[ijk]; }
- PrintIdeInfo(drive, diskdata);
- done := True;
- end;
- end;
- CloseHandle(hPhysicalDriveIOCTL);
- end;
- end;
- end;
- function DoIDENTIFY(hPhysicalDriveIOCTL: THandle; pSCIP: PSENDCMDINPARAMS;
- pSCOP: PSENDCMDOUTPARAMS; bIDCmd, bDriveNum: BYTE;
- lpcbBytesReturned: PDWORD): Boolean;
- var
- cbBytesReturned : DWORD;
- begin
- // Set up data structures for IDENTIFY command.
- pSCIP.cBufferSize := IDENTIFY_BUFFER_SIZE;
- pSCIP.irDriveRegs.bFeaturesReg := 0;
- pSCIP.irDriveRegs.bSectorCountReg := 1;
- pSCIP.irDriveRegs.bSectorNumberReg := 1;
- pSCIP.irDriveRegs.bCylLowReg := 0;
- pSCIP.irDriveRegs.bCylHighReg := 0;
- // Compute the drive number.
- pSCIP.irDriveRegs.bDriveHeadReg := $0A0 or ((bDriveNum and 1) shl 4);
- // The command can either be IDE identify or ATAPI identify.
- pSCIP.irDriveRegs.bCommandReg := bIDCmd;
- pSCIP.bDriveNumber := bDriveNum;
- pSCIP.cBufferSize := IDENTIFY_BUFFER_SIZE;
- Result := DeviceIoControl(hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,
- pSCIP, sizeof(SENDCMDINPARAMS) - 1, pSCOP,
- sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
- cbBytesReturned, nil);
- end;
- function ConvertToString(diskdata : Pointer; firstIndex,
- lastIndex: Integer): string;
- var
- index : Integer;
- ch : char;
- begin
- Result := '';
- // each integer has two characters stored in it backwards
- for index := firstIndex to lastIndex do
- begin
- // get high byte for 1st character
- ch := Char(Integer(Pointer(Integer(diskdata)+2*index)^) shr 8);
- Result := Result + ch;
- ch := Char(Integer(Pointer(Integer(diskdata)+2*index)^));
- Result := Result + ch;
- end;
- // end the string
- Result := Result + #0;
- end;
- procedure printf(mask: string; Args: array of const);
- begin
- Form1.Memo1.Lines.Add(Format(mask, Args));
- end;
- procedure PrintIdeInfo(drive: Integer; diskdata : array of DWORD);
- var
- DriveType : string;
- Header : string;
- begin
- // get drive type info
- if Boolean(diskdata[4] and $00080) then DriveType := 'Removable'
- else if Boolean(diskdata[4] and $00040) then DriveType := 'Fixed'
- else DriveType := 'Unknown';
- case drive div 2 of
- 0: Header := 'Primary Controller - ';
- 1: Header := 'Secondary Controller - ';
- 2: Header := 'Tertiary Controller - ';
- 3: Header := 'Quaternary Controller - ';
- end;
- case drive mod 2 of
- 0: Header := Header + 'Master drive';
- 1: Header := Header + 'Slave drive';
- end;
- printf(Header, []);
- printf('Drive Model Number________________: %s', [ConvertToString (@diskdata, 35, 54)]);
- printf('Drive Serial Number_______________: %s', [ConvertToString (@diskdata, 18, 27)]);
- printf('Drive Controller Revision Number__: %s', [ConvertToString (@diskdata, 31, 34)]);
- printf('Controller Buffer Size on Drive___: %u bytes', [Word(Pointer(Integer(@diskdata)+58)^) * 512]);
- printf('Drive Type________________________: %s', [DriveType]);
- printf('Physical Geometry: '+
- '%u Cylinders, %u Heads, %u Sectors per track',
- [Word(Pointer(Integer(@diskdata)+18)^),
- Word(Pointer(Integer(@diskdata)+22)^),
- Word(Pointer(Integer(@diskdata)+28)^)]);
- printf(' ', []);
- end;
- procedure TForm1.Button1Click(Sender: TObject);
- begin
- Memo1.Lines.Clear;
- ReadPhysicalDriveInNT;
- end;
- end.
- 1://////////////////////////METHOD 2 WITH CPU PROTECTION///////////////////////////////////
- 2:unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
- type
- TForm1 = class(TForm)
- Button1: TButton;
- procedure Button1Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.dfm}
- function GetEnvVarValue(const VarName: string): string;
- var
- BufSize: Integer; // buffer size required for value
- begin
- // Get required buffer size (inc. terminal #0)
- BufSize := GetEnvironmentVariable(PChar(VarName), nil, 0);
- if BufSize > 0 then
- begin
- // Read env var value into result string
- SetLength(Result, BufSize - 1);
- GetEnvironmentVariable(PChar(VarName),
- PChar(Result), BufSize);
- end
- else
- // No such environment variable
- Result := '';
- end;
- {
- ---List of different variables---
- ALLUSERSPROFILE
- APPDATA
- CLIENTNAME
- CommonProgramFiles
- COMPUTERNAME
- ComSpec
- HOMEDRIVE
- HOMEPATH
- LOGONSERVER
- NUMBER_OF_PROCESSORS
- OS
- Path
- PATHEXT
- PCToolsDir
- PROCESSOR_ARCHITECTURE
- PROCESSOR_IDENTIFIER
- PROCESSOR_LEVEL
- PROCESSOR_REVISION
- ProgramFiles
- SESSIONNAME
- SystemDrive
- SystemRoot
- TEMP
- TMP
- USERDOMAIN
- USERNAME
- USERPROFILE
- windir
- }
- procedure TForm1.Button1Click(Sender: TObject);
- begin
- ShowMessage(GetEnvVarValue('PROCESSOR_IDENTIFIER'));
- end;
- end.
- 3:
- 4:
- 5:
- 6:
- 7:
- 8:
- 9:
- 10:
- 11:
- 12:
- 13:
- 14:
- 15:
- 16:
- 17:
- 18:
- 19:
- 20:
- 21:
- 22:
- 23:
- 24:
- 25:
- 26:
- 27:
- 28:
- 29:
- 30:
- 31:
- 32:
- 33:
- 34:
- 35:
- 36:
- 37:
- 38:
- 39:
- 40:
- 41:
- 42:
- 43:
- 44:
- 45:
- 46:
- 47:
- 48:
- 49:
- 50:
- 51:
- 52:
- 53:
- 54:
- 55:
- 56:
- 57:
- 58:
- 59:
- 60:
- 61:
- 62:
- 63:
- 64:
- 65:
- 66:
- 67:
- 68:
- 69:
- 70:
- 71:
- 72:
- 73:
- 74:
- 75:
- 76:
- 77:
- 78:
- 79:
- 80:
- 81:
- 82:
- 83:
- 84:
- 85:
- 86:
- 87:
- 88:
- 89:
- 90:
- 91:
- 92:
- 93:
- 94:
- 95:
- 96:
- 97:
- 98:
- 99:
- 100:
- 101:
- 102:
- 103:
- 104:
- 105:
- 106:
- 107:
- 108:
- 109:
- 110:
- 111:
- 112:
- 113:
- 114:
- 115:
- 116:
- 117:
- 118:
- 119:
- 120:
- 121:
- 122:
- 123:
- 124:
- 125:
- 126:
- 127:
- 128:
- 129:
- 130:
- 131:
- 132:
- 133:
- 134:
- 135:
- 136:
- 137:
- 138:
- 139:
- 140:
- 141:
- 142:
- 143:
- 144:
- 145:
- 146:
- 147:
- 148:
- 149:
- 150:
- 151:
- 152:
- 153:
- 154:
- 155:
- 156:
- 157:
- 158:
- 159:
- 160:
- 161:
- 162:
- 163:
- 164:
- 165:
- 166:
- 167:
- 168:
- 169:
- 170:
- 171:
- 172:
- 173:
- 174:
- 175:
- 176:
- 177:
- 178:
- 179:
- 180:
- 181:
- 182:
- 183:
- 184:
- 185:
- 186:
- 187:
- 188:
- 189:
- 190:
- 191:
- 192:
- 193:
- 194:
- 195:
- 196:
- 197:
- 198:
- 199:
- 200:
- 201:
- 202:
- 203:
- 204:
- 205:
- 206:
- 207:
- 208:
- 209:
- 210:
- 211:
- 212:
- 213:
- 214:
- 215:
- 216:
- 217:
- 218:
- 219:
- 220:
- 221:
- 222:
- 223:
- 224:
- 225:
- 226:
- 227:
- 228:
- 229:
- 230:
- 231:
- 232:
- 233:
- 234:
- 235:
- 236:
- 237:
- 238:
- 239:
- 240:
- 241:
- 242:
- 243:
- 244:
- 245:
- 246:
- 247:
- 248:
- 249:
- 250:
- 251:
- 252:
- 253:
- 254:
- 255:
- 256:
- 257:
- 258:
- 259:
- 260:
- 261:
- 262:
- 263:
- 264:
- 265:
- 266:
- 267:
- 268:
- 269:
- 270:
- 271:
- 272:
- 273:
- 274:
- 275:
- 276:
- 277:
- 278:
- 279:
- 280:
- 281:
- 282:
- 283:
- 284:
- 285:
- 286:
- 287:
- 288:
- 289:
- 290:
- 291:
- 292:
- 293:
- 294:
- 295:
- 296:
- 297:
- 298:
- 299:
- 300:
- 301:
- 302:
- 303:
- 304:
- 305:
- 306:
- 307:
- 308:
- 309:
- 310:
- 311:
- 312:
- 313:
- 314:
- 315:
- 316:
- 317:
- 318:
- 319:
- 320:
- 321:
- 322:
- 323:
- 324:
- 325:
- 326:
- 327:
- 328:
- 329:
- 330:
- 331:
- 332:
- 333:
- 334:
- 335:
- 336:
- 337:
- 338:
- 339:
- 340:
- 341:
- 342:
- 343:
- 344:
- 345:
- 346:
- 347:
- 348:
- 349:
- 350:
- 351:
- 352:
- 353:
- 354:
- 355:
- 356:
- 357:
- 358:
- 359:
- Select allOpen in new window
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement