透過 ATA Commands 取得硬碟資訊 IOCTL_ATA_PASS_THROUGH |
缺席
|
ZongDe
一般會員 發表:9 回覆:11 積分:4 註冊:2002-11-27 發送簡訊給我 |
如上圖,我想透過ATA Commands取的硬碟相關資訊,該如何做到. 有人有相關經驗嗎? 是否可以給各方向.. 我有嘗試透下過IOCTL_ATA_PASS_THROUGH的方式,但是回傳的Error Code 是 5,查MSDN的意思是拒絕存取. 難道一定要透過driver層才可以嗎? 以下附上sample code... 這是計算硬碟大小的,可執行 [code cpp] void __fastcall TForm1::btnDiskSizeClick(TObject *Sender) { Memo1->Clear(); HANDLE hDev; BOOL bRet; DISK_GEOMETRY pdg; DWORD rByte; //SECURITY_ATTRIBUTES SA; // Security attributes char drvName[] = "\\\\.\\PhysicalDrive0"; hDev = CreateFile( drvName, // Object Name: Point Physical HDD 0 0, // Access Mode: 0 for Devices FILE_SHARE_READ | FILE_SHARE_WRITE, // Shared Mode: 0, // Security Attributes: NULL can not be inherited(繼承) OPEN_EXISTING, // Creation Disposition 0, // File flags and attributes NULL); // Do not copy file attributes if (hDev == INVALID_HANDLE_VALUE) { Memo1->Lines->Add("Open PHYSICALDRIVE0 handle failed!"); return; } bRet = DeviceIoControl( hDev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &pdg, sizeof(pdg), &rByte, NULL); if (!bRet) { Memo1->Lines->Add("DeviceIoControl Failed!"); //Memo1->Lines->Add("GetLastError: " IntToHex(GetLastError(), 8)); return; } char buf[64] = {0}; ULONGLONG dwDiskSize; sprintf(buf, "Cylinders = %I64d", pdg.Cylinders); Memo1->Lines->Add(buf); Memo1->Lines->Add("Tracks Per Cylinder = " IntToStr(pdg.TracksPerCylinder)); Memo1->Lines->Add("Sectors Per Track = " IntToStr(pdg.SectorsPerTrack)); Memo1->Lines->Add("Bytes Per Sector = " IntToStr(pdg.BytesPerSector)); dwDiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder * \ (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector; sprintf(buf, "Physcial Disk Size = %I64d Bytes = %I64d Mb", dwDiskSize, dwDiskSize/(1024 * 1024)); Memo1->Lines->Add(buf); CloseHandle(hDev); } [/code] 以下是透過IOCTL_ATA_PASS_THROUGH的方式 [code cpp] void __fastcall TForm1::btnATAClick(TObject *Sender) { Memo1->Clear(); HANDLE hDev; BOOL bRet; ATA_PASS_THROUGH_EX apt; DWORD rByte; //SECURITY_ATTRIBUTES SA; // Security attributes char drvName[] = "\\\\.\\PhysicalDrive0"; hDev = CreateFile( drvName, // Object Name: Point Physical HDD 0 0, // Access Mode: 0 for Devices FILE_SHARE_READ | FILE_SHARE_WRITE, // Shared Mode: 0, // Security Attributes: NULL can not be inherited(繼承) OPEN_EXISTING, // Creation Disposition 0, // File flags and attributes NULL); // Do not copy file attributes if (hDev == INVALID_HANDLE_VALUE) { Memo1->Lines->Add("Open PHYSICALDRIVE0 handle failed!"); return; } // // CMD,CYL default to SMART, changed by P?IDENTIFY and CHECK_POWER_MODE //IDEREGS regs; //memset(®s, 0, sizeof(regs)); //regs.bCommandReg = 0xEC;//ATA_IDENTIFY_DEVICE; //regs.bCylLowReg = regs.bCylHighReg = 0; //regs.bSectorCountReg = 1; // ATA_PASS_THROUGH_EX_WITH_BUFFERS ab; memset(&ab, 0, sizeof(ab)); ab.apt.Length = sizeof(ATA_PASS_THROUGH_EX); ab.apt.TimeOutValue = 10; unsigned size = offsetof(ATA_PASS_THROUGH_EX_WITH_BUFFERS, ucDataBuf); ab.apt.DataBufferOffset = size; ab.apt.AtaFlags = ATA_FLAGS_DATA_IN; ab.apt.DataTransferLength = 512; size = 512; ab.ucDataBuf[0] = 0xcf; ab.apt.CurrentTaskFile[1] = 1; ab.apt.CurrentTaskFile[3] = ab.apt.CurrentTaskFile[4] = 0; ab.apt.CurrentTaskFile[6] = 0xEC; bRet = DeviceIoControl( hDev, IOCTL_ATA_PASS_THROUGH, &ab, size, &ab, size, &rByte, NULL); if (!bRet) // 這裡回傳failed { long err = GetLastError(); // 取得拒絕存取的訊息 Memo1->Lines->Add("DeviceIoControl Failed! " IntToStr(err)); //Memo1->Lines->Add("GetLastError: " IntToHex(GetLastError(), 8)); return; } } [/code] |
ZongDe
一般會員 發表:9 回覆:11 積分:4 註冊:2002-11-27 發送簡訊給我 |
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |