CAFE

Win32Api활용

HDD 시리얼번호와 모델문자열 얻기

작성자죠우저프|작성시간13.06.10|조회수311 목록 댓글 0

///////////////////////////////////////////////////////////////////////////////
//		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;
    }

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼