唉!老夫真的豁出去了,谁回答也我的问题,我把分数全部给他!(300分)

S

silicon

Unregistered / Unconfirmed
GUEST, unregistred user!
我不知道这里是不是没有高手,我知道我的水平差看不懂英文,我也知道确实有很多人真的不知道
这个问题的答案,但我相信一定可以做到的。

我的问题就是:[red]如果判断指定的盘符在哪块物理硬盘上?[/red],请见http://www.delphibbs.com/delphibbs/dispq.asp?lid=1248289

如果大家不明白我到底在说什么,也可以把问题说成:
[red]“判断一个指定文件在哪块物理硬盘上?”[/red]
我要的是物理硬盘号,如0、1、2,而不是C盘、D盘、E盘。C盘、D盘、E盘都是逻辑盘,而不
我想要的物理硬盘号!

我应该把问题说清楚了,我相信也会有人知道问题的答案。谁回答出我的问题,我把我所
有待答问题的分数全部给他!
 
让偶帮你LOOK LOOK好了。 [8D]
 
老哥 别着急 我看了你的问题 我也帮你查了资料 可是我真的帮不上忙。。
没想到你真的这么着急
小弟只好帮你顶顶 ++人气
希望引来高手了

[:)][:)][:)]
 
在windows中你不能直接操作硬件,你的要求要靠I/O操作来实现
要获得Ring 0权限
在windows 98 要写驱动,要用DDK。
我是不太会的,帮你UP,顺便听听课.
 
我估计 DeviceIoControl 可以帮你,用 DRIVE_LAYOUT_INFORMATION_EX 参数。

但具体的我也还没看懂[:(],只知道 9x 下不行的,正在努力[:)]
 
帮你想想!!!
 
找找看,应该可以找到。
 
这几天没空,上次试了一下分析pqmagic的函数,应该可以找到。
 
你有多少分?
 
反过来讲,获得每个物理盘拥有的逻辑盘号 应该也可以吧?!
 
[red]好像我的回答文不对题,但我相信会对你有帮助,有耐心点看完[/red]
//获取第一个IDE硬盘的序列号

function GetIdeSerialNumber : SerialNumber;

const IDENTIFY_BUFFER_SIZE = 512;

type

TIDERegs = packed 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;

TSendCmdInParams = packed record

// Buffer size in bytes

cBufferSize : DWORD;

// Structure with drive register values.

irDriveRegs : TIDERegs;

// Physical drive number to send command to (0,1,2,3).

bDriveNumber : BYTE;

bReserved : Array[0..2] of Byte;

dwReserved : Array[0..3] of DWORD;

bBuffer : Array[0..0] of Byte; // Input buffer.

end;

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 : DWORD;

wMultSectorStuff : Word;

ulTotalAddressableSectors : DWORD;

wSingleWordDMA : Word;

wMultiWordDMA : Word;

bReserved : Array[0..127] of BYTE;

end;

PIdSector = ^TIdSector;

TDriverStatus = packed record

// 驱动器返回的错误代码,无错则返回0

bDriverError : Byte;

// IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效

bIDEStatus : Byte;

bReserved : Array[0..1] of Byte;

dwReserved : Array[0..1] of DWORD;

end;

TSendCmdOutParams = packed record

// bBuffer的大小

cBufferSize : DWORD;

// 驱动器状态

DriverStatus : TDriverStatus;

// 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定

bBuffer : Array[0..0] of BYTE;

end;



var hDevice : THandle;

cbBytesReturned : DWORD;

ptr : PChar;

SCIP : TSendCmdInParams;

aIdOutCmd : Array [0..(SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1)-1] of Byte;

IdOutCmd : TSendCmdOutParams absolute aIdOutCmd;



procedure ChangeByteOrder( var Data; Size : Integer );

var ptr : PChar;

i : Integer;

c : Char;

begin

ptr := @Data;

for i := 0 to (Size shr 1)-1 do

begin

c := ptr^;

ptr^ := (ptr+1)^;

(ptr+1)^ := c;

Inc(ptr,2);

end;

end;



begin

Result := ''; // 如果出错则返回空串

if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT, Windows 2000

begin

// 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '//./PhysicalDrive1/'

hDevice := CreateFile( '//./PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,

FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );

end

else // Version Windows 95 OSR2, Windows 98

hDevice := CreateFile( '//./SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );

if hDevice=INVALID_HANDLE_VALUE then Exit;

try

FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0);

FillChar(aIdOutCmd,SizeOf(aIdOutCmd),#0);

cbBytesReturned := 0;

// Set up data structures for IDENTIFY command.

with SCIP do

begin

cBufferSize := IDENTIFY_BUFFER_SIZE;

// bDriveNumber := 0;

with irDriveRegs do

begin

bSectorCountReg := 1;

bSectorNumberReg := 1;

// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0

// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);

bDriveHeadReg := $A0;

bCommandReg := $EC;

end;

end;

if not DeviceIoControl( hDevice, $0007c088, @SCIP, SizeOf(TSendCmdInParams)-1,

@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil ) then Exit;

finally

CloseHandle(hDevice);

end;

with PIdSector(@IdOutCmd.bBuffer)^ do

begin

ChangeByteOrder( sSerialNumber, SizeOf(sSerialNumber) );

(PChar(@sSerialNumber)+SizeOf(sSerialNumber))^ := #0;

Result := PChar(@sSerialNumber);

end;

end;



// 更多关于 S.M.A.R.T. ioctl 的信息可查看:

// http://www.microsoft.com/hwdev/download/respec/iocltapi.rtf



// MSDN库中也有一些简单的例子

// Windows Development -> Win32 Device Driver Kit ->

// SAMPLE: SmartApp.exe Accesses SMART stats in IDE drives



// 还可以查看 http://www.mtgroup.ru/~alexk

// IdeInfo.zip - 一个简单的使用了S.M.A.R.T. Ioctl API的Delphi应用程序



// 注意:



// WinNT/Win2000 - 你必须拥有对硬盘的读/写访问权限



// Win98

// SMARTVSD.VXD 必须安装到 /windows/system/iosubsys

// (不要忘记在复制后重新启动系统)

 
反过来说当然也可以了!

谢谢,我要仔细研究你的代码!
 
阳光游子,不好意思,分开你的时候已经没有分了!再说你的一个up也不值钱!呵呵[:D]
 
顶部