Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 팁&트릭
Delphi Programming Tip&Tricks
[41] [팁] SCSI 하드디스크 시리얼 알아내기
이상탁 [nofade] 6635 읽음    2003-02-11 11:31
아래에 IDE 방식의 하드디스크시리얼 알아내기가 있기에 같은 곳에서 가져온 소스입니다.

근데, 내 피시에 달린 하드디스크가 IDE 인지 SCSI 인지 구분하는 법은 어떻게 되나요?

// Alex Konshin    mailto:alexk@mtgroup.ru      17 jul 2000

program ScsiSN;

// PURPOSE: Simple console application that display SCSI harddisk serial number

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils;

//-------------------------------------------------------------
function GetDeviceHandle( sDeviceName : String ) : THandle;
begin
	Result := CreateFile( PChar('\\.\'+sDeviceName), GENERIC_READ or GENERIC_WRITE,
				FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 )
end;

//-------------------------------------------------------------
function ScsiHddSerialNumber( DeviceHandle : THandle ) : String;
{$ALIGN ON}
type
	TScsiPassThrough = record
		Length             : Word;
		ScsiStatus         : Byte;
		PathId             : Byte;
		TargetId           : Byte;
		Lun                : Byte;
		CdbLength          : Byte;
		SenseInfoLength    : Byte;
		DataIn             : Byte;
		DataTransferLength : ULONG;
		TimeOutValue       : ULONG;
		DataBufferOffset   : DWORD;
		SenseInfoOffset    : ULONG;
		Cdb                : Array[0..15] of Byte;
	end;
	TScsiPassThroughWithBuffers = record
		spt : TScsiPassThrough;
		bSenseBuf : Array[0..31] of Byte;
		bDataBuf : Array[0..191] of Byte;
	end;
{ALIGN OFF}
var	dwReturned : DWORD;
    len : DWORD;
		Buffer : Array[0..SizeOf(TScsiPassThroughWithBuffers)+SizeOf(TScsiPassThrough)-1] of Byte;
		sptwb : TScsiPassThroughWithBuffers absolute Buffer;
begin
	Result := '';
	FillChar(Buffer,SizeOf(Buffer),#0);
	with sptwb.spt do
	begin
		Length   := SizeOf(TScsiPassThrough);
		CdbLength := 6; // CDB6GENERIC_LENGTH
		SenseInfoLength := 24;
		DataIn := 1; // SCSI_IOCTL_DATA_IN
		DataTransferLength := 192;
		TimeOutValue := 2;
		DataBufferOffset := PChar(@sptwb.bDataBuf)-PChar(@sptwb);
		SenseInfoOffset := PChar(@sptwb.bSenseBuf)-PChar(@sptwb);
		Cdb[0] := $12; //	OperationCode := SCSIOP_INQUIRY;
		Cdb[1] := $01; //	Flags := CDB_INQUIRY_EVPD;  Vital product data
		Cdb[2] := $80; //	PageCode            Unit serial number
		Cdb[4] := 192; // AllocationLength
	end;
	len := sptwb.spt.DataBufferOffset+sptwb.spt.DataTransferLength;
	if DeviceIoControl( DeviceHandle, $0004d004, @sptwb, SizeOf(TScsiPassThrough), @sptwb, len, dwReturned, nil )
		and ((PChar(@sptwb.bDataBuf)+1)^=#$80)
	then SetString( Result, PChar(@sptwb.bDataBuf)+4, Ord((PChar(@sptwb.bDataBuf)+3)^) );
end;


//=============================================================
var
	hDevice : THandle = 0;
	sSerNum, sDeviceName : String;

begin
	sDeviceName := ParamStr(1);
	if sDeviceName='' then
	begin
		WriteLn;
		WriteLn('Display SCSI-2 device serial number.');
		WriteLn;
		WriteLn('Using:');
		WriteLn;
		WriteLn('  ScsiSN C:');
		if Win32Platform=VER_PLATFORM_WIN32_NT then	// Windows NT, Windows 2000
			WriteLn('  ScsiSN PhysicalDrive0');
		WriteLn('  ScsiSN Cdrom0');
		WriteLn('  ScsiSN Tape0');
		WriteLn;
		Exit;
	end;
	hDevice := GetDeviceHandle(sDeviceName);
	if hDevice=INVALID_HANDLE_VALUE then
		WriteLn('Error on GetDeviceHandle: ',SysErrorMessage(GetLastError))
	else
		try
			sSerNum := ScsiHddSerialNumber(hDevice);
			if sSerNum='' then
				WriteLn('Error on DeviceIoControl: ',SysErrorMessage(GetLastError))
			else
				WriteLn('Device '+sDeviceName+' serial number = "',sSerNum,'"');
		finally
			CloseHandle(hDevice);
		end;
end.

+ -

관련 글 리스트
41 [팁] SCSI 하드디스크 시리얼 알아내기 이상탁 6635 2003/02/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.