免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7043 | 回复: 13
打印 上一主题 下一主题

调用外部DLL获取硬盘ID [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-14 11:42 |只看该作者 |倒序浏览
5可用积分
有一个DiskID.dll(见附件) DiskID.rar (18.79 KB, 下载次数: 110) ,内部含有一个获取本机硬盘ID的函数,我希望用PERL代码调用它,正确获得硬盘ID。因为不熟悉调用细节,尝试了很多次都不成功,希望有经验的大虾支招。

下面是这个DLL的PASCAL调用代码:
  1. unit Unit1;

  2. interface

  3. uses
  4.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  5.   StdCtrls;

  6. type DRIVER_INFO_OK = record
  7.   ModalNumber : array[0..39] of char;
  8.   SerialNumber : array [0..19] of char;
  9.   ControlNum : array[0..7]of char;
  10.   DriveType : dword;
  11.   Cylinders : dword;
  12.   Heads : dword;
  13.   Sectors : dword;
  14. end;

  15. type
  16.   TForm1 = class(TForm)
  17.     Button1: TButton;
  18.     Memo1: TMemo;
  19.     procedure Button1Click(Sender: TObject);
  20.   private
  21.     { Private declarations }
  22.   public
  23.     { Public declarations }
  24.   end;
  25. function IsWinNT:boolean;
  26.         stdcall; external 'DiskID.dll'
  27.         name 'IsWinNT';
  28. function ReadPhysicalDrive(driveID:integer;buffer:Pointer;bufLen:integer):integer;
  29.         stdcall; external 'DiskID.dll'
  30.         name 'ReadPhysicalDriveInNT';
  31. function ReadPhysicalDrive9X(driveID:integer;buffer:Pointer;bufLen:integer):integer;
  32.         stdcall; external 'DiskID.dll'
  33.         name 'ReadDrivePortsInWin9X';
  34. function getHardDriveComputerID:int64;
  35.         stdcall; external 'DiskID.dll'
  36.         name 'getHardDriveComputerID';
  37. var
  38.   Form1: TForm1;

  39. implementation

  40. {$R *.DFM}

  41. procedure TForm1.Button1Click(Sender: TObject);
  42. var
  43.   x:DRIVER_INFO_OK;
  44.   intRet:integer;
  45. begin
  46.   if IsWinNT then
  47.     ReadPhysicalDrive(0,@x,256)
  48.   else
  49.     ReadPhysicalDrive9X(0,@x,256);

  50.   Memo1.Lines.Add(x.SerialNumber);
  51.   Memo1.Lines.Add(x.ModalNumber);
  52.   Memo1.Lines.Add(x.ControlNum);

  53.   showmessage(inttostr(getHardDriveComputerID));
  54. end;

  55. end.
复制代码

最佳答案

查看完整内容

Win32::API可以实现的吧.

论坛徽章:
0
2 [报告]
发表于 2010-05-14 11:42 |只看该作者
Win32::API可以实现的吧.

  1. use Win32::API;

  2. Win32::API::Struct->typedef('MYTYPE', qw(
  3.         char ModalNumber[39];
  4.         char SerialNumber[19];
  5.         char ControlNum[7];
  6.         DWORD DriveType;
  7.         DWORD Cylinders;
  8.         DWORD Heads;
  9.         DWORD Sectors;
  10. ));

  11. $p = Win32::API::Struct->new('MYTYPE');
  12. $p->{align} = 'auto';

  13. $f = Win32::API->new('DiskID.dll', 'int ReadPhysicalDriveInNT(int a, MYTYPE p , int n)');

  14. $rs = $f->Call(0, $p, 255);
  15. print($p->{ModalNumber});
复制代码

论坛徽章:
0
3 [报告]
发表于 2010-05-14 15:54 |只看该作者
据我知道的,Perl 5 似乎没有可以直接调用 dll 的可能,都是通过 xs 调用的,但 xs 要求你有 dll 的源码……
python 等脚本貌似都能支持 dll 直接调用了,perl6 应该会支持了~

论坛徽章:
0
4 [报告]
发表于 2010-05-14 16:14 |只看该作者
据我所知,是可以通过win32::api调用的,但可能在某些情况下不能调用。

论坛徽章:
0
5 [报告]
发表于 2010-05-14 16:35 |只看该作者
尝试第三方 module  
cpan有 关于硬盘序列号的 module吧

论坛徽章:
0
6 [报告]
发表于 2010-05-15 01:25 |只看该作者
学习了哦,真没有用过这个模块,Win32下的几个模块,真的很强大啊,要好好研究一下~

论坛徽章:
0
7 [报告]
发表于 2010-05-15 02:25 |只看该作者
非常感谢redskywy,现在除了SerialNumber,其他的都能获取了。看有没有高手把SerialNumber也正确获取,再一起给分。

论坛徽章:
0
8 [报告]
发表于 2010-05-15 08:57 |只看该作者
数组大小定义的有点问题,修改之,就可以获取serialnumber了~
Win32::API::Struct->typedef('MYTYPE', qw(
        char ModalNumber[40];
        char SerialNumber[20];
        char ControlNum[8];
        DWORD DriveType;
        DWORD Cylinders;
        DWORD Heads;
        DWORD Sectors;
));

论坛徽章:
0
9 [报告]
发表于 2010-05-15 09:36 |只看该作者
看了$p->{buffer}的内容做了下调整的
要把字符串的结束标志这个长度加进去不然会导致其它的成员无法取到

  1. Win32::API::Struct->typedef('MYTYPE', qw(
  2.         char ModalNumber[41];
  3.         char SerialNumber[21];
  4.         char ControlNum[11];
  5.         DWORD DriveType;
  6.         DWORD Cylinders;
  7.         DWORD Heads;
  8.         DWORD Sectors;
  9. ));
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2010-05-15 10:59 |只看该作者
本帖最后由 flw 于 2010-05-15 11:02 编辑
据我知道的,Perl 5 似乎没有可以直接调用 dll 的可能,都是通过 xs 调用的,但 xs 要求你有 dll 的源码…… ...
dugu072_cu 发表于 2010-05-14 15:54

我给你更正一下你这条记忆:
Perl5 是可以直接调用 dll 的。
事实上不光 Perl5 可以,所有的支持 C 扩展的语言都可以。

这个结论可以直接从你已有的知识当中经过逻辑推理得到。
试想如果不支持直接调用 dll,但支持 xs 扩展,
而 xs 扩展里是可以调用任何 dll 的,然后写一个叫做 I::Can::Call::Any::Dll 的 xs 扩展不就可以了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP