///////////////////////////////////////////////////////////////////////////////
// HDD의 모델번호와 시리얼번호를 얻음
// USB인터페이스로 장착된 HDD는 인식 못함
// 아래 구조체는 VC6사용시 필요, WDK사용시 불필요
// WDK에서는 WINIOCTL.H 를 Include 하면 됨
///////////////////////////////////////////////////////////////////////////////
#include <pshpack1.h>
typedef struct _IDEREGS
{
BYTE bFeaturesReg; //Used for specifying SMART "commands".
BYTE bSectorCountReg; //IDE sector count register
BYTE bSectorNumberReg; //IDE sector number register
BYTE bCylLowReg; //IDE low order cylinder value
BYTE bCylHighReg; //IDE high order cylinder value
BYTE bDriveHeadReg; //IDE drive/head register
BYTE bCommandReg; //Actual IDE command.
BYTE bReserved; //reserved for future use. Must be zero.
} IDEREGS;
typedef struct _SENDCMDINPARAMS
{
DWORD cBufferSize; //Buffer size in bytes
IDEREGS irDriveRegs; //Structure with drive register values.
BYTE bDriveNumber; //Physical drive number to send
//command to (0,1,2,3).
BYTE bReserved[3]; //Reserved for future expansion.
DWORD dwReserved[4]; //For future use.
BYTE bBuffer[1]; //Input buffer.
} SENDCMDINPARAMS;
typedef struct _DRIVERSTATUS
{
BYTE bDriverError; //Error code from driver,
//or 0 if no error.
BYTE bIDEError; //Contents of IDE Error register.
//Only valid when bDriverError
//is SMART_IDE_ERROR.
BYTE bReserved[2]; //Reserved for future expansion.
DWORD dwReserved[2]; //Reserved for future expansion.
} DRIVERSTATUS;
typedef struct _SENDCMDOUTPARAMS
{
DWORD cBufferSize; //Size of bBuffer in bytes
DRIVERSTATUS DriverStatus; //Driver status structure.
BYTE bBuffer[1]; //Buffer of arbitrary length in which to store the data read from the // drive.
} SENDCMDOUTPARAMS;
#include <poppack.h>
#define IDENTIFY_BUFFER_SIZE 512
#define LOCAL(type) static type WINAPI
#define ALLOCMEM4(lp1,lp1Size, lp2,lp2Size, lp3,lp3Size, lp4,lp4Size, ErrJump) \
if ((lp1=(LPSTR)AllocMem(lp1Size+lp2Size+lp3Size+lp4Size))==NULL) goto ErrJump; \
lp2=lp1+lp1Size; \
lp3=lp2+lp2Size; \
lp4=lp3+lp3Size
//-----------------------------------------------------------------------------
// Big Indian문자열을 주어진 길이만큼 빼냄
//-----------------------------------------------------------------------------
LOCAL(void) CatchBigIndianLenStr(LPSTR Dest, LPCSTR Src, int SrcLen)
{
int I;
for (I=0; I<SrcLen; I++) Dest[I]=Src[I^1]; //Big Indian Data를 변환
Dest[I]=0;
CleanUpStr(Dest);
}
//-----------------------------------------------------------------------------
// IDENTIFY 를 읽어서 HDD Serial No를 꺼내줌
//-----------------------------------------------------------------------------
BOOL WINAPI GetIdeModelNo(int PhyDriveNo, LPSTR Buff)
{
int Rslt=FALSE, Err;
DWORD RetBytes, BuffSize;
HANDLE hDrv=FBAD;
SENDCMDINPARAMS SCIP;
SENDCMDOUTPARAMS *SCOP=NULL;
LPSTR lp, lpMem, lpTmp, PhyDrvName;
Err=3;
BuffSize=sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE;
ALLOCMEM4(lpMem, MAX_PATH,
lpTmp, MAX_PATH,
PhyDrvName, 32,
lp, BuffSize,
MEMOWNER_SaveHddInfo, ProcExit);
SCOP=(SENDCMDOUTPARAMS*)lp;
Err=0;
wsprintf(PhyDrvName, "\\\\.\\PhysicalDrive%d", PhyDriveNo);
if ((hDrv=CreateFile(PhyDrvName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL))==FBAD)
{
//DebugOut(0,-1,"%s open Error", PhyDrvName);
Err=1; goto ProcExit;
}
//Retrieve the IDENTIFY data ... USB 인터페이스에선 동작안함
ZeroMem(&SCIP, sizeof(SENDCMDINPARAMS));
SCIP.irDriveRegs.bCommandReg=0xEC; //Returns ID sector for ATA
if (DeviceIoControl(hDrv, SMART_RCV_DRIVE_DATA, &SCIP, sizeof(SENDCMDINPARAMS), SCOP, BuffSize, &RetBytes, NULL)==FALSE)
{
//DebugOut(0,-1,"DeviceIoControl(SMART_RCV_DRIVE_DATA) Err=%d", GetLastError());
Err=4; goto ProcExit;
}
//DebugMem(SCOP->bBuffer, SCOP->cBufferSize);
//Offset 1B2: WORD 이값이 1이면 회전체가 없는 미디어 즉 SSD를 말함 (RPM값) //ATA8커멘드.pdf ... p179참조, 1B2: Nominal media rotation rate (RPM값, 5400, 7200)
//CatchBigIndianLenStr(Buff, (LPCSTR)SCOP->bBuffer+0x14, 20); //Offset 14~27: 시리얼번호
CatchBigIndianLenStr(Buff, (LPCSTR)SCOP->bBuffer+0x36, 40); //Offset 36~5D: 모델번호
Rslt++;
ProcExit:
FreeMem(lpMem);
FileClose(hDrv);
SetLastError(Err);
return Rslt;
}
다음검색