PDA

View Full Version : خواندن و نوشتن سکتور های یک درایو خاص



مهدی رحیم زاده
چهارشنبه 23 مرداد 1392, 13:35 عصر
با سلام خدمت تمامی دوستان و اساتید محترم
بنده میخوام سکتور های درایوی که ویندوز روش نصب هست رو بخونم . راهنمایی میخواستم که بدونم چطور میتونم این کار رو انجام بدم .
با تشکر

BORHAN TEC
چهارشنبه 23 مرداد 1392, 15:32 عصر
سلام
این کد رو من قبلاً با دلفی برای کار با sdcard نوشته بودم (و اون عدد 512 هم به خاطر همینه چرا که در حافظه sdcard هر سکتور از 512 بایت تشکیل شده است). این کد رو با نرم افزار Delphi2CPP به کد C++ Builder تبدیلش کردم. البته کد رو هنوز توی C++ builder تست نکرده ام و به همین خاطر هم کد دلفی رو قرار میدم و هم کد تبدیل شده(البته تست نشده). توجه داشته باشید که به راحتی و با اصلاحات کوچکی از این کد میتوان برای کار با درایوهای دیسک سخت هم استفاده کرد.
این از کد دلفی:
unit Unit1;

interface

uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ComCtrls,
Mask,
JvExMask,
JvToolEdit,
FileCtrl,
RzFilSys,
RzButton,
ExtCtrls,
RzPanel,
ImgList,
acAlphaImageList,
Menus;

type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
Label1: TLabel;
drvBackup: TRzDriveComboBox;
Label2: TLabel;
fileBackup: TJvFilenameEdit;
btnBackup: TButton;
pBackup: TProgressBar;
GroupBox2: TGroupBox;
Label3: TLabel;
Label4: TLabel;
drvRestore: TRzDriveComboBox;
fileRestore: TJvFilenameEdit;
btnRestore: TButton;
pRestore: TProgressBar;
RzToolbar1: TRzToolbar;
RzToolButton1: TRzToolButton;
RzToolButton2: TRzToolButton;
sAlphaImageList1: TsAlphaImageList;
procedure btnBackupClick(Sender: TObject);
procedure btnRestoreClick(Sender: TObject);
procedure RzToolButton1Click(Sender: TObject);
procedure RzToolButton2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
CancelFlag: Boolean;

implementation

{$R *.dfm}

function GetTotalSector(Drive: PWideChar): Int64;
var
SectorPerCluster, BytePerSector, NumFreeCluster, TotalNumCluster: Cardinal;
begin
GetDiskFreeSpace(Drive, SectorPerCluster, BytePerSector, NumFreeCluster,
TotalNumCluster);
Result := TotalNumCluster * SectorPerCluster;
end;

procedure TForm1.btnBackupClick(Sender: TObject);
var
RawMBR: array [0 .. 511] of byte;
btsIO: DWORD;
hDevice, hFile: THandle;
_Drive, _File: PWideChar;
_TotalSector, _CurrentSector: Cardinal;
begin
// =====================================
CancelFlag := False;
_CurrentSector := 0;
_TotalSector := 0;
pBackup.Position := 0;
// =====================================

_Drive := PWideChar(drvBackup.Drive + ':');
_TotalSector := GetTotalSector(PWideChar(_Drive));
pBackup.Max := _TotalSector;
hDevice := CreateFile(PWideChar('\\.\' + _Drive), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

_File := PWideChar(fileBackup.FileName);
hFile := CreateFile(PWideChar(fileBackup.FileName), GENERIC_WRITE,
FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
try

if hDevice = INVALID_HANDLE_VALUE then
begin
MessageBox(0, 'Invalid Drive.', 'Error', MB_OK or MB_ICONERROR);
Exit;
end;

if hFile = INVALID_HANDLE_VALUE then
begin
MessageBox(0, 'Invalid File.', 'Error', MB_OK or MB_ICONERROR);
Exit;
end;

while (_CurrentSector <= _TotalSector) do
begin
// Read From Drive : ===================
SetFilePointer(hDevice, 512 * _CurrentSector, nil, FILE_BEGIN);
// replace 0 with sector that you wish to read
ReadFile(hDevice, RawMBR[0], 512, btsIO, nil);
// =====================================

// Write To File : =====================
SetFilePointer(hFile, 0, nil, FILE_CURRENT);
WriteFile(hFile, RawMBR[0], 512, btsIO, nil);
// =====================================

if CancelFlag then
Break;

Application.ProcessMessages;

Inc(_CurrentSector);
pBackup.Position := pBackup.Position + 1;

end;

finally
// =====================================
CloseHandle(hDevice);
CloseHandle(hFile);
// =====================================
end;
MessageBox(0, 'Action Done.', 'Information', MB_OK or MB_ICONINFORMATION);

end;

procedure TForm1.btnRestoreClick(Sender: TObject);
var
RawMBR: array [0 .. 511] of byte;
btsIO: DWORD;
hDevice, hFile: THandle;
_Drive, _File: PWideChar;
_TotalPart, _CurrentPart: Cardinal;
begin
// =====================================
CancelFlag := False;
_CurrentPart := 0;
_TotalPart := 0;
pRestore.Position := 0;
// =====================================

_File := PWideChar(fileBackup.FileName);
hFile := CreateFile(PWideChar(fileRestore.FileName), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
_TotalPart := (GetFileSize(hFile, 0) div 512) + 1;

_Drive := PWideChar(drvRestore.Drive + ':');
pRestore.Max := _TotalPart;
hDevice := CreateFile(PWideChar('\\.\' + _Drive), GENERIC_WRITE,
FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
try

if hDevice = INVALID_HANDLE_VALUE then
begin
MessageBox(0, 'Invalid Drive.', 'Error', MB_OK or MB_ICONERROR);
Exit;
end;

if hFile = INVALID_HANDLE_VALUE then
begin
MessageBox(0, 'Invalid File.', 'Error', MB_OK or MB_ICONERROR);
Exit;
end;

while (_CurrentPart <= _TotalPart) do
begin
// Read From Drive : ===================
SetFilePointer(hFile, 512 * _CurrentPart, nil, FILE_BEGIN);
// replace 0 with sector that you wish to read
ReadFile(hFile, RawMBR[0], 512, btsIO, nil);
// =====================================

// Write To File : =====================
SetFilePointer(hDevice, 0, nil, FILE_CURRENT);
WriteFile(hDevice, RawMBR[0], 512, btsIO, nil);
// =====================================

if CancelFlag then
Break;

Application.ProcessMessages;

Inc(_CurrentPart);
pRestore.Position := pRestore.Position + 1;

end;

finally
// =====================================
CloseHandle(hDevice);
CloseHandle(hFile);
// =====================================
end;
MessageBox(0, 'Action Done.', 'Information', MB_OK or MB_ICONINFORMATION);

end;

procedure TForm1.RzToolButton1Click(Sender: TObject);
begin
drvBackup.Free;
drvBackup := TRzDriveComboBox.Create(Self);
with drvBackup do
begin
Parent := GroupBox1;
Top := 48;
Left := 16;
width := 241;
DriveTypes := [dtFloppy];
Show;
end;

drvRestore.Free;
drvRestore := TRzDriveComboBox.Create(Self);
with drvRestore do
begin
Parent := GroupBox2;
Top := 107;
Left := 16;
width := 241;
DriveTypes := [dtFloppy];
Show;
end;

end;

procedure TForm1.RzToolButton2Click(Sender: TObject);
begin
CancelFlag := True;
end;

end.


و اما تبدیل شده کدهای بالا به C++ builder:
فایل هدر:
#ifndef Unit1H
#define Unit1H


#include <System.hpp>

#include <windows.hpp>
#include <messages.hpp>
#include <sysutils.hpp>
#include <variants.hpp>
#include <classes.hpp>
#include <graphics.hpp>
#include <controls.hpp>
#include <forms.hpp>
#include <dialogs.hpp>
#include <stdctrls.hpp>
#include <comctrls.hpp>
#include <mask.hpp>
#include "JvExMask.h"
#include "JvToolEdit.h"
#include <filectrl.hpp>
#include "RzFilSys.h"
#include "RzButton.h"
#include <extctrls.hpp>
#include "RzPanel.h"
#include <imglist.hpp>
#include "acAlphaImageList.h"
#include <menus.hpp>



class TForm1;




class TForm1: public TForm {
typedef TForm inherited;
public:
TGroupBox GroupBox1;
TLabel Label1;
TRzDriveComboBox drvBackup;
TLabel Label2;
TJvFilenameEdit fileBackup;
TButton btnBackup;
TProgressBar pBackup;
TGroupBox GroupBox2;
TLabel Label3;
TLabel Label4;
TRzDriveComboBox drvRestore;
TJvFilenameEdit fileRestore;
TButton btnRestore;
TProgressBar pRestore;
TRzToolbar RzToolbar1;
TRzToolButton RzToolButton1;
TRzToolButton RzToolButton2;
TsAlphaImageList sAlphaImageList1;
void __fastcall btnBackupClick( TObject* Sender );
void __fastcall btnRestoreClick( TObject* Sender );
void __fastcall RzToolButton1Click( TObject* Sender );
void __fastcall RzToolButton2Click( TObject* Sender );
private:
/* Private declarations */
public:
/* Public declarations */
};


extern TForm1* Form1;
extern bool CancelFlag;

#endif // Unit1H
فایل کد:

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"


#pragma resource "*.dfm"


#include <System.hpp>


TForm1* Form1 = NULL;
bool CancelFlag = false;



__int64 __fastcall GetTotalSector( wchar_t* Drive )
{
__int64 result = 0;
unsigned int SectorPerCluster = 0, BytePerSector = 0, NumFreeCluster = 0, TotalNumCluster = 0;
GetDiskFreeSpace( Drive, SectorPerCluster, BytePerSector, NumFreeCluster, TotalNumCluster );
result = TotalNumCluster * SectorPerCluster;
return result;
}


void __fastcall TForm1::btnBackupClick( TObject* Sender )
{
unsigned char RawMBR[ 512/*# range 0..511*/ ];
DWORD btsIO = 0;
THandle hDevice, hFile;
wchar_t* _Drive = NULL,* _File = NULL;
unsigned int _TotalSector = 0, _CurrentSector = 0;
// =====================================
CancelFlag = false;
_CurrentSector = 0;
_TotalSector = 0;
pBackup.Position = 0;
// =====================================
_Drive = ( PWideChar ) ( drvBackup.Drive + ":" );
_TotalSector = GetTotalSector( ( PWideChar ) ( _Drive ) );
pBackup.Max = _TotalSector;
{
AnsiString Unit1__0 = AnsiString( L"\\\\.\\" ) + _Drive;
hDevice = CreateFile( Unit1__0.c_str( ), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
}
_File = ( PWideChar ) ( fileBackup.FileName );
hFile = CreateFile( ( PWideChar ) ( fileBackup.FileName ), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, 0 );
try
{
if ( hDevice == INVALID_HANDLE_VALUE )
{
MessageBox( 0, "Invalid Drive.", "Error", MB_OK | MB_ICONERROR );
return;
}
if ( hFile == INVALID_HANDLE_VALUE )
{
MessageBox( 0, "Invalid File.", "Error", MB_OK | MB_ICONERROR );
return;
}
while ( _CurrentSector <= _TotalSector )
{
// Read From Drive : ===================
SetFilePointer( hDevice, 512 * _CurrentSector, NULL, FILE_BEGIN );
// replace 0 with sector that you wish to read
ReadFile( hDevice, RawMBR[0], 512, btsIO, NULL );
// =====================================

// Write To File : =====================
SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
WriteFile( hFile, RawMBR[0], 512, btsIO, NULL );
// =====================================
if ( CancelFlag )
Break;
Application.ProcessMessages;
_CurrentSector++;
pBackup.Position = pBackup.Position + 1;
}
}
__finally
{
// =====================================
CloseHandle( hDevice );
CloseHandle( hFile );
// =====================================
}
MessageBox( 0, "Action Done.", "Information", MB_OK | MB_ICONINFORMATION );
}


void __fastcall TForm1::btnRestoreClick( TObject* Sender )
{
unsigned char RawMBR[ 512/*# range 0..511*/ ];
DWORD btsIO = 0;
THandle hDevice, hFile;
wchar_t* _Drive = NULL,* _File = NULL;
unsigned int _TotalPart = 0, _CurrentPart = 0;
// =====================================
CancelFlag = false;
_CurrentPart = 0;
_TotalPart = 0;
pRestore.Position = 0;
// =====================================
_File = ( PWideChar ) ( fileBackup.FileName );
hFile = CreateFile( ( PWideChar ) ( fileRestore.FileName ), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
_TotalPart = ( GetFileSize( hFile, 0 ) / 512 ) + 1;
_Drive = ( PWideChar ) ( drvRestore.Drive + ":" );
pRestore.Max = _TotalPart;
{
AnsiString Unit1__1 = AnsiString( L"\\\\.\\" ) + _Drive;
hDevice = CreateFile( Unit1__1.c_str( ), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, 0 );
}
try
{
if ( hDevice == INVALID_HANDLE_VALUE )
{
MessageBox( 0, "Invalid Drive.", "Error", MB_OK | MB_ICONERROR );
return;
}
if ( hFile == INVALID_HANDLE_VALUE )
{
MessageBox( 0, "Invalid File.", "Error", MB_OK | MB_ICONERROR );
return;
}
while ( _CurrentPart <= _TotalPart )
{
// Read From Drive : ===================
SetFilePointer( hFile, 512 * _CurrentPart, NULL, FILE_BEGIN );
// replace 0 with sector that you wish to read
ReadFile( hFile, RawMBR[0], 512, btsIO, NULL );
// =====================================

// Write To File : =====================
SetFilePointer( hDevice, 0, NULL, FILE_CURRENT );
WriteFile( hDevice, RawMBR[0], 512, btsIO, NULL );
// =====================================
if ( CancelFlag )
Break;
Application.ProcessMessages;
_CurrentPart++;
pRestore.Position = pRestore.Position + 1;
}
}
__finally
{
// =====================================
CloseHandle( hDevice );
CloseHandle( hFile );
// =====================================
}
MessageBox( 0, "Action Done.", "Information", MB_OK | MB_ICONINFORMATION );
}


void __fastcall TForm1::RzToolButton1Click( TObject* Sender )
{
drvBackup.Free;
drvBackup = TRzDriveComboBox.Create( this );
/*# with drvBackup do */
{
Parent = GroupBox1;
Top = 48;
Left = 16;
width = 241;
DriveTypes = ( System::Set < dtFloppy, 0, 255 >()
<< dtFloppy ( dtFloppy ) );
Show;
}
drvRestore.Free;
drvRestore = TRzDriveComboBox.Create( this );
/*# with drvRestore do */
{
Parent = GroupBox2;
Top = 107;
Left = 16;
width = 241;
DriveTypes = ( System::Set < dtFloppy, 0, 255 >()
<< dtFloppy ( dtFloppy ) );
Show;
}
}


void __fastcall TForm1::RzToolButton2Click( TObject* Sender )
{
CancelFlag = true;
}

اگر سوالی هست در خدمتم.
موفق باشید...

omidshaman
چهارشنبه 23 مرداد 1392, 22:21 عصر
شما می تونی از ReadFile و WriteFile استفاده کنی
https://www.google.com/#bav=on.2,or.r_cp.r_qf.&fp=fb830c9f65497401&q=how+to+rea+sector+of+drive+c%2B%2B&safe=off
یک چیزی تو مایه های این تاپیک
http://barnamenevis.org/showthread.php?413086-%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-%D8%B1%D8%B4%D8%AA%D9%87-%D8%A8%D8%A7-%D9%81%D8%B1%D9%85%D8%AA-Hex-%D8%A8%D9%87-%D8%AE%D8%B1%D9%88%D8%AC%DB%8C-%D8%AA%D8%A7%D8%A8%D8%B9%DB%8C-%D8%A8%D8%A7-%D9%86%D9%88%D8%B9-(LPSTR)-%D8%9F