1 1 1 1 1 1 1 1 1 1 Рейтинг 0.00 (0 Голоса(ов)

Сразу предупреждаю: прямая запись секторов на диск - дело опасное. Поэтому любые эксперименты оставляю на Ваш страх и риск. Не уверены, не лезьте.

Ответы на вопросы по переменным и типам, используемым в коде, вероятнее всего, Вы найдете тут.

Код Delphi:
  1. // так как диск для нас - это единый файл, то для перемещения по нему
  2. // с помощью SetFilePointer понадобится 64хразрядная арифметика
  3. function __Mul(a,b: DWORD; var HiDWORD: DWORD): DWORD; // Result = LoDWORD
  4. asm
  5. mul edx
  6. mov [ecx],edx
  7. end;

Для чтения нам понадобиться поток (если, конечно, Вы не относитесь к числу любителей "подвисания" программы на сбойных секторах).

Код Delphi:
  1. type
  2. TReadThread = class(TThread)
  3. private
  4. { Private declarations }
  5. protected
  6. Flag: boolean;
  7. DriveNumber: byte;
  8. StartingSector: DWORD;
  9. SectorCount: DWORD;
  10. Buffer: Pointer;
  11. BytesPerSector: DWORD;
  12. OutData: DWORD;
  13. hFile: THandle;
  14. ovrDisk: TOverlapped;
  15. procedure PostRead;
  16. procedure Execute; override;
  17. end;

 

Код Delphi:
  1. procedure TReadThread.Execute;
  2. var
  3. br,br1,TmpLo,TmpHi: DWORD;
  4. TimeOut:boolean;
  5. WFSO: DWORD;
  6. begin
  7. Flag:=true;
  8. FillChar(ovrDisk,SizeOf(ovrDisk),0);
  9. ovrDisk.hEvent := CreateEvent(nil, False, False, nil);
  10. hFile := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(DriveNumber)),
  11. GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,
  12. FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING,0);
  13. if hFile = INVALID_HANDLE_VALUE then Exit;
  14. TmpLo := __Mul(StartingSector,BytesPerSector,TmpHi);
  15. if SetFilePointer(hFile,TmpLo,@TmpHi,FILE_BEGIN) = TmpLo then
  16. begin
  17. SectorCount := SectorCount*BytesPerSector;
  18. TimeOut:=false;
  19. ResetEvent(ovrDisk.hEvent);
  20. ovrDisk.Offset:=TmpLo;
  21. ovrDisk.OffsetHigh:=TmpHi;
  22. if (not(ReadFile(hFile,Buffer^,SectorCount,br,@ovrDisk))) then
  23. begin
  24. if (GetLastError()<>ERROR_IO_PENDING) then
  25. OutData:=0
  26. else
  27. begin
  28. repeat
  29. WFSO:=WaitForSingleObject(ovrDisk.hEvent,1000*ReadTimeOut);
  30. if (WFSO=WAIT_ABANDONED) then
  31. TimeOut:=true;
  32. if (WFSO=WAIT_FAILED) then
  33. TimeOut:=true;
  34. if (WFSO=WAIT_TIMEOUT) then
  35. TimeOut:=true;
  36. Application.ProcessMessages;
  37. until (TimeOut or (WFSO=WAIT_OBJECT_0) or (not(InWork)));
  38. if TimeOut then
  39. OutData:=0
  40. else
  41. OutData:=SectorCount;
  42. end;
  43. end;
  44. end;
  45. CloseHandle(hFile);
  46. CloseHandle(ovrDisk.hEvent);
  47. Flag:=false;
  48. end;

Теперь можно приступать и к чтению/записи секторов

Код Delphi:
  1. function TForm1.ReadSectors(DriveNumber: Byte; StartingSector, SectorCount: DWORD;
  2. Buffer: Pointer; BytesPerSector: DWORD = 512): DWORD;
  3. begin
  4. Result := 0;
  5. ReadThread:=TReadThread.Create(true);
  6. ReadThread.Priority:=tpNormal;
  7. ReadThread.DriveNumber:=DriveNumber;
  8. ReadThread.StartingSector:=StartingSector;
  9. ReadThread.SectorCount:=SectorCount;
  10. ReadThread.Buffer:= Buffer;
  11. ReadThread.BytesPerSector:=BytesPerSector;
  12. ReadThread.FreeOnTerminate:=false;
  13. ReadThread.Execute;
  14. while ReadThread.Flag do
  15. Application.ProcessMessages;
  16. Result:=ReadThread.OutData;
  17. ReadThread.Destroy;
  18. end;
  19.  
  20. function TForm1.WriteSectors(DriveNumber: Byte; StartingSector, SectorCount: DWORD;
  21. Buffer: Pointer; BytesPerSector: DWORD = 512): DWORD;
  22. var
  23. hFile: THandle;
  24. bw,TmpLo,TmpHi: DWORD;
  25. begin
  26. Result := 0;
  27. hFile := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(DriveNumber)),
  28. GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  29. if hFile = INVALID_HANDLE_VALUE then Exit;
  30. TmpLo := __Mul(StartingSector,BytesPerSector,TmpHi);
  31. if SetFilePointer(hFile,TmpLo,@TmpHi,FILE_BEGIN) = TmpLo then
  32. begin
  33. SectorCount := SectorCount*BytesPerSector;
  34. if WriteFile(hFile,Buffer^,SectorCount,bw,nil) then Result := bw;
  35. end;
  36. CloseHandle(hFile);
  37. end;