IntToHex значений в 512-байтовом массиве, относящихся к дескриптору CreateFile, всегда возвращают один и тот же вывод? Синтаксис FreePascal\Delphi.
Короче говоря, моя программа позволяет перемешивать вещи. Единственное, чего в данный момент ему не хватает, - это возможность хэшировать физические диски в версии Windows (версия Linux позволяет пользователю выбирать /dev/sda и т. Д.).
Я создал кнопку, которая при нажатии выводит список подключенных устройств, чтобы дать мне "\.\PHYSICALDISKX" (благодаря предложениям пользователей SO в ответ на мои предыдущие сообщения). Затем я могу передать это значение в функцию API Windows CreateFile, когда пользователь дважды щелкает его, чтобы создать дескриптор для него как событие двойного щелчка ListBox. Так что я сделал все это. Код ниже относится.
Тем не менее, я хочу проверить, что установленный дескриптор CreateFile работает - оператор if предполагает, что это так, но мне нужно проверить, действительно ли я могу читать данные для передачи другим функциям. Чтобы проверить это, я пытаюсь прочитать первые 512 байт любого диска и "quickyl" отобразить его в блокноте. Тем не менее, я не могу на всю жизнь понять, почему мой вывод неверен, и это так. Я получаю некоторые шестнадцатеричные значения, но они не совпадают с шестнадцатеричными значениями, которые присутствуют в первых 512 байтах. И это всегда один и тот же список шестнадцатеричных значений, независимо от того, на какой диск я смотрю! Так что я понятия не имею, откуда эти ценности или почему они всегда одинаковы. Вся идея в том, чтобы я проверил, что мой дескриптор в порядке, и что я могу фактически прочитать данные с диска, чтобы потом перейти к своим функциям хэширования.
Кто-нибудь может увидеть, где я иду не так, пожалуйста?
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
listBox : TListBox;
index : Integer;
hDiskToHash, i : integer;
DiskHashValue, DiskToHashFileName, TmpStr : string;
RawMBR : array [0..511] of byte;
bytesread : DWORD;
begin
i := 0;
// Cast the passed object to its correct type
listBox := TListBox(Sender);
// Get the index of the selected list item
index := listBox.ItemIndex;
// Display the selected list item value
ShowMessage(listBox.Items[index]);
// sValue1 is a global variable containing string '\\.\PHYSICALDISKX', populated by procedure TForm1.GetWin32_DiskDriveInfo;
hDiskToHash := Windows.CreateFile(PChar(sValue1), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
if hDiskToHash <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hDiskToHash,512 * 0,nil,FILE_BEGIN); // replace 0 with sector that you wish to read
ReadFile(hDiskToHash, RawMBR[0], SizeOf(RawMBR), bytesread, nil);
for i := Low(RawMBR) to High(RawMBR) do
begin
Memo2.Lines.Add(IntToHex(RawMBR[i],2)); // Add each hex byte on a new line
end;
CloseHandle(hDiskToHash);
end
else
begin
ShowMessage('Failed to open '+sValue1);
end;
end;
1 ответ
На какой версии Windows вы работаете? Документация CreateFile() гласит:
Прямой доступ к диску или тому ограничен. Дополнительные сведения см. В разделе "Изменения в файловой системе и в стеке хранения для ограничения прямого доступа к диску и прямого доступа к томам в Windows Vista и Windows Server 2008" в базе знаний справки и поддержки по адресу http://support.microsoft.com/kb/942448.
С этим сказал попробуйте это:
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
listBox : TListBox;
index : Integer;
hDiskToHash: THandle;
i : integer;
RawMBR : array [0..511] of Byte;
Offset, BytesRead : DWORD;
begin
// Cast the passed object to its correct type
listBox := TListBox(Sender);
// Get the index of the selected list item
index := listBox.ItemIndex;
if index = -1 then Exit;
// Display the selected list item value
ShowMessage(listBox.Items[index]);
// sValue1 is a global variable containing string '\\.\PHYSICALDISKX',
// populated by procedure TForm1.GetWin32_DiskDriveInfo;
hDiskToHash := Windows.CreateFile(PChar(sValue1), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
if hDiskToHash = INVALID_HANDLE_VALUE then RaiseLastOSError;
try
Offset := 512 * 0; // replace 0 with sector that you wish to read
if (SetFilePointer(hDiskToHash, Offset, nil, FILE_BEGIN) <> Offset) then raise Exception.Create("Did not seek to sector 0 correctly!");
if not ReadFile(hDiskToHash, RawMBR[0], SizeOf(RawMBR), BytesRead, nil) then RaiseLastOSError;
if BytesRead <> SizeOf(RawMBR) then raise Exception.Create("Did not read the full MBR!");
for i := 0 to BytesRead-1 do
begin
Memo2.Lines.Add(IntToHex(RawMBR[i], 2)); // Add each hex byte on a new line
end;
finally
CloseHandle(hDiskToHash);
end;
end;