首页
社区
课程
招聘
关于获取硬盘等硬件的序列号问题
发表于: 2006-6-10 14:48 6245

关于获取硬盘等硬件的序列号问题

2006-6-10 14:48
6245
我在Google以及Pediy里面搜索了一下如何获取硬盘序列号的问题?
很多文章说,可以通过GetVolumeInformation()函数实现
比如
http://www.pediy.com/bbshtml/BBS3/Forum867.htm
http://www.pediy.com/bbshtml/BBS4/kanxue004.htm

但是我在一些技术群里面问了一下,很多人说这样不行?
我想问一下可行的方法,最好能贴出代码,顺便讲讲其他硬件(如CPU)如何获取它的注册码~~~~~~~~~~~~~~

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 446
活跃值: (758)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
function GetIdeDiskSerialNumber  :pchar; stdcall;

{得到硬盘序列号过程}
type
  TSrbIoControl = packed record
    HeaderLength : ULONG;
    Signature : Array[0..7] of Char;
    Timeout : ULONG;
    ControlCode : ULONG;
    ReturnCode : ULONG;
    Length : ULONG;
  end;
  SRB_IO_CONTROL = TSrbIoControl;
  PSrbIoControl = ^TSrbIoControl;
  TIDERegs = packed record
    bFeaturesReg : Byte;     // Used for specifying SMART "commands".
    bSectorCountReg : Byte;  // IDE sector count register
    bSectorNumberReg : Byte; // IDE sector number register
    bCylLowReg : Byte;       // IDE low order cylinder value
    bCylHighReg : Byte;      // IDE high order cylinder value
    bDriveHeadReg : Byte;    // IDE drive/head register
    bCommandReg : Byte;      // Actual IDE command.
    bReserved : Byte;        // reserved. Must be zero.
  end;
  IDEREGS = TIDERegs;
  PIDERegs = ^TIDERegs;
  TSendCmdInParams = packed record
    cBufferSize : DWORD;
    irDriveRegs : TIDERegs;
    bDriveNumber : Byte;
    bReserved : Array[0..2] of Byte;
    dwReserved : Array[0..3] of DWORD;
    bBuffer : Array[0..0] of Byte;
  end;
  SENDCMDINPARAMS = TSendCmdInParams;
  PSendCmdInParams = ^TSendCmdInParams;
  TIdSector = packed record
    wGenConfig : Word;
    wNumCyls : Word;
    wReserved : Word;
    wNumHeads : Word;
    wBytesPerTrack : Word;
    wBytesPerSector : Word;
    wSectorsPerTrack : Word;
    wVendorUnique : Array[0..2] of Word;
    sSerialNumber : Array[0..19] of Char;
    wBufferType : Word;
    wBufferSize : Word;  
    wECCSize : Word;  
    sFirmwareRev : Array[0..7] of Char;
    sModelNumber : Array[0..39] of Char;  
    wMoreVendorUnique : Word;  
    wDoubleWordIO : Word;  
    wCapabilities : Word;
    wReserved1 : Word;
    wPIOTiming : Word;  
    wDMATiming : Word;  
    wBS : Word;  
    wNumCurrentCyls : Word;
    wNumCurrentHeads : Word;
    wNumCurrentSectorsPerTrack : Word;
    ulCurrentSectorCapacity : ULONG;
    wMultSectorStuff : Word;
    ulTotalAddressableSectors : ULONG;
    wSingleWordDMA : Word;
    wMultiWordDMA : Word;
    bReserved : Array[0..127] of Byte;
  end;
  PIdSector = ^TIdSector;
const
  IDE_ID_FUNCTION = $EC;
  IDENTIFY_BUFFER_SIZE = 512;
  DFP_RECEIVE_DRIVE_DATA = $0007c088;
  IOCTL_SCSI_MINIPORT = $0004d008;
  IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;
  DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
  BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;
  W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;
var  
  hDevice : THandle;
  cbBytesReturned : DWORD;
  pInData : PSendCmdInParams;
  pOutData : Pointer; // PSendCmdOutParams
  Buffer : Array[0..BufferSize-1] of Byte;
  srbControl : TSrbIoControl absolute Buffer;

procedure ChangeByteOrder( var Data; Size : Integer );  
var
  ptr : PChar;
  i : Integer;
  c : Char;
begin
  ptr := @Data;
  for i := 0 to (Size shr 1)-1 do
  begin
    c := ptr^;
    ptr^ := (ptr+1)^;
    (ptr+1)^ := c;
    Inc(ptr,2);
  end;
end;  

begin  
  Result :='';
  FillChar(Buffer,BufferSize,#0);
  if Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT, Windows 2000
  begin         // Get SCSI port handle
    hDevice := CreateFile( '\\.\Scsi0:',GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
    if hDevice=INVALID_HANDLE_VALUE then Exit;
    try
      srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
      System.Move('SCSIDISK',srbControl.Signature,8);
      srbControl.Timeout := 2;
      srbControl.Length := DataSize;
      srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
      pInData := PSendCmdInParams(PChar(@Buffer)
      +SizeOf(SRB_IO_CONTROL));
      pOutData := pInData;
      with pInData^ do
      begin
        cBufferSize := IDENTIFY_BUFFER_SIZE;
        bDriveNumber := 0;
        with irDriveRegs do
        begin
          bFeaturesReg := 0;
          bSectorCountReg := 1;
          bSectorNumberReg := 1;
          bCylLowReg := 0;
          bCylHighReg := 0;
          bDriveHeadReg := $A0;
          bCommandReg := IDE_ID_FUNCTION;
        end;
      end;
      if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT,
      @Buffer, BufferSize, @Buffer, BufferSize,
      cbBytesReturned, nil ) then Exit;
    finally
      CloseHandle(hDevice);
    end;
  end else
  begin // Windows 95 OSR2, Windows 98
    hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil,CREATE_NEW, 0, 0 );
    if hDevice=INVALID_HANDLE_VALUE then Exit;
    try
      pInData := PSendCmdInParams(@Buffer);
      pOutData := @pInData^.bBuffer;
      with pInData^ do
      begin
        cBufferSize := IDENTIFY_BUFFER_SIZE;
        bDriveNumber := 0;
        with irDriveRegs do
        begin
          bFeaturesReg := 0;
          bSectorCountReg := 1;
          bSectorNumberReg := 1;
          bCylLowReg := 0;
          bCylHighReg := 0;
          bDriveHeadReg := $A0;
          bCommandReg := IDE_ID_FUNCTION;
        end;
      end;
      if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA,
      pInData, SizeOf(TSendCmdInParams)-1, pOutData,
      W9xBufferSize, cbBytesReturned, nil ) then Exit;
    finally
      CloseHandle(hDevice);
    end;
  end;
  with PIdSector(PChar(pOutData)+16)^ do
  begin
    ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
   // SetString(Result,sSerialNumber,SizeOf(sSerialNumber));

  result:=sSerialNumber;
end;
end;
2006-6-10 18:02
0
雪    币: 221
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
哇!!!
谢谢楼上的代码,不过希望能有一点原理讲解```
2006-6-11 19:59
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
GetVolumeInformation()是获取卷标信息的吧???获取硬盘序列号在win2k和win98下是不一样的,我发个很久以前抄的函数给你.

////////////////////////////////////将数据转换成可理解的数字////////////////////////////////////
//
//  参数说明:
//                DWORD diskdata [256]        : 硬盘的数据片断
//                int firstIndex                : 从firstIndex开始截取
//                int lastIndex            : 从lastIndex开始截取
//               
//   返回值  
//            0                        : 成功计算出结果,并将结果存放在TCHAR* string中
//            1                        : 带变量的表达式中有未定义的变量
//
//   备注:所有未定义的变量用sSep进行分隔存在pResultStr中
//
/////////////////////////////////////////////////////////////////////////////////////////////////
TCHAR* CMKYSystemInfo::ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex)
{
        static TCHAR string [1024];
        int index = 0;
        int position = 0;
       
        //  each integer has two characters stored in it backwards
        for (index = firstIndex; index <= lastIndex; index++)
        {
                //  get high byte for 1st character
                string [position] = (char) (diskdata [index] / 256);
                position++;
               
                //  get low byte for 2nd character
                string [position] = (char) (diskdata [index] % 256);
                position++;
        }
       
        //  end the string
        string [position] = '\0';
       
        //  cut off the trailing blanks
        for (index = position - 1; index > 0 && ' ' == string [index]; index--)
                string [index] = '\0';
       
        return string;
}

////////////////////////////////////发送IDENTIFY命令给硬盘驱动器/////////////////////////////////
//
//  参数说明:
//                HANDLE hPhysicalDriveIOCTL  : 硬盘的句柄
//                BYTE bDriveNum                    : 最多支持范围0-3内的硬盘
//                BYTE bIDCmd                 : IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
//   注意:   
//              DeviceIoControl函数为此函数的核心,详情参考MSDN       
//                       
//   返回值  
//            0                        : 发送成功
//            1                        : 发送失败
//
//   备注:所有未定义的变量用sSep进行分隔存在pResultStr中
//
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CMKYSystemInfo::DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
                                                                 PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
                                                                 PDWORD lpcbBytesReturned)
{
        // Set up data structures for IDENTIFY command.
        pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
        pSCIP -> irDriveRegs.bFeaturesReg = 0;
        pSCIP -> irDriveRegs.bSectorCountReg = 1;
        pSCIP -> irDriveRegs.bSectorNumberReg = 1;
        pSCIP -> irDriveRegs.bCylLowReg = 0;
        pSCIP -> irDriveRegs.bCylHighReg = 0;
       
        // Compute the drive number.
        pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);
       
        // The command can either be IDE identify or ATAPI identify.
        pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
        pSCIP -> bDriveNumber = bDriveNum;
        pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
       
        return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,
                (LPVOID) pSCIP,
                sizeof(SENDCMDINPARAMS) - 1,
                (LPVOID) pSCOP,
                sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
                lpcbBytesReturned, NULL) );
}
2006-6-12 14:50
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
一个函数是获取IDE,一个SCSI

////////////////////////获取NT系统下ide硬盘的信息/////////////////////////
//                      说明:当成功取得返回0                            //
//////////////////////////////////////////////////////////////////////////
BOOL CMKYSystemInfo::ReadPhysicalDriveInNT (void)
{
        BOOL done = FALSE;
        int drive = 0;
       
        for (drive = 0; drive < MAX_IDE_DRIVES; drive++)
        {
                HANDLE hPhysicalDriveIOCTL = 0;
               
                //  Try to get a handle to PhysicalDrive IOCTL, report failure
                //  and exit if can't.
                TCHAR driveName [256];
               
                sprintf (driveName, _T("\\\\.\\PhysicalDrive%d"), drive);
               
                //  Windows NT, Windows 2000, must have admin rights
                hPhysicalDriveIOCTL = CreateFile (driveName,
                        GENERIC_READ | GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, 0, NULL);
               
                if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
                {
                        GETVERSIONOUTPARAMS VersionParams;
                        DWORD               cbBytesReturned = 0;
                       
                        // Get the version, etc of PhysicalDrive IOCTL
                        memset ((void*) &VersionParams, 0, sizeof(VersionParams));
                       
                        if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION,
                                NULL,
                                0,
                                &VersionParams,
                                sizeof(VersionParams),
                                &cbBytesReturned, NULL) )
                        {         
                        }
                       
                        // If there is a IDE device at number "i" issue commands
                        // to the device
                        if (VersionParams.bIDEDeviceMap > 0)
                        {
                                BYTE             bIDCmd = 0;   // IDE or ATAPI IDENTIFY cmd
                                SENDCMDINPARAMS  scip;
                               
                                // Now, get the ID sector for all IDE devices in the system.
                                // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
                                // otherwise use the IDE_ATA_IDENTIFY command
                                bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10) ? \
                                IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
                               
                                memset (&scip, 0, sizeof(scip));
                                memset (IdOutCmd, 0, sizeof(IdOutCmd));
                               
                                if ( DoIDENTIFY (hPhysicalDriveIOCTL,
                                        &scip,
                                        (PSENDCMDOUTPARAMS)&IdOutCmd,
                                        (BYTE) bIDCmd,
                                        (BYTE) drive,
                                        &cbBytesReturned))
                                {
                                        DWORD diskdata [256];
                                        int ijk = 0;
                                        USHORT *pIdSector = (USHORT *)
                                                ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;
                                       
                                        for (ijk = 0; ijk < 256; ijk++)
                                                diskdata [ijk] = pIdSector [ijk];
                                       
                                        pcharHDSN = (CString *)ConvertToString (diskdata, 10, 19);
                                        done = TRUE;
                                }
                        }
                       
                        CloseHandle (hPhysicalDriveIOCTL);
                }
        }       
        return done;
}

////////////////////////获取NT系统下scsi硬盘的信息////////////////////////
//                      说明:当成功取得返回0                            //
//////////////////////////////////////////////////////////////////////////
int CMKYSystemInfo::ReadIdeDriveAsScsiDriveInNT (void)
{
        int done = FALSE;
        int controller = 0;
       
        for (controller = 0; controller < 2; controller++)
        {
                HANDLE hScsiDriveIOCTL = 0;
                TCHAR   driveName [256];
               
                //  Try to get a handle to PhysicalDrive IOCTL, report failure
                //  and exit if can't.
                sprintf (driveName, "\\\\.\\Scsi%d:", controller);
               
                //  Windows NT, Windows 2000, any rights should do
                hScsiDriveIOCTL = CreateFile (driveName,
                        GENERIC_READ | GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, 0, NULL);
               
                if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
                {
                        int drive = 0;
                       
                        for (drive = 0; drive < 2; drive++)
                        {
                                TCHAR buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
                                SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
                                SENDCMDINPARAMS *pin =
                                        (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
                                DWORD dummy;
                               
                                memset (buffer, 0, sizeof (buffer));
                                p -> HeaderLength = sizeof (SRB_IO_CONTROL);
                                p -> Timeout = 10000;
                                p -> Length = SENDIDLENGTH;
                                p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
                                strncpy ((TCHAR *) p -> Signature, "SCSIDISK", 8);
                               
                                pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
                                pin -> bDriveNumber = drive;
                               
                                if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
                                        buffer,
                                        sizeof (SRB_IO_CONTROL) +
                                        sizeof (SENDCMDINPARAMS) - 1,
                                        buffer,
                                        sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
                                        &dummy, NULL))
                                {
                                        SENDCMDOUTPARAMS *pOut =
                                                (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
                                        IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
                                        if (pId -> sModelNumber [0])
                                        {
                                                DWORD diskdata [256];
                                                int ijk = 0;
                                                USHORT *pIdSector = (USHORT *) pId;
                                               
                                                for (ijk = 0; ijk < 256; ijk++)
                                                        diskdata [ijk] = pIdSector [ijk];
                                               
                                                pcharHDSN = (CString *)ConvertToString (diskdata, 10, 19);
                                                done = TRUE;
                                        }
                                }
                        }
                        CloseHandle (hScsiDriveIOCTL);
                }
        }
       
        return done;
}

你可以自己写个类似的函数判断是不是NT操作系统
bool CMKYSystemInfo::IsWinNT()
{
        OSVERSIONINFO OSVersionInfo;
       
        OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
       
        GetVersionEx(&OSVersionInfo);
       
        return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}
2006-6-12 14:53
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
在win98系统下获取硬件信息需要获取ring0权限.

__declspec(naked) void Ring0GetPortVal()
{
        _asm
        {
                Cmp CL, 1
                        Je ByteVal
                        Cmp CL, 2
                        Je WordVal
                        Cmp CL, 4
                        Je DWordVal
                       
ByteVal:
               
                In AL, DX
                        Mov [EBX], AL
                        Retf
                       
WordVal:
               
                In AX, DX
                        Mov [EBX], AX
                        Retf
                       
DWordVal:
               
                In EAX, DX
                        Mov [EBX], EAX
                        Retf
        }
}

__declspec(naked) void Ring0SetPortVal()
{
        _asm
        {
                Cmp CL, 1
                        Je ByteVal
                        Cmp CL, 2
                        Je WordVal
                        Cmp CL, 4
                        Je DWordVal
                       
ByteVal:
               
                Mov AL, [EBX]
                        Out DX, AL
                        Retf
                       
WordVal:
               
                Mov AX, [EBX]
                        Out DX, AX
                        Retf
                       
DWordVal:
               
                Mov EAX, [EBX]
                        Out DX, EAX
                        Retf
        }
}

bool CMKYSystemInfo::InitializeWinIo()
{
        TCHAR szExePath[MAX_PATH];
        PSTR pszSlash;
       
        IsNT = IsWinNT();
       
        if (IsNT)
        {
                if (!GetModuleFileName(GetModuleHandle(NULL), szExePath, sizeof(szExePath)))
                        return false;
               
                pszSlash = strrchr(szExePath, '\\');
               
                if (pszSlash)
                        pszSlash[1] = 0;
                else
                        return false;
               
                strcat(szExePath, _T("winio.sys"));
        }
       
        IsWinIoInitialized = true;
       
        return true;
}

// This function makes it possible to call ring 0 code from a ring 3
// application.

bool CMKYSystemInfo::CallRing0(PVOID pvRing0FuncAddr, WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
       
        struct GDT_DESCRIPTOR *pGDTDescriptor;
        struct GDTR gdtr;
        WORD CallgateAddr[3];
        WORD wGDTIndex = 1;
       
        _asm Sgdt [gdtr]
               
                // Skip the null descriptor
               
                pGDTDescriptor = (struct GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);
       
        // Search for a free GDT descriptor
       
        for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
        {
                if (pGDTDescriptor->Type == 0     &&
                        pGDTDescriptor->System == 0   &&
                        pGDTDescriptor->DPL == 0      &&
                        pGDTDescriptor->Present == 0)
                {
                        // Found one !
                        // Now we need to transform this descriptor into a callgate.
                        // Note that we're using selector 0x28 since it corresponds
                        // to a ring 0 segment which spans the entire linear address
                        // space of the processor (0-4GB).
                       
                        struct CALLGATE_DESCRIPTOR *pCallgate;
                       
                        pCallgate =        (struct CALLGATE_DESCRIPTOR *) pGDTDescriptor;
                        pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
                        pCallgate->Selector = 0x28;
                        pCallgate->ParamCount =        0;
                        pCallgate->Unused = 0;
                        pCallgate->Type = 0xc;
                        pCallgate->System = 0;
                        pCallgate->DPL = 3;
                        pCallgate->Present = 1;
                        pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);
                       
                        // Prepare the far call parameters
                       
                        CallgateAddr[0] = 0x0;
                        CallgateAddr[1] = 0x0;
                        CallgateAddr[2] = (wGDTIndex << 3) | 3;
                       
                        // Please fasten your seat belts!
                        // We're about to make a hyperspace jump into RING 0.
                       
                        _asm Mov DX, [wPortAddr]
                                _asm Mov EBX, [pdwPortVal]
                                _asm Mov CL, [bSize]
                                _asm Call FWORD PTR [CallgateAddr]
                               
                                // We have made it !
                                // Now free the GDT descriptor
                               
                                memset(pGDTDescriptor, 0, 8);
                       
                        // Our journey was successful. Seeya.
                       
                        return true;
                }
               
                // Advance to the next GDT descriptor
               
                pGDTDescriptor++;
        }
       
        // Whoops, the GDT is full
       
        return false;
}

bool CMKYSystemInfo::GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
        bool Result;
        DWORD dwBytesReturned;
        struct tagPort32Struct Port32Struct;
       
        if (IsNT)
        {
                if (!IsWinIoInitialized)
                        return false;
               
                Port32Struct.wPortAddr = wPortAddr;
                Port32Struct.bSize = bSize;
               
                if (!DeviceIoControl(hDriver, IOCTL_WINIO_READPORT, &Port32Struct,
                        sizeof(struct tagPort32Struct), &Port32Struct,
                        sizeof(struct tagPort32Struct),
                        &dwBytesReturned, NULL))
                        return false;
                else
                        *pdwPortVal = Port32Struct.dwPortVal;
        }
        else
        {
                Result = CallRing0((PVOID)Ring0GetPortVal, wPortAddr, pdwPortVal, bSize);
               
                if (Result == false)
                        return false;
        }
       
        return true;
}

bool CMKYSystemInfo::SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize)
{
        DWORD dwBytesReturned;
        struct tagPort32Struct Port32Struct;
       
        if (IsNT)
        {
                if (!IsWinIoInitialized)
                        return false;
               
                Port32Struct.wPortAddr = wPortAddr;
                Port32Struct.dwPortVal = dwPortVal;
                Port32Struct.bSize = bSize;
               
                if (!DeviceIoControl(hDriver, IOCTL_WINIO_WRITEPORT, &Port32Struct,
                        sizeof(struct tagPort32Struct), NULL, 0, &dwBytesReturned, NULL))
                        return false;
        }
        else
                return CallRing0((PVOID)Ring0SetPortVal, wPortAddr, &dwPortVal, bSize);
       
        return true;
}

////////////////////////获取98系统下ide硬盘的信息/////////////////////////
//                      说明:当成功取得返回0                            //
//////////////////////////////////////////////////////////////////////////
int CMKYSystemInfo::ReadDrivePortsInWin9X (void)
{
        int done = FALSE;
        int drive = 0;
       
        InitializeWinIo ();   
       
        //  Get IDE Drive info from the hardware ports
        //  loop thru all possible drives
        for (drive = 0; drive < 8; drive++)
        {
                DWORD diskdata [256];
                WORD  baseAddress = 0;   //  Base address of drive controller
                DWORD portValue = 0;
                int waitLoop = 0;
                int index = 0;
               
                switch (drive / 2)
                {
                case 0: baseAddress = 0x1f0; break;
                case 1: baseAddress = 0x170; break;
                case 2: baseAddress = 0x1e8; break;
                case 3: baseAddress = 0x168; break;
                }
               
                //  Wait for controller not busy
                waitLoop = 100000;
                while (--waitLoop > 0)
                {
                        GetPortVal ((WORD) (baseAddress + 7), &portValue, (BYTE) 1);
                        //  drive is ready
                        if ((portValue & 0x40) == 0x40) break;
                        //  previous drive command ended in error
                        if ((portValue & 0x01) == 0x01) break;
                }
               
                if (waitLoop < 1) continue;
               
                //  Set Master or Slave drive
                if ((drive % 2) == 0)
                        SetPortVal ((WORD) (baseAddress + 6), 0xA0, 1);
                else
                        SetPortVal ((WORD) (baseAddress + 6), 0xB0, 1);
               
                //  Get drive info data
                SetPortVal ((WORD) (baseAddress + 7), 0xEC, 1);
               
                // Wait for data ready
                waitLoop = 100000;
                while (--waitLoop > 0)
                {
                        GetPortVal ((WORD) (baseAddress + 7), &portValue, 1);
                        //  see if the drive is ready and has it's info ready for us
                        if ((portValue & 0x48) == 0x48) break;
                        //  see if there is a drive error
                        if ((portValue & 0x01) == 0x01) break;
                }
               
                //  check for time out or other error                                                   
                if (waitLoop < 1 || portValue & 0x01) continue;
               
                //  read drive id information
                for (index = 0; index < 256; index++)
                {
                        diskdata [index] = 0;   //  init the space
                        GetPortVal (baseAddress, &(diskdata [index]), 2);
                }
               
                pcharHDSN = (CString *)ConvertToString (diskdata, 10, 19);
                done = TRUE;
        }
       
        return done;
}
2006-6-12 14:57
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
上面这些函数我都测试过的,当时好像是为了写个加密的程序,需要把硬件信息作为加密的引子,不知道楼主是否也是出于这个目的,除了获取CPU的物理硬件信息,你还可以考虑获取BIOS的序列号,网卡mac地址等等.

PS:不知道获取硬盘信息的函数能不能获取现在的串口硬盘信息,楼主可以试一下
2006-6-12 15:01
0
雪    币: 221
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
8
Thanks a lot
2006-6-12 17:03
0
雪    币: 446
活跃值: (758)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
8错,偶跟踪过几个程序,和上面的代码差不多,本来准备将ASM发上来的,现在不用了
2006-6-13 07:19
0
游客
登录 | 注册 方可回帖
返回
//