VC获取硬盘序列号源码
//  diskid32.cpp
//  for displaying the details of hard drives in a command window
//  06/11/00  Lynn McGuire  written with many contributions from others,
//                            IDE drives only under Windows NT/2K and 9X,
//                            maybe SCSI drives later
//  11/20/03  Lynn McGuire  added ReadPhysicalDriveInNTWithZeroRights
//  10/26/05  Lynn McGuire  fix the flipAndCodeBytes function
//  12/8/06  Chunlin Deng  update the string function to security version.
//  Testing Passed with Visul Studio 2005.
#define PRINTING_TO_CONSOLE_ALLOWED
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <windows.h>
#include <winioctl.h>
//  special include from the MS DDK
//#include "c:/win2kddk/inc/ddk/ntddk.h"
//#include "c:/win2kddk/inc/ntddstor.h"
#define  TITLE  "DiskId32"
char HardDriveSerialNumber [1024];
char HardDriveModelNumber [1024];
void WriteConstantString (char *entry, char *string)
{
}
//  Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(1)
#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 Co
mmand 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);
//  Max number of drives assuming primary/secondary, master/slave topology
#define  MAX_IDE_DRIVES  16
int ReadPhysicalDriveInNTWithAdminRights (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_s (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;
}
//  Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(4)
/
/
// IOCTL_STORAGE_QUERY_PROPERTY
//
// Input Buffer:
//      a STORAGE_PROPERTY_QUERY structure which describes what type of query
//      is being done, what property is being queried for, and any additional
//      parameters which a particular property query requires.
//
//  Output Buffer:
//      Contains a buffer to place the results of the query into.  Since all
//      property descriptors can be cast into a STORAGE_DESCRIPTOR_HEADER,
/
/      the IOCTL can be called once with a small buffer then again using
//      a buffer as large as the header reports is necessary.
//
//
// Types of queries
//
typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0,          // Retrieves the descriptor
PropertyExistsQuery,                // Used to test whether the descriptor is supported
PropertyMaskQuery,                  // Used to retrieve a mask of writeable fields in the descriptor
PropertyQueryMaxDefined    // use to validate the value
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
//
// define some initial property id's
//
typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0,
StorageAdapterProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
//
// Query structure - additional parameters for specific queries can follow
// the header
/
/
typedef struct _STORAGE_PROPERTY_QUERY {
//
// ID of the property being retrieved
//
STORAGE_PROPERTY_ID PropertyId;
//
// Flags indicating the type of query being performed
//
STORAGE_QUERY_TYPE QueryType;
//
/
/ Space for additional parameters if necessary
//
UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
#define IOCTL_STORAGE_QUERY_PROPERTY  CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
//
// Device property descriptor - this is really just a rehash of the inquiry
// data retrieved from a scsi device
//
// This may only be retrieved from a target device.  Sending this to the bus
// will result in an error
//
#pragma pack(4)
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
//
// Sizeof(STORAGE_DEVICE_DESCRIPTOR)
//
ULONG Version;
//
// Total size of the descriptor, including the space for additional
// data and id strings
//
ULONG Size;
//
// The SCSI-2 device type
//
UCHAR DeviceType;
//
// The SCSI-2 device type modifier (if any) - this may be zer
o
//
UCHAR DeviceTypeModifier;
//
/
/ Flag indicating whether the device's media (if any) is removable.  This
// field should be ignored for media-less devices
//
BOOLEAN RemovableMedia;
//
// Flag indicating whether the device can support mulitple outstanding
// commands.  The actual synchronization in this case is the responsibility
// of the port driver.
//
BOOLEAN CommandQueueing;
//
/
/ Byte offset to the zero-terminated ascii string containing the device's
// vendor id string.  For devices with no such ID this will be zero
//
ULONG VendorIdOffset;
//
// Byte offset to the zero-terminated ascii string containing the device's
// product id string.  For devices with no such ID this will be zero
//
ULONG ProductIdOffset;
//
// Byte offset to the zero-terminated ascii string containing the device's
/
/ product revision string.  For devices with no such string this will be
// zero
//
ULONG ProductRevisionOffset;
//
// Byte offset to the zero-terminated ascii string containing the device's
// serial number.  For devices with no serial number this will be zero
//
ULONG SerialNumberOffset;
//
// Contains the bus type (as defined above) of the device.  It should be
/
/ used to interpret the raw device properties at the end of this structure
// (if any)
//
STORAGE_BUS_TYPE BusType;
//
// The number of bytes of bus-specific data which have been appended to
// this descriptor
//
ULONG RawPropertiesLength;
//
// Place holder for the first byte of the bus specific property data
/
/
UCHAR RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
//  function to decode the serial numbers of IDE hard drives
//  using the IOCTL_STORAGE_QUERY_PROPERTY command
char * flipAndCodeBytes (char * str)
{
static char flipped [1000];
int i = 0;
int j = 0;
int k = 0;
int num = strlen (str);
strcpy_s (flipped,"");
for (i = 0; i < num; i += 4)
{
for (j = 1; j >= 0; j--)
{
int sum = 0;
for (k = 0; k < 2; k++)
{
sum *= 16;
switch (str [i + j * 2 + k])
{
case '0': sum += 0; break;
case '1': sum += 1; break;
case '2': sum += 2; break;
case '3': sum += 3; break;
case '4': sum += 4; break;
case '5': sum += 5; break;
case '6': sum += 6; break;
case '7': sum += 7; break;
case '8': sum += 8; break;
case '9': sum += 9; break;
case 'a': sum += 10; break;
case 'b': sum += 11; break;
case 'c': sum += 12; break;
硬盘序列号查询case 'd': sum += 13; break;
case 'e': sum += 14; break;
case 'f': sum += 15; break;
case 'A': sum += 10; break;
case 'B': sum += 11; break;
case 'C': sum += 12; break;
case 'D': sum += 13; break;
case 'E': sum +

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。