📄 diskid32.cpp
字号:
char driveName [256]; sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive); // Windows NT, Windows 2000, Windows Server 2003, Vista hPhysicalDriveIOCTL = 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) {#ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf ("\n%d ReadPhysicalDriveInNTUsingSmart ERROR" "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n" "Error Code %d\n", __LINE__, driveName, GetLastError ());#endif } else { GETVERSIONINPARAMS GetVersionParams; DWORD cbBytesReturned = 0; // Get the version, etc of PhysicalDrive IOCTL memset ((void*) & GetVersionParams, 0, sizeof(GetVersionParams)); if ( ! DeviceIoControl (hPhysicalDriveIOCTL, SMART_GET_VERSION, NULL, 0, &GetVersionParams, sizeof (GETVERSIONINPARAMS), &cbBytesReturned, NULL) ) { #ifdef PRINTING_TO_CONSOLE_ALLOWED 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); }#endif } else { // Print the SMART version // PrintVersion (& GetVersionParams); // Allocate the command buffer ULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE; PSENDCMDINPARAMS Command = (PSENDCMDINPARAMS) malloc (CommandSize); // Retrieve the IDENTIFY data // Prepare the command#define ID_CMD 0xEC // Returns ID sector for ATA Command -> 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 data DWORD diskdata [256]; USHORT *pIdSector = (USHORT *) (PIDENTIFY_DATA) ((PSENDCMDOUTPARAMS) Command) -> bBuffer; for (int ijk = 0; ijk < 256; ijk++) diskdata [ijk] = pIdSector [ijk]; PrintIdeInfo (drive, diskdata); done = TRUE; } // Done CloseHandle (hPhysicalDriveIOCTL); free (Command); } } } 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 zero // 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 (const char * str, int pos, int flip, char * buf){ int i; int j = 0; int k = 0; buf [0] = '\0'; if (pos <= 0) return buf; if ( ! j) { char p = 0; // First try to gather all characters representing hex digits only. j = 1; k = 0; buf[k] = 0; for (i = pos; j && str[i] != '\0'; ++i) { char c = tolower(str[i]); if (isspace(c)) c = '0'; ++p; buf[k] <<= 4; if (c >= '0' && c <= '9') buf[k] |= (unsigned char) (c - '0'); else if (c >= 'a' && c <= 'f') buf[k] |= (unsigned char) (c - 'a' + 10); else { j = 0; break; } if (p == 2) { if (buf[k] != '\0' && ! isprint(buf[k])) { j = 0; break; } ++k; p = 0; buf[k] = 0; } } } if ( ! j) { // There are non-digit characters, gather them as is. j = 1; k = 0; for (i = pos; j && str[i] != '\0'; ++i) { char c = str[i]; if ( ! isprint(c)) { j = 0; break; } buf[k++] = c; } } if ( ! j) { // The characters are not there or are not printable. k = 0; } buf[k] = '\0'; if (flip) // Flip adjacent characters for (j = 0; j < k; j += 2) { char t = buf[j]; buf[j] = buf[j + 1]; buf[j + 1] = t; } // Trim any beginning and end space i = j = -1; for (k = 0; buf[k] != '\0'; ++k) { if (! isspace(buf[k])) { if (i < 0) i = k; j = k; } } if ((i >= 0) && (j >= 0)) { for (k = i; (k <= j) && (buf[k] != '\0'); ++k) buf[k - i] = buf[k]; buf[k - i] = '\0'; } return buf;}#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)typedef struct _DISK_GEOMETRY_EX { DISK_GEOMETRY Geometry; LARGE_INTEGER DiskSize; UCHAR Data[1];} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX;int ReadPhysicalDriveInNTWithZeroRights (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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -