gpt4 book ai didi

c# - 在 C# 中通过 Pinvoke 读取 DVD 的特定扇区

转载 作者:太空宇宙 更新时间:2023-11-03 10:42:45 25 4
gpt4 key购买 nike

我正在使用 C# 直接从磁盘读取并调用 kernel32 ReadFile 方法。我只想读取一个特定的扇区以节省时间,但 ReadFile 从第一个扇区读取到 N 个扇区。如何根据我的选择只读自己的扇区?

    [StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED
{
public uint Internal;
public uint InternalHigh;
public uint Offset;
public uint OffsetHigh;
public int hEvent;
}

[DllImport("kernel32", SetLastError = true)]
static extern int CreateFile(string filename, uint desiredAccess, uint shareMode, IntPtr attributes, uint creationDisposition, uint flagsAndAttributes, IntPtr templateFile);

[DllImport("kernel32", SetLastError = true)]
public static extern Boolean CloseHandle(int handle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(IntPtr hFile, Byte[] buffer, UInt32 BytesToRead, ref UInt32 BytedRead, OVERLAPPED OverLapped);
static int EIGHT_K = 8192;
static int FIVE_TWELVE_BYTES = 512;
static uint GENERIC_READ = 0x80000000;
static uint OPEN_EXISTING = 3;
static uint FILE_SHARE_READ = 1;
static uint FILE_SHARE_WRITE = 2;

[STAThread]
private void button1_Click(object sender, EventArgs e)
{
int fileHandle = 0;
bool returnVal = true;

try
{
// Open the device specified (Using the boot partition)
string deviceName = @"\\.\f:";
fileHandle = CreateFile(deviceName, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, (IntPtr)0, OPEN_EXISTING, 0,(IntPtr)0);
if (fileHandle != -1)
{
Byte[] sector = new Byte[EIGHT_K];
UInt32 bytesRead = (uint)EIGHT_K;
OVERLAPPED ol = new OVERLAPPED();

// Can't get a FileStream ctor to work so I am using Win32 API ReadFile
bool worked = ReadFile((IntPtr)fileHandle, sector, (uint)EIGHT_K, ref bytesRead, ol);
return;

}
}

catch (Exception ex)
{
return;
}
finally
{
CloseHandle(fileHandle);
}
return;
}

我想将 DVD 标记为需要原始 DVD 才能运行该程序。

最佳答案

您的 OVERLAPPED 结构声明不当,在 64 位进程中不正确。但无论如何你不需要它。您没有执行重叠 I/O。这也是因为 ReadFile 的声明不正确。该函数需要一个指向 OVERLAPPED 结构的指针。您按值传递它。

在任何情况下,您都不需要考虑重叠 I/O。因此,通过从代码中删除 OVERLAPPED 结构声明来解决此问题。并像这样声明 ReadFile:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(IntPtr hFile, Byte[] buffer,
UInt32 BytesToRead, out UInt32 BytedRead, IntPtr Overlapped);

IntPtr.Zero 作为 Overlapped 参数传递。并确保检查 ReadFile 的返回值是否有错误。

下一步是查找文件中的某个位置。为此使用 SetFilePointerEx

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

查阅 SetFilePointerEx 的文档找出如何调用此函数。

由于您使用的是直接磁盘访问,因此您当然需要将读取与扇区边界对齐。

关于c# - 在 C# 中通过 Pinvoke 读取 DVD 的特定扇区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24746540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com