我有一個下載的程序,可以得到HD的物理ID.
有點長,得有人幫忙頂一下才能回復完.
//  diskid32.cpp//  for displaying the details of hard drives in //  06/11/2000  Lynn McGuire  written with many contributions from others,
//                            IDE drives only under Windows NT/2K and 9X,
//                            maybe SCSI drives later
#define PRINTING_TO_CONSOLE_ALLOWED
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
   //  Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(1)
   //  Max number of drives assuming primary/secondary, master/slave topology
#define  MAX_IDE_DRIVES  4
#define  IDENTIFY_BUFFER_SIZE  512
   //  IOCTL commands
#define  DFP_GET_VERSION          0x00074080
#define  DFP_SEND_DRIVE_COMMAND   0x0007c084
#define  DFP_RECEIVE_DRIVE_DATA   0x0007c088#define  FILE_DEVICE_SCSI              0x0000001b
#define  IOCTL_SCSI_MINIPORT_IDENTIFY  ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition   //  GETVERSIONOUTPARAMS contains the data returned from the 
   //  Get Driver Version function.
typedef struct _GETVERSIONOUTPARAMS
{
   BYTE bVersion;      // Binary driver version.
   BYTE bRevision;     // Binary driver revision.
   BYTE bReserved;     // Not used.
   BYTE bIDEDeviceMap; // Bit map of IDE devices.
   DWORD fCapabilities; // Bit mask of driver capabilities.
   DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
   //  Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS 
#define  CAP_IDE_ID_FUNCTION             1  // ATA ID command supported
#define  CAP_IDE_ATAPI_ID                2  // ATAPI ID command supported
#define  CAP_IDE_EXECUTE_SMART_FUNCTION  4  // SMART commannds supported
   //  IDE registers
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, *PIDEREGS, *LPIDEREGS;
   //  SENDCMDINPARAMS contains the input parameters for the 
   //  Send Command to Drive function.
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, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
   //  Valid values for the bCommandReg member of IDEREGS.
#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
   // Status returned from driver
typedef struct _DRIVERSTATUS
{
   BYTE  bDriverError;  //  Error code from driver, or 0 if no error.
   BYTE  bIDEStatus;    //  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, *PDRIVERSTATUS, *LPDRIVERSTATUS;
   // Structure returned by PhysicalDrive IOCTL for several commands
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, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
   // The following struct defines the interesting part of the IDENTIFY
   // buffer:
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;
typedef struct _SRB_IO_CONTROL
{
   ULONG HeaderLength;
   UCHAR Signature[8];
   ULONG Timeout;
   ULONG ControlCode;
   ULONG ReturnCode;
   ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
   // Define global buffers.
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex);
void PrintIdeInfo (int drive, DWORD diskdata [256]);
BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE,PDWORD);

解决方案 »

  1.   

    int ReadPhysicalDriveInNT (void)
    {
       int 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.
          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))
                {
                   DWORD diskdata [256];
                   int ijk = 0;
                   USHORT *pIdSector = (USHORT *)
                                 ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;               for (ijk = 0; ijk < 256; ijk++)
                      diskdata [ijk] = pIdSector [ijk];               PrintIdeInfo (drive, diskdata);               done = TRUE;
                }
        }         CloseHandle (hPhysicalDriveIOCTL);
          }
       }   return done;
    }
       // DoIDENTIFY
       // FUNCTION: Send an IDENTIFY command to the drive
       // bDriveNum = 0-3
       // bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
    BOOL 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) );
    }
      

  2.   

    int ReadPhysicalDriveInNT (void)
    {
       int 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.
          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))
                {
                   DWORD diskdata [256];
                   int ijk = 0;
                   USHORT *pIdSector = (USHORT *)
                                 ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;               for (ijk = 0; ijk < 256; ijk++)
                      diskdata [ijk] = pIdSector [ijk];               PrintIdeInfo (drive, diskdata);               done = TRUE;
                }
        }         CloseHandle (hPhysicalDriveIOCTL);
          }
       }   return done;
    }
       // DoIDENTIFY
       // FUNCTION: Send an IDENTIFY command to the drive
       // bDriveNum = 0-3
       // bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
    BOOL 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) );
    }
      

  3.   

    我记得好像有一个api函数可以
      

  4.   

    我的本意是想获得USN的盘符,本地硬盘这个程序好用,可USB的就不行了,
    另外请问
    #define  DFP_GET_VERSION          0x00074080
    #define  DFP_SEND_DRIVE_COMMAND   0x0007c084
    #define  DFP_RECEIVE_DRIVE_DATA   0x0007c088
    是什么意思?0x00074080在那里有声明?
      

  5.   

    这个问题我自己解决了,经研究microsoft的MFC和SDK没有提供类似的函数或编程接口,解决类似的问题有两种办法:1.利用2000,98或me的DDK写驱动程序; 2 查询注册表,在注册表中(不管2000,98或me)有一条线连着所有的类似信息,可以动态的查询出来。
    多谢各位帮忙。