fortran66のブログ

fortran について書きます。

HDD Serial Number

IDE の ドライブに ATA・ATAPI 制御コマンドを送って、シリアル番号やファームウェアバージョンなどのハードウェア固有の情報を得ることができます。

■実行結果

Fortranソースコード

参考にしたページは、主にここ http://www.usefullcode.net/2007/02/hdd.html です。
Win32 のプログラムはちんねりむっつり API を調べて呼ぶだけだから、つまんないですね。わけの分からん定数や構造体が次々出てくるし。

なお Vista では、実行ファイルを右クリックして管理者権限で実行する必要があります。

ドライブが複数あるときは、『ndrive = 0 ! First drive 0, Second Drive 1 ... 』この行の数値を変えることで、個々のハードウェアを指定できます。

PROGRAM disk   
USE kernel32   
IMPLICIT NONE   
INTEGER(HANDLE) :: hDevice            
INTEGER(LPDWORD) :: lpBytesReturned = 0   
INTEGER(BOOL) :: iret   
!   
TYPE :: t_IDENTIFY_DEVICE_OUTDATA   
 SEQUENCE   
 TYPE (t_SENDCMDOUTPARAMS):: snd_cmd_out   
 CHARACTER(511):: DriverStatus ! typedefs  DRIVERSTATUS    
END TYPE   
!   
TYPE (t_SENDCMDINPARAMS) :: snd_cmd   
TYPE (t_IDENTIFY_DEVICE_OUTDATA) :: out_data   
!   
INTEGER, PARAMETER :: DFP_RECEIVE_DRIVE_DATA = Z'0007c088'  
INTEGER, PARAMETER :: ATAPI_IDENTIFY_DEVICE  = Z'EC'  
!   
INTEGER :: i, ndrive   
CHARACTER(19) :: fn   
!   
ndrive = 0 ! First drive 0, Second Drive 1 ...   
WRITE(fn, '(a, i1, a)') '\\.\PhysicalDrive', ndrive, CHAR(0) !C string   
!   
hDevice = CreateFile(fn, IOR(GENERIC_READ, GENERIC_WRITE),IOR(FILE_SHARE_READ, FILE_SHARE_WRITE), &   
                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)   
IF (hDevice == INVALID_HANDLE_VALUE) THEN    
 PRINT *, GetLastError()   
 iret = CloseHandle(hDevice)   
 STOP 'error CreateFile'  
END IF    
!   
snd_cmd%irDriveRegs%bCommandReg = ATAPI_IDENTIFY_DEVICE   
snd_cmd%irDriveRegs%bDriveHeadReg = IOR(Z'A0', ISHFT(IAND(ndrive, 1), 4))    
snd_cmd%cBufferSize = sizeof(out_data) ! 511?   
snd_cmd%bDriveNumber = ndrive   
!   
iret = DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, LOC(snd_cmd), sizeof(snd_cmd), LOC(out_data), sizeof(out_data), LOC(lpBytesReturned), NULL)   
IF (iret == 0) THEN    
 PRINT *, GetLastError()   
 iret = CloseHandle(hDevice)   
 STOP 'error DeviceIoControl'  
END IF    
!   
! the order of "out_data%DriverStatus" is 2byte little endian   
!   
! http://www.usefullcode.net/2007/02/hdd.html   
!   
WRITE(*, '(a)', ADVANCE='NO') 'Serial Number = '  
DO i = 21, 39, 2   
 WRITE(*, '(2a1)', ADVANCE='NO') out_data%DriverStatus(i:i), out_data%DriverStatus(i - 1:i - 1)   
END DO   
WRITE(*, *)   
WRITE(*, '(a)', ADVANCE='NO') 'Model         = '  
DO i = 55, 93, 2    
 WRITE(*, '(2a1)', ADVANCE='NO') out_data%DriverStatus(i:i), out_data%DriverStatus(i - 1:i - 1)   
END DO   
WRITE(*, *)   
WRITE(*, '(a)', ADVANCE='NO') 'Firmware      = '  
DO i = 47, 53, 2   
 WRITE(*, '(2a1)', ADVANCE='NO') out_data%DriverStatus(i:i), out_data%DriverStatus(i - 1:i - 1)   
END DO   
WRITE(*, *)   
!
iret = CloseHandle(hDevice)   
!   
PAUSE ! for Vista    
!   
STOP   
END PROGRAM disk