c# - DumpSector 总是返回第一个磁盘扇区
问题描述
我从这里
得到代码
问题是无论我发送函数的扇区号是什么,它总是转储第一个扇区
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 警告。当你寻求帮助时总是提到这样的事情。喜欢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);
我重构了代码中的用法。
推荐阅读
- c# - 从 Web 服务生成的 html 在代码中添加反斜杠
- javascript - Discord.js 机器人记录已删除的消息不是一次而是很多
- c# - 正则表达式匹配在 C# 中不能很好地匹配
- php - 为什么我的数据库插入查询在考勤管理系统php/mysql中插入记录失败
- c - 程序不运行。说我正在尝试为指针赋值
- java - 使用 Writer 发送带有韩文文本的电子邮件输出垃圾
- python - 为什么我的线程锁在这种情况下失败了?
- javascript - 使用Javascript-按钮的Onclickevent,需要下载一个exe文件,直接存放在系统的temp文件夹中
- git - 如何使用 shell 脚本从 git repo 打印最新的提交 ID
- julia - 如何在 Julia 中运行构造命令?