【发布时间】:2014-06-11 19:56:52
【问题描述】:
我使用 Lazarus 1.2.2 和 Freepascal 2.6.4。
我有一个名为 QuickHash 的程序,它可以对文件进行哈希处理,当我在 Linux 上运行它时,它也可以用于对物理磁盘进行哈希处理 (/dev/sdXX)。但是,我想在 Windows 版本中添加该功能。
我认为要访问物理设备(如磁盘),必须使用CreateFile。具体来说,CreateFileW。
因此,用户单击一个按钮,该按钮会扫描计算机中的磁盘并将它们列在列表框中。然后将用户双击的字符串解析 (ListBox.GetSelectedText) 为字符串 '\.\PhyscialDiskX' 并将其分配给字符串变量,
strDiskID := getDiskID(Listbox.GetSelectedText);
效果很好。
然后我尝试创建该磁盘的句柄:
hSelectedDisk := Windows.CreateFileW(PWideChar(strDiskID), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
基于this article,特别是“您必须同时使用 CreateFile() FILE_SHARE_READ 和 FILE_SHARE_WRITE 标志才能访问驱动器”我还尝试了以下其他两种组合:
hSelectedDisk := CreateFileW(PWideChar(strDiskID), GENERIC_READ, FILE_SHARE_READ AND FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
hSelectedDisk := CreateFileW(PWideChar(strDiskID), GENERIC_READ, FILE_SHARE_READ OR FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
三个都成功分配了句柄。但是,顶部语法和底部语法最终会产生错误(解释如下)。中间选项立即返回零字节文件的默认初始化哈希,即 DA39... 用于 SHA1。
我的问题是我无法将该句柄(它是一个整数)传递给 Freepascal md5 和 SHA1 单元的 SHA1File 和 MD5FILE 函数。他们期望一个文件名,它必须是一个字符串。
因此,如果我将 strDiskID ('\.\PhyscialDiskX') 传递给它(这完全破坏了分配句柄的对象),我确实会获得磁盘活动并且程序似乎正在运行。
strDiskHashValue := SHA1Print(SHA1File(strDiskID));
ShowMessage(strDiskHashValue);
CloseHandle(hSelectedDisk);
但即使在非常小的磁盘上运行,如 500Mb USB 驱动器,也需要很多分钟并最终返回“运行错误 1117”,根据this 的意思是
"ERROR_IO_DEVICE
1117 (0x45D)
The request could not be performed because of an I/O device error."
但是,我已经在几个工作磁盘上尝试过,但错误仍然存在。
所以,我的问题归根结底是如何将成功分配的 THandle 传递给散列函数? (UI 也在Lazarus forums 上问过这个问题,但有时我会从那里没有看到线程的成员那里得到答案)
【问题讨论】:
标签: winapi freepascal