我从网上下载了一个得到硬盘ID的DLL,它其中对DELPHI调用是这样说明的:
type mychar=array[0..31] of char;
type TDiskID32=Function(var DiskModel,DiskID:mychar):BOOL;stdcall;请问,这样的说明该怎么调用?谢谢!

解决方案 »

  1.   

    delphi的string在c 中是不支持的。你也定义一个char的类型的数组就可以了。
    可以用pchar来输出
      

  2.   

    我是这样写的:
    var
      dk:TDiskID32;
      mc:mychar;
    begin 
      dk(mc,mc);
      showmessage(mc);
    //这样会出错的.
    end;cooling(cooling) :可不可以帮我写段代码?我不太懂啊.谢谢
      

  3.   

    意思很简单。MyChar就是存放ID的数组。而在Pascal中,静态数组不能做参数传递的,所以需要定义为类型。所以就有了:type mychar=array[0..31] of char; 来得到计算好的ID。
      

  4.   

    看清楚第一个参数:DiskModel磁盘类型不同的当然不同,这个是最麻烦的。他可能提供了这个初始化数据。另外,能不能把DLL的下载地址告知。我试试看。
      

  5.   

    http://www.playicq.com/dispdocnew.php?id=5756我知道它是把DISKMODEL,DISKID的值得到然后传到MYCHAR类型中了,可是就是不知道怎么来调用一开始这样函数?
      

  6.   

    //前面定义:
    type
      MyChar = array[0..31] of char;
      TDiskID32 = function(var DiskModel, DiskID: MyChar): BOOL; stdcall;//随便一个过程内const
      cDiskID32 = 'DiskID32.dll';
    var
      LibHandle: THandle;
      aDiskModal, aDiskID: MyChar;
      GetID: TDiskID32;
    begin
      LibHandle := LoadLibrary(cDiskID32);
      @GetID := GetProcAddress(LibHandle, 'DiskID32');
      GetID(aDiskModal, aDiskID);
      Showmessage(aDiskModal + aDiskID);
      FreeLibrary(LibHandle);
    end;
      

  7.   

    我是看了VB调用方法,知道了他的函数名就叫DiskID32所以采用了显式的调用,调用地址。你也可以用导出函数。//interface关键字内interfaceconst
      cDiskID32 = 'DiskID32.dll';
    type
      MyChar = array[0..31] of char;function DiskID32(var DiskModel, DiskID: MyChar): BOOL; stdcall;//implementation关键字内implementationfunction DiskID32; external cDiskID32 name 'DiskID32';//然后随便一个过程var
      aDiskModal, aDiskID: MyChar;
    begin
      DiskID32(aDiskModal, aDiskID);
      Showmessage(aDiskModal + aDiskID);
    end;
      

  8.   

    //获取硬盘系列号[DELPHI]
    unit hdsn;interfaceuses
     Windows,SysUtils;function getIDEHardDiskSN: string;
    type
    {*******Use in Win2k ****************}
    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;{************end Win2k*****************}const
    {********** Use in Win2k **********}
      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;
    {********* End Win2k***************}{********* Use in Win9x ***********}
      hookexceptionno = 5;
    {********* End in Win9x************}var{********* Use in Win9x ***********}
      pw: array[0..255] of Word; // pw[256];
      idtr_1: array[0..5] of Byte; //保存中断描述符表寄存器
      oldexceptionhook: DWord; //保存原先的中断入口地址
      IdeBase: Word;
      SelectDisk: Integer;
      ErrNo: Integer = 0;
    {********* End in Win9x************}implementation{********* Use in Win9x ***********}function inp(rdx: Word): Byte;
    asm
    mov dx, rdx
    in al, dx
    end;function inpw(rdx: Word): Word;
    asm
    mov dx, rdx
    in ax, dx
    end;procedure outp(ral: Byte; rdx: Word);
    asm
    mov dx, rdx
    mov al, ral
    out dx, al
    end;function WaitIde: Byte;
    var
      al: Byte;
    begin
      repeat
        al := inp(IdeBase + 7);
      until (al < $80) or (al = $A0); //$a0可能就没有硬盘
      WaitIde := al;
    end;procedure ReadIDE;
    var
      al: Byte;
      i: Integer;
    begin
      WaitIde;
      outp(SelectDisk, IdeBase + 6);
      al := WaitIde;
      if ((al and $50) <> $50) then
      begin
        ErrNo := 1;
        exit;
      end;
      outp(SelectDisk, IdeBase + 6);
      outp($EC, IdeBase + 7);
      al := WaitIde;
      if ((al and $58) <> $58) then
      begin
        ErrNo := 2;
        exit;
      end;
      for i := 0 to 255 do
      begin
        pw[i] := inpw(IdeBase);
      end;
    end;// 新的中断处理程序procedure ReadIt; assembler;
    asm
    push eax
    push ebx
    push ecx
    push edx
    push esi
    push edi
    // 在这里写读程序
    call ReadIDE
    pop edi
    pop esi
    pop edx
    pop ecx
    pop ebx
    pop eax
    iretd
    end;procedure GetSerialNo; assembler;
    asm
    push eax
    // 获取修改的中断的中断描述符(中断门)地址
    sidt idtr_1
    mov eax,dword ptr idtr_1+02h
    add eax,hookexceptionno*08h+04h
    // 保存原先的中断入口地址
    cli
    push ecx
    mov ecx,dword ptr [eax]
    mov cx,word ptr [eax-04h]
    mov dword ptr oldexceptionhook,ecx
    pop ecx
    // 设置修改的中断入口地址为新的中断处理程序入口地址
    push ebx
    lea ebx,ReadIt
    mov word ptr [eax-04h],bx
    shr ebx,10h
    mov word ptr [eax+02h],bx
    pop ebx
    // 执行中断,转到ring 0(与cih 病毒原理相似!)
    push ebx
    int hookexceptionno
    pop ebx
    // 恢复原先的中断入口地址
    push ecx
    mov ecx,dword ptr oldexceptionhook
    mov word ptr [eax-04h],cx
    shr ecx,10h
    mov word ptr [eax+02h],cx
    pop ecx
    // 结束
    sti
    pop eax
    ret
    end;procedure GetIdeDiskSN9X(DriverNo: integer; var s: string);
    var
      i: Integer;
    begin
    {如果有多硬盘一般可能有4个硬盘,也可能多至8个硬盘}
      ErrNo := 0;
      fillchar(pw, sizeof(pw), 0);
      s := '';{设置基址,
    4,5:IdeBase := $1e8;
    6,7:IdeBase := $168;}
      case DriverNo of
        0, 1: IdeBase := $1F0;
        2, 3: IdeBase := $170;
      end;{ 指定主从,Driver No 是奇数为$B0,偶数为$A0}
      case DriverNo of
        0, 2: SelectDisk := $A0;
        1, 3: SelectDisk := $B0;
      end;  GetSerialNo;
      if ErrNo <> 0 then
        Exit; //读错误
      if (pw[0] = 0) then
        s := ''
      else
        for i := 10 to 20 do
        begin
          s := s + char(pw[i] shr 8) + char(pw[i] and $FF);
        end;
    end;
    {********* End in Win9x************}{*******Use in Win2k ****************}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;
    { Windows NT, Windows 2000
    通过MS的S.M.A.R.T.接口,直接从RING3调用
    API DeviceIoControl()来获取硬盘信息
    Get SCSI port handle}function GetIdeDiskSNNT: string;
    var
      hDevice: THandle;
      cbBytesReturned: DWORD;
      pInData: PSendCmdInParams;
      pOutData: Pointer; // PSendCmdOutParams
      Buffer: array[0..BufferSize - 1] of Byte;
      srbControl: TSrbIoControl absolute Buffer;
    begin
      Result := '';
      FillChar(Buffer, BufferSize, #0);  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;  with PIdSector(PChar(pOutData) + 16)^ do
      begin
        ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
        SetString(Result, sSerialNumber, SizeOf(sSerialNumber));
      end;
      Result := Trim(Result);
    end;
    {********* End in Win2k************}function getIDEHardDiskSN: string;
    begin
      if Win32Platform = VER_PLATFORM_WIN32_NT then
        Result := getIDEDiskSNNT
      else if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
        getIDEDiskSN9x(0, Result)
      else
        Result := '';
    end;end.