Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-访问外部硬盘上高偏移量(超过4G)的原始扇区_C#_Kernel32 - Fatal编程技术网

C#-访问外部硬盘上高偏移量(超过4G)的原始扇区

C#-访问外部硬盘上高偏移量(超过4G)的原始扇区,c#,kernel32,C#,Kernel32,我在程序中使用“Kernel32.dll”功能访问WinXP SP3操作系统(外部硬盘)上的原始磁盘扇区 在程序到达扇区号8388607之前,一切正常-这意味着SetFilePointer中的字节偏移量超过32位(uint!)。 但我的代码如下所示,使用所有变量作为“long”。我做错了什么 代码(在“转储”按钮上单击): 我已经尝试了很多方法,但不知道哪里出了问题,应用程序最终出现了一个致命的异常,要求发送错误报告 非常感谢您的p/Invoke定义是错误的。该函数在中接受32位值,但您将其定义

我在程序中使用“Kernel32.dll”功能访问WinXP SP3操作系统(外部硬盘)上的原始磁盘扇区

在程序到达扇区号8388607之前,一切正常-这意味着SetFilePointer中的字节偏移量超过32位(uint!)。 但我的代码如下所示,使用所有变量作为“long”。我做错了什么

代码(在“转储”按钮上单击):

我已经尝试了很多方法,但不知道哪里出了问题,应用程序最终出现了一个致命的异常,要求发送错误报告


非常感谢

您的p/Invoke定义是错误的。该函数在中接受32位值,但您将其定义为64位值。它将无法正常工作,并且肯定不会超过32位变量的值范围

请参见有关如何在以下位置使用的定义和示例:

因此,您需要将64位值一分为二,并为函数提供这两部分


也不要对整数使用双精度。当精确性结束并且没有理由使用它们时,您会遇到麻烦。

然后会发生什么?错误?为什么要用双精度来表示整数呢?NET中的long与Win32API中的long也不一样。我纠正了它,但是在扇区8388636上,我得到了异常“HRESULT:0x80070017”,没有对到底发生了什么进行任何清楚的解释。这意味着什么?我发现了:我从现在开始寻找,改变了开始。
 int drive = DRV.SelectedIndex; // DRV is the drive combo box
 long bps = BytesPerSector(drive), spt = GetTotalSectors(drive);
 string dr = DRV.SelectedItem.ToString();
 int moveToHigh, read = 0;

 uint GENERIC_READ = 0x80000000;
 uint OPEN_EXISTING = 3;
 SafeFileHandle handleValue = CreateFile(dr, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
 if (handleValue.IsInvalid)
     Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());

 // idx = Loop starting index
 // FS = The starting sector index 
 // TS = The final sector index 
 long idx = (FS == -1) ? 0 : FS, tot = (TS == -1) ? spt : TS;

 for ( ; idx < tot; idx++)
 {
      byte[] b = new byte[bps];

      // HERE IS THE ISSUE!!!
      SetFilePointer(handleValue, idx*bps), out moveToHigh, EMoveMethod.Current);

      if (ReadFile(handleValue, b, bps, out read, IntPtr.Zero) == 0)
          Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());



       if (this.IsDisposed == true) { handleValue.Close(); break; }
            Application.DoEvents();
  }
  handleValue.Close();
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
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);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SetFilePointer(IntPtr handle, int lDistanceToMove, out int lpDistanceToMoveHigh, uint dwMoveMethod);


int lo = (int)(offset & 0xffffffff);
int hi = (int)(offset >> 32);

lo = SetFilePointer(handle, lo, out hi, moveMethod);