IntToHex значений в 512-байтовом массиве, относящихся к дескриптору CreateFile, всегда возвращают один и тот же вывод? Синтаксис FreePascal \ Delphi. - PullRequest
1 голос
/ 02 февраля 2012

Короче говоря, моя программа позволяет хешировать вещи.Единственное, чего в данный момент не хватает - это возможность хэшировать физические диски в версии Windows (версия Linux позволяет пользователю выбирать / dev / sda и т. Д.).

Я создал кнопку, которая при нажатии выводит списокподключенные устройства, чтобы дать мне "\. \ PHYSICALDISKX" (спасибо предложениям пользователей SO в ответ на мои предыдущие сообщения).Затем я могу передать это значение в функцию Windows API 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 Ответ

2 голосов
/ 02 февраля 2012

На какой версии 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;  
...