2011-12-14 2 views
4

Я спросил на форуме программирования Лазаря how to open a physical disk. Я хочу разрешить пользователю выбирать физические диски из своей системы, когда они нажимают кнопку «Выбрать диск». В Stack Overflow есть несколько примеров, которые похожи, но не совсем одинаковы (например, Delphi - Using DeviceIoControl passing IOCTL_DISK_GET_LENGTH_INFO to get flash media physical size (Not Partition)).Как использовать CreateFile для доступа к физическому диску?

Есть много C и C++ примеры использования CreateFile (in the documentation и особенно an example of calling DeviceIoControl), но я не могу найти для Free Pascal или Delphi, и я не достаточно хорош еще работать, как это сделать.

Может ли кто-нибудь указать мне в направлении ссылки, которая объясняет это, или, еще лучше, фактический пример, написанный на Delphi или Free Pascal? Может ли кто-нибудь помочь мне понять, как его использовать?

+0

Тип дубликатов: http://stackoverflow.com/questions/7826683/how-to-read-raw-block-from-an-usb-storage-device-with-delphi (За исключением того, что в этом упоминается USB, хотя USB здесь не является фактором. Любой диск доступен по той же методике) –

ответ

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 нетипизированным строковые константы автоматически независимо от типа они должны быть в контексте, так нам не нужен префикс L, например, C. Обратные косые черты не являются особыми в Delphi, поэтому их не нужно избегать. Delphi не позволяет инициализировать локальные переменные в декларации, поэтому мы используем ZeroMemory, чтобы установить все в ноль. Используйте @ вместо &, чтобы получить указатель на переменную.

+0

Спасибо всем за помощь до сих пор. Первый интерфейс re USB полезен, и преобразованный код в равной степени полезен для моего понимания. Тем не менее, одна вещь, о которой я не был ясно в своем вопросе, заключалась в том, что когда пользователь моей программы нажимает кнопку, я хочу, чтобы программа спросила операционную систему «Какие у вас диски?» поэтому он возвращает список всех физических дисков. То, что я не хочу делать, это жесткий код «\\. \ PHYSICALDISKX». Мне нужна программа, чтобы определить, какие диски есть, поэтому пользователь может выбрать ее. Затем я могу преобразовать это в \\. \ PHYSICALDISKX, если это имеет смысл? –

+2

Да, это имеет смысл, но это совсем не то, что вы просили. Получение списка физических дисков абсолютно не имеет никакого отношения к тому, как вызвать CreateFile. Если вы не можете понять [как получить такой список] (http://stackoverflow.com/search?q=list+of+physical+disks), то, пожалуйста, разместите здесь новый вопрос о переполнении стека. –

+0

+1. Хорошее объяснение, Роб. –