p / Invoke WriteFile在8次写入拒绝访问后失败

时间:2013-08-16 07:14:30

标签: c# pinvoke

我正在使用c#中的p / invoke直接写入本地HD。驱动器已格式化,但不包含任何数据。我要做的就是将512字节的0写入驱动器,直到驱动器完全充满。

代码:

for (double idx = 0; idx < TotalSectors; idx++)
    {
        File.Write(writeBuffer, (uint)writeBuffer.Length);  // write the buffer
        int val = pos += (int.Parse(BPS.ToString()) * int.Parse(idx.ToString()));
        File.MoveFilePointer(val);
        Application.DoEvents();
    }

正如您所看到的那样,只需迭代该过程,直到所有扇区都被写入。但是,由于某种原因,在8次迭代后,我收到“拒绝访问”错误。

有什么想法吗?

修改 感谢Xanatos - 修复了愚蠢的文件位置更新。但是,File.MoveFilePointer()方法采用int。所以我目前正在将val转换为(int)。该方法现在迭代14次,然后抛出“拒绝访问”异常。

编辑2 借用代码

write方法如下所示:

 public uint Write(byte[] buffer, uint cbToWrite)
    {
        // returns bytes read
        uint cbThatWereWritten = 0;
        if (!WriteFile(_hFile, buffer, cbToWrite,
         ref cbThatWereWritten, IntPtr.Zero))
            ThrowLastWin32Err();
        return cbThatWereWritten;
    }

并且File.MoveFilePointer方法如下所示:

public void MoveFilePointer(int cbToMove,
     MoveMethod fMoveMethod)
    {
        if (_hFile != null)
            if (SetFilePointer(_hFile, cbToMove, IntPtr.Zero,
             fMoveMethod) == INVALID_SET_FILE_POINTER)
                ThrowLastWin32Err();
    }

1 个答案:

答案 0 :(得分:3)

int bps = ... // Use int!
long TotalSectors = ... // use long!
long pos = 0; // use long!

for (long idx = 0; idx < TotalSectors; idx++)
{
    File.Write(writeBuffer, (uint)writeBuffer.Length);  // write the buffer
    pos += bps;
    // File.MoveFilePointer(pos); // Useless, the file pointer will be moved
                                  // by the File.Write
    Application.DoEvents();
}

完成!你正在增加pos

val = pos += (int.Parse(BPS.ToString()) * int.Parse(idx.ToString()));

忽略val,忽略它Parse(...ToString)

pos += BPS * idx;

所以

idx = 0, pos += 0 (pos = 0), // here it's already wrong! you are initializing twice 
                             // the same sector!
idx = 1, pos += 1 * 512 (pos = 512), 
idx = 2, pos += 2 * 512 (pos = 1536) WRONG!

作为旁注,在.net中long是64位,对于硬盘的扇区数量或其大小来说足够大。