線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:5988
推到 Plurk!
推到 Facebook!

我要如何得知, Disk E,,在哪一個PhysicalDrive中?又如何得知系統中有多少個 PhysicalDrive ?

答題得分者是:aftcast
davidsun
初階會員


發表:57
回覆:71
積分:25
註冊:2002-04-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-09-22 11:39:21 IP:220.130.xxx.xxx 訂閱
Greeting ,
請問各位如果我在電腦中有三部磁碟機,分別是 PhysicalDrive0, PhysicalDrive1 , PhysicalDrive2 , 但是三部磁碟機分別劃分為 PhysicalDrive0->C,D,E . PhysicalDrive1-> F,G . PhysicalDrive2->H 的分割區。請問在程式中,我要如何得知, Disk E, 其實在 PhysicalDrive0 中,而 Disk G 則在 PhysicalDrive1 中呢? 另外一個想要請教的我如何得知系統中有多少個 PhysicalDrive ? 例如從 PhysicalDrive0 ~ PhysicalDrive2 . 我目前的作法是用

CreateFile(pChar('\\.\PhysicalDrive0'), GENERIC_WRITE or GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

看看傳回的是不是 INVALID_HANDLE_VALUE ,如果是,則表示 PhysicalDrive0 不存在。請問是不是有更好的方法呢?

謝謝您。
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-09-22 23:39:01 IP:60.248.xxx.xxx 訂閱
你的方法應該很ok了。

至於logical map physical的方法,請用DeviceIoControl()配合IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS。會得到VOLUME_DISK_EXTENTS結構體,然後從這個結構體去得知physical的編號。
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
davidsun
初階會員


發表:57
回覆:71
積分:25
註冊:2002-04-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-09-23 16:09:31 IP:220.130.xxx.xxx 訂閱
謝謝您的指導,問題已經解決了,我的範例:


[code delphi]
unit _Utility;

interface



uses
Windows, SysUtils;

const
FILE_ANY_ACCESS = 0;
METHOD_BUFFERED = 0;
IOCTL_VOLUME_BASE = DWORD('V');
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (
(IOCTL_VOLUME_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
(0 shl 2) or METHOD_BUFFERED);

type
TIdSector = packed record
wGenConfig: Word;
wNumCyls: Word;
wReserved: Word;
wNumHeads: Word;
wBytesPerTrack: Word;
wBytesPerSector: Word;
wSectorsPerTrack: Word;
wVendorUnique: array[0..2] of Word;
sSerialNumber: array[0..19] of char;
wBufferType: Word;
wBufferSize: Word;
wECCSize: Word;
sFirmwareRev: array[0..7] of char;
sModelNumber: array[0..39] of char;
wMoreVendorUnique: Word;
wDoubleWordIO: Word;
wCapabilities: Word;
wReserved1: Word;
wPIOTiming: Word;
wDMATiming: Word;
wBS: Word;
wNumCurrentCyls: Word;
wNumCurrentHeads: Word;
wNumCurrentSectorsPerTrack: Word;
ulCurrentSectorCapacity: ULONG;
wMultSectorStuff: Word;
ulTotalAddressableSectors: ULONG;
wSingleWordDMA: Word;
wMultiWordDMA: Word;
bReserved: array[0..127] of Byte;
end;
PIdSector = ^TIdSector;
IDEREGS = record
bFeaturesReg: BYTE; // Used for specifying SMART "commands".
bSectorCountReg: BYTE; // IDE sector count register
bSectorNumberReg: BYTE; // IDE sector number register
bCylLowReg: BYTE; // IDE low order cylinder value
bCylHighReg: BYTE; // IDE high order cylinder value
bDriveHeadReg: BYTE; // IDE drive/head register
bCommandReg: BYTE; // Actual IDE command.
bReserved: BYTE; // reserved for future use. Must be zero.
end;
SENDCMDINPARAMS = record
cBufferSize: DWORD;
irDriveRegs: IDEREGS;
bDriveNumber: BYTE;
bReserved: array[0..2] of BYTE;
dwReserved: array[0..3] of DWORD;
bBuffer: BYTE;
end;
DRIVERSTATUS = record
bDriverError: BYTE;
bIDEStatus: BYTE;
bReserved: array[0..1] of BYTE;
dwReserved: array[0..1] of DWORD;
end;
SENDCMDOUTPARAMS = record
cBufferSize: DWORD;
DriverStatus: DRIVERSTATUS;
bBuffer: BYTE;
end;
PSENDCMDOUTPARAMS = ^SENDCMDOUTPARAMS;
// ·O"C,?A`(c)O~^(1)?A*I"¢
TDiskExtent = record
DiskNumber: Cardinal;
StartingOffset: LARGE_INTEGER;
ExtentLength: LARGE_INTEGER;
end;
DISK_EXTENT = TDiskExtent;
PDiskExtent = ^TDiskExtent;

TVolumeDiskExtents = record
NumberOfDiskExtents: Cardinal;
Extents: array[0..0] of TDiskExtent;
end;
VOLUME_DISK_EXTENTS = TVolumeDiskExtents;
PVolumeDiskExtents = ^TVolumeDiskExtents;

function GetVolumeInfo(DriverLetter: Char; var DiskExtent: TDiskExtent): Integer;

implementation

function GetVolumeInfo(DriverLetter: Char; var DiskExtent: TDiskExtent): Integer;
var
hVolume: THandle;
DiskExtents: PVolumeDiskExtents;
dwOutBytes: Cardinal;
begin
Result := -1;
hVolume := CreateFile(PChar('\\.\' DriverLetter ':'), GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hVolume < 1 then
Exit;
DiskExtents := AllocMem(Max_Path);
if DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0, DiskExtents, Max_Path,
dwOutBytes, nil) then
begin
if DiskExtents^.NumberOfDiskExtents > 0 then
begin
DiskExtent := DiskExtents^.Extents[0];
Result := 0;
end
else
Result := -3;
end
else
Result := -2;
FreeMem(DiskExtents);
CloseHandle(hVolume);
end;

end.


[/code]

只要呼叫 GetVolumeInfo(drive, DiskExtent);
從 DiskExtent 可以知道 Disk Lable 在哪一個物理詞區中。
謝謝您。

===================引 用 aftcast 文 章===================
你的方法應該很ok了。

至於logical map physical的方法,請用DeviceIoControl()配合IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS。會得到VOLUME_DISK_EXTENTS結構體,然後從這個結構體去得知physical的編號。
系統時間:2024-03-28 23:53:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!