如何使用CreateFile访问物理磁盘?

4
我在Lazarus编程论坛上询问了如何打开物理磁盘。当用户点击“选择磁盘”按钮时,我希望允许用户从系统中选择物理磁盘。这里有一些类似的示例,但不完全相同(例如Delphi-使用DeviceIoControl传递IOCTL_DISK_GET_LENGTH_INFO以获取闪存媒体物理大小(非分区))。
有很多C和C++的示例使用CreateFile在文档中,特别是调用DeviceIoControl的示例),但我找不到Free Pascal或Delphi的示例,而且我还不够熟练,无法解决这个问题。

有人能指向一个解释它的链接,或者更好的是一个用Delphi或Free Pascal编写的实际示例吗?有人能帮助我理解如何使用它吗?


这有点重复:https://dev59.com/3VzUa4cB1Zd3GeqP2mPZ(除了这个提到了USB,尽管在这里USB不是一个因素。任何磁盘都是通过相同的技术访问的) - Warren P
1个回答

7
您的C语言示例中包含以下代码:

/* LPWSTR wszPath */

hDevice = CreateFileW(wszPath,          // drive to open
                      0,                // no access to the drive
                      FILE_SHARE_READ | // share mode
                      FILE_SHARE_WRITE, 
                      NULL,             // default security attributes
                      OPEN_EXISTING,    // disposition
                      0,                // file attributes
                      NULL);            // do not copy file attributes

将该函数调用转换为Delphi只需要更改语法即可:
// wszPath: PWideChar

hDevice := CreateFileW(wszPath,
                       0,
                       FILE_SHARE_READ or
                       FILE_SHARE_WRITE,
                       nil,
                       OPEN_EXISTING,
                       0,
                       0);

也就是说,使用:=进行赋值,or用于组合位标志,nil表示空指针,0表示空文件句柄。

该函数的调用方式如下:

#define wszDrive L"\\\\.\\PhysicalDrive0"

DISK_GEOMETRY pdg = { 0 }; // disk drive geometry structure

bResult = GetDriveGeometry (wszDrive, &pdg);

再次强调,只需要将语法更改为Delphi:

const wszDrive = '\\.\PhysicalDrive0';

var pdg: DISK_GEOMETRY;

ZeroMemory(@pdg, SizeOf(pdg));
bResult := GetDriveGeometry(wszDrive, @pdg);

Delphi中未指定类型的字符串常量会根据上下文自动转换为所需类型,因此我们不需要像C语言一样使用L前缀。反斜杠在Delphi中不是特殊字符,因此无需转义。Delphi不允许在声明中初始化局部变量,因此我们使用ZeroMemory将所有内容设置为零。使用@而不是&来获取变量的指针。


感谢大家迄今为止的帮助。第一个关于USB的链接很有用,转换后的代码对我理解同样有帮助。然而,在我的问题中有一件事情我不是很清楚,那就是当我的程序用户按下按钮时,我希望程序询问操作系统“你有哪些磁盘?”以便返回所有物理磁盘的列表。我不想硬编码“\.\PHYSICALDISKX”,我需要程序计算出有哪些磁盘,这样用户就可以选择一个。从那里开始,我就可以将其转换为 \.\PHYSICALDISKX,如果这样说有意义的话? - Gizmo_the_Great
2
是的,那很有道理,但那根本不是你所问的。获取物理磁盘列表与如何调用CreateFile毫无关系。如果您无法弄清楚如何获取此类列表,请在Stack Overflow上发布一个新问题。 - Rob Kennedy
我会查看这些示例并尝试它们,特别是Delphi的示例,但我需要一些可以查询已连接设备的东西,无论它们是否已挂载(例如从苹果计算机附加到Windows PC的磁盘-在总线上物理存在,但不一定已挂载)。 dskwipe示例正是我所需要的,但那是另一个C示例。我已按照您的建议,并在此处询问了有关如何使用Delph \ Free Pascal调用物理附加磁盘列表的更具体问题:https://dev59.com/ZWoy5IYBdhLWcg3wfOF4 - Gizmo_the_Great

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接