How do I use CreateFile to access a physical disk?
Asked Answered
N

1

4

I asked on the Lazarus programming forum how to open a physical disk. I want to allow the user to select physical disks from their system when they click a "Select Disk" button. There are some examples here at Stack Overflow that are similar but not quite the same (such as Delphi - Using DeviceIoControl passing IOCTL_DISK_GET_LENGTH_INFO to get flash media physical size (Not Partition)).

There are lots of C and C++ examples of using CreateFile (in the documentation and especially an example of calling DeviceIoControl) but I can't find any for Free Pascal or Delphi and I am not good enough yet to work out how to do it.

Can anyone point me in the direction of a link that explains it or better still an actual example written in Delphi or Free Pascal? Can anyone help me understand how to use it?

Nasya answered 14/12, 2011 at 15:8 Comment(1)
Kind of duplicates: #7827183 (Except that this one mentions USB, although USB is a non-factor here. Any disk is accessed via the same technique)Masqat
A
7

Your C example has this code:

/* 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

Converting that function call to Delphi is just a matter of changing the syntax:

// wszPath: PWideChar

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

That is, use := for assignment, or for combining bit flags, nil for null pointers, and 0 for null file handles.

The function is called with this:

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

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

bResult = GetDriveGeometry (wszDrive, &pdg);

Again, just change the syntax to Delphi:

const wszDrive = '\\.\PhysicalDrive0';

var pdg: DISK_GEOMETRY;

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

Delphi untyped string constants are automatically whatever type they need to be in context, so we don't need any L prefix like C uses. Backslashes aren't special in Delphi, so they don't need to be escaped. Delphi doesn't allow initializing local variables in the declaration, so we use ZeroMemory to set everything to zero. Use @ instead of & to get a pointer to a variable.

Afghanistan answered 14/12, 2011 at 15:18 Comment(3)
Thanks everyone for the help so far. The first link re USB is useful and the converted code is equally helpful for my understanding. However, one thing I wasn't clear about in my question was that when the user of my program presses the button, I want the program to ask the operating system "What disks do you have?" so it returns a list of all the physical disks. What I don't want to have to do is hard code "\\.\PHYSICALDISKX" - I need the program to work out what disks there are so the user can then select one. From there, I can then convert that to \\.\PHYSICALDISKX, if that makes sense?Nasya
Yes, that makes sense, but that's not at all what you asked. Getting a list of physical disks has absolutely nothing to do with how to call CreateFile. If you can't figure out how to get such a list, then please post a new question here on Stack Overflow.Afghanistan
I will look at those examples and give them a try, especially the Delphi one, though I need something that will query the attached devices regardless of whether they have been mounted or not (e.g. disk from an Apple computer attached to a Windows PC - will be there physcially on the bus, but not necessarily mounted). The dskwipe example is exactly what I need, but that is another C example. I have done as you advised and asked a more specific question how to call a list of physically attached disks using Delph\Free Pascal here : https://mcmap.net/q/990733/-how-to-call-a-list-of-the-physically-attached-hard-disks-using-free-pascal-or-failing-that-delphiNasya

© 2022 - 2024 — McMap. All rights reserved.