BIOS 讀取 硬碟型號的問題 |
尚未結案
|
xiaolaba
一般會員 ![]() ![]() 發表:10 回覆:17 積分:5 註冊:2010-05-15 發送簡訊給我 |
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
自己研究一下程式碼吧,以下是在cb 6下可正常運行,而裡面的hugh(本人)有加入一點點程式碼。
[code cpp] #include #include #include #include #include #include #include #include #include #pragma comment(lib, "iphlpapi.lib") // must add path lib psdk #pragma hdrstop //--------------------------------------------------------------------------- #pragma package(smart_init) 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) // 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. 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 16 // 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 ReadPhysicalDriveInNTWithZeroRights(TStringList *ls) { 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, 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) { #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf("\n%d ReadPhysicalDriveInNTWithZeroRights ERROR" "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n", __LINE__, driveName); #endif } else { 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]; char vendorId[1000]; char productRevision[1000]; #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) { printf("\n%d STORAGE_DEVICE_DESCRIPTOR contents for drive %d\n" " Version: %ld\n" " Size: %ld\n" " DeviceType: x\n" " DeviceTypeModifier: x\n" " RemovableMedia: %d\n" " CommandQueueing: %d\n" " VendorIdOffset: %4ld (0xlx)\n" " ProductIdOffset: %4ld (0xlx)\n" " ProductRevisionOffset: %4ld (0xlx)\n" " SerialNumberOffset: %4ld (0xlx)\n" " BusType: %d\n" " RawPropertiesLength: %ld\n", __LINE__, drive, (unsigned long) descrip->Version, (unsigned long) descrip->Size, (int) descrip->DeviceType, (int) descrip->DeviceTypeModifier, (int) descrip->RemovableMedia, (int) descrip->CommandQueueing, (unsigned long) descrip->VendorIdOffset, (unsigned long) descrip->VendorIdOffset, (unsigned long) descrip->ProductIdOffset, (unsigned long) descrip->ProductIdOffset, (unsigned long) descrip->ProductRevisionOffset, (unsigned long) descrip->ProductRevisionOffset, (unsigned long) descrip->SerialNumberOffset, (unsigned long) descrip->SerialNumberOffset, (int) descrip->BusType, (unsigned long) descrip->RawPropertiesLength); dump_buffer("Contents of RawDeviceProperties", (unsigned char*) descrip->RawDeviceProperties, descrip->RawPropertiesLength); dump_buffer("Contents of first 256 bytes in buffer", (unsigned char*) buffer, 256); } #endif flipAndCodeBytes(buffer, descrip->VendorIdOffset, 0, vendorId); flipAndCodeBytes(buffer, descrip->ProductIdOffset, 0, modelNumber); flipAndCodeBytes(buffer, descrip->ProductRevisionOffset, 0, productRevision); flipAndCodeBytes(buffer, descrip->SerialNumberOffset, 1, serialNumber); if (0 == HardDriveSerialNumber[0] && // serial number must be alphanumeric // (but there can be leading spaces on IBM drives) (isalnum(serialNumber[0]) || isalnum(serialNumber[19]))) { strcpy(HardDriveSerialNumber, serialNumber); strcpy(HardDriveModelNumber, modelNumber); done = TRUE; } #ifdef PRINTING_TO_CONSOLE_ALLOWED printf("\n**** STORAGE_DEVICE_DESCRIPTOR for drive %d ****\n" "Vendor Id = [%s]\n" "Product Id = [%s]\n" "Product Revision = [%s]\n" "Serial Number = [%s]\n", drive, vendorId, modelNumber, productRevision, serialNumber); #endif // below add by Hugh 20120326 if (drive==0) { ls->Add(AnsiString(vendorId)); ls->Add(AnsiString(modelNumber)); ls->Add(AnsiString(productRevision)); ls->Add(AnsiString(serialNumber)); } // End by Hugh // Get the disk drive geometry. memset(buffer, 0, sizeof(buffer)); if (!DeviceIoControl(hPhysicalDriveIOCTL, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &buffer, sizeof(buffer), &cbBytesReturned, NULL)) { #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf("\n%d ReadPhysicalDriveInNTWithZeroRights ERROR" "|nDeviceIoControl(%s, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) returned 0", driveName); #endif } else { DISK_GEOMETRY_EX* geom = (DISK_GEOMETRY_EX*)&buffer; int fixed = (geom->Geometry.MediaType == FixedMedia); __int64 size = geom->DiskSize.QuadPart; #ifdef PRINTING_TO_CONSOLE_ALLOWED printf("\n**** DISK_GEOMETRY_EX for drive %d ****\n" "Disk is%s fixed\n" "DiskSize = %I64d\n", drive, fixed ? "" : " NOT", size); #endif } } else { DWORD err = GetLastError(); #ifdef PRINTING_TO_CONSOLE_ALLOWED printf("\nDeviceIOControl IOCTL_STORAGE_QUERY_PROPERTY error = %d\n", err); #endif } CloseHandle(hPhysicalDriveIOCTL); } } return done; } void __fastcall TForm1::_btn1Click(TObject *Sender) { // please search "hugh" to see what i added,and you can modify for fitting yours TStringList *info = new TStringList; ReadPhysicalDriveInNTWithZeroRights(info); delete info; } [/code]
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2013-02-26 21:53:09, 註解 無‧
|
xiaolaba
一般會員 ![]() ![]() 發表:10 回覆:17 積分:5 註冊:2010-05-15 發送簡訊給我 |
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
別客氣,
若你是vs2012,那麼應該把 TStringList的參數與相關內容刪除即可以跑。 TStringList是 delphi/cb 才有的東西,其它的部份應該可以在vc上跑。 ===================引 用 xiaolaba 文 章=================== 實在謝謝你 蕭沖大大 記得不久前也是你給俺的另外一個答案 俺有電腦時安裝的 Visual studio 2012 的, 但是 CB6就不明白是什麼軟件 這麼長, 俺可以研究好一陣子了
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
Ktop_Robot
站務副站長 ![]() ![]() 發表:0 回覆:3511 積分:0 註冊:2007-04-17 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |