我有一個下載的程序,可以得到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);
有點長,得有人幫忙頂一下才能回復完.
// 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);
{
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) );
}
{
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) );
}
另外请问
#define DFP_GET_VERSION 0x00074080
#define DFP_SEND_DRIVE_COMMAND 0x0007c084
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
是什么意思?0x00074080在那里有声明?
多谢各位帮忙。