1.我指的是“硬盘”的ID号,就是全球唯一的。
 2.不是说用GetVolumeInformation(...)得到的那种,
还有就是重装Windows后, 用GetVolumeInformation(...)得到同一磁盘的ID,在重装前后会不会一样?

解决方案 »

  1.   

    http://www.moreres.com/down/svc021405.zip //  IOCTL commands
    #define  DFP_GET_VERSION          0x00074080
    int ReadPhysicalDriveInNT (DWORD diskdata[256])
    {
       int done = FALSE;
       int drive = 0;   HANDLE hPhysicalDriveIOCTL = 0;   //  Try to get a handle to PhysicalDrive IOCTL, report failure
       //  and exit if can't.  char driveName [256];
      sprintf (driveName, "\\\\.\\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)
          //    printf ("Unable to open physical drive %d, error code: 0x%lX\n",
          //            drive, GetLastError ());   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) )
          {         
             // printf ("DFP_GET_VERSION failed for drive %d\n", i);
             // continue;
          }         // 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;
             //SENDCMDOUTPARAMS OutCmd;  // 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))
             {
     int ijk = 0;
     USHORT *pIdSector = (USHORT *)
                                 ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;  for (ijk = 0; ijk < 256; ijk++)
                      diskdata [ijk] = pIdSector [ijk];             done = TRUE;
        }         CloseHandle (hPhysicalDriveIOCTL);
          }
       }   return done;
    }
      

  2.   

    用GetVolumeInformation(...)得到同一磁盘的ID,在重装前后会不会一样?答:一样
      

  3.   

    可以通过调用Windows提供的外部函数GetVolumeInformationA()来实现。
      

  4.   

    GetVolumeInformation()得到的序列号格式化硬盘后就会改变。具体可以通过vol命令查看。如果非格式化重装,这个序列号是不会变的。以下是读硬盘出厂芯片id,可以在win98/me/2000/xp下运行,Good luck!!
      

  5.   

    //winio.h
    #ifndef WINIO_H
    #define WINIO_H// Define the various device type values.  Note that values used by Microsoft
    // Corporation are in the range 0-32767, and 32768-65535 are reserved for use
    // by customers.#define FILE_DEVICE_WINIO 0x00008010// Macro definition for defining IOCTL and FSCTL function control codes.
    // Note that function codes 0-2047 are reserved for Microsoft Corporation,
    // and 2048-4095 are reserved for customers.#define WINIO_IOCTL_INDEX 0x810// Define our own private IOCTL#define IOCTL_WINIO_MAPPHYSTOLIN  CTL_CODE(FILE_DEVICE_WINIO,  \
                                      WINIO_IOCTL_INDEX,      \
                                      METHOD_BUFFERED,        \
                                      FILE_ANY_ACCESS)#define IOCTL_WINIO_UNMAPPHYSADDR CTL_CODE(FILE_DEVICE_WINIO,  \
                                      WINIO_IOCTL_INDEX + 1,  \
                                      METHOD_BUFFERED,        \
                                      FILE_ANY_ACCESS)#define IOCTL_WINIO_WRITEPORT     CTL_CODE(FILE_DEVICE_WINIO,  \
                                      WINIO_IOCTL_INDEX + 2,   \
                                      METHOD_BUFFERED,         \
                                      FILE_ANY_ACCESS)#define IOCTL_WINIO_READPORT      CTL_CODE(FILE_DEVICE_WINIO,  \
                                      WINIO_IOCTL_INDEX + 3,   \
                                      METHOD_BUFFERED,         \
                                      FILE_ANY_ACCESS)struct tagPhys32Struct
    {
      HANDLE PhysicalMemoryHandle;
      ULONG dwPhysMemSizeInBytes;
      PVOID pvPhysAddress;
      PVOID pvPhysMemLin;
    };extern struct tagPhys32Struct Phys32Struct;struct tagPort32Struct
    {
      USHORT wPortAddr;
      ULONG dwPortVal;
      UCHAR bSize;
    };extern struct tagPort32Struct Port32Struct;#endif
      

  6.   

    //port32.h
    #ifndef PORT32_H
    #define PORT32_H#ifdef WINIO_DLL
    #define PORT32API _declspec(dllexport)
    #else
    #define PORT32API _declspec(dllimport)
    #endif#pragma pack(1)struct GDT_DESCRIPTOR
    {
      WORD Limit_0_15;
      WORD Base_0_15;
      BYTE Base_16_23;  BYTE Type         : 4;
      BYTE System       : 1;
      BYTE DPL          : 2;
      BYTE Present      : 1;
      BYTE Limit_16_19  : 4;
      BYTE Available    : 1;
      BYTE Reserved     : 1;
      BYTE D_B          : 1;
      BYTE Granularity  : 1;
      BYTE Base_24_31;
    };struct CALLGATE_DESCRIPTOR
    {
      WORD Offset_0_15;
      WORD Selector;
      WORD ParamCount   : 5;
      WORD Unused       : 3;
      WORD Type         : 4;
      WORD System       : 1;
      WORD DPL          : 2;
      WORD Present      : 1;
      WORD Offset_16_31;
    };struct GDTR
    {
      WORD wGDTLimit;
      DWORD dwGDTBase;
    };#pragma pack()
    //extern "C"
    //{
    //  PORT32API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
    //  PORT32API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
    //}#endif