转储扇区始终返回第一个磁盘扇区



我从这里
得到了代码 问题是,无论我发送函数的扇区号是什么,它总是转储第一个扇区

DumpSector(string drive, double sector, int bytesPerSector)始终返回第一个磁盘扇区

drive = "\.PHYSICALDRIVE1"  
sector = from 0 to totalSectors
bytesPerSector = 512

我很抱歉有大量的代码。

class LowReader
{
#region "WMI LOW LEVEL COMMANDS"                
public static int BytesPerSector(int drive)
{
int driveCounter = 0;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
if (driveCounter == drive)
{
var t = queryObj["BytesPerSector"];
return int.Parse(t.ToString());
}
driveCounter++;
}
}
catch (ManagementException)
{
return -1;
}
return 0;
}
public ArrayList GetDriveList()
{
ArrayList drivelist = new ArrayList();
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
drivelist.Add(queryObj["DeviceID"].ToString());
}
}
catch (ManagementException)
{
return null;
}
return drivelist;
}
public static long GetTotalSectors(int drive)
{
int driveCount = 0;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
if (driveCount == drive)
{
var t = queryObj["TotalSectors"];
return  long.Parse(t.ToString());
}
driveCount++;
}
}
catch (ManagementException)
{
return -1;
}
return -1;
}   
public static int GetSectorsPerTrack(int drive)
{
int driveCount = 0;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
if (driveCount == drive)
{
var t = queryObj["SectorsPerTrack"];
return int.Parse(t.ToString());
}
driveCount++;
}
}
catch (ManagementException)
{
return -1;
}
return -1;
}
public static int GetTotalTracks(int drive)
{
int DriveCount = 0;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\CIMV2",
"SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
if (DriveCount == drive)
{
var t = queryObj["TotalTracks"];
return int.Parse((t.ToString()));
}
DriveCount++;
}
}
catch (ManagementException)
{
return -1;
}
return -1;
}
#endregion
#region "API CALLS" 
public enum EMoveMethod : uint
{
Begin = 0,
Current = 1,
End = 2
}
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.ThisCall)]
static extern uint SetFilePointer(
[In] SafeFileHandle hFile,
[In] long lDistanceToMove,
[Out] out int lpDistanceToMoveHigh,
[In] EMoveMethod dwMoveMethod);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32", SetLastError = true)]
internal extern static int ReadFile(SafeFileHandle handle, byte[] bytes,
int numBytesToRead, out int numBytesRead, IntPtr overlapped_MustBeZero);
#endregion    
public byte[] DumpSector(string drive, double sector, int bytesPerSector)
{
short FILE_ATTRIBUTE_NORMAL = 0x80;
short INVALID_HANDLE_VALUE = -1;
uint GENERIC_READ = 0x80000000;
uint GENERIC_WRITE = 0x40000000;
uint CREATE_NEW = 1;
uint CREATE_ALWAYS = 2;
uint OPEN_EXISTING = 3;
SafeFileHandle handleValue = CreateFile(drive, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (handleValue.IsInvalid)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
double sec = sector * bytesPerSector;
int size = int.Parse(bytesPerSector.ToString());
byte[] buf = new byte[size];
int read = 0;
int moveToHigh;
SetFilePointer(handleValue, long.Parse(sec.ToString()), out moveToHigh, EMoveMethod.Begin);
ReadFile(handleValue, buf, size, out read, IntPtr.Zero);
handleValue.Close();
return buf;
}
private byte[] DumpTrack(string drive, double track, int bytesPerTrack, int TrackBufferSize)
{
short FILE_ATTRIBUTE_NORMAL = 0x80;
short INVALID_HANDLE_VALUE = -1;
uint GENERIC_READ = 0x80000000;
uint GENERIC_WRITE = 0x40000000;
uint CREATE_NEW = 1;
uint CREATE_ALWAYS = 2;
uint OPEN_EXISTING = 3;
SafeFileHandle handleValue = CreateFile(drive, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (handleValue.IsInvalid)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
double trx = (track * bytesPerTrack * TrackBufferSize);
int size = int.Parse(bytesPerTrack.ToString());
byte[] buf = new byte[size * TrackBufferSize];
int read = 0;
int moveToHigh;
SetFilePointer(handleValue, long.Parse(trx.ToString()), out moveToHigh, EMoveMethod.Begin);
ReadFile(handleValue, buf, size, out read, IntPtr.Zero);
handleValue.Close();
return buf;
}
}

正如@HansPassant所说

"SetFilePointer(( 声明是完全错误的。原始代码中错误,但在代码片段中变得更糟,看起来像是被随机黑客入侵,直到它停止生成 MDA 警告。当你寻求帮助时,总是提到这样的事情。Favor SetFilePointerEx.">

我改变了这个

[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.ThisCall)]
static extern uint SetFilePointer(
[In] SafeFileHandle hFile,
[In] long lDistanceToMove,
[Out] out int lpDistanceToMoveHigh,
[In] EMoveMethod dwMoveMethod);

对此

[DllImport("kernel32.dll")]
public static extern bool SetFilePointerEx(
SafeFileHandle hFile, 
long liDistanceToMove,
out long lpNewFilePointer, 
uint dwMoveMethod);

我重构了代码中的用法。

最新更新