参考:http://www.winsim.com/diskid32/diskid32.cpp

//  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. 

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "diskid.h"
#include <WinIoCtl.h>//  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 //  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. // 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],char *sDest,int nLen);
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(char *sBuff,int nLen)
{ int done = FALSE; HANDLE hPhysicalDriveIOCTL = 0; TCHAR driveName[MAX_PATH]; for ( int drive = 0; drive < MAX_IDE_DRIVES; drive++ ){ //  Try to get a handle to PhysicalDrive IOCTL, report failure //  and exit if can''t. _stprintf_s (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) //    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,sBuff,nLen); done = TRUE; } } CloseHandle(hPhysicalDriveIOCTL); } }//end forreturn 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.
// #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) //  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 += 14; break; case 'F':  sum += 15; break; } } if (sum > 0)  { char sub [2]; sub [0] = (char) sum; sub [1] = 0; strcat_s (flipped, sub); } } } return flipped;
} typedef struct _MEDIA_SERAL_NUMBER_DATA { ULONG  SerialNumberLength;  ULONG  Result; ULONG  Reserved[2]; UCHAR  SerialNumberData[1];
} MEDIA_SERIAL_NUMBER_DATA, *PMEDIA_SERIAL_NUMBER_DATA; int ReadPhysicalDriveInNTWithZeroRights(char *sBuff,int nLen)
{ int done = FALSE; HANDLE hPhysicalDriveIOCTL = 0; TCHAR driveName [MAX_PATH]; for (int drive = 0; drive < MAX_IDE_DRIVES; drive++){ //  Try to get a handle to PhysicalDrive IOCTL, report failure //  and exit if can''t. _stprintf_s (driveName, _T("\\\\.\\PhysicalDrive%d"), drive); //  Windows NT, Windows 2000, Windows XP - admin rights not required hPhysicalDriveIOCTL = CreateFile (driveName, 0, 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 ) { STORAGE_PROPERTY_QUERY query; DWORD cbBytesReturned = 0; char buffer [10000]; memset ((void *) & query, 0, sizeof (query)); query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; memset (buffer, 0, sizeof (buffer)); if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY, & query, sizeof(query), &buffer, sizeof(buffer), &cbBytesReturned, NULL) ){          STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *) & buffer; char serialNumber [1000]; char modelNumber [1000]; strcpy_s (serialNumber,  flipAndCodeBytes ( & buffer [descrip -> SerialNumberOffset])); strcpy_s (modelNumber, & buffer [descrip -> ProductIdOffset]); if ( 0 == sBuff [0] && //  serial number must be alphanumeric //  (but there can be leading spaces on IBM drives) (isalnum (serialNumber [0]) || isalnum (serialNumber [19])) ) { strcpy_s (sBuff, nLen, serialNumber); //strcpy_s (HardDriveModelNumber, modelNumber); done = TRUE; }  }else{ DWORD err = GetLastError(); //printf ("\nDeviceIOControl IOCTL_STORAGE_QUERY_PROPERTY error = %d\n", err);
            } memset (buffer, 0, sizeof (buffer)); if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, NULL, 0, &buffer, sizeof(buffer), &cbBytesReturned, NULL) ) {          MEDIA_SERIAL_NUMBER_DATA * mediaSerialNumber = (MEDIA_SERIAL_NUMBER_DATA *) & buffer; char serialNumber [1000]; // char modelNumber [1000]; strcpy_s (serialNumber, (char *) mediaSerialNumber -> SerialNumberData); // strcpy_s (modelNumber, & buffer [descrip -> ProductIdOffset]); if ( 0 == sBuff[0] && //  serial number must be alphanumeric //  (but there can be leading spaces on IBM drives) (isalnum (serialNumber [0]) || isalnum (serialNumber [19])) ) { strcpy_s (sBuff, nLen, serialNumber); // strcpy_s (HardDriveModelNumber, modelNumber); done = TRUE; } //printf ("\n**** MEDIA_SERIAL_NUMBER_DATA for drive %d ****\nSerial Number = %s\n", drive, serialNumber); }else{ //DWORD err = GetLastError (); //switch (err) //{ //case 1:  //    printf ("\nDeviceIOControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER error = \n" //        "              The request is not valid for this device.\n\n"); //    break; //case 50: //    printf ("\nDeviceIOControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER error = \n" //        "              The request is not supported for this device.\n\n"); //    break; //default: //    printf ("\nDeviceIOControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER error = %d\n\n", err); //}
            } CloseHandle (hPhysicalDriveIOCTL); } }//end forreturn 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) );
} //  --------------------------------------------------- // (* Output Bbuffer for the VxD (rt_IdeDinfo record) *)
typedef struct _rt_IdeDInfo_
{ BYTE IDEExists[4]; BYTE DiskExists[8]; WORD DisksRawInfo[8*256];
} rt_IdeDInfo, *pt_IdeDInfo; // (* IdeDinfo "data fields" *)
typedef struct _rt_DiskInfo_
{ BOOL DiskExists; BOOL ATAdevice; BOOL RemovableDevice; WORD TotLogCyl; WORD TotLogHeads; WORD TotLogSPT; char SerialNumber[20]; char FirmwareRevision[8]; char ModelNumber[40]; WORD CurLogCyl; WORD CurLogHeads; WORD CurLogSPT;
} rt_DiskInfo; #define  m_cVxDFunctionIdesDInfo  1 //int ReadDrivePortsInWin9X(char *sBuff,int nLen)
{ int done = FALSE; HANDLE VxDHandle = 0; pt_IdeDInfo pOutBufVxD = 0; DWORD lpBytesReturned = 0; //  set the thread priority high so that we get exclusive access to the disk BOOL status = SetPriorityClass (GetCurrentProcess (), REALTIME_PRIORITY_CLASS); if (0 == status){//printf ("\nERROR: Could not SetPriorityClass, LastError: %d\n", GetLastError ());
    }  // 1. Make an output buffer for the VxD
    rt_IdeDInfo info; pOutBufVxD = &info; // ***************** // KLUDGE WARNING!!! // HAVE to zero out the buffer space for the IDE information! // If this is NOT done then garbage could be in the memory // locations indicating if a disk exists or not. ZeroMemory (&info, sizeof(info)); // 1. Try to load the VxD //  must use the short file name path to open a VXD file //char StartupDirectory [2048]; //char shortFileNamePath [2048]; //char *p = NULL; //char vxd [2048]; //  get the directory that the exe was started from //GetModuleFileName (hInst, (LPSTR) StartupDirectory, sizeof (StartupDirectory)); //  cut the exe name from string //p = &(StartupDirectory [strlen (StartupDirectory) - 1]); //while (p >= StartupDirectory && *p && ''\\'' != *p) p--; //*p = ''\0'';    //GetShortPathName (StartupDirectory, shortFileNamePath, 2048); //sprintf_s (vxd, "\\\\.\\%s\\IDE21201.VXD", shortFileNamePath); //VxDHandle = CreateFile (vxd, 0, 0, 0, //               0, FILE_FLAG_DELETE_ON_CLOSE, 0);    VxDHandle = CreateFile (_T("\\\\.\\IDE21201.VXD"), 0, 0, 0, 0, FILE_FLAG_DELETE_ON_CLOSE, 0); if (VxDHandle != INVALID_HANDLE_VALUE) { // 2. Run VxD function DeviceIoControl (VxDHandle, m_cVxDFunctionIdesDInfo, 0, 0, pOutBufVxD, sizeof(pt_IdeDInfo), &lpBytesReturned, 0); // 3. Unload VxD
        CloseHandle (VxDHandle); }else{//MessageBox (NULL, "ERROR: Could not open IDE21201.VXD file",TITLE, MB_ICONSTOP);
    }// 4. Translate and store data for (int i=0; i<8; i++) { if((pOutBufVxD->DiskExists[i]) && (pOutBufVxD->IDEExists[i/2])) { DWORD diskinfo [256]; for (int j = 0; j < 256; j++)  diskinfo [j] = pOutBufVxD -> DisksRawInfo [i * 256 + j]; // process the information for this buffer
            PrintIdeInfo (i, diskinfo,sBuff,nLen); done = TRUE; } } //  reset the thread priority back to normal // SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_NORMAL);
    SetPriorityClass (GetCurrentProcess (), NORMAL_PRIORITY_CLASS); return done;
} #define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE int ReadIdeDriveAsScsiDriveInNT(char *sBuff,int nLen)
{ int done = FALSE; int controller = 0; for (controller = 0; controller < 16; controller++) { HANDLE hScsiDriveIOCTL = 0; TCHAR  driveName [MAX_PATH]; //  Try to get a handle to PhysicalDrive IOCTL, report failure //  and exit if can''t. _stprintf_s (driveName, _T("\\\\.\\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) //    printf ("Unable to open SCSI controller %d, error code: 0x%lX\n", //            controller, GetLastError ()); if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE) { int drive = 0; for (drive = 0; drive < 2; drive++) { char 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_s ((char *) p -> Signature,9,"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]; PrintIdeInfo (controller * 2 + drive, diskdata,sBuff,nLen); done = TRUE; } } } CloseHandle (hScsiDriveIOCTL); } } return done;
} ////
// IDENTIFY data (from ATAPI driver source)
//

#pragma pack(1)typedef struct _IDENTIFY_DATA {USHORT GeneralConfiguration;            // 00 00USHORT NumberOfCylinders;               // 02  1USHORT Reserved1;                       // 04  2USHORT NumberOfHeads;                   // 06  3USHORT UnformattedBytesPerTrack;        // 08  4USHORT UnformattedBytesPerSector;       // 0A  5USHORT SectorsPerTrack;                 // 0C  6USHORT VendorUnique1[3];                // 0E  7-9USHORT SerialNumber[10];                // 14  10-19USHORT BufferType;                      // 28  20USHORT BufferSectorSize;                // 2A  21USHORT NumberOfEccBytes;                // 2C  22USHORT FirmwareRevision[4];             // 2E  23-26USHORT ModelNumber[20];                 // 36  27-46UCHAR  MaximumBlockTransfer;            // 5E  47UCHAR  VendorUnique2;                   // 5FUSHORT DoubleWordIo;                    // 60  48USHORT Capabilities;                    // 62  49USHORT Reserved2;                       // 64  50UCHAR  VendorUnique3;                   // 66  51UCHAR  PioCycleTimingMode;              // 67UCHAR  VendorUnique4;                   // 68  52UCHAR  DmaCycleTimingMode;              // 69USHORT TranslationFieldsValid:1;        // 6A  53USHORT Reserved3:15;USHORT NumberOfCurrentCylinders;        // 6C  54USHORT NumberOfCurrentHeads;            // 6E  55USHORT CurrentSectorsPerTrack;          // 70  56ULONG  CurrentSectorCapacity;           // 72  57-58USHORT CurrentMultiSectorSetting;       //     59ULONG  UserAddressableSectors;          //     60-61USHORT SingleWordDMASupport : 8;        //     62USHORT SingleWordDMAActive : 8;USHORT MultiWordDMASupport : 8;         //     63USHORT MultiWordDMAActive : 8;USHORT AdvancedPIOModes : 8;            //     64USHORT Reserved4 : 8;USHORT MinimumMWXferCycleTime;          //     65USHORT RecommendedMWXferCycleTime;      //     66USHORT MinimumPIOCycleTime;             //     67USHORT MinimumPIOCycleTimeIORDY;        //     68USHORT Reserved5[2];                    //     69-70USHORT ReleaseTimeOverlapped;           //     71USHORT ReleaseTimeServiceCommand;       //     72USHORT MajorRevision;                   //     73USHORT MinorRevision;                   //     74USHORT Reserved6[50];                   //     75-126USHORT SpecialFunctionsEnabled;         //     127USHORT Reserved7[128];                  //     128-255
} IDENTIFY_DATA, *PIDENTIFY_DATA;#pragma pack()int ReadPhysicalDriveInNTUsingSmart(char *sBuff,int nLen)
{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.
        TCHAR driveName [MAX_PATH];_stprintf (driveName, _T("\\\\.\\PhysicalDrive%d"), drive);//  Windows NT, Windows 2000, Windows Server 2003, VistahPhysicalDriveIOCTL = CreateFile (driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE | 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){//if (PRINT_DEBUG) //    printf ("\n%d ReadPhysicalDriveInNTUsingSmart ERROR"//    "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n"//    "Error Code %d\n",//    __LINE__, driveName, GetLastError ());}else{GETVERSIONINPARAMS GetVersionParams;DWORD cbBytesReturned = 0;// Get the version, etc of PhysicalDrive IOCTLmemset ((void*) & GetVersionParams, 0, sizeof(GetVersionParams));if ( ! DeviceIoControl (hPhysicalDriveIOCTL, SMART_GET_VERSION, NULL, 0, &GetVersionParams, sizeof (GETVERSIONINPARAMS), &cbBytesReturned, NULL) ){         //if (PRINT_DEBUG)//{//    DWORD err = GetLastError ();//    printf ("\n%d ReadPhysicalDriveInNTUsingSmart ERROR"//        "\nDeviceIoControl(%d, SMART_GET_VERSION) returned 0, error is %d\n",//        __LINE__, (int) hPhysicalDriveIOCTL, (int) err);//}}else{// Print the SMART version// PrintVersion (& GetVersionParams);// Allocate the command bufferULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;PSENDCMDINPARAMS Command = (PSENDCMDINPARAMS)new BYTE[CommandSize];// Retrieve the IDENTIFY data// Prepare the command#define ID_CMD          0xEC            // Returns ID sector for ATACommand -> irDriveRegs.bCommandReg = ID_CMD;DWORD BytesReturned = 0;if ( ! DeviceIoControl (hPhysicalDriveIOCTL,SMART_RCV_DRIVE_DATA, Command, sizeof(SENDCMDINPARAMS), Command, CommandSize, &BytesReturned, NULL) ){// Print the error//PrintError ("SMART_RCV_DRIVE_DATA IOCTL", GetLastError());}else{// Print the IDENTIFY dataDWORD diskdata [256];USHORT *pIdSector = (USHORT *)(PIDENTIFY_DATA) ((PSENDCMDOUTPARAMS) Command) -> bBuffer;for (int ijk = 0; ijk < 256; ijk++){diskdata [ijk] = pIdSector [ijk];}PrintIdeInfo (drive, diskdata,sBuff,nLen); done = TRUE;}// Done
                CloseHandle (hPhysicalDriveIOCTL);delete []Command;}}}return done;
}void PrintIdeInfo(int drive, DWORD diskdata [256],char *sDest,int nLen)
{ char string1 [1024]; __int64 sectors = 0; __int64 bytes = 0; //  copy the hard drive serial number to the buffer strcpy_s (string1, ConvertToString (diskdata, 10, 19)); if (0 == sDest[0] && //  serial number must be alphanumeric //  (but there can be leading spaces on IBM drives) (isalnum (string1 [0]) || isalnum (string1 [19]))) { strcpy_s (sDest, nLen, string1); //strcpy_s (HardDriveModelNumber, ConvertToString (diskdata, 27, 46));
   }
} char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex)
{ static char string [1024]; int position = 0; //  each integer has two characters stored in it backwards for (int 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 (int index = position - 1; index > 0 && ' ' == string [index]; index--) string [index] = '\0'; return string;
} int GetHardDriveSerialNumber(char *sBuff,int nLen)
{int done = FALSE;// char string [1024];__int64 id = 0;OSVERSIONINFO version = {0};version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);GetVersionEx (&version);memset(sBuff,0,nLen);if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {//  this works under WinNT4 or Win2K if you have admin rights//printf ("\nTrying to read the drive IDs using physical access with admin rights\n");done = ReadPhysicalDriveInNTWithAdminRights(sBuff,nLen);//  this should work in WinNT or Win2K if previous did not work//  this is kind of a backdoor via the SCSI mini port driver into//     the IDE drives//printf ("\nTrying to read the drive IDs using the SCSI back door\n");if ( ! done){ done = ReadIdeDriveAsScsiDriveInNT(sBuff,nLen);}//  this works under WinNT4 or Win2K or WinXP if you have any rights//printf ("\nTrying to read the drive IDs using physical access with zero rights\n");if ( ! done){done = ReadPhysicalDriveInNTWithZeroRights(sBuff,nLen);}//  this works under WinNT4 or Win2K or WinXP or Windows Server 2003 or Vista if you have any rights//printf ("\nTrying to read the drive IDs using Smart\n");if ( ! done){done = ReadPhysicalDriveInNTUsingSmart(sBuff,nLen);}}else{//  this works under Win9X and calls a VXD//  try this up to 10 times to get a hard drive serial numberfor (int attempt = 0; attempt < 10 && ! done && 0 == sBuff[0]; attempt++) {done = ReadDrivePortsInWin9X(sBuff,nLen);}}return done;
}

转载于:https://www.cnblogs.com/initialb/archive/2013/04/07/3003893.html

正确获取硬盘序列号源码相关推荐

  1. 用C#获取硬盘序列号,CPU序列号,网卡MAC地址

    这个问题首先得考虑的就是你的硬盘是不是SCSI硬盘 如果是,那么根本不存在"物理序列号",只可能取得卷标的序列号 如果是卷标序列号,要注意的是每次格式化硬盘的时候这个序列号都会变 ...

  2. org.reflections 接口通过反射获取实现类源码研究

    org.reflections 接口通过反射获取实现类源码研究 版本 org.reflections reflections 0.9.12 Reflections通过扫描classpath,索引元数据 ...

  3. PHP 通过fsockopen函数获取远程网页源码

    最新PHP 通过fsockopen函数获取远程网页源码 以下是三零网为大家整理的最新PHP 通过fsockopen函数获取远程网页源码的文章,希望大家能够喜欢! 通过该函数可以获取指定端口的页面源码, ...

  4. aide怎么打开html文件,求助!aide获取网页html源码

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package com.mycompany.myapp; import android.app.*; import android.content.*; ...

  5. python 爬虫源代码-Python爬虫学习之获取指定网页源码

    本文实例为大家分享了Python获取指定网页源码的具体代码,供大家参考,具体内容如下 1.任务简介 前段时间一直在学习Python基础知识,故未更新博客,近段时间学习了一些关于爬虫的知识,我会分为多篇 ...

  6. Delphi自动提交网页表单和获取框架网页源码

    这两个问题的实现原理其实是差不多的,所以放在一起介绍,单元MSHtml封装了我们需要的功能. 首先,新建一个DELPHI工程,在USES部分添加MSHtml单元的引用. 然后,在窗体上放置一个TWeb ...

  7. linux eclipse 关联源码,获取Hadoop的源码和通过Eclipse关联Hadoop的源码

    一.获取Hadoop的源码 首先通过官网下载hadoop-2.5.2-src.tar.gz的软件包,下载好之后解压发现出现了一些错误,无法解压缩, 因此有部分源码我们无法解压 ,因此在这里我讲述一下如 ...

  8. VC6获取硬盘序列号、型号、修订版本号

    因为要做个读取硬盘参数信息的控件,所以在网上找了不少代码,但是自己作为一个初学者在使用别人代码时,总会发现有各种各样的问题: 1. 需要的头文件未写明 2. 有些定义未给出 3. 代码的开发环境未明, ...

  9. java使用websocket,并且获取HttpSession,源码分析

    一:本文使用范围 此文不仅仅局限于spring boot,普通的spring工程,甚至是servlet工程,都是一样的,只不过配置一些监听器的方法不同而已. 本文经过作者实践,确认完美运行. 二:Sp ...

最新文章

  1. win10自带Ubuntu
  2. 《LeetCode力扣练习》第62题 不同路径 Java
  3. Topcoder SRM570 900 CurvyonRails
  4. [链接]C++和Python版本的委托
  5. SpringBoot_入门-课程简介
  6. 每天进步一点点《ML - DBSCAN》
  7. linux设置temview密码,使用64位系统安装Teamviewer,但出现依赖性错误
  8. JavaScript学习(四十六)—练习题
  9. java如何使用while_java中的while(true)语句的用法是什么
  10. Spring集合类型属性注入
  11. QwebSocket即时通信
  12. 每日一题 第二次考试 数据库题目,7.17数据库面试题目补充
  13. 识字水平测试软件,3000字良心测评,市面上最火的3款识字App,这款最便宜好用...
  14. class java.util.LinkedHashMap cannot be cast to xxxx.xxx.xxxx
  15. MySQL数据库增删改查SQL语句
  16. 潜在狄利克雷分配(LDA)(latent Dirichlet allocation)
  17. python123判断火车票座位_[python篇]自己动手实现火车票中转查询
  18. 打印机部件到了服务期限的解决办法-复位法
  19. 虚拟专用网协议之PPTP
  20. 『赠书活动 | 第八期』《ChatGpt全能应用一本通》

热门文章

  1. ugui unity 取消选择_关于Unity中的UGUI优化,你可能遇到这些问题
  2. JavaScript进阶3-学习笔记
  3. R语言绘制ROC曲线如何画在一个图中
  4. 《剑指offer》扑克牌顺序
  5. 《剑指offer》反转链表
  6. hadoop集群中datanode启动几秒钟自动关闭
  7. 【搜索引擎Jediael开发笔记1】搜索引擎初步介绍及网络爬虫
  8. Spring 框架核心概念IoC 随笔
  9. 16、canvas性能优化建议
  10. Win10 Build 11099和11102的更动超过1200项