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

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[766] 하드디스크의 시리얼번호, 모델번호 알아내기(?)
이점한 [redyouth] 13489 읽음    2008-04-16 14:15
여기 팁란에 빈센트님 글도 있고 한데 .. 잘 안되신다는 분도 있고 해서 빈센트님글이나 델마당이나 MSDN
참조해서 정리해서 사용하고 있었는데 역시 점심먹고 배부르고 심심(?)해서 또 올려 봅니다.

예전에 만들어 둔게 있어서 혹시 필요 하신분 참조 하시라고 올려 봅니다.
물론 WMI를 잘 활용해도 되는데 .. 여러 제약이 있는 경우가 있으니 참조 하세요.

아래글에도 썼듯이 저 같은 경우는 시스템 고유 아이디 만들때 사용 했던 소스입니다.
이런식으로 활용 하실 수 있을 듯 ..

#####################
- 먼저 헤더에 들어갈 내용 ...
 
//----------- IDE Serial 얻기 위한 선언들 (시작)....
#include 
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088

typedef struct I_SENDCMDOUTPARAMS {
 DWORD    cBufferSize;  // Size of bBuffer in bytes
 DRIVERSTATUS DriverStatus;  // Driver status structure.
 BYTE   bBuffer[512];   // Buffer of arbitrary length
          // in which to store the data read from the drive.
} uSENDCMDOUTPARAMS;

typedef struct _IDSECTOR {
 USHORT wGenConfig;
 USHORT wNumCyls;
 USHORT wReserved;
 USHORT wNumHeads;
 USHORT wBytesPerTrack;
 USHORT wBytesPerSector;
 USHORT wSectorsPerTrack;
 USHORT wVendorUnique[3];
 CHAR sSerialNumber[20];
 USHORT wBufferType;
 USHORT wBufferSize;
 USHORT wECCSize;
 CHAR sFirmwareRev[8];
 CHAR sModelNumber[40];
 USHORT wMoreVendorUnique;
 USHORT wDoubleWordIO;
 USHORT wCapabilities;
 USHORT wReserved1;
 USHORT wPIOTiming;
 USHORT wDMATiming;
 USHORT wBS;
 USHORT wNumCurrentCyls;
 USHORT wNumCurrentHeads;
 USHORT wNumCurrentSectorsPerTrack;
 ULONG ulCurrentSectorCapacity;
 USHORT wMultSectorStuff;
 ULONG ulTotalAddressableSectors;
 USHORT wSingleWordDMA;
 USHORT wMultiWordDMA;
 BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;
//----------- IDE Serial 얻기 위한 선언들 (끝)....

#####################
- 소스에 들어갈 내용
 
//---------------------------------------------------------------------------
// IDE 시리얼 알아내기
AnsiString GetIDESerial()
{
    AnsiString _result, ModelNo, DiskSN;
    SENDCMDINPARAMS in;
    uSENDCMDOUTPARAMS out;
    HANDLE h;
    DWORD i;
    BYTE j;

    if ( IsWinNt() )
    {
      PIDSECTOR phdinfo;
      char s[41];

      h=CreateFile("\\\\.\\PhysicalDrive0",GENERIC_READ|GENERIC_WRITE,
       FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
      if (!h)
       return "";

      //Identify the IDE drives
      ZeroMemory(&in,sizeof(in));
      ZeroMemory(&out,sizeof(out));
      in.irDriveRegs.bDriveHeadReg=0xa0;

      in.irDriveRegs.bCommandReg=0xec;
      in.bDriveNumber = 0;
      in.irDriveRegs.bSectorCountReg=1;
      in.irDriveRegs.bSectorNumberReg=1;
      in.cBufferSize=512;
      if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0))
      {
       CloseHandle(h);
       return "";
      }
      phdinfo=(PIDSECTOR)out.bBuffer;
      memcpy(s,phdinfo->sModelNumber,40);
      s[40]=0;
      ChangeByteOrder(s,40);
      ModelNo = s;
      memcpy(s,phdinfo->sSerialNumber,20);
      s[20]=0;
      ChangeByteOrder(s,20);
      DiskSN = s;

      _result = ModelNo.Trim() + ":" + DiskSN.Trim();

      CloseHandle(h);

    }
    else
    {
      //We start in 95/98/Me
      h = CreateFile( "\\\\.\\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0 );
      if ( !h )
      {
        return "";
      }

      //Identify the IDE drives
      PIDSECTOR phdinfo;
      char s[41];

      ZeroMemory(&in,sizeof(in));
      ZeroMemory(&out,sizeof(out));
      in.irDriveRegs.bDriveHeadReg=0xa0;
      in.irDriveRegs.bCommandReg=0xec;
      in.bDriveNumber=0;
      in.irDriveRegs.bSectorCountReg=1;
      in.irDriveRegs.bSectorNumberReg=1;
      in.cBufferSize=512;
      if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0))
      {
        CloseHandle(h);
        return "";
      }
      phdinfo=(PIDSECTOR)out.bBuffer;
      memcpy(s,phdinfo->sModelNumber,40);
      s[40]=0;
      ChangeByteOrder(s,40);
      ModelNo = s;
      memcpy(s,phdinfo->sSerialNumber,20);
      s[20]=0;
      ChangeByteOrder(s,20);
      DiskSN = s;
      CloseHandle(h);

      _result = ModelNo.Trim() + ":" + DiskSN.Trim();

      //Close handle before quit
      CloseHandle(h);
    }

    if ( _result.Trim().IsEmpty() )  // 제품번호를 얻지 못하였을때 볼륨 시리얼로 대체
    {
      _result = GetVolSerial();
    }

    return _result;
}

// 아래는 위 함수에서 사용 하는 참조 함수들..
//---------------------------------------------------------------------------
// OS가 NT 계열인지...
bool IsWinNt()
{
    static OSVERSIONINFO sInfo = {sizeof(OSVERSIONINFO),0};

    if(!sInfo.dwMajorVersion)
      GetVersionEx(&sInfo);

    return sInfo.dwMajorVersion>4;
}
//------------------------------------------------------------
// IDE 시리얼 알아내기 - 관련함수
void ChangeByteOrder(PCHAR szString, USHORT uscStrSize)
{
    USHORT i;
    CHAR temp;

    for (i = 0; i < uscStrSize; i+=2)
    {
      temp = szString[i];
      szString[i] = szString[i+1];
      szString[i+1] = temp;
    }
}
//---------------------------------------------------------------------------
// 하드의 볼륨 시리얼 얻기
AnsiString GetVolSerial()
{
    char DrvRoot[4] = "C:\\";
    DWORD VolSerial;
    GetVolumeInformation(DrvRoot, NULL, 0, &VolSerial, NULL, NULL, NULL, 0);
    return IntToHex((int)VolSerial, 8);
}
//---------------------------------------------------------------------------


위소스를 보시면 아시겠지만 GetIDESerial() 이 함수 쓰면 제품번호 + 하드 Serial을 리턴 해주는데
소스중  _result = ModelNo.Trim() + ":" + DiskSN.Trim(); 이부분을 조절 하면 제품 번호나 하드 시리얼만
골라 낼 수 있습니다.

이미 나름대로 알려진 소스들인데 제가 쓰기 편하게 정리 한거입니다. 혹시나 모르시는 분들한테
조그만 도움이라도 되었으면 좋겠네요.
이현진 [cyberpd]   2008-04-17 10:49 X
감사합니다~ ^^
슬.강슬기 [mydog21]   2008-04-24 13:08 X
옷... 좋은 내용입니다...
크레브 [kkol]   2011-10-05 10:25 X
잘사용하겠습니다. 감사합니다.

+ -

관련 글 리스트
766 하드디스크의 시리얼번호, 모델번호 알아내기(?) 이점한 13489 2008/04/16
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.