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

取得硬碟序號

 
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊:2002-07-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-24 17:53:42 IP:61.218.xxx.xxx 未訂閱
下列程式碼經Win2000 D5/D6/D7 測試無誤    
function GetIdeDiskSerialNumber: string;
type
    TSrbIoControl = packed record
        HeaderLength: ULONG;
        Signature: array[0..7] of Char;
        Timeout: ULONG;
        ControlCode: ULONG;
        ReturnCode: ULONG;
        Length: ULONG;
    end;
    SRB_IO_CONTROL = TSrbIoControl;
    PSrbIoControl = ^TSrbIoControl;        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. Must be zero.
    end;
    IDEREGS = TIDERegs;
    PIDERegs = ^TIDERegs;        TSendCmdInParams = packed record
        cBufferSize: DWORD;
        irDriveRegs: TIDERegs;
        bDriveNumber: Byte;
        bReserved: array[0..2] of Byte;
        dwReserved: array[0..3] of DWORD;
        bBuffer: array[0..0] of Byte;
    end;
    SENDCMDINPARAMS = TSendCmdInParams;
    PSendCmdInParams = ^TSendCmdInParams;        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;    const
    IDE_ID_FUNCTION = $EC;
    IDENTIFY_BUFFER_SIZE = 512;
    DFP_RECEIVE_DRIVE_DATA = $0007C088;
    IOCTL_SCSI_MINIPORT = $0004D008;
    IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;
    DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;
    BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;
    W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;
var
    hDevice: THandle;
    cbBytesReturned: DWORD;
    pInData: PSendCmdInParams;
    pOutData: Pointer; // PSendCmdOutParams
    Buffer: array[0..BufferSize - 1] of Byte;
    srbControl: TSrbIoControl absolute Buffer;        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 := '';
    FillChar(Buffer, BufferSize, #0);
    if Win32Platform = VER_PLATFORM_WIN32_NT then
    begin // Windows NT, Windows 2000
        // Get SCSI port handle
        hDevice := CreateFile('\\.\Scsi0:',
            GENERIC_READ or GENERIC_WRITE,
            FILE_SHARE_READ or FILE_SHARE_WRITE,
            nil, OPEN_EXISTING, 0, 0);
        if hDevice = INVALID_HANDLE_VALUE then
            Exit;
        try
            srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
            System.Move('SCSIDISK', srbControl.Signature, 8);
            srbControl.Timeout := 2;
            srbControl.Length := DataSize;
            srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
            pInData := PSendCmdInParams(PChar(@Buffer)
                + SizeOf(SRB_IO_CONTROL));
            pOutData := pInData;
            with pInData^ do
            begin
                cBufferSize := IDENTIFY_BUFFER_SIZE;
                bDriveNumber := 0;
                with irDriveRegs do
                begin
                    bFeaturesReg := 0;
                    bSectorCountReg := 1;
                    bSectorNumberReg := 1;
                    bCylLowReg := 0;
                    bCylHighReg := 0;
                    bDriveHeadReg := $A0;
                    bCommandReg := IDE_ID_FUNCTION;
                end;
            end;
            if not DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT,
                @Buffer, BufferSize, @Buffer, BufferSize,
                cbBytesReturned, nil) then
                Exit;
        finally
            CloseHandle(hDevice);
        end;
    end
    else
    begin // Windows 95 OSR2, Windows 98
        hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil,
            CREATE_NEW, 0, 0);
        if hDevice = INVALID_HANDLE_VALUE then
            Exit;
        try
            pInData := PSendCmdInParams(@Buffer);
            pOutData := @pInData^.bBuffer;
            with pInData^ do
            begin
                cBufferSize := IDENTIFY_BUFFER_SIZE;
                bDriveNumber := 0;
                with irDriveRegs do
                begin
                    bFeaturesReg := 0;
                    bSectorCountReg := 1;
                    bSectorNumberReg := 1;
                    bCylLowReg := 0;
                    bCylHighReg := 0;
                    bDriveHeadReg := $A0;
                    bCommandReg := IDE_ID_FUNCTION;
                end;
            end;
            if not DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA,
                pInData, SizeOf(TSendCmdInParams) - 1, pOutData,
                W9xBufferSize, cbBytesReturned, nil) then
                Exit;
        finally
            CloseHandle(hDevice);
        end;
    end;
    with PIdSector(PChar(pOutData) + 16)^ do
    begin
        ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
        SetString(Result, sSerialNumber, SizeOf(sSerialNumber));
    end;
end;
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-02-24 18:37:48 IP:192.168.xxx.xxx 未訂閱
上面這個程式在win98好像不行, 有無for win98的IDE硬碟序號取得的範例嗎? ~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊:2002-07-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-02-25 13:42:03 IP:61.218.xxx.xxx 未訂閱
實際上我測98 也是不行 但是程式碼裡也有判斷 > < src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=8147403&CC=182217">
longsanglin
初階會員


發表:10
回覆:57
積分:43
註冊:2002-04-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-02-26 14:20:46 IP:211.22.xxx.xxx 未訂閱
引言: 上面這個程式在win98好像不行, 有無for win98的IDE硬碟序號取得的範例嗎? ~~~Delphi K.Top討論區站長~~~
試試看如下function (應沒有windows版本之分) function TForm1.GetHDDriveInfo(DriverName: String) : String; var VolName: array [0..200] of Char; NameBuff: array [0..50] of Char; VolSer, MaxComLen, FSFlags: DWORD; begin if GetVolumeInformationA(PChar(DriverName), VolName, 200, @VolSer, MaxComLen, FSFlags, NameBuff, 50) then begin if VolSer = 0 then Result:= '' else Result:= InttoHex(VolSer,8); end else begin Result:='無法辨識'; end; end; procedure TForm1.BitBtn1Click(Sender: TObject); begin Label1.Caption:=GetHDDriveInfo('c:\'); end;
oasis
一般會員


發表:22
回覆:10
積分:6
註冊:2002-11-01

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-02-27 16:49:13 IP:61.190.xxx.xxx 未訂閱
我的测试结果与你们相反,我在98下可以读出硬盘号的。 但是在nt下读不出来,在2000下没测试。
領航天使
站長


發表:12216
回覆:4186
積分:4084
註冊:2001-07-25

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-02-27 17:15:32 IP:210.202.xxx.xxx 未訂閱
ddy sir: 我在2000下測也出不來 caption:=GetIdeDiskSerialNumber;傳回空白 ??? ~~~Delphi K.Top討論區站長~~~
------
~~~Delphi K.Top討論區站長~~~
系統時間:2024-11-22 22:45:12
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!