?? 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// 01/22/08 Lynn McGuire incorporate changes from Gonzalo Diethelm,// remove media serial number code since does // not work on USB hard drives or thumb drives// 01/29/08 Lynn McGuire add ReadPhysicalDriveInNTUsingSmart#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];int PRINT_DEBUG = false;static void dump_buffer (const char* title, const unsigned char* buffer, int len);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#define SMART_GET_VERSION CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)#define SMART_SEND_DRIVE_COMMAND CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)typedef struct _GETVERSIONINPARAMS { UCHAR bVersion; // Binary driver version. UCHAR bRevision; // Binary driver revision. UCHAR bReserved; // Not used. UCHAR bIDEDeviceMap; // Bit map of IDE devices. ULONG fCapabilities; // Bit mask of driver capabilities. ULONG dwReserved[4]; // For future use.} GETVERSIONINPARAMS, *PGETVERSIONINPARAMS, *LPGETVERSIONINPARAMS; // 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 registerstypedef 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 drivertypedef 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 commandstypedef 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, char* buf);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 16int 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 (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) {#ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf ("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR" "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n", __LINE__, driveName);#endif } else { 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) ) { #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) { DWORD err = GetLastError (); printf ("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR" "\nDeviceIoControl(%d, DFP_GET_VERSION) returned 0, error is %d\n", __LINE__, (int) hPhysicalDriveIOCTL, (int) err); }#endif } // If there is a IDE device at number "i" issue commands // to the device if (VersionParams.bIDEDeviceMap <= 0) {#ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf ("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR" "\nNo device found at position %d (%d)\n", __LINE__, (int) drive, (int) VersionParams.bIDEDeviceMap);#endif } else { 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;}//// IDENTIFY data (from ATAPI driver source)//#pragma pack(1)typedef struct _IDENTIFY_DATA { USHORT GeneralConfiguration; // 00 00 USHORT NumberOfCylinders; // 02 1 USHORT Reserved1; // 04 2 USHORT NumberOfHeads; // 06 3 USHORT UnformattedBytesPerTrack; // 08 4 USHORT UnformattedBytesPerSector; // 0A 5 USHORT SectorsPerTrack; // 0C 6 USHORT VendorUnique1[3]; // 0E 7-9 USHORT SerialNumber[10]; // 14 10-19 USHORT BufferType; // 28 20 USHORT BufferSectorSize; // 2A 21 USHORT NumberOfEccBytes; // 2C 22 USHORT FirmwareRevision[4]; // 2E 23-26 USHORT ModelNumber[20]; // 36 27-46 UCHAR MaximumBlockTransfer; // 5E 47 UCHAR VendorUnique2; // 5F USHORT DoubleWordIo; // 60 48 USHORT Capabilities; // 62 49 USHORT Reserved2; // 64 50 UCHAR VendorUnique3; // 66 51 UCHAR PioCycleTimingMode; // 67 UCHAR VendorUnique4; // 68 52 UCHAR DmaCycleTimingMode; // 69 USHORT TranslationFieldsValid:1; // 6A 53 USHORT Reserved3:15; USHORT NumberOfCurrentCylinders; // 6C 54 USHORT NumberOfCurrentHeads; // 6E 55 USHORT CurrentSectorsPerTrack; // 70 56 ULONG CurrentSectorCapacity; // 72 57-58 USHORT CurrentMultiSectorSetting; // 59 ULONG UserAddressableSectors; // 60-61 USHORT SingleWordDMASupport : 8; // 62 USHORT SingleWordDMAActive : 8; USHORT MultiWordDMASupport : 8; // 63 USHORT MultiWordDMAActive : 8; USHORT AdvancedPIOModes : 8; // 64 USHORT Reserved4 : 8; USHORT MinimumMWXferCycleTime; // 65 USHORT RecommendedMWXferCycleTime; // 66 USHORT MinimumPIOCycleTime; // 67 USHORT MinimumPIOCycleTimeIORDY; // 68 USHORT Reserved5[2]; // 69-70 USHORT ReleaseTimeOverlapped; // 71 USHORT ReleaseTimeServiceCommand; // 72 USHORT MajorRevision; // 73 USHORT MinorRevision; // 74 USHORT Reserved6[50]; // 75-126 USHORT SpecialFunctionsEnabled; // 127 USHORT Reserved7[128]; // 128-255} IDENTIFY_DATA, *PIDENTIFY_DATA;#pragma pack()int ReadPhysicalDriveInNTUsingSmart (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.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -